diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog index 6470f42f8479..359b1d56c2c0 100644 --- a/LayoutTests/ChangeLog +++ b/LayoutTests/ChangeLog @@ -1,3 +1,14 @@ +2016-04-19 Alex Christensen + + Update ANGLE + https://bugs.webkit.org/show_bug.cgi?id=156755 + + Reviewed by Dean Jackson. + + * webgl/1.0.2/conformance/glsl/reserved/webgl_preprocessor_reserved-expected.txt: Removed. + * webgl/1.0.2/conformance/glsl/reserved/webgl_preprocessor_reserved.html: Removed. + Removed invalid test based on https://github.com/KhronosGroup/WebGL/pull/1230 + 2016-04-19 Youenn Fablet imported/w3c/web-platform-tests/streams/readable-streams/general.https.html is a flaky failure diff --git a/LayoutTests/webgl/1.0.2/conformance/glsl/reserved/webgl_preprocessor_reserved-expected.txt b/LayoutTests/webgl/1.0.2/conformance/glsl/reserved/webgl_preprocessor_reserved-expected.txt deleted file mode 100644 index 7d382e7615f9..000000000000 --- a/LayoutTests/webgl/1.0.2/conformance/glsl/reserved/webgl_preprocessor_reserved-expected.txt +++ /dev/null @@ -1,5 +0,0 @@ -This test runs the WebGL Test listed below in an iframe and reports PASS or FAIL. - -Test: ../../../resources/webgl_test_files/conformance/glsl/reserved/webgl_preprocessor_reserved.html -PASS - diff --git a/LayoutTests/webgl/1.0.2/conformance/glsl/reserved/webgl_preprocessor_reserved.html b/LayoutTests/webgl/1.0.2/conformance/glsl/reserved/webgl_preprocessor_reserved.html deleted file mode 100644 index dd6517aea949..000000000000 --- a/LayoutTests/webgl/1.0.2/conformance/glsl/reserved/webgl_preprocessor_reserved.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - -WebGL Conformance Test Wrapper for webgl_preprocessor_reserved.html - - - - -

This test runs the WebGL Test listed below in an iframe and reports PASS or FAIL.

-Test: ../../../resources/webgl_test_files/conformance/glsl/reserved/webgl_preprocessor_reserved.html -
-
- -
- - diff --git a/Source/ThirdParty/ANGLE/ANGLE.plist b/Source/ThirdParty/ANGLE/ANGLE.plist index 2b5b158e9285..b3e9e95626cc 100644 --- a/Source/ThirdParty/ANGLE/ANGLE.plist +++ b/Source/ThirdParty/ANGLE/ANGLE.plist @@ -10,7 +10,7 @@ OpenSourceWebsiteURL http://code.google.com/p/angleproject/ OpenSourceSCM - git clone https://chromium.googlesource.com/angle/angle && cd angle && git checkout b11e2483742db884bd0af41f78f528240577356b + git clone https://chromium.googlesource.com/angle/angle && cd angle && git checkout 6684007a77572f3616fc453138b0ef5f7d42d038 OpenSourceImportDate 2014-04-29 OpenSourceLicense diff --git a/Source/ThirdParty/ANGLE/ANGLE.xcodeproj/project.pbxproj b/Source/ThirdParty/ANGLE/ANGLE.xcodeproj/project.pbxproj index e74a367c7e9e..5b2da1ef38f5 100644 --- a/Source/ThirdParty/ANGLE/ANGLE.xcodeproj/project.pbxproj +++ b/Source/ThirdParty/ANGLE/ANGLE.xcodeproj/project.pbxproj @@ -57,13 +57,11 @@ 31012E5018B97B9B0039062F /* OutputGLSLBase.h in Headers */ = {isa = PBXBuildFile; fileRef = 31012DE018B97B9B0039062F /* OutputGLSLBase.h */; }; 31012E5118B97B9B0039062F /* OutputHLSL.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 31012DE118B97B9B0039062F /* OutputHLSL.cpp */; }; 31012E5218B97B9B0039062F /* OutputHLSL.h in Headers */ = {isa = PBXBuildFile; fileRef = 31012DE218B97B9B0039062F /* OutputHLSL.h */; }; - 31012E5318B97B9B0039062F /* parseConst.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 31012DE318B97B9B0039062F /* parseConst.cpp */; }; 31012E5418B97B9B0039062F /* ParseContext.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 31012DE418B97B9B0039062F /* ParseContext.cpp */; }; 31012E5518B97B9B0039062F /* ParseContext.h in Headers */ = {isa = PBXBuildFile; fileRef = 31012DE518B97B9B0039062F /* ParseContext.h */; }; 31012E5618B97B9B0039062F /* PoolAlloc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 31012DE618B97B9B0039062F /* PoolAlloc.cpp */; }; 31012E5718B97B9B0039062F /* PoolAlloc.h in Headers */ = {isa = PBXBuildFile; fileRef = 31012DE718B97B9B0039062F /* PoolAlloc.h */; }; 31012E5818B97B9B0039062F /* Pragma.h in Headers */ = {isa = PBXBuildFile; fileRef = 31012DE818B97B9B0039062F /* Pragma.h */; }; - 31012E5918B97B9B0039062F /* QualifierAlive.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 31012DE918B97B9B0039062F /* QualifierAlive.cpp */; }; 31012E5A18B97B9B0039062F /* QualifierAlive.h in Headers */ = {isa = PBXBuildFile; fileRef = 31012DEA18B97B9B0039062F /* QualifierAlive.h */; }; 31012E5D18B97B9B0039062F /* RenameFunction.h in Headers */ = {isa = PBXBuildFile; fileRef = 31012DED18B97B9B0039062F /* RenameFunction.h */; }; 31012E5E18B97B9B0039062F /* RewriteElseBlocks.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 31012DEE18B97B9B0039062F /* RewriteElseBlocks.cpp */; }; @@ -84,8 +82,6 @@ 31012E6E18B97B9B0039062F /* TranslatorHLSL.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 31012DFF18B97B9B0039062F /* TranslatorHLSL.cpp */; }; 31012E6F18B97B9B0039062F /* TranslatorHLSL.h in Headers */ = {isa = PBXBuildFile; fileRef = 31012E0018B97B9B0039062F /* TranslatorHLSL.h */; }; 31012E7018B97B9B0039062F /* Types.h in Headers */ = {isa = PBXBuildFile; fileRef = 31012E0118B97B9B0039062F /* Types.h */; }; - 31012E7118B97B9B0039062F /* UnfoldShortCircuit.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 31012E0218B97B9B0039062F /* UnfoldShortCircuit.cpp */; }; - 31012E7218B97B9B0039062F /* UnfoldShortCircuit.h in Headers */ = {isa = PBXBuildFile; fileRef = 31012E0318B97B9B0039062F /* UnfoldShortCircuit.h */; }; 31012E7318B97B9B0039062F /* UnfoldShortCircuitAST.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 31012E0418B97B9B0039062F /* UnfoldShortCircuitAST.cpp */; }; 31012E7418B97B9B0039062F /* UnfoldShortCircuitAST.h in Headers */ = {isa = PBXBuildFile; fileRef = 31012E0518B97B9B0039062F /* UnfoldShortCircuitAST.h */; }; 31012E7718B97B9B0039062F /* util.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 31012E0818B97B9B0039062F /* util.cpp */; }; @@ -142,8 +138,6 @@ 5C1DBC3F1B04375F00235552 /* SeparateDeclarations.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5C1DBC181B04375F00235552 /* SeparateDeclarations.cpp */; }; 5C1DBC401B04375F00235552 /* SeparateDeclarations.h in Headers */ = {isa = PBXBuildFile; fileRef = 5C1DBC191B04375F00235552 /* SeparateDeclarations.h */; }; 5C1DBC411B04375F00235552 /* ShaderVars.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5C1DBC1A1B04375F00235552 /* ShaderVars.cpp */; }; - 5C1DBC421B04375F00235552 /* SimplifyArrayAssignment.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5C1DBC1B1B04375F00235552 /* SimplifyArrayAssignment.cpp */; }; - 5C1DBC431B04375F00235552 /* SimplifyArrayAssignment.h in Headers */ = {isa = PBXBuildFile; fileRef = 5C1DBC1C1B04375F00235552 /* SimplifyArrayAssignment.h */; }; 5C1DBC441B04375F00235552 /* Types.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5C1DBC1D1B04375F00235552 /* Types.cpp */; }; 5C1DBC451B04375F00235552 /* ValidateSwitch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5C1DBC1E1B04375F00235552 /* ValidateSwitch.cpp */; }; 5C1DBC461B04375F00235552 /* ValidateSwitch.h in Headers */ = {isa = PBXBuildFile; fileRef = 5C1DBC1F1B04375F00235552 /* ValidateSwitch.h */; }; @@ -193,7 +187,6 @@ 5C1DBE021B0438D300235552 /* Query.h in Headers */ = {isa = PBXBuildFile; fileRef = 5C1DBC791B0438D200235552 /* Query.h */; }; 5C1DBE031B0438D300235552 /* queryconversions.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5C1DBC7A1B0438D200235552 /* queryconversions.cpp */; }; 5C1DBE041B0438D300235552 /* queryconversions.h in Headers */ = {isa = PBXBuildFile; fileRef = 5C1DBC7B1B0438D200235552 /* queryconversions.h */; }; - 5C1DBE051B0438D300235552 /* RefCountObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5C1DBC7C1B0438D200235552 /* RefCountObject.cpp */; }; 5C1DBE061B0438D300235552 /* RefCountObject.h in Headers */ = {isa = PBXBuildFile; fileRef = 5C1DBC7D1B0438D200235552 /* RefCountObject.h */; }; 5C1DBE071B0438D300235552 /* Renderbuffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5C1DBC7E1B0438D200235552 /* Renderbuffer.cpp */; }; 5C1DBE081B0438D300235552 /* Renderbuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = 5C1DBC7F1B0438D200235552 /* Renderbuffer.h */; }; @@ -225,6 +218,28 @@ 5C1DBF401B0438D300235552 /* VertexArray.h in Headers */ = {isa = PBXBuildFile; fileRef = 5C1DBDD01B0438D300235552 /* VertexArray.h */; }; 5C1DBF411B0438D300235552 /* VertexAttribute.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5C1DBDD11B0438D300235552 /* VertexAttribute.cpp */; }; 5C1DBF421B0438D300235552 /* VertexAttribute.h in Headers */ = {isa = PBXBuildFile; fileRef = 5C1DBDD21B0438D300235552 /* VertexAttribute.h */; }; + 5C315CFE1CC5B6DA00776697 /* Cache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5C315CE81CC5B6DA00776697 /* Cache.cpp */; }; + 5C315CFF1CC5B6DA00776697 /* Cache.h in Headers */ = {isa = PBXBuildFile; fileRef = 5C315CE91CC5B6DA00776697 /* Cache.h */; }; + 5C315D001CC5B6DA00776697 /* DeferGlobalInitializers.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5C315CEA1CC5B6DA00776697 /* DeferGlobalInitializers.cpp */; }; + 5C315D011CC5B6DA00776697 /* DeferGlobalInitializers.h in Headers */ = {isa = PBXBuildFile; fileRef = 5C315CEB1CC5B6DA00776697 /* DeferGlobalInitializers.h */; }; + 5C315D021CC5B6DA00776697 /* ExtensionGLSL.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5C315CEC1CC5B6DA00776697 /* ExtensionGLSL.cpp */; }; + 5C315D031CC5B6DA00776697 /* ExtensionGLSL.h in Headers */ = {isa = PBXBuildFile; fileRef = 5C315CED1CC5B6DA00776697 /* ExtensionGLSL.h */; }; + 5C315D041CC5B6DA00776697 /* RecordConstantPrecision.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5C315CEE1CC5B6DA00776697 /* RecordConstantPrecision.cpp */; }; + 5C315D051CC5B6DA00776697 /* RecordConstantPrecision.h in Headers */ = {isa = PBXBuildFile; fileRef = 5C315CEF1CC5B6DA00776697 /* RecordConstantPrecision.h */; }; + 5C315D061CC5B6DA00776697 /* RemoveDynamicIndexing.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5C315CF01CC5B6DA00776697 /* RemoveDynamicIndexing.cpp */; }; + 5C315D071CC5B6DA00776697 /* RemoveDynamicIndexing.h in Headers */ = {isa = PBXBuildFile; fileRef = 5C315CF11CC5B6DA00776697 /* RemoveDynamicIndexing.h */; }; + 5C315D081CC5B6DA00776697 /* RemovePow.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5C315CF21CC5B6DA00776697 /* RemovePow.cpp */; }; + 5C315D091CC5B6DA00776697 /* RemovePow.h in Headers */ = {isa = PBXBuildFile; fileRef = 5C315CF31CC5B6DA00776697 /* RemovePow.h */; }; + 5C315D0A1CC5B6DA00776697 /* RewriteDoWhile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5C315CF41CC5B6DA00776697 /* RewriteDoWhile.cpp */; }; + 5C315D0B1CC5B6DA00776697 /* RewriteDoWhile.h in Headers */ = {isa = PBXBuildFile; fileRef = 5C315CF51CC5B6DA00776697 /* RewriteDoWhile.h */; }; + 5C315D0C1CC5B6DA00776697 /* SeparateExpressionsReturningArrays.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5C315CF61CC5B6DA00776697 /* SeparateExpressionsReturningArrays.cpp */; }; + 5C315D0D1CC5B6DA00776697 /* SeparateExpressionsReturningArrays.h in Headers */ = {isa = PBXBuildFile; fileRef = 5C315CF71CC5B6DA00776697 /* SeparateExpressionsReturningArrays.h */; }; + 5C315D0E1CC5B6DA00776697 /* UnfoldShortCircuitToIf.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5C315CF81CC5B6DA00776697 /* UnfoldShortCircuitToIf.cpp */; }; + 5C315D0F1CC5B6DA00776697 /* UnfoldShortCircuitToIf.h in Headers */ = {isa = PBXBuildFile; fileRef = 5C315CF91CC5B6DA00776697 /* UnfoldShortCircuitToIf.h */; }; + 5C315D101CC5B6DA00776697 /* ValidateGlobalInitializer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5C315CFA1CC5B6DA00776697 /* ValidateGlobalInitializer.cpp */; }; + 5C315D111CC5B6DA00776697 /* ValidateGlobalInitializer.h in Headers */ = {isa = PBXBuildFile; fileRef = 5C315CFB1CC5B6DA00776697 /* ValidateGlobalInitializer.h */; }; + 5C315D121CC5B6DA00776697 /* ValidateMaxParameters.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5C315CFC1CC5B6DA00776697 /* ValidateMaxParameters.cpp */; }; + 5C315D131CC5B6DA00776697 /* ValidateMaxParameters.h in Headers */ = {isa = PBXBuildFile; fileRef = 5C315CFD1CC5B6DA00776697 /* ValidateMaxParameters.h */; }; 5C9FFF4E19102A000025B8FA /* FlagStd140Structs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5C9FFF4C19102A000025B8FA /* FlagStd140Structs.cpp */; }; 5C9FFF4F19102A000025B8FA /* FlagStd140Structs.h in Headers */ = {isa = PBXBuildFile; fileRef = 5C9FFF4D19102A000025B8FA /* FlagStd140Structs.h */; }; 5CC7D452191024E4000B8C1F /* LoopInfo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5CC7D44B191024E3000B8C1F /* LoopInfo.cpp */; }; @@ -346,13 +361,11 @@ 31012DE018B97B9B0039062F /* OutputGLSLBase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OutputGLSLBase.h; sourceTree = ""; }; 31012DE118B97B9B0039062F /* OutputHLSL.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OutputHLSL.cpp; sourceTree = ""; }; 31012DE218B97B9B0039062F /* OutputHLSL.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OutputHLSL.h; sourceTree = ""; }; - 31012DE318B97B9B0039062F /* parseConst.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = parseConst.cpp; sourceTree = ""; }; 31012DE418B97B9B0039062F /* ParseContext.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ParseContext.cpp; sourceTree = ""; }; 31012DE518B97B9B0039062F /* ParseContext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ParseContext.h; sourceTree = ""; }; 31012DE618B97B9B0039062F /* PoolAlloc.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PoolAlloc.cpp; sourceTree = ""; }; 31012DE718B97B9B0039062F /* PoolAlloc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PoolAlloc.h; sourceTree = ""; }; 31012DE818B97B9B0039062F /* Pragma.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Pragma.h; sourceTree = ""; }; - 31012DE918B97B9B0039062F /* QualifierAlive.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = QualifierAlive.cpp; sourceTree = ""; }; 31012DEA18B97B9B0039062F /* QualifierAlive.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = QualifierAlive.h; sourceTree = ""; }; 31012DED18B97B9B0039062F /* RenameFunction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RenameFunction.h; sourceTree = ""; }; 31012DEE18B97B9B0039062F /* RewriteElseBlocks.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RewriteElseBlocks.cpp; sourceTree = ""; }; @@ -373,8 +386,6 @@ 31012DFF18B97B9B0039062F /* TranslatorHLSL.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TranslatorHLSL.cpp; sourceTree = ""; }; 31012E0018B97B9B0039062F /* TranslatorHLSL.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TranslatorHLSL.h; sourceTree = ""; }; 31012E0118B97B9B0039062F /* Types.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Types.h; sourceTree = ""; }; - 31012E0218B97B9B0039062F /* UnfoldShortCircuit.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = UnfoldShortCircuit.cpp; sourceTree = ""; }; - 31012E0318B97B9B0039062F /* UnfoldShortCircuit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UnfoldShortCircuit.h; sourceTree = ""; }; 31012E0418B97B9B0039062F /* UnfoldShortCircuitAST.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = UnfoldShortCircuitAST.cpp; sourceTree = ""; }; 31012E0518B97B9B0039062F /* UnfoldShortCircuitAST.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UnfoldShortCircuitAST.h; sourceTree = ""; }; 31012E0818B97B9B0039062F /* util.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = util.cpp; sourceTree = ""; }; @@ -431,8 +442,6 @@ 5C1DBC181B04375F00235552 /* SeparateDeclarations.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SeparateDeclarations.cpp; sourceTree = ""; }; 5C1DBC191B04375F00235552 /* SeparateDeclarations.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SeparateDeclarations.h; sourceTree = ""; }; 5C1DBC1A1B04375F00235552 /* ShaderVars.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ShaderVars.cpp; sourceTree = ""; }; - 5C1DBC1B1B04375F00235552 /* SimplifyArrayAssignment.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SimplifyArrayAssignment.cpp; sourceTree = ""; }; - 5C1DBC1C1B04375F00235552 /* SimplifyArrayAssignment.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SimplifyArrayAssignment.h; sourceTree = ""; }; 5C1DBC1D1B04375F00235552 /* Types.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Types.cpp; sourceTree = ""; }; 5C1DBC1E1B04375F00235552 /* ValidateSwitch.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ValidateSwitch.cpp; sourceTree = ""; }; 5C1DBC1F1B04375F00235552 /* ValidateSwitch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ValidateSwitch.h; sourceTree = ""; }; @@ -483,7 +492,6 @@ 5C1DBC791B0438D200235552 /* Query.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Query.h; path = src/libANGLE/Query.h; sourceTree = ""; }; 5C1DBC7A1B0438D200235552 /* queryconversions.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = queryconversions.cpp; path = src/libANGLE/queryconversions.cpp; sourceTree = ""; }; 5C1DBC7B1B0438D200235552 /* queryconversions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = queryconversions.h; path = src/libANGLE/queryconversions.h; sourceTree = ""; }; - 5C1DBC7C1B0438D200235552 /* RefCountObject.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = RefCountObject.cpp; path = src/libANGLE/RefCountObject.cpp; sourceTree = ""; }; 5C1DBC7D1B0438D200235552 /* RefCountObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RefCountObject.h; path = src/libANGLE/RefCountObject.h; sourceTree = ""; }; 5C1DBC7E1B0438D200235552 /* Renderbuffer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Renderbuffer.cpp; path = src/libANGLE/Renderbuffer.cpp; sourceTree = ""; }; 5C1DBC7F1B0438D200235552 /* Renderbuffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Renderbuffer.h; path = src/libANGLE/Renderbuffer.h; sourceTree = ""; }; @@ -515,6 +523,28 @@ 5C1DBDD01B0438D300235552 /* VertexArray.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = VertexArray.h; path = src/libANGLE/VertexArray.h; sourceTree = ""; }; 5C1DBDD11B0438D300235552 /* VertexAttribute.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = VertexAttribute.cpp; path = src/libANGLE/VertexAttribute.cpp; sourceTree = ""; }; 5C1DBDD21B0438D300235552 /* VertexAttribute.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = VertexAttribute.h; path = src/libANGLE/VertexAttribute.h; sourceTree = ""; }; + 5C315CE81CC5B6DA00776697 /* Cache.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Cache.cpp; sourceTree = ""; }; + 5C315CE91CC5B6DA00776697 /* Cache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Cache.h; sourceTree = ""; }; + 5C315CEA1CC5B6DA00776697 /* DeferGlobalInitializers.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DeferGlobalInitializers.cpp; sourceTree = ""; }; + 5C315CEB1CC5B6DA00776697 /* DeferGlobalInitializers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DeferGlobalInitializers.h; sourceTree = ""; }; + 5C315CEC1CC5B6DA00776697 /* ExtensionGLSL.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ExtensionGLSL.cpp; sourceTree = ""; }; + 5C315CED1CC5B6DA00776697 /* ExtensionGLSL.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ExtensionGLSL.h; sourceTree = ""; }; + 5C315CEE1CC5B6DA00776697 /* RecordConstantPrecision.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RecordConstantPrecision.cpp; sourceTree = ""; }; + 5C315CEF1CC5B6DA00776697 /* RecordConstantPrecision.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RecordConstantPrecision.h; sourceTree = ""; }; + 5C315CF01CC5B6DA00776697 /* RemoveDynamicIndexing.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RemoveDynamicIndexing.cpp; sourceTree = ""; }; + 5C315CF11CC5B6DA00776697 /* RemoveDynamicIndexing.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RemoveDynamicIndexing.h; sourceTree = ""; }; + 5C315CF21CC5B6DA00776697 /* RemovePow.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RemovePow.cpp; sourceTree = ""; }; + 5C315CF31CC5B6DA00776697 /* RemovePow.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RemovePow.h; sourceTree = ""; }; + 5C315CF41CC5B6DA00776697 /* RewriteDoWhile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RewriteDoWhile.cpp; sourceTree = ""; }; + 5C315CF51CC5B6DA00776697 /* RewriteDoWhile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RewriteDoWhile.h; sourceTree = ""; }; + 5C315CF61CC5B6DA00776697 /* SeparateExpressionsReturningArrays.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SeparateExpressionsReturningArrays.cpp; sourceTree = ""; }; + 5C315CF71CC5B6DA00776697 /* SeparateExpressionsReturningArrays.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SeparateExpressionsReturningArrays.h; sourceTree = ""; }; + 5C315CF81CC5B6DA00776697 /* UnfoldShortCircuitToIf.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = UnfoldShortCircuitToIf.cpp; sourceTree = ""; }; + 5C315CF91CC5B6DA00776697 /* UnfoldShortCircuitToIf.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UnfoldShortCircuitToIf.h; sourceTree = ""; }; + 5C315CFA1CC5B6DA00776697 /* ValidateGlobalInitializer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ValidateGlobalInitializer.cpp; sourceTree = ""; }; + 5C315CFB1CC5B6DA00776697 /* ValidateGlobalInitializer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ValidateGlobalInitializer.h; sourceTree = ""; }; + 5C315CFC1CC5B6DA00776697 /* ValidateMaxParameters.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ValidateMaxParameters.cpp; sourceTree = ""; }; + 5C315CFD1CC5B6DA00776697 /* ValidateMaxParameters.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ValidateMaxParameters.h; sourceTree = ""; }; 5C9FFF4C19102A000025B8FA /* FlagStd140Structs.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FlagStd140Structs.cpp; sourceTree = ""; }; 5C9FFF4D19102A000025B8FA /* FlagStd140Structs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FlagStd140Structs.h; sourceTree = ""; }; 5CC7D44B191024E3000B8C1F /* LoopInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LoopInfo.cpp; sourceTree = ""; }; @@ -580,6 +610,28 @@ 31012D9F18B97B9B0039062F /* translator */ = { isa = PBXGroup; children = ( + 5C315CE81CC5B6DA00776697 /* Cache.cpp */, + 5C315CE91CC5B6DA00776697 /* Cache.h */, + 5C315CEA1CC5B6DA00776697 /* DeferGlobalInitializers.cpp */, + 5C315CEB1CC5B6DA00776697 /* DeferGlobalInitializers.h */, + 5C315CEC1CC5B6DA00776697 /* ExtensionGLSL.cpp */, + 5C315CED1CC5B6DA00776697 /* ExtensionGLSL.h */, + 5C315CEE1CC5B6DA00776697 /* RecordConstantPrecision.cpp */, + 5C315CEF1CC5B6DA00776697 /* RecordConstantPrecision.h */, + 5C315CF01CC5B6DA00776697 /* RemoveDynamicIndexing.cpp */, + 5C315CF11CC5B6DA00776697 /* RemoveDynamicIndexing.h */, + 5C315CF21CC5B6DA00776697 /* RemovePow.cpp */, + 5C315CF31CC5B6DA00776697 /* RemovePow.h */, + 5C315CF41CC5B6DA00776697 /* RewriteDoWhile.cpp */, + 5C315CF51CC5B6DA00776697 /* RewriteDoWhile.h */, + 5C315CF61CC5B6DA00776697 /* SeparateExpressionsReturningArrays.cpp */, + 5C315CF71CC5B6DA00776697 /* SeparateExpressionsReturningArrays.h */, + 5C315CF81CC5B6DA00776697 /* UnfoldShortCircuitToIf.cpp */, + 5C315CF91CC5B6DA00776697 /* UnfoldShortCircuitToIf.h */, + 5C315CFA1CC5B6DA00776697 /* ValidateGlobalInitializer.cpp */, + 5C315CFB1CC5B6DA00776697 /* ValidateGlobalInitializer.h */, + 5C315CFC1CC5B6DA00776697 /* ValidateMaxParameters.cpp */, + 5C315CFD1CC5B6DA00776697 /* ValidateMaxParameters.h */, 5C1DBBF91B04375E00235552 /* ArrayReturnValueToOutParameter.cpp */, 5C1DBBFA1B04375E00235552 /* ArrayReturnValueToOutParameter.h */, 5C1DBBFB1B04375F00235552 /* ASTMetadataHLSL.cpp */, @@ -614,8 +666,6 @@ 5C1DBC181B04375F00235552 /* SeparateDeclarations.cpp */, 5C1DBC191B04375F00235552 /* SeparateDeclarations.h */, 5C1DBC1A1B04375F00235552 /* ShaderVars.cpp */, - 5C1DBC1B1B04375F00235552 /* SimplifyArrayAssignment.cpp */, - 5C1DBC1C1B04375F00235552 /* SimplifyArrayAssignment.h */, 5C1DBC1D1B04375F00235552 /* Types.cpp */, 5C1DBC1E1B04375F00235552 /* ValidateSwitch.cpp */, 5C1DBC1F1B04375F00235552 /* ValidateSwitch.h */, @@ -670,13 +720,11 @@ 31012DE018B97B9B0039062F /* OutputGLSLBase.h */, 31012DE118B97B9B0039062F /* OutputHLSL.cpp */, 31012DE218B97B9B0039062F /* OutputHLSL.h */, - 31012DE318B97B9B0039062F /* parseConst.cpp */, 31012DE418B97B9B0039062F /* ParseContext.cpp */, 31012DE518B97B9B0039062F /* ParseContext.h */, 31012DE618B97B9B0039062F /* PoolAlloc.cpp */, 31012DE718B97B9B0039062F /* PoolAlloc.h */, 31012DE818B97B9B0039062F /* Pragma.h */, - 31012DE918B97B9B0039062F /* QualifierAlive.cpp */, 31012DEA18B97B9B0039062F /* QualifierAlive.h */, 31012DED18B97B9B0039062F /* RenameFunction.h */, 31012DEE18B97B9B0039062F /* RewriteElseBlocks.cpp */, @@ -693,8 +741,6 @@ 31012DFF18B97B9B0039062F /* TranslatorHLSL.cpp */, 31012E0018B97B9B0039062F /* TranslatorHLSL.h */, 31012E0118B97B9B0039062F /* Types.h */, - 31012E0218B97B9B0039062F /* UnfoldShortCircuit.cpp */, - 31012E0318B97B9B0039062F /* UnfoldShortCircuit.h */, 31012E0418B97B9B0039062F /* UnfoldShortCircuitAST.cpp */, 31012E0518B97B9B0039062F /* UnfoldShortCircuitAST.h */, 31012E0818B97B9B0039062F /* util.cpp */, @@ -795,7 +841,6 @@ 5C1DBC791B0438D200235552 /* Query.h */, 5C1DBC7A1B0438D200235552 /* queryconversions.cpp */, 5C1DBC7B1B0438D200235552 /* queryconversions.h */, - 5C1DBC7C1B0438D200235552 /* RefCountObject.cpp */, 5C1DBC7D1B0438D200235552 /* RefCountObject.h */, 5C1DBC7E1B0438D200235552 /* Renderbuffer.cpp */, 5C1DBC7F1B0438D200235552 /* Renderbuffer.h */, @@ -989,6 +1034,8 @@ isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( + 5C315D131CC5B6DA00776697 /* ValidateMaxParameters.h in Headers */, + 5C315D071CC5B6DA00776697 /* RemoveDynamicIndexing.h in Headers */, 31012E3C18B97B9B0039062F /* InitializeParseContext.h in Headers */, A08C3CDD16D6CB61003F0B83 /* ArrayBoundsClamper.h in Headers */, 5CC7D46F19102621000B8C1F /* debug.h in Headers */, @@ -999,10 +1046,10 @@ 31012E5518B97B9B0039062F /* ParseContext.h in Headers */, 5C1DBDEF1B0438D300235552 /* Fence.h in Headers */, 31012E2C18B97B9B0039062F /* ForLoopUnroll.h in Headers */, + 5C315D031CC5B6DA00776697 /* ExtensionGLSL.h in Headers */, 31012E6D18B97B9B0039062F /* TranslatorGLSL.h in Headers */, 5C1DBC3E1B04375F00235552 /* SeparateArrayInitialization.h in Headers */, 31012E4618B97B9B0039062F /* MMap.h in Headers */, - 5C1DBC431B04375F00235552 /* SimplifyArrayAssignment.h in Headers */, 5CC7D47319102621000B8C1F /* mathutil.h in Headers */, 31012E6B18B97B9B0039062F /* TranslatorESSL.h in Headers */, 5C1DBE001B0438D300235552 /* Program.h in Headers */, @@ -1011,6 +1058,7 @@ 31012E2018B97B9B0039062F /* DependencyGraphOutput.h in Headers */, 31012E7C18B97B9B0039062F /* VariableInfo.h in Headers */, 5C1DBDDB1B0438D300235552 /* Caps.h in Headers */, + 5C315D091CC5B6DA00776697 /* RemovePow.h in Headers */, 5C1DBE021B0438D300235552 /* Query.h in Headers */, 31012E6118B97B9B0039062F /* SearchSymbol.h in Headers */, 5C1DBF311B0438D300235552 /* Texture.h in Headers */, @@ -1029,12 +1077,14 @@ 5CC7D47119102621000B8C1F /* event_tracer.h in Headers */, 5C1DBDE71B0438D300235552 /* Device.h in Headers */, 5C1DBE061B0438D300235552 /* RefCountObject.h in Headers */, + 5C315D051CC5B6DA00776697 /* RecordConstantPrecision.h in Headers */, 31012E5D18B97B9B0039062F /* RenameFunction.h in Headers */, 5C1DBDFA1B0438D300235552 /* histogram_macros.h in Headers */, 5C1DBDD71B0438D300235552 /* BinaryStream.h in Headers */, 31012E3A18B97B9B0039062F /* InitializeGlobals.h in Headers */, 5C1DBC291B04375F00235552 /* BuiltInFunctionEmulatorGLSL.h in Headers */, 5C1DBBE61B04075B00235552 /* ShaderVars.h in Headers */, + 5C315D0B1CC5B6DA00776697 /* RewriteDoWhile.h in Headers */, 5C1DBC251B04375F00235552 /* blocklayout.h in Headers */, 5C1DBC271B04375F00235552 /* blocklayoutHLSL.h in Headers */, 31012E8018B97B9B0039062F /* VersionGLSL.h in Headers */, @@ -1043,6 +1093,7 @@ 5C1DBDD91B0438D300235552 /* Buffer.h in Headers */, 31012E2718B97B9B0039062F /* Diagnostics.h in Headers */, 5C1DBC361B04375F00235552 /* PruneEmptyDeclarations.h in Headers */, + 5C315D011CC5B6DA00776697 /* DeferGlobalInitializers.h in Headers */, 5C1DBDF61B0438D300235552 /* FramebufferAttachment.h in Headers */, 5CC7D46B19102620000B8C1F /* angleutils.h in Headers */, 31012E3218B97B9B0039062F /* glslang_tab.h in Headers */, @@ -1055,7 +1106,6 @@ 5CC7D458191024E4000B8C1F /* ValidateOutputs.h in Headers */, 31012E7418B97B9B0039062F /* UnfoldShortCircuitAST.h in Headers */, 5C1DBDF41B0438D300235552 /* Framebuffer.h in Headers */, - 31012E7218B97B9B0039062F /* UnfoldShortCircuit.h in Headers */, A264F8B316974DED006FAA5A /* ExpressionParser.h in Headers */, 31012E3518B97B9B0039062F /* InfoSink.h in Headers */, 5C1DBF3A1B0438D300235552 /* validationES.h in Headers */, @@ -1069,6 +1119,7 @@ 31012E6718B97B9B0039062F /* RestrictFragmentShaderTiming.h in Headers */, 5CC7D47B19102621000B8C1F /* version.h in Headers */, 5C1DBF281B0438D300235552 /* Sampler.h in Headers */, + 5C315D111CC5B6DA00776697 /* ValidateGlobalInitializer.h in Headers */, 5C1DBF381B0438D300235552 /* validationEGL.h in Headers */, 5C1DBF3C1B0438D300235552 /* validationES2.h in Headers */, 31012E7818B97B9B0039062F /* util.h in Headers */, @@ -1079,10 +1130,12 @@ A264F8CD169762AA006FAA5A /* khrplatform.h in Headers */, 5C1DBBF71B0436EC00235552 /* tls.h in Headers */, 5C1DBBF51B0436EC00235552 /* platform.h in Headers */, + 5C315D0F1CC5B6DA00776697 /* UnfoldShortCircuitToIf.h in Headers */, 5CC7D47A19102621000B8C1F /* utilities.h in Headers */, 31012E3918B97B9B0039062F /* InitializeDll.h in Headers */, 5C1DBBF21B0436EC00235552 /* MemoryBuffer.h in Headers */, A264F8B716974DED006FAA5A /* Lexer.h in Headers */, + 5C315D0D1CC5B6DA00776697 /* SeparateExpressionsReturningArrays.h in Headers */, A264F8B916974DED006FAA5A /* Macro.h in Headers */, 31012E5A18B97B9B0039062F /* QualifierAlive.h in Headers */, 31012E5718B97B9B0039062F /* PoolAlloc.h in Headers */, @@ -1119,6 +1172,7 @@ 31012E7A18B97B9B0039062F /* ValidateLimitations.h in Headers */, 5C1DBC341B04375F00235552 /* Operator.h in Headers */, 5C1DBC401B04375F00235552 /* SeparateDeclarations.h in Headers */, + 5C315CFF1CC5B6DA00776697 /* Cache.h in Headers */, 5C1DBDD61B0438D300235552 /* AttributeMap.h in Headers */, 31012E3318B97B9B0039062F /* HashNames.h in Headers */, A264F8C216974DED006FAA5A /* Token.h in Headers */, @@ -1188,14 +1242,17 @@ 31012E2618B97B9B0039062F /* Diagnostics.cpp in Sources */, 31012E3D18B97B9B0039062F /* InitializeVariables.cpp in Sources */, 31012E7F18B97B9B0039062F /* VersionGLSL.cpp in Sources */, + 5C315D0A1CC5B6DA00776697 /* RewriteDoWhile.cpp in Sources */, A08C3CDC16D6CB61003F0B83 /* ArrayBoundsClamper.cpp in Sources */, 5C1DBC451B04375F00235552 /* ValidateSwitch.cpp in Sources */, 5C1DBDF51B0438D300235552 /* FramebufferAttachment.cpp in Sources */, 5C1DBC441B04375F00235552 /* Types.cpp in Sources */, 72309A56183C27DE00370B93 /* Tokenizer.cpp in Sources */, 31012E6C18B97B9B0039062F /* TranslatorGLSL.cpp in Sources */, + 5C315D0E1CC5B6DA00776697 /* UnfoldShortCircuitToIf.cpp in Sources */, 5C1DBF411B0438D300235552 /* VertexAttribute.cpp in Sources */, A264F8AC16974DED006FAA5A /* DiagnosticsBase.cpp in Sources */, + 5C315D101CC5B6DA00776697 /* ValidateGlobalInitializer.cpp in Sources */, 5C1DBDE41B0438D300235552 /* Data.cpp in Sources */, 5C1DBF291B0438D300235552 /* Shader.cpp in Sources */, 31012E1518B97B9B0039062F /* CodeGen.cpp in Sources */, @@ -1204,7 +1261,7 @@ 5CC7D47219102621000B8C1F /* mathutil.cpp in Sources */, 5C1DBE071B0438D300235552 /* Renderbuffer.cpp in Sources */, 31012E3B18B97B9B0039062F /* InitializeParseContext.cpp in Sources */, - 5C1DBE051B0438D300235552 /* RefCountObject.cpp in Sources */, + 5C315D021CC5B6DA00776697 /* ExtensionGLSL.cpp in Sources */, 5CC7D47019102621000B8C1F /* event_tracer.cpp in Sources */, 5C1DBF371B0438D300235552 /* validationEGL.cpp in Sources */, 31012E3118B97B9B0039062F /* glslang_tab.cpp in Sources */, @@ -1220,6 +1277,7 @@ A264F8AE16974DED006FAA5A /* DirectiveHandlerBase.cpp in Sources */, 31012E4D18B97B9B0039062F /* OutputGLSL.cpp in Sources */, 31012E3018B97B9B0039062F /* glslang_lex.cpp in Sources */, + 5C315D001CC5B6DA00776697 /* DeferGlobalInitializers.cpp in Sources */, 5C1DBDE61B0438D300235552 /* Device.cpp in Sources */, 5C1DBDDF1B0438D300235552 /* Config.cpp in Sources */, 5C1DBDEA1B0438D300235552 /* Error.cpp in Sources */, @@ -1235,11 +1293,10 @@ 31012E6018B97B9B0039062F /* SearchSymbol.cpp in Sources */, 72309A58183C27F300370B93 /* ExpressionParser.cpp in Sources */, 31012E2818B97B9B0039062F /* DirectiveHandler.cpp in Sources */, - 31012E5918B97B9B0039062F /* QualifierAlive.cpp in Sources */, - 31012E7118B97B9B0039062F /* UnfoldShortCircuit.cpp in Sources */, 31012E6418B97B9B0039062F /* SymbolTable.cpp in Sources */, 5C1DBF351B0438D300235552 /* Uniform.cpp in Sources */, 5C1DBC261B04375F00235552 /* blocklayoutHLSL.cpp in Sources */, + 5C315D081CC5B6DA00776697 /* RemovePow.cpp in Sources */, A264F8B416974DED006FAA5A /* Input.cpp in Sources */, 5C1DBC301B04375F00235552 /* IntermNode.cpp in Sources */, 5CC7D47919102621000B8C1F /* utilities.cpp in Sources */, @@ -1262,7 +1319,6 @@ 5C1DBC411B04375F00235552 /* ShaderVars.cpp in Sources */, 5C1DBF331B0438D300235552 /* TransformFeedback.cpp in Sources */, 31012E3418B97B9B0039062F /* InfoSink.cpp in Sources */, - 31012E5318B97B9B0039062F /* parseConst.cpp in Sources */, 5C1DBC201B04375F00235552 /* ArrayReturnValueToOutParameter.cpp in Sources */, 31012E5618B97B9B0039062F /* PoolAlloc.cpp in Sources */, 31012E6618B97B9B0039062F /* RestrictFragmentShaderTiming.cpp in Sources */, @@ -1272,12 +1328,15 @@ 31012E7718B97B9B0039062F /* util.cpp in Sources */, 5C1DBDE21B0438D300235552 /* Context.cpp in Sources */, 31012E5118B97B9B0039062F /* OutputHLSL.cpp in Sources */, + 5C315D0C1CC5B6DA00776697 /* SeparateExpressionsReturningArrays.cpp in Sources */, 31012E3618B97B9B0039062F /* Initialize.cpp in Sources */, 5C1DBE011B0438D300235552 /* Query.cpp in Sources */, 5C1DBF391B0438D300235552 /* validationES.cpp in Sources */, 5C1DBDFF1B0438D300235552 /* Program.cpp in Sources */, + 5C315D041CC5B6DA00776697 /* RecordConstantPrecision.cpp in Sources */, 31012E7B18B97B9B0039062F /* VariableInfo.cpp in Sources */, 5C1DBF2B1B0438D300235552 /* State.cpp in Sources */, + 5C315D061CC5B6DA00776697 /* RemoveDynamicIndexing.cpp in Sources */, 5C1DBBF61B0436EC00235552 /* tls.cpp in Sources */, 5CC7D452191024E4000B8C1F /* LoopInfo.cpp in Sources */, 5C1DBC3F1B04375F00235552 /* SeparateDeclarations.cpp in Sources */, @@ -1285,15 +1344,16 @@ 31012E7D18B97B9B0039062F /* VariablePacker.cpp in Sources */, 5C1DBDF31B0438D300235552 /* Framebuffer.cpp in Sources */, 31012E1F18B97B9B0039062F /* DependencyGraphOutput.cpp in Sources */, + 5C315D121CC5B6DA00776697 /* ValidateMaxParameters.cpp in Sources */, 5C1DBDD81B0438D300235552 /* Buffer.cpp in Sources */, 5C1DBDD31B0438D300235552 /* angletypes.cpp in Sources */, 5C1DBF251B0438D300235552 /* ResourceManager.cpp in Sources */, 31012E4B18B97B9B0039062F /* OutputESSL.cpp in Sources */, A264F8BE16974DED006FAA5A /* Preprocessor.cpp in Sources */, + 5C315CFE1CC5B6DA00776697 /* Cache.cpp in Sources */, 5C1DBDEE1B0438D300235552 /* Fence.cpp in Sources */, 5CC7D457191024E4000B8C1F /* ValidateOutputs.cpp in Sources */, 5C1DBBF01B0436EC00235552 /* angleutils.cpp in Sources */, - 5C1DBC421B04375F00235552 /* SimplifyArrayAssignment.cpp in Sources */, 31012E2B18B97B9B0039062F /* ForLoopUnroll.cpp in Sources */, 5C1DBC3D1B04375F00235552 /* SeparateArrayInitialization.cpp in Sources */, 5C9FFF4E19102A000025B8FA /* FlagStd140Structs.cpp in Sources */, @@ -1325,6 +1385,10 @@ isa = XCBuildConfiguration; baseConfigurationReference = 5D7C59C51208C68B001C873E /* ANGLE.xcconfig */; buildSettings = { + GCC_PREPROCESSOR_DEFINITIONS = ( + ANGLE_ENABLE_OPENGL, + ANGLE_ENABLE_GLSL, + ); }; name = Production; }; @@ -1347,6 +1411,10 @@ isa = XCBuildConfiguration; baseConfigurationReference = 5D7C59C51208C68B001C873E /* ANGLE.xcconfig */; buildSettings = { + GCC_PREPROCESSOR_DEFINITIONS = ( + ANGLE_ENABLE_OPENGL, + ANGLE_ENABLE_GLSL, + ); }; name = Debug; }; @@ -1354,6 +1422,10 @@ isa = XCBuildConfiguration; baseConfigurationReference = 5D7C59C51208C68B001C873E /* ANGLE.xcconfig */; buildSettings = { + GCC_PREPROCESSOR_DEFINITIONS = ( + ANGLE_ENABLE_OPENGL, + ANGLE_ENABLE_GLSL, + ); }; name = Release; }; diff --git a/Source/ThirdParty/ANGLE/AUTHORS b/Source/ThirdParty/ANGLE/AUTHORS index 836bed8e8ab7..3a6739f14961 100644 --- a/Source/ThirdParty/ANGLE/AUTHORS +++ b/Source/ThirdParty/ANGLE/AUTHORS @@ -26,6 +26,7 @@ Microsoft Open Technologies, Inc. NVIDIA Corporation Opera Software ASA The Qt Company Ltd. +Advanced Micro Devices, Inc. Jacek Caban Mark Callow @@ -41,3 +42,5 @@ Aitor Moreno Yuri O'Donnell Josh Soref Maks Naumov +Jinyoung Hur +Sebastian Bergstein diff --git a/Source/ThirdParty/ANGLE/BUILD.gn b/Source/ThirdParty/ANGLE/BUILD.gn index 58c10534ae7c..d2c0839fe916 100644 --- a/Source/ThirdParty/ANGLE/BUILD.gn +++ b/Source/ThirdParty/ANGLE/BUILD.gn @@ -1,25 +1,34 @@ -# Copyright 2014 The Chromium Authors. All rights reserved. +# Copyright 2014-2015 The Chromium 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_gypi = exec_script( - "//build/gypi_to_gn.py", - [ rebase_path("src/libGLESv2.gypi") ], - "scope", - [ "src/libGLESv2.gypi" ]) +# import the use_x11 variable +import("//build/config/ui.gni") +import("//third_party/angle/build/angle_common.gni") -compiler_gypi = exec_script( - "//build/gypi_to_gn.py", - [ rebase_path("src/compiler.gypi") ], - "scope", - [ "src/compiler.gypi" ]) +angle_git_is_present = exec_script("src/commit_id.py", + [ + "check", + rebase_path(".", root_build_dir), + ], + "value") + +angle_use_commit_id = angle_git_is_present == 1 + +gles_gypi = exec_script("//build/gypi_to_gn.py", + [ rebase_path("src/libGLESv2.gypi") ], + "scope", + [ "src/libGLESv2.gypi" ]) + +compiler_gypi = exec_script("//build/gypi_to_gn.py", + [ rebase_path("src/compiler.gypi") ], + "scope", + [ "src/compiler.gypi" ]) # This config is exported to dependent targets (and also applied to internal # ones). config("external_config") { - include_dirs = [ - "include", - ] + include_dirs = [ "include" ] } # This config is applied to internal Angle targets (not pushed to dependents). @@ -30,27 +39,15 @@ config("internal_config") { ] } -angle_enable_d3d9 = false -angle_enable_d3d11 = false -angle_enable_gl = false - if (is_win) { - angle_enable_d3d9 = true - angle_enable_d3d11 = true - angle_enable_gl = true - - import("//build/config/win/visual_studio_version.gni") copy("copy_compiler_dll") { - sources = [ "$windows_sdk_path/Redist/D3D/$target_cpu/d3dcompiler_47.dll" ] - outputs = [ "$root_build_dir/d3dcompiler_47.dll" ] + sources = [ + "$windows_sdk_path/Redist/D3D/$target_cpu/d3dcompiler_47.dll", + ] + outputs = [ + "$root_out_dir/d3dcompiler_47.dll", + ] } - -} # is_win - -angle_enable_hlsl = false - -if (angle_enable_d3d9 || angle_enable_d3d11) { - angle_enable_hlsl = true } component("translator") { @@ -61,11 +58,6 @@ component("translator") { defines = [ "ANGLE_TRANSLATOR_IMPLEMENTATION" ] - if (angle_enable_hlsl) { - sources += rebase_path(compiler_gypi.angle_translator_lib_hlsl_sources, ".", "src") - defines += [ "ANGLE_ENABLE_HLSL" ] - } - configs -= [ "//build/config/compiler:chromium_code" ] configs += [ ":internal_config", @@ -87,7 +79,8 @@ source_set("includes") { "include/GLES2/gl2ext.h", "include/GLES2/gl2platform.h", "include/GLES3/gl3.h", - "include/GLES3/gl3ext.h", + "include/GLES3/gl31.h", + "include/GLES3/gl32.h", "include/GLES3/gl3platform.h", "include/GLSLANG/ShaderLang.h", "include/KHR/khrplatform.h", @@ -108,20 +101,45 @@ config("translator_static_config") { defines = [ "ANGLE_TRANSLATOR_STATIC" ] } +config("debug_annotations_config") { + if (is_debug) { + defines = [ "ANGLE_ENABLE_DEBUG_ANNOTATIONS" ] + } +} + static_library("angle_common") { sources = rebase_path(gles_gypi.libangle_common_sources, ".", "src") + configs -= [ "//build/config/compiler:chromium_code" ] configs += [ ":internal_config", + ":debug_annotations_config", + "//build/config/compiler:no_chromium_code", ] + + public_deps = [ ":commit_id" ] } static_library("translator_lib") { sources = rebase_path(compiler_gypi.angle_translator_lib_sources, ".", "src") + defines = [] + + if (angle_enable_essl) { + sources += + rebase_path(compiler_gypi.angle_translator_lib_essl_sources, ".", "src") + defines += [ "ANGLE_ENABLE_ESSL" ] + } + + if (angle_enable_glsl) { + sources += + rebase_path(compiler_gypi.angle_translator_lib_glsl_sources, ".", "src") + defines += [ "ANGLE_ENABLE_GLSL" ] + } if (angle_enable_hlsl) { - sources += rebase_path(compiler_gypi.angle_translator_lib_hlsl_sources, ".", "src") - defines = [ "ANGLE_ENABLE_HLSL" ] + sources += + rebase_path(compiler_gypi.angle_translator_lib_hlsl_sources, ".", "src") + defines += [ "ANGLE_ENABLE_HLSL" ] } configs -= [ "//build/config/compiler:chromium_code" ] configs += [ @@ -167,19 +185,32 @@ config("commit_id_config") { include_dirs = [ "$root_gen_dir/angle" ] } -action("commit_id") { - script = "src/commit_id.py" - - output_file = "$root_gen_dir/angle/id/commit.h" - outputs = [ output_file ] +commit_id_output_file = "$root_gen_dir/angle/id/commit.h" +if (angle_use_commit_id) { + action("commit_id") { + script = "src/commit_id.py" + outputs = [ + commit_id_output_file, + ] - args = [ - "gen", - rebase_path(".", root_build_dir), - rebase_path(output_file, root_build_dir), - ] + args = [ + "gen", + rebase_path(".", root_build_dir), + rebase_path(commit_id_output_file, root_build_dir), + ] - public_configs = [ ":commit_id_config" ] + public_configs = [ ":commit_id_config" ] + } +} else { + copy("commit_id") { + sources = [ + "src/commit.h", + ] + outputs = [ + commit_id_output_file, + ] + public_configs = [ ":commit_id_config" ] + } } config("libANGLE_config") { @@ -194,11 +225,25 @@ config("libANGLE_config") { if (angle_enable_gl) { defines += [ "ANGLE_ENABLE_OPENGL" ] } + if (use_x11) { + defines += [ "ANGLE_USE_X11" ] + } defines += [ - "GL_APICALL=", - "GL_GLEXT_PROTOTYPES=", - "EGLAPI=", + "GL_GLEXT_PROTOTYPES", + "EGL_EGLEXT_PROTOTYPES", ] + + if (is_win) { + defines += [ + "GL_APICALL=", + "EGLAPI=", + ] + } else { + defines += [ + "GL_APICALL=__attribute__((visibility(\"default\")))", + "EGLAPI=__attribute__((visibility(\"default\")))", + ] + } if (is_win) { cflags += [ "/wd4530" ] # C++ exception handler used, but unwind semantics are not enabled. } @@ -209,18 +254,20 @@ static_library("libANGLE") { include_dirs = [] libs = [] - defines = [ - "LIBANGLE_IMPLEMENTATION", + defines = [ "LIBANGLE_IMPLEMENTATION" ] + + deps = [ + ":angle_common", + ":commit_id", + ":includes", + ":translator_static", ] # Shared D3D sources. if (angle_enable_d3d9 || angle_enable_d3d11) { sources += rebase_path(gles_gypi.libangle_d3d_shared_sources, ".", "src") - defines += [ - "ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ " + - "\"d3dcompiler_47.dll\", \"d3dcompiler_46.dll\", \"d3dcompiler_43.dll\" }", - ] + defines += [ "ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ " + "\"d3dcompiler_47.dll\", \"d3dcompiler_46.dll\", \"d3dcompiler_43.dll\" }" ] } if (angle_enable_d3d9) { @@ -241,30 +288,32 @@ static_library("libANGLE") { if (is_win) { sources += rebase_path(gles_gypi.libangle_gl_wgl_sources, ".", "src") } + if (use_x11) { + sources += rebase_path(gles_gypi.libangle_gl_glx_sources, ".", "src") + deps += [ + "src/third_party/libXNVCtrl:libXNVCtrl" + ] + libs += [ + "X11", + "Xi", + "Xext", + ] + } } if (is_debug) { - defines += [ - "ANGLE_GENERATE_SHADER_DEBUG_INFO", - "ANGLE_ENABLE_DEBUG_ANNOTATIONS", - ] + defines += [ "ANGLE_GENERATE_SHADER_DEBUG_INFO" ] } configs -= [ "//build/config/compiler:chromium_code" ] configs += [ ":commit_id_config", + ":debug_annotations_config", ":libANGLE_config", ":internal_config", "//build/config/compiler:no_chromium_code", ] - deps = [ - ":commit_id", - ":includes", - ":translator_static", - ":angle_common", - ] - if (is_win) { deps += [ ":copy_compiler_dll" ] } @@ -274,21 +323,20 @@ shared_library("libGLESv2") { sources = rebase_path(gles_gypi.libglesv2_sources, ".", "src") if (is_win) { - ldflags = [ "/DEF:" + - rebase_path("src/libGLESv2/libGLESv2.def", root_build_dir) ] + ldflags = + [ "/DEF:" + rebase_path("src/libGLESv2/libGLESv2.def", root_build_dir) ] } configs -= [ "//build/config/compiler:chromium_code" ] configs += [ ":internal_config", ":commit_id_config", + ":debug_annotations_config", ":libANGLE_config", "//build/config/compiler:no_chromium_code", ] - defines = [ - "LIBGLESV2_IMPLEMENTATION", - ] + defines = [ "LIBGLESV2_IMPLEMENTATION" ] deps = [ ":includes", @@ -300,24 +348,73 @@ shared_library("libEGL") { sources = rebase_path(gles_gypi.libegl_sources, ".", "src") if (is_win) { - ldflags = [ "/DEF:" + - rebase_path("src/libEGL/libEGL.def", root_build_dir) ] + ldflags = [ "/DEF:" + rebase_path("src/libEGL/libEGL.def", root_build_dir) ] } configs -= [ "//build/config/compiler:chromium_code" ] configs += [ ":internal_config", ":commit_id_config", + ":debug_annotations_config", ":libANGLE_config", "//build/config/compiler:no_chromium_code", ] + defines = [ "LIBEGL_IMPLEMENTATION" ] + + deps = [ + ":includes", + ":libGLESv2", + ] +} + +util_gypi = exec_script("//build/gypi_to_gn.py", + [ rebase_path("util/util.gyp") ], + "scope", + [ "util/util.gyp" ]) + +config("angle_util_config") { + include_dirs = [ "util" ] + if (is_linux) { + libs = [ "X11" ] + } +} + +static_library("angle_util") { + sources = rebase_path(util_gypi.util_sources, ".", "util") + + if (is_win) { + sources += rebase_path(util_gypi.util_win32_sources, ".", "util") + } + + if (is_linux) { + sources += rebase_path(util_gypi.util_linux_sources, ".", "util") + libs = [ "rt" ] + } + + if (is_mac) { + sources += rebase_path(util_gypi.util_osx_sources, ".", "util") + } + + if (use_x11) { + sources += rebase_path(util_gypi.util_x11_sources, ".", "util") + } + defines = [ - "LIBEGL_IMPLEMENTATION", + "GL_GLEXT_PROTOTYPES", + "EGL_EGLEXT_PROTOTYPES", + ] + + configs += [ ":debug_annotations_config" ] + + public_configs = [ + ":angle_util_config", + ":internal_config", ] deps = [ - ":includes", + ":angle_common", + ":libEGL", ":libGLESv2", ] } diff --git a/Source/ThirdParty/ANGLE/CMakeLists.txt b/Source/ThirdParty/ANGLE/CMakeLists.txt index cbcc912d71ca..a745e14ec4e8 100644 --- a/Source/ThirdParty/ANGLE/CMakeLists.txt +++ b/Source/ThirdParty/ANGLE/CMakeLists.txt @@ -74,7 +74,6 @@ add_library(libANGLE STATIC src/compiler/translator/SearchSymbol.cpp src/compiler/translator/TranslatorESSL.cpp src/compiler/translator/TranslatorGLSL.cpp - src/compiler/translator/UnfoldShortCircuit.cpp src/compiler/translator/VersionGLSL.cpp src/compiler/translator/ASTMetadataHLSL.cpp src/compiler/translator/blocklayoutHLSL.cpp @@ -89,9 +88,11 @@ add_library(libANGLE STATIC src/compiler/translator/ArrayReturnValueToOutParameter.cpp src/compiler/translator/blocklayout.cpp src/compiler/translator/BuiltInFunctionEmulator.cpp + src/compiler/translator/Cache.cpp src/compiler/translator/CallDAG.cpp src/compiler/translator/CodeGen.cpp src/compiler/translator/Compiler.cpp + src/compiler/translator/DeferGlobalInitializers.cpp src/compiler/translator/Diagnostics.cpp src/compiler/translator/DirectiveHandler.cpp src/compiler/translator/EmulatePrecision.cpp @@ -108,27 +109,31 @@ add_library(libANGLE STATIC src/compiler/translator/IntermTraverse.cpp src/compiler/translator/LoopInfo.cpp src/compiler/translator/Operator.cpp - src/compiler/translator/parseConst.cpp src/compiler/translator/ParseContext.cpp src/compiler/translator/PoolAlloc.cpp src/compiler/translator/PruneEmptyDeclarations.cpp - src/compiler/translator/QualifierAlive.cpp src/compiler/translator/RegenerateStructNames.cpp + src/compiler/translator/RemoveDynamicIndexing.cpp + src/compiler/translator/RemovePow.cpp src/compiler/translator/RemoveSwitchFallThrough.cpp + src/compiler/translator/RewriteDoWhile.cpp src/compiler/translator/RewriteElseBlocks.cpp src/compiler/translator/ScalarizeVecAndMatConstructorArgs.cpp src/compiler/translator/SearchSymbol.cpp src/compiler/translator/SeparateArrayInitialization.cpp src/compiler/translator/SeparateDeclarations.cpp + src/compiler/translator/SeparateExpressionsReturningArrays.cpp src/compiler/translator/ShaderLang.cpp src/compiler/translator/ShaderVars.cpp - src/compiler/translator/SimplifyArrayAssignment.cpp src/compiler/translator/SymbolTable.cpp src/compiler/translator/Types.cpp src/compiler/translator/UnfoldShortCircuit.cpp src/compiler/translator/UnfoldShortCircuitAST.cpp + src/compiler/translator/UnfoldShortCircuitToIf.cpp src/compiler/translator/util.cpp + src/compiler/translator/ValidateGlobalInitializer.cpp src/compiler/translator/ValidateLimitations.cpp + src/compiler/translator/ValidateMaxParameters.cpp src/compiler/translator/ValidateOutputs.cpp src/compiler/translator/ValidateSwitch.cpp src/compiler/translator/VariableInfo.cpp @@ -150,6 +155,7 @@ add_library(libANGLE STATIC src/libANGLE/Config.cpp src/libANGLE/Context.cpp src/libANGLE/Data.cpp + src/libANGLE/Debug.cpp src/libANGLE/Device.cpp src/libANGLE/Display.cpp src/libANGLE/Error.cpp @@ -159,6 +165,8 @@ add_library(libANGLE STATIC src/libANGLE/Framebuffer.cpp src/libANGLE/FramebufferAttachment.cpp src/libANGLE/HandleAllocator.cpp + src/libANGLE/IndexRangeCache.cpp + src/libANGLE/Image.cpp src/libANGLE/ImageIndex.cpp src/libANGLE/Platform.cpp src/libANGLE/Program.cpp @@ -166,8 +174,10 @@ add_library(libANGLE STATIC src/libANGLE/queryconversions.cpp src/libANGLE/RefCountObject.cpp src/libANGLE/Renderbuffer.cpp + src/libANGLE/Stream.cpp src/libANGLE/renderer/d3d/BufferD3D.cpp src/libANGLE/renderer/d3d/CompilerD3D.cpp + src/libANGLE/renderer/d3d/EGLImageD3D.cpp src/libANGLE/renderer/d3d/copyimage.cpp src/libANGLE/renderer/d3d/d3d11/Blit11.cpp src/libANGLE/renderer/d3d/d3d11/Buffer11.cpp @@ -185,11 +195,18 @@ add_library(libANGLE STATIC src/libANGLE/renderer/d3d/d3d11/renderer11_utils.cpp src/libANGLE/renderer/d3d/d3d11/RenderStateCache.cpp src/libANGLE/renderer/d3d/d3d11/RenderTarget11.cpp + src/libANGLE/renderer/d3d/d3d11/StateManager11.cpp + src/libANGLE/renderer/d3d/d3d11/Stream11.cpp src/libANGLE/renderer/d3d/d3d11/ShaderExecutable11.cpp src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp src/libANGLE/renderer/d3d/d3d11/TextureStorage11.cpp src/libANGLE/renderer/d3d/d3d11/Trim11.cpp + src/libANGLE/renderer/d3d/d3d11/VertexArray11.cpp src/libANGLE/renderer/d3d/d3d11/VertexBuffer11.cpp + src/libANGLE/renderer/d3d/d3d11/dxgi_support_table.cpp + src/libANGLE/renderer/d3d/d3d11/loadimage_etc.cpp + src/libANGLE/renderer/d3d/d3d11/load_functions_table_autogen.cpp + src/libANGLE/renderer/d3d/d3d11/texture_format_table_autogen.cpp src/libANGLE/renderer/d3d/d3d11/win32/NativeWindow.cpp src/libANGLE/renderer/d3d/d3d9/Blit9.cpp src/libANGLE/renderer/d3d/d3d9/Buffer9.cpp @@ -204,6 +221,7 @@ add_library(libANGLE STATIC src/libANGLE/renderer/d3d/d3d9/renderer9_utils.cpp src/libANGLE/renderer/d3d/d3d9/RenderTarget9.cpp src/libANGLE/renderer/d3d/d3d9/ShaderExecutable9.cpp + src/libANGLE/renderer/d3d/d3d9/StateManager9.cpp src/libANGLE/renderer/d3d/d3d9/SwapChain9.cpp src/libANGLE/renderer/d3d/d3d9/TextureStorage9.cpp src/libANGLE/renderer/d3d/d3d9/VertexBuffer9.cpp @@ -227,15 +245,12 @@ add_library(libANGLE STATIC src/libANGLE/renderer/d3d/ShaderExecutableD3D.cpp src/libANGLE/renderer/d3d/SurfaceD3D.cpp src/libANGLE/renderer/d3d/TextureD3D.cpp - src/libANGLE/renderer/d3d/TextureStorage.cpp src/libANGLE/renderer/d3d/TransformFeedbackD3D.cpp + src/libANGLE/renderer/d3d/VaryingPacking.cpp src/libANGLE/renderer/d3d/VertexBuffer.cpp src/libANGLE/renderer/d3d/VertexDataManager.cpp src/libANGLE/renderer/DeviceImpl.cpp src/libANGLE/renderer/DisplayImpl.cpp - src/libANGLE/renderer/IndexRangeCache.cpp - src/libANGLE/renderer/ProgramImpl.cpp - src/libANGLE/renderer/RenderbufferImpl.cpp src/libANGLE/renderer/Renderer.cpp src/libANGLE/renderer/SurfaceImpl.cpp src/libANGLE/ResourceManager.cpp diff --git a/Source/ThirdParty/ANGLE/CONTRIBUTORS b/Source/ThirdParty/ANGLE/CONTRIBUTORS index faba0afb2ec1..bd394b5e4fcc 100644 --- a/Source/ThirdParty/ANGLE/CONTRIBUTORS +++ b/Source/ThirdParty/ANGLE/CONTRIBUTORS @@ -1,104 +1,111 @@ -# This is the official list of people who can contribute -# (and who have contributed) code to the ANGLE project -# repository. -# The AUTHORS file lists the copyright holders; this file -# lists people. For example, Google employees are listed here -# but not in AUTHORS, because Google holds the copyright. -# - -TransGaming Inc. - Nicolas Capens - Daniel Koch - Geoff Lang - Andrew Lewycky - Jamie Madill - Gavriel State - Shannon Woods - -Google Inc. - Brent Austin - Michael Bai - John Bauman - Peter Beverloo - Steve Block - Rachel Blum - Eric Boren - Henry Bridge - Nat Duca - Peter Kasting - Vangelis Kokkevis - Zhenyao Mo - Daniel Nicoara - Alastair Patrick - Alok Priyadarshi - Kenneth Russell - Brian Salomon - Gregg Tavares - Jeff Timanus - Ben Vanik - Adrienne Walker - thestig@chromium.org - Justin Schuh - Scott Graham - Corentin Wallez - -Adobe Systems Inc. - Alexandru Chiculita - Steve Minns - Max Vujovic - -Autodesk, Inc. - Ranger Harke - -Cloud Party, Inc. - Conor Dickinson - -The Qt Company Ltd. - Andrew Knight - -Imagination Technologies Ltd. - Gregoire Payen de La Garanderie - -Intel Corporation - Jin Yang - Andy Chen - Josh Triplett - Sudarsana Nagineni - -Klarälvdalens Datakonsult AB - Milian Wolff - -Mozilla Corp. - Ehsan Akhgari - Jeff Gilbert - Mike Hommey - Benoit Jacob - Makoto Kato - Vladimir Vukicevic - -Turbulenz - Michael Braithwaite - -Ulrik Persson (ddefrostt) -Mark Banner (standard8mbp) -David Kilzer -Jacek Caban -Tibor den Ouden -Régis Fénéon - -Microsoft Corporation - Cooper Partin - Austin Kinross - Minmin Gong - -Microsoft Open Technologies, Inc. - Cooper Partin - Austin Kinross - -NVIDIA Corporation - Olli Etuaho - Arun Patole - Qingqing Deng - -Opera Software ASA - Daniel Bratell +# This is the official list of people who can contribute +# (and who have contributed) code to the ANGLE project +# repository. +# The AUTHORS file lists the copyright holders; this file +# lists people. For example, Google employees are listed here +# but not in AUTHORS, because Google holds the copyright. +# + +TransGaming Inc. + Nicolas Capens + Daniel Koch + Geoff Lang + Andrew Lewycky + Jamie Madill + Gavriel State + Shannon Woods + +Google Inc. + Brent Austin + Michael Bai + John Bauman + Peter Beverloo + Steve Block + Rachel Blum + Eric Boren + Henry Bridge + Nat Duca + Peter Kasting + Vangelis Kokkevis + Zhenyao Mo + Daniel Nicoara + Alastair Patrick + Alok Priyadarshi + Kenneth Russell + Brian Salomon + Gregg Tavares + Jeff Timanus + Ben Vanik + Adrienne Walker + thestig@chromium.org + Justin Schuh + Scott Graham + Corentin Wallez + +Adobe Systems Inc. + Alexandru Chiculita + Steve Minns + Max Vujovic + +Autodesk, Inc. + Ranger Harke + +Cloud Party, Inc. + Conor Dickinson + +The Qt Company Ltd. + Andrew Knight + +Imagination Technologies Ltd. + Gregoire Payen de La Garanderie + +Intel Corporation + Jin Yang + Andy Chen + Josh Triplett + Sudarsana Nagineni + +Klarälvdalens Datakonsult AB + Milian Wolff + +Mozilla Corp. + Ehsan Akhgari + Jeff Gilbert + Mike Hommey + Benoit Jacob + Makoto Kato + Vladimir Vukicevic + +Turbulenz + Michael Braithwaite + +Ulrik Persson (ddefrostt) +Mark Banner (standard8mbp) +David Kilzer +Jacek Caban +Tibor den Ouden +Régis Fénéon +Sebastian Bergstein + +Microsoft Corporation + Cooper Partin + Austin Kinross + Minmin Gong + Shawn Hargreaves + +Microsoft Open Technologies, Inc. + Cooper Partin + Austin Kinross + +NVIDIA Corporation + Olli Etuaho + Arun Patole + Qingqing Deng + Kimmo Kinnunen + +Opera Software ASA + Daniel Bratell + Tomasz Moniuszko + +Advanced Micro Devices, Inc. + Russ Lind diff --git a/Source/ThirdParty/ANGLE/ChangeLog b/Source/ThirdParty/ANGLE/ChangeLog index fd209e945078..161558c08945 100644 --- a/Source/ThirdParty/ANGLE/ChangeLog +++ b/Source/ThirdParty/ANGLE/ChangeLog @@ -1,3 +1,12 @@ +2016-04-19 Alex Christensen + + Update ANGLE + https://bugs.webkit.org/show_bug.cgi?id=156755 + + Reviewed by Dean Jackson. + + Huge list of changed files omitted. + 2016-04-12 Alex Christensen Remove failing assertion in ANGLE diff --git a/Source/ThirdParty/ANGLE/DEPS b/Source/ThirdParty/ANGLE/DEPS index ffad7b86fb09..056d764f8dba 100644 --- a/Source/ThirdParty/ANGLE/DEPS +++ b/Source/ThirdParty/ANGLE/DEPS @@ -1,26 +1,105 @@ +vars = { + 'chromium_git': 'https://chromium.googlesource.com', +} + deps = { "third_party/gyp": - "http://gyp.googlecode.com/svn/trunk@1987", + Var('chromium_git') + "/external/gyp@81c2e5ff92af29bab61c982808076ddce3d200a2", # TODO(kbr): figure out how to better stay in sync with Chromium's # versions of googletest and googlemock. "src/tests/third_party/googletest": - "http://googletest.googlecode.com/svn/trunk@629", + Var('chromium_git') + "/external/googletest.git@9855a87157778d39b95eccfb201a9dc90f6d61c6", "src/tests/third_party/googlemock": - "http://googlemock.googlecode.com/svn/trunk@410", + Var('chromium_git') + "/external/googlemock.git@b2cb211e49d872101d991201362d7b97d7d69910", - "src/tests/third_party/deqp": - "https://android.googlesource.com/platform/external/deqp@c7661bcd3bcec04b1abf6c3b290c4150db565604", + # Cherry is a dEQP management GUI written in Go. We use it for viewing test results. + "third_party/cherry": + "https://android.googlesource.com/platform/external/cherry@af6c09fe05115f0cca61ae23ee871bda27cf1ff5", - "src/tests/third_party/libpng": + "third_party/deqp/src": + "https://android.googlesource.com/platform/external/deqp@cc0ded6c77267bbb14d21aac358fc5d9690c07f8", + + "third_party/libpng": "https://android.googlesource.com/platform/external/libpng@094e181e79a3d6c23fd005679025058b7df1ad6c", - "src/tests/third_party/zlib": - "https://chromium.googlesource.com/chromium/src/third_party/zlib@afd8c4593c010c045902f6c0501718f1823064a3", + "third_party/zlib": + Var('chromium_git') + "/chromium/src/third_party/zlib@afd8c4593c010c045902f6c0501718f1823064a3", + + "buildtools": + Var('chromium_git') + '/chromium/buildtools.git@125d157607de4d7c95bf8b02dd580aae17962f19', } hooks = [ + # Pull clang-format binaries using checked-in hashes. + { + 'name': 'clang_format_win', + 'pattern': '.', + 'action': [ 'download_from_google_storage', + '--no_resume', + '--platform=win32', + '--no_auth', + '--bucket', 'chromium-clang-format', + '-s', 'buildtools/win/clang-format.exe.sha1', + ], + }, + { + 'name': 'clang_format_mac', + 'pattern': '.', + 'action': [ 'download_from_google_storage', + '--no_resume', + '--platform=darwin', + '--no_auth', + '--bucket', 'chromium-clang-format', + '-s', 'buildtools/mac/clang-format.sha1', + ], + }, + { + 'name': 'clang_format_linux', + 'pattern': '.', + 'action': [ 'download_from_google_storage', + '--no_resume', + '--platform=linux*', + '--no_auth', + '--bucket', 'chromium-clang-format', + '-s', 'buildtools/linux64/clang-format.sha1', + ], + }, + # Pull GN binaries using checked-in hashes. + { + 'name': 'gn_win', + 'pattern': '.', + 'action': [ 'download_from_google_storage', + '--no_resume', + '--platform=win32', + '--no_auth', + '--bucket', 'chromium-gn', + '-s', 'buildtools/win/gn.exe.sha1', + ], + }, + { + 'name': 'gn_mac', + 'pattern': '.', + 'action': [ 'download_from_google_storage', + '--no_resume', + '--platform=darwin', + '--no_auth', + '--bucket', 'chromium-gn', + '-s', 'buildtools/mac/gn.sha1', + ], + }, + { + 'name': 'gn_linux64', + 'pattern': '.', + 'action': [ 'download_from_google_storage', + '--no_resume', + '--platform=linux*', + '--no_auth', + '--bucket', 'chromium-gn', + '-s', 'buildtools/linux64/gn.sha1', + ], + }, { # A change to a .gyp, .gypi, or to GYP itself should run the generator. "pattern": ".", diff --git a/Source/ThirdParty/ANGLE/README.md b/Source/ThirdParty/ANGLE/README.md index e20ae0573861..632b4163481a 100644 --- a/Source/ThirdParty/ANGLE/README.md +++ b/Source/ThirdParty/ANGLE/README.md @@ -1,22 +1,44 @@ #ANGLE -The goal of ANGLE is to allow Windows users to seamlessly run WebGL and other OpenGL ES content by translating OpenGL ES API calls to DirectX 9 or DirectX 11 API calls. +The goal of ANGLE is to allow users of multiple operating systems to seamlessly run WebGL and other OpenGL ES content by translating OpenGL ES API calls to one of the hardware-supported APIs available for that platform. ANGLE currently provides translation from OpenGL ES 2.0 to desktop OpenGL, Direct3D 9, and Direct3D 11. Support for translation from OpenGL ES 3.0 to all of these APIs is nearing completion, and future plans include enabling validated ES-to-ES support. -ANGLE is a conformant implementation of the OpenGL ES 2.0 specification that is hardware‐accelerated via Direct3D. ANGLE v1.0.772 was certified compliant by passing the ES 2.0.3 conformance tests in October 2011. ANGLE also provides an implementation of the EGL 1.4 specification. Work on ANGLE's OpenGL ES 3.0 implementation is currently in progress, but should not be considered stable. +| | Direct3D 9 | Direct3D 11 | Desktop GL | GL ES | +|----------------|:-------------:|:-------------------:|:------------------:|:---------:| +| OpenGL ES 2.0 | complete | complete | complete | planned | +| OpenGL ES 3.0 | | nearing completion | nearing completion | planned | +[Level of OpenGL ES support via backing renderers] + + +| | Direct3D 9 | Direct3D 11 | Desktop GL | +|------------:|:--------------:|:--------------:|:-------------:| +| Windows | * | * | * | +| Linux | | | * | +| Mac OS X | | | in progress | +[Platform support via backing renderers] + +ANGLE v1.0.772 was certified compliant by passing the ES 2.0.3 conformance tests in October 2011. ANGLE also provides an implementation of the EGL 1.4 specification. ANGLE is used as the default WebGL backend for both Google Chrome and Mozilla Firefox on Windows platforms. Chrome uses ANGLE for all graphics rendering on Windows, including the accelerated Canvas2D implementation and the Native Client sandbox environment. Portions of the ANGLE shader compiler are used as a shader validator and translator by WebGL implementations across multiple platforms. It is used on Mac OS X, Linux, and in mobile variants of the browsers. Having one shader validator helps to ensure that a consistent set of GLSL ES shaders are accepted across browsers and platforms. The shader translator can be used to translate shaders to other shading languages, and to optionally apply shader modifications to work around bugs or quirks in the native graphics drivers. The translator targets Desktop GLSL, Direct3D HLSL, and even ESSL for native GLES2 platforms. +##Browsing +Browse ANGLE's source in the [repository](https://chromium.googlesource.com/angle/angle) + ##Building -For building instructions, visit the [dev setup wiki](https://code.google.com/p/angleproject/wiki/DevSetup). +View the [Dev setup instructions](doc/DevSetup.md). For generating a Windows Store version of ANGLE view the [Windows Store instructions](doc/BuildingAngleForWindowsStore.md) ##Contributing * Join our [Google group](https://groups.google.com/group/angleproject) to keep up to date. * Join us on IRC in the #ANGLEproject channel on FreeNode. -* Read about ANGLE development on the [wiki](http://code.google.com/p/angleproject/w/list). -* Become a [code contributor](https://code.google.com/p/angleproject/wiki/ContributingCode). +* Read about ANGLE development in our [documentation](doc). +* Become a [code contributor](doc/ContributingCode.md). +* Refer to ANGLE's [coding standard](doc/CodingStandard.md). +* Learn how to [build ANGLE for Chromium development](doc/BuildingAngleForChromiumDevelopment.md). +* [Choose an ANGLE branch](doc/ChoosingANGLEBranch.md) to track in your own project. * File bugs in the [issue tracker](http://code.google.com/p/angleproject/issues/list) (preferably with an isolated test-case). * Read about WebGL on the [Khronos WebGL Wiki](http://khronos.org/webgl/wiki/Main_Page). -* Learn about implementation details in the [OpenGL Insights chapter on ANGLE](http://www.seas.upenn.edu/~pcozzi/OpenGLInsights/OpenGLInsights-ANGLE.pdf) and this [ANGLE presentation](https://code.google.com/p/angleproject/downloads/detail?name=ANGLE%20and%20Cross-Platform%20WebGL%20Support.pdf&can=2&q=). +* Learn about implementation details in the [OpenGL Insights chapter on ANGLE](http://www.seas.upenn.edu/~pcozzi/OpenGLInsights/OpenGLInsights-ANGLE.pdf) and this [ANGLE presentation](https://drive.google.com/file/d/0Bw29oYeC09QbbHoxNE5EUFh0RGs/view?usp=sharing). * Learn about the past, present, and future of the ANGLE implementation in [this recent presentation](https://docs.google.com/presentation/d/1CucIsdGVDmdTWRUbg68IxLE5jXwCb2y1E9YVhQo0thg/pub?start=false&loop=false). -* If you use ANGLE in your own project, we'd love to hear about it! \ No newline at end of file +* Notes on [debugging ANGLE](doc/DebuggingTips.md). +* If you use ANGLE in your own project, we'd love to hear about it! + diff --git a/Source/ThirdParty/ANGLE/angle.isolate b/Source/ThirdParty/ANGLE/angle.isolate index 6ba275216f2c..a0e8e260d2ea 100644 --- a/Source/ThirdParty/ANGLE/angle.isolate +++ b/Source/ThirdParty/ANGLE/angle.isolate @@ -1,6 +1,9 @@ # 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. + +# This isolate expresses the Chromium project's default runtime +# dependencies. { 'conditions': [ ['OS=="win"', { diff --git a/Source/ThirdParty/ANGLE/changes.diff b/Source/ThirdParty/ANGLE/changes.diff index 94227bd8f569..4328a00a99ab 100644 --- a/Source/ThirdParty/ANGLE/changes.diff +++ b/Source/ThirdParty/ANGLE/changes.diff @@ -1,5 +1,5 @@ diff --git a/include/GLSLANG/ShaderLang.h b/include/GLSLANG/ShaderLang.h -index e750e32..7d3f415 100644 +index 78f8ef6..b7fdf55 100644 --- a/include/GLSLANG/ShaderLang.h +++ b/include/GLSLANG/ShaderLang.h @@ -25,7 +25,7 @@ @@ -11,21 +11,17 @@ index e750e32..7d3f415 100644 #include #include -diff --git a/src/common/mathutil.h b/src/common/mathutil.h -index 9f5c9fd..7959da8 100644 ---- a/src/common/mathutil.h -+++ b/src/common/mathutil.h -@@ -478,7 +478,7 @@ inline unsigned int average(unsigned int a, unsigned int b) - - inline signed int average(signed int a, signed int b) - { -- return ((long long)a + (long long)b) / 2; -+ return (signed int)((long long)a + (long long)b) / 2; - } - - inline float average(float a, float b) +@@ -343,7 +343,7 @@ COMPILER_EXPORT const std::string &ShGetBuiltInResourcesString(const ShHandle ha + // type: Specifies the type of shader - GL_FRAGMENT_SHADER or GL_VERTEX_SHADER. + // spec: Specifies the language spec the compiler must conform to - + // SH_GLES2_SPEC or SH_WEBGL_SPEC. +-// output: Specifies the output code type - for example SH_ESSL_OUTPUT, SH_GLSL_OUTPUT, ++// output: Specifies the output code type - for example SH_ESSL_OUTPUT, SH_GLSL_COMPATIBILITY_OUTPUT, + // SH_HLSL_3_0_OUTPUT or SH_HLSL_4_1_OUTPUT. Note: Each output type may only + // be supported in some configurations. + // resources: Specifies the built-in resources. diff --git a/src/common/version.h b/src/common/version.h -index 758c78d..2a44709 100644 +index e7ffa7c..b653ae3 100644 --- a/src/common/version.h +++ b/src/common/version.h @@ -7,7 +7,7 @@ @@ -38,524 +34,142 @@ index 758c78d..2a44709 100644 #define ANGLE_MAJOR_VERSION 2 #define ANGLE_MINOR_VERSION 1 diff --git a/src/compiler/preprocessor/ExpressionParser.cpp b/src/compiler/preprocessor/ExpressionParser.cpp -index 683195c..851183e 100644 +index 193b150..b38b7ae 100644 --- a/src/compiler/preprocessor/ExpressionParser.cpp +++ b/src/compiler/preprocessor/ExpressionParser.cpp @@ -1,5 +1,7 @@ /* A Bison parser, made by GNU Bison 3.0.4. */ -+/* Apple Note: For the avoidance of doubt, Apple elects to distribute this file under the terms of the BSD license. */ ++/* Apple Note: For the avoidance of doubt, Apple elects to distribute this file under the terms of the BSD license. */ + /* Bison implementation for Yacc-like parsers in C Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc. diff --git a/src/compiler/preprocessor/Tokenizer.cpp b/src/compiler/preprocessor/Tokenizer.cpp -index 75df434..dd9d41a 100644 +index eb6156f..1caee47 100644 --- a/src/compiler/preprocessor/Tokenizer.cpp +++ b/src/compiler/preprocessor/Tokenizer.cpp -@@ -6,6 +6,11 @@ - // - - // This file is auto-generated by generate_parser.sh. DO NOT EDIT! -+// This file was edited anyways to ignore clang warnings. -+#if defined(__clang__) -+#pragma clang diagnostic push -+#pragma GCC diagnostic ignored "-Wunneeded-internal-declaration" -+#endif - - - -diff --git a/src/compiler/translator/CallDAG.cpp b/src/compiler/translator/CallDAG.cpp -index 1d1eb8b..95dbea1 100644 ---- a/src/compiler/translator/CallDAG.cpp -+++ b/src/compiler/translator/CallDAG.cpp -@@ -71,10 +71,10 @@ class CallDAG::CallDAGCreator : public TIntermTraverser - record.callees.reserve(data.callees.size()); - for (auto &callee : data.callees) - { -- record.callees.push_back(callee->index); -+ record.callees.push_back(static_cast(callee->index)); - } - -- (*idToIndex)[data.node->getFunctionId()] = data.index; -+ (*idToIndex)[data.node->getFunctionId()] = static_cast(data.index); - } - } - -diff --git a/src/compiler/translator/Compiler.cpp b/src/compiler/translator/Compiler.cpp -index 8b5b12f..5c029ba 100644 ---- a/src/compiler/translator/Compiler.cpp -+++ b/src/compiler/translator/Compiler.cpp -@@ -528,15 +528,15 @@ bool TCompiler::checkCallDepth() - infoSink.info << "Call stack too deep (larger than " << maxCallStackDepth - << ") with the following call chain: " << record.name; - -- int currentFunction = i; -+ signed long long currentFunction = i; - int currentDepth = depth; - - while (currentFunction != -1) - { -- infoSink.info << " -> " << mCallDag.getRecordFromIndex(currentFunction).name; -+ infoSink.info << " -> " << mCallDag.getRecordFromIndex(static_cast(currentFunction)).name; +@@ -712,7 +712,7 @@ static void yy_flex_strncpy (char *,yyconst char *,int ,yyscan_t yyscanner); + static int yy_flex_strlen (yyconst char * ,yyscan_t yyscanner); + #endif - int nextFunction = -1; -- for (auto& calleeIndex : mCallDag.getRecordFromIndex(currentFunction).callees) -+ for (auto& calleeIndex : mCallDag.getRecordFromIndex(static_cast(currentFunction)).callees) - { - if (depths[calleeIndex] == currentDepth - 1) - { -@@ -558,7 +558,7 @@ bool TCompiler::checkCallDepth() - bool TCompiler::tagUsedFunctions() - { - // Search from main, starting from the end of the DAG as it usually is the root. -- for (int i = mCallDag.size(); i-- > 0;) -+ for (size_t i = mCallDag.size(); i--;) - { - if (mCallDag.getRecordFromIndex(i).name == "main(") - { -diff --git a/src/compiler/translator/ParseContext.cpp b/src/compiler/translator/ParseContext.cpp -index cd7ffc4..1cd787c 100644 ---- a/src/compiler/translator/ParseContext.cpp -+++ b/src/compiler/translator/ParseContext.cpp -@@ -511,7 +511,7 @@ bool TParseContext::constructorErrorCheck(const TSourceLoc& line, TIntermNode* n - { - if (type->isUnsizedArray()) - { -- type->setArraySize(function.getParamCount()); -+ type->setArraySize(static_cast(function.getParamCount())); - } - else if (static_cast(type->getArraySize()) != function.getParamCount()) - { -diff --git a/src/compiler/translator/VariableInfo.cpp b/src/compiler/translator/VariableInfo.cpp -index 808db95..1aa9e59 100644 ---- a/src/compiler/translator/VariableInfo.cpp -+++ b/src/compiler/translator/VariableInfo.cpp -@@ -55,7 +55,7 @@ void ExpandVariable(const ShaderVariable &variable, - { - if (variable.isArray()) - { -- for (size_t elementIndex = 0; elementIndex < variable.elementCount(); elementIndex++) -+ for (unsigned int elementIndex = 0; elementIndex < variable.elementCount(); elementIndex++) - { - std::string lname = name + ::ArrayString(elementIndex); - std::string lmappedName = mappedName + ::ArrayString(elementIndex); -diff --git a/src/compiler/translator/blocklayout.cpp b/src/compiler/translator/blocklayout.cpp -index 7c74105..7cc6315 100644 ---- a/src/compiler/translator/blocklayout.cpp -+++ b/src/compiler/translator/blocklayout.cpp -@@ -27,7 +27,7 @@ BlockMemberInfo BlockLayoutEncoder::encodeType(GLenum type, unsigned int arraySi +-#ifndef YY_NO_INPUT ++#if 0 //#ifndef YY_NO_INPUT - getBlockLayoutInfo(type, arraySize, isRowMajorMatrix, &arrayStride, &matrixStride); + #ifdef __cplusplus + static int yyinput (yyscan_t yyscanner ); +@@ -1526,7 +1526,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner) + return yy_is_jam ? 0 : yy_current_state; + } -- const BlockMemberInfo memberInfo(mCurrentOffset * BytesPerComponent, arrayStride * BytesPerComponent, matrixStride * BytesPerComponent, isRowMajorMatrix); -+ const BlockMemberInfo memberInfo(static_cast(mCurrentOffset * BytesPerComponent), arrayStride * BytesPerComponent, matrixStride * BytesPerComponent, isRowMajorMatrix); +-#ifndef YY_NO_INPUT ++#if 0 //#ifndef YY_NO_INPUT + #ifdef __cplusplus + static int yyinput (yyscan_t yyscanner) + #else +diff --git a/src/compiler/translator/CodeGen.cpp b/src/compiler/translator/CodeGen.cpp +index f099bcc..fe7c4f1 100644 +--- a/src/compiler/translator/CodeGen.cpp ++++ b/src/compiler/translator/CodeGen.cpp +@@ -4,6 +4,8 @@ + // found in the LICENSE file. + // - advanceOffset(type, arraySize, isRowMajorMatrix, arrayStride, matrixStride); ++#include "compiler/translator/Compiler.h" ++ + #ifdef ANGLE_ENABLE_ESSL + #include "compiler/translator/TranslatorESSL.h" + #endif +diff --git a/src/compiler/translator/ShaderLang.cpp b/src/compiler/translator/ShaderLang.cpp +index 421597b..a58e917 100644 +--- a/src/compiler/translator/ShaderLang.cpp ++++ b/src/compiler/translator/ShaderLang.cpp +@@ -374,4 +374,4 @@ const std::map *ShGetUniformRegisterMap(const ShHandl + static std::map map; + return ↦ + #endif // ANGLE_ENABLE_HLSL +-} +\ No newline at end of file ++} +diff --git a/src/compiler/translator/TranslatorHLSL.cpp b/src/compiler/translator/TranslatorHLSL.cpp +index 111a38b..2940260 100644 +--- a/src/compiler/translator/TranslatorHLSL.cpp ++++ b/src/compiler/translator/TranslatorHLSL.cpp +@@ -75,4 +75,4 @@ unsigned int TranslatorHLSL::getInterfaceBlockRegister(const std::string &interf + const std::map *TranslatorHLSL::getUniformRegisterMap() const + { + return &mUniformRegisterMap; +-} +\ No newline at end of file ++} +diff --git a/src/compiler/translator/TranslatorHLSL.h b/src/compiler/translator/TranslatorHLSL.h +index 40cfd70..4e84612 100644 +--- a/src/compiler/translator/TranslatorHLSL.h ++++ b/src/compiler/translator/TranslatorHLSL.h +@@ -13,7 +13,9 @@ class TranslatorHLSL : public TCompiler + { + public: + TranslatorHLSL(sh::GLenum type, ShShaderSpec spec, ShShaderOutput output); ++#ifdef ANGLE_ENABLE_HLSL + TranslatorHLSL *getAsTranslatorHLSL() override { return this; } ++#endif + bool hasInterfaceBlock(const std::string &interfaceBlockName) const; + unsigned int getInterfaceBlockRegister(const std::string &interfaceBlockName) const; +diff --git a/src/compiler/translator/glslang_lex.cpp b/src/compiler/translator/glslang_lex.cpp +index ff6c2d6..1af876b 100644 +--- a/src/compiler/translator/glslang_lex.cpp ++++ b/src/compiler/translator/glslang_lex.cpp +@@ -2090,7 +2090,7 @@ case YY_STATE_EOF(FIELDS): + YY_BREAK + case 239: + YY_RULE_SETUP +-{ assert(false); return 0; } ++{ return 0; } + YY_BREAK + case 240: + YY_RULE_SETUP diff --git a/src/compiler/translator/glslang_tab.cpp b/src/compiler/translator/glslang_tab.cpp -index 03cef93..6fb0d46 100644 +index 8b4fbd2..a799d29 100644 --- a/src/compiler/translator/glslang_tab.cpp +++ b/src/compiler/translator/glslang_tab.cpp @@ -1,5 +1,7 @@ /* A Bison parser, made by GNU Bison 3.0.4. */ -+/* Apple Note: For the avoidance of doubt, Apple elects to distribute this file under the terms of the BSD license. */ ++/* Apple Note: For the avoidance of doubt, Apple elects to distribute this file under the terms of the BSD license. */ + /* Bison implementation for Yacc-like parsers in C Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc. -diff --git a/src/libANGLE/Config.cpp b/src/libANGLE/Config.cpp -index 1b1fc50..2a68d5b 100644 ---- a/src/libANGLE/Config.cpp -+++ b/src/libANGLE/Config.cpp -@@ -64,7 +64,7 @@ Config::Config() - 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 = mConfigs.size() + 1; -+ EGLint id = static_cast(mConfigs.size() + 1); - - Config copyConfig(config); - copyConfig.configID = id; -diff --git a/src/libANGLE/Context.cpp b/src/libANGLE/Context.cpp -index 545284a..c8ea993 100644 ---- a/src/libANGLE/Context.cpp -+++ b/src/libANGLE/Context.cpp -@@ -838,7 +838,7 @@ void Context::getIntegerv(GLenum pname, GLint *params) - case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS: *params = mCaps.maxTransformFeedbackInterleavedComponents; break; - case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS: *params = mCaps.maxTransformFeedbackSeparateAttributes; break; - case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS: *params = mCaps.maxTransformFeedbackSeparateComponents; break; -- case GL_NUM_COMPRESSED_TEXTURE_FORMATS: *params = mCaps.compressedTextureFormats.size(); break; -+ case GL_NUM_COMPRESSED_TEXTURE_FORMATS: *params = static_cast(mCaps.compressedTextureFormats.size()); break; - case GL_MAX_SAMPLES_ANGLE: *params = mCaps.maxSamples; break; - case GL_MAX_VIEWPORT_DIMS: - { -@@ -853,13 +853,13 @@ void Context::getIntegerv(GLenum pname, GLint *params) - *params = mResetStrategy; - break; - case GL_NUM_SHADER_BINARY_FORMATS: -- *params = mCaps.shaderBinaryFormats.size(); -+ *params = static_cast(mCaps.shaderBinaryFormats.size()); - break; - case GL_SHADER_BINARY_FORMATS: - std::copy(mCaps.shaderBinaryFormats.begin(), mCaps.shaderBinaryFormats.end(), params); - break; - case GL_NUM_PROGRAM_BINARY_FORMATS: -- *params = mCaps.programBinaryFormats.size(); -+ *params = static_cast(mCaps.programBinaryFormats.size()); - break; - case GL_PROGRAM_BINARY_FORMATS: - std::copy(mCaps.programBinaryFormats.begin(), mCaps.programBinaryFormats.end(), params); -@@ -939,19 +939,19 @@ bool Context::getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *nu - case GL_COMPRESSED_TEXTURE_FORMATS: - { - *type = GL_INT; -- *numParams = mCaps.compressedTextureFormats.size(); -+ *numParams = static_cast(mCaps.compressedTextureFormats.size()); - } - return true; - case GL_PROGRAM_BINARY_FORMATS_OES: - { - *type = GL_INT; -- *numParams = mCaps.programBinaryFormats.size(); -+ *numParams = static_cast(mCaps.programBinaryFormats.size()); - } - return true; - case GL_SHADER_BINARY_FORMATS: - { - *type = GL_INT; -- *numParams = mCaps.shaderBinaryFormats.size(); -+ *numParams = static_cast(mCaps.shaderBinaryFormats.size()); - } - return true; - -diff --git a/src/libANGLE/Framebuffer.cpp b/src/libANGLE/Framebuffer.cpp -index faee83c..3870e69 100644 ---- a/src/libANGLE/Framebuffer.cpp -+++ b/src/libANGLE/Framebuffer.cpp -@@ -269,7 +269,7 @@ bool Framebuffer::hasEnabledColorAttachment() const - { - for (size_t colorAttachment = 0; colorAttachment < mData.mColorAttachments.size(); ++colorAttachment) - { -- if (isEnabledColorAttachment(colorAttachment)) -+ if (static_cast(isEnabledColorAttachment(colorAttachment))) - { - return true; - } -@@ -287,7 +287,7 @@ bool Framebuffer::usingExtendedDrawBuffers() const - { - for (size_t colorAttachment = 1; colorAttachment < mData.mColorAttachments.size(); ++colorAttachment) - { -- if (isEnabledColorAttachment(colorAttachment)) -+ if (static_cast(isEnabledColorAttachment(colorAttachment))) - { - return true; - } -diff --git a/src/libANGLE/ImageIndex.cpp b/src/libANGLE/ImageIndex.cpp -index ac7302d..538258f 100644 ---- a/src/libANGLE/ImageIndex.cpp -+++ b/src/libANGLE/ImageIndex.cpp -@@ -35,7 +35,7 @@ ImageIndex ImageIndex::Make2D(GLint mipIndex) - ImageIndex ImageIndex::MakeCube(GLenum target, GLint mipIndex) - { - ASSERT(gl::IsCubeMapTextureTarget(target)); -- return ImageIndex(target, mipIndex, CubeMapTextureTargetToLayerIndex(target)); -+ return ImageIndex(target, mipIndex, static_cast(CubeMapTextureTargetToLayerIndex(target))); - } - - ImageIndex ImageIndex::Make2DArray(GLint mipIndex, GLint layerIndex) -@@ -50,7 +50,7 @@ ImageIndex ImageIndex::Make3D(GLint mipIndex, GLint layerIndex) - - ImageIndex ImageIndex::MakeGeneric(GLenum target, GLint mipIndex) - { -- GLint layerIndex = IsCubeMapTextureTarget(target) ? CubeMapTextureTargetToLayerIndex(target) : ENTIRE_LEVEL; -+ GLint layerIndex = IsCubeMapTextureTarget(target) ? static_cast(CubeMapTextureTargetToLayerIndex(target)) : ENTIRE_LEVEL; - return ImageIndex(target, mipIndex, layerIndex); - } - -diff --git a/src/libANGLE/Program.cpp b/src/libANGLE/Program.cpp -index e215379..42f09b9 100644 ---- a/src/libANGLE/Program.cpp -+++ b/src/libANGLE/Program.cpp -@@ -483,7 +483,7 @@ Error Program::saveBinary(GLenum *binaryFormat, void *binary, GLsizei bufSize, G - return error; - } - -- GLsizei streamLength = stream.length(); -+ GLsizei streamLength = static_cast(stream.length()); - const void *streamData = stream.data(); - - if (streamLength > bufSize) -@@ -645,7 +645,7 @@ void Program::getActiveAttribute(GLuint index, GLsizei bufsize, GLsizei *length, - - if (length) - { -- *length = strlen(name); -+ *length = static_cast(strlen(name)); - } - } - -@@ -762,7 +762,7 @@ void Program::getActiveUniform(GLuint index, GLsizei bufsize, GLsizei *length, G - - if (length) - { -- *length = strlen(name); -+ *length = static_cast(strlen(name)); - } - } - -@@ -790,7 +790,7 @@ GLint Program::getActiveUniformCount() - { - if (mLinked) - { -- return mProgram->getUniforms().size(); -+ return static_cast(mProgram->getUniforms().size()); - } - else - { -@@ -804,7 +804,7 @@ GLint Program::getActiveUniformMaxLength() - - if (mLinked) - { -- unsigned int numUniforms = mProgram->getUniforms().size(); -+ unsigned int numUniforms = static_cast(mProgram->getUniforms().size()); - for (unsigned int uniformIndex = 0; uniformIndex < numUniforms; uniformIndex++) - { - if (!mProgram->getUniforms()[uniformIndex]->name.empty()) -@@ -1042,7 +1042,7 @@ void Program::updateSamplerMapping() - - GLuint Program::getActiveUniformBlockCount() - { -- return mProgram->getUniformBlocks().size(); -+ return static_cast(mProgram->getUniformBlocks().size()); - } - - void Program::getActiveUniformBlockName(GLuint uniformBlockIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformBlockName) const -@@ -1065,7 +1065,7 @@ void Program::getActiveUniformBlockName(GLuint uniformBlockIndex, GLsizei bufSiz - - if (length) - { -- *length = strlen(uniformBlockName); -+ *length = static_cast(strlen(uniformBlockName)); - } - } - } -@@ -1111,13 +1111,13 @@ GLint Program::getActiveUniformBlockMaxLength() +diff --git a/src/compiler/translator/glslang_tab.h b/src/compiler/translator/glslang_tab.h +index 7331594..eb7ef39 100644 +--- a/src/compiler/translator/glslang_tab.h ++++ b/src/compiler/translator/glslang_tab.h +@@ -1,5 +1,7 @@ + /* A Bison parser, made by GNU Bison 3.0.4. */ - if (mLinked) - { -- unsigned int numUniformBlocks = mProgram->getUniformBlocks().size(); -+ unsigned int numUniformBlocks = static_cast(mProgram->getUniformBlocks().size()); - for (unsigned int uniformBlockIndex = 0; uniformBlockIndex < numUniformBlocks; uniformBlockIndex++) - { - const UniformBlock &uniformBlock = *mProgram->getUniformBlocks()[uniformBlockIndex]; - if (!uniformBlock.name.empty()) - { -- const int length = uniformBlock.name.length() + 1; -+ const int length = static_cast(uniformBlock.name.length() + 1); ++/* Apple Note: For the avoidance of doubt, Apple elects to distribute this file under the terms of the BSD license. */ ++ + /* Bison interface for Yacc-like parsers in C - // Counting in "[0]". - const int arrayLength = (uniformBlock.isArrayElement() ? 3 : 0); -@@ -1466,7 +1466,7 @@ bool Program::areMatchingInterfaceBlocks(gl::InfoLog &infoLog, const sh::Interfa - infoLog.append("Layout qualifiers differ for interface block '%s' between vertex and fragment shaders", blockName); - return false; - } -- const unsigned int numBlockMembers = vertexInterfaceBlock.fields.size(); -+ const unsigned int numBlockMembers = static_cast(vertexInterfaceBlock.fields.size()); - for (unsigned int blockMemberIndex = 0; blockMemberIndex < numBlockMembers; blockMemberIndex++) - { - const sh::InterfaceBlockField &vertexMember = vertexInterfaceBlock.fields[blockMemberIndex]; -@@ -1510,7 +1510,7 @@ bool Program::linkValidateVariablesBase(InfoLog &infoLog, const std::string &var - infoLog.append("Structure lengths for %s differ between vertex and fragment shaders", variableName.c_str()); - return false; - } -- const unsigned int numMembers = vertexVariable.fields.size(); -+ const unsigned int numMembers = static_cast(vertexVariable.fields.size()); - for (unsigned int memberIndex = 0; memberIndex < numMembers; memberIndex++) + Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc. +diff --git a/src/libANGLE/Display.cpp b/src/libANGLE/Display.cpp +index c94dff2..4de579b 100644 +--- a/src/libANGLE/Display.cpp ++++ b/src/libANGLE/Display.cpp +@@ -139,6 +139,7 @@ rx::DisplayImpl *CreateDisplayFromAttribs(const AttributeMap &attribMap) + switch (displayType) { - const sh::ShaderVariable &vertexMember = vertexVariable.fields[memberIndex]; -diff --git a/src/libANGLE/Renderbuffer.cpp b/src/libANGLE/Renderbuffer.cpp -index 85b920b..34cc365 100644 ---- a/src/libANGLE/Renderbuffer.cpp -+++ b/src/libANGLE/Renderbuffer.cpp -@@ -42,8 +42,8 @@ Error Renderbuffer::setStorage(GLenum internalformat, size_t width, size_t heigh - return error; - } - -- mWidth = width; -- mHeight = height; -+ mWidth = static_cast(width); -+ mHeight = static_cast(height); - mInternalFormat = internalformat; - mSamples = 0; - -@@ -58,10 +58,10 @@ Error Renderbuffer::setStorageMultisample(size_t samples, GLenum internalformat, - return error; - } - -- mWidth = width; -- mHeight = height; -+ mWidth = static_cast(width); -+ mHeight = static_cast(height); - mInternalFormat = internalformat; -- mSamples = samples; -+ mSamples = static_cast(samples); - - return Error(GL_NO_ERROR); - } -diff --git a/src/libANGLE/Shader.cpp b/src/libANGLE/Shader.cpp -index 7af4ff3..5106e95 100644 ---- a/src/libANGLE/Shader.cpp -+++ b/src/libANGLE/Shader.cpp -@@ -66,7 +66,7 @@ void Shader::setSource(GLsizei count, const char *const *string, const GLint *le - - int Shader::getInfoLogLength() const - { -- return mShader->getInfoLog().empty() ? 0 : (mShader->getInfoLog().length() + 1); -+ return mShader->getInfoLog().empty() ? 0 : static_cast(mShader->getInfoLog().length() + 1); - } - - void Shader::getInfoLog(GLsizei bufSize, GLsizei *length, char *infoLog) const -@@ -89,12 +89,12 @@ void Shader::getInfoLog(GLsizei bufSize, GLsizei *length, char *infoLog) const - - int Shader::getSourceLength() const - { -- return mSource.empty() ? 0 : (mSource.length() + 1); -+ return mSource.empty() ? 0 : static_cast(mSource.length() + 1); - } - - int Shader::getTranslatedSourceLength() const - { -- return mShader->getTranslatedSource().empty() ? 0 : (mShader->getTranslatedSource().length() + 1); -+ return mShader->getTranslatedSource().empty() ? 0 : static_cast(mShader->getTranslatedSource().length() + 1); - } - - void Shader::getSourceImpl(const std::string &source, GLsizei bufSize, GLsizei *length, char *buffer) -diff --git a/src/libANGLE/State.cpp b/src/libANGLE/State.cpp -index f731774..f6837f4 100644 ---- a/src/libANGLE/State.cpp -+++ b/src/libANGLE/State.cpp -@@ -569,7 +569,7 @@ void State::setActiveSampler(unsigned int active) - - unsigned int State::getActiveSampler() const - { -- return mActiveSampler; -+ return static_cast(mActiveSampler); - } - - void State::setSamplerTexture(GLenum type, Texture *texture) -@@ -1192,7 +1192,7 @@ void State::getIntegerv(const gl::Data &data, GLenum pname, GLint *params) - case GL_UNPACK_ROW_LENGTH: *params = mUnpack.rowLength; break; - case GL_GENERATE_MIPMAP_HINT: *params = mGenerateMipmapHint; break; - case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES: *params = mFragmentShaderDerivativeHint; break; -- case GL_ACTIVE_TEXTURE: *params = (mActiveSampler + GL_TEXTURE0); 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 = clampToInt(mDepthStencil.stencilMask); break; -@@ -1316,19 +1316,19 @@ void State::getIntegerv(const gl::Data &data, GLenum pname, GLint *params) - break; - case GL_TEXTURE_BINDING_2D: - ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits); -- *params = getSamplerTextureId(mActiveSampler, GL_TEXTURE_2D) ; -+ *params = getSamplerTextureId(static_cast(mActiveSampler), GL_TEXTURE_2D) ; - break; - case GL_TEXTURE_BINDING_CUBE_MAP: - ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits); -- *params = getSamplerTextureId(mActiveSampler, GL_TEXTURE_CUBE_MAP); -+ *params = getSamplerTextureId(static_cast(mActiveSampler), GL_TEXTURE_CUBE_MAP); - break; - case GL_TEXTURE_BINDING_3D: - ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits); -- *params = getSamplerTextureId(mActiveSampler, GL_TEXTURE_3D); -+ *params = getSamplerTextureId(static_cast(mActiveSampler), GL_TEXTURE_3D); - break; - case GL_TEXTURE_BINDING_2D_ARRAY: - ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits); -- *params = getSamplerTextureId(mActiveSampler, GL_TEXTURE_2D_ARRAY); -+ *params = getSamplerTextureId(static_cast(mActiveSampler), GL_TEXTURE_2D_ARRAY); + case EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE: ++#if defined(ANGLE_ENABLE_OPENGL) + #if defined(ANGLE_ENABLE_D3D9) || defined(ANGLE_ENABLE_D3D11) + // Default to D3D displays + impl = new rx::DisplayD3D(); +@@ -150,6 +151,7 @@ rx::DisplayImpl *CreateDisplayFromAttribs(const AttributeMap &attribMap) + // No display available + UNREACHABLE(); + #endif ++#endif break; - case GL_UNIFORM_BUFFER_BINDING: - *params = mGenericUniformBuffer.id(); -diff --git a/src/libANGLE/Surface.cpp b/src/libANGLE/Surface.cpp -index c42b69d..9742f5d 100644 ---- a/src/libANGLE/Surface.cpp -+++ b/src/libANGLE/Surface.cpp -@@ -135,12 +135,12 @@ EGLint Surface::isFixedSize() const - - EGLint Surface::getWidth() const - { -- return mFixedSize ? mFixedWidth : mImplementation->getWidth(); -+ return mFixedSize ? static_cast(mFixedWidth) : mImplementation->getWidth(); - } - - EGLint Surface::getHeight() const - { -- return mFixedSize ? mFixedHeight : mImplementation->getHeight(); -+ return mFixedSize ? static_cast(mFixedHeight) : mImplementation->getHeight(); - } - - Error Surface::bindTexImage(gl::Texture *texture, EGLint buffer) -diff --git a/src/libANGLE/Texture.cpp b/src/libANGLE/Texture.cpp -index 1ab5c7d..437ba0d 100644 ---- a/src/libANGLE/Texture.cpp -+++ b/src/libANGLE/Texture.cpp -@@ -266,7 +266,7 @@ Error Texture::setStorage(GLenum target, size_t levels, GLenum internalFormat, c - - releaseTexImage(); - -- mImmutableLevelCount = levels; -+ mImmutableLevelCount = static_cast(levels); - clearImageDescs(); - setImageDescChain(levels, size, internalFormat); - -@@ -295,16 +295,16 @@ void Texture::setImageDescChain(size_t levels, Extents baseSize, GLenum sizedInt - { - for (size_t level = 0; level < levels; level++) - { -- Extents levelSize(std::max(baseSize.width >> level, 1), -- std::max(baseSize.height >> level, 1), -- (mTarget == GL_TEXTURE_2D_ARRAY) ? baseSize.depth : std::max(baseSize.depth >> level, 1)); -+ Extents levelSize(std::max(baseSize.width >> level, 1), -+ std::max(baseSize.height >> level, 1), -+ (mTarget == GL_TEXTURE_2D_ARRAY) ? baseSize.depth : std::max(baseSize.depth >> level, 1)); - ImageDesc levelInfo(levelSize, sizedInternalFormat); - - if (mTarget == GL_TEXTURE_CUBE_MAP) - { - for (size_t face = FirstCubeMapTextureTarget; face <= LastCubeMapTextureTarget; face++) - { -- setImageDesc(face, level, levelInfo); -+ setImageDesc(static_cast(face), level, levelInfo); - } - } - else -@@ -571,12 +571,12 @@ Texture::SamplerCompletenessCache::SamplerCompletenessCache() - - GLsizei Texture::getAttachmentWidth(const gl::FramebufferAttachment::Target &target) const - { -- return getWidth(target.textureIndex().type, target.textureIndex().mipIndex); -+ return static_cast(getWidth(target.textureIndex().type, target.textureIndex().mipIndex)); - } - - GLsizei Texture::getAttachmentHeight(const gl::FramebufferAttachment::Target &target) const - { -- return getHeight(target.textureIndex().type, target.textureIndex().mipIndex); -+ return static_cast(getHeight(target.textureIndex().type, target.textureIndex().mipIndex)); - } - - GLenum Texture::getAttachmentInternalFormat(const gl::FramebufferAttachment::Target &target) const -diff --git a/src/libANGLE/validationES.cpp b/src/libANGLE/validationES.cpp -index 1896138..2a288a2 100644 ---- a/src/libANGLE/validationES.cpp -+++ b/src/libANGLE/validationES.cpp -@@ -174,7 +174,7 @@ bool ValidMipLevel(const Context *context, GLenum target, GLint level) - default: UNREACHABLE(); - } - -- return level <= gl::log2(maxDimension); -+ return level <= gl::log2(static_cast(maxDimension)); - } - bool ValidImageSize(const Context *context, GLenum target, GLint level, + case EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE: diff --git a/Source/ThirdParty/ANGLE/codereview.settings b/Source/ThirdParty/ANGLE/codereview.settings index 255d8b7b1e2b..516eaaa50562 100644 --- a/Source/ThirdParty/ANGLE/codereview.settings +++ b/Source/ThirdParty/ANGLE/codereview.settings @@ -1,4 +1,4 @@ -# This file is used by gcl to get repository specific information. -GERRIT_HOST: chromium-review.googlesource.com -GERRIT_PORT: 29418 -CODE_REVIEW_SERVER: chromium-review.googlesource.com +# This file is used by git cl to get repository specific information. +CODE_REVIEW_SERVER: https://chromium-review.googlesource.com +GERRIT_HOST: True +TRYSERVER_GERRIT_URL: https://chromium-review.googlesource.com diff --git a/Source/ThirdParty/ANGLE/include/EGL/eglext.h b/Source/ThirdParty/ANGLE/include/EGL/eglext.h index 4b0ea7282a8c..2d919b09b49f 100644 --- a/Source/ThirdParty/ANGLE/include/EGL/eglext.h +++ b/Source/ThirdParty/ANGLE/include/EGL/eglext.h @@ -6,7 +6,7 @@ extern "C" { #endif /* -** Copyright (c) 2013-2014 The Khronos Group Inc. +** Copyright (c) 2013-2016 The Khronos Group Inc. ** ** Permission is hereby granted, free of charge, to any person obtaining a ** copy of this software and/or associated documentation files (the @@ -33,12 +33,12 @@ extern "C" { ** used to make the header, and the header can be found at ** http://www.opengl.org/registry/ ** -** Khronos $Revision: 27018 $ on $Date: 2014-06-10 08:06:12 -0700 (Tue, 10 Jun 2014) $ +** Khronos $Revision: 32432 $ on $Date: 2016-02-09 23:01:07 -0800 (Tue, 09 Feb 2016) $ */ #include -#define EGL_EGLEXT_VERSION 20140610 +#define EGL_EGLEXT_VERSION 20160209 /* Generated C header for: * API: egl @@ -94,12 +94,55 @@ EGLAPI EGLSyncKHR EGLAPIENTRY eglCreateSync64KHR (EGLDisplay dpy, EGLenum type, #define EGL_OPENGL_ES3_BIT_KHR 0x00000040 #endif /* EGL_KHR_create_context */ +#ifndef EGL_KHR_create_context_no_error +#define EGL_KHR_create_context_no_error 1 +#define EGL_CONTEXT_OPENGL_NO_ERROR_KHR 0x31B3 +#endif /* EGL_KHR_create_context_no_error */ + +#ifndef EGL_KHR_debug +#define EGL_KHR_debug 1 +typedef void *EGLLabelKHR; +typedef void *EGLObjectKHR; +typedef void (EGLAPIENTRY *EGLDEBUGPROCKHR)(EGLenum error,const char *command,EGLint messageType,EGLLabelKHR threadLabel,EGLLabelKHR objectLabel,const char* message); +#define EGL_OBJECT_THREAD_KHR 0x33B0 +#define EGL_OBJECT_DISPLAY_KHR 0x33B1 +#define EGL_OBJECT_CONTEXT_KHR 0x33B2 +#define EGL_OBJECT_SURFACE_KHR 0x33B3 +#define EGL_OBJECT_IMAGE_KHR 0x33B4 +#define EGL_OBJECT_SYNC_KHR 0x33B5 +#define EGL_OBJECT_STREAM_KHR 0x33B6 +#define EGL_DEBUG_MSG_CRITICAL_KHR 0x33B9 +#define EGL_DEBUG_MSG_ERROR_KHR 0x33BA +#define EGL_DEBUG_MSG_WARN_KHR 0x33BB +#define EGL_DEBUG_MSG_INFO_KHR 0x33BC +#define EGL_DEBUG_CALLBACK_KHR 0x33B8 +typedef EGLint (EGLAPIENTRYP PFNEGLDEBUGMESSAGECONTROLKHRPROC) (EGLDEBUGPROCKHR callback, const EGLAttrib *attrib_list); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYDEBUGKHRPROC) (EGLint attribute, EGLAttrib *value); +typedef EGLint (EGLAPIENTRYP PFNEGLLABELOBJECTKHRPROC) (EGLDisplay display, EGLenum objectType, EGLObjectKHR object, EGLLabelKHR label); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLint EGLAPIENTRY eglDebugMessageControlKHR (EGLDEBUGPROCKHR callback, const EGLAttrib *attrib_list); +EGLAPI EGLBoolean EGLAPIENTRY eglQueryDebugKHR (EGLint attribute, EGLAttrib *value); +EGLAPI EGLint EGLAPIENTRY eglLabelObjectKHR (EGLDisplay display, EGLenum objectType, EGLObjectKHR object, EGLLabelKHR label); +#endif +#endif /* EGL_KHR_debug */ + #ifndef EGL_KHR_fence_sync #define EGL_KHR_fence_sync 1 +typedef khronos_utime_nanoseconds_t EGLTimeKHR; #ifdef KHRONOS_SUPPORT_INT64 #define EGL_SYNC_PRIOR_COMMANDS_COMPLETE_KHR 0x30F0 #define EGL_SYNC_CONDITION_KHR 0x30F8 #define EGL_SYNC_FENCE_KHR 0x30F9 +typedef EGLSyncKHR (EGLAPIENTRYP PFNEGLCREATESYNCKHRPROC) (EGLDisplay dpy, EGLenum type, const EGLint *attrib_list); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYSYNCKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync); +typedef EGLint (EGLAPIENTRYP PFNEGLCLIENTWAITSYNCKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETSYNCATTRIBKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint *value); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLSyncKHR EGLAPIENTRY eglCreateSyncKHR (EGLDisplay dpy, EGLenum type, const EGLint *attrib_list); +EGLAPI EGLBoolean EGLAPIENTRY eglDestroySyncKHR (EGLDisplay dpy, EGLSyncKHR sync); +EGLAPI EGLint EGLAPIENTRY eglClientWaitSyncKHR (EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout); +EGLAPI EGLBoolean EGLAPIENTRY eglGetSyncAttribKHR (EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint *value); +#endif #endif /* KHRONOS_SUPPORT_INT64 */ #endif /* EGL_KHR_fence_sync */ @@ -207,6 +250,15 @@ EGLAPI EGLBoolean EGLAPIENTRY eglQuerySurface64KHR (EGLDisplay dpy, EGLSurface s #endif #endif /* EGL_KHR_lock_surface3 */ +#ifndef EGL_KHR_partial_update +#define EGL_KHR_partial_update 1 +#define EGL_BUFFER_AGE_KHR 0x313D +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSETDAMAGEREGIONKHRPROC) (EGLDisplay dpy, EGLSurface surface, EGLint *rects, EGLint n_rects); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglSetDamageRegionKHR (EGLDisplay dpy, EGLSurface surface, EGLint *rects, EGLint n_rects); +#endif +#endif /* EGL_KHR_partial_update */ + #ifndef EGL_KHR_platform_android #define EGL_KHR_platform_android 1 #define EGL_PLATFORM_ANDROID_KHR 0x3141 @@ -230,7 +282,6 @@ EGLAPI EGLBoolean EGLAPIENTRY eglQuerySurface64KHR (EGLDisplay dpy, EGLSurface s #ifndef EGL_KHR_reusable_sync #define EGL_KHR_reusable_sync 1 -typedef khronos_utime_nanoseconds_t EGLTimeKHR; #ifdef KHRONOS_SUPPORT_INT64 #define EGL_SYNC_STATUS_KHR 0x30F1 #define EGL_SIGNALED_KHR 0x30F2 @@ -242,17 +293,9 @@ typedef khronos_utime_nanoseconds_t EGLTimeKHR; #define EGL_SYNC_FLUSH_COMMANDS_BIT_KHR 0x0001 #define EGL_FOREVER_KHR 0xFFFFFFFFFFFFFFFFull #define EGL_NO_SYNC_KHR ((EGLSyncKHR)0) -typedef EGLSyncKHR (EGLAPIENTRYP PFNEGLCREATESYNCKHRPROC) (EGLDisplay dpy, EGLenum type, const EGLint *attrib_list); -typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYSYNCKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync); -typedef EGLint (EGLAPIENTRYP PFNEGLCLIENTWAITSYNCKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout); typedef EGLBoolean (EGLAPIENTRYP PFNEGLSIGNALSYNCKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync, EGLenum mode); -typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETSYNCATTRIBKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint *value); #ifdef EGL_EGLEXT_PROTOTYPES -EGLAPI EGLSyncKHR EGLAPIENTRY eglCreateSyncKHR (EGLDisplay dpy, EGLenum type, const EGLint *attrib_list); -EGLAPI EGLBoolean EGLAPIENTRY eglDestroySyncKHR (EGLDisplay dpy, EGLSyncKHR sync); -EGLAPI EGLint EGLAPIENTRY eglClientWaitSyncKHR (EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout); EGLAPI EGLBoolean EGLAPIENTRY eglSignalSyncKHR (EGLDisplay dpy, EGLSyncKHR sync, EGLenum mode); -EGLAPI EGLBoolean EGLAPIENTRY eglGetSyncAttribKHR (EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint *value); #endif #endif /* KHRONOS_SUPPORT_INT64 */ #endif /* EGL_KHR_reusable_sync */ @@ -354,6 +397,14 @@ EGLAPI EGLSurface EGLAPIENTRY eglCreateStreamProducerSurfaceKHR (EGLDisplay dpy, #define EGL_KHR_surfaceless_context 1 #endif /* EGL_KHR_surfaceless_context */ +#ifndef EGL_KHR_swap_buffers_with_damage +#define EGL_KHR_swap_buffers_with_damage 1 +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSWAPBUFFERSWITHDAMAGEKHRPROC) (EGLDisplay dpy, EGLSurface surface, EGLint *rects, EGLint n_rects); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffersWithDamageKHR (EGLDisplay dpy, EGLSurface surface, EGLint *rects, EGLint n_rects); +#endif +#endif /* EGL_KHR_swap_buffers_with_damage */ + #ifndef EGL_KHR_vg_parent_image #define EGL_KHR_vg_parent_image 1 #define EGL_VG_PARENT_IMAGE_KHR 0x30BA @@ -410,10 +461,16 @@ EGLAPI EGLint EGLAPIENTRY eglDupNativeFenceFDANDROID (EGLDisplay dpy, EGLSyncKHR #define EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE 0x3200 #endif /* EGL_ANGLE_d3d_share_handle_client_buffer */ -#ifndef EGL_ANGLE_window_fixed_size -#define EGL_ANGLE_window_fixed_size 1 -#define EGL_FIXED_SIZE_ANGLE 0x3201 -#endif /* EGL_ANGLE_window_fixed_size */ +#ifndef EGL_ANGLE_device_d3d +#define EGL_ANGLE_device_d3d 1 +#define EGL_D3D9_DEVICE_ANGLE 0x33A0 +#define EGL_D3D11_DEVICE_ANGLE 0x33A1 +#endif /* EGL_ANGLE_device_d3d */ + +#ifndef EGL_ANGLE_keyed_mutex +#define EGL_ANGLE_keyed_mutex 1 +#define EGL_DXGI_KEYED_MUTEX_ANGLE 0x33A2 +#endif /* EGL_ANGLE_keyed_mutex */ #ifndef EGL_ANGLE_query_surface_pointer #define EGL_ANGLE_query_surface_pointer 1 @@ -438,6 +495,11 @@ EGLAPI EGLBoolean EGLAPIENTRY eglQuerySurfacePointerANGLE (EGLDisplay dpy, EGLSu #define EGL_ANGLE_surface_d3d_texture_2d_share_handle 1 #endif /* EGL_ANGLE_surface_d3d_texture_2d_share_handle */ +#ifndef EGL_ANGLE_direct_composition +#define EGL_ANGLE_direct_composition 1 +#define EGL_DIRECT_COMPOSITION_ANGLE 0x33A5 +#endif /* EGL_ANGLE_direct_composition */ + #ifndef EGL_ANGLE_platform_angle #define EGL_ANGLE_platform_angle 1 #define EGL_PLATFORM_ANGLE_ANGLE 0x3202 @@ -464,11 +526,46 @@ EGLAPI EGLBoolean EGLAPIENTRY eglQuerySurfacePointerANGLE (EGLDisplay dpy, EGLSu #define EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE 0x320E #endif /* EGL_ANGLE_platform_angle_opengl */ -#ifndef EGL_ANGLE_device_d3d -#define EGL_ANGLE_device_d3d 1 -#define EGL_D3D9_DEVICE_ANGLE 0x33A0 -#define EGL_D3D11_DEVICE_ANGLE 0x33A1 -#endif /* EGL_ANGLE_device_d3d */ +#ifndef EGL_ANGLE_window_fixed_size +#define EGL_ANGLE_window_fixed_size 1 +#define EGL_FIXED_SIZE_ANGLE 0x3201 +#endif /* EGL_ANGLE_window_fixed_size */ + +#ifndef EGL_ANGLE_x11_visual +#define EGL_ANGLE_x11_visual +#define EGL_X11_VISUAL_ID_ANGLE 0x33A3 +#endif /* EGL_ANGLE_x11_visual */ + +#ifndef EGL_ANGLE_flexible_surface_compatibility +#define EGL_ANGLE_flexible_surface_compatibility 1 +#define EGL_FLEXIBLE_SURFACE_COMPATIBILITY_SUPPORTED_ANGLE 0x33A6 +#endif /* EGL_ANGLE_flexible_surface_compatibility */ + +#ifndef EGL_ANGLE_surface_orientation +#define EGL_ANGLE_surface_orientation +#define EGL_OPTIMAL_SURFACE_ORIENTATION_ANGLE 0x33A7 +#define EGL_SURFACE_ORIENTATION_ANGLE 0x33A8 +#define EGL_SURFACE_ORIENTATION_INVERT_X_ANGLE 0x0001 +#define EGL_SURFACE_ORIENTATION_INVERT_Y_ANGLE 0x0002 +#endif /* EGL_ANGLE_surface_orientation */ + +#ifndef EGL_ANGLE_experimental_present_path +#define EGL_ANGLE_experimental_present_path +#define EGL_EXPERIMENTAL_PRESENT_PATH_ANGLE 0x33A4 +#define EGL_EXPERIMENTAL_PRESENT_PATH_FAST_ANGLE 0x33A9 +#define EGL_EXPERIMENTAL_PRESENT_PATH_COPY_ANGLE 0x33AA +#endif /* EGL_ANGLE_experimental_present_path */ + +#ifndef EGL_ANGLE_stream_producer_d3d_texture_nv12 +#define EGL_ANGLE_stream_producer_d3d_texture_nv12 +#define EGL_D3D_TEXTURE_SUBRESOURCE_ID_ANGLE 0x3AAB +typedef EGLBoolean(EGLAPIENTRYP PFNEGLCREATESTREAMPRODUCERD3DTEXTURENV12ANGLEPROC)(EGLDisplay dpy, EGLStreamKHR stream, const EGLAttrib *attrib_list); +typedef EGLBoolean(EGLAPIENTRYP PFNEGLSTREAMPOSTD3DTEXTURENV12ANGLEPROC)(EGLDisplay dpy, EGLStreamKHR stream, void *texture, const EGLAttrib *attrib_list); +#ifdef EGL_EXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglCreateStreamProducerD3DTextureNV12ANGLE(EGLDisplay dpy, EGLStreamKHR stream, const EGLAttrib *attrib_list); +EGLAPI EGLBoolean EGLAPIENTRY eglStreamPostD3DTextureNV12ANGLE(EGLDisplay dpy, EGLStreamKHR stream, void *texture, const EGLAttrib *attrib_list); +#endif +#endif /* EGL_ANGLE_stream_producer_d3d_texture_nv12 */ #ifndef EGL_ARM_pixmap_multisample_discard #define EGL_ARM_pixmap_multisample_discard 1 @@ -510,6 +607,30 @@ EGLAPI EGLBoolean EGLAPIENTRY eglQueryDisplayAttribEXT (EGLDisplay dpy, EGLint a #endif #endif /* EGL_EXT_device_base */ +#ifndef EGL_ANGLE_device_creation +#define EGL_ANGLE_device_creation 1 +typedef EGLDeviceEXT (EGLAPIENTRYP PFNEGLCREATEDEVICEANGLEPROC) (EGLint device_type, void *native_device, const EGLAttrib *attrib_list); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLRELEASEDEVICEANGLEPROC) (EGLDeviceEXT device); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLDeviceEXT EGLAPIENTRY eglCreateDeviceANGLE (EGLint device_type, void *native_device, const EGLAttrib *attrib_list); +EGLAPI EGLBoolean EGLAPIENTRY eglReleaseDeviceANGLE (EGLDeviceEXT device); +#endif +#endif /* EGL_ANGLE_device_creation */ + +#ifndef EGL_EXT_device_drm +#define EGL_EXT_device_drm 1 +#define EGL_DRM_DEVICE_FILE_EXT 0x3233 +#endif /* EGL_EXT_device_drm */ + +#ifndef EGL_EXT_device_enumeration +#define EGL_EXT_device_enumeration 1 +#endif /* EGL_EXT_device_enumeration */ + +#ifndef EGL_EXT_device_openwf +#define EGL_EXT_device_openwf 1 +#define EGL_OPENWF_DEVICE_ID_EXT 0x3237 +#endif /* EGL_EXT_device_openwf */ + #ifndef EGL_EXT_device_query #define EGL_EXT_device_query 1 #endif /* EGL_EXT_device_query */ @@ -545,6 +666,48 @@ EGLAPI EGLBoolean EGLAPIENTRY eglQueryDisplayAttribEXT (EGLDisplay dpy, EGLint a #define EGL_MULTIVIEW_VIEW_COUNT_EXT 0x3134 #endif /* EGL_EXT_multiview_window */ +#ifndef EGL_EXT_output_base +#define EGL_EXT_output_base 1 +typedef void *EGLOutputLayerEXT; +typedef void *EGLOutputPortEXT; +#define EGL_NO_OUTPUT_LAYER_EXT ((EGLOutputLayerEXT)0) +#define EGL_NO_OUTPUT_PORT_EXT ((EGLOutputPortEXT)0) +#define EGL_BAD_OUTPUT_LAYER_EXT 0x322D +#define EGL_BAD_OUTPUT_PORT_EXT 0x322E +#define EGL_SWAP_INTERVAL_EXT 0x322F +typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETOUTPUTLAYERSEXTPROC) (EGLDisplay dpy, const EGLAttrib *attrib_list, EGLOutputLayerEXT *layers, EGLint max_layers, EGLint *num_layers); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETOUTPUTPORTSEXTPROC) (EGLDisplay dpy, const EGLAttrib *attrib_list, EGLOutputPortEXT *ports, EGLint max_ports, EGLint *num_ports); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLOUTPUTLAYERATTRIBEXTPROC) (EGLDisplay dpy, EGLOutputLayerEXT layer, EGLint attribute, EGLAttrib value); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYOUTPUTLAYERATTRIBEXTPROC) (EGLDisplay dpy, EGLOutputLayerEXT layer, EGLint attribute, EGLAttrib *value); +typedef const char *(EGLAPIENTRYP PFNEGLQUERYOUTPUTLAYERSTRINGEXTPROC) (EGLDisplay dpy, EGLOutputLayerEXT layer, EGLint name); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLOUTPUTPORTATTRIBEXTPROC) (EGLDisplay dpy, EGLOutputPortEXT port, EGLint attribute, EGLAttrib value); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYOUTPUTPORTATTRIBEXTPROC) (EGLDisplay dpy, EGLOutputPortEXT port, EGLint attribute, EGLAttrib *value); +typedef const char *(EGLAPIENTRYP PFNEGLQUERYOUTPUTPORTSTRINGEXTPROC) (EGLDisplay dpy, EGLOutputPortEXT port, EGLint name); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglGetOutputLayersEXT (EGLDisplay dpy, const EGLAttrib *attrib_list, EGLOutputLayerEXT *layers, EGLint max_layers, EGLint *num_layers); +EGLAPI EGLBoolean EGLAPIENTRY eglGetOutputPortsEXT (EGLDisplay dpy, const EGLAttrib *attrib_list, EGLOutputPortEXT *ports, EGLint max_ports, EGLint *num_ports); +EGLAPI EGLBoolean EGLAPIENTRY eglOutputLayerAttribEXT (EGLDisplay dpy, EGLOutputLayerEXT layer, EGLint attribute, EGLAttrib value); +EGLAPI EGLBoolean EGLAPIENTRY eglQueryOutputLayerAttribEXT (EGLDisplay dpy, EGLOutputLayerEXT layer, EGLint attribute, EGLAttrib *value); +EGLAPI const char *EGLAPIENTRY eglQueryOutputLayerStringEXT (EGLDisplay dpy, EGLOutputLayerEXT layer, EGLint name); +EGLAPI EGLBoolean EGLAPIENTRY eglOutputPortAttribEXT (EGLDisplay dpy, EGLOutputPortEXT port, EGLint attribute, EGLAttrib value); +EGLAPI EGLBoolean EGLAPIENTRY eglQueryOutputPortAttribEXT (EGLDisplay dpy, EGLOutputPortEXT port, EGLint attribute, EGLAttrib *value); +EGLAPI const char *EGLAPIENTRY eglQueryOutputPortStringEXT (EGLDisplay dpy, EGLOutputPortEXT port, EGLint name); +#endif +#endif /* EGL_EXT_output_base */ + +#ifndef EGL_EXT_output_drm +#define EGL_EXT_output_drm 1 +#define EGL_DRM_CRTC_EXT 0x3234 +#define EGL_DRM_PLANE_EXT 0x3235 +#define EGL_DRM_CONNECTOR_EXT 0x3236 +#endif /* EGL_EXT_output_drm */ + +#ifndef EGL_EXT_output_openwf +#define EGL_EXT_output_openwf 1 +#define EGL_OPENWF_PIPELINE_ID_EXT 0x3238 +#define EGL_OPENWF_PORT_ID_EXT 0x3239 +#endif /* EGL_EXT_output_openwf */ + #ifndef EGL_EXT_platform_base #define EGL_EXT_platform_base 1 typedef EGLDisplay (EGLAPIENTRYP PFNEGLGETPLATFORMDISPLAYEXTPROC) (EGLenum platform, void *native_display, const EGLint *attrib_list); @@ -578,6 +741,14 @@ EGLAPI EGLSurface EGLAPIENTRY eglCreatePlatformPixmapSurfaceEXT (EGLDisplay dpy, #define EGL_PROTECTED_CONTENT_EXT 0x32C0 #endif /* EGL_EXT_protected_surface */ +#ifndef EGL_EXT_stream_consumer_egloutput +#define EGL_EXT_stream_consumer_egloutput 1 +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMCONSUMEROUTPUTEXTPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLOutputLayerEXT layer); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglStreamConsumerOutputEXT (EGLDisplay dpy, EGLStreamKHR stream, EGLOutputLayerEXT layer); +#endif +#endif /* EGL_EXT_stream_consumer_egloutput */ + #ifndef EGL_EXT_swap_buffers_with_damage #define EGL_EXT_swap_buffers_with_damage 1 typedef EGLBoolean (EGLAPIENTRYP PFNEGLSWAPBUFFERSWITHDAMAGEEXTPROC) (EGLDisplay dpy, EGLSurface surface, EGLint *rects, EGLint n_rects); @@ -586,6 +757,35 @@ EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffersWithDamageEXT (EGLDisplay dpy, EGLSu #endif #endif /* EGL_EXT_swap_buffers_with_damage */ +#ifndef EGL_EXT_yuv_surface +#define EGL_EXT_yuv_surface 1 +#define EGL_YUV_ORDER_EXT 0x3301 +#define EGL_YUV_NUMBER_OF_PLANES_EXT 0x3311 +#define EGL_YUV_SUBSAMPLE_EXT 0x3312 +#define EGL_YUV_DEPTH_RANGE_EXT 0x3317 +#define EGL_YUV_CSC_STANDARD_EXT 0x330A +#define EGL_YUV_PLANE_BPP_EXT 0x331A +#define EGL_YUV_BUFFER_EXT 0x3300 +#define EGL_YUV_ORDER_YUV_EXT 0x3302 +#define EGL_YUV_ORDER_YVU_EXT 0x3303 +#define EGL_YUV_ORDER_YUYV_EXT 0x3304 +#define EGL_YUV_ORDER_UYVY_EXT 0x3305 +#define EGL_YUV_ORDER_YVYU_EXT 0x3306 +#define EGL_YUV_ORDER_VYUY_EXT 0x3307 +#define EGL_YUV_ORDER_AYUV_EXT 0x3308 +#define EGL_YUV_SUBSAMPLE_4_2_0_EXT 0x3313 +#define EGL_YUV_SUBSAMPLE_4_2_2_EXT 0x3314 +#define EGL_YUV_SUBSAMPLE_4_4_4_EXT 0x3315 +#define EGL_YUV_DEPTH_RANGE_LIMITED_EXT 0x3318 +#define EGL_YUV_DEPTH_RANGE_FULL_EXT 0x3319 +#define EGL_YUV_CSC_STANDARD_601_EXT 0x330B +#define EGL_YUV_CSC_STANDARD_709_EXT 0x330C +#define EGL_YUV_CSC_STANDARD_2020_EXT 0x330D +#define EGL_YUV_PLANE_BPP_0_EXT 0x331B +#define EGL_YUV_PLANE_BPP_8_EXT 0x331C +#define EGL_YUV_PLANE_BPP_10_EXT 0x331D +#endif /* EGL_EXT_yuv_surface */ + #ifndef EGL_HI_clientpixmap #define EGL_HI_clientpixmap 1 struct EGLClientPixmapHI { @@ -617,6 +817,12 @@ EGLAPI EGLSurface EGLAPIENTRY eglCreatePixmapSurfaceHI (EGLDisplay dpy, EGLConfi #define EGL_CONTEXT_PRIORITY_LOW_IMG 0x3103 #endif /* EGL_IMG_context_priority */ +#ifndef EGL_IMG_image_plane_attribs +#define EGL_IMG_image_plane_attribs 1 +#define EGL_NATIVE_BUFFER_MULTIPLANE_SEPARATE_IMG 0x3105 +#define EGL_NATIVE_BUFFER_PLANE_OFFSET_IMG 0x3106 +#endif /* EGL_IMG_image_plane_attribs */ + #ifndef EGL_MESA_drm_image #define EGL_MESA_drm_image 1 #define EGL_DRM_BUFFER_FORMAT_MESA 0x31D0 @@ -634,6 +840,16 @@ EGLAPI EGLBoolean EGLAPIENTRY eglExportDRMImageMESA (EGLDisplay dpy, EGLImageKHR #endif #endif /* EGL_MESA_drm_image */ +#ifndef EGL_MESA_image_dma_buf_export +#define EGL_MESA_image_dma_buf_export 1 +typedef EGLBoolean (EGLAPIENTRYP PFNEGLEXPORTDMABUFIMAGEQUERYMESAPROC) (EGLDisplay dpy, EGLImageKHR image, int *fourcc, int *num_planes, EGLuint64KHR *modifiers); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLEXPORTDMABUFIMAGEMESAPROC) (EGLDisplay dpy, EGLImageKHR image, int *fds, EGLint *strides, EGLint *offsets); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglExportDMABUFImageQueryMESA (EGLDisplay dpy, EGLImageKHR image, int *fourcc, int *num_planes, EGLuint64KHR *modifiers); +EGLAPI EGLBoolean EGLAPIENTRY eglExportDMABUFImageMESA (EGLDisplay dpy, EGLImageKHR image, int *fds, EGLint *strides, EGLint *offsets); +#endif +#endif /* EGL_MESA_image_dma_buf_export */ + #ifndef EGL_MESA_platform_gbm #define EGL_MESA_platform_gbm 1 #define EGL_PLATFORM_GBM_MESA 0x31D7 @@ -678,6 +894,13 @@ EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffersRegion2NOK (EGLDisplay dpy, EGLSurfa #define EGL_COVERAGE_SAMPLE_RESOLVE_NONE_NV 0x3133 #endif /* EGL_NV_coverage_sample_resolve */ +#ifndef EGL_NV_cuda_event +#define EGL_NV_cuda_event 1 +#define EGL_CUDA_EVENT_HANDLE_NV 0x323B +#define EGL_SYNC_CUDA_EVENT_NV 0x323C +#define EGL_SYNC_CUDA_EVENT_COMPLETE_NV 0x323D +#endif /* EGL_NV_cuda_event */ + #ifndef EGL_NV_depth_nonlinear #define EGL_NV_depth_nonlinear 1 #define EGL_DEPTH_ENCODING_NV 0x30E2 @@ -685,6 +908,11 @@ EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffersRegion2NOK (EGLDisplay dpy, EGLSurfa #define EGL_DEPTH_ENCODING_NONLINEAR_NV 0x30E3 #endif /* EGL_NV_depth_nonlinear */ +#ifndef EGL_NV_device_cuda +#define EGL_NV_device_cuda 1 +#define EGL_CUDA_DEVICE_NV 0x323A +#endif /* EGL_NV_device_cuda */ + #ifndef EGL_NV_native_query #define EGL_NV_native_query 1 typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYNATIVEDISPLAYNVPROC) (EGLDisplay dpy, EGLNativeDisplayType *display_id); @@ -710,6 +938,43 @@ EGLAPI EGLBoolean EGLAPIENTRY eglPostSubBufferNV (EGLDisplay dpy, EGLSurface sur #endif #endif /* EGL_NV_post_sub_buffer */ +#ifndef EGL_NV_stream_consumer_gltexture_yuv +#define EGL_NV_stream_consumer_gltexture_yuv 1 +#define EGL_YUV_PLANE0_TEXTURE_UNIT_NV 0x332C +#define EGL_YUV_PLANE1_TEXTURE_UNIT_NV 0x332D +#define EGL_YUV_PLANE2_TEXTURE_UNIT_NV 0x332E +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMCONSUMERGLTEXTUREEXTERNALATTRIBSNVPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLAttrib *attrib_list); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglStreamConsumerGLTextureExternalAttribsNV (EGLDisplay dpy, EGLStreamKHR stream, EGLAttrib *attrib_list); +#endif +#endif /* EGL_NV_stream_consumer_gltexture_yuv */ + +#ifndef EGL_NV_stream_metadata +#define EGL_NV_stream_metadata 1 +#define EGL_MAX_STREAM_METADATA_BLOCKS_NV 0x3250 +#define EGL_MAX_STREAM_METADATA_BLOCK_SIZE_NV 0x3251 +#define EGL_MAX_STREAM_METADATA_TOTAL_SIZE_NV 0x3252 +#define EGL_PRODUCER_METADATA_NV 0x3253 +#define EGL_CONSUMER_METADATA_NV 0x3254 +#define EGL_PENDING_METADATA_NV 0x3328 +#define EGL_METADATA0_SIZE_NV 0x3255 +#define EGL_METADATA1_SIZE_NV 0x3256 +#define EGL_METADATA2_SIZE_NV 0x3257 +#define EGL_METADATA3_SIZE_NV 0x3258 +#define EGL_METADATA0_TYPE_NV 0x3259 +#define EGL_METADATA1_TYPE_NV 0x325A +#define EGL_METADATA2_TYPE_NV 0x325B +#define EGL_METADATA3_TYPE_NV 0x325C +typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYDISPLAYATTRIBNVPROC) (EGLDisplay dpy, EGLint attribute, EGLAttrib *value); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSETSTREAMMETADATANVPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLint n, EGLint offset, EGLint size, const void *data); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSTREAMMETADATANVPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLenum name, EGLint n, EGLint offset, EGLint size, void *data); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglQueryDisplayAttribNV (EGLDisplay dpy, EGLint attribute, EGLAttrib *value); +EGLAPI EGLBoolean EGLAPIENTRY eglSetStreamMetadataNV (EGLDisplay dpy, EGLStreamKHR stream, EGLint n, EGLint offset, EGLint size, const void *data); +EGLAPI EGLBoolean EGLAPIENTRY eglQueryStreamMetadataNV (EGLDisplay dpy, EGLStreamKHR stream, EGLenum name, EGLint n, EGLint offset, EGLint size, void *data); +#endif +#endif /* EGL_NV_stream_metadata */ + #ifndef EGL_NV_stream_sync #define EGL_NV_stream_sync 1 #define EGL_SYNC_NEW_FRAME_NV 0x321F @@ -767,6 +1032,16 @@ EGLAPI EGLuint64NV EGLAPIENTRY eglGetSystemTimeNV (void); #endif /* KHRONOS_SUPPORT_INT64 */ #endif /* EGL_NV_system_time */ +#ifndef EGL_TIZEN_image_native_buffer +#define EGL_TIZEN_image_native_buffer 1 +#define EGL_NATIVE_BUFFER_TIZEN 0x32A0 +#endif /* EGL_TIZEN_image_native_buffer */ + +#ifndef EGL_TIZEN_image_native_surface +#define EGL_TIZEN_image_native_surface 1 +#define EGL_NATIVE_SURFACE_TIZEN 0x32A1 +#endif /* EGL_TIZEN_image_native_surface */ + #ifdef __cplusplus } #endif diff --git a/Source/ThirdParty/ANGLE/include/EGL/eglplatform.h b/Source/ThirdParty/ANGLE/include/EGL/eglplatform.h index 519df3e750ba..6d550da9cd79 100644 --- a/Source/ThirdParty/ANGLE/include/EGL/eglplatform.h +++ b/Source/ThirdParty/ANGLE/include/EGL/eglplatform.h @@ -25,7 +25,7 @@ */ /* Platform-specific types and definitions for egl.h - * $Revision: 23432 $ on $Date: 2013-10-09 00:57:24 -0700 (Wed, 09 Oct 2013) $ + * $Revision: 30994 $ on $Date: 2015-04-30 13:36:48 -0700 (Thu, 30 Apr 2015) $ * * Adopters may modify khrplatform.h and this file to suit their platform. * You are encouraged to submit all modifications to the Khronos group so that @@ -99,6 +99,12 @@ typedef struct ANativeWindow* EGLNativeWindowType; typedef struct egl_native_pixmap_t* EGLNativePixmapType; typedef void* EGLNativeDisplayType; +#elif defined(USE_OZONE) + +typedef intptr_t EGLNativeDisplayType; +typedef intptr_t EGLNativeWindowType; +typedef intptr_t EGLNativePixmapType; + #elif defined(__unix__) /* X11 (tentative) */ @@ -111,11 +117,15 @@ typedef Window EGLNativeWindowType; #elif defined(__GNUC__) && ( defined(__APPLE_CPP__) || defined(__APPLE_CC__) || defined(__MACOS_CLASSIC__) ) -// TODO(jmadill): native implementation for OSX +#if defined(__OBJC__) +@class CALayer; +#else +class CALayer; +#endif typedef void *EGLNativeDisplayType; typedef void *EGLNativePixmapType; -typedef void *EGLNativeWindowType; +typedef CALayer *EGLNativeWindowType; #else #error "Platform not recognized" diff --git a/Source/ThirdParty/ANGLE/include/GLES2/gl2.h b/Source/ThirdParty/ANGLE/include/GLES2/gl2.h index 9ab58324c46b..4d710c20adc6 100644 --- a/Source/ThirdParty/ANGLE/include/GLES2/gl2.h +++ b/Source/ThirdParty/ANGLE/include/GLES2/gl2.h @@ -1,56 +1,87 @@ #ifndef __gl2_h_ -#define __gl2_h_ - -/* $Revision: 20555 $ on $Date:: 2013-02-12 14:32:47 -0800 #$ */ - -#include +#define __gl2_h_ 1 #ifdef __cplusplus extern "C" { #endif /* - * This document is licensed under the SGI Free Software B License Version - * 2.0. For details, see http://oss.sgi.com/projects/FreeB/ . - */ +** Copyright (c) 2013-2015 The Khronos Group Inc. +** +** Permission is hereby granted, free of charge, to any person obtaining a +** copy of this software and/or associated documentation files (the +** "Materials"), to deal in the Materials without restriction, including +** without limitation the rights to use, copy, modify, merge, publish, +** distribute, sublicense, and/or sell copies of the Materials, and to +** permit persons to whom the Materials are furnished to do so, subject to +** the following conditions: +** +** The above copyright notice and this permission notice shall be included +** in all copies or substantial portions of the Materials. +** +** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. +*/ +/* +** This header is generated from the Khronos OpenGL / OpenGL ES XML +** API Registry. The current version of the Registry, generator scripts +** used to make the header, and the header can be found at +** http://www.opengl.org/registry/ +** +** Khronos $Revision: 31811 $ on $Date: 2015-08-10 00:01:11 -0700 (Mon, 10 Aug 2015) $ +*/ -/*------------------------------------------------------------------------- - * Data type definitions - *-----------------------------------------------------------------------*/ +#include -typedef void GLvoid; -typedef char GLchar; -typedef unsigned int GLenum; -typedef unsigned char GLboolean; -typedef unsigned int GLbitfield; -typedef khronos_int8_t GLbyte; -typedef short GLshort; -typedef int GLint; -typedef int GLsizei; -typedef khronos_uint8_t GLubyte; -typedef unsigned short GLushort; -typedef unsigned int GLuint; -typedef khronos_float_t GLfloat; -typedef khronos_float_t GLclampf; -typedef khronos_int32_t GLfixed; +#ifndef GL_APIENTRYP +#define GL_APIENTRYP GL_APIENTRY* +#endif -/* GL types for handling large vertex buffer objects */ -typedef khronos_intptr_t GLintptr; -typedef khronos_ssize_t GLsizeiptr; +/* Generated on date 20150809 */ -/* OpenGL ES core versions */ -#define GL_ES_VERSION_2_0 1 +/* Generated C header for: + * API: gles2 + * Profile: common + * Versions considered: 2\.[0-9] + * Versions emitted: .* + * Default extensions included: None + * Additional extensions included: _nomatch_^ + * Extensions removed: _nomatch_^ + */ -/* ClearBufferMask */ +#ifndef GL_ES_VERSION_2_0 +#define GL_ES_VERSION_2_0 1 +#include +typedef khronos_int8_t GLbyte; +typedef khronos_float_t GLclampf; +typedef khronos_int32_t GLfixed; +typedef short GLshort; +typedef unsigned short GLushort; +typedef void GLvoid; +typedef struct __GLsync *GLsync; +typedef khronos_int64_t GLint64; +typedef khronos_uint64_t GLuint64; +typedef unsigned int GLenum; +typedef unsigned int GLuint; +typedef char GLchar; +typedef khronos_float_t GLfloat; +typedef khronos_ssize_t GLsizeiptr; +typedef khronos_intptr_t GLintptr; +typedef unsigned int GLbitfield; +typedef int GLint; +typedef unsigned char GLboolean; +typedef int GLsizei; +typedef khronos_uint8_t GLubyte; #define GL_DEPTH_BUFFER_BIT 0x00000100 #define GL_STENCIL_BUFFER_BIT 0x00000400 #define GL_COLOR_BUFFER_BIT 0x00004000 - -/* Boolean */ #define GL_FALSE 0 #define GL_TRUE 1 - -/* BeginMode */ #define GL_POINTS 0x0000 #define GL_LINES 0x0001 #define GL_LINE_LOOP 0x0002 @@ -58,18 +89,6 @@ typedef khronos_ssize_t GLsizeiptr; #define GL_TRIANGLES 0x0004 #define GL_TRIANGLE_STRIP 0x0005 #define GL_TRIANGLE_FAN 0x0006 - -/* AlphaFunction (not supported in ES20) */ -/* GL_NEVER */ -/* GL_LESS */ -/* GL_EQUAL */ -/* GL_LEQUAL */ -/* GL_GREATER */ -/* GL_NOTEQUAL */ -/* GL_GEQUAL */ -/* GL_ALWAYS */ - -/* BlendingFactorDest */ #define GL_ZERO 0 #define GL_ONE 1 #define GL_SRC_COLOR 0x0300 @@ -78,29 +97,15 @@ typedef khronos_ssize_t GLsizeiptr; #define GL_ONE_MINUS_SRC_ALPHA 0x0303 #define GL_DST_ALPHA 0x0304 #define GL_ONE_MINUS_DST_ALPHA 0x0305 - -/* BlendingFactorSrc */ -/* GL_ZERO */ -/* GL_ONE */ #define GL_DST_COLOR 0x0306 #define GL_ONE_MINUS_DST_COLOR 0x0307 #define GL_SRC_ALPHA_SATURATE 0x0308 -/* GL_SRC_ALPHA */ -/* GL_ONE_MINUS_SRC_ALPHA */ -/* GL_DST_ALPHA */ -/* GL_ONE_MINUS_DST_ALPHA */ - -/* BlendEquationSeparate */ #define GL_FUNC_ADD 0x8006 #define GL_BLEND_EQUATION 0x8009 -#define GL_BLEND_EQUATION_RGB 0x8009 /* same as BLEND_EQUATION */ +#define GL_BLEND_EQUATION_RGB 0x8009 #define GL_BLEND_EQUATION_ALPHA 0x883D - -/* BlendSubtract */ #define GL_FUNC_SUBTRACT 0x800A #define GL_FUNC_REVERSE_SUBTRACT 0x800B - -/* Separate Blend Functions */ #define GL_BLEND_DST_RGB 0x80C8 #define GL_BLEND_SRC_RGB 0x80C9 #define GL_BLEND_DST_ALPHA 0x80CA @@ -110,38 +115,19 @@ typedef khronos_ssize_t GLsizeiptr; #define GL_CONSTANT_ALPHA 0x8003 #define GL_ONE_MINUS_CONSTANT_ALPHA 0x8004 #define GL_BLEND_COLOR 0x8005 - -/* Buffer Objects */ #define GL_ARRAY_BUFFER 0x8892 #define GL_ELEMENT_ARRAY_BUFFER 0x8893 #define GL_ARRAY_BUFFER_BINDING 0x8894 #define GL_ELEMENT_ARRAY_BUFFER_BINDING 0x8895 - #define GL_STREAM_DRAW 0x88E0 #define GL_STATIC_DRAW 0x88E4 #define GL_DYNAMIC_DRAW 0x88E8 - #define GL_BUFFER_SIZE 0x8764 #define GL_BUFFER_USAGE 0x8765 - #define GL_CURRENT_VERTEX_ATTRIB 0x8626 - -/* CullFaceMode */ #define GL_FRONT 0x0404 #define GL_BACK 0x0405 #define GL_FRONT_AND_BACK 0x0408 - -/* DepthFunction */ -/* GL_NEVER */ -/* GL_LESS */ -/* GL_EQUAL */ -/* GL_LEQUAL */ -/* GL_GREATER */ -/* GL_NOTEQUAL */ -/* GL_GEQUAL */ -/* GL_ALWAYS */ - -/* EnableCap */ #define GL_TEXTURE_2D 0x0DE1 #define GL_CULL_FACE 0x0B44 #define GL_BLEND 0x0BE2 @@ -152,19 +138,13 @@ typedef khronos_ssize_t GLsizeiptr; #define GL_POLYGON_OFFSET_FILL 0x8037 #define GL_SAMPLE_ALPHA_TO_COVERAGE 0x809E #define GL_SAMPLE_COVERAGE 0x80A0 - -/* ErrorCode */ #define GL_NO_ERROR 0 #define GL_INVALID_ENUM 0x0500 #define GL_INVALID_VALUE 0x0501 #define GL_INVALID_OPERATION 0x0502 #define GL_OUT_OF_MEMORY 0x0505 - -/* FrontFaceDirection */ #define GL_CW 0x0900 #define GL_CCW 0x0901 - -/* GetPName */ #define GL_LINE_WIDTH 0x0B21 #define GL_ALIASED_POINT_SIZE_RANGE 0x846D #define GL_ALIASED_LINE_WIDTH_RANGE 0x846E @@ -191,7 +171,6 @@ typedef khronos_ssize_t GLsizeiptr; #define GL_STENCIL_BACK_WRITEMASK 0x8CA5 #define GL_VIEWPORT 0x0BA2 #define GL_SCISSOR_BOX 0x0C10 -/* GL_SCISSOR_TEST */ #define GL_COLOR_CLEAR_VALUE 0x0C22 #define GL_COLOR_WRITEMASK 0x0C23 #define GL_UNPACK_ALIGNMENT 0x0CF5 @@ -206,32 +185,18 @@ typedef khronos_ssize_t GLsizeiptr; #define GL_DEPTH_BITS 0x0D56 #define GL_STENCIL_BITS 0x0D57 #define GL_POLYGON_OFFSET_UNITS 0x2A00 -/* GL_POLYGON_OFFSET_FILL */ #define GL_POLYGON_OFFSET_FACTOR 0x8038 #define GL_TEXTURE_BINDING_2D 0x8069 #define GL_SAMPLE_BUFFERS 0x80A8 #define GL_SAMPLES 0x80A9 #define GL_SAMPLE_COVERAGE_VALUE 0x80AA #define GL_SAMPLE_COVERAGE_INVERT 0x80AB - -/* GetTextureParameter */ -/* GL_TEXTURE_MAG_FILTER */ -/* GL_TEXTURE_MIN_FILTER */ -/* GL_TEXTURE_WRAP_S */ -/* GL_TEXTURE_WRAP_T */ - #define GL_NUM_COMPRESSED_TEXTURE_FORMATS 0x86A2 #define GL_COMPRESSED_TEXTURE_FORMATS 0x86A3 - -/* HintMode */ #define GL_DONT_CARE 0x1100 #define GL_FASTEST 0x1101 #define GL_NICEST 0x1102 - -/* HintTarget */ -#define GL_GENERATE_MIPMAP_HINT 0x8192 - -/* DataType */ +#define GL_GENERATE_MIPMAP_HINT 0x8192 #define GL_BYTE 0x1400 #define GL_UNSIGNED_BYTE 0x1401 #define GL_SHORT 0x1402 @@ -240,44 +205,35 @@ typedef khronos_ssize_t GLsizeiptr; #define GL_UNSIGNED_INT 0x1405 #define GL_FLOAT 0x1406 #define GL_FIXED 0x140C - -/* PixelFormat */ #define GL_DEPTH_COMPONENT 0x1902 #define GL_ALPHA 0x1906 #define GL_RGB 0x1907 #define GL_RGBA 0x1908 #define GL_LUMINANCE 0x1909 #define GL_LUMINANCE_ALPHA 0x190A - -/* PixelType */ -/* GL_UNSIGNED_BYTE */ #define GL_UNSIGNED_SHORT_4_4_4_4 0x8033 #define GL_UNSIGNED_SHORT_5_5_5_1 0x8034 #define GL_UNSIGNED_SHORT_5_6_5 0x8363 - -/* Shaders */ -#define GL_FRAGMENT_SHADER 0x8B30 -#define GL_VERTEX_SHADER 0x8B31 -#define GL_MAX_VERTEX_ATTRIBS 0x8869 -#define GL_MAX_VERTEX_UNIFORM_VECTORS 0x8DFB -#define GL_MAX_VARYING_VECTORS 0x8DFC +#define GL_FRAGMENT_SHADER 0x8B30 +#define GL_VERTEX_SHADER 0x8B31 +#define GL_MAX_VERTEX_ATTRIBS 0x8869 +#define GL_MAX_VERTEX_UNIFORM_VECTORS 0x8DFB +#define GL_MAX_VARYING_VECTORS 0x8DFC #define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS 0x8B4D -#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS 0x8B4C -#define GL_MAX_TEXTURE_IMAGE_UNITS 0x8872 -#define GL_MAX_FRAGMENT_UNIFORM_VECTORS 0x8DFD -#define GL_SHADER_TYPE 0x8B4F -#define GL_DELETE_STATUS 0x8B80 -#define GL_LINK_STATUS 0x8B82 -#define GL_VALIDATE_STATUS 0x8B83 -#define GL_ATTACHED_SHADERS 0x8B85 -#define GL_ACTIVE_UNIFORMS 0x8B86 -#define GL_ACTIVE_UNIFORM_MAX_LENGTH 0x8B87 -#define GL_ACTIVE_ATTRIBUTES 0x8B89 -#define GL_ACTIVE_ATTRIBUTE_MAX_LENGTH 0x8B8A -#define GL_SHADING_LANGUAGE_VERSION 0x8B8C -#define GL_CURRENT_PROGRAM 0x8B8D - -/* StencilFunction */ +#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS 0x8B4C +#define GL_MAX_TEXTURE_IMAGE_UNITS 0x8872 +#define GL_MAX_FRAGMENT_UNIFORM_VECTORS 0x8DFD +#define GL_SHADER_TYPE 0x8B4F +#define GL_DELETE_STATUS 0x8B80 +#define GL_LINK_STATUS 0x8B82 +#define GL_VALIDATE_STATUS 0x8B83 +#define GL_ATTACHED_SHADERS 0x8B85 +#define GL_ACTIVE_UNIFORMS 0x8B86 +#define GL_ACTIVE_UNIFORM_MAX_LENGTH 0x8B87 +#define GL_ACTIVE_ATTRIBUTES 0x8B89 +#define GL_ACTIVE_ATTRIBUTE_MAX_LENGTH 0x8B8A +#define GL_SHADING_LANGUAGE_VERSION 0x8B8C +#define GL_CURRENT_PROGRAM 0x8B8D #define GL_NEVER 0x0200 #define GL_LESS 0x0201 #define GL_EQUAL 0x0202 @@ -286,9 +242,6 @@ typedef khronos_ssize_t GLsizeiptr; #define GL_NOTEQUAL 0x0205 #define GL_GEQUAL 0x0206 #define GL_ALWAYS 0x0207 - -/* StencilOp */ -/* GL_ZERO */ #define GL_KEEP 0x1E00 #define GL_REPLACE 0x1E01 #define GL_INCR 0x1E02 @@ -296,35 +249,21 @@ typedef khronos_ssize_t GLsizeiptr; #define GL_INVERT 0x150A #define GL_INCR_WRAP 0x8507 #define GL_DECR_WRAP 0x8508 - -/* StringName */ #define GL_VENDOR 0x1F00 #define GL_RENDERER 0x1F01 #define GL_VERSION 0x1F02 #define GL_EXTENSIONS 0x1F03 - -/* TextureMagFilter */ #define GL_NEAREST 0x2600 #define GL_LINEAR 0x2601 - -/* TextureMinFilter */ -/* GL_NEAREST */ -/* GL_LINEAR */ #define GL_NEAREST_MIPMAP_NEAREST 0x2700 #define GL_LINEAR_MIPMAP_NEAREST 0x2701 #define GL_NEAREST_MIPMAP_LINEAR 0x2702 #define GL_LINEAR_MIPMAP_LINEAR 0x2703 - -/* TextureParameterName */ #define GL_TEXTURE_MAG_FILTER 0x2800 #define GL_TEXTURE_MIN_FILTER 0x2801 #define GL_TEXTURE_WRAP_S 0x2802 #define GL_TEXTURE_WRAP_T 0x2803 - -/* TextureTarget */ -/* GL_TEXTURE_2D */ #define GL_TEXTURE 0x1702 - #define GL_TEXTURE_CUBE_MAP 0x8513 #define GL_TEXTURE_BINDING_CUBE_MAP 0x8514 #define GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x8515 @@ -334,8 +273,6 @@ typedef khronos_ssize_t GLsizeiptr; #define GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x8519 #define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x851A #define GL_MAX_CUBE_MAP_TEXTURE_SIZE 0x851C - -/* TextureUnit */ #define GL_TEXTURE0 0x84C0 #define GL_TEXTURE1 0x84C1 #define GL_TEXTURE2 0x84C2 @@ -369,13 +306,9 @@ typedef khronos_ssize_t GLsizeiptr; #define GL_TEXTURE30 0x84DE #define GL_TEXTURE31 0x84DF #define GL_ACTIVE_TEXTURE 0x84E0 - -/* TextureWrapMode */ #define GL_REPEAT 0x2901 #define GL_CLAMP_TO_EDGE 0x812F #define GL_MIRRORED_REPEAT 0x8370 - -/* Uniform Types */ #define GL_FLOAT_VEC2 0x8B50 #define GL_FLOAT_VEC3 0x8B51 #define GL_FLOAT_VEC4 0x8B52 @@ -391,48 +324,34 @@ typedef khronos_ssize_t GLsizeiptr; #define GL_FLOAT_MAT4 0x8B5C #define GL_SAMPLER_2D 0x8B5E #define GL_SAMPLER_CUBE 0x8B60 - -/* Vertex Arrays */ -#define GL_VERTEX_ATTRIB_ARRAY_ENABLED 0x8622 -#define GL_VERTEX_ATTRIB_ARRAY_SIZE 0x8623 -#define GL_VERTEX_ATTRIB_ARRAY_STRIDE 0x8624 -#define GL_VERTEX_ATTRIB_ARRAY_TYPE 0x8625 -#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED 0x886A -#define GL_VERTEX_ATTRIB_ARRAY_POINTER 0x8645 +#define GL_VERTEX_ATTRIB_ARRAY_ENABLED 0x8622 +#define GL_VERTEX_ATTRIB_ARRAY_SIZE 0x8623 +#define GL_VERTEX_ATTRIB_ARRAY_STRIDE 0x8624 +#define GL_VERTEX_ATTRIB_ARRAY_TYPE 0x8625 +#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED 0x886A +#define GL_VERTEX_ATTRIB_ARRAY_POINTER 0x8645 #define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING 0x889F - -/* Read Format */ -#define GL_IMPLEMENTATION_COLOR_READ_TYPE 0x8B9A +#define GL_IMPLEMENTATION_COLOR_READ_TYPE 0x8B9A #define GL_IMPLEMENTATION_COLOR_READ_FORMAT 0x8B9B - -/* Shader Source */ #define GL_COMPILE_STATUS 0x8B81 #define GL_INFO_LOG_LENGTH 0x8B84 #define GL_SHADER_SOURCE_LENGTH 0x8B88 #define GL_SHADER_COMPILER 0x8DFA - -/* Shader Binary */ #define GL_SHADER_BINARY_FORMATS 0x8DF8 #define GL_NUM_SHADER_BINARY_FORMATS 0x8DF9 - -/* Shader Precision-Specified Types */ #define GL_LOW_FLOAT 0x8DF0 #define GL_MEDIUM_FLOAT 0x8DF1 #define GL_HIGH_FLOAT 0x8DF2 #define GL_LOW_INT 0x8DF3 #define GL_MEDIUM_INT 0x8DF4 #define GL_HIGH_INT 0x8DF5 - -/* Framebuffer Object. */ #define GL_FRAMEBUFFER 0x8D40 #define GL_RENDERBUFFER 0x8D41 - #define GL_RGBA4 0x8056 #define GL_RGB5_A1 0x8057 #define GL_RGB565 0x8D62 #define GL_DEPTH_COMPONENT16 0x81A5 #define GL_STENCIL_INDEX8 0x8D48 - #define GL_RENDERBUFFER_WIDTH 0x8D42 #define GL_RENDERBUFFER_HEIGHT 0x8D43 #define GL_RENDERBUFFER_INTERNAL_FORMAT 0x8D44 @@ -442,185 +361,319 @@ typedef khronos_ssize_t GLsizeiptr; #define GL_RENDERBUFFER_ALPHA_SIZE 0x8D53 #define GL_RENDERBUFFER_DEPTH_SIZE 0x8D54 #define GL_RENDERBUFFER_STENCIL_SIZE 0x8D55 - -#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE 0x8CD0 -#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME 0x8CD1 -#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL 0x8CD2 +#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE 0x8CD0 +#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME 0x8CD1 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL 0x8CD2 #define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE 0x8CD3 - #define GL_COLOR_ATTACHMENT0 0x8CE0 #define GL_DEPTH_ATTACHMENT 0x8D00 #define GL_STENCIL_ATTACHMENT 0x8D20 - #define GL_NONE 0 - -#define GL_FRAMEBUFFER_COMPLETE 0x8CD5 -#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT 0x8CD6 +#define GL_FRAMEBUFFER_COMPLETE 0x8CD5 +#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT 0x8CD6 #define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT 0x8CD7 -#define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS 0x8CD9 -#define GL_FRAMEBUFFER_UNSUPPORTED 0x8CDD - +#define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS 0x8CD9 +#define GL_FRAMEBUFFER_UNSUPPORTED 0x8CDD #define GL_FRAMEBUFFER_BINDING 0x8CA6 #define GL_RENDERBUFFER_BINDING 0x8CA7 #define GL_MAX_RENDERBUFFER_SIZE 0x84E8 - #define GL_INVALID_FRAMEBUFFER_OPERATION 0x0506 - -/*------------------------------------------------------------------------- - * GL core functions. - *-----------------------------------------------------------------------*/ +typedef void (GL_APIENTRYP PFNGLACTIVETEXTUREPROC) (GLenum texture); +typedef void (GL_APIENTRYP PFNGLATTACHSHADERPROC) (GLuint program, GLuint shader); +typedef void (GL_APIENTRYP PFNGLBINDATTRIBLOCATIONPROC) (GLuint program, GLuint index, const GLchar *name); +typedef void (GL_APIENTRYP PFNGLBINDBUFFERPROC) (GLenum target, GLuint buffer); +typedef void (GL_APIENTRYP PFNGLBINDFRAMEBUFFERPROC) (GLenum target, GLuint framebuffer); +typedef void (GL_APIENTRYP PFNGLBINDRENDERBUFFERPROC) (GLenum target, GLuint renderbuffer); +typedef void (GL_APIENTRYP PFNGLBINDTEXTUREPROC) (GLenum target, GLuint texture); +typedef void (GL_APIENTRYP PFNGLBLENDCOLORPROC) (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); +typedef void (GL_APIENTRYP PFNGLBLENDEQUATIONPROC) (GLenum mode); +typedef void (GL_APIENTRYP PFNGLBLENDEQUATIONSEPARATEPROC) (GLenum modeRGB, GLenum modeAlpha); +typedef void (GL_APIENTRYP PFNGLBLENDFUNCPROC) (GLenum sfactor, GLenum dfactor); +typedef void (GL_APIENTRYP PFNGLBLENDFUNCSEPARATEPROC) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); +typedef void (GL_APIENTRYP PFNGLBUFFERDATAPROC) (GLenum target, GLsizeiptr size, const void *data, GLenum usage); +typedef void (GL_APIENTRYP PFNGLBUFFERSUBDATAPROC) (GLenum target, GLintptr offset, GLsizeiptr size, const void *data); +typedef GLenum (GL_APIENTRYP PFNGLCHECKFRAMEBUFFERSTATUSPROC) (GLenum target); +typedef void (GL_APIENTRYP PFNGLCLEARPROC) (GLbitfield mask); +typedef void (GL_APIENTRYP PFNGLCLEARCOLORPROC) (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); +typedef void (GL_APIENTRYP PFNGLCLEARDEPTHFPROC) (GLfloat d); +typedef void (GL_APIENTRYP PFNGLCLEARSTENCILPROC) (GLint s); +typedef void (GL_APIENTRYP PFNGLCOLORMASKPROC) (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); +typedef void (GL_APIENTRYP PFNGLCOMPILESHADERPROC) (GLuint shader); +typedef void (GL_APIENTRYP PFNGLCOMPRESSEDTEXIMAGE2DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void *data); +typedef void (GL_APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *data); +typedef void (GL_APIENTRYP PFNGLCOPYTEXIMAGE2DPROC) (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); +typedef void (GL_APIENTRYP PFNGLCOPYTEXSUBIMAGE2DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); +typedef GLuint (GL_APIENTRYP PFNGLCREATEPROGRAMPROC) (void); +typedef GLuint (GL_APIENTRYP PFNGLCREATESHADERPROC) (GLenum type); +typedef void (GL_APIENTRYP PFNGLCULLFACEPROC) (GLenum mode); +typedef void (GL_APIENTRYP PFNGLDELETEBUFFERSPROC) (GLsizei n, const GLuint *buffers); +typedef void (GL_APIENTRYP PFNGLDELETEFRAMEBUFFERSPROC) (GLsizei n, const GLuint *framebuffers); +typedef void (GL_APIENTRYP PFNGLDELETEPROGRAMPROC) (GLuint program); +typedef void (GL_APIENTRYP PFNGLDELETERENDERBUFFERSPROC) (GLsizei n, const GLuint *renderbuffers); +typedef void (GL_APIENTRYP PFNGLDELETESHADERPROC) (GLuint shader); +typedef void (GL_APIENTRYP PFNGLDELETETEXTURESPROC) (GLsizei n, const GLuint *textures); +typedef void (GL_APIENTRYP PFNGLDEPTHFUNCPROC) (GLenum func); +typedef void (GL_APIENTRYP PFNGLDEPTHMASKPROC) (GLboolean flag); +typedef void (GL_APIENTRYP PFNGLDEPTHRANGEFPROC) (GLfloat n, GLfloat f); +typedef void (GL_APIENTRYP PFNGLDETACHSHADERPROC) (GLuint program, GLuint shader); +typedef void (GL_APIENTRYP PFNGLDISABLEPROC) (GLenum cap); +typedef void (GL_APIENTRYP PFNGLDISABLEVERTEXATTRIBARRAYPROC) (GLuint index); +typedef void (GL_APIENTRYP PFNGLDRAWARRAYSPROC) (GLenum mode, GLint first, GLsizei count); +typedef void (GL_APIENTRYP PFNGLDRAWELEMENTSPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices); +typedef void (GL_APIENTRYP PFNGLENABLEPROC) (GLenum cap); +typedef void (GL_APIENTRYP PFNGLENABLEVERTEXATTRIBARRAYPROC) (GLuint index); +typedef void (GL_APIENTRYP PFNGLFINISHPROC) (void); +typedef void (GL_APIENTRYP PFNGLFLUSHPROC) (void); +typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERRENDERBUFFERPROC) (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); +typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERTEXTURE2DPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +typedef void (GL_APIENTRYP PFNGLFRONTFACEPROC) (GLenum mode); +typedef void (GL_APIENTRYP PFNGLGENBUFFERSPROC) (GLsizei n, GLuint *buffers); +typedef void (GL_APIENTRYP PFNGLGENERATEMIPMAPPROC) (GLenum target); +typedef void (GL_APIENTRYP PFNGLGENFRAMEBUFFERSPROC) (GLsizei n, GLuint *framebuffers); +typedef void (GL_APIENTRYP PFNGLGENRENDERBUFFERSPROC) (GLsizei n, GLuint *renderbuffers); +typedef void (GL_APIENTRYP PFNGLGENTEXTURESPROC) (GLsizei n, GLuint *textures); +typedef void (GL_APIENTRYP PFNGLGETACTIVEATTRIBPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name); +typedef void (GL_APIENTRYP PFNGLGETACTIVEUNIFORMPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name); +typedef void (GL_APIENTRYP PFNGLGETATTACHEDSHADERSPROC) (GLuint program, GLsizei maxCount, GLsizei *count, GLuint *shaders); +typedef GLint (GL_APIENTRYP PFNGLGETATTRIBLOCATIONPROC) (GLuint program, const GLchar *name); +typedef void (GL_APIENTRYP PFNGLGETBOOLEANVPROC) (GLenum pname, GLboolean *data); +typedef void (GL_APIENTRYP PFNGLGETBUFFERPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); +typedef GLenum (GL_APIENTRYP PFNGLGETERRORPROC) (void); +typedef void (GL_APIENTRYP PFNGLGETFLOATVPROC) (GLenum pname, GLfloat *data); +typedef void (GL_APIENTRYP PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC) (GLenum target, GLenum attachment, GLenum pname, GLint *params); +typedef void (GL_APIENTRYP PFNGLGETINTEGERVPROC) (GLenum pname, GLint *data); +typedef void (GL_APIENTRYP PFNGLGETPROGRAMIVPROC) (GLuint program, GLenum pname, GLint *params); +typedef void (GL_APIENTRYP PFNGLGETPROGRAMINFOLOGPROC) (GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog); +typedef void (GL_APIENTRYP PFNGLGETRENDERBUFFERPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (GL_APIENTRYP PFNGLGETSHADERIVPROC) (GLuint shader, GLenum pname, GLint *params); +typedef void (GL_APIENTRYP PFNGLGETSHADERINFOLOGPROC) (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog); +typedef void (GL_APIENTRYP PFNGLGETSHADERPRECISIONFORMATPROC) (GLenum shadertype, GLenum precisiontype, GLint *range, GLint *precision); +typedef void (GL_APIENTRYP PFNGLGETSHADERSOURCEPROC) (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *source); +typedef const GLubyte *(GL_APIENTRYP PFNGLGETSTRINGPROC) (GLenum name); +typedef void (GL_APIENTRYP PFNGLGETTEXPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params); +typedef void (GL_APIENTRYP PFNGLGETTEXPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (GL_APIENTRYP PFNGLGETUNIFORMFVPROC) (GLuint program, GLint location, GLfloat *params); +typedef void (GL_APIENTRYP PFNGLGETUNIFORMIVPROC) (GLuint program, GLint location, GLint *params); +typedef GLint (GL_APIENTRYP PFNGLGETUNIFORMLOCATIONPROC) (GLuint program, const GLchar *name); +typedef void (GL_APIENTRYP PFNGLGETVERTEXATTRIBFVPROC) (GLuint index, GLenum pname, GLfloat *params); +typedef void (GL_APIENTRYP PFNGLGETVERTEXATTRIBIVPROC) (GLuint index, GLenum pname, GLint *params); +typedef void (GL_APIENTRYP PFNGLGETVERTEXATTRIBPOINTERVPROC) (GLuint index, GLenum pname, void **pointer); +typedef void (GL_APIENTRYP PFNGLHINTPROC) (GLenum target, GLenum mode); +typedef GLboolean (GL_APIENTRYP PFNGLISBUFFERPROC) (GLuint buffer); +typedef GLboolean (GL_APIENTRYP PFNGLISENABLEDPROC) (GLenum cap); +typedef GLboolean (GL_APIENTRYP PFNGLISFRAMEBUFFERPROC) (GLuint framebuffer); +typedef GLboolean (GL_APIENTRYP PFNGLISPROGRAMPROC) (GLuint program); +typedef GLboolean (GL_APIENTRYP PFNGLISRENDERBUFFERPROC) (GLuint renderbuffer); +typedef GLboolean (GL_APIENTRYP PFNGLISSHADERPROC) (GLuint shader); +typedef GLboolean (GL_APIENTRYP PFNGLISTEXTUREPROC) (GLuint texture); +typedef void (GL_APIENTRYP PFNGLLINEWIDTHPROC) (GLfloat width); +typedef void (GL_APIENTRYP PFNGLLINKPROGRAMPROC) (GLuint program); +typedef void (GL_APIENTRYP PFNGLPIXELSTOREIPROC) (GLenum pname, GLint param); +typedef void (GL_APIENTRYP PFNGLPOLYGONOFFSETPROC) (GLfloat factor, GLfloat units); +typedef void (GL_APIENTRYP PFNGLREADPIXELSPROC) (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void *pixels); +typedef void (GL_APIENTRYP PFNGLRELEASESHADERCOMPILERPROC) (void); +typedef void (GL_APIENTRYP PFNGLRENDERBUFFERSTORAGEPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (GL_APIENTRYP PFNGLSAMPLECOVERAGEPROC) (GLfloat value, GLboolean invert); +typedef void (GL_APIENTRYP PFNGLSCISSORPROC) (GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (GL_APIENTRYP PFNGLSHADERBINARYPROC) (GLsizei count, const GLuint *shaders, GLenum binaryformat, const void *binary, GLsizei length); +typedef void (GL_APIENTRYP PFNGLSHADERSOURCEPROC) (GLuint shader, GLsizei count, const GLchar *const*string, const GLint *length); +typedef void (GL_APIENTRYP PFNGLSTENCILFUNCPROC) (GLenum func, GLint ref, GLuint mask); +typedef void (GL_APIENTRYP PFNGLSTENCILFUNCSEPARATEPROC) (GLenum face, GLenum func, GLint ref, GLuint mask); +typedef void (GL_APIENTRYP PFNGLSTENCILMASKPROC) (GLuint mask); +typedef void (GL_APIENTRYP PFNGLSTENCILMASKSEPARATEPROC) (GLenum face, GLuint mask); +typedef void (GL_APIENTRYP PFNGLSTENCILOPPROC) (GLenum fail, GLenum zfail, GLenum zpass); +typedef void (GL_APIENTRYP PFNGLSTENCILOPSEPARATEPROC) (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass); +typedef void (GL_APIENTRYP PFNGLTEXIMAGE2DPROC) (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels); +typedef void (GL_APIENTRYP PFNGLTEXPARAMETERFPROC) (GLenum target, GLenum pname, GLfloat param); +typedef void (GL_APIENTRYP PFNGLTEXPARAMETERFVPROC) (GLenum target, GLenum pname, const GLfloat *params); +typedef void (GL_APIENTRYP PFNGLTEXPARAMETERIPROC) (GLenum target, GLenum pname, GLint param); +typedef void (GL_APIENTRYP PFNGLTEXPARAMETERIVPROC) (GLenum target, GLenum pname, const GLint *params); +typedef void (GL_APIENTRYP PFNGLTEXSUBIMAGE2DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels); +typedef void (GL_APIENTRYP PFNGLUNIFORM1FPROC) (GLint location, GLfloat v0); +typedef void (GL_APIENTRYP PFNGLUNIFORM1FVPROC) (GLint location, GLsizei count, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLUNIFORM1IPROC) (GLint location, GLint v0); +typedef void (GL_APIENTRYP PFNGLUNIFORM1IVPROC) (GLint location, GLsizei count, const GLint *value); +typedef void (GL_APIENTRYP PFNGLUNIFORM2FPROC) (GLint location, GLfloat v0, GLfloat v1); +typedef void (GL_APIENTRYP PFNGLUNIFORM2FVPROC) (GLint location, GLsizei count, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLUNIFORM2IPROC) (GLint location, GLint v0, GLint v1); +typedef void (GL_APIENTRYP PFNGLUNIFORM2IVPROC) (GLint location, GLsizei count, const GLint *value); +typedef void (GL_APIENTRYP PFNGLUNIFORM3FPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2); +typedef void (GL_APIENTRYP PFNGLUNIFORM3FVPROC) (GLint location, GLsizei count, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLUNIFORM3IPROC) (GLint location, GLint v0, GLint v1, GLint v2); +typedef void (GL_APIENTRYP PFNGLUNIFORM3IVPROC) (GLint location, GLsizei count, const GLint *value); +typedef void (GL_APIENTRYP PFNGLUNIFORM4FPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); +typedef void (GL_APIENTRYP PFNGLUNIFORM4FVPROC) (GLint location, GLsizei count, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLUNIFORM4IPROC) (GLint location, GLint v0, GLint v1, GLint v2, GLint v3); +typedef void (GL_APIENTRYP PFNGLUNIFORM4IVPROC) (GLint location, GLsizei count, const GLint *value); +typedef void (GL_APIENTRYP PFNGLUNIFORMMATRIX2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLUNIFORMMATRIX3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLUNIFORMMATRIX4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLUSEPROGRAMPROC) (GLuint program); +typedef void (GL_APIENTRYP PFNGLVALIDATEPROGRAMPROC) (GLuint program); +typedef void (GL_APIENTRYP PFNGLVERTEXATTRIB1FPROC) (GLuint index, GLfloat x); +typedef void (GL_APIENTRYP PFNGLVERTEXATTRIB1FVPROC) (GLuint index, const GLfloat *v); +typedef void (GL_APIENTRYP PFNGLVERTEXATTRIB2FPROC) (GLuint index, GLfloat x, GLfloat y); +typedef void (GL_APIENTRYP PFNGLVERTEXATTRIB2FVPROC) (GLuint index, const GLfloat *v); +typedef void (GL_APIENTRYP PFNGLVERTEXATTRIB3FPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z); +typedef void (GL_APIENTRYP PFNGLVERTEXATTRIB3FVPROC) (GLuint index, const GLfloat *v); +typedef void (GL_APIENTRYP PFNGLVERTEXATTRIB4FPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (GL_APIENTRYP PFNGLVERTEXATTRIB4FVPROC) (GLuint index, const GLfloat *v); +typedef void (GL_APIENTRYP PFNGLVERTEXATTRIBPOINTERPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer); +typedef void (GL_APIENTRYP PFNGLVIEWPORTPROC) (GLint x, GLint y, GLsizei width, GLsizei height); #if defined(_MSC_VER) && !defined(ANGLE_WEBKIT_WIN) #include #else -GL_APICALL void GL_APIENTRY glActiveTexture (GLenum texture); -GL_APICALL void GL_APIENTRY glAttachShader (GLuint program, GLuint shader); -GL_APICALL void GL_APIENTRY glBindAttribLocation (GLuint program, GLuint index, const GLchar* name); -GL_APICALL void GL_APIENTRY glBindBuffer (GLenum target, GLuint buffer); -GL_APICALL void GL_APIENTRY glBindFramebuffer (GLenum target, GLuint framebuffer); -GL_APICALL void GL_APIENTRY glBindRenderbuffer (GLenum target, GLuint renderbuffer); -GL_APICALL void GL_APIENTRY glBindTexture (GLenum target, GLuint texture); -GL_APICALL void GL_APIENTRY glBlendColor (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); -GL_APICALL void GL_APIENTRY glBlendEquation ( GLenum mode ); -GL_APICALL void GL_APIENTRY glBlendEquationSeparate (GLenum modeRGB, GLenum modeAlpha); -GL_APICALL void GL_APIENTRY glBlendFunc (GLenum sfactor, GLenum dfactor); -GL_APICALL void GL_APIENTRY glBlendFuncSeparate (GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha); -GL_APICALL void GL_APIENTRY glBufferData (GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage); -GL_APICALL void GL_APIENTRY glBufferSubData (GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data); -GL_APICALL GLenum GL_APIENTRY glCheckFramebufferStatus (GLenum target); -GL_APICALL void GL_APIENTRY glClear (GLbitfield mask); -GL_APICALL void GL_APIENTRY glClearColor (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); -GL_APICALL void GL_APIENTRY glClearDepthf (GLclampf depth); -GL_APICALL void GL_APIENTRY glClearStencil (GLint s); -GL_APICALL void GL_APIENTRY glColorMask (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); -GL_APICALL void GL_APIENTRY glCompileShader (GLuint shader); -GL_APICALL void GL_APIENTRY glCompressedTexImage2D (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid* data); -GL_APICALL void GL_APIENTRY glCompressedTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid* data); -GL_APICALL void GL_APIENTRY glCopyTexImage2D (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); -GL_APICALL void GL_APIENTRY glCopyTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); -GL_APICALL GLuint GL_APIENTRY glCreateProgram (void); -GL_APICALL GLuint GL_APIENTRY glCreateShader (GLenum type); -GL_APICALL void GL_APIENTRY glCullFace (GLenum mode); -GL_APICALL void GL_APIENTRY glDeleteBuffers (GLsizei n, const GLuint* buffers); -GL_APICALL void GL_APIENTRY glDeleteFramebuffers (GLsizei n, const GLuint* framebuffers); -GL_APICALL void GL_APIENTRY glDeleteProgram (GLuint program); -GL_APICALL void GL_APIENTRY glDeleteRenderbuffers (GLsizei n, const GLuint* renderbuffers); -GL_APICALL void GL_APIENTRY glDeleteShader (GLuint shader); -GL_APICALL void GL_APIENTRY glDeleteTextures (GLsizei n, const GLuint* textures); -GL_APICALL void GL_APIENTRY glDepthFunc (GLenum func); -GL_APICALL void GL_APIENTRY glDepthMask (GLboolean flag); -GL_APICALL void GL_APIENTRY glDepthRangef (GLclampf zNear, GLclampf zFar); -GL_APICALL void GL_APIENTRY glDetachShader (GLuint program, GLuint shader); -GL_APICALL void GL_APIENTRY glDisable (GLenum cap); -GL_APICALL void GL_APIENTRY glDisableVertexAttribArray (GLuint index); -GL_APICALL void GL_APIENTRY glDrawArrays (GLenum mode, GLint first, GLsizei count); -GL_APICALL void GL_APIENTRY glDrawElements (GLenum mode, GLsizei count, GLenum type, const GLvoid* indices); -GL_APICALL void GL_APIENTRY glEnable (GLenum cap); -GL_APICALL void GL_APIENTRY glEnableVertexAttribArray (GLuint index); -GL_APICALL void GL_APIENTRY glFinish (void); -GL_APICALL void GL_APIENTRY glFlush (void); -GL_APICALL void GL_APIENTRY glFramebufferRenderbuffer (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); -GL_APICALL void GL_APIENTRY glFramebufferTexture2D (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); -GL_APICALL void GL_APIENTRY glFrontFace (GLenum mode); -GL_APICALL void GL_APIENTRY glGenBuffers (GLsizei n, GLuint* buffers); -GL_APICALL void GL_APIENTRY glGenerateMipmap (GLenum target); -GL_APICALL void GL_APIENTRY glGenFramebuffers (GLsizei n, GLuint* framebuffers); -GL_APICALL void GL_APIENTRY glGenRenderbuffers (GLsizei n, GLuint* renderbuffers); -GL_APICALL void GL_APIENTRY glGenTextures (GLsizei n, GLuint* textures); -GL_APICALL void GL_APIENTRY glGetActiveAttrib (GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name); -GL_APICALL void GL_APIENTRY glGetActiveUniform (GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name); -GL_APICALL void GL_APIENTRY glGetAttachedShaders (GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders); -GL_APICALL GLint GL_APIENTRY glGetAttribLocation (GLuint program, const GLchar* name); -GL_APICALL void GL_APIENTRY glGetBooleanv (GLenum pname, GLboolean* params); -GL_APICALL void GL_APIENTRY glGetBufferParameteriv (GLenum target, GLenum pname, GLint* params); -GL_APICALL GLenum GL_APIENTRY glGetError (void); -GL_APICALL void GL_APIENTRY glGetFloatv (GLenum pname, GLfloat* params); -GL_APICALL void GL_APIENTRY glGetFramebufferAttachmentParameteriv (GLenum target, GLenum attachment, GLenum pname, GLint* params); -GL_APICALL void GL_APIENTRY glGetIntegerv (GLenum pname, GLint* params); -GL_APICALL void GL_APIENTRY glGetProgramiv (GLuint program, GLenum pname, GLint* params); -GL_APICALL void GL_APIENTRY glGetProgramInfoLog (GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog); -GL_APICALL void GL_APIENTRY glGetRenderbufferParameteriv (GLenum target, GLenum pname, GLint* params); -GL_APICALL void GL_APIENTRY glGetShaderiv (GLuint shader, GLenum pname, GLint* params); -GL_APICALL void GL_APIENTRY glGetShaderInfoLog (GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog); -GL_APICALL void GL_APIENTRY glGetShaderPrecisionFormat (GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision); -GL_APICALL void GL_APIENTRY glGetShaderSource (GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source); -GL_APICALL const GLubyte* GL_APIENTRY glGetString (GLenum name); -GL_APICALL void GL_APIENTRY glGetTexParameterfv (GLenum target, GLenum pname, GLfloat* params); -GL_APICALL void GL_APIENTRY glGetTexParameteriv (GLenum target, GLenum pname, GLint* params); -GL_APICALL void GL_APIENTRY glGetUniformfv (GLuint program, GLint location, GLfloat* params); -GL_APICALL void GL_APIENTRY glGetUniformiv (GLuint program, GLint location, GLint* params); -GL_APICALL GLint GL_APIENTRY glGetUniformLocation (GLuint program, const GLchar* name); -GL_APICALL void GL_APIENTRY glGetVertexAttribfv (GLuint index, GLenum pname, GLfloat* params); -GL_APICALL void GL_APIENTRY glGetVertexAttribiv (GLuint index, GLenum pname, GLint* params); -GL_APICALL void GL_APIENTRY glGetVertexAttribPointerv (GLuint index, GLenum pname, GLvoid** pointer); -GL_APICALL void GL_APIENTRY glHint (GLenum target, GLenum mode); -GL_APICALL GLboolean GL_APIENTRY glIsBuffer (GLuint buffer); -GL_APICALL GLboolean GL_APIENTRY glIsEnabled (GLenum cap); -GL_APICALL GLboolean GL_APIENTRY glIsFramebuffer (GLuint framebuffer); -GL_APICALL GLboolean GL_APIENTRY glIsProgram (GLuint program); -GL_APICALL GLboolean GL_APIENTRY glIsRenderbuffer (GLuint renderbuffer); -GL_APICALL GLboolean GL_APIENTRY glIsShader (GLuint shader); -GL_APICALL GLboolean GL_APIENTRY glIsTexture (GLuint texture); -GL_APICALL void GL_APIENTRY glLineWidth (GLfloat width); -GL_APICALL void GL_APIENTRY glLinkProgram (GLuint program); -GL_APICALL void GL_APIENTRY glPixelStorei (GLenum pname, GLint param); -GL_APICALL void GL_APIENTRY glPolygonOffset (GLfloat factor, GLfloat units); -GL_APICALL void GL_APIENTRY glReadPixels (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels); -GL_APICALL void GL_APIENTRY glReleaseShaderCompiler (void); -GL_APICALL void GL_APIENTRY glRenderbufferStorage (GLenum target, GLenum internalformat, GLsizei width, GLsizei height); -GL_APICALL void GL_APIENTRY glSampleCoverage (GLclampf value, GLboolean invert); -GL_APICALL void GL_APIENTRY glScissor (GLint x, GLint y, GLsizei width, GLsizei height); -GL_APICALL void GL_APIENTRY glShaderBinary (GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length); -GL_APICALL void GL_APIENTRY glShaderSource (GLuint shader, GLsizei count, const GLchar* const* string, const GLint* length); -GL_APICALL void GL_APIENTRY glStencilFunc (GLenum func, GLint ref, GLuint mask); -GL_APICALL void GL_APIENTRY glStencilFuncSeparate (GLenum face, GLenum func, GLint ref, GLuint mask); -GL_APICALL void GL_APIENTRY glStencilMask (GLuint mask); -GL_APICALL void GL_APIENTRY glStencilMaskSeparate (GLenum face, GLuint mask); -GL_APICALL void GL_APIENTRY glStencilOp (GLenum fail, GLenum zfail, GLenum zpass); -GL_APICALL void GL_APIENTRY glStencilOpSeparate (GLenum face, GLenum fail, GLenum zfail, GLenum zpass); -GL_APICALL void GL_APIENTRY glTexImage2D (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid* pixels); -GL_APICALL void GL_APIENTRY glTexParameterf (GLenum target, GLenum pname, GLfloat param); -GL_APICALL void GL_APIENTRY glTexParameterfv (GLenum target, GLenum pname, const GLfloat* params); -GL_APICALL void GL_APIENTRY glTexParameteri (GLenum target, GLenum pname, GLint param); -GL_APICALL void GL_APIENTRY glTexParameteriv (GLenum target, GLenum pname, const GLint* params); -GL_APICALL void GL_APIENTRY glTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid* pixels); -GL_APICALL void GL_APIENTRY glUniform1f (GLint location, GLfloat x); -GL_APICALL void GL_APIENTRY glUniform1fv (GLint location, GLsizei count, const GLfloat* v); -GL_APICALL void GL_APIENTRY glUniform1i (GLint location, GLint x); -GL_APICALL void GL_APIENTRY glUniform1iv (GLint location, GLsizei count, const GLint* v); -GL_APICALL void GL_APIENTRY glUniform2f (GLint location, GLfloat x, GLfloat y); -GL_APICALL void GL_APIENTRY glUniform2fv (GLint location, GLsizei count, const GLfloat* v); -GL_APICALL void GL_APIENTRY glUniform2i (GLint location, GLint x, GLint y); -GL_APICALL void GL_APIENTRY glUniform2iv (GLint location, GLsizei count, const GLint* v); -GL_APICALL void GL_APIENTRY glUniform3f (GLint location, GLfloat x, GLfloat y, GLfloat z); -GL_APICALL void GL_APIENTRY glUniform3fv (GLint location, GLsizei count, const GLfloat* v); -GL_APICALL void GL_APIENTRY glUniform3i (GLint location, GLint x, GLint y, GLint z); -GL_APICALL void GL_APIENTRY glUniform3iv (GLint location, GLsizei count, const GLint* v); -GL_APICALL void GL_APIENTRY glUniform4f (GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w); -GL_APICALL void GL_APIENTRY glUniform4fv (GLint location, GLsizei count, const GLfloat* v); -GL_APICALL void GL_APIENTRY glUniform4i (GLint location, GLint x, GLint y, GLint z, GLint w); -GL_APICALL void GL_APIENTRY glUniform4iv (GLint location, GLsizei count, const GLint* v); -GL_APICALL void GL_APIENTRY glUniformMatrix2fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); -GL_APICALL void GL_APIENTRY glUniformMatrix3fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); -GL_APICALL void GL_APIENTRY glUniformMatrix4fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); -GL_APICALL void GL_APIENTRY glUseProgram (GLuint program); -GL_APICALL void GL_APIENTRY glValidateProgram (GLuint program); -GL_APICALL void GL_APIENTRY glVertexAttrib1f (GLuint indx, GLfloat x); -GL_APICALL void GL_APIENTRY glVertexAttrib1fv (GLuint indx, const GLfloat* values); -GL_APICALL void GL_APIENTRY glVertexAttrib2f (GLuint indx, GLfloat x, GLfloat y); -GL_APICALL void GL_APIENTRY glVertexAttrib2fv (GLuint indx, const GLfloat* values); -GL_APICALL void GL_APIENTRY glVertexAttrib3f (GLuint indx, GLfloat x, GLfloat y, GLfloat z); -GL_APICALL void GL_APIENTRY glVertexAttrib3fv (GLuint indx, const GLfloat* values); -GL_APICALL void GL_APIENTRY glVertexAttrib4f (GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w); -GL_APICALL void GL_APIENTRY glVertexAttrib4fv (GLuint indx, const GLfloat* values); -GL_APICALL void GL_APIENTRY glVertexAttribPointer (GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr); -GL_APICALL void GL_APIENTRY glViewport (GLint x, GLint y, GLsizei width, GLsizei height); - +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glActiveTexture (GLenum texture); +GL_APICALL void GL_APIENTRY glAttachShader (GLuint program, GLuint shader); +GL_APICALL void GL_APIENTRY glBindAttribLocation (GLuint program, GLuint index, const GLchar *name); +GL_APICALL void GL_APIENTRY glBindBuffer (GLenum target, GLuint buffer); +GL_APICALL void GL_APIENTRY glBindFramebuffer (GLenum target, GLuint framebuffer); +GL_APICALL void GL_APIENTRY glBindRenderbuffer (GLenum target, GLuint renderbuffer); +GL_APICALL void GL_APIENTRY glBindTexture (GLenum target, GLuint texture); +GL_APICALL void GL_APIENTRY glBlendColor (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); +GL_APICALL void GL_APIENTRY glBlendEquation (GLenum mode); +GL_APICALL void GL_APIENTRY glBlendEquationSeparate (GLenum modeRGB, GLenum modeAlpha); +GL_APICALL void GL_APIENTRY glBlendFunc (GLenum sfactor, GLenum dfactor); +GL_APICALL void GL_APIENTRY glBlendFuncSeparate (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); +GL_APICALL void GL_APIENTRY glBufferData (GLenum target, GLsizeiptr size, const void *data, GLenum usage); +GL_APICALL void GL_APIENTRY glBufferSubData (GLenum target, GLintptr offset, GLsizeiptr size, const void *data); +GL_APICALL GLenum GL_APIENTRY glCheckFramebufferStatus (GLenum target); +GL_APICALL void GL_APIENTRY glClear (GLbitfield mask); +GL_APICALL void GL_APIENTRY glClearColor (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); +GL_APICALL void GL_APIENTRY glClearDepthf (GLfloat d); +GL_APICALL void GL_APIENTRY glClearStencil (GLint s); +GL_APICALL void GL_APIENTRY glColorMask (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); +GL_APICALL void GL_APIENTRY glCompileShader (GLuint shader); +GL_APICALL void GL_APIENTRY glCompressedTexImage2D (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void *data); +GL_APICALL void GL_APIENTRY glCompressedTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *data); +GL_APICALL void GL_APIENTRY glCopyTexImage2D (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); +GL_APICALL void GL_APIENTRY glCopyTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); +GL_APICALL GLuint GL_APIENTRY glCreateProgram (void); +GL_APICALL GLuint GL_APIENTRY glCreateShader (GLenum type); +GL_APICALL void GL_APIENTRY glCullFace (GLenum mode); +GL_APICALL void GL_APIENTRY glDeleteBuffers (GLsizei n, const GLuint *buffers); +GL_APICALL void GL_APIENTRY glDeleteFramebuffers (GLsizei n, const GLuint *framebuffers); +GL_APICALL void GL_APIENTRY glDeleteProgram (GLuint program); +GL_APICALL void GL_APIENTRY glDeleteRenderbuffers (GLsizei n, const GLuint *renderbuffers); +GL_APICALL void GL_APIENTRY glDeleteShader (GLuint shader); +GL_APICALL void GL_APIENTRY glDeleteTextures (GLsizei n, const GLuint *textures); +GL_APICALL void GL_APIENTRY glDepthFunc (GLenum func); +GL_APICALL void GL_APIENTRY glDepthMask (GLboolean flag); +GL_APICALL void GL_APIENTRY glDepthRangef (GLfloat n, GLfloat f); +GL_APICALL void GL_APIENTRY glDetachShader (GLuint program, GLuint shader); +GL_APICALL void GL_APIENTRY glDisable (GLenum cap); +GL_APICALL void GL_APIENTRY glDisableVertexAttribArray (GLuint index); +GL_APICALL void GL_APIENTRY glDrawArrays (GLenum mode, GLint first, GLsizei count); +GL_APICALL void GL_APIENTRY glDrawElements (GLenum mode, GLsizei count, GLenum type, const void *indices); +GL_APICALL void GL_APIENTRY glEnable (GLenum cap); +GL_APICALL void GL_APIENTRY glEnableVertexAttribArray (GLuint index); +GL_APICALL void GL_APIENTRY glFinish (void); +GL_APICALL void GL_APIENTRY glFlush (void); +GL_APICALL void GL_APIENTRY glFramebufferRenderbuffer (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); +GL_APICALL void GL_APIENTRY glFramebufferTexture2D (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +GL_APICALL void GL_APIENTRY glFrontFace (GLenum mode); +GL_APICALL void GL_APIENTRY glGenBuffers (GLsizei n, GLuint *buffers); +GL_APICALL void GL_APIENTRY glGenerateMipmap (GLenum target); +GL_APICALL void GL_APIENTRY glGenFramebuffers (GLsizei n, GLuint *framebuffers); +GL_APICALL void GL_APIENTRY glGenRenderbuffers (GLsizei n, GLuint *renderbuffers); +GL_APICALL void GL_APIENTRY glGenTextures (GLsizei n, GLuint *textures); +GL_APICALL void GL_APIENTRY glGetActiveAttrib (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name); +GL_APICALL void GL_APIENTRY glGetActiveUniform (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name); +GL_APICALL void GL_APIENTRY glGetAttachedShaders (GLuint program, GLsizei maxCount, GLsizei *count, GLuint *shaders); +GL_APICALL GLint GL_APIENTRY glGetAttribLocation (GLuint program, const GLchar *name); +GL_APICALL void GL_APIENTRY glGetBooleanv (GLenum pname, GLboolean *data); +GL_APICALL void GL_APIENTRY glGetBufferParameteriv (GLenum target, GLenum pname, GLint *params); +GL_APICALL GLenum GL_APIENTRY glGetError (void); +GL_APICALL void GL_APIENTRY glGetFloatv (GLenum pname, GLfloat *data); +GL_APICALL void GL_APIENTRY glGetFramebufferAttachmentParameteriv (GLenum target, GLenum attachment, GLenum pname, GLint *params); +GL_APICALL void GL_APIENTRY glGetIntegerv (GLenum pname, GLint *data); +GL_APICALL void GL_APIENTRY glGetProgramiv (GLuint program, GLenum pname, GLint *params); +GL_APICALL void GL_APIENTRY glGetProgramInfoLog (GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog); +GL_APICALL void GL_APIENTRY glGetRenderbufferParameteriv (GLenum target, GLenum pname, GLint *params); +GL_APICALL void GL_APIENTRY glGetShaderiv (GLuint shader, GLenum pname, GLint *params); +GL_APICALL void GL_APIENTRY glGetShaderInfoLog (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog); +GL_APICALL void GL_APIENTRY glGetShaderPrecisionFormat (GLenum shadertype, GLenum precisiontype, GLint *range, GLint *precision); +GL_APICALL void GL_APIENTRY glGetShaderSource (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *source); +GL_APICALL const GLubyte *GL_APIENTRY glGetString (GLenum name); +GL_APICALL void GL_APIENTRY glGetTexParameterfv (GLenum target, GLenum pname, GLfloat *params); +GL_APICALL void GL_APIENTRY glGetTexParameteriv (GLenum target, GLenum pname, GLint *params); +GL_APICALL void GL_APIENTRY glGetUniformfv (GLuint program, GLint location, GLfloat *params); +GL_APICALL void GL_APIENTRY glGetUniformiv (GLuint program, GLint location, GLint *params); +GL_APICALL GLint GL_APIENTRY glGetUniformLocation (GLuint program, const GLchar *name); +GL_APICALL void GL_APIENTRY glGetVertexAttribfv (GLuint index, GLenum pname, GLfloat *params); +GL_APICALL void GL_APIENTRY glGetVertexAttribiv (GLuint index, GLenum pname, GLint *params); +GL_APICALL void GL_APIENTRY glGetVertexAttribPointerv (GLuint index, GLenum pname, void **pointer); +GL_APICALL void GL_APIENTRY glHint (GLenum target, GLenum mode); +GL_APICALL GLboolean GL_APIENTRY glIsBuffer (GLuint buffer); +GL_APICALL GLboolean GL_APIENTRY glIsEnabled (GLenum cap); +GL_APICALL GLboolean GL_APIENTRY glIsFramebuffer (GLuint framebuffer); +GL_APICALL GLboolean GL_APIENTRY glIsProgram (GLuint program); +GL_APICALL GLboolean GL_APIENTRY glIsRenderbuffer (GLuint renderbuffer); +GL_APICALL GLboolean GL_APIENTRY glIsShader (GLuint shader); +GL_APICALL GLboolean GL_APIENTRY glIsTexture (GLuint texture); +GL_APICALL void GL_APIENTRY glLineWidth (GLfloat width); +GL_APICALL void GL_APIENTRY glLinkProgram (GLuint program); +GL_APICALL void GL_APIENTRY glPixelStorei (GLenum pname, GLint param); +GL_APICALL void GL_APIENTRY glPolygonOffset (GLfloat factor, GLfloat units); +GL_APICALL void GL_APIENTRY glReadPixels (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void *pixels); +GL_APICALL void GL_APIENTRY glReleaseShaderCompiler (void); +GL_APICALL void GL_APIENTRY glRenderbufferStorage (GLenum target, GLenum internalformat, GLsizei width, GLsizei height); +GL_APICALL void GL_APIENTRY glSampleCoverage (GLfloat value, GLboolean invert); +GL_APICALL void GL_APIENTRY glScissor (GLint x, GLint y, GLsizei width, GLsizei height); +GL_APICALL void GL_APIENTRY glShaderBinary (GLsizei count, const GLuint *shaders, GLenum binaryformat, const void *binary, GLsizei length); +GL_APICALL void GL_APIENTRY glShaderSource (GLuint shader, GLsizei count, const GLchar *const*string, const GLint *length); +GL_APICALL void GL_APIENTRY glStencilFunc (GLenum func, GLint ref, GLuint mask); +GL_APICALL void GL_APIENTRY glStencilFuncSeparate (GLenum face, GLenum func, GLint ref, GLuint mask); +GL_APICALL void GL_APIENTRY glStencilMask (GLuint mask); +GL_APICALL void GL_APIENTRY glStencilMaskSeparate (GLenum face, GLuint mask); +GL_APICALL void GL_APIENTRY glStencilOp (GLenum fail, GLenum zfail, GLenum zpass); +GL_APICALL void GL_APIENTRY glStencilOpSeparate (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass); +GL_APICALL void GL_APIENTRY glTexImage2D (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels); +GL_APICALL void GL_APIENTRY glTexParameterf (GLenum target, GLenum pname, GLfloat param); +GL_APICALL void GL_APIENTRY glTexParameterfv (GLenum target, GLenum pname, const GLfloat *params); +GL_APICALL void GL_APIENTRY glTexParameteri (GLenum target, GLenum pname, GLint param); +GL_APICALL void GL_APIENTRY glTexParameteriv (GLenum target, GLenum pname, const GLint *params); +GL_APICALL void GL_APIENTRY glTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels); +GL_APICALL void GL_APIENTRY glUniform1f (GLint location, GLfloat v0); +GL_APICALL void GL_APIENTRY glUniform1fv (GLint location, GLsizei count, const GLfloat *value); +GL_APICALL void GL_APIENTRY glUniform1i (GLint location, GLint v0); +GL_APICALL void GL_APIENTRY glUniform1iv (GLint location, GLsizei count, const GLint *value); +GL_APICALL void GL_APIENTRY glUniform2f (GLint location, GLfloat v0, GLfloat v1); +GL_APICALL void GL_APIENTRY glUniform2fv (GLint location, GLsizei count, const GLfloat *value); +GL_APICALL void GL_APIENTRY glUniform2i (GLint location, GLint v0, GLint v1); +GL_APICALL void GL_APIENTRY glUniform2iv (GLint location, GLsizei count, const GLint *value); +GL_APICALL void GL_APIENTRY glUniform3f (GLint location, GLfloat v0, GLfloat v1, GLfloat v2); +GL_APICALL void GL_APIENTRY glUniform3fv (GLint location, GLsizei count, const GLfloat *value); +GL_APICALL void GL_APIENTRY glUniform3i (GLint location, GLint v0, GLint v1, GLint v2); +GL_APICALL void GL_APIENTRY glUniform3iv (GLint location, GLsizei count, const GLint *value); +GL_APICALL void GL_APIENTRY glUniform4f (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); +GL_APICALL void GL_APIENTRY glUniform4fv (GLint location, GLsizei count, const GLfloat *value); +GL_APICALL void GL_APIENTRY glUniform4i (GLint location, GLint v0, GLint v1, GLint v2, GLint v3); +GL_APICALL void GL_APIENTRY glUniform4iv (GLint location, GLsizei count, const GLint *value); +GL_APICALL void GL_APIENTRY glUniformMatrix2fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GL_APICALL void GL_APIENTRY glUniformMatrix3fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GL_APICALL void GL_APIENTRY glUniformMatrix4fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GL_APICALL void GL_APIENTRY glUseProgram (GLuint program); +GL_APICALL void GL_APIENTRY glValidateProgram (GLuint program); +GL_APICALL void GL_APIENTRY glVertexAttrib1f (GLuint index, GLfloat x); +GL_APICALL void GL_APIENTRY glVertexAttrib1fv (GLuint index, const GLfloat *v); +GL_APICALL void GL_APIENTRY glVertexAttrib2f (GLuint index, GLfloat x, GLfloat y); +GL_APICALL void GL_APIENTRY glVertexAttrib2fv (GLuint index, const GLfloat *v); +GL_APICALL void GL_APIENTRY glVertexAttrib3f (GLuint index, GLfloat x, GLfloat y, GLfloat z); +GL_APICALL void GL_APIENTRY glVertexAttrib3fv (GLuint index, const GLfloat *v); +GL_APICALL void GL_APIENTRY glVertexAttrib4f (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +GL_APICALL void GL_APIENTRY glVertexAttrib4fv (GLuint index, const GLfloat *v); +GL_APICALL void GL_APIENTRY glVertexAttribPointer (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer); +GL_APICALL void GL_APIENTRY glViewport (GLint x, GLint y, GLsizei width, GLsizei height); #endif +#endif +#endif /* GL_ES_VERSION_2_0 */ #ifdef __cplusplus } #endif -#endif /* __gl2_h_ */ +#endif diff --git a/Source/ThirdParty/ANGLE/include/GLES2/gl2ext.h b/Source/ThirdParty/ANGLE/include/GLES2/gl2ext.h index d77fdbaebc34..51886a2dcb8a 100644 --- a/Source/ThirdParty/ANGLE/include/GLES2/gl2ext.h +++ b/Source/ThirdParty/ANGLE/include/GLES2/gl2ext.h @@ -1,1370 +1,960 @@ #ifndef __gl2ext_h_ -#define __gl2ext_h_ - -/* $Revision: 20795 $ on $Date:: 2013-03-07 01:01:58 -0800 #$ */ +#define __gl2ext_h_ 1 #ifdef __cplusplus extern "C" { #endif /* - * This document is licensed under the SGI Free Software B License Version - * 2.0. For details, see http://oss.sgi.com/projects/FreeB/ . - */ +** Copyright (c) 2013-2015 The Khronos Group Inc. +** +** Permission is hereby granted, free of charge, to any person obtaining a +** copy of this software and/or associated documentation files (the +** "Materials"), to deal in the Materials without restriction, including +** without limitation the rights to use, copy, modify, merge, publish, +** distribute, sublicense, and/or sell copies of the Materials, and to +** permit persons to whom the Materials are furnished to do so, subject to +** the following conditions: +** +** The above copyright notice and this permission notice shall be included +** in all copies or substantial portions of the Materials. +** +** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. +*/ +/* +** This header is generated from the Khronos OpenGL / OpenGL ES XML +** API Registry. The current version of the Registry, generator scripts +** used to make the header, and the header can be found at +** http://www.opengl.org/registry/ +** +** Khronos $Revision: 31902 $ on $Date: 2015-09-03 15:44:53 -0700 (Thu, 03 Sep 2015) $ +*/ #ifndef GL_APIENTRYP -# define GL_APIENTRYP GL_APIENTRY* -#endif - -/*------------------------------------------------------------------------* - * OES extension tokens - *------------------------------------------------------------------------*/ - -/* GL_OES_compressed_ETC1_RGB8_texture */ -#ifndef GL_OES_compressed_ETC1_RGB8_texture -#define GL_ETC1_RGB8_OES 0x8D64 -#endif - -/* GL_OES_compressed_paletted_texture */ -#ifndef GL_OES_compressed_paletted_texture -#define GL_PALETTE4_RGB8_OES 0x8B90 -#define GL_PALETTE4_RGBA8_OES 0x8B91 -#define GL_PALETTE4_R5_G6_B5_OES 0x8B92 -#define GL_PALETTE4_RGBA4_OES 0x8B93 -#define GL_PALETTE4_RGB5_A1_OES 0x8B94 -#define GL_PALETTE8_RGB8_OES 0x8B95 -#define GL_PALETTE8_RGBA8_OES 0x8B96 -#define GL_PALETTE8_R5_G6_B5_OES 0x8B97 -#define GL_PALETTE8_RGBA4_OES 0x8B98 -#define GL_PALETTE8_RGB5_A1_OES 0x8B99 -#endif - -/* GL_OES_depth24 */ -#ifndef GL_OES_depth24 -#define GL_DEPTH_COMPONENT24_OES 0x81A6 -#endif - -/* GL_OES_depth32 */ -#ifndef GL_OES_depth32 -#define GL_DEPTH_COMPONENT32_OES 0x81A7 -#endif - -/* GL_OES_depth_texture */ -/* No new tokens introduced by this extension. */ - -/* GL_OES_EGL_image */ -#ifndef GL_OES_EGL_image -typedef void* GLeglImageOES; -#endif - -/* GL_OES_EGL_image_external */ -#ifndef GL_OES_EGL_image_external -/* GLeglImageOES defined in GL_OES_EGL_image already. */ -#define GL_TEXTURE_EXTERNAL_OES 0x8D65 -#define GL_SAMPLER_EXTERNAL_OES 0x8D66 -#define GL_TEXTURE_BINDING_EXTERNAL_OES 0x8D67 -#define GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES 0x8D68 -#endif - -/* GL_OES_element_index_uint */ -#ifndef GL_OES_element_index_uint -#define GL_UNSIGNED_INT 0x1405 -#endif - -/* GL_OES_get_program_binary */ -#ifndef GL_OES_get_program_binary -#define GL_PROGRAM_BINARY_LENGTH_OES 0x8741 -#define GL_NUM_PROGRAM_BINARY_FORMATS_OES 0x87FE -#define GL_PROGRAM_BINARY_FORMATS_OES 0x87FF -#endif - -/* GL_OES_mapbuffer */ -#ifndef GL_OES_mapbuffer -#define GL_WRITE_ONLY_OES 0x88B9 -#define GL_BUFFER_ACCESS_OES 0x88BB -#define GL_BUFFER_MAPPED_OES 0x88BC -#define GL_BUFFER_MAP_POINTER_OES 0x88BD -#endif - -/* GL_OES_packed_depth_stencil */ -#ifndef GL_OES_packed_depth_stencil -#define GL_DEPTH_STENCIL_OES 0x84F9 -#define GL_UNSIGNED_INT_24_8_OES 0x84FA -#define GL_DEPTH24_STENCIL8_OES 0x88F0 -#endif - -/* GL_OES_required_internalformat */ -#ifndef GL_OES_required_internalformat -#define GL_ALPHA8_OES 0x803C -#define GL_DEPTH_COMPONENT16_OES 0x81A5 -/* reuse GL_DEPTH_COMPONENT24_OES */ -/* reuse GL_DEPTH24_STENCIL8_OES */ -/* reuse GL_DEPTH_COMPONENT32_OES */ -#define GL_LUMINANCE4_ALPHA4_OES 0x8043 -#define GL_LUMINANCE8_ALPHA8_OES 0x8045 -#define GL_LUMINANCE8_OES 0x8040 -#define GL_RGBA4_OES 0x8056 -#define GL_RGB5_A1_OES 0x8057 -#define GL_RGB565_OES 0x8D62 -/* reuse GL_RGB8_OES */ -/* reuse GL_RGBA8_OES */ -/* reuse GL_RGB10_EXT */ -/* reuse GL_RGB10_A2_EXT */ -#endif - -/* GL_OES_rgb8_rgba8 */ -#ifndef GL_OES_rgb8_rgba8 -#define GL_RGB8_OES 0x8051 -#define GL_RGBA8_OES 0x8058 +#define GL_APIENTRYP GL_APIENTRY* #endif -/* GL_OES_standard_derivatives */ -#ifndef GL_OES_standard_derivatives -#define GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES 0x8B8B -#endif - -/* GL_OES_stencil1 */ -#ifndef GL_OES_stencil1 -#define GL_STENCIL_INDEX1_OES 0x8D46 -#endif - -/* GL_OES_stencil4 */ -#ifndef GL_OES_stencil4 -#define GL_STENCIL_INDEX4_OES 0x8D47 -#endif - -#ifndef GL_OES_surfaceless_context -#define GL_FRAMEBUFFER_UNDEFINED_OES 0x8219 -#endif - -/* GL_OES_texture_3D */ -#ifndef GL_OES_texture_3D -#define GL_TEXTURE_WRAP_R_OES 0x8072 -#define GL_TEXTURE_3D_OES 0x806F -#define GL_TEXTURE_BINDING_3D_OES 0x806A -#define GL_MAX_3D_TEXTURE_SIZE_OES 0x8073 -#define GL_SAMPLER_3D_OES 0x8B5F -#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_OES 0x8CD4 -#endif - -/* GL_OES_texture_float */ -/* No new tokens introduced by this extension. */ - -/* GL_OES_texture_float_linear */ -/* No new tokens introduced by this extension. */ - -/* GL_OES_texture_half_float */ -#ifndef GL_OES_texture_half_float -#define GL_HALF_FLOAT_OES 0x8D61 -#endif - -/* GL_OES_texture_half_float_linear */ -/* No new tokens introduced by this extension. */ +/* Generated on date 20150903 */ -/* GL_OES_texture_npot */ -/* No new tokens introduced by this extension. */ +/* Generated C header for: + * API: gles2 + * Profile: common + * Versions considered: 2\.[0-9] + * Versions emitted: _nomatch_^ + * Default extensions included: gles2 + * Additional extensions included: _nomatch_^ + * Extensions removed: _nomatch_^ + */ -/* GL_OES_vertex_array_object */ -#ifndef GL_OES_vertex_array_object -#define GL_VERTEX_ARRAY_BINDING_OES 0x85B5 +#ifndef GL_KHR_blend_equation_advanced +#define GL_KHR_blend_equation_advanced 1 +#define GL_MULTIPLY_KHR 0x9294 +#define GL_SCREEN_KHR 0x9295 +#define GL_OVERLAY_KHR 0x9296 +#define GL_DARKEN_KHR 0x9297 +#define GL_LIGHTEN_KHR 0x9298 +#define GL_COLORDODGE_KHR 0x9299 +#define GL_COLORBURN_KHR 0x929A +#define GL_HARDLIGHT_KHR 0x929B +#define GL_SOFTLIGHT_KHR 0x929C +#define GL_DIFFERENCE_KHR 0x929E +#define GL_EXCLUSION_KHR 0x92A0 +#define GL_HSL_HUE_KHR 0x92AD +#define GL_HSL_SATURATION_KHR 0x92AE +#define GL_HSL_COLOR_KHR 0x92AF +#define GL_HSL_LUMINOSITY_KHR 0x92B0 +typedef void (GL_APIENTRYP PFNGLBLENDBARRIERKHRPROC) (void); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glBlendBarrierKHR (void); #endif +#endif /* GL_KHR_blend_equation_advanced */ -/* GL_OES_vertex_half_float */ -/* GL_HALF_FLOAT_OES defined in GL_OES_texture_half_float already. */ - -/* GL_OES_vertex_type_10_10_10_2 */ -#ifndef GL_OES_vertex_type_10_10_10_2 -#define GL_UNSIGNED_INT_10_10_10_2_OES 0x8DF6 -#define GL_INT_10_10_10_2_OES 0x8DF7 -#endif +#ifndef GL_KHR_blend_equation_advanced_coherent +#define GL_KHR_blend_equation_advanced_coherent 1 +#define GL_BLEND_ADVANCED_COHERENT_KHR 0x9285 +#endif /* GL_KHR_blend_equation_advanced_coherent */ -/*------------------------------------------------------------------------* - * KHR extension tokens - *------------------------------------------------------------------------*/ +#ifndef GL_KHR_context_flush_control +#define GL_KHR_context_flush_control 1 +#define GL_CONTEXT_RELEASE_BEHAVIOR_KHR 0x82FB +#define GL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_KHR 0x82FC +#endif /* GL_KHR_context_flush_control */ #ifndef GL_KHR_debug -typedef void (GL_APIENTRYP GLDEBUGPROC)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,GLvoid *userParam); -#define GL_DEBUG_OUTPUT_SYNCHRONOUS 0x8242 -#define GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH 0x8243 -#define GL_DEBUG_CALLBACK_FUNCTION 0x8244 -#define GL_DEBUG_CALLBACK_USER_PARAM 0x8245 -#define GL_DEBUG_SOURCE_API 0x8246 -#define GL_DEBUG_SOURCE_WINDOW_SYSTEM 0x8247 -#define GL_DEBUG_SOURCE_SHADER_COMPILER 0x8248 -#define GL_DEBUG_SOURCE_THIRD_PARTY 0x8249 -#define GL_DEBUG_SOURCE_APPLICATION 0x824A -#define GL_DEBUG_SOURCE_OTHER 0x824B -#define GL_DEBUG_TYPE_ERROR 0x824C -#define GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR 0x824D -#define GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR 0x824E -#define GL_DEBUG_TYPE_PORTABILITY 0x824F -#define GL_DEBUG_TYPE_PERFORMANCE 0x8250 -#define GL_DEBUG_TYPE_OTHER 0x8251 -#define GL_DEBUG_TYPE_MARKER 0x8268 -#define GL_DEBUG_TYPE_PUSH_GROUP 0x8269 -#define GL_DEBUG_TYPE_POP_GROUP 0x826A -#define GL_DEBUG_SEVERITY_NOTIFICATION 0x826B -#define GL_MAX_DEBUG_GROUP_STACK_DEPTH 0x826C -#define GL_DEBUG_GROUP_STACK_DEPTH 0x826D -#define GL_BUFFER 0x82E0 -#define GL_SHADER 0x82E1 -#define GL_PROGRAM 0x82E2 -#define GL_QUERY 0x82E3 -/* PROGRAM_PIPELINE only in GL */ -#define GL_SAMPLER 0x82E6 -/* DISPLAY_LIST only in GL */ -#define GL_MAX_LABEL_LENGTH 0x82E8 -#define GL_MAX_DEBUG_MESSAGE_LENGTH 0x9143 -#define GL_MAX_DEBUG_LOGGED_MESSAGES 0x9144 -#define GL_DEBUG_LOGGED_MESSAGES 0x9145 -#define GL_DEBUG_SEVERITY_HIGH 0x9146 -#define GL_DEBUG_SEVERITY_MEDIUM 0x9147 -#define GL_DEBUG_SEVERITY_LOW 0x9148 -#define GL_DEBUG_OUTPUT 0x92E0 -#define GL_CONTEXT_FLAG_DEBUG_BIT 0x00000002 -#define GL_STACK_OVERFLOW 0x0503 -#define GL_STACK_UNDERFLOW 0x0504 -#endif +#define GL_KHR_debug 1 +typedef void (GL_APIENTRY *GLDEBUGPROCKHR)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,const void *userParam); +#define GL_SAMPLER 0x82E6 +#define GL_DEBUG_OUTPUT_SYNCHRONOUS_KHR 0x8242 +#define GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH_KHR 0x8243 +#define GL_DEBUG_CALLBACK_FUNCTION_KHR 0x8244 +#define GL_DEBUG_CALLBACK_USER_PARAM_KHR 0x8245 +#define GL_DEBUG_SOURCE_API_KHR 0x8246 +#define GL_DEBUG_SOURCE_WINDOW_SYSTEM_KHR 0x8247 +#define GL_DEBUG_SOURCE_SHADER_COMPILER_KHR 0x8248 +#define GL_DEBUG_SOURCE_THIRD_PARTY_KHR 0x8249 +#define GL_DEBUG_SOURCE_APPLICATION_KHR 0x824A +#define GL_DEBUG_SOURCE_OTHER_KHR 0x824B +#define GL_DEBUG_TYPE_ERROR_KHR 0x824C +#define GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_KHR 0x824D +#define GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_KHR 0x824E +#define GL_DEBUG_TYPE_PORTABILITY_KHR 0x824F +#define GL_DEBUG_TYPE_PERFORMANCE_KHR 0x8250 +#define GL_DEBUG_TYPE_OTHER_KHR 0x8251 +#define GL_DEBUG_TYPE_MARKER_KHR 0x8268 +#define GL_DEBUG_TYPE_PUSH_GROUP_KHR 0x8269 +#define GL_DEBUG_TYPE_POP_GROUP_KHR 0x826A +#define GL_DEBUG_SEVERITY_NOTIFICATION_KHR 0x826B +#define GL_MAX_DEBUG_GROUP_STACK_DEPTH_KHR 0x826C +#define GL_DEBUG_GROUP_STACK_DEPTH_KHR 0x826D +#define GL_BUFFER_KHR 0x82E0 +#define GL_SHADER_KHR 0x82E1 +#define GL_PROGRAM_KHR 0x82E2 +#define GL_VERTEX_ARRAY_KHR 0x8074 +#define GL_QUERY_KHR 0x82E3 +#define GL_PROGRAM_PIPELINE_KHR 0x82E4 +#define GL_SAMPLER_KHR 0x82E6 +#define GL_MAX_LABEL_LENGTH_KHR 0x82E8 +#define GL_MAX_DEBUG_MESSAGE_LENGTH_KHR 0x9143 +#define GL_MAX_DEBUG_LOGGED_MESSAGES_KHR 0x9144 +#define GL_DEBUG_LOGGED_MESSAGES_KHR 0x9145 +#define GL_DEBUG_SEVERITY_HIGH_KHR 0x9146 +#define GL_DEBUG_SEVERITY_MEDIUM_KHR 0x9147 +#define GL_DEBUG_SEVERITY_LOW_KHR 0x9148 +#define GL_DEBUG_OUTPUT_KHR 0x92E0 +#define GL_CONTEXT_FLAG_DEBUG_BIT_KHR 0x00000002 +#define GL_STACK_OVERFLOW_KHR 0x0503 +#define GL_STACK_UNDERFLOW_KHR 0x0504 +typedef void (GL_APIENTRYP PFNGLDEBUGMESSAGECONTROLKHRPROC) (GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled); +typedef void (GL_APIENTRYP PFNGLDEBUGMESSAGEINSERTKHRPROC) (GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *buf); +typedef void (GL_APIENTRYP PFNGLDEBUGMESSAGECALLBACKKHRPROC) (GLDEBUGPROCKHR callback, const void *userParam); +typedef GLuint (GL_APIENTRYP PFNGLGETDEBUGMESSAGELOGKHRPROC) (GLuint count, GLsizei bufSize, GLenum *sources, GLenum *types, GLuint *ids, GLenum *severities, GLsizei *lengths, GLchar *messageLog); +typedef void (GL_APIENTRYP PFNGLPUSHDEBUGGROUPKHRPROC) (GLenum source, GLuint id, GLsizei length, const GLchar *message); +typedef void (GL_APIENTRYP PFNGLPOPDEBUGGROUPKHRPROC) (void); +typedef void (GL_APIENTRYP PFNGLOBJECTLABELKHRPROC) (GLenum identifier, GLuint name, GLsizei length, const GLchar *label); +typedef void (GL_APIENTRYP PFNGLGETOBJECTLABELKHRPROC) (GLenum identifier, GLuint name, GLsizei bufSize, GLsizei *length, GLchar *label); +typedef void (GL_APIENTRYP PFNGLOBJECTPTRLABELKHRPROC) (const void *ptr, GLsizei length, const GLchar *label); +typedef void (GL_APIENTRYP PFNGLGETOBJECTPTRLABELKHRPROC) (const void *ptr, GLsizei bufSize, GLsizei *length, GLchar *label); +typedef void (GL_APIENTRYP PFNGLGETPOINTERVKHRPROC) (GLenum pname, void **params); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glDebugMessageControlKHR (GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled); +GL_APICALL void GL_APIENTRY glDebugMessageInsertKHR (GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *buf); +GL_APICALL void GL_APIENTRY glDebugMessageCallbackKHR (GLDEBUGPROCKHR callback, const void *userParam); +GL_APICALL GLuint GL_APIENTRY glGetDebugMessageLogKHR (GLuint count, GLsizei bufSize, GLenum *sources, GLenum *types, GLuint *ids, GLenum *severities, GLsizei *lengths, GLchar *messageLog); +GL_APICALL void GL_APIENTRY glPushDebugGroupKHR (GLenum source, GLuint id, GLsizei length, const GLchar *message); +GL_APICALL void GL_APIENTRY glPopDebugGroupKHR (void); +GL_APICALL void GL_APIENTRY glObjectLabelKHR (GLenum identifier, GLuint name, GLsizei length, const GLchar *label); +GL_APICALL void GL_APIENTRY glGetObjectLabelKHR (GLenum identifier, GLuint name, GLsizei bufSize, GLsizei *length, GLchar *label); +GL_APICALL void GL_APIENTRY glObjectPtrLabelKHR (const void *ptr, GLsizei length, const GLchar *label); +GL_APICALL void GL_APIENTRY glGetObjectPtrLabelKHR (const void *ptr, GLsizei bufSize, GLsizei *length, GLchar *label); +GL_APICALL void GL_APIENTRY glGetPointervKHR (GLenum pname, void **params); +#endif +#endif /* GL_KHR_debug */ + +#ifndef GL_KHR_no_error +#define GL_KHR_no_error 1 +#define GL_CONTEXT_FLAG_NO_ERROR_BIT_KHR 0x00000008 +#endif /* GL_KHR_no_error */ + +#ifndef GL_KHR_robust_buffer_access_behavior +#define GL_KHR_robust_buffer_access_behavior 1 +#endif /* GL_KHR_robust_buffer_access_behavior */ + +#ifndef GL_KHR_robustness +#define GL_KHR_robustness 1 +#define GL_CONTEXT_ROBUST_ACCESS_KHR 0x90F3 +#define GL_LOSE_CONTEXT_ON_RESET_KHR 0x8252 +#define GL_GUILTY_CONTEXT_RESET_KHR 0x8253 +#define GL_INNOCENT_CONTEXT_RESET_KHR 0x8254 +#define GL_UNKNOWN_CONTEXT_RESET_KHR 0x8255 +#define GL_RESET_NOTIFICATION_STRATEGY_KHR 0x8256 +#define GL_NO_RESET_NOTIFICATION_KHR 0x8261 +#define GL_CONTEXT_LOST_KHR 0x0507 +typedef GLenum (GL_APIENTRYP PFNGLGETGRAPHICSRESETSTATUSKHRPROC) (void); +typedef void (GL_APIENTRYP PFNGLREADNPIXELSKHRPROC) (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, void *data); +typedef void (GL_APIENTRYP PFNGLGETNUNIFORMFVKHRPROC) (GLuint program, GLint location, GLsizei bufSize, GLfloat *params); +typedef void (GL_APIENTRYP PFNGLGETNUNIFORMIVKHRPROC) (GLuint program, GLint location, GLsizei bufSize, GLint *params); +typedef void (GL_APIENTRYP PFNGLGETNUNIFORMUIVKHRPROC) (GLuint program, GLint location, GLsizei bufSize, GLuint *params); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL GLenum GL_APIENTRY glGetGraphicsResetStatusKHR (void); +GL_APICALL void GL_APIENTRY glReadnPixelsKHR (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, void *data); +GL_APICALL void GL_APIENTRY glGetnUniformfvKHR (GLuint program, GLint location, GLsizei bufSize, GLfloat *params); +GL_APICALL void GL_APIENTRY glGetnUniformivKHR (GLuint program, GLint location, GLsizei bufSize, GLint *params); +GL_APICALL void GL_APIENTRY glGetnUniformuivKHR (GLuint program, GLint location, GLsizei bufSize, GLuint *params); +#endif +#endif /* GL_KHR_robustness */ + +#ifndef GL_KHR_texture_compression_astc_hdr +#define GL_KHR_texture_compression_astc_hdr 1 +#define GL_COMPRESSED_RGBA_ASTC_4x4_KHR 0x93B0 +#define GL_COMPRESSED_RGBA_ASTC_5x4_KHR 0x93B1 +#define GL_COMPRESSED_RGBA_ASTC_5x5_KHR 0x93B2 +#define GL_COMPRESSED_RGBA_ASTC_6x5_KHR 0x93B3 +#define GL_COMPRESSED_RGBA_ASTC_6x6_KHR 0x93B4 +#define GL_COMPRESSED_RGBA_ASTC_8x5_KHR 0x93B5 +#define GL_COMPRESSED_RGBA_ASTC_8x6_KHR 0x93B6 +#define GL_COMPRESSED_RGBA_ASTC_8x8_KHR 0x93B7 +#define GL_COMPRESSED_RGBA_ASTC_10x5_KHR 0x93B8 +#define GL_COMPRESSED_RGBA_ASTC_10x6_KHR 0x93B9 +#define GL_COMPRESSED_RGBA_ASTC_10x8_KHR 0x93BA +#define GL_COMPRESSED_RGBA_ASTC_10x10_KHR 0x93BB +#define GL_COMPRESSED_RGBA_ASTC_12x10_KHR 0x93BC +#define GL_COMPRESSED_RGBA_ASTC_12x12_KHR 0x93BD +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR 0x93D0 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR 0x93D1 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR 0x93D2 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR 0x93D3 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR 0x93D4 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR 0x93D5 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR 0x93D6 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR 0x93D7 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR 0x93D8 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR 0x93D9 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR 0x93DA +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR 0x93DB +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR 0x93DC +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR 0x93DD +#endif /* GL_KHR_texture_compression_astc_hdr */ #ifndef GL_KHR_texture_compression_astc_ldr -#define GL_COMPRESSED_RGBA_ASTC_4x4_KHR 0x93B0 -#define GL_COMPRESSED_RGBA_ASTC_5x4_KHR 0x93B1 -#define GL_COMPRESSED_RGBA_ASTC_5x5_KHR 0x93B2 -#define GL_COMPRESSED_RGBA_ASTC_6x5_KHR 0x93B3 -#define GL_COMPRESSED_RGBA_ASTC_6x6_KHR 0x93B4 -#define GL_COMPRESSED_RGBA_ASTC_8x5_KHR 0x93B5 -#define GL_COMPRESSED_RGBA_ASTC_8x6_KHR 0x93B6 -#define GL_COMPRESSED_RGBA_ASTC_8x8_KHR 0x93B7 -#define GL_COMPRESSED_RGBA_ASTC_10x5_KHR 0x93B8 -#define GL_COMPRESSED_RGBA_ASTC_10x6_KHR 0x93B9 -#define GL_COMPRESSED_RGBA_ASTC_10x8_KHR 0x93BA -#define GL_COMPRESSED_RGBA_ASTC_10x10_KHR 0x93BB -#define GL_COMPRESSED_RGBA_ASTC_12x10_KHR 0x93BC -#define GL_COMPRESSED_RGBA_ASTC_12x12_KHR 0x93BD -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR 0x93D0 -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR 0x93D1 -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR 0x93D2 -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR 0x93D3 -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR 0x93D4 -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR 0x93D5 -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR 0x93D6 -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR 0x93D7 -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR 0x93D8 -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR 0x93D9 -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR 0x93DA -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR 0x93DB -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR 0x93DC -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR 0x93DD -#endif - -/*------------------------------------------------------------------------* - * AMD extension tokens - *------------------------------------------------------------------------*/ - -/* GL_AMD_compressed_3DC_texture */ -#ifndef GL_AMD_compressed_3DC_texture -#define GL_3DC_X_AMD 0x87F9 -#define GL_3DC_XY_AMD 0x87FA -#endif - -/* GL_AMD_compressed_ATC_texture */ -#ifndef GL_AMD_compressed_ATC_texture -#define GL_ATC_RGB_AMD 0x8C92 -#define GL_ATC_RGBA_EXPLICIT_ALPHA_AMD 0x8C93 -#define GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD 0x87EE -#endif - -/* GL_AMD_performance_monitor */ -#ifndef GL_AMD_performance_monitor -#define GL_COUNTER_TYPE_AMD 0x8BC0 -#define GL_COUNTER_RANGE_AMD 0x8BC1 -#define GL_UNSIGNED_INT64_AMD 0x8BC2 -#define GL_PERCENTAGE_AMD 0x8BC3 -#define GL_PERFMON_RESULT_AVAILABLE_AMD 0x8BC4 -#define GL_PERFMON_RESULT_SIZE_AMD 0x8BC5 -#define GL_PERFMON_RESULT_AMD 0x8BC6 -#endif - -/* GL_AMD_program_binary_Z400 */ -#ifndef GL_AMD_program_binary_Z400 -#define GL_Z400_BINARY_AMD 0x8740 -#endif - -/*------------------------------------------------------------------------* - * ANGLE extension tokens - *------------------------------------------------------------------------*/ - -/* GL_ANGLE_depth_texture */ -#ifndef GL_ANGLE_depth_texture -#define GL_DEPTH_COMPONENT 0x1902 -#define GL_DEPTH_STENCIL_OES 0x84F9 -#define GL_UNSIGNED_SHORT 0x1403 -#define GL_UNSIGNED_INT 0x1405 -#define GL_UNSIGNED_INT_24_8_OES 0x84FA -#define GL_DEPTH_COMPONENT16 0x81A5 -#define GL_DEPTH_COMPONENT32_OES 0x81A7 -#define GL_DEPTH24_STENCIL8_OES 0x88F0 -#endif - -/* GL_ANGLE_framebuffer_blit */ -#ifndef GL_ANGLE_framebuffer_blit -#define GL_READ_FRAMEBUFFER_ANGLE 0x8CA8 -#define GL_DRAW_FRAMEBUFFER_ANGLE 0x8CA9 -#define GL_DRAW_FRAMEBUFFER_BINDING_ANGLE 0x8CA6 -#define GL_READ_FRAMEBUFFER_BINDING_ANGLE 0x8CAA -#endif - -/* GL_ANGLE_framebuffer_multisample */ -#ifndef GL_ANGLE_framebuffer_multisample -#define GL_RENDERBUFFER_SAMPLES_ANGLE 0x8CAB -#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_ANGLE 0x8D56 -#define GL_MAX_SAMPLES_ANGLE 0x8D57 -#endif - -/* GL_ANGLE_instanced_arrays */ -#ifndef GL_ANGLE_instanced_arrays -#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE 0x88FE -#endif - -/* GL_ANGLE_pack_reverse_row_order */ -#ifndef GL_ANGLE_pack_reverse_row_order -#define GL_PACK_REVERSE_ROW_ORDER_ANGLE 0x93A4 -#endif - -/* GL_ANGLE_program_binary */ -#ifndef GL_ANGLE_program_binary -#define GL_PROGRAM_BINARY_ANGLE 0x93A6 -#endif - -/* GL_ANGLE_texture_compression_dxt3 */ -#ifndef GL_ANGLE_texture_compression_dxt3 -#define GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE 0x83F2 -#endif - -/* GL_ANGLE_texture_compression_dxt5 */ -#ifndef GL_ANGLE_texture_compression_dxt5 -#define GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE 0x83F3 -#endif - -/* GL_ANGLE_texture_usage */ -#ifndef GL_ANGLE_texture_usage -#define GL_TEXTURE_USAGE_ANGLE 0x93A2 -#define GL_FRAMEBUFFER_ATTACHMENT_ANGLE 0x93A3 -#endif - -/* GL_ANGLE_translated_shader_source */ -#ifndef GL_ANGLE_translated_shader_source -#define GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE 0x93A0 -#endif - -/*------------------------------------------------------------------------* - * APPLE extension tokens - *------------------------------------------------------------------------*/ - -/* GL_APPLE_copy_texture_levels */ -/* No new tokens introduced by this extension. */ - -/* GL_APPLE_framebuffer_multisample */ -#ifndef GL_APPLE_framebuffer_multisample -#define GL_RENDERBUFFER_SAMPLES_APPLE 0x8CAB -#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_APPLE 0x8D56 -#define GL_MAX_SAMPLES_APPLE 0x8D57 -#define GL_READ_FRAMEBUFFER_APPLE 0x8CA8 -#define GL_DRAW_FRAMEBUFFER_APPLE 0x8CA9 -#define GL_DRAW_FRAMEBUFFER_BINDING_APPLE 0x8CA6 -#define GL_READ_FRAMEBUFFER_BINDING_APPLE 0x8CAA -#endif - -/* GL_APPLE_rgb_422 */ -#ifndef GL_APPLE_rgb_422 -#define GL_RGB_422_APPLE 0x8A1F -#define GL_UNSIGNED_SHORT_8_8_APPLE 0x85BA -#define GL_UNSIGNED_SHORT_8_8_REV_APPLE 0x85BB -#endif - -/* GL_APPLE_sync */ -#ifndef GL_APPLE_sync - -#ifndef __gl3_h_ -/* These types are defined with reference to - * in the Apple extension spec, but here we use the Khronos - * portable types in khrplatform.h, and assume those types - * are always defined. - * If any other extensions using these types are defined, - * the typedefs must move out of this block and be shared. - */ -typedef khronos_int64_t GLint64; -typedef khronos_uint64_t GLuint64; -typedef struct __GLsync *GLsync; -#endif - -#define GL_SYNC_OBJECT_APPLE 0x8A53 -#define GL_MAX_SERVER_WAIT_TIMEOUT_APPLE 0x9111 -#define GL_OBJECT_TYPE_APPLE 0x9112 -#define GL_SYNC_CONDITION_APPLE 0x9113 -#define GL_SYNC_STATUS_APPLE 0x9114 -#define GL_SYNC_FLAGS_APPLE 0x9115 -#define GL_SYNC_FENCE_APPLE 0x9116 -#define GL_SYNC_GPU_COMMANDS_COMPLETE_APPLE 0x9117 -#define GL_UNSIGNALED_APPLE 0x9118 -#define GL_SIGNALED_APPLE 0x9119 -#define GL_ALREADY_SIGNALED_APPLE 0x911A -#define GL_TIMEOUT_EXPIRED_APPLE 0x911B -#define GL_CONDITION_SATISFIED_APPLE 0x911C -#define GL_WAIT_FAILED_APPLE 0x911D -#define GL_SYNC_FLUSH_COMMANDS_BIT_APPLE 0x00000001 -#define GL_TIMEOUT_IGNORED_APPLE 0xFFFFFFFFFFFFFFFFull -#endif - -/* GL_APPLE_texture_format_BGRA8888 */ -#ifndef GL_APPLE_texture_format_BGRA8888 -#define GL_BGRA_EXT 0x80E1 -#endif - -/* GL_APPLE_texture_max_level */ -#ifndef GL_APPLE_texture_max_level -#define GL_TEXTURE_MAX_LEVEL_APPLE 0x813D -#endif - -/*------------------------------------------------------------------------* - * ARM extension tokens - *------------------------------------------------------------------------*/ - -/* GL_ARM_mali_program_binary */ -#ifndef GL_ARM_mali_program_binary -#define GL_MALI_PROGRAM_BINARY_ARM 0x8F61 -#endif - -/* GL_ARM_mali_shader_binary */ -#ifndef GL_ARM_mali_shader_binary -#define GL_MALI_SHADER_BINARY_ARM 0x8F60 -#endif - -/* GL_ARM_rgba8 */ -/* No new tokens introduced by this extension. */ - -/*------------------------------------------------------------------------* - * EXT extension tokens - *------------------------------------------------------------------------*/ - -/* GL_EXT_blend_minmax */ -#ifndef GL_EXT_blend_minmax -#define GL_MIN_EXT 0x8007 -#define GL_MAX_EXT 0x8008 -#endif - -/* GL_EXT_color_buffer_half_float */ -#ifndef GL_EXT_color_buffer_half_float -#define GL_RGBA16F_EXT 0x881A -#define GL_RGB16F_EXT 0x881B -#define GL_RG16F_EXT 0x822F -#define GL_R16F_EXT 0x822D -#define GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE_EXT 0x8211 -#define GL_UNSIGNED_NORMALIZED_EXT 0x8C17 -#endif - -/* GL_EXT_debug_label */ -#ifndef GL_EXT_debug_label -#define GL_PROGRAM_PIPELINE_OBJECT_EXT 0x8A4F -#define GL_PROGRAM_OBJECT_EXT 0x8B40 -#define GL_SHADER_OBJECT_EXT 0x8B48 -#define GL_BUFFER_OBJECT_EXT 0x9151 -#define GL_QUERY_OBJECT_EXT 0x9153 -#define GL_VERTEX_ARRAY_OBJECT_EXT 0x9154 -#endif - -/* GL_EXT_debug_marker */ -/* No new tokens introduced by this extension. */ - -/* GL_EXT_discard_framebuffer */ -#ifndef GL_EXT_discard_framebuffer -#define GL_COLOR_EXT 0x1800 -#define GL_DEPTH_EXT 0x1801 -#define GL_STENCIL_EXT 0x1802 -#endif - -/* GL_EXT_map_buffer_range */ -#ifndef GL_EXT_map_buffer_range -#define GL_MAP_READ_BIT_EXT 0x0001 -#define GL_MAP_WRITE_BIT_EXT 0x0002 -#define GL_MAP_INVALIDATE_RANGE_BIT_EXT 0x0004 -#define GL_MAP_INVALIDATE_BUFFER_BIT_EXT 0x0008 -#define GL_MAP_FLUSH_EXPLICIT_BIT_EXT 0x0010 -#define GL_MAP_UNSYNCHRONIZED_BIT_EXT 0x0020 -#endif - -/* GL_EXT_multisampled_render_to_texture */ -#ifndef GL_EXT_multisampled_render_to_texture -#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_SAMPLES_EXT 0x8D6C -/* reuse values from GL_EXT_framebuffer_multisample (desktop extension) */ -#define GL_RENDERBUFFER_SAMPLES_EXT 0x8CAB -#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT 0x8D56 -#define GL_MAX_SAMPLES_EXT 0x8D57 -#endif - -/* GL_EXT_multiview_draw_buffers */ -#ifndef GL_EXT_multiview_draw_buffers -#define GL_COLOR_ATTACHMENT_EXT 0x90F0 -#define GL_MULTIVIEW_EXT 0x90F1 -#define GL_DRAW_BUFFER_EXT 0x0C01 -#define GL_READ_BUFFER_EXT 0x0C02 -#define GL_MAX_MULTIVIEW_BUFFERS_EXT 0x90F2 -#endif - -/* GL_EXT_multi_draw_arrays */ -/* No new tokens introduced by this extension. */ - -/* GL_EXT_occlusion_query_boolean */ -#ifndef GL_EXT_occlusion_query_boolean -#define GL_ANY_SAMPLES_PASSED_EXT 0x8C2F -#define GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT 0x8D6A -#define GL_CURRENT_QUERY_EXT 0x8865 -#define GL_QUERY_RESULT_EXT 0x8866 -#define GL_QUERY_RESULT_AVAILABLE_EXT 0x8867 -#endif - -/* GL_EXT_read_format_bgra */ -#ifndef GL_EXT_read_format_bgra -#define GL_BGRA_EXT 0x80E1 -#define GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT 0x8365 -#define GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT 0x8366 -#endif - -/* GL_EXT_robustness */ -#ifndef GL_EXT_robustness -/* reuse GL_NO_ERROR */ -#define GL_GUILTY_CONTEXT_RESET_EXT 0x8253 -#define GL_INNOCENT_CONTEXT_RESET_EXT 0x8254 -#define GL_UNKNOWN_CONTEXT_RESET_EXT 0x8255 -#define GL_CONTEXT_ROBUST_ACCESS_EXT 0x90F3 -#define GL_RESET_NOTIFICATION_STRATEGY_EXT 0x8256 -#define GL_LOSE_CONTEXT_ON_RESET_EXT 0x8252 -#define GL_NO_RESET_NOTIFICATION_EXT 0x8261 -#endif - -/* GL_EXT_separate_shader_objects */ -#ifndef GL_EXT_separate_shader_objects -#define GL_VERTEX_SHADER_BIT_EXT 0x00000001 -#define GL_FRAGMENT_SHADER_BIT_EXT 0x00000002 -#define GL_ALL_SHADER_BITS_EXT 0xFFFFFFFF -#define GL_PROGRAM_SEPARABLE_EXT 0x8258 -#define GL_ACTIVE_PROGRAM_EXT 0x8259 -#define GL_PROGRAM_PIPELINE_BINDING_EXT 0x825A -#endif - -/* GL_EXT_shader_framebuffer_fetch */ -#ifndef GL_EXT_shader_framebuffer_fetch -#define GL_FRAGMENT_SHADER_DISCARDS_SAMPLES_EXT 0x8A52 -#endif - -/* GL_EXT_shader_texture_lod */ -/* No new tokens introduced by this extension. */ - -/* GL_EXT_shadow_samplers */ -#ifndef GL_EXT_shadow_samplers -#define GL_TEXTURE_COMPARE_MODE_EXT 0x884C -#define GL_TEXTURE_COMPARE_FUNC_EXT 0x884D -#define GL_COMPARE_REF_TO_TEXTURE_EXT 0x884E -#define GL_SAMPLER_2D_SHADOW_EXT 0x8B62 -#endif - -/* GL_EXT_sRGB */ -#ifndef GL_EXT_sRGB -#define GL_SRGB_EXT 0x8C40 -#define GL_SRGB_ALPHA_EXT 0x8C42 -#define GL_SRGB8_ALPHA8_EXT 0x8C43 -#define GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING_EXT 0x8210 -#endif - -/* GL_EXT_texture_compression_dxt1 */ -#ifndef GL_EXT_texture_compression_dxt1 -#define GL_COMPRESSED_RGB_S3TC_DXT1_EXT 0x83F0 -#define GL_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1 -#endif - -/* GL_EXT_texture_filter_anisotropic */ -#ifndef GL_EXT_texture_filter_anisotropic -#define GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE -#define GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT 0x84FF -#endif - -/* GL_EXT_texture_format_BGRA8888 */ -#ifndef GL_EXT_texture_format_BGRA8888 -#define GL_BGRA_EXT 0x80E1 -#endif - -/* GL_EXT_texture_rg */ -#ifndef GL_EXT_texture_rg -#define GL_RED_EXT 0x1903 -#define GL_RG_EXT 0x8227 -#define GL_R8_EXT 0x8229 -#define GL_RG8_EXT 0x822B -#endif - -/* GL_EXT_texture_storage */ -#ifndef GL_EXT_texture_storage -#define GL_TEXTURE_IMMUTABLE_FORMAT_EXT 0x912F -#define GL_ALPHA8_EXT 0x803C -#define GL_LUMINANCE8_EXT 0x8040 -#define GL_LUMINANCE8_ALPHA8_EXT 0x8045 -#define GL_RGBA32F_EXT 0x8814 -#define GL_RGB32F_EXT 0x8815 -#define GL_ALPHA32F_EXT 0x8816 -#define GL_LUMINANCE32F_EXT 0x8818 -#define GL_LUMINANCE_ALPHA32F_EXT 0x8819 -/* reuse GL_RGBA16F_EXT */ -/* reuse GL_RGB16F_EXT */ -#define GL_ALPHA16F_EXT 0x881C -#define GL_LUMINANCE16F_EXT 0x881E -#define GL_LUMINANCE_ALPHA16F_EXT 0x881F -#define GL_RGB10_A2_EXT 0x8059 -#define GL_RGB10_EXT 0x8052 -#define GL_BGRA8_EXT 0x93A1 -#define GL_R8_EXT 0x8229 -#define GL_RG8_EXT 0x822B -#define GL_R32F_EXT 0x822E -#define GL_RG32F_EXT 0x8230 -#define GL_R16F_EXT 0x822D -#define GL_RG16F_EXT 0x822F -#endif - -/* GL_EXT_texture_type_2_10_10_10_REV */ -#ifndef GL_EXT_texture_type_2_10_10_10_REV -#define GL_UNSIGNED_INT_2_10_10_10_REV_EXT 0x8368 -#endif - -/* GL_EXT_unpack_subimage */ -#ifndef GL_EXT_unpack_subimage -#define GL_UNPACK_ROW_LENGTH_EXT 0x0CF2 -#define GL_UNPACK_SKIP_ROWS_EXT 0x0CF3 -#define GL_UNPACK_SKIP_PIXELS_EXT 0x0CF4 -#endif - -/*------------------------------------------------------------------------* - * DMP extension tokens - *------------------------------------------------------------------------*/ - -/* GL_DMP_shader_binary */ -#ifndef GL_DMP_shader_binary -#define GL_SHADER_BINARY_DMP 0x9250 -#endif - -/*------------------------------------------------------------------------* - * FJ extension tokens - *------------------------------------------------------------------------*/ - -/* GL_FJ_shader_binary_GCCSO */ -#ifndef GL_FJ_shader_binary_GCCSO -#define GL_GCCSO_SHADER_BINARY_F 0x9260 -#endif - -/*------------------------------------------------------------------------* - * IMG extension tokens - *------------------------------------------------------------------------*/ - -/* GL_IMG_program_binary */ -#ifndef GL_IMG_program_binary -#define GL_SGX_PROGRAM_BINARY_IMG 0x9130 -#endif - -/* GL_IMG_read_format */ -#ifndef GL_IMG_read_format -#define GL_BGRA_IMG 0x80E1 -#define GL_UNSIGNED_SHORT_4_4_4_4_REV_IMG 0x8365 -#endif - -/* GL_IMG_shader_binary */ -#ifndef GL_IMG_shader_binary -#define GL_SGX_BINARY_IMG 0x8C0A -#endif - -/* GL_IMG_texture_compression_pvrtc */ -#ifndef GL_IMG_texture_compression_pvrtc -#define GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG 0x8C00 -#define GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG 0x8C01 -#define GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG 0x8C02 -#define GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG 0x8C03 -#endif - -/* GL_IMG_texture_compression_pvrtc2 */ -#ifndef GL_IMG_texture_compression_pvrtc2 -#define GL_COMPRESSED_RGBA_PVRTC_2BPPV2_IMG 0x9137 -#define GL_COMPRESSED_RGBA_PVRTC_4BPPV2_IMG 0x9138 -#endif - -/* GL_IMG_multisampled_render_to_texture */ -#ifndef GL_IMG_multisampled_render_to_texture -#define GL_RENDERBUFFER_SAMPLES_IMG 0x9133 -#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_IMG 0x9134 -#define GL_MAX_SAMPLES_IMG 0x9135 -#define GL_TEXTURE_SAMPLES_IMG 0x9136 -#endif - -/*------------------------------------------------------------------------* - * NV extension tokens - *------------------------------------------------------------------------*/ - -/* GL_NV_coverage_sample */ -#ifndef GL_NV_coverage_sample -#define GL_COVERAGE_COMPONENT_NV 0x8ED0 -#define GL_COVERAGE_COMPONENT4_NV 0x8ED1 -#define GL_COVERAGE_ATTACHMENT_NV 0x8ED2 -#define GL_COVERAGE_BUFFERS_NV 0x8ED3 -#define GL_COVERAGE_SAMPLES_NV 0x8ED4 -#define GL_COVERAGE_ALL_FRAGMENTS_NV 0x8ED5 -#define GL_COVERAGE_EDGE_FRAGMENTS_NV 0x8ED6 -#define GL_COVERAGE_AUTOMATIC_NV 0x8ED7 -#define GL_COVERAGE_BUFFER_BIT_NV 0x8000 -#endif - -/* GL_NV_depth_nonlinear */ -#ifndef GL_NV_depth_nonlinear -#define GL_DEPTH_COMPONENT16_NONLINEAR_NV 0x8E2C -#endif - -/* GL_NV_draw_buffers */ -#ifndef GL_NV_draw_buffers -#define GL_MAX_DRAW_BUFFERS_NV 0x8824 -#define GL_DRAW_BUFFER0_NV 0x8825 -#define GL_DRAW_BUFFER1_NV 0x8826 -#define GL_DRAW_BUFFER2_NV 0x8827 -#define GL_DRAW_BUFFER3_NV 0x8828 -#define GL_DRAW_BUFFER4_NV 0x8829 -#define GL_DRAW_BUFFER5_NV 0x882A -#define GL_DRAW_BUFFER6_NV 0x882B -#define GL_DRAW_BUFFER7_NV 0x882C -#define GL_DRAW_BUFFER8_NV 0x882D -#define GL_DRAW_BUFFER9_NV 0x882E -#define GL_DRAW_BUFFER10_NV 0x882F -#define GL_DRAW_BUFFER11_NV 0x8830 -#define GL_DRAW_BUFFER12_NV 0x8831 -#define GL_DRAW_BUFFER13_NV 0x8832 -#define GL_DRAW_BUFFER14_NV 0x8833 -#define GL_DRAW_BUFFER15_NV 0x8834 -#define GL_COLOR_ATTACHMENT0_NV 0x8CE0 -#define GL_COLOR_ATTACHMENT1_NV 0x8CE1 -#define GL_COLOR_ATTACHMENT2_NV 0x8CE2 -#define GL_COLOR_ATTACHMENT3_NV 0x8CE3 -#define GL_COLOR_ATTACHMENT4_NV 0x8CE4 -#define GL_COLOR_ATTACHMENT5_NV 0x8CE5 -#define GL_COLOR_ATTACHMENT6_NV 0x8CE6 -#define GL_COLOR_ATTACHMENT7_NV 0x8CE7 -#define GL_COLOR_ATTACHMENT8_NV 0x8CE8 -#define GL_COLOR_ATTACHMENT9_NV 0x8CE9 -#define GL_COLOR_ATTACHMENT10_NV 0x8CEA -#define GL_COLOR_ATTACHMENT11_NV 0x8CEB -#define GL_COLOR_ATTACHMENT12_NV 0x8CEC -#define GL_COLOR_ATTACHMENT13_NV 0x8CED -#define GL_COLOR_ATTACHMENT14_NV 0x8CEE -#define GL_COLOR_ATTACHMENT15_NV 0x8CEF -#endif - -/* GL_EXT_draw_buffers */ -#ifndef GL_EXT_draw_buffers -#define GL_MAX_DRAW_BUFFERS_EXT 0x8824 -#define GL_DRAW_BUFFER0_EXT 0x8825 -#define GL_DRAW_BUFFER1_EXT 0x8826 -#define GL_DRAW_BUFFER2_EXT 0x8827 -#define GL_DRAW_BUFFER3_EXT 0x8828 -#define GL_DRAW_BUFFER4_EXT 0x8829 -#define GL_DRAW_BUFFER5_EXT 0x882A -#define GL_DRAW_BUFFER6_EXT 0x882B -#define GL_DRAW_BUFFER7_EXT 0x882C -#define GL_DRAW_BUFFER8_EXT 0x882D -#define GL_DRAW_BUFFER9_EXT 0x882E -#define GL_DRAW_BUFFER10_EXT 0x882F -#define GL_DRAW_BUFFER11_EXT 0x8830 -#define GL_DRAW_BUFFER12_EXT 0x8831 -#define GL_DRAW_BUFFER13_EXT 0x8832 -#define GL_DRAW_BUFFER14_EXT 0x8833 -#define GL_DRAW_BUFFER15_EXT 0x8834 -#define GL_COLOR_ATTACHMENT0_EXT 0x8CE0 -#define GL_COLOR_ATTACHMENT1_EXT 0x8CE1 -#define GL_COLOR_ATTACHMENT2_EXT 0x8CE2 -#define GL_COLOR_ATTACHMENT3_EXT 0x8CE3 -#define GL_COLOR_ATTACHMENT4_EXT 0x8CE4 -#define GL_COLOR_ATTACHMENT5_EXT 0x8CE5 -#define GL_COLOR_ATTACHMENT6_EXT 0x8CE6 -#define GL_COLOR_ATTACHMENT7_EXT 0x8CE7 -#define GL_COLOR_ATTACHMENT8_EXT 0x8CE8 -#define GL_COLOR_ATTACHMENT9_EXT 0x8CE9 -#define GL_COLOR_ATTACHMENT10_EXT 0x8CEA -#define GL_COLOR_ATTACHMENT11_EXT 0x8CEB -#define GL_COLOR_ATTACHMENT12_EXT 0x8CEC -#define GL_COLOR_ATTACHMENT13_EXT 0x8CED -#define GL_COLOR_ATTACHMENT14_EXT 0x8CEE -#define GL_COLOR_ATTACHMENT15_EXT 0x8CEF -#define GL_MAX_COLOR_ATTACHMENTS_EXT 0x8CDF -#endif - -/* GL_NV_draw_instanced */ -/* No new tokens introduced by this extension. */ - -/* GL_NV_fbo_color_attachments */ -#ifndef GL_NV_fbo_color_attachments -#define GL_MAX_COLOR_ATTACHMENTS_NV 0x8CDF -/* GL_COLOR_ATTACHMENT{0-15}_NV defined in GL_NV_draw_buffers already. */ -#endif - -/* GL_NV_fence */ -#ifndef GL_NV_fence -#define GL_ALL_COMPLETED_NV 0x84F2 -#define GL_FENCE_STATUS_NV 0x84F3 -#define GL_FENCE_CONDITION_NV 0x84F4 -#endif - -/* GL_NV_framebuffer_blit */ -#ifndef GL_NV_framebuffer_blit -#define GL_READ_FRAMEBUFFER_NV 0x8CA8 -#define GL_DRAW_FRAMEBUFFER_NV 0x8CA9 -#define GL_DRAW_FRAMEBUFFER_BINDING_NV 0x8CA6 -#define GL_READ_FRAMEBUFFER_BINDING_NV 0x8CAA -#endif - -/* GL_NV_framebuffer_multisample */ -#ifndef GL_NV_framebuffer_multisample -#define GL_RENDERBUFFER_SAMPLES_NV 0x8CAB -#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_NV 0x8D56 -#define GL_MAX_SAMPLES_NV 0x8D57 -#endif - -/* GL_NV_generate_mipmap_sRGB */ -/* No new tokens introduced by this extension. */ - -/* GL_NV_instanced_arrays */ -#ifndef GL_NV_instanced_arrays -#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR_NV 0x88FE -#endif - -/* GL_NV_read_buffer */ -#ifndef GL_NV_read_buffer -#define GL_READ_BUFFER_NV 0x0C02 -#endif - -/* GL_NV_read_buffer_front */ -/* No new tokens introduced by this extension. */ - -/* GL_NV_read_depth */ -/* No new tokens introduced by this extension. */ - -/* GL_NV_read_depth_stencil */ -/* No new tokens introduced by this extension. */ - -/* GL_NV_read_stencil */ -/* No new tokens introduced by this extension. */ - -/* GL_NV_shadow_samplers_array */ -#ifndef GL_NV_shadow_samplers_array -#define GL_SAMPLER_2D_ARRAY_SHADOW_NV 0x8DC4 -#endif - -/* GL_NV_shadow_samplers_cube */ -#ifndef GL_NV_shadow_samplers_cube -#define GL_SAMPLER_CUBE_SHADOW_NV 0x8DC5 -#endif - -/* GL_NV_sRGB_formats */ -#ifndef GL_NV_sRGB_formats -#define GL_SLUMINANCE_NV 0x8C46 -#define GL_SLUMINANCE_ALPHA_NV 0x8C44 -#define GL_SRGB8_NV 0x8C41 -#define GL_SLUMINANCE8_NV 0x8C47 -#define GL_SLUMINANCE8_ALPHA8_NV 0x8C45 -#define GL_COMPRESSED_SRGB_S3TC_DXT1_NV 0x8C4C -#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_NV 0x8C4D -#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_NV 0x8C4E -#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_NV 0x8C4F -#define GL_ETC1_SRGB8_NV 0x88EE -#endif - -/* GL_NV_texture_border_clamp */ -#ifndef GL_NV_texture_border_clamp -#define GL_TEXTURE_BORDER_COLOR_NV 0x1004 -#define GL_CLAMP_TO_BORDER_NV 0x812D -#endif - -/* GL_NV_texture_compression_s3tc_update */ -/* No new tokens introduced by this extension. */ - -/* GL_NV_texture_npot_2D_mipmap */ -/* No new tokens introduced by this extension. */ - -/*------------------------------------------------------------------------* - * QCOM extension tokens - *------------------------------------------------------------------------*/ - -/* GL_QCOM_alpha_test */ -#ifndef GL_QCOM_alpha_test -#define GL_ALPHA_TEST_QCOM 0x0BC0 -#define GL_ALPHA_TEST_FUNC_QCOM 0x0BC1 -#define GL_ALPHA_TEST_REF_QCOM 0x0BC2 -#endif - -/* GL_QCOM_binning_control */ -#ifndef GL_QCOM_binning_control -#define GL_BINNING_CONTROL_HINT_QCOM 0x8FB0 -#define GL_CPU_OPTIMIZED_QCOM 0x8FB1 -#define GL_GPU_OPTIMIZED_QCOM 0x8FB2 -#define GL_RENDER_DIRECT_TO_FRAMEBUFFER_QCOM 0x8FB3 -#endif - -/* GL_QCOM_driver_control */ -/* No new tokens introduced by this extension. */ - -/* GL_QCOM_extended_get */ -#ifndef GL_QCOM_extended_get -#define GL_TEXTURE_WIDTH_QCOM 0x8BD2 -#define GL_TEXTURE_HEIGHT_QCOM 0x8BD3 -#define GL_TEXTURE_DEPTH_QCOM 0x8BD4 -#define GL_TEXTURE_INTERNAL_FORMAT_QCOM 0x8BD5 -#define GL_TEXTURE_FORMAT_QCOM 0x8BD6 -#define GL_TEXTURE_TYPE_QCOM 0x8BD7 -#define GL_TEXTURE_IMAGE_VALID_QCOM 0x8BD8 -#define GL_TEXTURE_NUM_LEVELS_QCOM 0x8BD9 -#define GL_TEXTURE_TARGET_QCOM 0x8BDA -#define GL_TEXTURE_OBJECT_VALID_QCOM 0x8BDB -#define GL_STATE_RESTORE 0x8BDC -#endif - -/* GL_QCOM_extended_get2 */ -/* No new tokens introduced by this extension. */ - -/* GL_QCOM_perfmon_global_mode */ -#ifndef GL_QCOM_perfmon_global_mode -#define GL_PERFMON_GLOBAL_MODE_QCOM 0x8FA0 -#endif +#define GL_KHR_texture_compression_astc_ldr 1 +#endif /* GL_KHR_texture_compression_astc_ldr */ -/* GL_QCOM_writeonly_rendering */ -#ifndef GL_QCOM_writeonly_rendering -#define GL_WRITEONLY_RENDERING_QCOM 0x8823 +#ifndef GL_OES_EGL_image +#define GL_OES_EGL_image 1 +typedef void *GLeglImageOES; +typedef void (GL_APIENTRYP PFNGLEGLIMAGETARGETTEXTURE2DOESPROC) (GLenum target, GLeglImageOES image); +typedef void (GL_APIENTRYP PFNGLEGLIMAGETARGETRENDERBUFFERSTORAGEOESPROC) (GLenum target, GLeglImageOES image); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glEGLImageTargetTexture2DOES (GLenum target, GLeglImageOES image); +GL_APICALL void GL_APIENTRY glEGLImageTargetRenderbufferStorageOES (GLenum target, GLeglImageOES image); #endif +#endif /* GL_OES_EGL_image */ -/* GL_QCOM_tiled_rendering */ -#ifndef GL_QCOM_tiled_rendering -#define GL_COLOR_BUFFER_BIT0_QCOM 0x00000001 -#define GL_COLOR_BUFFER_BIT1_QCOM 0x00000002 -#define GL_COLOR_BUFFER_BIT2_QCOM 0x00000004 -#define GL_COLOR_BUFFER_BIT3_QCOM 0x00000008 -#define GL_COLOR_BUFFER_BIT4_QCOM 0x00000010 -#define GL_COLOR_BUFFER_BIT5_QCOM 0x00000020 -#define GL_COLOR_BUFFER_BIT6_QCOM 0x00000040 -#define GL_COLOR_BUFFER_BIT7_QCOM 0x00000080 -#define GL_DEPTH_BUFFER_BIT0_QCOM 0x00000100 -#define GL_DEPTH_BUFFER_BIT1_QCOM 0x00000200 -#define GL_DEPTH_BUFFER_BIT2_QCOM 0x00000400 -#define GL_DEPTH_BUFFER_BIT3_QCOM 0x00000800 -#define GL_DEPTH_BUFFER_BIT4_QCOM 0x00001000 -#define GL_DEPTH_BUFFER_BIT5_QCOM 0x00002000 -#define GL_DEPTH_BUFFER_BIT6_QCOM 0x00004000 -#define GL_DEPTH_BUFFER_BIT7_QCOM 0x00008000 -#define GL_STENCIL_BUFFER_BIT0_QCOM 0x00010000 -#define GL_STENCIL_BUFFER_BIT1_QCOM 0x00020000 -#define GL_STENCIL_BUFFER_BIT2_QCOM 0x00040000 -#define GL_STENCIL_BUFFER_BIT3_QCOM 0x00080000 -#define GL_STENCIL_BUFFER_BIT4_QCOM 0x00100000 -#define GL_STENCIL_BUFFER_BIT5_QCOM 0x00200000 -#define GL_STENCIL_BUFFER_BIT6_QCOM 0x00400000 -#define GL_STENCIL_BUFFER_BIT7_QCOM 0x00800000 -#define GL_MULTISAMPLE_BUFFER_BIT0_QCOM 0x01000000 -#define GL_MULTISAMPLE_BUFFER_BIT1_QCOM 0x02000000 -#define GL_MULTISAMPLE_BUFFER_BIT2_QCOM 0x04000000 -#define GL_MULTISAMPLE_BUFFER_BIT3_QCOM 0x08000000 -#define GL_MULTISAMPLE_BUFFER_BIT4_QCOM 0x10000000 -#define GL_MULTISAMPLE_BUFFER_BIT5_QCOM 0x20000000 -#define GL_MULTISAMPLE_BUFFER_BIT6_QCOM 0x40000000 -#define GL_MULTISAMPLE_BUFFER_BIT7_QCOM 0x80000000 -#endif - -/*------------------------------------------------------------------------* - * VIV extension tokens - *------------------------------------------------------------------------*/ - -/* GL_VIV_shader_binary */ -#ifndef GL_VIV_shader_binary -#define GL_SHADER_BINARY_VIV 0x8FC4 -#endif +#ifndef GL_OES_EGL_image_external +#define GL_OES_EGL_image_external 1 +#define GL_TEXTURE_EXTERNAL_OES 0x8D65 +#define GL_TEXTURE_BINDING_EXTERNAL_OES 0x8D67 +#define GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES 0x8D68 +#define GL_SAMPLER_EXTERNAL_OES 0x8D66 +#endif /* GL_OES_EGL_image_external */ -/*------------------------------------------------------------------------* - * End of extension tokens, start of corresponding extension functions - *------------------------------------------------------------------------*/ +#ifndef GL_OES_EGL_image_external_essl3 +#define GL_OES_EGL_image_external_essl3 1 +#endif /* GL_OES_EGL_image_external_essl3 */ -/*------------------------------------------------------------------------* - * OES extension functions - *------------------------------------------------------------------------*/ +#ifndef GL_OES_compressed_ETC1_RGB8_sub_texture +#define GL_OES_compressed_ETC1_RGB8_sub_texture 1 +#endif /* GL_OES_compressed_ETC1_RGB8_sub_texture */ -/* GL_OES_compressed_ETC1_RGB8_texture */ #ifndef GL_OES_compressed_ETC1_RGB8_texture #define GL_OES_compressed_ETC1_RGB8_texture 1 -#endif +#define GL_ETC1_RGB8_OES 0x8D64 +#endif /* GL_OES_compressed_ETC1_RGB8_texture */ -/* GL_OES_compressed_paletted_texture */ #ifndef GL_OES_compressed_paletted_texture #define GL_OES_compressed_paletted_texture 1 +#define GL_PALETTE4_RGB8_OES 0x8B90 +#define GL_PALETTE4_RGBA8_OES 0x8B91 +#define GL_PALETTE4_R5_G6_B5_OES 0x8B92 +#define GL_PALETTE4_RGBA4_OES 0x8B93 +#define GL_PALETTE4_RGB5_A1_OES 0x8B94 +#define GL_PALETTE8_RGB8_OES 0x8B95 +#define GL_PALETTE8_RGBA8_OES 0x8B96 +#define GL_PALETTE8_R5_G6_B5_OES 0x8B97 +#define GL_PALETTE8_RGBA4_OES 0x8B98 +#define GL_PALETTE8_RGB5_A1_OES 0x8B99 +#endif /* GL_OES_compressed_paletted_texture */ + +#ifndef GL_OES_copy_image +#define GL_OES_copy_image 1 +typedef void (GL_APIENTRYP PFNGLCOPYIMAGESUBDATAOESPROC) (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); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glCopyImageSubDataOES (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); #endif +#endif /* GL_OES_copy_image */ -/* GL_OES_depth24 */ #ifndef GL_OES_depth24 #define GL_OES_depth24 1 -#endif +#define GL_DEPTH_COMPONENT24_OES 0x81A6 +#endif /* GL_OES_depth24 */ -/* GL_OES_depth32 */ #ifndef GL_OES_depth32 #define GL_OES_depth32 1 -#endif +#define GL_DEPTH_COMPONENT32_OES 0x81A7 +#endif /* GL_OES_depth32 */ -/* GL_OES_depth_texture */ #ifndef GL_OES_depth_texture #define GL_OES_depth_texture 1 -#endif - -/* GL_OES_EGL_image */ -#ifndef GL_OES_EGL_image -#define GL_OES_EGL_image 1 +#endif /* GL_OES_depth_texture */ + +#ifndef GL_OES_draw_buffers_indexed +#define GL_OES_draw_buffers_indexed 1 +#define GL_MIN 0x8007 +#define GL_MAX 0x8008 +typedef void (GL_APIENTRYP PFNGLENABLEIOESPROC) (GLenum target, GLuint index); +typedef void (GL_APIENTRYP PFNGLDISABLEIOESPROC) (GLenum target, GLuint index); +typedef void (GL_APIENTRYP PFNGLBLENDEQUATIONIOESPROC) (GLuint buf, GLenum mode); +typedef void (GL_APIENTRYP PFNGLBLENDEQUATIONSEPARATEIOESPROC) (GLuint buf, GLenum modeRGB, GLenum modeAlpha); +typedef void (GL_APIENTRYP PFNGLBLENDFUNCIOESPROC) (GLuint buf, GLenum src, GLenum dst); +typedef void (GL_APIENTRYP PFNGLBLENDFUNCSEPARATEIOESPROC) (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha); +typedef void (GL_APIENTRYP PFNGLCOLORMASKIOESPROC) (GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a); +typedef GLboolean (GL_APIENTRYP PFNGLISENABLEDIOESPROC) (GLenum target, GLuint index); #ifdef GL_GLEXT_PROTOTYPES -GL_APICALL void GL_APIENTRY glEGLImageTargetTexture2DOES (GLenum target, GLeglImageOES image); -GL_APICALL void GL_APIENTRY glEGLImageTargetRenderbufferStorageOES (GLenum target, GLeglImageOES image); -#endif -typedef void (GL_APIENTRYP PFNGLEGLIMAGETARGETTEXTURE2DOESPROC) (GLenum target, GLeglImageOES image); -typedef void (GL_APIENTRYP PFNGLEGLIMAGETARGETRENDERBUFFERSTORAGEOESPROC) (GLenum target, GLeglImageOES image); -#endif - -/* GL_OES_EGL_image_external */ -#ifndef GL_OES_EGL_image_external -#define GL_OES_EGL_image_external 1 -/* glEGLImageTargetTexture2DOES defined in GL_OES_EGL_image already. */ +GL_APICALL void GL_APIENTRY glEnableiOES (GLenum target, GLuint index); +GL_APICALL void GL_APIENTRY glDisableiOES (GLenum target, GLuint index); +GL_APICALL void GL_APIENTRY glBlendEquationiOES (GLuint buf, GLenum mode); +GL_APICALL void GL_APIENTRY glBlendEquationSeparateiOES (GLuint buf, GLenum modeRGB, GLenum modeAlpha); +GL_APICALL void GL_APIENTRY glBlendFunciOES (GLuint buf, GLenum src, GLenum dst); +GL_APICALL void GL_APIENTRY glBlendFuncSeparateiOES (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha); +GL_APICALL void GL_APIENTRY glColorMaskiOES (GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a); +GL_APICALL GLboolean GL_APIENTRY glIsEnablediOES (GLenum target, GLuint index); +#endif +#endif /* GL_OES_draw_buffers_indexed */ + +#ifndef GL_OES_draw_elements_base_vertex +#define GL_OES_draw_elements_base_vertex 1 +typedef void (GL_APIENTRYP PFNGLDRAWELEMENTSBASEVERTEXOESPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLint basevertex); +typedef void (GL_APIENTRYP PFNGLDRAWRANGEELEMENTSBASEVERTEXOESPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices, GLint basevertex); +typedef void (GL_APIENTRYP PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXOESPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLint basevertex); +typedef void (GL_APIENTRYP PFNGLMULTIDRAWELEMENTSBASEVERTEXOESPROC) (GLenum mode, const GLsizei *count, GLenum type, const void *const*indices, GLsizei primcount, const GLint *basevertex); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glDrawElementsBaseVertexOES (GLenum mode, GLsizei count, GLenum type, const void *indices, GLint basevertex); +GL_APICALL void GL_APIENTRY glDrawRangeElementsBaseVertexOES (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices, GLint basevertex); +GL_APICALL void GL_APIENTRY glDrawElementsInstancedBaseVertexOES (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLint basevertex); +GL_APICALL void GL_APIENTRY glMultiDrawElementsBaseVertexOES (GLenum mode, const GLsizei *count, GLenum type, const void *const*indices, GLsizei primcount, const GLint *basevertex); #endif +#endif /* GL_OES_draw_elements_base_vertex */ -/* GL_OES_element_index_uint */ #ifndef GL_OES_element_index_uint #define GL_OES_element_index_uint 1 -#endif +#endif /* GL_OES_element_index_uint */ -/* GL_OES_fbo_render_mipmap */ #ifndef GL_OES_fbo_render_mipmap #define GL_OES_fbo_render_mipmap 1 -#endif +#endif /* GL_OES_fbo_render_mipmap */ -/* GL_OES_fragment_precision_high */ #ifndef GL_OES_fragment_precision_high #define GL_OES_fragment_precision_high 1 +#endif /* GL_OES_fragment_precision_high */ + +#ifndef GL_OES_geometry_point_size +#define GL_OES_geometry_point_size 1 +#endif /* GL_OES_geometry_point_size */ + +#ifndef GL_OES_geometry_shader +#define GL_OES_geometry_shader 1 +#define GL_GEOMETRY_SHADER_OES 0x8DD9 +#define GL_GEOMETRY_SHADER_BIT_OES 0x00000004 +#define GL_GEOMETRY_LINKED_VERTICES_OUT_OES 0x8916 +#define GL_GEOMETRY_LINKED_INPUT_TYPE_OES 0x8917 +#define GL_GEOMETRY_LINKED_OUTPUT_TYPE_OES 0x8918 +#define GL_GEOMETRY_SHADER_INVOCATIONS_OES 0x887F +#define GL_LAYER_PROVOKING_VERTEX_OES 0x825E +#define GL_LINES_ADJACENCY_OES 0x000A +#define GL_LINE_STRIP_ADJACENCY_OES 0x000B +#define GL_TRIANGLES_ADJACENCY_OES 0x000C +#define GL_TRIANGLE_STRIP_ADJACENCY_OES 0x000D +#define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_OES 0x8DDF +#define GL_MAX_GEOMETRY_UNIFORM_BLOCKS_OES 0x8A2C +#define GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS_OES 0x8A32 +#define GL_MAX_GEOMETRY_INPUT_COMPONENTS_OES 0x9123 +#define GL_MAX_GEOMETRY_OUTPUT_COMPONENTS_OES 0x9124 +#define GL_MAX_GEOMETRY_OUTPUT_VERTICES_OES 0x8DE0 +#define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_OES 0x8DE1 +#define GL_MAX_GEOMETRY_SHADER_INVOCATIONS_OES 0x8E5A +#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_OES 0x8C29 +#define GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS_OES 0x92CF +#define GL_MAX_GEOMETRY_ATOMIC_COUNTERS_OES 0x92D5 +#define GL_MAX_GEOMETRY_IMAGE_UNIFORMS_OES 0x90CD +#define GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS_OES 0x90D7 +#define GL_FIRST_VERTEX_CONVENTION_OES 0x8E4D +#define GL_LAST_VERTEX_CONVENTION_OES 0x8E4E +#define GL_UNDEFINED_VERTEX_OES 0x8260 +#define GL_PRIMITIVES_GENERATED_OES 0x8C87 +#define GL_FRAMEBUFFER_DEFAULT_LAYERS_OES 0x9312 +#define GL_MAX_FRAMEBUFFER_LAYERS_OES 0x9317 +#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_OES 0x8DA8 +#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED_OES 0x8DA7 +#define GL_REFERENCED_BY_GEOMETRY_SHADER_OES 0x9309 +typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERTEXTUREOESPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glFramebufferTextureOES (GLenum target, GLenum attachment, GLuint texture, GLint level); #endif +#endif /* GL_OES_geometry_shader */ -/* GL_OES_get_program_binary */ #ifndef GL_OES_get_program_binary #define GL_OES_get_program_binary 1 +#define GL_PROGRAM_BINARY_LENGTH_OES 0x8741 +#define GL_NUM_PROGRAM_BINARY_FORMATS_OES 0x87FE +#define GL_PROGRAM_BINARY_FORMATS_OES 0x87FF +typedef void (GL_APIENTRYP PFNGLGETPROGRAMBINARYOESPROC) (GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, void *binary); +typedef void (GL_APIENTRYP PFNGLPROGRAMBINARYOESPROC) (GLuint program, GLenum binaryFormat, const void *binary, GLint length); #ifdef GL_GLEXT_PROTOTYPES -GL_APICALL void GL_APIENTRY glGetProgramBinaryOES (GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, GLvoid *binary); -GL_APICALL void GL_APIENTRY glProgramBinaryOES (GLuint program, GLenum binaryFormat, const GLvoid *binary, GLint length); -#endif -typedef void (GL_APIENTRYP PFNGLGETPROGRAMBINARYOESPROC) (GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, GLvoid *binary); -typedef void (GL_APIENTRYP PFNGLPROGRAMBINARYOESPROC) (GLuint program, GLenum binaryFormat, const GLvoid *binary, GLint length); +GL_APICALL void GL_APIENTRY glGetProgramBinaryOES (GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, void *binary); +GL_APICALL void GL_APIENTRY glProgramBinaryOES (GLuint program, GLenum binaryFormat, const void *binary, GLint length); #endif +#endif /* GL_OES_get_program_binary */ + +#ifndef GL_OES_gpu_shader5 +#define GL_OES_gpu_shader5 1 +#endif /* GL_OES_gpu_shader5 */ -/* GL_OES_mapbuffer */ #ifndef GL_OES_mapbuffer #define GL_OES_mapbuffer 1 +#define GL_WRITE_ONLY_OES 0x88B9 +#define GL_BUFFER_ACCESS_OES 0x88BB +#define GL_BUFFER_MAPPED_OES 0x88BC +#define GL_BUFFER_MAP_POINTER_OES 0x88BD +typedef void *(GL_APIENTRYP PFNGLMAPBUFFEROESPROC) (GLenum target, GLenum access); +typedef GLboolean (GL_APIENTRYP PFNGLUNMAPBUFFEROESPROC) (GLenum target); +typedef void (GL_APIENTRYP PFNGLGETBUFFERPOINTERVOESPROC) (GLenum target, GLenum pname, void **params); #ifdef GL_GLEXT_PROTOTYPES -GL_APICALL void* GL_APIENTRY glMapBufferOES (GLenum target, GLenum access); +GL_APICALL void *GL_APIENTRY glMapBufferOES (GLenum target, GLenum access); GL_APICALL GLboolean GL_APIENTRY glUnmapBufferOES (GLenum target); -GL_APICALL void GL_APIENTRY glGetBufferPointervOES (GLenum target, GLenum pname, GLvoid** params); -#endif -typedef void* (GL_APIENTRYP PFNGLMAPBUFFEROESPROC) (GLenum target, GLenum access); -typedef GLboolean (GL_APIENTRYP PFNGLUNMAPBUFFEROESPROC) (GLenum target); -typedef void (GL_APIENTRYP PFNGLGETBUFFERPOINTERVOESPROC) (GLenum target, GLenum pname, GLvoid** params); +GL_APICALL void GL_APIENTRY glGetBufferPointervOES (GLenum target, GLenum pname, void **params); #endif +#endif /* GL_OES_mapbuffer */ -/* GL_OES_packed_depth_stencil */ #ifndef GL_OES_packed_depth_stencil #define GL_OES_packed_depth_stencil 1 +#define GL_DEPTH_STENCIL_OES 0x84F9 +#define GL_UNSIGNED_INT_24_8_OES 0x84FA +#define GL_DEPTH24_STENCIL8_OES 0x88F0 +#endif /* GL_OES_packed_depth_stencil */ + +#ifndef GL_OES_primitive_bounding_box +#define GL_OES_primitive_bounding_box 1 +#define GL_PRIMITIVE_BOUNDING_BOX_OES 0x92BE +typedef void (GL_APIENTRYP PFNGLPRIMITIVEBOUNDINGBOXOESPROC) (GLfloat minX, GLfloat minY, GLfloat minZ, GLfloat minW, GLfloat maxX, GLfloat maxY, GLfloat maxZ, GLfloat maxW); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glPrimitiveBoundingBoxOES (GLfloat minX, GLfloat minY, GLfloat minZ, GLfloat minW, GLfloat maxX, GLfloat maxY, GLfloat maxZ, GLfloat maxW); #endif +#endif /* GL_OES_primitive_bounding_box */ -/* GL_OES_required_internalformat */ #ifndef GL_OES_required_internalformat #define GL_OES_required_internalformat 1 -#endif +#define GL_ALPHA8_OES 0x803C +#define GL_DEPTH_COMPONENT16_OES 0x81A5 +#define GL_LUMINANCE4_ALPHA4_OES 0x8043 +#define GL_LUMINANCE8_ALPHA8_OES 0x8045 +#define GL_LUMINANCE8_OES 0x8040 +#define GL_RGBA4_OES 0x8056 +#define GL_RGB5_A1_OES 0x8057 +#define GL_RGB565_OES 0x8D62 +#define GL_RGB8_OES 0x8051 +#define GL_RGBA8_OES 0x8058 +#define GL_RGB10_EXT 0x8052 +#define GL_RGB10_A2_EXT 0x8059 +#endif /* GL_OES_required_internalformat */ -/* GL_OES_rgb8_rgba8 */ #ifndef GL_OES_rgb8_rgba8 #define GL_OES_rgb8_rgba8 1 +#endif /* GL_OES_rgb8_rgba8 */ + +#ifndef GL_OES_sample_shading +#define GL_OES_sample_shading 1 +#define GL_SAMPLE_SHADING_OES 0x8C36 +#define GL_MIN_SAMPLE_SHADING_VALUE_OES 0x8C37 +typedef void (GL_APIENTRYP PFNGLMINSAMPLESHADINGOESPROC) (GLfloat value); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glMinSampleShadingOES (GLfloat value); #endif +#endif /* GL_OES_sample_shading */ + +#ifndef GL_OES_sample_variables +#define GL_OES_sample_variables 1 +#endif /* GL_OES_sample_variables */ + +#ifndef GL_OES_shader_image_atomic +#define GL_OES_shader_image_atomic 1 +#endif /* GL_OES_shader_image_atomic */ + +#ifndef GL_OES_shader_io_blocks +#define GL_OES_shader_io_blocks 1 +#endif /* GL_OES_shader_io_blocks */ + +#ifndef GL_OES_shader_multisample_interpolation +#define GL_OES_shader_multisample_interpolation 1 +#define GL_MIN_FRAGMENT_INTERPOLATION_OFFSET_OES 0x8E5B +#define GL_MAX_FRAGMENT_INTERPOLATION_OFFSET_OES 0x8E5C +#define GL_FRAGMENT_INTERPOLATION_OFFSET_BITS_OES 0x8E5D +#endif /* GL_OES_shader_multisample_interpolation */ -/* GL_OES_standard_derivatives */ #ifndef GL_OES_standard_derivatives #define GL_OES_standard_derivatives 1 -#endif +#define GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES 0x8B8B +#endif /* GL_OES_standard_derivatives */ -/* GL_OES_stencil1 */ #ifndef GL_OES_stencil1 #define GL_OES_stencil1 1 -#endif +#define GL_STENCIL_INDEX1_OES 0x8D46 +#endif /* GL_OES_stencil1 */ -/* GL_OES_stencil4 */ #ifndef GL_OES_stencil4 #define GL_OES_stencil4 1 -#endif +#define GL_STENCIL_INDEX4_OES 0x8D47 +#endif /* GL_OES_stencil4 */ #ifndef GL_OES_surfaceless_context #define GL_OES_surfaceless_context 1 +#define GL_FRAMEBUFFER_UNDEFINED_OES 0x8219 +#endif /* GL_OES_surfaceless_context */ + +#ifndef GL_OES_tessellation_point_size +#define GL_OES_tessellation_point_size 1 +#endif /* GL_OES_tessellation_point_size */ + +#ifndef GL_OES_tessellation_shader +#define GL_OES_tessellation_shader 1 +#define GL_PATCHES_OES 0x000E +#define GL_PATCH_VERTICES_OES 0x8E72 +#define GL_TESS_CONTROL_OUTPUT_VERTICES_OES 0x8E75 +#define GL_TESS_GEN_MODE_OES 0x8E76 +#define GL_TESS_GEN_SPACING_OES 0x8E77 +#define GL_TESS_GEN_VERTEX_ORDER_OES 0x8E78 +#define GL_TESS_GEN_POINT_MODE_OES 0x8E79 +#define GL_ISOLINES_OES 0x8E7A +#define GL_QUADS_OES 0x0007 +#define GL_FRACTIONAL_ODD_OES 0x8E7B +#define GL_FRACTIONAL_EVEN_OES 0x8E7C +#define GL_MAX_PATCH_VERTICES_OES 0x8E7D +#define GL_MAX_TESS_GEN_LEVEL_OES 0x8E7E +#define GL_MAX_TESS_CONTROL_UNIFORM_COMPONENTS_OES 0x8E7F +#define GL_MAX_TESS_EVALUATION_UNIFORM_COMPONENTS_OES 0x8E80 +#define GL_MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS_OES 0x8E81 +#define GL_MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS_OES 0x8E82 +#define GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS_OES 0x8E83 +#define GL_MAX_TESS_PATCH_COMPONENTS_OES 0x8E84 +#define GL_MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS_OES 0x8E85 +#define GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS_OES 0x8E86 +#define GL_MAX_TESS_CONTROL_UNIFORM_BLOCKS_OES 0x8E89 +#define GL_MAX_TESS_EVALUATION_UNIFORM_BLOCKS_OES 0x8E8A +#define GL_MAX_TESS_CONTROL_INPUT_COMPONENTS_OES 0x886C +#define GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS_OES 0x886D +#define GL_MAX_COMBINED_TESS_CONTROL_UNIFORM_COMPONENTS_OES 0x8E1E +#define GL_MAX_COMBINED_TESS_EVALUATION_UNIFORM_COMPONENTS_OES 0x8E1F +#define GL_MAX_TESS_CONTROL_ATOMIC_COUNTER_BUFFERS_OES 0x92CD +#define GL_MAX_TESS_EVALUATION_ATOMIC_COUNTER_BUFFERS_OES 0x92CE +#define GL_MAX_TESS_CONTROL_ATOMIC_COUNTERS_OES 0x92D3 +#define GL_MAX_TESS_EVALUATION_ATOMIC_COUNTERS_OES 0x92D4 +#define GL_MAX_TESS_CONTROL_IMAGE_UNIFORMS_OES 0x90CB +#define GL_MAX_TESS_EVALUATION_IMAGE_UNIFORMS_OES 0x90CC +#define GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS_OES 0x90D8 +#define GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS_OES 0x90D9 +#define GL_PRIMITIVE_RESTART_FOR_PATCHES_SUPPORTED_OES 0x8221 +#define GL_IS_PER_PATCH_OES 0x92E7 +#define GL_REFERENCED_BY_TESS_CONTROL_SHADER_OES 0x9307 +#define GL_REFERENCED_BY_TESS_EVALUATION_SHADER_OES 0x9308 +#define GL_TESS_CONTROL_SHADER_OES 0x8E88 +#define GL_TESS_EVALUATION_SHADER_OES 0x8E87 +#define GL_TESS_CONTROL_SHADER_BIT_OES 0x00000008 +#define GL_TESS_EVALUATION_SHADER_BIT_OES 0x00000010 +typedef void (GL_APIENTRYP PFNGLPATCHPARAMETERIOESPROC) (GLenum pname, GLint value); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glPatchParameteriOES (GLenum pname, GLint value); #endif +#endif /* GL_OES_tessellation_shader */ -/* GL_OES_texture_3D */ #ifndef GL_OES_texture_3D #define GL_OES_texture_3D 1 +#define GL_TEXTURE_WRAP_R_OES 0x8072 +#define GL_TEXTURE_3D_OES 0x806F +#define GL_TEXTURE_BINDING_3D_OES 0x806A +#define GL_MAX_3D_TEXTURE_SIZE_OES 0x8073 +#define GL_SAMPLER_3D_OES 0x8B5F +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_OES 0x8CD4 +typedef void (GL_APIENTRYP PFNGLTEXIMAGE3DOESPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *pixels); +typedef void (GL_APIENTRYP PFNGLTEXSUBIMAGE3DOESPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels); +typedef void (GL_APIENTRYP PFNGLCOPYTEXSUBIMAGE3DOESPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (GL_APIENTRYP PFNGLCOMPRESSEDTEXIMAGE3DOESPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *data); +typedef void (GL_APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE3DOESPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *data); +typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERTEXTURE3DOESPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset); #ifdef GL_GLEXT_PROTOTYPES -GL_APICALL void GL_APIENTRY glTexImage3DOES (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid* pixels); -GL_APICALL void GL_APIENTRY glTexSubImage3DOES (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid* pixels); +GL_APICALL void GL_APIENTRY glTexImage3DOES (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *pixels); +GL_APICALL void GL_APIENTRY glTexSubImage3DOES (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels); GL_APICALL void GL_APIENTRY glCopyTexSubImage3DOES (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); -GL_APICALL void GL_APIENTRY glCompressedTexImage3DOES (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid* data); -GL_APICALL void GL_APIENTRY glCompressedTexSubImage3DOES (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid* data); +GL_APICALL void GL_APIENTRY glCompressedTexImage3DOES (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *data); +GL_APICALL void GL_APIENTRY glCompressedTexSubImage3DOES (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *data); GL_APICALL void GL_APIENTRY glFramebufferTexture3DOES (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset); #endif -typedef void (GL_APIENTRYP PFNGLTEXIMAGE3DOESPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid* pixels); -typedef void (GL_APIENTRYP PFNGLTEXSUBIMAGE3DOESPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid* pixels); -typedef void (GL_APIENTRYP PFNGLCOPYTEXSUBIMAGE3DOESPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); -typedef void (GL_APIENTRYP PFNGLCOMPRESSEDTEXIMAGE3DOESPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid* data); -typedef void (GL_APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE3DOESPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid* data); -typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERTEXTURE3DOES) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset); -#endif +#endif /* GL_OES_texture_3D */ + +#ifndef GL_OES_texture_border_clamp +#define GL_OES_texture_border_clamp 1 +#define GL_TEXTURE_BORDER_COLOR_OES 0x1004 +#define GL_CLAMP_TO_BORDER_OES 0x812D +typedef void (GL_APIENTRYP PFNGLTEXPARAMETERIIVOESPROC) (GLenum target, GLenum pname, const GLint *params); +typedef void (GL_APIENTRYP PFNGLTEXPARAMETERIUIVOESPROC) (GLenum target, GLenum pname, const GLuint *params); +typedef void (GL_APIENTRYP PFNGLGETTEXPARAMETERIIVOESPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (GL_APIENTRYP PFNGLGETTEXPARAMETERIUIVOESPROC) (GLenum target, GLenum pname, GLuint *params); +typedef void (GL_APIENTRYP PFNGLSAMPLERPARAMETERIIVOESPROC) (GLuint sampler, GLenum pname, const GLint *param); +typedef void (GL_APIENTRYP PFNGLSAMPLERPARAMETERIUIVOESPROC) (GLuint sampler, GLenum pname, const GLuint *param); +typedef void (GL_APIENTRYP PFNGLGETSAMPLERPARAMETERIIVOESPROC) (GLuint sampler, GLenum pname, GLint *params); +typedef void (GL_APIENTRYP PFNGLGETSAMPLERPARAMETERIUIVOESPROC) (GLuint sampler, GLenum pname, GLuint *params); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glTexParameterIivOES (GLenum target, GLenum pname, const GLint *params); +GL_APICALL void GL_APIENTRY glTexParameterIuivOES (GLenum target, GLenum pname, const GLuint *params); +GL_APICALL void GL_APIENTRY glGetTexParameterIivOES (GLenum target, GLenum pname, GLint *params); +GL_APICALL void GL_APIENTRY glGetTexParameterIuivOES (GLenum target, GLenum pname, GLuint *params); +GL_APICALL void GL_APIENTRY glSamplerParameterIivOES (GLuint sampler, GLenum pname, const GLint *param); +GL_APICALL void GL_APIENTRY glSamplerParameterIuivOES (GLuint sampler, GLenum pname, const GLuint *param); +GL_APICALL void GL_APIENTRY glGetSamplerParameterIivOES (GLuint sampler, GLenum pname, GLint *params); +GL_APICALL void GL_APIENTRY glGetSamplerParameterIuivOES (GLuint sampler, GLenum pname, GLuint *params); +#endif +#endif /* GL_OES_texture_border_clamp */ + +#ifndef GL_OES_texture_buffer +#define GL_OES_texture_buffer 1 +#define GL_TEXTURE_BUFFER_OES 0x8C2A +#define GL_TEXTURE_BUFFER_BINDING_OES 0x8C2A +#define GL_MAX_TEXTURE_BUFFER_SIZE_OES 0x8C2B +#define GL_TEXTURE_BINDING_BUFFER_OES 0x8C2C +#define GL_TEXTURE_BUFFER_DATA_STORE_BINDING_OES 0x8C2D +#define GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT_OES 0x919F +#define GL_SAMPLER_BUFFER_OES 0x8DC2 +#define GL_INT_SAMPLER_BUFFER_OES 0x8DD0 +#define GL_UNSIGNED_INT_SAMPLER_BUFFER_OES 0x8DD8 +#define GL_IMAGE_BUFFER_OES 0x9051 +#define GL_INT_IMAGE_BUFFER_OES 0x905C +#define GL_UNSIGNED_INT_IMAGE_BUFFER_OES 0x9067 +#define GL_TEXTURE_BUFFER_OFFSET_OES 0x919D +#define GL_TEXTURE_BUFFER_SIZE_OES 0x919E +typedef void (GL_APIENTRYP PFNGLTEXBUFFEROESPROC) (GLenum target, GLenum internalformat, GLuint buffer); +typedef void (GL_APIENTRYP PFNGLTEXBUFFERRANGEOESPROC) (GLenum target, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glTexBufferOES (GLenum target, GLenum internalformat, GLuint buffer); +GL_APICALL void GL_APIENTRY glTexBufferRangeOES (GLenum target, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size); +#endif +#endif /* GL_OES_texture_buffer */ + +#ifndef GL_OES_texture_compression_astc +#define GL_OES_texture_compression_astc 1 +#define GL_COMPRESSED_RGBA_ASTC_3x3x3_OES 0x93C0 +#define GL_COMPRESSED_RGBA_ASTC_4x3x3_OES 0x93C1 +#define GL_COMPRESSED_RGBA_ASTC_4x4x3_OES 0x93C2 +#define GL_COMPRESSED_RGBA_ASTC_4x4x4_OES 0x93C3 +#define GL_COMPRESSED_RGBA_ASTC_5x4x4_OES 0x93C4 +#define GL_COMPRESSED_RGBA_ASTC_5x5x4_OES 0x93C5 +#define GL_COMPRESSED_RGBA_ASTC_5x5x5_OES 0x93C6 +#define GL_COMPRESSED_RGBA_ASTC_6x5x5_OES 0x93C7 +#define GL_COMPRESSED_RGBA_ASTC_6x6x5_OES 0x93C8 +#define GL_COMPRESSED_RGBA_ASTC_6x6x6_OES 0x93C9 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_3x3x3_OES 0x93E0 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x3x3_OES 0x93E1 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x3_OES 0x93E2 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x4_OES 0x93E3 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4x4_OES 0x93E4 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x4_OES 0x93E5 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x5_OES 0x93E6 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5x5_OES 0x93E7 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x5_OES 0x93E8 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x6_OES 0x93E9 +#endif /* GL_OES_texture_compression_astc */ + +#ifndef GL_OES_texture_cube_map_array +#define GL_OES_texture_cube_map_array 1 +#define GL_TEXTURE_CUBE_MAP_ARRAY_OES 0x9009 +#define GL_TEXTURE_BINDING_CUBE_MAP_ARRAY_OES 0x900A +#define GL_SAMPLER_CUBE_MAP_ARRAY_OES 0x900C +#define GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW_OES 0x900D +#define GL_INT_SAMPLER_CUBE_MAP_ARRAY_OES 0x900E +#define GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY_OES 0x900F +#define GL_IMAGE_CUBE_MAP_ARRAY_OES 0x9054 +#define GL_INT_IMAGE_CUBE_MAP_ARRAY_OES 0x905F +#define GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY_OES 0x906A +#endif /* GL_OES_texture_cube_map_array */ -/* GL_OES_texture_float */ #ifndef GL_OES_texture_float #define GL_OES_texture_float 1 -#endif +#endif /* GL_OES_texture_float */ -/* GL_OES_texture_float_linear */ #ifndef GL_OES_texture_float_linear #define GL_OES_texture_float_linear 1 -#endif +#endif /* GL_OES_texture_float_linear */ -/* GL_OES_texture_half_float */ #ifndef GL_OES_texture_half_float #define GL_OES_texture_half_float 1 -#endif +#define GL_HALF_FLOAT_OES 0x8D61 +#endif /* GL_OES_texture_half_float */ -/* GL_OES_texture_half_float_linear */ #ifndef GL_OES_texture_half_float_linear #define GL_OES_texture_half_float_linear 1 -#endif +#endif /* GL_OES_texture_half_float_linear */ -/* GL_OES_texture_npot */ #ifndef GL_OES_texture_npot #define GL_OES_texture_npot 1 +#endif /* GL_OES_texture_npot */ + +#ifndef GL_OES_texture_stencil8 +#define GL_OES_texture_stencil8 1 +#define GL_STENCIL_INDEX_OES 0x1901 +#define GL_STENCIL_INDEX8_OES 0x8D48 +#endif /* GL_OES_texture_stencil8 */ + +#ifndef GL_OES_texture_storage_multisample_2d_array +#define GL_OES_texture_storage_multisample_2d_array 1 +#define GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES 0x9102 +#define GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY_OES 0x9105 +#define GL_SAMPLER_2D_MULTISAMPLE_ARRAY_OES 0x910B +#define GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY_OES 0x910C +#define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY_OES 0x910D +typedef void (GL_APIENTRYP PFNGLTEXSTORAGE3DMULTISAMPLEOESPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glTexStorage3DMultisampleOES (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations); +#endif +#endif /* GL_OES_texture_storage_multisample_2d_array */ + +#ifndef GL_OES_texture_view +#define GL_OES_texture_view 1 +#define GL_TEXTURE_VIEW_MIN_LEVEL_OES 0x82DB +#define GL_TEXTURE_VIEW_NUM_LEVELS_OES 0x82DC +#define GL_TEXTURE_VIEW_MIN_LAYER_OES 0x82DD +#define GL_TEXTURE_VIEW_NUM_LAYERS_OES 0x82DE +#define GL_TEXTURE_IMMUTABLE_LEVELS 0x82DF +typedef void (GL_APIENTRYP PFNGLTEXTUREVIEWOESPROC) (GLuint texture, GLenum target, GLuint origtexture, GLenum internalformat, GLuint minlevel, GLuint numlevels, GLuint minlayer, GLuint numlayers); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glTextureViewOES (GLuint texture, GLenum target, GLuint origtexture, GLenum internalformat, GLuint minlevel, GLuint numlevels, GLuint minlayer, GLuint numlayers); #endif +#endif /* GL_OES_texture_view */ -/* GL_OES_vertex_array_object */ #ifndef GL_OES_vertex_array_object #define GL_OES_vertex_array_object 1 +#define GL_VERTEX_ARRAY_BINDING_OES 0x85B5 +typedef void (GL_APIENTRYP PFNGLBINDVERTEXARRAYOESPROC) (GLuint array); +typedef void (GL_APIENTRYP PFNGLDELETEVERTEXARRAYSOESPROC) (GLsizei n, const GLuint *arrays); +typedef void (GL_APIENTRYP PFNGLGENVERTEXARRAYSOESPROC) (GLsizei n, GLuint *arrays); +typedef GLboolean (GL_APIENTRYP PFNGLISVERTEXARRAYOESPROC) (GLuint array); #ifdef GL_GLEXT_PROTOTYPES GL_APICALL void GL_APIENTRY glBindVertexArrayOES (GLuint array); GL_APICALL void GL_APIENTRY glDeleteVertexArraysOES (GLsizei n, const GLuint *arrays); GL_APICALL void GL_APIENTRY glGenVertexArraysOES (GLsizei n, GLuint *arrays); GL_APICALL GLboolean GL_APIENTRY glIsVertexArrayOES (GLuint array); #endif -typedef void (GL_APIENTRYP PFNGLBINDVERTEXARRAYOESPROC) (GLuint array); -typedef void (GL_APIENTRYP PFNGLDELETEVERTEXARRAYSOESPROC) (GLsizei n, const GLuint *arrays); -typedef void (GL_APIENTRYP PFNGLGENVERTEXARRAYSOESPROC) (GLsizei n, GLuint *arrays); -typedef GLboolean (GL_APIENTRYP PFNGLISVERTEXARRAYOESPROC) (GLuint array); -#endif +#endif /* GL_OES_vertex_array_object */ -/* GL_OES_vertex_half_float */ #ifndef GL_OES_vertex_half_float #define GL_OES_vertex_half_float 1 -#endif +#endif /* GL_OES_vertex_half_float */ -/* GL_OES_vertex_type_10_10_10_2 */ #ifndef GL_OES_vertex_type_10_10_10_2 #define GL_OES_vertex_type_10_10_10_2 1 -#endif - -/*------------------------------------------------------------------------* - * KHR extension functions - *------------------------------------------------------------------------*/ - -#ifndef GL_KHR_debug -#define GL_KHR_debug 1 -#ifdef GL_GLEXT_PROTOTYPES -GL_APICALL void GL_APIENTRY glDebugMessageControl (GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled); -GL_APICALL void GL_APIENTRY glDebugMessageInsert (GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *buf); -GL_APICALL void GL_APIENTRY glDebugMessageCallback (GLDEBUGPROC callback, const void *userParam); -GL_APICALL GLuint GL_APIENTRY glGetDebugMessageLog (GLuint count, GLsizei bufsize, GLenum *sources, GLenum *types, GLuint *ids, GLenum *severities, GLsizei *lengths, GLchar *messageLog); -GL_APICALL void GL_APIENTRY glPushDebugGroup (GLenum source, GLuint id, GLsizei length, const GLchar *message); -GL_APICALL void GL_APIENTRY glPopDebugGroup (void); -GL_APICALL void GL_APIENTRY glObjectLabel (GLenum identifier, GLuint name, GLsizei length, const GLchar *label); -GL_APICALL void GL_APIENTRY glGetObjectLabel (GLenum identifier, GLuint name, GLsizei bufSize, GLsizei *length, GLchar *label); -GL_APICALL void GL_APIENTRY glObjectPtrLabel (const void *ptr, GLsizei length, const GLchar *label); -GL_APICALL void GL_APIENTRY glGetObjectPtrLabel (const void *ptr, GLsizei bufSize, GLsizei *length, GLchar *label); -GL_APICALL void GL_APIENTRY glGetPointerv (GLenum pname, void **params); -#endif -typedef void (GL_APIENTRYP PFNGLDEBUGMESSAGECONTROLPROC) (GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled); -typedef void (GL_APIENTRYP PFNGLDEBUGMESSAGEINSERTPROC) (GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *buf); -typedef void (GL_APIENTRYP PFNGLDEBUGMESSAGECALLBACKPROC) (GLDEBUGPROC callback, const void *userParam); -typedef GLuint (GL_APIENTRYP PFNGLGETDEBUGMESSAGELOGPROC) (GLuint count, GLsizei bufsize, GLenum *sources, GLenum *types, GLuint *ids, GLenum *severities, GLsizei *lengths, GLchar *messageLog); -typedef void (GL_APIENTRYP PFNGLPUSHDEBUGGROUPPROC) (GLenum source, GLuint id, GLsizei length, const GLchar *message); -typedef void (GL_APIENTRYP PFNGLPOPDEBUGGROUPPROC) (void); -typedef void (GL_APIENTRYP PFNGLOBJECTLABELPROC) (GLenum identifier, GLuint name, GLsizei length, const GLchar *label); -typedef void (GL_APIENTRYP PFNGLGETOBJECTLABELPROC) (GLenum identifier, GLuint name, GLsizei bufSize, GLsizei *length, GLchar *label); -typedef void (GL_APIENTRYP PFNGLOBJECTPTRLABELPROC) (const void *ptr, GLsizei length, const GLchar *label); -typedef void (GL_APIENTRYP PFNGLGETOBJECTPTRLABELPROC) (const void *ptr, GLsizei bufSize, GLsizei *length, GLchar *label); -typedef void (GL_APIENTRYP PFNGLGETPOINTERVPROC) (GLenum pname, void **params); -#endif - -#ifndef GL_KHR_texture_compression_astc_ldr -#define GL_KHR_texture_compression_astc_ldr 1 -#endif - +#define GL_UNSIGNED_INT_10_10_10_2_OES 0x8DF6 +#define GL_INT_10_10_10_2_OES 0x8DF7 +#endif /* GL_OES_vertex_type_10_10_10_2 */ -/*------------------------------------------------------------------------* - * AMD extension functions - *------------------------------------------------------------------------*/ - -/* GL_AMD_compressed_3DC_texture */ #ifndef GL_AMD_compressed_3DC_texture #define GL_AMD_compressed_3DC_texture 1 -#endif +#define GL_3DC_X_AMD 0x87F9 +#define GL_3DC_XY_AMD 0x87FA +#endif /* GL_AMD_compressed_3DC_texture */ -/* GL_AMD_compressed_ATC_texture */ #ifndef GL_AMD_compressed_ATC_texture #define GL_AMD_compressed_ATC_texture 1 -#endif +#define GL_ATC_RGB_AMD 0x8C92 +#define GL_ATC_RGBA_EXPLICIT_ALPHA_AMD 0x8C93 +#define GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD 0x87EE +#endif /* GL_AMD_compressed_ATC_texture */ -/* AMD_performance_monitor */ #ifndef GL_AMD_performance_monitor #define GL_AMD_performance_monitor 1 +#define GL_COUNTER_TYPE_AMD 0x8BC0 +#define GL_COUNTER_RANGE_AMD 0x8BC1 +#define GL_UNSIGNED_INT64_AMD 0x8BC2 +#define GL_PERCENTAGE_AMD 0x8BC3 +#define GL_PERFMON_RESULT_AVAILABLE_AMD 0x8BC4 +#define GL_PERFMON_RESULT_SIZE_AMD 0x8BC5 +#define GL_PERFMON_RESULT_AMD 0x8BC6 +typedef void (GL_APIENTRYP PFNGLGETPERFMONITORGROUPSAMDPROC) (GLint *numGroups, GLsizei groupsSize, GLuint *groups); +typedef void (GL_APIENTRYP PFNGLGETPERFMONITORCOUNTERSAMDPROC) (GLuint group, GLint *numCounters, GLint *maxActiveCounters, GLsizei counterSize, GLuint *counters); +typedef void (GL_APIENTRYP PFNGLGETPERFMONITORGROUPSTRINGAMDPROC) (GLuint group, GLsizei bufSize, GLsizei *length, GLchar *groupString); +typedef void (GL_APIENTRYP PFNGLGETPERFMONITORCOUNTERSTRINGAMDPROC) (GLuint group, GLuint counter, GLsizei bufSize, GLsizei *length, GLchar *counterString); +typedef void (GL_APIENTRYP PFNGLGETPERFMONITORCOUNTERINFOAMDPROC) (GLuint group, GLuint counter, GLenum pname, void *data); +typedef void (GL_APIENTRYP PFNGLGENPERFMONITORSAMDPROC) (GLsizei n, GLuint *monitors); +typedef void (GL_APIENTRYP PFNGLDELETEPERFMONITORSAMDPROC) (GLsizei n, GLuint *monitors); +typedef void (GL_APIENTRYP PFNGLSELECTPERFMONITORCOUNTERSAMDPROC) (GLuint monitor, GLboolean enable, GLuint group, GLint numCounters, GLuint *counterList); +typedef void (GL_APIENTRYP PFNGLBEGINPERFMONITORAMDPROC) (GLuint monitor); +typedef void (GL_APIENTRYP PFNGLENDPERFMONITORAMDPROC) (GLuint monitor); +typedef void (GL_APIENTRYP PFNGLGETPERFMONITORCOUNTERDATAAMDPROC) (GLuint monitor, GLenum pname, GLsizei dataSize, GLuint *data, GLint *bytesWritten); #ifdef GL_GLEXT_PROTOTYPES GL_APICALL void GL_APIENTRY glGetPerfMonitorGroupsAMD (GLint *numGroups, GLsizei groupsSize, GLuint *groups); GL_APICALL void GL_APIENTRY glGetPerfMonitorCountersAMD (GLuint group, GLint *numCounters, GLint *maxActiveCounters, GLsizei counterSize, GLuint *counters); GL_APICALL void GL_APIENTRY glGetPerfMonitorGroupStringAMD (GLuint group, GLsizei bufSize, GLsizei *length, GLchar *groupString); GL_APICALL void GL_APIENTRY glGetPerfMonitorCounterStringAMD (GLuint group, GLuint counter, GLsizei bufSize, GLsizei *length, GLchar *counterString); -GL_APICALL void GL_APIENTRY glGetPerfMonitorCounterInfoAMD (GLuint group, GLuint counter, GLenum pname, GLvoid *data); +GL_APICALL void GL_APIENTRY glGetPerfMonitorCounterInfoAMD (GLuint group, GLuint counter, GLenum pname, void *data); GL_APICALL void GL_APIENTRY glGenPerfMonitorsAMD (GLsizei n, GLuint *monitors); GL_APICALL void GL_APIENTRY glDeletePerfMonitorsAMD (GLsizei n, GLuint *monitors); -GL_APICALL void GL_APIENTRY glSelectPerfMonitorCountersAMD (GLuint monitor, GLboolean enable, GLuint group, GLint numCounters, GLuint *countersList); +GL_APICALL void GL_APIENTRY glSelectPerfMonitorCountersAMD (GLuint monitor, GLboolean enable, GLuint group, GLint numCounters, GLuint *counterList); GL_APICALL void GL_APIENTRY glBeginPerfMonitorAMD (GLuint monitor); GL_APICALL void GL_APIENTRY glEndPerfMonitorAMD (GLuint monitor); GL_APICALL void GL_APIENTRY glGetPerfMonitorCounterDataAMD (GLuint monitor, GLenum pname, GLsizei dataSize, GLuint *data, GLint *bytesWritten); #endif -typedef void (GL_APIENTRYP PFNGLGETPERFMONITORGROUPSAMDPROC) (GLint *numGroups, GLsizei groupsSize, GLuint *groups); -typedef void (GL_APIENTRYP PFNGLGETPERFMONITORCOUNTERSAMDPROC) (GLuint group, GLint *numCounters, GLint *maxActiveCounters, GLsizei counterSize, GLuint *counters); -typedef void (GL_APIENTRYP PFNGLGETPERFMONITORGROUPSTRINGAMDPROC) (GLuint group, GLsizei bufSize, GLsizei *length, GLchar *groupString); -typedef void (GL_APIENTRYP PFNGLGETPERFMONITORCOUNTERSTRINGAMDPROC) (GLuint group, GLuint counter, GLsizei bufSize, GLsizei *length, GLchar *counterString); -typedef void (GL_APIENTRYP PFNGLGETPERFMONITORCOUNTERINFOAMDPROC) (GLuint group, GLuint counter, GLenum pname, GLvoid *data); -typedef void (GL_APIENTRYP PFNGLGENPERFMONITORSAMDPROC) (GLsizei n, GLuint *monitors); -typedef void (GL_APIENTRYP PFNGLDELETEPERFMONITORSAMDPROC) (GLsizei n, GLuint *monitors); -typedef void (GL_APIENTRYP PFNGLSELECTPERFMONITORCOUNTERSAMDPROC) (GLuint monitor, GLboolean enable, GLuint group, GLint numCounters, GLuint *countersList); -typedef void (GL_APIENTRYP PFNGLBEGINPERFMONITORAMDPROC) (GLuint monitor); -typedef void (GL_APIENTRYP PFNGLENDPERFMONITORAMDPROC) (GLuint monitor); -typedef void (GL_APIENTRYP PFNGLGETPERFMONITORCOUNTERDATAAMDPROC) (GLuint monitor, GLenum pname, GLsizei dataSize, GLuint *data, GLint *bytesWritten); -#endif +#endif /* GL_AMD_performance_monitor */ -/* GL_AMD_program_binary_Z400 */ #ifndef GL_AMD_program_binary_Z400 #define GL_AMD_program_binary_Z400 1 -#endif +#define GL_Z400_BINARY_AMD 0x8740 +#endif /* GL_AMD_program_binary_Z400 */ -/*------------------------------------------------------------------------* - * ANGLE extension functions - *------------------------------------------------------------------------*/ +#ifndef GL_ANDROID_extension_pack_es31a +#define GL_ANDROID_extension_pack_es31a 1 +#endif /* GL_ANDROID_extension_pack_es31a */ -/* GL_ANGLE_depth_texture */ #ifndef GL_ANGLE_depth_texture #define GL_ANGLE_depth_texture 1 -#endif +#endif /* GL_ANGLE_depth_texture */ -/* GL_ANGLE_framebuffer_blit */ #ifndef GL_ANGLE_framebuffer_blit #define GL_ANGLE_framebuffer_blit 1 +#define GL_READ_FRAMEBUFFER_ANGLE 0x8CA8 +#define GL_DRAW_FRAMEBUFFER_ANGLE 0x8CA9 +#define GL_DRAW_FRAMEBUFFER_BINDING_ANGLE 0x8CA6 +#define GL_READ_FRAMEBUFFER_BINDING_ANGLE 0x8CAA +typedef void (GL_APIENTRYP PFNGLBLITFRAMEBUFFERANGLEPROC) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); #ifdef GL_GLEXT_PROTOTYPES GL_APICALL void GL_APIENTRY glBlitFramebufferANGLE (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); #endif -typedef void (GL_APIENTRYP PFNGLBLITFRAMEBUFFERANGLEPROC) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); -#endif +#endif /* GL_ANGLE_framebuffer_blit */ -/* GL_ANGLE_framebuffer_multisample */ #ifndef GL_ANGLE_framebuffer_multisample #define GL_ANGLE_framebuffer_multisample 1 +#define GL_RENDERBUFFER_SAMPLES_ANGLE 0x8CAB +#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_ANGLE 0x8D56 +#define GL_MAX_SAMPLES_ANGLE 0x8D57 +typedef void (GL_APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEANGLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); #ifdef GL_GLEXT_PROTOTYPES GL_APICALL void GL_APIENTRY glRenderbufferStorageMultisampleANGLE (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); #endif -typedef void (GL_APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEANGLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); -#endif +#endif /* GL_ANGLE_framebuffer_multisample */ -#ifndef GL_ANGLE_instanced_arrays +#ifndef GL_ANGLE_instanced_arrays #define GL_ANGLE_instanced_arrays 1 +#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE 0x88FE +typedef void (GL_APIENTRYP PFNGLDRAWARRAYSINSTANCEDANGLEPROC) (GLenum mode, GLint first, GLsizei count, GLsizei primcount); +typedef void (GL_APIENTRYP PFNGLDRAWELEMENTSINSTANCEDANGLEPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount); +typedef void (GL_APIENTRYP PFNGLVERTEXATTRIBDIVISORANGLEPROC) (GLuint index, GLuint divisor); #ifdef GL_GLEXT_PROTOTYPES GL_APICALL void GL_APIENTRY glDrawArraysInstancedANGLE (GLenum mode, GLint first, GLsizei count, GLsizei primcount); GL_APICALL void GL_APIENTRY glDrawElementsInstancedANGLE (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount); GL_APICALL void GL_APIENTRY glVertexAttribDivisorANGLE (GLuint index, GLuint divisor); #endif -typedef void (GL_APIENTRYP PFNGLDRAWARRAYSINSTANCEDANGLEPROC) (GLenum mode, GLint first, GLsizei count, GLsizei primcount); -typedef void (GL_APIENTRYP PFNGLDRAWELEMENTSINSTANCEDANGLEPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount); -typedef void (GL_APIENTRYP PFNGLVERTEXATTRIBDIVISORANGLEPROC) (GLuint index, GLuint divisor); -#endif +#endif /* GL_ANGLE_instanced_arrays */ -/* GL_ANGLE_pack_reverse_row_order */ -#ifndef GL_ANGLE_pack_reverse_row_order +#ifndef GL_ANGLE_pack_reverse_row_order #define GL_ANGLE_pack_reverse_row_order 1 -#endif +#define GL_PACK_REVERSE_ROW_ORDER_ANGLE 0x93A4 +#endif /* GL_ANGLE_pack_reverse_row_order */ -/* GL_ANGLE_program_binary */ #ifndef GL_ANGLE_program_binary #define GL_ANGLE_program_binary 1 -#endif +#define GL_PROGRAM_BINARY_ANGLE 0x93A6 +#endif /* GL_ANGLE_program_binary */ -/* GL_ANGLE_texture_compression_dxt3 */ -#ifndef GL_ANGLE_texture_compression_dxt3 +#ifndef GL_ANGLE_texture_compression_dxt3 #define GL_ANGLE_texture_compression_dxt3 1 -#endif +#define GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE 0x83F2 +#endif /* GL_ANGLE_texture_compression_dxt3 */ -/* GL_ANGLE_texture_compression_dxt5 */ -#ifndef GL_ANGLE_texture_compression_dxt5 +#ifndef GL_ANGLE_texture_compression_dxt5 #define GL_ANGLE_texture_compression_dxt5 1 -#endif +#define GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE 0x83F3 +#endif /* GL_ANGLE_texture_compression_dxt5 */ -/* GL_ANGLE_texture_usage */ -#ifndef GL_ANGLE_texture_usage +#ifndef GL_ANGLE_texture_usage #define GL_ANGLE_texture_usage 1 -#endif +#define GL_TEXTURE_USAGE_ANGLE 0x93A2 +#define GL_FRAMEBUFFER_ATTACHMENT_ANGLE 0x93A3 +#endif /* GL_ANGLE_texture_usage */ -#ifndef GL_ANGLE_translated_shader_source +#ifndef GL_ANGLE_translated_shader_source #define GL_ANGLE_translated_shader_source 1 +#define GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE 0x93A0 +typedef void (GL_APIENTRYP PFNGLGETTRANSLATEDSHADERSOURCEANGLEPROC) (GLuint shader, GLsizei bufsize, GLsizei *length, GLchar *source); #ifdef GL_GLEXT_PROTOTYPES GL_APICALL void GL_APIENTRY glGetTranslatedShaderSourceANGLE (GLuint shader, GLsizei bufsize, GLsizei *length, GLchar *source); #endif -typedef void (GL_APIENTRYP PFNGLGETTRANSLATEDSHADERSOURCEANGLEPROC) (GLuint shader, GLsizei bufsize, GLsizei *length, GLchar *source); -#endif - -/*------------------------------------------------------------------------* - * APPLE extension functions - *------------------------------------------------------------------------*/ +#endif /* GL_ANGLE_translated_shader_source */ + +#ifndef GL_APPLE_clip_distance +#define GL_APPLE_clip_distance 1 +#define GL_MAX_CLIP_DISTANCES_APPLE 0x0D32 +#define GL_CLIP_DISTANCE0_APPLE 0x3000 +#define GL_CLIP_DISTANCE1_APPLE 0x3001 +#define GL_CLIP_DISTANCE2_APPLE 0x3002 +#define GL_CLIP_DISTANCE3_APPLE 0x3003 +#define GL_CLIP_DISTANCE4_APPLE 0x3004 +#define GL_CLIP_DISTANCE5_APPLE 0x3005 +#define GL_CLIP_DISTANCE6_APPLE 0x3006 +#define GL_CLIP_DISTANCE7_APPLE 0x3007 +#endif /* GL_APPLE_clip_distance */ + +#ifndef GL_APPLE_color_buffer_packed_float +#define GL_APPLE_color_buffer_packed_float 1 +#endif /* GL_APPLE_color_buffer_packed_float */ -/* GL_APPLE_copy_texture_levels */ #ifndef GL_APPLE_copy_texture_levels #define GL_APPLE_copy_texture_levels 1 +typedef void (GL_APIENTRYP PFNGLCOPYTEXTURELEVELSAPPLEPROC) (GLuint destinationTexture, GLuint sourceTexture, GLint sourceBaseLevel, GLsizei sourceLevelCount); #ifdef GL_GLEXT_PROTOTYPES GL_APICALL void GL_APIENTRY glCopyTextureLevelsAPPLE (GLuint destinationTexture, GLuint sourceTexture, GLint sourceBaseLevel, GLsizei sourceLevelCount); #endif -typedef void (GL_APIENTRYP PFNGLCOPYTEXTURELEVELSAPPLEPROC) (GLuint destinationTexture, GLuint sourceTexture, GLint sourceBaseLevel, GLsizei sourceLevelCount); -#endif +#endif /* GL_APPLE_copy_texture_levels */ -/* GL_APPLE_framebuffer_multisample */ #ifndef GL_APPLE_framebuffer_multisample #define GL_APPLE_framebuffer_multisample 1 -#ifdef GL_GLEXT_PROTOTYPES -GL_APICALL void GL_APIENTRY glRenderbufferStorageMultisampleAPPLE (GLenum, GLsizei, GLenum, GLsizei, GLsizei); -GL_APICALL void GL_APIENTRY glResolveMultisampleFramebufferAPPLE (void); -#endif /* GL_GLEXT_PROTOTYPES */ +#define GL_RENDERBUFFER_SAMPLES_APPLE 0x8CAB +#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_APPLE 0x8D56 +#define GL_MAX_SAMPLES_APPLE 0x8D57 +#define GL_READ_FRAMEBUFFER_APPLE 0x8CA8 +#define GL_DRAW_FRAMEBUFFER_APPLE 0x8CA9 +#define GL_DRAW_FRAMEBUFFER_BINDING_APPLE 0x8CA6 +#define GL_READ_FRAMEBUFFER_BINDING_APPLE 0x8CAA typedef void (GL_APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEAPPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); typedef void (GL_APIENTRYP PFNGLRESOLVEMULTISAMPLEFRAMEBUFFERAPPLEPROC) (void); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glRenderbufferStorageMultisampleAPPLE (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +GL_APICALL void GL_APIENTRY glResolveMultisampleFramebufferAPPLE (void); #endif +#endif /* GL_APPLE_framebuffer_multisample */ -/* GL_APPLE_rgb_422 */ #ifndef GL_APPLE_rgb_422 #define GL_APPLE_rgb_422 1 -#endif +#define GL_RGB_422_APPLE 0x8A1F +#define GL_UNSIGNED_SHORT_8_8_APPLE 0x85BA +#define GL_UNSIGNED_SHORT_8_8_REV_APPLE 0x85BB +#define GL_RGB_RAW_422_APPLE 0x8A51 +#endif /* GL_APPLE_rgb_422 */ -/* GL_APPLE_sync */ #ifndef GL_APPLE_sync #define GL_APPLE_sync 1 +#define GL_SYNC_OBJECT_APPLE 0x8A53 +#define GL_MAX_SERVER_WAIT_TIMEOUT_APPLE 0x9111 +#define GL_OBJECT_TYPE_APPLE 0x9112 +#define GL_SYNC_CONDITION_APPLE 0x9113 +#define GL_SYNC_STATUS_APPLE 0x9114 +#define GL_SYNC_FLAGS_APPLE 0x9115 +#define GL_SYNC_FENCE_APPLE 0x9116 +#define GL_SYNC_GPU_COMMANDS_COMPLETE_APPLE 0x9117 +#define GL_UNSIGNALED_APPLE 0x9118 +#define GL_SIGNALED_APPLE 0x9119 +#define GL_ALREADY_SIGNALED_APPLE 0x911A +#define GL_TIMEOUT_EXPIRED_APPLE 0x911B +#define GL_CONDITION_SATISFIED_APPLE 0x911C +#define GL_WAIT_FAILED_APPLE 0x911D +#define GL_SYNC_FLUSH_COMMANDS_BIT_APPLE 0x00000001 +#define GL_TIMEOUT_IGNORED_APPLE 0xFFFFFFFFFFFFFFFFull +typedef GLsync (GL_APIENTRYP PFNGLFENCESYNCAPPLEPROC) (GLenum condition, GLbitfield flags); +typedef GLboolean (GL_APIENTRYP PFNGLISSYNCAPPLEPROC) (GLsync sync); +typedef void (GL_APIENTRYP PFNGLDELETESYNCAPPLEPROC) (GLsync sync); +typedef GLenum (GL_APIENTRYP PFNGLCLIENTWAITSYNCAPPLEPROC) (GLsync sync, GLbitfield flags, GLuint64 timeout); +typedef void (GL_APIENTRYP PFNGLWAITSYNCAPPLEPROC) (GLsync sync, GLbitfield flags, GLuint64 timeout); +typedef void (GL_APIENTRYP PFNGLGETINTEGER64VAPPLEPROC) (GLenum pname, GLint64 *params); +typedef void (GL_APIENTRYP PFNGLGETSYNCIVAPPLEPROC) (GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values); #ifdef GL_GLEXT_PROTOTYPES GL_APICALL GLsync GL_APIENTRY glFenceSyncAPPLE (GLenum condition, GLbitfield flags); GL_APICALL GLboolean GL_APIENTRY glIsSyncAPPLE (GLsync sync); @@ -1374,287 +964,892 @@ GL_APICALL void GL_APIENTRY glWaitSyncAPPLE (GLsync sync, GLbitfield flags, GLui GL_APICALL void GL_APIENTRY glGetInteger64vAPPLE (GLenum pname, GLint64 *params); GL_APICALL void GL_APIENTRY glGetSyncivAPPLE (GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values); #endif -typedef GLsync (GL_APIENTRYP PFNGLFENCESYNCAPPLEPROC) (GLenum condition, GLbitfield flags); -typedef GLboolean (GL_APIENTRYP PFNGLISSYNCAPPLEPROC) (GLsync sync); -typedef void (GL_APIENTRYP PFNGLDELETESYNCAPPLEPROC) (GLsync sync); -typedef GLenum (GL_APIENTRYP PFNGLCLIENTWAITSYNCAPPLEPROC) (GLsync sync, GLbitfield flags, GLuint64 timeout); -typedef void (GL_APIENTRYP PFNGLWAITSYNCAPPLEPROC) (GLsync sync, GLbitfield flags, GLuint64 timeout); -typedef void (GL_APIENTRYP PFNGLGETINTEGER64VAPPLEPROC) (GLenum pname, GLint64 *params); -typedef void (GL_APIENTRYP PFNGLGETSYNCIVAPPLEPROC) (GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values); -#endif +#endif /* GL_APPLE_sync */ -/* GL_APPLE_texture_format_BGRA8888 */ #ifndef GL_APPLE_texture_format_BGRA8888 #define GL_APPLE_texture_format_BGRA8888 1 -#endif +#define GL_BGRA_EXT 0x80E1 +#define GL_BGRA8_EXT 0x93A1 +#endif /* GL_APPLE_texture_format_BGRA8888 */ -/* GL_APPLE_texture_max_level */ #ifndef GL_APPLE_texture_max_level #define GL_APPLE_texture_max_level 1 -#endif +#define GL_TEXTURE_MAX_LEVEL_APPLE 0x813D +#endif /* GL_APPLE_texture_max_level */ -/*------------------------------------------------------------------------* - * ARM extension functions - *------------------------------------------------------------------------*/ +#ifndef GL_APPLE_texture_packed_float +#define GL_APPLE_texture_packed_float 1 +#define GL_UNSIGNED_INT_10F_11F_11F_REV_APPLE 0x8C3B +#define GL_UNSIGNED_INT_5_9_9_9_REV_APPLE 0x8C3E +#define GL_R11F_G11F_B10F_APPLE 0x8C3A +#define GL_RGB9_E5_APPLE 0x8C3D +#endif /* GL_APPLE_texture_packed_float */ -/* GL_ARM_mali_program_binary */ #ifndef GL_ARM_mali_program_binary #define GL_ARM_mali_program_binary 1 -#endif +#define GL_MALI_PROGRAM_BINARY_ARM 0x8F61 +#endif /* GL_ARM_mali_program_binary */ -/* GL_ARM_mali_shader_binary */ #ifndef GL_ARM_mali_shader_binary #define GL_ARM_mali_shader_binary 1 -#endif +#define GL_MALI_SHADER_BINARY_ARM 0x8F60 +#endif /* GL_ARM_mali_shader_binary */ -/* GL_ARM_rgba8 */ #ifndef GL_ARM_rgba8 #define GL_ARM_rgba8 1 -#endif +#endif /* GL_ARM_rgba8 */ -/*------------------------------------------------------------------------* - * EXT extension functions - *------------------------------------------------------------------------*/ +#ifndef GL_ARM_shader_framebuffer_fetch +#define GL_ARM_shader_framebuffer_fetch 1 +#define GL_FETCH_PER_SAMPLE_ARM 0x8F65 +#define GL_FRAGMENT_SHADER_FRAMEBUFFER_FETCH_MRT_ARM 0x8F66 +#endif /* GL_ARM_shader_framebuffer_fetch */ + +#ifndef GL_ARM_shader_framebuffer_fetch_depth_stencil +#define GL_ARM_shader_framebuffer_fetch_depth_stencil 1 +#endif /* GL_ARM_shader_framebuffer_fetch_depth_stencil */ + +#ifndef GL_DMP_program_binary +#define GL_DMP_program_binary 1 +#define GL_SMAPHS30_PROGRAM_BINARY_DMP 0x9251 +#define GL_SMAPHS_PROGRAM_BINARY_DMP 0x9252 +#define GL_DMP_PROGRAM_BINARY_DMP 0x9253 +#endif /* GL_DMP_program_binary */ + +#ifndef GL_DMP_shader_binary +#define GL_DMP_shader_binary 1 +#define GL_SHADER_BINARY_DMP 0x9250 +#endif /* GL_DMP_shader_binary */ + +#ifndef GL_EXT_YUV_target +#define GL_EXT_YUV_target 1 +#define GL_SAMPLER_EXTERNAL_2D_Y2Y_EXT 0x8BE7 +#endif /* GL_EXT_YUV_target */ + +#ifndef GL_EXT_base_instance +#define GL_EXT_base_instance 1 +typedef void (GL_APIENTRYP PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEEXTPROC) (GLenum mode, GLint first, GLsizei count, GLsizei instancecount, GLuint baseinstance); +typedef void (GL_APIENTRYP PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEEXTPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLuint baseinstance); +typedef void (GL_APIENTRYP PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEEXTPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLint basevertex, GLuint baseinstance); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glDrawArraysInstancedBaseInstanceEXT (GLenum mode, GLint first, GLsizei count, GLsizei instancecount, GLuint baseinstance); +GL_APICALL void GL_APIENTRY glDrawElementsInstancedBaseInstanceEXT (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLuint baseinstance); +GL_APICALL void GL_APIENTRY glDrawElementsInstancedBaseVertexBaseInstanceEXT (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLint basevertex, GLuint baseinstance); +#endif +#endif /* GL_EXT_base_instance */ + +#ifndef GL_EXT_blend_func_extended +#define GL_EXT_blend_func_extended 1 +#define GL_SRC1_COLOR_EXT 0x88F9 +#define GL_SRC1_ALPHA_EXT 0x8589 +#define GL_ONE_MINUS_SRC1_COLOR_EXT 0x88FA +#define GL_ONE_MINUS_SRC1_ALPHA_EXT 0x88FB +#define GL_SRC_ALPHA_SATURATE_EXT 0x0308 +#define GL_LOCATION_INDEX_EXT 0x930F +#define GL_MAX_DUAL_SOURCE_DRAW_BUFFERS_EXT 0x88FC +typedef void (GL_APIENTRYP PFNGLBINDFRAGDATALOCATIONINDEXEDEXTPROC) (GLuint program, GLuint colorNumber, GLuint index, const GLchar *name); +typedef void (GL_APIENTRYP PFNGLBINDFRAGDATALOCATIONEXTPROC) (GLuint program, GLuint color, const GLchar *name); +typedef GLint (GL_APIENTRYP PFNGLGETPROGRAMRESOURCELOCATIONINDEXEXTPROC) (GLuint program, GLenum programInterface, const GLchar *name); +typedef GLint (GL_APIENTRYP PFNGLGETFRAGDATAINDEXEXTPROC) (GLuint program, const GLchar *name); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glBindFragDataLocationIndexedEXT (GLuint program, GLuint colorNumber, GLuint index, const GLchar *name); +GL_APICALL void GL_APIENTRY glBindFragDataLocationEXT (GLuint program, GLuint color, const GLchar *name); +GL_APICALL GLint GL_APIENTRY glGetProgramResourceLocationIndexEXT (GLuint program, GLenum programInterface, const GLchar *name); +GL_APICALL GLint GL_APIENTRY glGetFragDataIndexEXT (GLuint program, const GLchar *name); +#endif +#endif /* GL_EXT_blend_func_extended */ -/* GL_EXT_blend_minmax */ #ifndef GL_EXT_blend_minmax #define GL_EXT_blend_minmax 1 +#define GL_MIN_EXT 0x8007 +#define GL_MAX_EXT 0x8008 +#endif /* GL_EXT_blend_minmax */ + +#ifndef GL_EXT_buffer_storage +#define GL_EXT_buffer_storage 1 +#define GL_MAP_READ_BIT 0x0001 +#define GL_MAP_WRITE_BIT 0x0002 +#define GL_MAP_PERSISTENT_BIT_EXT 0x0040 +#define GL_MAP_COHERENT_BIT_EXT 0x0080 +#define GL_DYNAMIC_STORAGE_BIT_EXT 0x0100 +#define GL_CLIENT_STORAGE_BIT_EXT 0x0200 +#define GL_CLIENT_MAPPED_BUFFER_BARRIER_BIT_EXT 0x00004000 +#define GL_BUFFER_IMMUTABLE_STORAGE_EXT 0x821F +#define GL_BUFFER_STORAGE_FLAGS_EXT 0x8220 +typedef void (GL_APIENTRYP PFNGLBUFFERSTORAGEEXTPROC) (GLenum target, GLsizeiptr size, const void *data, GLbitfield flags); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glBufferStorageEXT (GLenum target, GLsizeiptr size, const void *data, GLbitfield flags); #endif +#endif /* GL_EXT_buffer_storage */ + +#ifndef GL_EXT_color_buffer_float +#define GL_EXT_color_buffer_float 1 +#endif /* GL_EXT_color_buffer_float */ -/* GL_EXT_color_buffer_half_float */ #ifndef GL_EXT_color_buffer_half_float #define GL_EXT_color_buffer_half_float 1 +#define GL_RGBA16F_EXT 0x881A +#define GL_RGB16F_EXT 0x881B +#define GL_RG16F_EXT 0x822F +#define GL_R16F_EXT 0x822D +#define GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE_EXT 0x8211 +#define GL_UNSIGNED_NORMALIZED_EXT 0x8C17 +#endif /* GL_EXT_color_buffer_half_float */ + +#ifndef GL_EXT_copy_image +#define GL_EXT_copy_image 1 +typedef void (GL_APIENTRYP PFNGLCOPYIMAGESUBDATAEXTPROC) (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); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glCopyImageSubDataEXT (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); #endif +#endif /* GL_EXT_copy_image */ -/* GL_EXT_debug_label */ #ifndef GL_EXT_debug_label #define GL_EXT_debug_label 1 +#define GL_PROGRAM_PIPELINE_OBJECT_EXT 0x8A4F +#define GL_PROGRAM_OBJECT_EXT 0x8B40 +#define GL_SHADER_OBJECT_EXT 0x8B48 +#define GL_BUFFER_OBJECT_EXT 0x9151 +#define GL_QUERY_OBJECT_EXT 0x9153 +#define GL_VERTEX_ARRAY_OBJECT_EXT 0x9154 +#define GL_TRANSFORM_FEEDBACK 0x8E22 +typedef void (GL_APIENTRYP PFNGLLABELOBJECTEXTPROC) (GLenum type, GLuint object, GLsizei length, const GLchar *label); +typedef void (GL_APIENTRYP PFNGLGETOBJECTLABELEXTPROC) (GLenum type, GLuint object, GLsizei bufSize, GLsizei *length, GLchar *label); #ifdef GL_GLEXT_PROTOTYPES GL_APICALL void GL_APIENTRY glLabelObjectEXT (GLenum type, GLuint object, GLsizei length, const GLchar *label); GL_APICALL void GL_APIENTRY glGetObjectLabelEXT (GLenum type, GLuint object, GLsizei bufSize, GLsizei *length, GLchar *label); #endif -typedef void (GL_APIENTRYP PFNGLLABELOBJECTEXTPROC) (GLenum type, GLuint object, GLsizei length, const GLchar *label); -typedef void (GL_APIENTRYP PFNGLGETOBJECTLABELEXTPROC) (GLenum type, GLuint object, GLsizei bufSize, GLsizei *length, GLchar *label); -#endif +#endif /* GL_EXT_debug_label */ -/* GL_EXT_debug_marker */ #ifndef GL_EXT_debug_marker #define GL_EXT_debug_marker 1 +typedef void (GL_APIENTRYP PFNGLINSERTEVENTMARKEREXTPROC) (GLsizei length, const GLchar *marker); +typedef void (GL_APIENTRYP PFNGLPUSHGROUPMARKEREXTPROC) (GLsizei length, const GLchar *marker); +typedef void (GL_APIENTRYP PFNGLPOPGROUPMARKEREXTPROC) (void); #ifdef GL_GLEXT_PROTOTYPES GL_APICALL void GL_APIENTRY glInsertEventMarkerEXT (GLsizei length, const GLchar *marker); GL_APICALL void GL_APIENTRY glPushGroupMarkerEXT (GLsizei length, const GLchar *marker); GL_APICALL void GL_APIENTRY glPopGroupMarkerEXT (void); #endif -typedef void (GL_APIENTRYP PFNGLINSERTEVENTMARKEREXTPROC) (GLsizei length, const GLchar *marker); -typedef void (GL_APIENTRYP PFNGLPUSHGROUPMARKEREXTPROC) (GLsizei length, const GLchar *marker); -typedef void (GL_APIENTRYP PFNGLPOPGROUPMARKEREXTPROC) (void); -#endif +#endif /* GL_EXT_debug_marker */ -/* GL_EXT_discard_framebuffer */ #ifndef GL_EXT_discard_framebuffer #define GL_EXT_discard_framebuffer 1 +#define GL_COLOR_EXT 0x1800 +#define GL_DEPTH_EXT 0x1801 +#define GL_STENCIL_EXT 0x1802 +typedef void (GL_APIENTRYP PFNGLDISCARDFRAMEBUFFEREXTPROC) (GLenum target, GLsizei numAttachments, const GLenum *attachments); #ifdef GL_GLEXT_PROTOTYPES GL_APICALL void GL_APIENTRY glDiscardFramebufferEXT (GLenum target, GLsizei numAttachments, const GLenum *attachments); #endif -typedef void (GL_APIENTRYP PFNGLDISCARDFRAMEBUFFEREXTPROC) (GLenum target, GLsizei numAttachments, const GLenum *attachments); +#endif /* GL_EXT_discard_framebuffer */ + +#ifndef GL_EXT_disjoint_timer_query +#define GL_EXT_disjoint_timer_query 1 +#define GL_QUERY_COUNTER_BITS_EXT 0x8864 +#define GL_CURRENT_QUERY_EXT 0x8865 +#define GL_QUERY_RESULT_EXT 0x8866 +#define GL_QUERY_RESULT_AVAILABLE_EXT 0x8867 +#define GL_TIME_ELAPSED_EXT 0x88BF +#define GL_TIMESTAMP_EXT 0x8E28 +#define GL_GPU_DISJOINT_EXT 0x8FBB +typedef void (GL_APIENTRYP PFNGLGENQUERIESEXTPROC) (GLsizei n, GLuint *ids); +typedef void (GL_APIENTRYP PFNGLDELETEQUERIESEXTPROC) (GLsizei n, const GLuint *ids); +typedef GLboolean (GL_APIENTRYP PFNGLISQUERYEXTPROC) (GLuint id); +typedef void (GL_APIENTRYP PFNGLBEGINQUERYEXTPROC) (GLenum target, GLuint id); +typedef void (GL_APIENTRYP PFNGLENDQUERYEXTPROC) (GLenum target); +typedef void (GL_APIENTRYP PFNGLQUERYCOUNTEREXTPROC) (GLuint id, GLenum target); +typedef void (GL_APIENTRYP PFNGLGETQUERYIVEXTPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (GL_APIENTRYP PFNGLGETQUERYOBJECTIVEXTPROC) (GLuint id, GLenum pname, GLint *params); +typedef void (GL_APIENTRYP PFNGLGETQUERYOBJECTUIVEXTPROC) (GLuint id, GLenum pname, GLuint *params); +typedef void (GL_APIENTRYP PFNGLGETQUERYOBJECTI64VEXTPROC) (GLuint id, GLenum pname, GLint64 *params); +typedef void (GL_APIENTRYP PFNGLGETQUERYOBJECTUI64VEXTPROC) (GLuint id, GLenum pname, GLuint64 *params); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glGenQueriesEXT (GLsizei n, GLuint *ids); +GL_APICALL void GL_APIENTRY glDeleteQueriesEXT (GLsizei n, const GLuint *ids); +GL_APICALL GLboolean GL_APIENTRY glIsQueryEXT (GLuint id); +GL_APICALL void GL_APIENTRY glBeginQueryEXT (GLenum target, GLuint id); +GL_APICALL void GL_APIENTRY glEndQueryEXT (GLenum target); +GL_APICALL void GL_APIENTRY glQueryCounterEXT (GLuint id, GLenum target); +GL_APICALL void GL_APIENTRY glGetQueryivEXT (GLenum target, GLenum pname, GLint *params); +GL_APICALL void GL_APIENTRY glGetQueryObjectivEXT (GLuint id, GLenum pname, GLint *params); +GL_APICALL void GL_APIENTRY glGetQueryObjectuivEXT (GLuint id, GLenum pname, GLuint *params); +GL_APICALL void GL_APIENTRY glGetQueryObjecti64vEXT (GLuint id, GLenum pname, GLint64 *params); +GL_APICALL void GL_APIENTRY glGetQueryObjectui64vEXT (GLuint id, GLenum pname, GLuint64 *params); #endif +#endif /* GL_EXT_disjoint_timer_query */ -/* GL_EXT_map_buffer_range */ -#ifndef GL_EXT_map_buffer_range -#define GL_EXT_map_buffer_range 1 +#ifndef GL_EXT_draw_buffers +#define GL_EXT_draw_buffers 1 +#define GL_MAX_COLOR_ATTACHMENTS_EXT 0x8CDF +#define GL_MAX_DRAW_BUFFERS_EXT 0x8824 +#define GL_DRAW_BUFFER0_EXT 0x8825 +#define GL_DRAW_BUFFER1_EXT 0x8826 +#define GL_DRAW_BUFFER2_EXT 0x8827 +#define GL_DRAW_BUFFER3_EXT 0x8828 +#define GL_DRAW_BUFFER4_EXT 0x8829 +#define GL_DRAW_BUFFER5_EXT 0x882A +#define GL_DRAW_BUFFER6_EXT 0x882B +#define GL_DRAW_BUFFER7_EXT 0x882C +#define GL_DRAW_BUFFER8_EXT 0x882D +#define GL_DRAW_BUFFER9_EXT 0x882E +#define GL_DRAW_BUFFER10_EXT 0x882F +#define GL_DRAW_BUFFER11_EXT 0x8830 +#define GL_DRAW_BUFFER12_EXT 0x8831 +#define GL_DRAW_BUFFER13_EXT 0x8832 +#define GL_DRAW_BUFFER14_EXT 0x8833 +#define GL_DRAW_BUFFER15_EXT 0x8834 +#define GL_COLOR_ATTACHMENT0_EXT 0x8CE0 +#define GL_COLOR_ATTACHMENT1_EXT 0x8CE1 +#define GL_COLOR_ATTACHMENT2_EXT 0x8CE2 +#define GL_COLOR_ATTACHMENT3_EXT 0x8CE3 +#define GL_COLOR_ATTACHMENT4_EXT 0x8CE4 +#define GL_COLOR_ATTACHMENT5_EXT 0x8CE5 +#define GL_COLOR_ATTACHMENT6_EXT 0x8CE6 +#define GL_COLOR_ATTACHMENT7_EXT 0x8CE7 +#define GL_COLOR_ATTACHMENT8_EXT 0x8CE8 +#define GL_COLOR_ATTACHMENT9_EXT 0x8CE9 +#define GL_COLOR_ATTACHMENT10_EXT 0x8CEA +#define GL_COLOR_ATTACHMENT11_EXT 0x8CEB +#define GL_COLOR_ATTACHMENT12_EXT 0x8CEC +#define GL_COLOR_ATTACHMENT13_EXT 0x8CED +#define GL_COLOR_ATTACHMENT14_EXT 0x8CEE +#define GL_COLOR_ATTACHMENT15_EXT 0x8CEF +typedef void (GL_APIENTRYP PFNGLDRAWBUFFERSEXTPROC) (GLsizei n, const GLenum *bufs); #ifdef GL_GLEXT_PROTOTYPES -GL_APICALL void* GL_APIENTRY glMapBufferRangeEXT (GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access); -GL_APICALL void GL_APIENTRY glFlushMappedBufferRangeEXT (GLenum target, GLintptr offset, GLsizeiptr length); +GL_APICALL void GL_APIENTRY glDrawBuffersEXT (GLsizei n, const GLenum *bufs); #endif -typedef void* (GL_APIENTRYP PFNGLMAPBUFFERRANGEEXTPROC) (GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access); -typedef void (GL_APIENTRYP PFNGLFLUSHMAPPEDBUFFERRANGEEXTPROC) (GLenum target, GLintptr offset, GLsizeiptr length); +#endif /* GL_EXT_draw_buffers */ + +#ifndef GL_EXT_draw_buffers_indexed +#define GL_EXT_draw_buffers_indexed 1 +typedef void (GL_APIENTRYP PFNGLENABLEIEXTPROC) (GLenum target, GLuint index); +typedef void (GL_APIENTRYP PFNGLDISABLEIEXTPROC) (GLenum target, GLuint index); +typedef void (GL_APIENTRYP PFNGLBLENDEQUATIONIEXTPROC) (GLuint buf, GLenum mode); +typedef void (GL_APIENTRYP PFNGLBLENDEQUATIONSEPARATEIEXTPROC) (GLuint buf, GLenum modeRGB, GLenum modeAlpha); +typedef void (GL_APIENTRYP PFNGLBLENDFUNCIEXTPROC) (GLuint buf, GLenum src, GLenum dst); +typedef void (GL_APIENTRYP PFNGLBLENDFUNCSEPARATEIEXTPROC) (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha); +typedef void (GL_APIENTRYP PFNGLCOLORMASKIEXTPROC) (GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a); +typedef GLboolean (GL_APIENTRYP PFNGLISENABLEDIEXTPROC) (GLenum target, GLuint index); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glEnableiEXT (GLenum target, GLuint index); +GL_APICALL void GL_APIENTRY glDisableiEXT (GLenum target, GLuint index); +GL_APICALL void GL_APIENTRY glBlendEquationiEXT (GLuint buf, GLenum mode); +GL_APICALL void GL_APIENTRY glBlendEquationSeparateiEXT (GLuint buf, GLenum modeRGB, GLenum modeAlpha); +GL_APICALL void GL_APIENTRY glBlendFunciEXT (GLuint buf, GLenum src, GLenum dst); +GL_APICALL void GL_APIENTRY glBlendFuncSeparateiEXT (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha); +GL_APICALL void GL_APIENTRY glColorMaskiEXT (GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a); +GL_APICALL GLboolean GL_APIENTRY glIsEnablediEXT (GLenum target, GLuint index); +#endif +#endif /* GL_EXT_draw_buffers_indexed */ + +#ifndef GL_EXT_draw_elements_base_vertex +#define GL_EXT_draw_elements_base_vertex 1 +typedef void (GL_APIENTRYP PFNGLDRAWELEMENTSBASEVERTEXEXTPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLint basevertex); +typedef void (GL_APIENTRYP PFNGLDRAWRANGEELEMENTSBASEVERTEXEXTPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices, GLint basevertex); +typedef void (GL_APIENTRYP PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXEXTPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLint basevertex); +typedef void (GL_APIENTRYP PFNGLMULTIDRAWELEMENTSBASEVERTEXEXTPROC) (GLenum mode, const GLsizei *count, GLenum type, const void *const*indices, GLsizei primcount, const GLint *basevertex); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glDrawElementsBaseVertexEXT (GLenum mode, GLsizei count, GLenum type, const void *indices, GLint basevertex); +GL_APICALL void GL_APIENTRY glDrawRangeElementsBaseVertexEXT (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices, GLint basevertex); +GL_APICALL void GL_APIENTRY glDrawElementsInstancedBaseVertexEXT (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLint basevertex); +GL_APICALL void GL_APIENTRY glMultiDrawElementsBaseVertexEXT (GLenum mode, const GLsizei *count, GLenum type, const void *const*indices, GLsizei primcount, const GLint *basevertex); #endif +#endif /* GL_EXT_draw_elements_base_vertex */ -/* GL_EXT_multisampled_render_to_texture */ -#ifndef GL_EXT_multisampled_render_to_texture -#define GL_EXT_multisampled_render_to_texture 1 +#ifndef GL_EXT_draw_instanced +#define GL_EXT_draw_instanced 1 +typedef void (GL_APIENTRYP PFNGLDRAWARRAYSINSTANCEDEXTPROC) (GLenum mode, GLint start, GLsizei count, GLsizei primcount); +typedef void (GL_APIENTRYP PFNGLDRAWELEMENTSINSTANCEDEXTPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount); #ifdef GL_GLEXT_PROTOTYPES -GL_APICALL void GL_APIENTRY glRenderbufferStorageMultisampleEXT (GLenum, GLsizei, GLenum, GLsizei, GLsizei); -GL_APICALL void GL_APIENTRY glFramebufferTexture2DMultisampleEXT (GLenum, GLenum, GLenum, GLuint, GLint, GLsizei); -#endif -typedef void (GL_APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); -typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples); +GL_APICALL void GL_APIENTRY glDrawArraysInstancedEXT (GLenum mode, GLint start, GLsizei count, GLsizei primcount); +GL_APICALL void GL_APIENTRY glDrawElementsInstancedEXT (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount); +#endif +#endif /* GL_EXT_draw_instanced */ + +#ifndef GL_EXT_float_blend +#define GL_EXT_float_blend 1 +#endif /* GL_EXT_float_blend */ + +#ifndef GL_EXT_geometry_point_size +#define GL_EXT_geometry_point_size 1 +#endif /* GL_EXT_geometry_point_size */ + +#ifndef GL_EXT_geometry_shader +#define GL_EXT_geometry_shader 1 +#define GL_GEOMETRY_SHADER_EXT 0x8DD9 +#define GL_GEOMETRY_SHADER_BIT_EXT 0x00000004 +#define GL_GEOMETRY_LINKED_VERTICES_OUT_EXT 0x8916 +#define GL_GEOMETRY_LINKED_INPUT_TYPE_EXT 0x8917 +#define GL_GEOMETRY_LINKED_OUTPUT_TYPE_EXT 0x8918 +#define GL_GEOMETRY_SHADER_INVOCATIONS_EXT 0x887F +#define GL_LAYER_PROVOKING_VERTEX_EXT 0x825E +#define GL_LINES_ADJACENCY_EXT 0x000A +#define GL_LINE_STRIP_ADJACENCY_EXT 0x000B +#define GL_TRIANGLES_ADJACENCY_EXT 0x000C +#define GL_TRIANGLE_STRIP_ADJACENCY_EXT 0x000D +#define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_EXT 0x8DDF +#define GL_MAX_GEOMETRY_UNIFORM_BLOCKS_EXT 0x8A2C +#define GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS_EXT 0x8A32 +#define GL_MAX_GEOMETRY_INPUT_COMPONENTS_EXT 0x9123 +#define GL_MAX_GEOMETRY_OUTPUT_COMPONENTS_EXT 0x9124 +#define GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT 0x8DE0 +#define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_EXT 0x8DE1 +#define GL_MAX_GEOMETRY_SHADER_INVOCATIONS_EXT 0x8E5A +#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT 0x8C29 +#define GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS_EXT 0x92CF +#define GL_MAX_GEOMETRY_ATOMIC_COUNTERS_EXT 0x92D5 +#define GL_MAX_GEOMETRY_IMAGE_UNIFORMS_EXT 0x90CD +#define GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS_EXT 0x90D7 +#define GL_FIRST_VERTEX_CONVENTION_EXT 0x8E4D +#define GL_LAST_VERTEX_CONVENTION_EXT 0x8E4E +#define GL_UNDEFINED_VERTEX_EXT 0x8260 +#define GL_PRIMITIVES_GENERATED_EXT 0x8C87 +#define GL_FRAMEBUFFER_DEFAULT_LAYERS_EXT 0x9312 +#define GL_MAX_FRAMEBUFFER_LAYERS_EXT 0x9317 +#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_EXT 0x8DA8 +#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED_EXT 0x8DA7 +#define GL_REFERENCED_BY_GEOMETRY_SHADER_EXT 0x9309 +typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERTEXTUREEXTPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glFramebufferTextureEXT (GLenum target, GLenum attachment, GLuint texture, GLint level); #endif +#endif /* GL_EXT_geometry_shader */ -/* GL_EXT_multiview_draw_buffers */ -#ifndef GL_EXT_multiview_draw_buffers -#define GL_EXT_multiview_draw_buffers 1 +#ifndef GL_EXT_gpu_shader5 +#define GL_EXT_gpu_shader5 1 +#endif /* GL_EXT_gpu_shader5 */ + +#ifndef GL_EXT_instanced_arrays +#define GL_EXT_instanced_arrays 1 +#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR_EXT 0x88FE +typedef void (GL_APIENTRYP PFNGLVERTEXATTRIBDIVISOREXTPROC) (GLuint index, GLuint divisor); #ifdef GL_GLEXT_PROTOTYPES -GL_APICALL void GL_APIENTRY glReadBufferIndexedEXT (GLenum src, GLint index); -GL_APICALL void GL_APIENTRY glDrawBuffersIndexedEXT (GLint n, const GLenum *location, const GLint *indices); -GL_APICALL void GL_APIENTRY glGetIntegeri_vEXT (GLenum target, GLuint index, GLint *data); +GL_APICALL void GL_APIENTRY glVertexAttribDivisorEXT (GLuint index, GLuint divisor); #endif -typedef void (GL_APIENTRYP PFNGLREADBUFFERINDEXEDEXTPROC) (GLenum src, GLint index); -typedef void (GL_APIENTRYP PFNGLDRAWBUFFERSINDEXEDEXTPROC) (GLint n, const GLenum *location, const GLint *indices); -typedef void (GL_APIENTRYP PFNGLGETINTEGERI_VEXTPROC) (GLenum target, GLuint index, GLint *data); +#endif /* GL_EXT_instanced_arrays */ + +#ifndef GL_EXT_map_buffer_range +#define GL_EXT_map_buffer_range 1 +#define GL_MAP_READ_BIT_EXT 0x0001 +#define GL_MAP_WRITE_BIT_EXT 0x0002 +#define GL_MAP_INVALIDATE_RANGE_BIT_EXT 0x0004 +#define GL_MAP_INVALIDATE_BUFFER_BIT_EXT 0x0008 +#define GL_MAP_FLUSH_EXPLICIT_BIT_EXT 0x0010 +#define GL_MAP_UNSYNCHRONIZED_BIT_EXT 0x0020 +typedef void *(GL_APIENTRYP PFNGLMAPBUFFERRANGEEXTPROC) (GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access); +typedef void (GL_APIENTRYP PFNGLFLUSHMAPPEDBUFFERRANGEEXTPROC) (GLenum target, GLintptr offset, GLsizeiptr length); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void *GL_APIENTRY glMapBufferRangeEXT (GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access); +GL_APICALL void GL_APIENTRY glFlushMappedBufferRangeEXT (GLenum target, GLintptr offset, GLsizeiptr length); #endif +#endif /* GL_EXT_map_buffer_range */ #ifndef GL_EXT_multi_draw_arrays #define GL_EXT_multi_draw_arrays 1 +typedef void (GL_APIENTRYP PFNGLMULTIDRAWARRAYSEXTPROC) (GLenum mode, const GLint *first, const GLsizei *count, GLsizei primcount); +typedef void (GL_APIENTRYP PFNGLMULTIDRAWELEMENTSEXTPROC) (GLenum mode, const GLsizei *count, GLenum type, const void *const*indices, GLsizei primcount); #ifdef GL_GLEXT_PROTOTYPES -GL_APICALL void GL_APIENTRY glMultiDrawArraysEXT (GLenum, const GLint *, const GLsizei *, GLsizei); -GL_APICALL void GL_APIENTRY glMultiDrawElementsEXT (GLenum, const GLsizei *, GLenum, const GLvoid* *, GLsizei); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (GL_APIENTRYP PFNGLMULTIDRAWARRAYSEXTPROC) (GLenum mode, GLint *first, GLsizei *count, GLsizei primcount); -typedef void (GL_APIENTRYP PFNGLMULTIDRAWELEMENTSEXTPROC) (GLenum mode, const GLsizei *count, GLenum type, const GLvoid* *indices, GLsizei primcount); +GL_APICALL void GL_APIENTRY glMultiDrawArraysEXT (GLenum mode, const GLint *first, const GLsizei *count, GLsizei primcount); +GL_APICALL void GL_APIENTRY glMultiDrawElementsEXT (GLenum mode, const GLsizei *count, GLenum type, const void *const*indices, GLsizei primcount); #endif +#endif /* GL_EXT_multi_draw_arrays */ -/* GL_EXT_occlusion_query_boolean */ -#ifndef GL_EXT_occlusion_query_boolean -#define GL_EXT_occlusion_query_boolean 1 +#ifndef GL_EXT_multi_draw_indirect +#define GL_EXT_multi_draw_indirect 1 +typedef void (GL_APIENTRYP PFNGLMULTIDRAWARRAYSINDIRECTEXTPROC) (GLenum mode, const void *indirect, GLsizei drawcount, GLsizei stride); +typedef void (GL_APIENTRYP PFNGLMULTIDRAWELEMENTSINDIRECTEXTPROC) (GLenum mode, GLenum type, const void *indirect, GLsizei drawcount, GLsizei stride); #ifdef GL_GLEXT_PROTOTYPES -GL_APICALL void GL_APIENTRY glGenQueriesEXT (GLsizei n, GLuint *ids); -GL_APICALL void GL_APIENTRY glDeleteQueriesEXT (GLsizei n, const GLuint *ids); -GL_APICALL GLboolean GL_APIENTRY glIsQueryEXT (GLuint id); -GL_APICALL void GL_APIENTRY glBeginQueryEXT (GLenum target, GLuint id); -GL_APICALL void GL_APIENTRY glEndQueryEXT (GLenum target); -GL_APICALL void GL_APIENTRY glGetQueryivEXT (GLenum target, GLenum pname, GLint *params); -GL_APICALL void GL_APIENTRY glGetQueryObjectuivEXT (GLuint id, GLenum pname, GLuint *params); +GL_APICALL void GL_APIENTRY glMultiDrawArraysIndirectEXT (GLenum mode, const void *indirect, GLsizei drawcount, GLsizei stride); +GL_APICALL void GL_APIENTRY glMultiDrawElementsIndirectEXT (GLenum mode, GLenum type, const void *indirect, GLsizei drawcount, GLsizei stride); #endif -typedef void (GL_APIENTRYP PFNGLGENQUERIESEXTPROC) (GLsizei n, GLuint *ids); -typedef void (GL_APIENTRYP PFNGLDELETEQUERIESEXTPROC) (GLsizei n, const GLuint *ids); -typedef GLboolean (GL_APIENTRYP PFNGLISQUERYEXTPROC) (GLuint id); -typedef void (GL_APIENTRYP PFNGLBEGINQUERYEXTPROC) (GLenum target, GLuint id); -typedef void (GL_APIENTRYP PFNGLENDQUERYEXTPROC) (GLenum target); -typedef void (GL_APIENTRYP PFNGLGETQUERYIVEXTPROC) (GLenum target, GLenum pname, GLint *params); -typedef void (GL_APIENTRYP PFNGLGETQUERYOBJECTUIVEXTPROC) (GLuint id, GLenum pname, GLuint *params); +#endif /* GL_EXT_multi_draw_indirect */ + +#ifndef GL_EXT_multisampled_compatibility +#define GL_EXT_multisampled_compatibility 1 +#define GL_MULTISAMPLE_EXT 0x809D +#define GL_SAMPLE_ALPHA_TO_ONE_EXT 0x809F +#endif /* GL_EXT_multisampled_compatibility */ + +#ifndef GL_EXT_multisampled_render_to_texture +#define GL_EXT_multisampled_render_to_texture 1 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_SAMPLES_EXT 0x8D6C +#define GL_RENDERBUFFER_SAMPLES_EXT 0x8CAB +#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT 0x8D56 +#define GL_MAX_SAMPLES_EXT 0x8D57 +typedef void (GL_APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glRenderbufferStorageMultisampleEXT (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +GL_APICALL void GL_APIENTRY glFramebufferTexture2DMultisampleEXT (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples); +#endif +#endif /* GL_EXT_multisampled_render_to_texture */ + +#ifndef GL_EXT_multiview_draw_buffers +#define GL_EXT_multiview_draw_buffers 1 +#define GL_COLOR_ATTACHMENT_EXT 0x90F0 +#define GL_MULTIVIEW_EXT 0x90F1 +#define GL_DRAW_BUFFER_EXT 0x0C01 +#define GL_READ_BUFFER_EXT 0x0C02 +#define GL_MAX_MULTIVIEW_BUFFERS_EXT 0x90F2 +typedef void (GL_APIENTRYP PFNGLREADBUFFERINDEXEDEXTPROC) (GLenum src, GLint index); +typedef void (GL_APIENTRYP PFNGLDRAWBUFFERSINDEXEDEXTPROC) (GLint n, const GLenum *location, const GLint *indices); +typedef void (GL_APIENTRYP PFNGLGETINTEGERI_VEXTPROC) (GLenum target, GLuint index, GLint *data); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glReadBufferIndexedEXT (GLenum src, GLint index); +GL_APICALL void GL_APIENTRY glDrawBuffersIndexedEXT (GLint n, const GLenum *location, const GLint *indices); +GL_APICALL void GL_APIENTRY glGetIntegeri_vEXT (GLenum target, GLuint index, GLint *data); +#endif +#endif /* GL_EXT_multiview_draw_buffers */ + +#ifndef GL_EXT_occlusion_query_boolean +#define GL_EXT_occlusion_query_boolean 1 +#define GL_ANY_SAMPLES_PASSED_EXT 0x8C2F +#define GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT 0x8D6A +#endif /* GL_EXT_occlusion_query_boolean */ + +#ifndef GL_EXT_post_depth_coverage +#define GL_EXT_post_depth_coverage 1 +#endif /* GL_EXT_post_depth_coverage */ + +#ifndef GL_EXT_primitive_bounding_box +#define GL_EXT_primitive_bounding_box 1 +#define GL_PRIMITIVE_BOUNDING_BOX_EXT 0x92BE +typedef void (GL_APIENTRYP PFNGLPRIMITIVEBOUNDINGBOXEXTPROC) (GLfloat minX, GLfloat minY, GLfloat minZ, GLfloat minW, GLfloat maxX, GLfloat maxY, GLfloat maxZ, GLfloat maxW); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glPrimitiveBoundingBoxEXT (GLfloat minX, GLfloat minY, GLfloat minZ, GLfloat minW, GLfloat maxX, GLfloat maxY, GLfloat maxZ, GLfloat maxW); +#endif +#endif /* GL_EXT_primitive_bounding_box */ + +#ifndef GL_EXT_pvrtc_sRGB +#define GL_EXT_pvrtc_sRGB 1 +#define GL_COMPRESSED_SRGB_PVRTC_2BPPV1_EXT 0x8A54 +#define GL_COMPRESSED_SRGB_PVRTC_4BPPV1_EXT 0x8A55 +#define GL_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV1_EXT 0x8A56 +#define GL_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV1_EXT 0x8A57 +#define GL_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV2_IMG 0x93F0 +#define GL_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV2_IMG 0x93F1 +#endif /* GL_EXT_pvrtc_sRGB */ + +#ifndef GL_EXT_raster_multisample +#define GL_EXT_raster_multisample 1 +#define GL_RASTER_MULTISAMPLE_EXT 0x9327 +#define GL_RASTER_SAMPLES_EXT 0x9328 +#define GL_MAX_RASTER_SAMPLES_EXT 0x9329 +#define GL_RASTER_FIXED_SAMPLE_LOCATIONS_EXT 0x932A +#define GL_MULTISAMPLE_RASTERIZATION_ALLOWED_EXT 0x932B +#define GL_EFFECTIVE_RASTER_SAMPLES_EXT 0x932C +typedef void (GL_APIENTRYP PFNGLRASTERSAMPLESEXTPROC) (GLuint samples, GLboolean fixedsamplelocations); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glRasterSamplesEXT (GLuint samples, GLboolean fixedsamplelocations); #endif +#endif /* GL_EXT_raster_multisample */ -/* GL_EXT_read_format_bgra */ #ifndef GL_EXT_read_format_bgra #define GL_EXT_read_format_bgra 1 -#endif +#define GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT 0x8365 +#define GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT 0x8366 +#endif /* GL_EXT_read_format_bgra */ + +#ifndef GL_EXT_render_snorm +#define GL_EXT_render_snorm 1 +#define GL_R8_SNORM 0x8F94 +#define GL_RG8_SNORM 0x8F95 +#define GL_RGBA8_SNORM 0x8F97 +#define GL_R16_SNORM_EXT 0x8F98 +#define GL_RG16_SNORM_EXT 0x8F99 +#define GL_RGBA16_SNORM_EXT 0x8F9B +#endif /* GL_EXT_render_snorm */ -/* GL_EXT_robustness */ #ifndef GL_EXT_robustness #define GL_EXT_robustness 1 +#define GL_GUILTY_CONTEXT_RESET_EXT 0x8253 +#define GL_INNOCENT_CONTEXT_RESET_EXT 0x8254 +#define GL_UNKNOWN_CONTEXT_RESET_EXT 0x8255 +#define GL_CONTEXT_ROBUST_ACCESS_EXT 0x90F3 +#define GL_RESET_NOTIFICATION_STRATEGY_EXT 0x8256 +#define GL_LOSE_CONTEXT_ON_RESET_EXT 0x8252 +#define GL_NO_RESET_NOTIFICATION_EXT 0x8261 +typedef GLenum (GL_APIENTRYP PFNGLGETGRAPHICSRESETSTATUSEXTPROC) (void); +typedef void (GL_APIENTRYP PFNGLREADNPIXELSEXTPROC) (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, void *data); +typedef void (GL_APIENTRYP PFNGLGETNUNIFORMFVEXTPROC) (GLuint program, GLint location, GLsizei bufSize, GLfloat *params); +typedef void (GL_APIENTRYP PFNGLGETNUNIFORMIVEXTPROC) (GLuint program, GLint location, GLsizei bufSize, GLint *params); #ifdef GL_GLEXT_PROTOTYPES GL_APICALL GLenum GL_APIENTRY glGetGraphicsResetStatusEXT (void); GL_APICALL void GL_APIENTRY glReadnPixelsEXT (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, void *data); -GL_APICALL void GL_APIENTRY glGetnUniformfvEXT (GLuint program, GLint location, GLsizei bufSize, float *params); +GL_APICALL void GL_APIENTRY glGetnUniformfvEXT (GLuint program, GLint location, GLsizei bufSize, GLfloat *params); GL_APICALL void GL_APIENTRY glGetnUniformivEXT (GLuint program, GLint location, GLsizei bufSize, GLint *params); #endif -typedef GLenum (GL_APIENTRYP PFNGLGETGRAPHICSRESETSTATUSEXTPROC) (void); -typedef void (GL_APIENTRYP PFNGLREADNPIXELSEXTPROC) (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, void *data); -typedef void (GL_APIENTRYP PFNGLGETNUNIFORMFVEXTPROC) (GLuint program, GLint location, GLsizei bufSize, float *params); -typedef void (GL_APIENTRYP PFNGLGETNUNIFORMIVEXTPROC) (GLuint program, GLint location, GLsizei bufSize, GLint *params); -#endif +#endif /* GL_EXT_robustness */ + +#ifndef GL_EXT_sRGB +#define GL_EXT_sRGB 1 +#define GL_SRGB_EXT 0x8C40 +#define GL_SRGB_ALPHA_EXT 0x8C42 +#define GL_SRGB8_ALPHA8_EXT 0x8C43 +#define GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING_EXT 0x8210 +#endif /* GL_EXT_sRGB */ + +#ifndef GL_EXT_sRGB_write_control +#define GL_EXT_sRGB_write_control 1 +#define GL_FRAMEBUFFER_SRGB_EXT 0x8DB9 +#endif /* GL_EXT_sRGB_write_control */ -/* GL_EXT_separate_shader_objects */ #ifndef GL_EXT_separate_shader_objects #define GL_EXT_separate_shader_objects 1 +#define GL_ACTIVE_PROGRAM_EXT 0x8259 +#define GL_VERTEX_SHADER_BIT_EXT 0x00000001 +#define GL_FRAGMENT_SHADER_BIT_EXT 0x00000002 +#define GL_ALL_SHADER_BITS_EXT 0xFFFFFFFF +#define GL_PROGRAM_SEPARABLE_EXT 0x8258 +#define GL_PROGRAM_PIPELINE_BINDING_EXT 0x825A +typedef void (GL_APIENTRYP PFNGLACTIVESHADERPROGRAMEXTPROC) (GLuint pipeline, GLuint program); +typedef void (GL_APIENTRYP PFNGLBINDPROGRAMPIPELINEEXTPROC) (GLuint pipeline); +typedef GLuint (GL_APIENTRYP PFNGLCREATESHADERPROGRAMVEXTPROC) (GLenum type, GLsizei count, const GLchar **strings); +typedef void (GL_APIENTRYP PFNGLDELETEPROGRAMPIPELINESEXTPROC) (GLsizei n, const GLuint *pipelines); +typedef void (GL_APIENTRYP PFNGLGENPROGRAMPIPELINESEXTPROC) (GLsizei n, GLuint *pipelines); +typedef void (GL_APIENTRYP PFNGLGETPROGRAMPIPELINEINFOLOGEXTPROC) (GLuint pipeline, GLsizei bufSize, GLsizei *length, GLchar *infoLog); +typedef void (GL_APIENTRYP PFNGLGETPROGRAMPIPELINEIVEXTPROC) (GLuint pipeline, GLenum pname, GLint *params); +typedef GLboolean (GL_APIENTRYP PFNGLISPROGRAMPIPELINEEXTPROC) (GLuint pipeline); +typedef void (GL_APIENTRYP PFNGLPROGRAMPARAMETERIEXTPROC) (GLuint program, GLenum pname, GLint value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM1FEXTPROC) (GLuint program, GLint location, GLfloat v0); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM1FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM1IEXTPROC) (GLuint program, GLint location, GLint v0); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM1IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM2FEXTPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM2FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM2IEXTPROC) (GLuint program, GLint location, GLint v0, GLint v1); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM2IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM3FEXTPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM3FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM3IEXTPROC) (GLuint program, GLint location, GLint v0, GLint v1, GLint v2); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM3IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM4FEXTPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM4FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM4IEXTPROC) (GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM4IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLUSEPROGRAMSTAGESEXTPROC) (GLuint pipeline, GLbitfield stages, GLuint program); +typedef void (GL_APIENTRYP PFNGLVALIDATEPROGRAMPIPELINEEXTPROC) (GLuint pipeline); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM1UIEXTPROC) (GLuint program, GLint location, GLuint v0); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM2UIEXTPROC) (GLuint program, GLint location, GLuint v0, GLuint v1); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM3UIEXTPROC) (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM4UIEXTPROC) (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM1UIVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM2UIVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM3UIVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM4UIVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2X3FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3X2FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2X4FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4X2FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3X4FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4X3FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); #ifdef GL_GLEXT_PROTOTYPES -GL_APICALL void GL_APIENTRY glUseProgramStagesEXT (GLuint pipeline, GLbitfield stages, GLuint program); GL_APICALL void GL_APIENTRY glActiveShaderProgramEXT (GLuint pipeline, GLuint program); -GL_APICALL GLuint GL_APIENTRY glCreateShaderProgramvEXT (GLenum type, GLsizei count, const GLchar **strings); GL_APICALL void GL_APIENTRY glBindProgramPipelineEXT (GLuint pipeline); +GL_APICALL GLuint GL_APIENTRY glCreateShaderProgramvEXT (GLenum type, GLsizei count, const GLchar **strings); GL_APICALL void GL_APIENTRY glDeleteProgramPipelinesEXT (GLsizei n, const GLuint *pipelines); GL_APICALL void GL_APIENTRY glGenProgramPipelinesEXT (GLsizei n, GLuint *pipelines); +GL_APICALL void GL_APIENTRY glGetProgramPipelineInfoLogEXT (GLuint pipeline, GLsizei bufSize, GLsizei *length, GLchar *infoLog); +GL_APICALL void GL_APIENTRY glGetProgramPipelineivEXT (GLuint pipeline, GLenum pname, GLint *params); GL_APICALL GLboolean GL_APIENTRY glIsProgramPipelineEXT (GLuint pipeline); GL_APICALL void GL_APIENTRY glProgramParameteriEXT (GLuint program, GLenum pname, GLint value); -GL_APICALL void GL_APIENTRY glGetProgramPipelineivEXT (GLuint pipeline, GLenum pname, GLint *params); -GL_APICALL void GL_APIENTRY glProgramUniform1iEXT (GLuint program, GLint location, GLint x); -GL_APICALL void GL_APIENTRY glProgramUniform2iEXT (GLuint program, GLint location, GLint x, GLint y); -GL_APICALL void GL_APIENTRY glProgramUniform3iEXT (GLuint program, GLint location, GLint x, GLint y, GLint z); -GL_APICALL void GL_APIENTRY glProgramUniform4iEXT (GLuint program, GLint location, GLint x, GLint y, GLint z, GLint w); -GL_APICALL void GL_APIENTRY glProgramUniform1fEXT (GLuint program, GLint location, GLfloat x); -GL_APICALL void GL_APIENTRY glProgramUniform2fEXT (GLuint program, GLint location, GLfloat x, GLfloat y); -GL_APICALL void GL_APIENTRY glProgramUniform3fEXT (GLuint program, GLint location, GLfloat x, GLfloat y, GLfloat z); -GL_APICALL void GL_APIENTRY glProgramUniform4fEXT (GLuint program, GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w); -GL_APICALL void GL_APIENTRY glProgramUniform1ivEXT (GLuint program, GLint location, GLsizei count, const GLint *value); -GL_APICALL void GL_APIENTRY glProgramUniform2ivEXT (GLuint program, GLint location, GLsizei count, const GLint *value); -GL_APICALL void GL_APIENTRY glProgramUniform3ivEXT (GLuint program, GLint location, GLsizei count, const GLint *value); -GL_APICALL void GL_APIENTRY glProgramUniform4ivEXT (GLuint program, GLint location, GLsizei count, const GLint *value); +GL_APICALL void GL_APIENTRY glProgramUniform1fEXT (GLuint program, GLint location, GLfloat v0); GL_APICALL void GL_APIENTRY glProgramUniform1fvEXT (GLuint program, GLint location, GLsizei count, const GLfloat *value); +GL_APICALL void GL_APIENTRY glProgramUniform1iEXT (GLuint program, GLint location, GLint v0); +GL_APICALL void GL_APIENTRY glProgramUniform1ivEXT (GLuint program, GLint location, GLsizei count, const GLint *value); +GL_APICALL void GL_APIENTRY glProgramUniform2fEXT (GLuint program, GLint location, GLfloat v0, GLfloat v1); GL_APICALL void GL_APIENTRY glProgramUniform2fvEXT (GLuint program, GLint location, GLsizei count, const GLfloat *value); +GL_APICALL void GL_APIENTRY glProgramUniform2iEXT (GLuint program, GLint location, GLint v0, GLint v1); +GL_APICALL void GL_APIENTRY glProgramUniform2ivEXT (GLuint program, GLint location, GLsizei count, const GLint *value); +GL_APICALL void GL_APIENTRY glProgramUniform3fEXT (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2); GL_APICALL void GL_APIENTRY glProgramUniform3fvEXT (GLuint program, GLint location, GLsizei count, const GLfloat *value); +GL_APICALL void GL_APIENTRY glProgramUniform3iEXT (GLuint program, GLint location, GLint v0, GLint v1, GLint v2); +GL_APICALL void GL_APIENTRY glProgramUniform3ivEXT (GLuint program, GLint location, GLsizei count, const GLint *value); +GL_APICALL void GL_APIENTRY glProgramUniform4fEXT (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); GL_APICALL void GL_APIENTRY glProgramUniform4fvEXT (GLuint program, GLint location, GLsizei count, const GLfloat *value); +GL_APICALL void GL_APIENTRY glProgramUniform4iEXT (GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3); +GL_APICALL void GL_APIENTRY glProgramUniform4ivEXT (GLuint program, GLint location, GLsizei count, const GLint *value); GL_APICALL void GL_APIENTRY glProgramUniformMatrix2fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); GL_APICALL void GL_APIENTRY glProgramUniformMatrix3fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); GL_APICALL void GL_APIENTRY glProgramUniformMatrix4fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GL_APICALL void GL_APIENTRY glUseProgramStagesEXT (GLuint pipeline, GLbitfield stages, GLuint program); GL_APICALL void GL_APIENTRY glValidateProgramPipelineEXT (GLuint pipeline); -GL_APICALL void GL_APIENTRY glGetProgramPipelineInfoLogEXT (GLuint pipeline, GLsizei bufSize, GLsizei *length, GLchar *infoLog); -#endif -typedef void (GL_APIENTRYP PFNGLUSEPROGRAMSTAGESEXTPROC) (GLuint pipeline, GLbitfield stages, GLuint program); -typedef void (GL_APIENTRYP PFNGLACTIVESHADERPROGRAMEXTPROC) (GLuint pipeline, GLuint program); -typedef GLuint (GL_APIENTRYP PFNGLCREATESHADERPROGRAMVEXTPROC) (GLenum type, GLsizei count, const GLchar **strings); -typedef void (GL_APIENTRYP PFNGLBINDPROGRAMPIPELINEEXTPROC) (GLuint pipeline); -typedef void (GL_APIENTRYP PFNGLDELETEPROGRAMPIPELINESEXTPROC) (GLsizei n, const GLuint *pipelines); -typedef void (GL_APIENTRYP PFNGLGENPROGRAMPIPELINESEXTPROC) (GLsizei n, GLuint *pipelines); -typedef GLboolean (GL_APIENTRYP PFNGLISPROGRAMPIPELINEEXTPROC) (GLuint pipeline); -typedef void (GL_APIENTRYP PFNGLPROGRAMPARAMETERIEXTPROC) (GLuint program, GLenum pname, GLint value); -typedef void (GL_APIENTRYP PFNGLGETPROGRAMPIPELINEIVEXTPROC) (GLuint pipeline, GLenum pname, GLint *params); -typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM1IEXTPROC) (GLuint program, GLint location, GLint x); -typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM2IEXTPROC) (GLuint program, GLint location, GLint x, GLint y); -typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM3IEXTPROC) (GLuint program, GLint location, GLint x, GLint y, GLint z); -typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM4IEXTPROC) (GLuint program, GLint location, GLint x, GLint y, GLint z, GLint w); -typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM1FEXTPROC) (GLuint program, GLint location, GLfloat x); -typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM2FEXTPROC) (GLuint program, GLint location, GLfloat x, GLfloat y); -typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM3FEXTPROC) (GLuint program, GLint location, GLfloat x, GLfloat y, GLfloat z); -typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM4FEXTPROC) (GLuint program, GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w); -typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM1IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint *value); -typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM2IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint *value); -typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM3IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint *value); -typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM4IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint *value); -typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM1FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value); -typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM2FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value); -typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM3FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value); -typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM4FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value); -typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (GL_APIENTRYP PFNGLVALIDATEPROGRAMPIPELINEEXTPROC) (GLuint pipeline); -typedef void (GL_APIENTRYP PFNGLGETPROGRAMPIPELINEINFOLOGEXTPROC) (GLuint pipeline, GLsizei bufSize, GLsizei *length, GLchar *infoLog); -#endif +GL_APICALL void GL_APIENTRY glProgramUniform1uiEXT (GLuint program, GLint location, GLuint v0); +GL_APICALL void GL_APIENTRY glProgramUniform2uiEXT (GLuint program, GLint location, GLuint v0, GLuint v1); +GL_APICALL void GL_APIENTRY glProgramUniform3uiEXT (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2); +GL_APICALL void GL_APIENTRY glProgramUniform4uiEXT (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); +GL_APICALL void GL_APIENTRY glProgramUniform1uivEXT (GLuint program, GLint location, GLsizei count, const GLuint *value); +GL_APICALL void GL_APIENTRY glProgramUniform2uivEXT (GLuint program, GLint location, GLsizei count, const GLuint *value); +GL_APICALL void GL_APIENTRY glProgramUniform3uivEXT (GLuint program, GLint location, GLsizei count, const GLuint *value); +GL_APICALL void GL_APIENTRY glProgramUniform4uivEXT (GLuint program, GLint location, GLsizei count, const GLuint *value); +GL_APICALL void GL_APIENTRY glProgramUniformMatrix2x3fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GL_APICALL void GL_APIENTRY glProgramUniformMatrix3x2fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GL_APICALL void GL_APIENTRY glProgramUniformMatrix2x4fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GL_APICALL void GL_APIENTRY glProgramUniformMatrix4x2fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GL_APICALL void GL_APIENTRY glProgramUniformMatrix3x4fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GL_APICALL void GL_APIENTRY glProgramUniformMatrix4x3fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +#endif +#endif /* GL_EXT_separate_shader_objects */ -/* GL_EXT_shader_framebuffer_fetch */ #ifndef GL_EXT_shader_framebuffer_fetch #define GL_EXT_shader_framebuffer_fetch 1 -#endif +#define GL_FRAGMENT_SHADER_DISCARDS_SAMPLES_EXT 0x8A52 +#endif /* GL_EXT_shader_framebuffer_fetch */ + +#ifndef GL_EXT_shader_implicit_conversions +#define GL_EXT_shader_implicit_conversions 1 +#endif /* GL_EXT_shader_implicit_conversions */ + +#ifndef GL_EXT_shader_integer_mix +#define GL_EXT_shader_integer_mix 1 +#endif /* GL_EXT_shader_integer_mix */ + +#ifndef GL_EXT_shader_io_blocks +#define GL_EXT_shader_io_blocks 1 +#endif /* GL_EXT_shader_io_blocks */ + +#ifndef GL_EXT_shader_pixel_local_storage +#define GL_EXT_shader_pixel_local_storage 1 +#define GL_MAX_SHADER_PIXEL_LOCAL_STORAGE_FAST_SIZE_EXT 0x8F63 +#define GL_MAX_SHADER_PIXEL_LOCAL_STORAGE_SIZE_EXT 0x8F67 +#define GL_SHADER_PIXEL_LOCAL_STORAGE_EXT 0x8F64 +#endif /* GL_EXT_shader_pixel_local_storage */ -/* GL_EXT_shader_texture_lod */ #ifndef GL_EXT_shader_texture_lod #define GL_EXT_shader_texture_lod 1 -#endif +#endif /* GL_EXT_shader_texture_lod */ -/* GL_EXT_shadow_samplers */ #ifndef GL_EXT_shadow_samplers #define GL_EXT_shadow_samplers 1 +#define GL_TEXTURE_COMPARE_MODE_EXT 0x884C +#define GL_TEXTURE_COMPARE_FUNC_EXT 0x884D +#define GL_COMPARE_REF_TO_TEXTURE_EXT 0x884E +#define GL_SAMPLER_2D_SHADOW_EXT 0x8B62 +#endif /* GL_EXT_shadow_samplers */ + +#ifndef GL_EXT_sparse_texture +#define GL_EXT_sparse_texture 1 +#define GL_TEXTURE_SPARSE_EXT 0x91A6 +#define GL_VIRTUAL_PAGE_SIZE_INDEX_EXT 0x91A7 +#define GL_NUM_SPARSE_LEVELS_EXT 0x91AA +#define GL_NUM_VIRTUAL_PAGE_SIZES_EXT 0x91A8 +#define GL_VIRTUAL_PAGE_SIZE_X_EXT 0x9195 +#define GL_VIRTUAL_PAGE_SIZE_Y_EXT 0x9196 +#define GL_VIRTUAL_PAGE_SIZE_Z_EXT 0x9197 +#define GL_TEXTURE_2D_ARRAY 0x8C1A +#define GL_TEXTURE_3D 0x806F +#define GL_MAX_SPARSE_TEXTURE_SIZE_EXT 0x9198 +#define GL_MAX_SPARSE_3D_TEXTURE_SIZE_EXT 0x9199 +#define GL_MAX_SPARSE_ARRAY_TEXTURE_LAYERS_EXT 0x919A +#define GL_SPARSE_TEXTURE_FULL_ARRAY_CUBE_MIPMAPS_EXT 0x91A9 +typedef void (GL_APIENTRYP PFNGLTEXPAGECOMMITMENTEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLboolean commit); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glTexPageCommitmentEXT (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLboolean commit); +#endif +#endif /* GL_EXT_sparse_texture */ + +#ifndef GL_EXT_tessellation_point_size +#define GL_EXT_tessellation_point_size 1 +#endif /* GL_EXT_tessellation_point_size */ + +#ifndef GL_EXT_tessellation_shader +#define GL_EXT_tessellation_shader 1 +#define GL_PATCHES_EXT 0x000E +#define GL_PATCH_VERTICES_EXT 0x8E72 +#define GL_TESS_CONTROL_OUTPUT_VERTICES_EXT 0x8E75 +#define GL_TESS_GEN_MODE_EXT 0x8E76 +#define GL_TESS_GEN_SPACING_EXT 0x8E77 +#define GL_TESS_GEN_VERTEX_ORDER_EXT 0x8E78 +#define GL_TESS_GEN_POINT_MODE_EXT 0x8E79 +#define GL_ISOLINES_EXT 0x8E7A +#define GL_QUADS_EXT 0x0007 +#define GL_FRACTIONAL_ODD_EXT 0x8E7B +#define GL_FRACTIONAL_EVEN_EXT 0x8E7C +#define GL_MAX_PATCH_VERTICES_EXT 0x8E7D +#define GL_MAX_TESS_GEN_LEVEL_EXT 0x8E7E +#define GL_MAX_TESS_CONTROL_UNIFORM_COMPONENTS_EXT 0x8E7F +#define GL_MAX_TESS_EVALUATION_UNIFORM_COMPONENTS_EXT 0x8E80 +#define GL_MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS_EXT 0x8E81 +#define GL_MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS_EXT 0x8E82 +#define GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS_EXT 0x8E83 +#define GL_MAX_TESS_PATCH_COMPONENTS_EXT 0x8E84 +#define GL_MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS_EXT 0x8E85 +#define GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS_EXT 0x8E86 +#define GL_MAX_TESS_CONTROL_UNIFORM_BLOCKS_EXT 0x8E89 +#define GL_MAX_TESS_EVALUATION_UNIFORM_BLOCKS_EXT 0x8E8A +#define GL_MAX_TESS_CONTROL_INPUT_COMPONENTS_EXT 0x886C +#define GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS_EXT 0x886D +#define GL_MAX_COMBINED_TESS_CONTROL_UNIFORM_COMPONENTS_EXT 0x8E1E +#define GL_MAX_COMBINED_TESS_EVALUATION_UNIFORM_COMPONENTS_EXT 0x8E1F +#define GL_MAX_TESS_CONTROL_ATOMIC_COUNTER_BUFFERS_EXT 0x92CD +#define GL_MAX_TESS_EVALUATION_ATOMIC_COUNTER_BUFFERS_EXT 0x92CE +#define GL_MAX_TESS_CONTROL_ATOMIC_COUNTERS_EXT 0x92D3 +#define GL_MAX_TESS_EVALUATION_ATOMIC_COUNTERS_EXT 0x92D4 +#define GL_MAX_TESS_CONTROL_IMAGE_UNIFORMS_EXT 0x90CB +#define GL_MAX_TESS_EVALUATION_IMAGE_UNIFORMS_EXT 0x90CC +#define GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS_EXT 0x90D8 +#define GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS_EXT 0x90D9 +#define GL_PRIMITIVE_RESTART_FOR_PATCHES_SUPPORTED 0x8221 +#define GL_IS_PER_PATCH_EXT 0x92E7 +#define GL_REFERENCED_BY_TESS_CONTROL_SHADER_EXT 0x9307 +#define GL_REFERENCED_BY_TESS_EVALUATION_SHADER_EXT 0x9308 +#define GL_TESS_CONTROL_SHADER_EXT 0x8E88 +#define GL_TESS_EVALUATION_SHADER_EXT 0x8E87 +#define GL_TESS_CONTROL_SHADER_BIT_EXT 0x00000008 +#define GL_TESS_EVALUATION_SHADER_BIT_EXT 0x00000010 +typedef void (GL_APIENTRYP PFNGLPATCHPARAMETERIEXTPROC) (GLenum pname, GLint value); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glPatchParameteriEXT (GLenum pname, GLint value); +#endif +#endif /* GL_EXT_tessellation_shader */ + +#ifndef GL_EXT_texture_border_clamp +#define GL_EXT_texture_border_clamp 1 +#define GL_TEXTURE_BORDER_COLOR_EXT 0x1004 +#define GL_CLAMP_TO_BORDER_EXT 0x812D +typedef void (GL_APIENTRYP PFNGLTEXPARAMETERIIVEXTPROC) (GLenum target, GLenum pname, const GLint *params); +typedef void (GL_APIENTRYP PFNGLTEXPARAMETERIUIVEXTPROC) (GLenum target, GLenum pname, const GLuint *params); +typedef void (GL_APIENTRYP PFNGLGETTEXPARAMETERIIVEXTPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (GL_APIENTRYP PFNGLGETTEXPARAMETERIUIVEXTPROC) (GLenum target, GLenum pname, GLuint *params); +typedef void (GL_APIENTRYP PFNGLSAMPLERPARAMETERIIVEXTPROC) (GLuint sampler, GLenum pname, const GLint *param); +typedef void (GL_APIENTRYP PFNGLSAMPLERPARAMETERIUIVEXTPROC) (GLuint sampler, GLenum pname, const GLuint *param); +typedef void (GL_APIENTRYP PFNGLGETSAMPLERPARAMETERIIVEXTPROC) (GLuint sampler, GLenum pname, GLint *params); +typedef void (GL_APIENTRYP PFNGLGETSAMPLERPARAMETERIUIVEXTPROC) (GLuint sampler, GLenum pname, GLuint *params); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glTexParameterIivEXT (GLenum target, GLenum pname, const GLint *params); +GL_APICALL void GL_APIENTRY glTexParameterIuivEXT (GLenum target, GLenum pname, const GLuint *params); +GL_APICALL void GL_APIENTRY glGetTexParameterIivEXT (GLenum target, GLenum pname, GLint *params); +GL_APICALL void GL_APIENTRY glGetTexParameterIuivEXT (GLenum target, GLenum pname, GLuint *params); +GL_APICALL void GL_APIENTRY glSamplerParameterIivEXT (GLuint sampler, GLenum pname, const GLint *param); +GL_APICALL void GL_APIENTRY glSamplerParameterIuivEXT (GLuint sampler, GLenum pname, const GLuint *param); +GL_APICALL void GL_APIENTRY glGetSamplerParameterIivEXT (GLuint sampler, GLenum pname, GLint *params); +GL_APICALL void GL_APIENTRY glGetSamplerParameterIuivEXT (GLuint sampler, GLenum pname, GLuint *params); +#endif +#endif /* GL_EXT_texture_border_clamp */ + +#ifndef GL_EXT_texture_buffer +#define GL_EXT_texture_buffer 1 +#define GL_TEXTURE_BUFFER_EXT 0x8C2A +#define GL_TEXTURE_BUFFER_BINDING_EXT 0x8C2A +#define GL_MAX_TEXTURE_BUFFER_SIZE_EXT 0x8C2B +#define GL_TEXTURE_BINDING_BUFFER_EXT 0x8C2C +#define GL_TEXTURE_BUFFER_DATA_STORE_BINDING_EXT 0x8C2D +#define GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT_EXT 0x919F +#define GL_SAMPLER_BUFFER_EXT 0x8DC2 +#define GL_INT_SAMPLER_BUFFER_EXT 0x8DD0 +#define GL_UNSIGNED_INT_SAMPLER_BUFFER_EXT 0x8DD8 +#define GL_IMAGE_BUFFER_EXT 0x9051 +#define GL_INT_IMAGE_BUFFER_EXT 0x905C +#define GL_UNSIGNED_INT_IMAGE_BUFFER_EXT 0x9067 +#define GL_TEXTURE_BUFFER_OFFSET_EXT 0x919D +#define GL_TEXTURE_BUFFER_SIZE_EXT 0x919E +typedef void (GL_APIENTRYP PFNGLTEXBUFFEREXTPROC) (GLenum target, GLenum internalformat, GLuint buffer); +typedef void (GL_APIENTRYP PFNGLTEXBUFFERRANGEEXTPROC) (GLenum target, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glTexBufferEXT (GLenum target, GLenum internalformat, GLuint buffer); +GL_APICALL void GL_APIENTRY glTexBufferRangeEXT (GLenum target, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size); #endif +#endif /* GL_EXT_texture_buffer */ -/* GL_EXT_sRGB */ -#ifndef GL_EXT_sRGB -#define GL_EXT_sRGB 1 -#endif - -/* GL_EXT_texture_compression_dxt1 */ #ifndef GL_EXT_texture_compression_dxt1 #define GL_EXT_texture_compression_dxt1 1 -#endif +#define GL_COMPRESSED_RGB_S3TC_DXT1_EXT 0x83F0 +#define GL_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1 +#endif /* GL_EXT_texture_compression_dxt1 */ + +#ifndef GL_EXT_texture_compression_s3tc +#define GL_EXT_texture_compression_s3tc 1 +#define GL_COMPRESSED_RGBA_S3TC_DXT3_EXT 0x83F2 +#define GL_COMPRESSED_RGBA_S3TC_DXT5_EXT 0x83F3 +#endif /* GL_EXT_texture_compression_s3tc */ + +#ifndef GL_EXT_texture_cube_map_array +#define GL_EXT_texture_cube_map_array 1 +#define GL_TEXTURE_CUBE_MAP_ARRAY_EXT 0x9009 +#define GL_TEXTURE_BINDING_CUBE_MAP_ARRAY_EXT 0x900A +#define GL_SAMPLER_CUBE_MAP_ARRAY_EXT 0x900C +#define GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW_EXT 0x900D +#define GL_INT_SAMPLER_CUBE_MAP_ARRAY_EXT 0x900E +#define GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY_EXT 0x900F +#define GL_IMAGE_CUBE_MAP_ARRAY_EXT 0x9054 +#define GL_INT_IMAGE_CUBE_MAP_ARRAY_EXT 0x905F +#define GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY_EXT 0x906A +#endif /* GL_EXT_texture_cube_map_array */ -/* GL_EXT_texture_filter_anisotropic */ #ifndef GL_EXT_texture_filter_anisotropic #define GL_EXT_texture_filter_anisotropic 1 -#endif +#define GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE +#define GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT 0x84FF +#endif /* GL_EXT_texture_filter_anisotropic */ + +#ifndef GL_EXT_texture_filter_minmax +#define GL_EXT_texture_filter_minmax 1 +#endif /* GL_EXT_texture_filter_minmax */ -/* GL_EXT_texture_format_BGRA8888 */ #ifndef GL_EXT_texture_format_BGRA8888 #define GL_EXT_texture_format_BGRA8888 1 -#endif +#endif /* GL_EXT_texture_format_BGRA8888 */ + +#ifndef GL_EXT_texture_norm16 +#define GL_EXT_texture_norm16 1 +#define GL_R16_EXT 0x822A +#define GL_RG16_EXT 0x822C +#define GL_RGBA16_EXT 0x805B +#define GL_RGB16_EXT 0x8054 +#define GL_RGB16_SNORM_EXT 0x8F9A +#endif /* GL_EXT_texture_norm16 */ -/* GL_EXT_texture_rg */ #ifndef GL_EXT_texture_rg #define GL_EXT_texture_rg 1 -#endif +#define GL_RED_EXT 0x1903 +#define GL_RG_EXT 0x8227 +#define GL_R8_EXT 0x8229 +#define GL_RG8_EXT 0x822B +#endif /* GL_EXT_texture_rg */ + +#ifndef GL_EXT_texture_sRGB_R8 +#define GL_EXT_texture_sRGB_R8 1 +#define GL_SR8_EXT 0x8FBD +#endif /* GL_EXT_texture_sRGB_R8 */ + +#ifndef GL_EXT_texture_sRGB_RG8 +#define GL_EXT_texture_sRGB_RG8 1 +#define GL_SRG8_EXT 0x8FBE +#endif /* GL_EXT_texture_sRGB_RG8 */ + +#ifndef GL_EXT_texture_sRGB_decode +#define GL_EXT_texture_sRGB_decode 1 +#define GL_TEXTURE_SRGB_DECODE_EXT 0x8A48 +#define GL_DECODE_EXT 0x8A49 +#define GL_SKIP_DECODE_EXT 0x8A4A +#endif /* GL_EXT_texture_sRGB_decode */ -/* GL_EXT_texture_storage */ #ifndef GL_EXT_texture_storage #define GL_EXT_texture_storage 1 +#define GL_TEXTURE_IMMUTABLE_FORMAT_EXT 0x912F +#define GL_ALPHA8_EXT 0x803C +#define GL_LUMINANCE8_EXT 0x8040 +#define GL_LUMINANCE8_ALPHA8_EXT 0x8045 +#define GL_RGBA32F_EXT 0x8814 +#define GL_RGB32F_EXT 0x8815 +#define GL_ALPHA32F_EXT 0x8816 +#define GL_LUMINANCE32F_EXT 0x8818 +#define GL_LUMINANCE_ALPHA32F_EXT 0x8819 +#define GL_ALPHA16F_EXT 0x881C +#define GL_LUMINANCE16F_EXT 0x881E +#define GL_LUMINANCE_ALPHA16F_EXT 0x881F +#define GL_R32F_EXT 0x822E +#define GL_RG32F_EXT 0x8230 +typedef void (GL_APIENTRYP PFNGLTEXSTORAGE1DEXTPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width); +typedef void (GL_APIENTRYP PFNGLTEXSTORAGE2DEXTPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (GL_APIENTRYP PFNGLTEXSTORAGE3DEXTPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); +typedef void (GL_APIENTRYP PFNGLTEXTURESTORAGE1DEXTPROC) (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width); +typedef void (GL_APIENTRYP PFNGLTEXTURESTORAGE2DEXTPROC) (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (GL_APIENTRYP PFNGLTEXTURESTORAGE3DEXTPROC) (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); #ifdef GL_GLEXT_PROTOTYPES GL_APICALL void GL_APIENTRY glTexStorage1DEXT (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width); GL_APICALL void GL_APIENTRY glTexStorage2DEXT (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); @@ -1663,148 +1858,356 @@ GL_APICALL void GL_APIENTRY glTextureStorage1DEXT (GLuint texture, GLenum target GL_APICALL void GL_APIENTRY glTextureStorage2DEXT (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); GL_APICALL void GL_APIENTRY glTextureStorage3DEXT (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); #endif -typedef void (GL_APIENTRYP PFNGLTEXSTORAGE1DEXTPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width); -typedef void (GL_APIENTRYP PFNGLTEXSTORAGE2DEXTPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); -typedef void (GL_APIENTRYP PFNGLTEXSTORAGE3DEXTPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); -typedef void (GL_APIENTRYP PFNGLTEXTURESTORAGE1DEXTPROC) (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width); -typedef void (GL_APIENTRYP PFNGLTEXTURESTORAGE2DEXTPROC) (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); -typedef void (GL_APIENTRYP PFNGLTEXTURESTORAGE3DEXTPROC) (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); -#endif +#endif /* GL_EXT_texture_storage */ -/* GL_EXT_texture_type_2_10_10_10_REV */ #ifndef GL_EXT_texture_type_2_10_10_10_REV #define GL_EXT_texture_type_2_10_10_10_REV 1 +#define GL_UNSIGNED_INT_2_10_10_10_REV_EXT 0x8368 +#endif /* GL_EXT_texture_type_2_10_10_10_REV */ + +#ifndef GL_EXT_texture_view +#define GL_EXT_texture_view 1 +#define GL_TEXTURE_VIEW_MIN_LEVEL_EXT 0x82DB +#define GL_TEXTURE_VIEW_NUM_LEVELS_EXT 0x82DC +#define GL_TEXTURE_VIEW_MIN_LAYER_EXT 0x82DD +#define GL_TEXTURE_VIEW_NUM_LAYERS_EXT 0x82DE +typedef void (GL_APIENTRYP PFNGLTEXTUREVIEWEXTPROC) (GLuint texture, GLenum target, GLuint origtexture, GLenum internalformat, GLuint minlevel, GLuint numlevels, GLuint minlayer, GLuint numlayers); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glTextureViewEXT (GLuint texture, GLenum target, GLuint origtexture, GLenum internalformat, GLuint minlevel, GLuint numlevels, GLuint minlayer, GLuint numlayers); #endif +#endif /* GL_EXT_texture_view */ -/* GL_EXT_unpack_subimage */ #ifndef GL_EXT_unpack_subimage #define GL_EXT_unpack_subimage 1 -#endif +#define GL_UNPACK_ROW_LENGTH_EXT 0x0CF2 +#define GL_UNPACK_SKIP_ROWS_EXT 0x0CF3 +#define GL_UNPACK_SKIP_PIXELS_EXT 0x0CF4 +#endif /* GL_EXT_unpack_subimage */ -/*------------------------------------------------------------------------* - * DMP extension functions - *------------------------------------------------------------------------*/ - -/* GL_DMP_shader_binary */ -#ifndef GL_DMP_shader_binary -#define GL_DMP_shader_binary 1 -#endif - -/*------------------------------------------------------------------------* - * FJ extension functions - *------------------------------------------------------------------------*/ - -/* GL_FJ_shader_binary_GCCSO */ #ifndef GL_FJ_shader_binary_GCCSO #define GL_FJ_shader_binary_GCCSO 1 -#endif +#define GL_GCCSO_SHADER_BINARY_FJ 0x9260 +#endif /* GL_FJ_shader_binary_GCCSO */ -/*------------------------------------------------------------------------* - * IMG extension functions - *------------------------------------------------------------------------*/ +#ifndef GL_IMG_multisampled_render_to_texture +#define GL_IMG_multisampled_render_to_texture 1 +#define GL_RENDERBUFFER_SAMPLES_IMG 0x9133 +#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_IMG 0x9134 +#define GL_MAX_SAMPLES_IMG 0x9135 +#define GL_TEXTURE_SAMPLES_IMG 0x9136 +typedef void (GL_APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEIMGPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEIMGPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glRenderbufferStorageMultisampleIMG (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +GL_APICALL void GL_APIENTRY glFramebufferTexture2DMultisampleIMG (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples); +#endif +#endif /* GL_IMG_multisampled_render_to_texture */ -/* GL_IMG_program_binary */ #ifndef GL_IMG_program_binary #define GL_IMG_program_binary 1 -#endif +#define GL_SGX_PROGRAM_BINARY_IMG 0x9130 +#endif /* GL_IMG_program_binary */ -/* GL_IMG_read_format */ #ifndef GL_IMG_read_format #define GL_IMG_read_format 1 -#endif +#define GL_BGRA_IMG 0x80E1 +#define GL_UNSIGNED_SHORT_4_4_4_4_REV_IMG 0x8365 +#endif /* GL_IMG_read_format */ -/* GL_IMG_shader_binary */ #ifndef GL_IMG_shader_binary #define GL_IMG_shader_binary 1 -#endif +#define GL_SGX_BINARY_IMG 0x8C0A +#endif /* GL_IMG_shader_binary */ -/* GL_IMG_texture_compression_pvrtc */ #ifndef GL_IMG_texture_compression_pvrtc #define GL_IMG_texture_compression_pvrtc 1 -#endif +#define GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG 0x8C00 +#define GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG 0x8C01 +#define GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG 0x8C02 +#define GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG 0x8C03 +#endif /* GL_IMG_texture_compression_pvrtc */ -/* GL_IMG_texture_compression_pvrtc2 */ #ifndef GL_IMG_texture_compression_pvrtc2 #define GL_IMG_texture_compression_pvrtc2 1 -#endif +#define GL_COMPRESSED_RGBA_PVRTC_2BPPV2_IMG 0x9137 +#define GL_COMPRESSED_RGBA_PVRTC_4BPPV2_IMG 0x9138 +#endif /* GL_IMG_texture_compression_pvrtc2 */ -/* GL_IMG_multisampled_render_to_texture */ -#ifndef GL_IMG_multisampled_render_to_texture -#define GL_IMG_multisampled_render_to_texture 1 +#ifndef GL_INTEL_framebuffer_CMAA +#define GL_INTEL_framebuffer_CMAA 1 +typedef void (GL_APIENTRYP PFNGLAPPLYFRAMEBUFFERATTACHMENTCMAAINTELPROC) (void); #ifdef GL_GLEXT_PROTOTYPES -GL_APICALL void GL_APIENTRY glRenderbufferStorageMultisampleIMG (GLenum, GLsizei, GLenum, GLsizei, GLsizei); -GL_APICALL void GL_APIENTRY glFramebufferTexture2DMultisampleIMG (GLenum, GLenum, GLenum, GLuint, GLint, GLsizei); -#endif -typedef void (GL_APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEIMGPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); -typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEIMGPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples); +GL_APICALL void GL_APIENTRY glApplyFramebufferAttachmentCMAAINTEL (void); +#endif +#endif /* GL_INTEL_framebuffer_CMAA */ + +#ifndef GL_INTEL_performance_query +#define GL_INTEL_performance_query 1 +#define GL_PERFQUERY_SINGLE_CONTEXT_INTEL 0x00000000 +#define GL_PERFQUERY_GLOBAL_CONTEXT_INTEL 0x00000001 +#define GL_PERFQUERY_WAIT_INTEL 0x83FB +#define GL_PERFQUERY_FLUSH_INTEL 0x83FA +#define GL_PERFQUERY_DONOT_FLUSH_INTEL 0x83F9 +#define GL_PERFQUERY_COUNTER_EVENT_INTEL 0x94F0 +#define GL_PERFQUERY_COUNTER_DURATION_NORM_INTEL 0x94F1 +#define GL_PERFQUERY_COUNTER_DURATION_RAW_INTEL 0x94F2 +#define GL_PERFQUERY_COUNTER_THROUGHPUT_INTEL 0x94F3 +#define GL_PERFQUERY_COUNTER_RAW_INTEL 0x94F4 +#define GL_PERFQUERY_COUNTER_TIMESTAMP_INTEL 0x94F5 +#define GL_PERFQUERY_COUNTER_DATA_UINT32_INTEL 0x94F8 +#define GL_PERFQUERY_COUNTER_DATA_UINT64_INTEL 0x94F9 +#define GL_PERFQUERY_COUNTER_DATA_FLOAT_INTEL 0x94FA +#define GL_PERFQUERY_COUNTER_DATA_DOUBLE_INTEL 0x94FB +#define GL_PERFQUERY_COUNTER_DATA_BOOL32_INTEL 0x94FC +#define GL_PERFQUERY_QUERY_NAME_LENGTH_MAX_INTEL 0x94FD +#define GL_PERFQUERY_COUNTER_NAME_LENGTH_MAX_INTEL 0x94FE +#define GL_PERFQUERY_COUNTER_DESC_LENGTH_MAX_INTEL 0x94FF +#define GL_PERFQUERY_GPA_EXTENDED_COUNTERS_INTEL 0x9500 +typedef void (GL_APIENTRYP PFNGLBEGINPERFQUERYINTELPROC) (GLuint queryHandle); +typedef void (GL_APIENTRYP PFNGLCREATEPERFQUERYINTELPROC) (GLuint queryId, GLuint *queryHandle); +typedef void (GL_APIENTRYP PFNGLDELETEPERFQUERYINTELPROC) (GLuint queryHandle); +typedef void (GL_APIENTRYP PFNGLENDPERFQUERYINTELPROC) (GLuint queryHandle); +typedef void (GL_APIENTRYP PFNGLGETFIRSTPERFQUERYIDINTELPROC) (GLuint *queryId); +typedef void (GL_APIENTRYP PFNGLGETNEXTPERFQUERYIDINTELPROC) (GLuint queryId, GLuint *nextQueryId); +typedef void (GL_APIENTRYP PFNGLGETPERFCOUNTERINFOINTELPROC) (GLuint queryId, GLuint counterId, GLuint counterNameLength, GLchar *counterName, GLuint counterDescLength, GLchar *counterDesc, GLuint *counterOffset, GLuint *counterDataSize, GLuint *counterTypeEnum, GLuint *counterDataTypeEnum, GLuint64 *rawCounterMaxValue); +typedef void (GL_APIENTRYP PFNGLGETPERFQUERYDATAINTELPROC) (GLuint queryHandle, GLuint flags, GLsizei dataSize, GLvoid *data, GLuint *bytesWritten); +typedef void (GL_APIENTRYP PFNGLGETPERFQUERYIDBYNAMEINTELPROC) (GLchar *queryName, GLuint *queryId); +typedef void (GL_APIENTRYP PFNGLGETPERFQUERYINFOINTELPROC) (GLuint queryId, GLuint queryNameLength, GLchar *queryName, GLuint *dataSize, GLuint *noCounters, GLuint *noInstances, GLuint *capsMask); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glBeginPerfQueryINTEL (GLuint queryHandle); +GL_APICALL void GL_APIENTRY glCreatePerfQueryINTEL (GLuint queryId, GLuint *queryHandle); +GL_APICALL void GL_APIENTRY glDeletePerfQueryINTEL (GLuint queryHandle); +GL_APICALL void GL_APIENTRY glEndPerfQueryINTEL (GLuint queryHandle); +GL_APICALL void GL_APIENTRY glGetFirstPerfQueryIdINTEL (GLuint *queryId); +GL_APICALL void GL_APIENTRY glGetNextPerfQueryIdINTEL (GLuint queryId, GLuint *nextQueryId); +GL_APICALL void GL_APIENTRY glGetPerfCounterInfoINTEL (GLuint queryId, GLuint counterId, GLuint counterNameLength, GLchar *counterName, GLuint counterDescLength, GLchar *counterDesc, GLuint *counterOffset, GLuint *counterDataSize, GLuint *counterTypeEnum, GLuint *counterDataTypeEnum, GLuint64 *rawCounterMaxValue); +GL_APICALL void GL_APIENTRY glGetPerfQueryDataINTEL (GLuint queryHandle, GLuint flags, GLsizei dataSize, GLvoid *data, GLuint *bytesWritten); +GL_APICALL void GL_APIENTRY glGetPerfQueryIdByNameINTEL (GLchar *queryName, GLuint *queryId); +GL_APICALL void GL_APIENTRY glGetPerfQueryInfoINTEL (GLuint queryId, GLuint queryNameLength, GLchar *queryName, GLuint *dataSize, GLuint *noCounters, GLuint *noInstances, GLuint *capsMask); +#endif +#endif /* GL_INTEL_performance_query */ + +#ifndef GL_NV_bindless_texture +#define GL_NV_bindless_texture 1 +typedef GLuint64 (GL_APIENTRYP PFNGLGETTEXTUREHANDLENVPROC) (GLuint texture); +typedef GLuint64 (GL_APIENTRYP PFNGLGETTEXTURESAMPLERHANDLENVPROC) (GLuint texture, GLuint sampler); +typedef void (GL_APIENTRYP PFNGLMAKETEXTUREHANDLERESIDENTNVPROC) (GLuint64 handle); +typedef void (GL_APIENTRYP PFNGLMAKETEXTUREHANDLENONRESIDENTNVPROC) (GLuint64 handle); +typedef GLuint64 (GL_APIENTRYP PFNGLGETIMAGEHANDLENVPROC) (GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum format); +typedef void (GL_APIENTRYP PFNGLMAKEIMAGEHANDLERESIDENTNVPROC) (GLuint64 handle, GLenum access); +typedef void (GL_APIENTRYP PFNGLMAKEIMAGEHANDLENONRESIDENTNVPROC) (GLuint64 handle); +typedef void (GL_APIENTRYP PFNGLUNIFORMHANDLEUI64NVPROC) (GLint location, GLuint64 value); +typedef void (GL_APIENTRYP PFNGLUNIFORMHANDLEUI64VNVPROC) (GLint location, GLsizei count, const GLuint64 *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORMHANDLEUI64NVPROC) (GLuint program, GLint location, GLuint64 value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORMHANDLEUI64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLuint64 *values); +typedef GLboolean (GL_APIENTRYP PFNGLISTEXTUREHANDLERESIDENTNVPROC) (GLuint64 handle); +typedef GLboolean (GL_APIENTRYP PFNGLISIMAGEHANDLERESIDENTNVPROC) (GLuint64 handle); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL GLuint64 GL_APIENTRY glGetTextureHandleNV (GLuint texture); +GL_APICALL GLuint64 GL_APIENTRY glGetTextureSamplerHandleNV (GLuint texture, GLuint sampler); +GL_APICALL void GL_APIENTRY glMakeTextureHandleResidentNV (GLuint64 handle); +GL_APICALL void GL_APIENTRY glMakeTextureHandleNonResidentNV (GLuint64 handle); +GL_APICALL GLuint64 GL_APIENTRY glGetImageHandleNV (GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum format); +GL_APICALL void GL_APIENTRY glMakeImageHandleResidentNV (GLuint64 handle, GLenum access); +GL_APICALL void GL_APIENTRY glMakeImageHandleNonResidentNV (GLuint64 handle); +GL_APICALL void GL_APIENTRY glUniformHandleui64NV (GLint location, GLuint64 value); +GL_APICALL void GL_APIENTRY glUniformHandleui64vNV (GLint location, GLsizei count, const GLuint64 *value); +GL_APICALL void GL_APIENTRY glProgramUniformHandleui64NV (GLuint program, GLint location, GLuint64 value); +GL_APICALL void GL_APIENTRY glProgramUniformHandleui64vNV (GLuint program, GLint location, GLsizei count, const GLuint64 *values); +GL_APICALL GLboolean GL_APIENTRY glIsTextureHandleResidentNV (GLuint64 handle); +GL_APICALL GLboolean GL_APIENTRY glIsImageHandleResidentNV (GLuint64 handle); +#endif +#endif /* GL_NV_bindless_texture */ + +#ifndef GL_NV_blend_equation_advanced +#define GL_NV_blend_equation_advanced 1 +#define GL_BLEND_OVERLAP_NV 0x9281 +#define GL_BLEND_PREMULTIPLIED_SRC_NV 0x9280 +#define GL_BLUE_NV 0x1905 +#define GL_COLORBURN_NV 0x929A +#define GL_COLORDODGE_NV 0x9299 +#define GL_CONJOINT_NV 0x9284 +#define GL_CONTRAST_NV 0x92A1 +#define GL_DARKEN_NV 0x9297 +#define GL_DIFFERENCE_NV 0x929E +#define GL_DISJOINT_NV 0x9283 +#define GL_DST_ATOP_NV 0x928F +#define GL_DST_IN_NV 0x928B +#define GL_DST_NV 0x9287 +#define GL_DST_OUT_NV 0x928D +#define GL_DST_OVER_NV 0x9289 +#define GL_EXCLUSION_NV 0x92A0 +#define GL_GREEN_NV 0x1904 +#define GL_HARDLIGHT_NV 0x929B +#define GL_HARDMIX_NV 0x92A9 +#define GL_HSL_COLOR_NV 0x92AF +#define GL_HSL_HUE_NV 0x92AD +#define GL_HSL_LUMINOSITY_NV 0x92B0 +#define GL_HSL_SATURATION_NV 0x92AE +#define GL_INVERT_OVG_NV 0x92B4 +#define GL_INVERT_RGB_NV 0x92A3 +#define GL_LIGHTEN_NV 0x9298 +#define GL_LINEARBURN_NV 0x92A5 +#define GL_LINEARDODGE_NV 0x92A4 +#define GL_LINEARLIGHT_NV 0x92A7 +#define GL_MINUS_CLAMPED_NV 0x92B3 +#define GL_MINUS_NV 0x929F +#define GL_MULTIPLY_NV 0x9294 +#define GL_OVERLAY_NV 0x9296 +#define GL_PINLIGHT_NV 0x92A8 +#define GL_PLUS_CLAMPED_ALPHA_NV 0x92B2 +#define GL_PLUS_CLAMPED_NV 0x92B1 +#define GL_PLUS_DARKER_NV 0x9292 +#define GL_PLUS_NV 0x9291 +#define GL_RED_NV 0x1903 +#define GL_SCREEN_NV 0x9295 +#define GL_SOFTLIGHT_NV 0x929C +#define GL_SRC_ATOP_NV 0x928E +#define GL_SRC_IN_NV 0x928A +#define GL_SRC_NV 0x9286 +#define GL_SRC_OUT_NV 0x928C +#define GL_SRC_OVER_NV 0x9288 +#define GL_UNCORRELATED_NV 0x9282 +#define GL_VIVIDLIGHT_NV 0x92A6 +#define GL_XOR_NV 0x1506 +typedef void (GL_APIENTRYP PFNGLBLENDPARAMETERINVPROC) (GLenum pname, GLint value); +typedef void (GL_APIENTRYP PFNGLBLENDBARRIERNVPROC) (void); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glBlendParameteriNV (GLenum pname, GLint value); +GL_APICALL void GL_APIENTRY glBlendBarrierNV (void); +#endif +#endif /* GL_NV_blend_equation_advanced */ + +#ifndef GL_NV_blend_equation_advanced_coherent +#define GL_NV_blend_equation_advanced_coherent 1 +#define GL_BLEND_ADVANCED_COHERENT_NV 0x9285 +#endif /* GL_NV_blend_equation_advanced_coherent */ + +#ifndef GL_NV_conditional_render +#define GL_NV_conditional_render 1 +#define GL_QUERY_WAIT_NV 0x8E13 +#define GL_QUERY_NO_WAIT_NV 0x8E14 +#define GL_QUERY_BY_REGION_WAIT_NV 0x8E15 +#define GL_QUERY_BY_REGION_NO_WAIT_NV 0x8E16 +typedef void (GL_APIENTRYP PFNGLBEGINCONDITIONALRENDERNVPROC) (GLuint id, GLenum mode); +typedef void (GL_APIENTRYP PFNGLENDCONDITIONALRENDERNVPROC) (void); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glBeginConditionalRenderNV (GLuint id, GLenum mode); +GL_APICALL void GL_APIENTRY glEndConditionalRenderNV (void); +#endif +#endif /* GL_NV_conditional_render */ + +#ifndef GL_NV_conservative_raster +#define GL_NV_conservative_raster 1 +#define GL_CONSERVATIVE_RASTERIZATION_NV 0x9346 +#define GL_SUBPIXEL_PRECISION_BIAS_X_BITS_NV 0x9347 +#define GL_SUBPIXEL_PRECISION_BIAS_Y_BITS_NV 0x9348 +#define GL_MAX_SUBPIXEL_PRECISION_BIAS_BITS_NV 0x9349 +typedef void (GL_APIENTRYP PFNGLSUBPIXELPRECISIONBIASNVPROC) (GLuint xbits, GLuint ybits); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glSubpixelPrecisionBiasNV (GLuint xbits, GLuint ybits); #endif +#endif /* GL_NV_conservative_raster */ -/*------------------------------------------------------------------------* - * NV extension functions - *------------------------------------------------------------------------*/ +#ifndef GL_NV_copy_buffer +#define GL_NV_copy_buffer 1 +#define GL_COPY_READ_BUFFER_NV 0x8F36 +#define GL_COPY_WRITE_BUFFER_NV 0x8F37 +typedef void (GL_APIENTRYP PFNGLCOPYBUFFERSUBDATANVPROC) (GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glCopyBufferSubDataNV (GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); +#endif +#endif /* GL_NV_copy_buffer */ -/* GL_NV_coverage_sample */ #ifndef GL_NV_coverage_sample #define GL_NV_coverage_sample 1 +#define GL_COVERAGE_COMPONENT_NV 0x8ED0 +#define GL_COVERAGE_COMPONENT4_NV 0x8ED1 +#define GL_COVERAGE_ATTACHMENT_NV 0x8ED2 +#define GL_COVERAGE_BUFFERS_NV 0x8ED3 +#define GL_COVERAGE_SAMPLES_NV 0x8ED4 +#define GL_COVERAGE_ALL_FRAGMENTS_NV 0x8ED5 +#define GL_COVERAGE_EDGE_FRAGMENTS_NV 0x8ED6 +#define GL_COVERAGE_AUTOMATIC_NV 0x8ED7 +#define GL_COVERAGE_BUFFER_BIT_NV 0x00008000 +typedef void (GL_APIENTRYP PFNGLCOVERAGEMASKNVPROC) (GLboolean mask); +typedef void (GL_APIENTRYP PFNGLCOVERAGEOPERATIONNVPROC) (GLenum operation); #ifdef GL_GLEXT_PROTOTYPES GL_APICALL void GL_APIENTRY glCoverageMaskNV (GLboolean mask); GL_APICALL void GL_APIENTRY glCoverageOperationNV (GLenum operation); #endif -typedef void (GL_APIENTRYP PFNGLCOVERAGEMASKNVPROC) (GLboolean mask); -typedef void (GL_APIENTRYP PFNGLCOVERAGEOPERATIONNVPROC) (GLenum operation); -#endif +#endif /* GL_NV_coverage_sample */ -/* GL_NV_depth_nonlinear */ #ifndef GL_NV_depth_nonlinear #define GL_NV_depth_nonlinear 1 -#endif +#define GL_DEPTH_COMPONENT16_NONLINEAR_NV 0x8E2C +#endif /* GL_NV_depth_nonlinear */ -/* GL_NV_draw_buffers */ #ifndef GL_NV_draw_buffers #define GL_NV_draw_buffers 1 -#ifdef GL_GLEXT_PROTOTYPES -GL_APICALL void GL_APIENTRY glDrawBuffersNV (GLsizei n, const GLenum *bufs); -#endif +#define GL_MAX_DRAW_BUFFERS_NV 0x8824 +#define GL_DRAW_BUFFER0_NV 0x8825 +#define GL_DRAW_BUFFER1_NV 0x8826 +#define GL_DRAW_BUFFER2_NV 0x8827 +#define GL_DRAW_BUFFER3_NV 0x8828 +#define GL_DRAW_BUFFER4_NV 0x8829 +#define GL_DRAW_BUFFER5_NV 0x882A +#define GL_DRAW_BUFFER6_NV 0x882B +#define GL_DRAW_BUFFER7_NV 0x882C +#define GL_DRAW_BUFFER8_NV 0x882D +#define GL_DRAW_BUFFER9_NV 0x882E +#define GL_DRAW_BUFFER10_NV 0x882F +#define GL_DRAW_BUFFER11_NV 0x8830 +#define GL_DRAW_BUFFER12_NV 0x8831 +#define GL_DRAW_BUFFER13_NV 0x8832 +#define GL_DRAW_BUFFER14_NV 0x8833 +#define GL_DRAW_BUFFER15_NV 0x8834 +#define GL_COLOR_ATTACHMENT0_NV 0x8CE0 +#define GL_COLOR_ATTACHMENT1_NV 0x8CE1 +#define GL_COLOR_ATTACHMENT2_NV 0x8CE2 +#define GL_COLOR_ATTACHMENT3_NV 0x8CE3 +#define GL_COLOR_ATTACHMENT4_NV 0x8CE4 +#define GL_COLOR_ATTACHMENT5_NV 0x8CE5 +#define GL_COLOR_ATTACHMENT6_NV 0x8CE6 +#define GL_COLOR_ATTACHMENT7_NV 0x8CE7 +#define GL_COLOR_ATTACHMENT8_NV 0x8CE8 +#define GL_COLOR_ATTACHMENT9_NV 0x8CE9 +#define GL_COLOR_ATTACHMENT10_NV 0x8CEA +#define GL_COLOR_ATTACHMENT11_NV 0x8CEB +#define GL_COLOR_ATTACHMENT12_NV 0x8CEC +#define GL_COLOR_ATTACHMENT13_NV 0x8CED +#define GL_COLOR_ATTACHMENT14_NV 0x8CEE +#define GL_COLOR_ATTACHMENT15_NV 0x8CEF typedef void (GL_APIENTRYP PFNGLDRAWBUFFERSNVPROC) (GLsizei n, const GLenum *bufs); -#endif - -/* GL_EXT_draw_buffers */ -#ifndef GL_EXT_draw_buffers -#define GL_EXT_draw_buffers 1 #ifdef GL_GLEXT_PROTOTYPES -GL_APICALL void GL_APIENTRY glDrawBuffersEXT (GLsizei n, const GLenum *bufs); -#endif -typedef void (GL_APIENTRYP PFNGLDRAWBUFFERSEXTPROC) (GLsizei n, const GLenum *bufs); +GL_APICALL void GL_APIENTRY glDrawBuffersNV (GLsizei n, const GLenum *bufs); #endif +#endif /* GL_NV_draw_buffers */ -/* GL_NV_draw_instanced */ #ifndef GL_NV_draw_instanced #define GL_NV_draw_instanced 1 +typedef void (GL_APIENTRYP PFNGLDRAWARRAYSINSTANCEDNVPROC) (GLenum mode, GLint first, GLsizei count, GLsizei primcount); +typedef void (GL_APIENTRYP PFNGLDRAWELEMENTSINSTANCEDNVPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount); #ifdef GL_GLEXT_PROTOTYPES GL_APICALL void GL_APIENTRY glDrawArraysInstancedNV (GLenum mode, GLint first, GLsizei count, GLsizei primcount); -GL_APICALL void GL_APIENTRY glDrawElementsInstancedNV (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei primcount); -#endif -typedef void (GL_APIENTRYP PFNDRAWARRAYSINSTANCEDNVPROC) (GLenum mode, GLint first, GLsizei count, GLsizei primcount); -typedef void (GL_APIENTRYP PFNDRAWELEMENTSINSTANCEDNVPROC) (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei primcount); +GL_APICALL void GL_APIENTRY glDrawElementsInstancedNV (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount); #endif +#endif /* GL_NV_draw_instanced */ + +#ifndef GL_NV_explicit_attrib_location +#define GL_NV_explicit_attrib_location 1 +#endif /* GL_NV_explicit_attrib_location */ -/* GL_NV_fbo_color_attachments */ #ifndef GL_NV_fbo_color_attachments #define GL_NV_fbo_color_attachments 1 -#endif +#define GL_MAX_COLOR_ATTACHMENTS_NV 0x8CDF +#endif /* GL_NV_fbo_color_attachments */ -/* GL_NV_fence */ #ifndef GL_NV_fence #define GL_NV_fence 1 -#ifdef GL_GLEXT_PROTOTYPES -GL_APICALL void GL_APIENTRY glDeleteFencesNV (GLsizei, const GLuint *); -GL_APICALL void GL_APIENTRY glGenFencesNV (GLsizei, GLuint *); -GL_APICALL GLboolean GL_APIENTRY glIsFenceNV (GLuint); -GL_APICALL GLboolean GL_APIENTRY glTestFenceNV (GLuint); -GL_APICALL void GL_APIENTRY glGetFenceivNV (GLuint, GLenum, GLint *); -GL_APICALL void GL_APIENTRY glFinishFenceNV (GLuint); -GL_APICALL void GL_APIENTRY glSetFenceNV (GLuint, GLenum); -#endif +#define GL_ALL_COMPLETED_NV 0x84F2 +#define GL_FENCE_STATUS_NV 0x84F3 +#define GL_FENCE_CONDITION_NV 0x84F4 typedef void (GL_APIENTRYP PFNGLDELETEFENCESNVPROC) (GLsizei n, const GLuint *fences); typedef void (GL_APIENTRYP PFNGLGENFENCESNVPROC) (GLsizei n, GLuint *fences); typedef GLboolean (GL_APIENTRYP PFNGLISFENCENVPROC) (GLuint fence); @@ -1812,135 +2215,628 @@ typedef GLboolean (GL_APIENTRYP PFNGLTESTFENCENVPROC) (GLuint fence); typedef void (GL_APIENTRYP PFNGLGETFENCEIVNVPROC) (GLuint fence, GLenum pname, GLint *params); typedef void (GL_APIENTRYP PFNGLFINISHFENCENVPROC) (GLuint fence); typedef void (GL_APIENTRYP PFNGLSETFENCENVPROC) (GLuint fence, GLenum condition); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glDeleteFencesNV (GLsizei n, const GLuint *fences); +GL_APICALL void GL_APIENTRY glGenFencesNV (GLsizei n, GLuint *fences); +GL_APICALL GLboolean GL_APIENTRY glIsFenceNV (GLuint fence); +GL_APICALL GLboolean GL_APIENTRY glTestFenceNV (GLuint fence); +GL_APICALL void GL_APIENTRY glGetFenceivNV (GLuint fence, GLenum pname, GLint *params); +GL_APICALL void GL_APIENTRY glFinishFenceNV (GLuint fence); +GL_APICALL void GL_APIENTRY glSetFenceNV (GLuint fence, GLenum condition); +#endif +#endif /* GL_NV_fence */ + +#ifndef GL_NV_fill_rectangle +#define GL_NV_fill_rectangle 1 +#define GL_FILL_RECTANGLE_NV 0x933C +#endif /* GL_NV_fill_rectangle */ + +#ifndef GL_NV_fragment_coverage_to_color +#define GL_NV_fragment_coverage_to_color 1 +#define GL_FRAGMENT_COVERAGE_TO_COLOR_NV 0x92DD +#define GL_FRAGMENT_COVERAGE_COLOR_NV 0x92DE +typedef void (GL_APIENTRYP PFNGLFRAGMENTCOVERAGECOLORNVPROC) (GLuint color); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glFragmentCoverageColorNV (GLuint color); #endif +#endif /* GL_NV_fragment_coverage_to_color */ + +#ifndef GL_NV_fragment_shader_interlock +#define GL_NV_fragment_shader_interlock 1 +#endif /* GL_NV_fragment_shader_interlock */ -/* GL_NV_framebuffer_blit */ #ifndef GL_NV_framebuffer_blit #define GL_NV_framebuffer_blit 1 +#define GL_READ_FRAMEBUFFER_NV 0x8CA8 +#define GL_DRAW_FRAMEBUFFER_NV 0x8CA9 +#define GL_DRAW_FRAMEBUFFER_BINDING_NV 0x8CA6 +#define GL_READ_FRAMEBUFFER_BINDING_NV 0x8CAA +typedef void (GL_APIENTRYP PFNGLBLITFRAMEBUFFERNVPROC) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); #ifdef GL_GLEXT_PROTOTYPES -GL_APICALL void GL_APIENTRY glBlitFramebufferNV (int srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); -#endif -typedef void (GL_APIENTRYP PFNBLITFRAMEBUFFERNVPROC) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); +GL_APICALL void GL_APIENTRY glBlitFramebufferNV (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); +#endif +#endif /* GL_NV_framebuffer_blit */ + +#ifndef GL_NV_framebuffer_mixed_samples +#define GL_NV_framebuffer_mixed_samples 1 +#define GL_COVERAGE_MODULATION_TABLE_NV 0x9331 +#define GL_COLOR_SAMPLES_NV 0x8E20 +#define GL_DEPTH_SAMPLES_NV 0x932D +#define GL_STENCIL_SAMPLES_NV 0x932E +#define GL_MIXED_DEPTH_SAMPLES_SUPPORTED_NV 0x932F +#define GL_MIXED_STENCIL_SAMPLES_SUPPORTED_NV 0x9330 +#define GL_COVERAGE_MODULATION_NV 0x9332 +#define GL_COVERAGE_MODULATION_TABLE_SIZE_NV 0x9333 +typedef void (GL_APIENTRYP PFNGLCOVERAGEMODULATIONTABLENVPROC) (GLsizei n, const GLfloat *v); +typedef void (GL_APIENTRYP PFNGLGETCOVERAGEMODULATIONTABLENVPROC) (GLsizei bufsize, GLfloat *v); +typedef void (GL_APIENTRYP PFNGLCOVERAGEMODULATIONNVPROC) (GLenum components); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glCoverageModulationTableNV (GLsizei n, const GLfloat *v); +GL_APICALL void GL_APIENTRY glGetCoverageModulationTableNV (GLsizei bufsize, GLfloat *v); +GL_APICALL void GL_APIENTRY glCoverageModulationNV (GLenum components); #endif +#endif /* GL_NV_framebuffer_mixed_samples */ -/* GL_NV_framebuffer_multisample */ #ifndef GL_NV_framebuffer_multisample #define GL_NV_framebuffer_multisample 1 +#define GL_RENDERBUFFER_SAMPLES_NV 0x8CAB +#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_NV 0x8D56 +#define GL_MAX_SAMPLES_NV 0x8D57 +typedef void (GL_APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLENVPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); #ifdef GL_GLEXT_PROTOTYPES -GL_APICALL void GL_APIENTRY glRenderbufferStorageMultisampleNV ( GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); -#endif -typedef void (GL_APIENTRYP PFNRENDERBUFFERSTORAGEMULTISAMPLENVPROC) ( GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +GL_APICALL void GL_APIENTRY glRenderbufferStorageMultisampleNV (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); #endif +#endif /* GL_NV_framebuffer_multisample */ -/* GL_NV_generate_mipmap_sRGB */ #ifndef GL_NV_generate_mipmap_sRGB #define GL_NV_generate_mipmap_sRGB 1 -#endif +#endif /* GL_NV_generate_mipmap_sRGB */ + +#ifndef GL_NV_geometry_shader_passthrough +#define GL_NV_geometry_shader_passthrough 1 +#endif /* GL_NV_geometry_shader_passthrough */ + +#ifndef GL_NV_image_formats +#define GL_NV_image_formats 1 +#endif /* GL_NV_image_formats */ -/* GL_NV_instanced_arrays */ #ifndef GL_NV_instanced_arrays #define GL_NV_instanced_arrays 1 +#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR_NV 0x88FE +typedef void (GL_APIENTRYP PFNGLVERTEXATTRIBDIVISORNVPROC) (GLuint index, GLuint divisor); #ifdef GL_GLEXT_PROTOTYPES GL_APICALL void GL_APIENTRY glVertexAttribDivisorNV (GLuint index, GLuint divisor); #endif -typedef void (GL_APIENTRYP PFNVERTEXATTRIBDIVISORNVPROC) (GLuint index, GLuint divisor); +#endif /* GL_NV_instanced_arrays */ + +#ifndef GL_NV_internalformat_sample_query +#define GL_NV_internalformat_sample_query 1 +#define GL_TEXTURE_2D_MULTISAMPLE 0x9100 +#define GL_TEXTURE_2D_MULTISAMPLE_ARRAY 0x9102 +#define GL_MULTISAMPLES_NV 0x9371 +#define GL_SUPERSAMPLE_SCALE_X_NV 0x9372 +#define GL_SUPERSAMPLE_SCALE_Y_NV 0x9373 +#define GL_CONFORMANT_NV 0x9374 +typedef void (GL_APIENTRYP PFNGLGETINTERNALFORMATSAMPLEIVNVPROC) (GLenum target, GLenum internalformat, GLsizei samples, GLenum pname, GLsizei bufSize, GLint *params); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glGetInternalformatSampleivNV (GLenum target, GLenum internalformat, GLsizei samples, GLenum pname, GLsizei bufSize, GLint *params); +#endif +#endif /* GL_NV_internalformat_sample_query */ + +#ifndef GL_NV_non_square_matrices +#define GL_NV_non_square_matrices 1 +#define GL_FLOAT_MAT2x3_NV 0x8B65 +#define GL_FLOAT_MAT2x4_NV 0x8B66 +#define GL_FLOAT_MAT3x2_NV 0x8B67 +#define GL_FLOAT_MAT3x4_NV 0x8B68 +#define GL_FLOAT_MAT4x2_NV 0x8B69 +#define GL_FLOAT_MAT4x3_NV 0x8B6A +typedef void (GL_APIENTRYP PFNGLUNIFORMMATRIX2X3FVNVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLUNIFORMMATRIX3X2FVNVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLUNIFORMMATRIX2X4FVNVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLUNIFORMMATRIX4X2FVNVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLUNIFORMMATRIX3X4FVNVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLUNIFORMMATRIX4X3FVNVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glUniformMatrix2x3fvNV (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GL_APICALL void GL_APIENTRY glUniformMatrix3x2fvNV (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GL_APICALL void GL_APIENTRY glUniformMatrix2x4fvNV (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GL_APICALL void GL_APIENTRY glUniformMatrix4x2fvNV (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GL_APICALL void GL_APIENTRY glUniformMatrix3x4fvNV (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GL_APICALL void GL_APIENTRY glUniformMatrix4x3fvNV (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +#endif +#endif /* GL_NV_non_square_matrices */ + +#ifndef GL_NV_path_rendering +#define GL_NV_path_rendering 1 +#define GL_PATH_FORMAT_SVG_NV 0x9070 +#define GL_PATH_FORMAT_PS_NV 0x9071 +#define GL_STANDARD_FONT_NAME_NV 0x9072 +#define GL_SYSTEM_FONT_NAME_NV 0x9073 +#define GL_FILE_NAME_NV 0x9074 +#define GL_PATH_STROKE_WIDTH_NV 0x9075 +#define GL_PATH_END_CAPS_NV 0x9076 +#define GL_PATH_INITIAL_END_CAP_NV 0x9077 +#define GL_PATH_TERMINAL_END_CAP_NV 0x9078 +#define GL_PATH_JOIN_STYLE_NV 0x9079 +#define GL_PATH_MITER_LIMIT_NV 0x907A +#define GL_PATH_DASH_CAPS_NV 0x907B +#define GL_PATH_INITIAL_DASH_CAP_NV 0x907C +#define GL_PATH_TERMINAL_DASH_CAP_NV 0x907D +#define GL_PATH_DASH_OFFSET_NV 0x907E +#define GL_PATH_CLIENT_LENGTH_NV 0x907F +#define GL_PATH_FILL_MODE_NV 0x9080 +#define GL_PATH_FILL_MASK_NV 0x9081 +#define GL_PATH_FILL_COVER_MODE_NV 0x9082 +#define GL_PATH_STROKE_COVER_MODE_NV 0x9083 +#define GL_PATH_STROKE_MASK_NV 0x9084 +#define GL_COUNT_UP_NV 0x9088 +#define GL_COUNT_DOWN_NV 0x9089 +#define GL_PATH_OBJECT_BOUNDING_BOX_NV 0x908A +#define GL_CONVEX_HULL_NV 0x908B +#define GL_BOUNDING_BOX_NV 0x908D +#define GL_TRANSLATE_X_NV 0x908E +#define GL_TRANSLATE_Y_NV 0x908F +#define GL_TRANSLATE_2D_NV 0x9090 +#define GL_TRANSLATE_3D_NV 0x9091 +#define GL_AFFINE_2D_NV 0x9092 +#define GL_AFFINE_3D_NV 0x9094 +#define GL_TRANSPOSE_AFFINE_2D_NV 0x9096 +#define GL_TRANSPOSE_AFFINE_3D_NV 0x9098 +#define GL_UTF8_NV 0x909A +#define GL_UTF16_NV 0x909B +#define GL_BOUNDING_BOX_OF_BOUNDING_BOXES_NV 0x909C +#define GL_PATH_COMMAND_COUNT_NV 0x909D +#define GL_PATH_COORD_COUNT_NV 0x909E +#define GL_PATH_DASH_ARRAY_COUNT_NV 0x909F +#define GL_PATH_COMPUTED_LENGTH_NV 0x90A0 +#define GL_PATH_FILL_BOUNDING_BOX_NV 0x90A1 +#define GL_PATH_STROKE_BOUNDING_BOX_NV 0x90A2 +#define GL_SQUARE_NV 0x90A3 +#define GL_ROUND_NV 0x90A4 +#define GL_TRIANGULAR_NV 0x90A5 +#define GL_BEVEL_NV 0x90A6 +#define GL_MITER_REVERT_NV 0x90A7 +#define GL_MITER_TRUNCATE_NV 0x90A8 +#define GL_SKIP_MISSING_GLYPH_NV 0x90A9 +#define GL_USE_MISSING_GLYPH_NV 0x90AA +#define GL_PATH_ERROR_POSITION_NV 0x90AB +#define GL_ACCUM_ADJACENT_PAIRS_NV 0x90AD +#define GL_ADJACENT_PAIRS_NV 0x90AE +#define GL_FIRST_TO_REST_NV 0x90AF +#define GL_PATH_GEN_MODE_NV 0x90B0 +#define GL_PATH_GEN_COEFF_NV 0x90B1 +#define GL_PATH_GEN_COMPONENTS_NV 0x90B3 +#define GL_PATH_STENCIL_FUNC_NV 0x90B7 +#define GL_PATH_STENCIL_REF_NV 0x90B8 +#define GL_PATH_STENCIL_VALUE_MASK_NV 0x90B9 +#define GL_PATH_STENCIL_DEPTH_OFFSET_FACTOR_NV 0x90BD +#define GL_PATH_STENCIL_DEPTH_OFFSET_UNITS_NV 0x90BE +#define GL_PATH_COVER_DEPTH_FUNC_NV 0x90BF +#define GL_PATH_DASH_OFFSET_RESET_NV 0x90B4 +#define GL_MOVE_TO_RESETS_NV 0x90B5 +#define GL_MOVE_TO_CONTINUES_NV 0x90B6 +#define GL_CLOSE_PATH_NV 0x00 +#define GL_MOVE_TO_NV 0x02 +#define GL_RELATIVE_MOVE_TO_NV 0x03 +#define GL_LINE_TO_NV 0x04 +#define GL_RELATIVE_LINE_TO_NV 0x05 +#define GL_HORIZONTAL_LINE_TO_NV 0x06 +#define GL_RELATIVE_HORIZONTAL_LINE_TO_NV 0x07 +#define GL_VERTICAL_LINE_TO_NV 0x08 +#define GL_RELATIVE_VERTICAL_LINE_TO_NV 0x09 +#define GL_QUADRATIC_CURVE_TO_NV 0x0A +#define GL_RELATIVE_QUADRATIC_CURVE_TO_NV 0x0B +#define GL_CUBIC_CURVE_TO_NV 0x0C +#define GL_RELATIVE_CUBIC_CURVE_TO_NV 0x0D +#define GL_SMOOTH_QUADRATIC_CURVE_TO_NV 0x0E +#define GL_RELATIVE_SMOOTH_QUADRATIC_CURVE_TO_NV 0x0F +#define GL_SMOOTH_CUBIC_CURVE_TO_NV 0x10 +#define GL_RELATIVE_SMOOTH_CUBIC_CURVE_TO_NV 0x11 +#define GL_SMALL_CCW_ARC_TO_NV 0x12 +#define GL_RELATIVE_SMALL_CCW_ARC_TO_NV 0x13 +#define GL_SMALL_CW_ARC_TO_NV 0x14 +#define GL_RELATIVE_SMALL_CW_ARC_TO_NV 0x15 +#define GL_LARGE_CCW_ARC_TO_NV 0x16 +#define GL_RELATIVE_LARGE_CCW_ARC_TO_NV 0x17 +#define GL_LARGE_CW_ARC_TO_NV 0x18 +#define GL_RELATIVE_LARGE_CW_ARC_TO_NV 0x19 +#define GL_RESTART_PATH_NV 0xF0 +#define GL_DUP_FIRST_CUBIC_CURVE_TO_NV 0xF2 +#define GL_DUP_LAST_CUBIC_CURVE_TO_NV 0xF4 +#define GL_RECT_NV 0xF6 +#define GL_CIRCULAR_CCW_ARC_TO_NV 0xF8 +#define GL_CIRCULAR_CW_ARC_TO_NV 0xFA +#define GL_CIRCULAR_TANGENT_ARC_TO_NV 0xFC +#define GL_ARC_TO_NV 0xFE +#define GL_RELATIVE_ARC_TO_NV 0xFF +#define GL_BOLD_BIT_NV 0x01 +#define GL_ITALIC_BIT_NV 0x02 +#define GL_GLYPH_WIDTH_BIT_NV 0x01 +#define GL_GLYPH_HEIGHT_BIT_NV 0x02 +#define GL_GLYPH_HORIZONTAL_BEARING_X_BIT_NV 0x04 +#define GL_GLYPH_HORIZONTAL_BEARING_Y_BIT_NV 0x08 +#define GL_GLYPH_HORIZONTAL_BEARING_ADVANCE_BIT_NV 0x10 +#define GL_GLYPH_VERTICAL_BEARING_X_BIT_NV 0x20 +#define GL_GLYPH_VERTICAL_BEARING_Y_BIT_NV 0x40 +#define GL_GLYPH_VERTICAL_BEARING_ADVANCE_BIT_NV 0x80 +#define GL_GLYPH_HAS_KERNING_BIT_NV 0x100 +#define GL_FONT_X_MIN_BOUNDS_BIT_NV 0x00010000 +#define GL_FONT_Y_MIN_BOUNDS_BIT_NV 0x00020000 +#define GL_FONT_X_MAX_BOUNDS_BIT_NV 0x00040000 +#define GL_FONT_Y_MAX_BOUNDS_BIT_NV 0x00080000 +#define GL_FONT_UNITS_PER_EM_BIT_NV 0x00100000 +#define GL_FONT_ASCENDER_BIT_NV 0x00200000 +#define GL_FONT_DESCENDER_BIT_NV 0x00400000 +#define GL_FONT_HEIGHT_BIT_NV 0x00800000 +#define GL_FONT_MAX_ADVANCE_WIDTH_BIT_NV 0x01000000 +#define GL_FONT_MAX_ADVANCE_HEIGHT_BIT_NV 0x02000000 +#define GL_FONT_UNDERLINE_POSITION_BIT_NV 0x04000000 +#define GL_FONT_UNDERLINE_THICKNESS_BIT_NV 0x08000000 +#define GL_FONT_HAS_KERNING_BIT_NV 0x10000000 +#define GL_ROUNDED_RECT_NV 0xE8 +#define GL_RELATIVE_ROUNDED_RECT_NV 0xE9 +#define GL_ROUNDED_RECT2_NV 0xEA +#define GL_RELATIVE_ROUNDED_RECT2_NV 0xEB +#define GL_ROUNDED_RECT4_NV 0xEC +#define GL_RELATIVE_ROUNDED_RECT4_NV 0xED +#define GL_ROUNDED_RECT8_NV 0xEE +#define GL_RELATIVE_ROUNDED_RECT8_NV 0xEF +#define GL_RELATIVE_RECT_NV 0xF7 +#define GL_FONT_GLYPHS_AVAILABLE_NV 0x9368 +#define GL_FONT_TARGET_UNAVAILABLE_NV 0x9369 +#define GL_FONT_UNAVAILABLE_NV 0x936A +#define GL_FONT_UNINTELLIGIBLE_NV 0x936B +#define GL_CONIC_CURVE_TO_NV 0x1A +#define GL_RELATIVE_CONIC_CURVE_TO_NV 0x1B +#define GL_FONT_NUM_GLYPH_INDICES_BIT_NV 0x20000000 +#define GL_STANDARD_FONT_FORMAT_NV 0x936C +#define GL_PATH_PROJECTION_NV 0x1701 +#define GL_PATH_MODELVIEW_NV 0x1700 +#define GL_PATH_MODELVIEW_STACK_DEPTH_NV 0x0BA3 +#define GL_PATH_MODELVIEW_MATRIX_NV 0x0BA6 +#define GL_PATH_MAX_MODELVIEW_STACK_DEPTH_NV 0x0D36 +#define GL_PATH_TRANSPOSE_MODELVIEW_MATRIX_NV 0x84E3 +#define GL_PATH_PROJECTION_STACK_DEPTH_NV 0x0BA4 +#define GL_PATH_PROJECTION_MATRIX_NV 0x0BA7 +#define GL_PATH_MAX_PROJECTION_STACK_DEPTH_NV 0x0D38 +#define GL_PATH_TRANSPOSE_PROJECTION_MATRIX_NV 0x84E4 +#define GL_FRAGMENT_INPUT_NV 0x936D +typedef GLuint (GL_APIENTRYP PFNGLGENPATHSNVPROC) (GLsizei range); +typedef void (GL_APIENTRYP PFNGLDELETEPATHSNVPROC) (GLuint path, GLsizei range); +typedef GLboolean (GL_APIENTRYP PFNGLISPATHNVPROC) (GLuint path); +typedef void (GL_APIENTRYP PFNGLPATHCOMMANDSNVPROC) (GLuint path, GLsizei numCommands, const GLubyte *commands, GLsizei numCoords, GLenum coordType, const void *coords); +typedef void (GL_APIENTRYP PFNGLPATHCOORDSNVPROC) (GLuint path, GLsizei numCoords, GLenum coordType, const void *coords); +typedef void (GL_APIENTRYP PFNGLPATHSUBCOMMANDSNVPROC) (GLuint path, GLsizei commandStart, GLsizei commandsToDelete, GLsizei numCommands, const GLubyte *commands, GLsizei numCoords, GLenum coordType, const void *coords); +typedef void (GL_APIENTRYP PFNGLPATHSUBCOORDSNVPROC) (GLuint path, GLsizei coordStart, GLsizei numCoords, GLenum coordType, const void *coords); +typedef void (GL_APIENTRYP PFNGLPATHSTRINGNVPROC) (GLuint path, GLenum format, GLsizei length, const void *pathString); +typedef void (GL_APIENTRYP PFNGLPATHGLYPHSNVPROC) (GLuint firstPathName, GLenum fontTarget, const void *fontName, GLbitfield fontStyle, GLsizei numGlyphs, GLenum type, const void *charcodes, GLenum handleMissingGlyphs, GLuint pathParameterTemplate, GLfloat emScale); +typedef void (GL_APIENTRYP PFNGLPATHGLYPHRANGENVPROC) (GLuint firstPathName, GLenum fontTarget, const void *fontName, GLbitfield fontStyle, GLuint firstGlyph, GLsizei numGlyphs, GLenum handleMissingGlyphs, GLuint pathParameterTemplate, GLfloat emScale); +typedef void (GL_APIENTRYP PFNGLWEIGHTPATHSNVPROC) (GLuint resultPath, GLsizei numPaths, const GLuint *paths, const GLfloat *weights); +typedef void (GL_APIENTRYP PFNGLCOPYPATHNVPROC) (GLuint resultPath, GLuint srcPath); +typedef void (GL_APIENTRYP PFNGLINTERPOLATEPATHSNVPROC) (GLuint resultPath, GLuint pathA, GLuint pathB, GLfloat weight); +typedef void (GL_APIENTRYP PFNGLTRANSFORMPATHNVPROC) (GLuint resultPath, GLuint srcPath, GLenum transformType, const GLfloat *transformValues); +typedef void (GL_APIENTRYP PFNGLPATHPARAMETERIVNVPROC) (GLuint path, GLenum pname, const GLint *value); +typedef void (GL_APIENTRYP PFNGLPATHPARAMETERINVPROC) (GLuint path, GLenum pname, GLint value); +typedef void (GL_APIENTRYP PFNGLPATHPARAMETERFVNVPROC) (GLuint path, GLenum pname, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLPATHPARAMETERFNVPROC) (GLuint path, GLenum pname, GLfloat value); +typedef void (GL_APIENTRYP PFNGLPATHDASHARRAYNVPROC) (GLuint path, GLsizei dashCount, const GLfloat *dashArray); +typedef void (GL_APIENTRYP PFNGLPATHSTENCILFUNCNVPROC) (GLenum func, GLint ref, GLuint mask); +typedef void (GL_APIENTRYP PFNGLPATHSTENCILDEPTHOFFSETNVPROC) (GLfloat factor, GLfloat units); +typedef void (GL_APIENTRYP PFNGLSTENCILFILLPATHNVPROC) (GLuint path, GLenum fillMode, GLuint mask); +typedef void (GL_APIENTRYP PFNGLSTENCILSTROKEPATHNVPROC) (GLuint path, GLint reference, GLuint mask); +typedef void (GL_APIENTRYP PFNGLSTENCILFILLPATHINSTANCEDNVPROC) (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLenum fillMode, GLuint mask, GLenum transformType, const GLfloat *transformValues); +typedef void (GL_APIENTRYP PFNGLSTENCILSTROKEPATHINSTANCEDNVPROC) (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLint reference, GLuint mask, GLenum transformType, const GLfloat *transformValues); +typedef void (GL_APIENTRYP PFNGLPATHCOVERDEPTHFUNCNVPROC) (GLenum func); +typedef void (GL_APIENTRYP PFNGLCOVERFILLPATHNVPROC) (GLuint path, GLenum coverMode); +typedef void (GL_APIENTRYP PFNGLCOVERSTROKEPATHNVPROC) (GLuint path, GLenum coverMode); +typedef void (GL_APIENTRYP PFNGLCOVERFILLPATHINSTANCEDNVPROC) (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLenum coverMode, GLenum transformType, const GLfloat *transformValues); +typedef void (GL_APIENTRYP PFNGLCOVERSTROKEPATHINSTANCEDNVPROC) (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLenum coverMode, GLenum transformType, const GLfloat *transformValues); +typedef void (GL_APIENTRYP PFNGLGETPATHPARAMETERIVNVPROC) (GLuint path, GLenum pname, GLint *value); +typedef void (GL_APIENTRYP PFNGLGETPATHPARAMETERFVNVPROC) (GLuint path, GLenum pname, GLfloat *value); +typedef void (GL_APIENTRYP PFNGLGETPATHCOMMANDSNVPROC) (GLuint path, GLubyte *commands); +typedef void (GL_APIENTRYP PFNGLGETPATHCOORDSNVPROC) (GLuint path, GLfloat *coords); +typedef void (GL_APIENTRYP PFNGLGETPATHDASHARRAYNVPROC) (GLuint path, GLfloat *dashArray); +typedef void (GL_APIENTRYP PFNGLGETPATHMETRICSNVPROC) (GLbitfield metricQueryMask, GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLsizei stride, GLfloat *metrics); +typedef void (GL_APIENTRYP PFNGLGETPATHMETRICRANGENVPROC) (GLbitfield metricQueryMask, GLuint firstPathName, GLsizei numPaths, GLsizei stride, GLfloat *metrics); +typedef void (GL_APIENTRYP PFNGLGETPATHSPACINGNVPROC) (GLenum pathListMode, GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLfloat advanceScale, GLfloat kerningScale, GLenum transformType, GLfloat *returnedSpacing); +typedef GLboolean (GL_APIENTRYP PFNGLISPOINTINFILLPATHNVPROC) (GLuint path, GLuint mask, GLfloat x, GLfloat y); +typedef GLboolean (GL_APIENTRYP PFNGLISPOINTINSTROKEPATHNVPROC) (GLuint path, GLfloat x, GLfloat y); +typedef GLfloat (GL_APIENTRYP PFNGLGETPATHLENGTHNVPROC) (GLuint path, GLsizei startSegment, GLsizei numSegments); +typedef GLboolean (GL_APIENTRYP PFNGLPOINTALONGPATHNVPROC) (GLuint path, GLsizei startSegment, GLsizei numSegments, GLfloat distance, GLfloat *x, GLfloat *y, GLfloat *tangentX, GLfloat *tangentY); +typedef void (GL_APIENTRYP PFNGLMATRIXLOAD3X2FNVPROC) (GLenum matrixMode, const GLfloat *m); +typedef void (GL_APIENTRYP PFNGLMATRIXLOAD3X3FNVPROC) (GLenum matrixMode, const GLfloat *m); +typedef void (GL_APIENTRYP PFNGLMATRIXLOADTRANSPOSE3X3FNVPROC) (GLenum matrixMode, const GLfloat *m); +typedef void (GL_APIENTRYP PFNGLMATRIXMULT3X2FNVPROC) (GLenum matrixMode, const GLfloat *m); +typedef void (GL_APIENTRYP PFNGLMATRIXMULT3X3FNVPROC) (GLenum matrixMode, const GLfloat *m); +typedef void (GL_APIENTRYP PFNGLMATRIXMULTTRANSPOSE3X3FNVPROC) (GLenum matrixMode, const GLfloat *m); +typedef void (GL_APIENTRYP PFNGLSTENCILTHENCOVERFILLPATHNVPROC) (GLuint path, GLenum fillMode, GLuint mask, GLenum coverMode); +typedef void (GL_APIENTRYP PFNGLSTENCILTHENCOVERSTROKEPATHNVPROC) (GLuint path, GLint reference, GLuint mask, GLenum coverMode); +typedef void (GL_APIENTRYP PFNGLSTENCILTHENCOVERFILLPATHINSTANCEDNVPROC) (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLenum fillMode, GLuint mask, GLenum coverMode, GLenum transformType, const GLfloat *transformValues); +typedef void (GL_APIENTRYP PFNGLSTENCILTHENCOVERSTROKEPATHINSTANCEDNVPROC) (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLint reference, GLuint mask, GLenum coverMode, GLenum transformType, const GLfloat *transformValues); +typedef GLenum (GL_APIENTRYP PFNGLPATHGLYPHINDEXRANGENVPROC) (GLenum fontTarget, const void *fontName, GLbitfield fontStyle, GLuint pathParameterTemplate, GLfloat emScale, GLuint baseAndCount[2]); +typedef GLenum (GL_APIENTRYP PFNGLPATHGLYPHINDEXARRAYNVPROC) (GLuint firstPathName, GLenum fontTarget, const void *fontName, GLbitfield fontStyle, GLuint firstGlyphIndex, GLsizei numGlyphs, GLuint pathParameterTemplate, GLfloat emScale); +typedef GLenum (GL_APIENTRYP PFNGLPATHMEMORYGLYPHINDEXARRAYNVPROC) (GLuint firstPathName, GLenum fontTarget, GLsizeiptr fontSize, const void *fontData, GLsizei faceIndex, GLuint firstGlyphIndex, GLsizei numGlyphs, GLuint pathParameterTemplate, GLfloat emScale); +typedef void (GL_APIENTRYP PFNGLPROGRAMPATHFRAGMENTINPUTGENNVPROC) (GLuint program, GLint location, GLenum genMode, GLint components, const GLfloat *coeffs); +typedef void (GL_APIENTRYP PFNGLGETPROGRAMRESOURCEFVNVPROC) (GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum *props, GLsizei bufSize, GLsizei *length, GLfloat *params); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL GLuint GL_APIENTRY glGenPathsNV (GLsizei range); +GL_APICALL void GL_APIENTRY glDeletePathsNV (GLuint path, GLsizei range); +GL_APICALL GLboolean GL_APIENTRY glIsPathNV (GLuint path); +GL_APICALL void GL_APIENTRY glPathCommandsNV (GLuint path, GLsizei numCommands, const GLubyte *commands, GLsizei numCoords, GLenum coordType, const void *coords); +GL_APICALL void GL_APIENTRY glPathCoordsNV (GLuint path, GLsizei numCoords, GLenum coordType, const void *coords); +GL_APICALL void GL_APIENTRY glPathSubCommandsNV (GLuint path, GLsizei commandStart, GLsizei commandsToDelete, GLsizei numCommands, const GLubyte *commands, GLsizei numCoords, GLenum coordType, const void *coords); +GL_APICALL void GL_APIENTRY glPathSubCoordsNV (GLuint path, GLsizei coordStart, GLsizei numCoords, GLenum coordType, const void *coords); +GL_APICALL void GL_APIENTRY glPathStringNV (GLuint path, GLenum format, GLsizei length, const void *pathString); +GL_APICALL void GL_APIENTRY glPathGlyphsNV (GLuint firstPathName, GLenum fontTarget, const void *fontName, GLbitfield fontStyle, GLsizei numGlyphs, GLenum type, const void *charcodes, GLenum handleMissingGlyphs, GLuint pathParameterTemplate, GLfloat emScale); +GL_APICALL void GL_APIENTRY glPathGlyphRangeNV (GLuint firstPathName, GLenum fontTarget, const void *fontName, GLbitfield fontStyle, GLuint firstGlyph, GLsizei numGlyphs, GLenum handleMissingGlyphs, GLuint pathParameterTemplate, GLfloat emScale); +GL_APICALL void GL_APIENTRY glWeightPathsNV (GLuint resultPath, GLsizei numPaths, const GLuint *paths, const GLfloat *weights); +GL_APICALL void GL_APIENTRY glCopyPathNV (GLuint resultPath, GLuint srcPath); +GL_APICALL void GL_APIENTRY glInterpolatePathsNV (GLuint resultPath, GLuint pathA, GLuint pathB, GLfloat weight); +GL_APICALL void GL_APIENTRY glTransformPathNV (GLuint resultPath, GLuint srcPath, GLenum transformType, const GLfloat *transformValues); +GL_APICALL void GL_APIENTRY glPathParameterivNV (GLuint path, GLenum pname, const GLint *value); +GL_APICALL void GL_APIENTRY glPathParameteriNV (GLuint path, GLenum pname, GLint value); +GL_APICALL void GL_APIENTRY glPathParameterfvNV (GLuint path, GLenum pname, const GLfloat *value); +GL_APICALL void GL_APIENTRY glPathParameterfNV (GLuint path, GLenum pname, GLfloat value); +GL_APICALL void GL_APIENTRY glPathDashArrayNV (GLuint path, GLsizei dashCount, const GLfloat *dashArray); +GL_APICALL void GL_APIENTRY glPathStencilFuncNV (GLenum func, GLint ref, GLuint mask); +GL_APICALL void GL_APIENTRY glPathStencilDepthOffsetNV (GLfloat factor, GLfloat units); +GL_APICALL void GL_APIENTRY glStencilFillPathNV (GLuint path, GLenum fillMode, GLuint mask); +GL_APICALL void GL_APIENTRY glStencilStrokePathNV (GLuint path, GLint reference, GLuint mask); +GL_APICALL void GL_APIENTRY glStencilFillPathInstancedNV (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLenum fillMode, GLuint mask, GLenum transformType, const GLfloat *transformValues); +GL_APICALL void GL_APIENTRY glStencilStrokePathInstancedNV (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLint reference, GLuint mask, GLenum transformType, const GLfloat *transformValues); +GL_APICALL void GL_APIENTRY glPathCoverDepthFuncNV (GLenum func); +GL_APICALL void GL_APIENTRY glCoverFillPathNV (GLuint path, GLenum coverMode); +GL_APICALL void GL_APIENTRY glCoverStrokePathNV (GLuint path, GLenum coverMode); +GL_APICALL void GL_APIENTRY glCoverFillPathInstancedNV (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLenum coverMode, GLenum transformType, const GLfloat *transformValues); +GL_APICALL void GL_APIENTRY glCoverStrokePathInstancedNV (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLenum coverMode, GLenum transformType, const GLfloat *transformValues); +GL_APICALL void GL_APIENTRY glGetPathParameterivNV (GLuint path, GLenum pname, GLint *value); +GL_APICALL void GL_APIENTRY glGetPathParameterfvNV (GLuint path, GLenum pname, GLfloat *value); +GL_APICALL void GL_APIENTRY glGetPathCommandsNV (GLuint path, GLubyte *commands); +GL_APICALL void GL_APIENTRY glGetPathCoordsNV (GLuint path, GLfloat *coords); +GL_APICALL void GL_APIENTRY glGetPathDashArrayNV (GLuint path, GLfloat *dashArray); +GL_APICALL void GL_APIENTRY glGetPathMetricsNV (GLbitfield metricQueryMask, GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLsizei stride, GLfloat *metrics); +GL_APICALL void GL_APIENTRY glGetPathMetricRangeNV (GLbitfield metricQueryMask, GLuint firstPathName, GLsizei numPaths, GLsizei stride, GLfloat *metrics); +GL_APICALL void GL_APIENTRY glGetPathSpacingNV (GLenum pathListMode, GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLfloat advanceScale, GLfloat kerningScale, GLenum transformType, GLfloat *returnedSpacing); +GL_APICALL GLboolean GL_APIENTRY glIsPointInFillPathNV (GLuint path, GLuint mask, GLfloat x, GLfloat y); +GL_APICALL GLboolean GL_APIENTRY glIsPointInStrokePathNV (GLuint path, GLfloat x, GLfloat y); +GL_APICALL GLfloat GL_APIENTRY glGetPathLengthNV (GLuint path, GLsizei startSegment, GLsizei numSegments); +GL_APICALL GLboolean GL_APIENTRY glPointAlongPathNV (GLuint path, GLsizei startSegment, GLsizei numSegments, GLfloat distance, GLfloat *x, GLfloat *y, GLfloat *tangentX, GLfloat *tangentY); +GL_APICALL void GL_APIENTRY glMatrixLoad3x2fNV (GLenum matrixMode, const GLfloat *m); +GL_APICALL void GL_APIENTRY glMatrixLoad3x3fNV (GLenum matrixMode, const GLfloat *m); +GL_APICALL void GL_APIENTRY glMatrixLoadTranspose3x3fNV (GLenum matrixMode, const GLfloat *m); +GL_APICALL void GL_APIENTRY glMatrixMult3x2fNV (GLenum matrixMode, const GLfloat *m); +GL_APICALL void GL_APIENTRY glMatrixMult3x3fNV (GLenum matrixMode, const GLfloat *m); +GL_APICALL void GL_APIENTRY glMatrixMultTranspose3x3fNV (GLenum matrixMode, const GLfloat *m); +GL_APICALL void GL_APIENTRY glStencilThenCoverFillPathNV (GLuint path, GLenum fillMode, GLuint mask, GLenum coverMode); +GL_APICALL void GL_APIENTRY glStencilThenCoverStrokePathNV (GLuint path, GLint reference, GLuint mask, GLenum coverMode); +GL_APICALL void GL_APIENTRY glStencilThenCoverFillPathInstancedNV (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLenum fillMode, GLuint mask, GLenum coverMode, GLenum transformType, const GLfloat *transformValues); +GL_APICALL void GL_APIENTRY glStencilThenCoverStrokePathInstancedNV (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLint reference, GLuint mask, GLenum coverMode, GLenum transformType, const GLfloat *transformValues); +GL_APICALL GLenum GL_APIENTRY glPathGlyphIndexRangeNV (GLenum fontTarget, const void *fontName, GLbitfield fontStyle, GLuint pathParameterTemplate, GLfloat emScale, GLuint baseAndCount[2]); +GL_APICALL GLenum GL_APIENTRY glPathGlyphIndexArrayNV (GLuint firstPathName, GLenum fontTarget, const void *fontName, GLbitfield fontStyle, GLuint firstGlyphIndex, GLsizei numGlyphs, GLuint pathParameterTemplate, GLfloat emScale); +GL_APICALL GLenum GL_APIENTRY glPathMemoryGlyphIndexArrayNV (GLuint firstPathName, GLenum fontTarget, GLsizeiptr fontSize, const void *fontData, GLsizei faceIndex, GLuint firstGlyphIndex, GLsizei numGlyphs, GLuint pathParameterTemplate, GLfloat emScale); +GL_APICALL void GL_APIENTRY glProgramPathFragmentInputGenNV (GLuint program, GLint location, GLenum genMode, GLint components, const GLfloat *coeffs); +GL_APICALL void GL_APIENTRY glGetProgramResourcefvNV (GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum *props, GLsizei bufSize, GLsizei *length, GLfloat *params); +#endif +#endif /* GL_NV_path_rendering */ + +#ifndef GL_NV_path_rendering_shared_edge +#define GL_NV_path_rendering_shared_edge 1 +#define GL_SHARED_EDGE_NV 0xC0 +#endif /* GL_NV_path_rendering_shared_edge */ + +#ifndef GL_NV_polygon_mode +#define GL_NV_polygon_mode 1 +#define GL_POLYGON_MODE_NV 0x0B40 +#define GL_POLYGON_OFFSET_POINT_NV 0x2A01 +#define GL_POLYGON_OFFSET_LINE_NV 0x2A02 +#define GL_POINT_NV 0x1B00 +#define GL_LINE_NV 0x1B01 +#define GL_FILL_NV 0x1B02 +typedef void (GL_APIENTRYP PFNGLPOLYGONMODENVPROC) (GLenum face, GLenum mode); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glPolygonModeNV (GLenum face, GLenum mode); #endif +#endif /* GL_NV_polygon_mode */ -/* GL_NV_read_buffer */ #ifndef GL_NV_read_buffer #define GL_NV_read_buffer 1 +#define GL_READ_BUFFER_NV 0x0C02 +typedef void (GL_APIENTRYP PFNGLREADBUFFERNVPROC) (GLenum mode); #ifdef GL_GLEXT_PROTOTYPES GL_APICALL void GL_APIENTRY glReadBufferNV (GLenum mode); #endif -typedef void (GL_APIENTRYP PFNGLREADBUFFERNVPROC) (GLenum mode); -#endif +#endif /* GL_NV_read_buffer */ -/* GL_NV_read_buffer_front */ #ifndef GL_NV_read_buffer_front #define GL_NV_read_buffer_front 1 -#endif +#endif /* GL_NV_read_buffer_front */ -/* GL_NV_read_depth */ #ifndef GL_NV_read_depth #define GL_NV_read_depth 1 -#endif +#endif /* GL_NV_read_depth */ -/* GL_NV_read_depth_stencil */ #ifndef GL_NV_read_depth_stencil #define GL_NV_read_depth_stencil 1 -#endif +#endif /* GL_NV_read_depth_stencil */ -/* GL_NV_read_stencil */ #ifndef GL_NV_read_stencil #define GL_NV_read_stencil 1 +#endif /* GL_NV_read_stencil */ + +#ifndef GL_NV_sRGB_formats +#define GL_NV_sRGB_formats 1 +#define GL_SLUMINANCE_NV 0x8C46 +#define GL_SLUMINANCE_ALPHA_NV 0x8C44 +#define GL_SRGB8_NV 0x8C41 +#define GL_SLUMINANCE8_NV 0x8C47 +#define GL_SLUMINANCE8_ALPHA8_NV 0x8C45 +#define GL_COMPRESSED_SRGB_S3TC_DXT1_NV 0x8C4C +#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_NV 0x8C4D +#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_NV 0x8C4E +#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_NV 0x8C4F +#define GL_ETC1_SRGB8_NV 0x88EE +#endif /* GL_NV_sRGB_formats */ + +#ifndef GL_NV_sample_locations +#define GL_NV_sample_locations 1 +#define GL_SAMPLE_LOCATION_SUBPIXEL_BITS_NV 0x933D +#define GL_SAMPLE_LOCATION_PIXEL_GRID_WIDTH_NV 0x933E +#define GL_SAMPLE_LOCATION_PIXEL_GRID_HEIGHT_NV 0x933F +#define GL_PROGRAMMABLE_SAMPLE_LOCATION_TABLE_SIZE_NV 0x9340 +#define GL_SAMPLE_LOCATION_NV 0x8E50 +#define GL_PROGRAMMABLE_SAMPLE_LOCATION_NV 0x9341 +#define GL_FRAMEBUFFER_PROGRAMMABLE_SAMPLE_LOCATIONS_NV 0x9342 +#define GL_FRAMEBUFFER_SAMPLE_LOCATION_PIXEL_GRID_NV 0x9343 +typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERSAMPLELOCATIONSFVNVPROC) (GLenum target, GLuint start, GLsizei count, const GLfloat *v); +typedef void (GL_APIENTRYP PFNGLNAMEDFRAMEBUFFERSAMPLELOCATIONSFVNVPROC) (GLuint framebuffer, GLuint start, GLsizei count, const GLfloat *v); +typedef void (GL_APIENTRYP PFNGLRESOLVEDEPTHVALUESNVPROC) (void); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glFramebufferSampleLocationsfvNV (GLenum target, GLuint start, GLsizei count, const GLfloat *v); +GL_APICALL void GL_APIENTRY glNamedFramebufferSampleLocationsfvNV (GLuint framebuffer, GLuint start, GLsizei count, const GLfloat *v); +GL_APICALL void GL_APIENTRY glResolveDepthValuesNV (void); #endif +#endif /* GL_NV_sample_locations */ + +#ifndef GL_NV_sample_mask_override_coverage +#define GL_NV_sample_mask_override_coverage 1 +#endif /* GL_NV_sample_mask_override_coverage */ + +#ifndef GL_NV_shader_noperspective_interpolation +#define GL_NV_shader_noperspective_interpolation 1 +#endif /* GL_NV_shader_noperspective_interpolation */ -/* GL_NV_shadow_samplers_array */ #ifndef GL_NV_shadow_samplers_array #define GL_NV_shadow_samplers_array 1 -#endif +#define GL_SAMPLER_2D_ARRAY_SHADOW_NV 0x8DC4 +#endif /* GL_NV_shadow_samplers_array */ -/* GL_NV_shadow_samplers_cube */ #ifndef GL_NV_shadow_samplers_cube #define GL_NV_shadow_samplers_cube 1 -#endif - -/* GL_NV_sRGB_formats */ -#ifndef GL_NV_sRGB_formats -#define GL_NV_sRGB_formats 1 -#endif +#define GL_SAMPLER_CUBE_SHADOW_NV 0x8DC5 +#endif /* GL_NV_shadow_samplers_cube */ -/* GL_NV_texture_border_clamp */ #ifndef GL_NV_texture_border_clamp #define GL_NV_texture_border_clamp 1 -#endif +#define GL_TEXTURE_BORDER_COLOR_NV 0x1004 +#define GL_CLAMP_TO_BORDER_NV 0x812D +#endif /* GL_NV_texture_border_clamp */ -/* GL_NV_texture_compression_s3tc_update */ #ifndef GL_NV_texture_compression_s3tc_update #define GL_NV_texture_compression_s3tc_update 1 -#endif +#endif /* GL_NV_texture_compression_s3tc_update */ -/* GL_NV_texture_npot_2D_mipmap */ #ifndef GL_NV_texture_npot_2D_mipmap #define GL_NV_texture_npot_2D_mipmap 1 +#endif /* GL_NV_texture_npot_2D_mipmap */ + +#ifndef GL_NV_viewport_array +#define GL_NV_viewport_array 1 +#define GL_MAX_VIEWPORTS_NV 0x825B +#define GL_VIEWPORT_SUBPIXEL_BITS_NV 0x825C +#define GL_VIEWPORT_BOUNDS_RANGE_NV 0x825D +#define GL_VIEWPORT_INDEX_PROVOKING_VERTEX_NV 0x825F +typedef void (GL_APIENTRYP PFNGLVIEWPORTARRAYVNVPROC) (GLuint first, GLsizei count, const GLfloat *v); +typedef void (GL_APIENTRYP PFNGLVIEWPORTINDEXEDFNVPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat w, GLfloat h); +typedef void (GL_APIENTRYP PFNGLVIEWPORTINDEXEDFVNVPROC) (GLuint index, const GLfloat *v); +typedef void (GL_APIENTRYP PFNGLSCISSORARRAYVNVPROC) (GLuint first, GLsizei count, const GLint *v); +typedef void (GL_APIENTRYP PFNGLSCISSORINDEXEDNVPROC) (GLuint index, GLint left, GLint bottom, GLsizei width, GLsizei height); +typedef void (GL_APIENTRYP PFNGLSCISSORINDEXEDVNVPROC) (GLuint index, const GLint *v); +typedef void (GL_APIENTRYP PFNGLDEPTHRANGEARRAYFVNVPROC) (GLuint first, GLsizei count, const GLfloat *v); +typedef void (GL_APIENTRYP PFNGLDEPTHRANGEINDEXEDFNVPROC) (GLuint index, GLfloat n, GLfloat f); +typedef void (GL_APIENTRYP PFNGLGETFLOATI_VNVPROC) (GLenum target, GLuint index, GLfloat *data); +typedef void (GL_APIENTRYP PFNGLENABLEINVPROC) (GLenum target, GLuint index); +typedef void (GL_APIENTRYP PFNGLDISABLEINVPROC) (GLenum target, GLuint index); +typedef GLboolean (GL_APIENTRYP PFNGLISENABLEDINVPROC) (GLenum target, GLuint index); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glViewportArrayvNV (GLuint first, GLsizei count, const GLfloat *v); +GL_APICALL void GL_APIENTRY glViewportIndexedfNV (GLuint index, GLfloat x, GLfloat y, GLfloat w, GLfloat h); +GL_APICALL void GL_APIENTRY glViewportIndexedfvNV (GLuint index, const GLfloat *v); +GL_APICALL void GL_APIENTRY glScissorArrayvNV (GLuint first, GLsizei count, const GLint *v); +GL_APICALL void GL_APIENTRY glScissorIndexedNV (GLuint index, GLint left, GLint bottom, GLsizei width, GLsizei height); +GL_APICALL void GL_APIENTRY glScissorIndexedvNV (GLuint index, const GLint *v); +GL_APICALL void GL_APIENTRY glDepthRangeArrayfvNV (GLuint first, GLsizei count, const GLfloat *v); +GL_APICALL void GL_APIENTRY glDepthRangeIndexedfNV (GLuint index, GLfloat n, GLfloat f); +GL_APICALL void GL_APIENTRY glGetFloati_vNV (GLenum target, GLuint index, GLfloat *data); +GL_APICALL void GL_APIENTRY glEnableiNV (GLenum target, GLuint index); +GL_APICALL void GL_APIENTRY glDisableiNV (GLenum target, GLuint index); +GL_APICALL GLboolean GL_APIENTRY glIsEnablediNV (GLenum target, GLuint index); +#endif +#endif /* GL_NV_viewport_array */ + +#ifndef GL_NV_viewport_array2 +#define GL_NV_viewport_array2 1 +#endif /* GL_NV_viewport_array2 */ + +#ifndef GL_OVR_multiview +#define GL_OVR_multiview 1 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_NUM_VIEWS_OVR 0x9630 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_BASE_VIEW_INDEX_OVR 0x9632 +#define GL_MAX_VIEWS_OVR 0x9631 +typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERTEXTUREMULTIVIEWOVRPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint baseViewIndex, GLsizei numViews); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glFramebufferTextureMultiviewOVR (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint baseViewIndex, GLsizei numViews); #endif +#endif /* GL_OVR_multiview */ -/*------------------------------------------------------------------------* - * QCOM extension functions - *------------------------------------------------------------------------*/ +#ifndef GL_OVR_multiview2 +#define GL_OVR_multiview2 1 +#endif /* GL_OVR_multiview2 */ -/* GL_QCOM_alpha_test */ #ifndef GL_QCOM_alpha_test #define GL_QCOM_alpha_test 1 +#define GL_ALPHA_TEST_QCOM 0x0BC0 +#define GL_ALPHA_TEST_FUNC_QCOM 0x0BC1 +#define GL_ALPHA_TEST_REF_QCOM 0x0BC2 +typedef void (GL_APIENTRYP PFNGLALPHAFUNCQCOMPROC) (GLenum func, GLclampf ref); #ifdef GL_GLEXT_PROTOTYPES GL_APICALL void GL_APIENTRY glAlphaFuncQCOM (GLenum func, GLclampf ref); #endif -typedef void (GL_APIENTRYP PFNGLALPHAFUNCQCOMPROC) (GLenum func, GLclampf ref); -#endif +#endif /* GL_QCOM_alpha_test */ -/* GL_QCOM_binning_control */ #ifndef GL_QCOM_binning_control #define GL_QCOM_binning_control 1 -#endif +#define GL_BINNING_CONTROL_HINT_QCOM 0x8FB0 +#define GL_CPU_OPTIMIZED_QCOM 0x8FB1 +#define GL_GPU_OPTIMIZED_QCOM 0x8FB2 +#define GL_RENDER_DIRECT_TO_FRAMEBUFFER_QCOM 0x8FB3 +#endif /* GL_QCOM_binning_control */ -/* GL_QCOM_driver_control */ #ifndef GL_QCOM_driver_control #define GL_QCOM_driver_control 1 +typedef void (GL_APIENTRYP PFNGLGETDRIVERCONTROLSQCOMPROC) (GLint *num, GLsizei size, GLuint *driverControls); +typedef void (GL_APIENTRYP PFNGLGETDRIVERCONTROLSTRINGQCOMPROC) (GLuint driverControl, GLsizei bufSize, GLsizei *length, GLchar *driverControlString); +typedef void (GL_APIENTRYP PFNGLENABLEDRIVERCONTROLQCOMPROC) (GLuint driverControl); +typedef void (GL_APIENTRYP PFNGLDISABLEDRIVERCONTROLQCOMPROC) (GLuint driverControl); #ifdef GL_GLEXT_PROTOTYPES GL_APICALL void GL_APIENTRY glGetDriverControlsQCOM (GLint *num, GLsizei size, GLuint *driverControls); GL_APICALL void GL_APIENTRY glGetDriverControlStringQCOM (GLuint driverControl, GLsizei bufSize, GLsizei *length, GLchar *driverControlString); GL_APICALL void GL_APIENTRY glEnableDriverControlQCOM (GLuint driverControl); GL_APICALL void GL_APIENTRY glDisableDriverControlQCOM (GLuint driverControl); #endif -typedef void (GL_APIENTRYP PFNGLGETDRIVERCONTROLSQCOMPROC) (GLint *num, GLsizei size, GLuint *driverControls); -typedef void (GL_APIENTRYP PFNGLGETDRIVERCONTROLSTRINGQCOMPROC) (GLuint driverControl, GLsizei bufSize, GLsizei *length, GLchar *driverControlString); -typedef void (GL_APIENTRYP PFNGLENABLEDRIVERCONTROLQCOMPROC) (GLuint driverControl); -typedef void (GL_APIENTRYP PFNGLDISABLEDRIVERCONTROLQCOMPROC) (GLuint driverControl); -#endif +#endif /* GL_QCOM_driver_control */ -/* GL_QCOM_extended_get */ #ifndef GL_QCOM_extended_get #define GL_QCOM_extended_get 1 +#define GL_TEXTURE_WIDTH_QCOM 0x8BD2 +#define GL_TEXTURE_HEIGHT_QCOM 0x8BD3 +#define GL_TEXTURE_DEPTH_QCOM 0x8BD4 +#define GL_TEXTURE_INTERNAL_FORMAT_QCOM 0x8BD5 +#define GL_TEXTURE_FORMAT_QCOM 0x8BD6 +#define GL_TEXTURE_TYPE_QCOM 0x8BD7 +#define GL_TEXTURE_IMAGE_VALID_QCOM 0x8BD8 +#define GL_TEXTURE_NUM_LEVELS_QCOM 0x8BD9 +#define GL_TEXTURE_TARGET_QCOM 0x8BDA +#define GL_TEXTURE_OBJECT_VALID_QCOM 0x8BDB +#define GL_STATE_RESTORE 0x8BDC +typedef void (GL_APIENTRYP PFNGLEXTGETTEXTURESQCOMPROC) (GLuint *textures, GLint maxTextures, GLint *numTextures); +typedef void (GL_APIENTRYP PFNGLEXTGETBUFFERSQCOMPROC) (GLuint *buffers, GLint maxBuffers, GLint *numBuffers); +typedef void (GL_APIENTRYP PFNGLEXTGETRENDERBUFFERSQCOMPROC) (GLuint *renderbuffers, GLint maxRenderbuffers, GLint *numRenderbuffers); +typedef void (GL_APIENTRYP PFNGLEXTGETFRAMEBUFFERSQCOMPROC) (GLuint *framebuffers, GLint maxFramebuffers, GLint *numFramebuffers); +typedef void (GL_APIENTRYP PFNGLEXTGETTEXLEVELPARAMETERIVQCOMPROC) (GLuint texture, GLenum face, GLint level, GLenum pname, GLint *params); +typedef void (GL_APIENTRYP PFNGLEXTTEXOBJECTSTATEOVERRIDEIQCOMPROC) (GLenum target, GLenum pname, GLint param); +typedef void (GL_APIENTRYP PFNGLEXTGETTEXSUBIMAGEQCOMPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, void *texels); +typedef void (GL_APIENTRYP PFNGLEXTGETBUFFERPOINTERVQCOMPROC) (GLenum target, void **params); #ifdef GL_GLEXT_PROTOTYPES GL_APICALL void GL_APIENTRY glExtGetTexturesQCOM (GLuint *textures, GLint maxTextures, GLint *numTextures); GL_APICALL void GL_APIENTRY glExtGetBuffersQCOM (GLuint *buffers, GLint maxBuffers, GLint *numBuffers); @@ -1948,66 +2844,99 @@ GL_APICALL void GL_APIENTRY glExtGetRenderbuffersQCOM (GLuint *renderbuffers, GL GL_APICALL void GL_APIENTRY glExtGetFramebuffersQCOM (GLuint *framebuffers, GLint maxFramebuffers, GLint *numFramebuffers); GL_APICALL void GL_APIENTRY glExtGetTexLevelParameterivQCOM (GLuint texture, GLenum face, GLint level, GLenum pname, GLint *params); GL_APICALL void GL_APIENTRY glExtTexObjectStateOverrideiQCOM (GLenum target, GLenum pname, GLint param); -GL_APICALL void GL_APIENTRY glExtGetTexSubImageQCOM (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, GLvoid *texels); -GL_APICALL void GL_APIENTRY glExtGetBufferPointervQCOM (GLenum target, GLvoid **params); -#endif -typedef void (GL_APIENTRYP PFNGLEXTGETTEXTURESQCOMPROC) (GLuint *textures, GLint maxTextures, GLint *numTextures); -typedef void (GL_APIENTRYP PFNGLEXTGETBUFFERSQCOMPROC) (GLuint *buffers, GLint maxBuffers, GLint *numBuffers); -typedef void (GL_APIENTRYP PFNGLEXTGETRENDERBUFFERSQCOMPROC) (GLuint *renderbuffers, GLint maxRenderbuffers, GLint *numRenderbuffers); -typedef void (GL_APIENTRYP PFNGLEXTGETFRAMEBUFFERSQCOMPROC) (GLuint *framebuffers, GLint maxFramebuffers, GLint *numFramebuffers); -typedef void (GL_APIENTRYP PFNGLEXTGETTEXLEVELPARAMETERIVQCOMPROC) (GLuint texture, GLenum face, GLint level, GLenum pname, GLint *params); -typedef void (GL_APIENTRYP PFNGLEXTTEXOBJECTSTATEOVERRIDEIQCOMPROC) (GLenum target, GLenum pname, GLint param); -typedef void (GL_APIENTRYP PFNGLEXTGETTEXSUBIMAGEQCOMPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, GLvoid *texels); -typedef void (GL_APIENTRYP PFNGLEXTGETBUFFERPOINTERVQCOMPROC) (GLenum target, GLvoid **params); +GL_APICALL void GL_APIENTRY glExtGetTexSubImageQCOM (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, void *texels); +GL_APICALL void GL_APIENTRY glExtGetBufferPointervQCOM (GLenum target, void **params); #endif +#endif /* GL_QCOM_extended_get */ -/* GL_QCOM_extended_get2 */ #ifndef GL_QCOM_extended_get2 #define GL_QCOM_extended_get2 1 +typedef void (GL_APIENTRYP PFNGLEXTGETSHADERSQCOMPROC) (GLuint *shaders, GLint maxShaders, GLint *numShaders); +typedef void (GL_APIENTRYP PFNGLEXTGETPROGRAMSQCOMPROC) (GLuint *programs, GLint maxPrograms, GLint *numPrograms); +typedef GLboolean (GL_APIENTRYP PFNGLEXTISPROGRAMBINARYQCOMPROC) (GLuint program); +typedef void (GL_APIENTRYP PFNGLEXTGETPROGRAMBINARYSOURCEQCOMPROC) (GLuint program, GLenum shadertype, GLchar *source, GLint *length); #ifdef GL_GLEXT_PROTOTYPES GL_APICALL void GL_APIENTRY glExtGetShadersQCOM (GLuint *shaders, GLint maxShaders, GLint *numShaders); GL_APICALL void GL_APIENTRY glExtGetProgramsQCOM (GLuint *programs, GLint maxPrograms, GLint *numPrograms); GL_APICALL GLboolean GL_APIENTRY glExtIsProgramBinaryQCOM (GLuint program); GL_APICALL void GL_APIENTRY glExtGetProgramBinarySourceQCOM (GLuint program, GLenum shadertype, GLchar *source, GLint *length); #endif -typedef void (GL_APIENTRYP PFNGLEXTGETSHADERSQCOMPROC) (GLuint *shaders, GLint maxShaders, GLint *numShaders); -typedef void (GL_APIENTRYP PFNGLEXTGETPROGRAMSQCOMPROC) (GLuint *programs, GLint maxPrograms, GLint *numPrograms); -typedef GLboolean (GL_APIENTRYP PFNGLEXTISPROGRAMBINARYQCOMPROC) (GLuint program); -typedef void (GL_APIENTRYP PFNGLEXTGETPROGRAMBINARYSOURCEQCOMPROC) (GLuint program, GLenum shadertype, GLchar *source, GLint *length); -#endif +#endif /* GL_QCOM_extended_get2 */ -/* GL_QCOM_perfmon_global_mode */ #ifndef GL_QCOM_perfmon_global_mode #define GL_QCOM_perfmon_global_mode 1 -#endif - -/* GL_QCOM_writeonly_rendering */ -#ifndef GL_QCOM_writeonly_rendering -#define GL_QCOM_writeonly_rendering 1 -#endif +#define GL_PERFMON_GLOBAL_MODE_QCOM 0x8FA0 +#endif /* GL_QCOM_perfmon_global_mode */ -/* GL_QCOM_tiled_rendering */ #ifndef GL_QCOM_tiled_rendering #define GL_QCOM_tiled_rendering 1 +#define GL_COLOR_BUFFER_BIT0_QCOM 0x00000001 +#define GL_COLOR_BUFFER_BIT1_QCOM 0x00000002 +#define GL_COLOR_BUFFER_BIT2_QCOM 0x00000004 +#define GL_COLOR_BUFFER_BIT3_QCOM 0x00000008 +#define GL_COLOR_BUFFER_BIT4_QCOM 0x00000010 +#define GL_COLOR_BUFFER_BIT5_QCOM 0x00000020 +#define GL_COLOR_BUFFER_BIT6_QCOM 0x00000040 +#define GL_COLOR_BUFFER_BIT7_QCOM 0x00000080 +#define GL_DEPTH_BUFFER_BIT0_QCOM 0x00000100 +#define GL_DEPTH_BUFFER_BIT1_QCOM 0x00000200 +#define GL_DEPTH_BUFFER_BIT2_QCOM 0x00000400 +#define GL_DEPTH_BUFFER_BIT3_QCOM 0x00000800 +#define GL_DEPTH_BUFFER_BIT4_QCOM 0x00001000 +#define GL_DEPTH_BUFFER_BIT5_QCOM 0x00002000 +#define GL_DEPTH_BUFFER_BIT6_QCOM 0x00004000 +#define GL_DEPTH_BUFFER_BIT7_QCOM 0x00008000 +#define GL_STENCIL_BUFFER_BIT0_QCOM 0x00010000 +#define GL_STENCIL_BUFFER_BIT1_QCOM 0x00020000 +#define GL_STENCIL_BUFFER_BIT2_QCOM 0x00040000 +#define GL_STENCIL_BUFFER_BIT3_QCOM 0x00080000 +#define GL_STENCIL_BUFFER_BIT4_QCOM 0x00100000 +#define GL_STENCIL_BUFFER_BIT5_QCOM 0x00200000 +#define GL_STENCIL_BUFFER_BIT6_QCOM 0x00400000 +#define GL_STENCIL_BUFFER_BIT7_QCOM 0x00800000 +#define GL_MULTISAMPLE_BUFFER_BIT0_QCOM 0x01000000 +#define GL_MULTISAMPLE_BUFFER_BIT1_QCOM 0x02000000 +#define GL_MULTISAMPLE_BUFFER_BIT2_QCOM 0x04000000 +#define GL_MULTISAMPLE_BUFFER_BIT3_QCOM 0x08000000 +#define GL_MULTISAMPLE_BUFFER_BIT4_QCOM 0x10000000 +#define GL_MULTISAMPLE_BUFFER_BIT5_QCOM 0x20000000 +#define GL_MULTISAMPLE_BUFFER_BIT6_QCOM 0x40000000 +#define GL_MULTISAMPLE_BUFFER_BIT7_QCOM 0x80000000 +typedef void (GL_APIENTRYP PFNGLSTARTTILINGQCOMPROC) (GLuint x, GLuint y, GLuint width, GLuint height, GLbitfield preserveMask); +typedef void (GL_APIENTRYP PFNGLENDTILINGQCOMPROC) (GLbitfield preserveMask); #ifdef GL_GLEXT_PROTOTYPES GL_APICALL void GL_APIENTRY glStartTilingQCOM (GLuint x, GLuint y, GLuint width, GLuint height, GLbitfield preserveMask); GL_APICALL void GL_APIENTRY glEndTilingQCOM (GLbitfield preserveMask); #endif -typedef void (GL_APIENTRYP PFNGLSTARTTILINGQCOMPROC) (GLuint x, GLuint y, GLuint width, GLuint height, GLbitfield preserveMask); -typedef void (GL_APIENTRYP PFNGLENDTILINGQCOMPROC) (GLbitfield preserveMask); -#endif +#endif /* GL_QCOM_tiled_rendering */ -/*------------------------------------------------------------------------* - * VIV extension tokens - *------------------------------------------------------------------------*/ +#ifndef GL_QCOM_writeonly_rendering +#define GL_QCOM_writeonly_rendering 1 +#define GL_WRITEONLY_RENDERING_QCOM 0x8823 +#endif /* GL_QCOM_writeonly_rendering */ -/* GL_VIV_shader_binary */ #ifndef GL_VIV_shader_binary #define GL_VIV_shader_binary 1 -#endif +#define GL_SHADER_BINARY_VIV 0x8FC4 +#endif /* GL_VIV_shader_binary */ + +#ifndef GL_ANGLE_lossy_etc_decode +#define GL_ANGLE_lossy_etc_decode 1 +#define GL_ETC1_RGB8_LOSSY_DECODE_ANGLE 0x9690 +#define GL_COMPRESSED_R11_LOSSY_DECODE_EAC_ANGLE 0x9691 +#define GL_COMPRESSED_SIGNED_R11_LOSSY_DECODE_EAC_ANGLE 0x9692 +#define GL_COMPRESSED_RG11_LOSSY_DECODE_EAC_ANGLE 0x9693 +#define GL_COMPRESSED_SIGNED_RG11_LOSSY_DECODE_EAC_ANGLE 0x9694 +#define GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE 0x9695 +#define GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE 0x9696 +#define GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE 0x9697 +#define GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE 0x9698 +#define GL_COMPRESSED_RGBA8_LOSSY_DECODE_ETC2_EAC_ANGLE 0x9699 +#define GL_COMPRESSED_SRGB8_ALPHA8_LOSSY_DECODE_ETC2_EAC_ANGLE 0x969A +#endif /* GL_ANGLE_lossy_etc_decode */ #ifdef __cplusplus } #endif -#endif /* __gl2ext_h_ */ +#endif diff --git a/Source/ThirdParty/ANGLE/include/GLES2/gl2platform.h b/Source/ThirdParty/ANGLE/include/GLES2/gl2platform.h index c9fa3c4d64bd..89d4d44dc1bb 100644 --- a/Source/ThirdParty/ANGLE/include/GLES2/gl2platform.h +++ b/Source/ThirdParty/ANGLE/include/GLES2/gl2platform.h @@ -1,7 +1,7 @@ #ifndef __gl2platform_h_ #define __gl2platform_h_ -/* $Revision: 10602 $ on $Date:: 2010-03-04 22:35:34 -0800 #$ */ +/* $Revision: 23328 $ on $Date:: 2013-10-02 02:28:28 -0700 #$ */ /* * This document is licensed under the SGI Free Software B License Version diff --git a/Source/ThirdParty/ANGLE/include/GLES3/gl3.h b/Source/ThirdParty/ANGLE/include/GLES3/gl3.h index 9c79862c0d08..53c59b85fed7 100644 --- a/Source/ThirdParty/ANGLE/include/GLES3/gl3.h +++ b/Source/ThirdParty/ANGLE/include/GLES3/gl3.h @@ -1,18 +1,12 @@ #ifndef __gl3_h_ -#define __gl3_h_ - -/* - * gl3.h last updated on $Date: 2013-02-12 14:37:24 -0800 (Tue, 12 Feb 2013) $ - */ - -#include +#define __gl3_h_ 1 #ifdef __cplusplus extern "C" { #endif /* -** Copyright (c) 2007-2013 The Khronos Group Inc. +** Copyright (c) 2013-2015 The Khronos Group Inc. ** ** Permission is hereby granted, free of charge, to any person obtaining a ** copy of this software and/or associated documentation files (the @@ -33,1026 +27,1180 @@ extern "C" { ** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE ** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. */ +/* +** This header is generated from the Khronos OpenGL / OpenGL ES XML +** API Registry. The current version of the Registry, generator scripts +** used to make the header, and the header can be found at +** http://www.opengl.org/registry/ +** +** Khronos $Revision: 31811 $ on $Date: 2015-08-10 00:01:11 -0700 (Mon, 10 Aug 2015) $ +*/ -/*------------------------------------------------------------------------- - * Data type definitions - *-----------------------------------------------------------------------*/ +#include -/* OpenGL ES 2.0 */ +#ifndef GL_APIENTRYP +#define GL_APIENTRYP GL_APIENTRY* +#endif -typedef void GLvoid; -typedef char GLchar; -typedef unsigned int GLenum; -typedef unsigned char GLboolean; -typedef unsigned int GLbitfield; -typedef khronos_int8_t GLbyte; -typedef short GLshort; -typedef int GLint; -typedef int GLsizei; -typedef khronos_uint8_t GLubyte; -typedef unsigned short GLushort; -typedef unsigned int GLuint; -typedef khronos_float_t GLfloat; -typedef khronos_float_t GLclampf; -typedef khronos_int32_t GLfixed; -typedef khronos_intptr_t GLintptr; -typedef khronos_ssize_t GLsizeiptr; +/* Generated on date 20150809 */ -/* OpenGL ES 3.0 */ +/* Generated C header for: + * API: gles2 + * Profile: common + * Versions considered: 2\.[0-9]|3\.0 + * Versions emitted: .* + * Default extensions included: None + * Additional extensions included: _nomatch_^ + * Extensions removed: _nomatch_^ + */ -typedef unsigned short GLhalf; -typedef khronos_int64_t GLint64; -typedef khronos_uint64_t GLuint64; +#ifndef GL_ES_VERSION_2_0 +#define GL_ES_VERSION_2_0 1 +#include +typedef khronos_int8_t GLbyte; +typedef khronos_float_t GLclampf; +typedef khronos_int32_t GLfixed; +typedef short GLshort; +typedef unsigned short GLushort; +typedef void GLvoid; typedef struct __GLsync *GLsync; - -/*------------------------------------------------------------------------- - * Token definitions - *-----------------------------------------------------------------------*/ - -/* OpenGL ES core versions */ -#define GL_ES_VERSION_3_0 1 -#define GL_ES_VERSION_2_0 1 - -/* OpenGL ES 2.0 */ - -/* ClearBufferMask */ -#define GL_DEPTH_BUFFER_BIT 0x00000100 -#define GL_STENCIL_BUFFER_BIT 0x00000400 -#define GL_COLOR_BUFFER_BIT 0x00004000 - -/* Boolean */ -#define GL_FALSE 0 -#define GL_TRUE 1 - -/* BeginMode */ -#define GL_POINTS 0x0000 -#define GL_LINES 0x0001 -#define GL_LINE_LOOP 0x0002 -#define GL_LINE_STRIP 0x0003 -#define GL_TRIANGLES 0x0004 -#define GL_TRIANGLE_STRIP 0x0005 -#define GL_TRIANGLE_FAN 0x0006 - -/* BlendingFactorDest */ -#define GL_ZERO 0 -#define GL_ONE 1 -#define GL_SRC_COLOR 0x0300 -#define GL_ONE_MINUS_SRC_COLOR 0x0301 -#define GL_SRC_ALPHA 0x0302 -#define GL_ONE_MINUS_SRC_ALPHA 0x0303 -#define GL_DST_ALPHA 0x0304 -#define GL_ONE_MINUS_DST_ALPHA 0x0305 - -/* BlendingFactorSrc */ -/* GL_ZERO */ -/* GL_ONE */ -#define GL_DST_COLOR 0x0306 -#define GL_ONE_MINUS_DST_COLOR 0x0307 -#define GL_SRC_ALPHA_SATURATE 0x0308 -/* GL_SRC_ALPHA */ -/* GL_ONE_MINUS_SRC_ALPHA */ -/* GL_DST_ALPHA */ -/* GL_ONE_MINUS_DST_ALPHA */ - -/* BlendEquationSeparate */ -#define GL_FUNC_ADD 0x8006 -#define GL_BLEND_EQUATION 0x8009 -#define GL_BLEND_EQUATION_RGB 0x8009 /* same as BLEND_EQUATION */ -#define GL_BLEND_EQUATION_ALPHA 0x883D - -/* BlendSubtract */ -#define GL_FUNC_SUBTRACT 0x800A -#define GL_FUNC_REVERSE_SUBTRACT 0x800B - -/* Separate Blend Functions */ -#define GL_BLEND_DST_RGB 0x80C8 -#define GL_BLEND_SRC_RGB 0x80C9 -#define GL_BLEND_DST_ALPHA 0x80CA -#define GL_BLEND_SRC_ALPHA 0x80CB -#define GL_CONSTANT_COLOR 0x8001 -#define GL_ONE_MINUS_CONSTANT_COLOR 0x8002 -#define GL_CONSTANT_ALPHA 0x8003 -#define GL_ONE_MINUS_CONSTANT_ALPHA 0x8004 -#define GL_BLEND_COLOR 0x8005 - -/* Buffer Objects */ -#define GL_ARRAY_BUFFER 0x8892 -#define GL_ELEMENT_ARRAY_BUFFER 0x8893 -#define GL_ARRAY_BUFFER_BINDING 0x8894 -#define GL_ELEMENT_ARRAY_BUFFER_BINDING 0x8895 - -#define GL_STREAM_DRAW 0x88E0 -#define GL_STATIC_DRAW 0x88E4 -#define GL_DYNAMIC_DRAW 0x88E8 - -#define GL_BUFFER_SIZE 0x8764 -#define GL_BUFFER_USAGE 0x8765 - -#define GL_CURRENT_VERTEX_ATTRIB 0x8626 - -/* CullFaceMode */ -#define GL_FRONT 0x0404 -#define GL_BACK 0x0405 -#define GL_FRONT_AND_BACK 0x0408 - -/* DepthFunction */ -/* GL_NEVER */ -/* GL_LESS */ -/* GL_EQUAL */ -/* GL_LEQUAL */ -/* GL_GREATER */ -/* GL_NOTEQUAL */ -/* GL_GEQUAL */ -/* GL_ALWAYS */ - -/* EnableCap */ -#define GL_TEXTURE_2D 0x0DE1 -#define GL_CULL_FACE 0x0B44 -#define GL_BLEND 0x0BE2 -#define GL_DITHER 0x0BD0 -#define GL_STENCIL_TEST 0x0B90 -#define GL_DEPTH_TEST 0x0B71 -#define GL_SCISSOR_TEST 0x0C11 -#define GL_POLYGON_OFFSET_FILL 0x8037 -#define GL_SAMPLE_ALPHA_TO_COVERAGE 0x809E -#define GL_SAMPLE_COVERAGE 0x80A0 - -/* ErrorCode */ -#define GL_NO_ERROR 0 -#define GL_INVALID_ENUM 0x0500 -#define GL_INVALID_VALUE 0x0501 -#define GL_INVALID_OPERATION 0x0502 -#define GL_OUT_OF_MEMORY 0x0505 - -/* FrontFaceDirection */ -#define GL_CW 0x0900 -#define GL_CCW 0x0901 - -/* GetPName */ -#define GL_LINE_WIDTH 0x0B21 -#define GL_ALIASED_POINT_SIZE_RANGE 0x846D -#define GL_ALIASED_LINE_WIDTH_RANGE 0x846E -#define GL_CULL_FACE_MODE 0x0B45 -#define GL_FRONT_FACE 0x0B46 -#define GL_DEPTH_RANGE 0x0B70 -#define GL_DEPTH_WRITEMASK 0x0B72 -#define GL_DEPTH_CLEAR_VALUE 0x0B73 -#define GL_DEPTH_FUNC 0x0B74 -#define GL_STENCIL_CLEAR_VALUE 0x0B91 -#define GL_STENCIL_FUNC 0x0B92 -#define GL_STENCIL_FAIL 0x0B94 -#define GL_STENCIL_PASS_DEPTH_FAIL 0x0B95 -#define GL_STENCIL_PASS_DEPTH_PASS 0x0B96 -#define GL_STENCIL_REF 0x0B97 -#define GL_STENCIL_VALUE_MASK 0x0B93 -#define GL_STENCIL_WRITEMASK 0x0B98 -#define GL_STENCIL_BACK_FUNC 0x8800 -#define GL_STENCIL_BACK_FAIL 0x8801 -#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_VIEWPORT 0x0BA2 -#define GL_SCISSOR_BOX 0x0C10 -/* GL_SCISSOR_TEST */ -#define GL_COLOR_CLEAR_VALUE 0x0C22 -#define GL_COLOR_WRITEMASK 0x0C23 -#define GL_UNPACK_ALIGNMENT 0x0CF5 -#define GL_PACK_ALIGNMENT 0x0D05 -#define GL_MAX_TEXTURE_SIZE 0x0D33 -#define GL_MAX_VIEWPORT_DIMS 0x0D3A -#define GL_SUBPIXEL_BITS 0x0D50 -#define GL_RED_BITS 0x0D52 -#define GL_GREEN_BITS 0x0D53 -#define GL_BLUE_BITS 0x0D54 -#define GL_ALPHA_BITS 0x0D55 -#define GL_DEPTH_BITS 0x0D56 -#define GL_STENCIL_BITS 0x0D57 -#define GL_POLYGON_OFFSET_UNITS 0x2A00 -/* GL_POLYGON_OFFSET_FILL */ -#define GL_POLYGON_OFFSET_FACTOR 0x8038 -#define GL_TEXTURE_BINDING_2D 0x8069 -#define GL_SAMPLE_BUFFERS 0x80A8 -#define GL_SAMPLES 0x80A9 -#define GL_SAMPLE_COVERAGE_VALUE 0x80AA -#define GL_SAMPLE_COVERAGE_INVERT 0x80AB - -/* GetTextureParameter */ -/* GL_TEXTURE_MAG_FILTER */ -/* GL_TEXTURE_MIN_FILTER */ -/* GL_TEXTURE_WRAP_S */ -/* GL_TEXTURE_WRAP_T */ - -#define GL_NUM_COMPRESSED_TEXTURE_FORMATS 0x86A2 -#define GL_COMPRESSED_TEXTURE_FORMATS 0x86A3 - -/* HintMode */ -#define GL_DONT_CARE 0x1100 -#define GL_FASTEST 0x1101 -#define GL_NICEST 0x1102 - -/* HintTarget */ -#define GL_GENERATE_MIPMAP_HINT 0x8192 - -/* DataType */ -#define GL_BYTE 0x1400 -#define GL_UNSIGNED_BYTE 0x1401 -#define GL_SHORT 0x1402 -#define GL_UNSIGNED_SHORT 0x1403 -#define GL_INT 0x1404 -#define GL_UNSIGNED_INT 0x1405 -#define GL_FLOAT 0x1406 -#define GL_FIXED 0x140C - -/* PixelFormat */ -#define GL_DEPTH_COMPONENT 0x1902 -#define GL_ALPHA 0x1906 -#define GL_RGB 0x1907 -#define GL_RGBA 0x1908 -#define GL_LUMINANCE 0x1909 -#define GL_LUMINANCE_ALPHA 0x190A - -/* PixelType */ -/* GL_UNSIGNED_BYTE */ -#define GL_UNSIGNED_SHORT_4_4_4_4 0x8033 -#define GL_UNSIGNED_SHORT_5_5_5_1 0x8034 -#define GL_UNSIGNED_SHORT_5_6_5 0x8363 - -/* Shaders */ -#define GL_FRAGMENT_SHADER 0x8B30 -#define GL_VERTEX_SHADER 0x8B31 -#define GL_MAX_VERTEX_ATTRIBS 0x8869 -#define GL_MAX_VERTEX_UNIFORM_VECTORS 0x8DFB -#define GL_MAX_VARYING_VECTORS 0x8DFC -#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS 0x8B4D -#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS 0x8B4C -#define GL_MAX_TEXTURE_IMAGE_UNITS 0x8872 -#define GL_MAX_FRAGMENT_UNIFORM_VECTORS 0x8DFD -#define GL_SHADER_TYPE 0x8B4F -#define GL_DELETE_STATUS 0x8B80 -#define GL_LINK_STATUS 0x8B82 -#define GL_VALIDATE_STATUS 0x8B83 -#define GL_ATTACHED_SHADERS 0x8B85 -#define GL_ACTIVE_UNIFORMS 0x8B86 -#define GL_ACTIVE_UNIFORM_MAX_LENGTH 0x8B87 -#define GL_ACTIVE_ATTRIBUTES 0x8B89 -#define GL_ACTIVE_ATTRIBUTE_MAX_LENGTH 0x8B8A -#define GL_SHADING_LANGUAGE_VERSION 0x8B8C -#define GL_CURRENT_PROGRAM 0x8B8D - -/* StencilFunction */ -#define GL_NEVER 0x0200 -#define GL_LESS 0x0201 -#define GL_EQUAL 0x0202 -#define GL_LEQUAL 0x0203 -#define GL_GREATER 0x0204 -#define GL_NOTEQUAL 0x0205 -#define GL_GEQUAL 0x0206 -#define GL_ALWAYS 0x0207 - -/* StencilOp */ -/* GL_ZERO */ -#define GL_KEEP 0x1E00 -#define GL_REPLACE 0x1E01 -#define GL_INCR 0x1E02 -#define GL_DECR 0x1E03 -#define GL_INVERT 0x150A -#define GL_INCR_WRAP 0x8507 -#define GL_DECR_WRAP 0x8508 - -/* StringName */ -#define GL_VENDOR 0x1F00 -#define GL_RENDERER 0x1F01 -#define GL_VERSION 0x1F02 -#define GL_EXTENSIONS 0x1F03 - -/* TextureMagFilter */ -#define GL_NEAREST 0x2600 -#define GL_LINEAR 0x2601 - -/* TextureMinFilter */ -/* GL_NEAREST */ -/* GL_LINEAR */ -#define GL_NEAREST_MIPMAP_NEAREST 0x2700 -#define GL_LINEAR_MIPMAP_NEAREST 0x2701 -#define GL_NEAREST_MIPMAP_LINEAR 0x2702 -#define GL_LINEAR_MIPMAP_LINEAR 0x2703 - -/* TextureParameterName */ -#define GL_TEXTURE_MAG_FILTER 0x2800 -#define GL_TEXTURE_MIN_FILTER 0x2801 -#define GL_TEXTURE_WRAP_S 0x2802 -#define GL_TEXTURE_WRAP_T 0x2803 - -/* TextureTarget */ -/* GL_TEXTURE_2D */ -#define GL_TEXTURE 0x1702 - -#define GL_TEXTURE_CUBE_MAP 0x8513 -#define GL_TEXTURE_BINDING_CUBE_MAP 0x8514 -#define GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x8515 -#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x8516 -#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x8517 -#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x8518 -#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x8519 -#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x851A -#define GL_MAX_CUBE_MAP_TEXTURE_SIZE 0x851C - -/* TextureUnit */ -#define GL_TEXTURE0 0x84C0 -#define GL_TEXTURE1 0x84C1 -#define GL_TEXTURE2 0x84C2 -#define GL_TEXTURE3 0x84C3 -#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_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_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_TEXTURE30 0x84DE -#define GL_TEXTURE31 0x84DF -#define GL_ACTIVE_TEXTURE 0x84E0 - -/* TextureWrapMode */ -#define GL_REPEAT 0x2901 -#define GL_CLAMP_TO_EDGE 0x812F -#define GL_MIRRORED_REPEAT 0x8370 - -/* Uniform Types */ -#define GL_FLOAT_VEC2 0x8B50 -#define GL_FLOAT_VEC3 0x8B51 -#define GL_FLOAT_VEC4 0x8B52 -#define GL_INT_VEC2 0x8B53 -#define GL_INT_VEC3 0x8B54 -#define GL_INT_VEC4 0x8B55 -#define GL_BOOL 0x8B56 -#define GL_BOOL_VEC2 0x8B57 -#define GL_BOOL_VEC3 0x8B58 -#define GL_BOOL_VEC4 0x8B59 -#define GL_FLOAT_MAT2 0x8B5A -#define GL_FLOAT_MAT3 0x8B5B -#define GL_FLOAT_MAT4 0x8B5C -#define GL_SAMPLER_2D 0x8B5E -#define GL_SAMPLER_CUBE 0x8B60 - -/* Vertex Arrays */ -#define GL_VERTEX_ATTRIB_ARRAY_ENABLED 0x8622 -#define GL_VERTEX_ATTRIB_ARRAY_SIZE 0x8623 -#define GL_VERTEX_ATTRIB_ARRAY_STRIDE 0x8624 -#define GL_VERTEX_ATTRIB_ARRAY_TYPE 0x8625 -#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED 0x886A -#define GL_VERTEX_ATTRIB_ARRAY_POINTER 0x8645 -#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING 0x889F - -/* Read Format */ -#define GL_IMPLEMENTATION_COLOR_READ_TYPE 0x8B9A -#define GL_IMPLEMENTATION_COLOR_READ_FORMAT 0x8B9B - -/* Shader Source */ -#define GL_COMPILE_STATUS 0x8B81 -#define GL_INFO_LOG_LENGTH 0x8B84 -#define GL_SHADER_SOURCE_LENGTH 0x8B88 -#define GL_SHADER_COMPILER 0x8DFA - -/* Shader Binary */ -#define GL_SHADER_BINARY_FORMATS 0x8DF8 -#define GL_NUM_SHADER_BINARY_FORMATS 0x8DF9 - -/* Shader Precision-Specified Types */ -#define GL_LOW_FLOAT 0x8DF0 -#define GL_MEDIUM_FLOAT 0x8DF1 -#define GL_HIGH_FLOAT 0x8DF2 -#define GL_LOW_INT 0x8DF3 -#define GL_MEDIUM_INT 0x8DF4 -#define GL_HIGH_INT 0x8DF5 - -/* Framebuffer Object. */ -#define GL_FRAMEBUFFER 0x8D40 -#define GL_RENDERBUFFER 0x8D41 - -#define GL_RGBA4 0x8056 -#define GL_RGB5_A1 0x8057 -#define GL_RGB565 0x8D62 -#define GL_DEPTH_COMPONENT16 0x81A5 -#define GL_STENCIL_INDEX8 0x8D48 - -#define GL_RENDERBUFFER_WIDTH 0x8D42 -#define GL_RENDERBUFFER_HEIGHT 0x8D43 -#define GL_RENDERBUFFER_INTERNAL_FORMAT 0x8D44 -#define GL_RENDERBUFFER_RED_SIZE 0x8D50 -#define GL_RENDERBUFFER_GREEN_SIZE 0x8D51 -#define GL_RENDERBUFFER_BLUE_SIZE 0x8D52 -#define GL_RENDERBUFFER_ALPHA_SIZE 0x8D53 -#define GL_RENDERBUFFER_DEPTH_SIZE 0x8D54 -#define GL_RENDERBUFFER_STENCIL_SIZE 0x8D55 - -#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE 0x8CD0 -#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME 0x8CD1 -#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL 0x8CD2 -#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE 0x8CD3 - -#define GL_COLOR_ATTACHMENT0 0x8CE0 -#define GL_DEPTH_ATTACHMENT 0x8D00 -#define GL_STENCIL_ATTACHMENT 0x8D20 - -#define GL_NONE 0 - -#define GL_FRAMEBUFFER_COMPLETE 0x8CD5 -#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT 0x8CD6 -#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT 0x8CD7 -#define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS 0x8CD9 -#define GL_FRAMEBUFFER_UNSUPPORTED 0x8CDD - -#define GL_FRAMEBUFFER_BINDING 0x8CA6 -#define GL_RENDERBUFFER_BINDING 0x8CA7 -#define GL_MAX_RENDERBUFFER_SIZE 0x84E8 - -#define GL_INVALID_FRAMEBUFFER_OPERATION 0x0506 - -/* OpenGL ES 3.0 */ - -#define GL_READ_BUFFER 0x0C02 -#define GL_UNPACK_ROW_LENGTH 0x0CF2 -#define GL_UNPACK_SKIP_ROWS 0x0CF3 -#define GL_UNPACK_SKIP_PIXELS 0x0CF4 -#define GL_PACK_ROW_LENGTH 0x0D02 -#define GL_PACK_SKIP_ROWS 0x0D03 -#define GL_PACK_SKIP_PIXELS 0x0D04 -#define GL_COLOR 0x1800 -#define GL_DEPTH 0x1801 -#define GL_STENCIL 0x1802 -#define GL_RED 0x1903 -#define GL_RGB8 0x8051 -#define GL_RGBA8 0x8058 -#define GL_RGB10_A2 0x8059 -#define GL_TEXTURE_BINDING_3D 0x806A -#define GL_UNPACK_SKIP_IMAGES 0x806D -#define GL_UNPACK_IMAGE_HEIGHT 0x806E -#define GL_TEXTURE_3D 0x806F -#define GL_TEXTURE_WRAP_R 0x8072 -#define GL_MAX_3D_TEXTURE_SIZE 0x8073 -#define GL_UNSIGNED_INT_2_10_10_10_REV 0x8368 -#define GL_MAX_ELEMENTS_VERTICES 0x80E8 -#define GL_MAX_ELEMENTS_INDICES 0x80E9 -#define GL_TEXTURE_MIN_LOD 0x813A -#define GL_TEXTURE_MAX_LOD 0x813B -#define GL_TEXTURE_BASE_LEVEL 0x813C -#define GL_TEXTURE_MAX_LEVEL 0x813D -#define GL_MIN 0x8007 -#define GL_MAX 0x8008 -#define GL_DEPTH_COMPONENT24 0x81A6 -#define GL_MAX_TEXTURE_LOD_BIAS 0x84FD -#define GL_TEXTURE_COMPARE_MODE 0x884C -#define GL_TEXTURE_COMPARE_FUNC 0x884D -#define GL_CURRENT_QUERY 0x8865 -#define GL_QUERY_RESULT 0x8866 -#define GL_QUERY_RESULT_AVAILABLE 0x8867 -#define GL_BUFFER_MAPPED 0x88BC -#define GL_BUFFER_MAP_POINTER 0x88BD -#define GL_STREAM_READ 0x88E1 -#define GL_STREAM_COPY 0x88E2 -#define GL_STATIC_READ 0x88E5 -#define GL_STATIC_COPY 0x88E6 -#define GL_DYNAMIC_READ 0x88E9 -#define GL_DYNAMIC_COPY 0x88EA -#define GL_MAX_DRAW_BUFFERS 0x8824 -#define GL_DRAW_BUFFER0 0x8825 -#define GL_DRAW_BUFFER1 0x8826 -#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_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_MAX_FRAGMENT_UNIFORM_COMPONENTS 0x8B49 -#define GL_MAX_VERTEX_UNIFORM_COMPONENTS 0x8B4A -#define GL_SAMPLER_3D 0x8B5F -#define GL_SAMPLER_2D_SHADOW 0x8B62 -#define GL_FRAGMENT_SHADER_DERIVATIVE_HINT 0x8B8B -#define GL_PIXEL_PACK_BUFFER 0x88EB -#define GL_PIXEL_UNPACK_BUFFER 0x88EC -#define GL_PIXEL_PACK_BUFFER_BINDING 0x88ED -#define GL_PIXEL_UNPACK_BUFFER_BINDING 0x88EF -#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_SRGB 0x8C40 -#define GL_SRGB8 0x8C41 -#define GL_SRGB8_ALPHA8 0x8C43 -#define GL_COMPARE_REF_TO_TEXTURE 0x884E -#define GL_MAJOR_VERSION 0x821B -#define GL_MINOR_VERSION 0x821C -#define GL_NUM_EXTENSIONS 0x821D -#define GL_RGBA32F 0x8814 -#define GL_RGB32F 0x8815 -#define GL_RGBA16F 0x881A -#define GL_RGB16F 0x881B -#define GL_VERTEX_ATTRIB_ARRAY_INTEGER 0x88FD -#define GL_MAX_ARRAY_TEXTURE_LAYERS 0x88FF -#define GL_MIN_PROGRAM_TEXEL_OFFSET 0x8904 -#define GL_MAX_PROGRAM_TEXEL_OFFSET 0x8905 -#define GL_MAX_VARYING_COMPONENTS 0x8B4B -#define GL_TEXTURE_2D_ARRAY 0x8C1A -#define GL_TEXTURE_BINDING_2D_ARRAY 0x8C1D -#define GL_R11F_G11F_B10F 0x8C3A -#define GL_UNSIGNED_INT_10F_11F_11F_REV 0x8C3B -#define GL_RGB9_E5 0x8C3D -#define GL_UNSIGNED_INT_5_9_9_9_REV 0x8C3E -#define GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH 0x8C76 -#define GL_TRANSFORM_FEEDBACK_BUFFER_MODE 0x8C7F -#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS 0x8C80 -#define GL_TRANSFORM_FEEDBACK_VARYINGS 0x8C83 -#define GL_TRANSFORM_FEEDBACK_BUFFER_START 0x8C84 -#define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE 0x8C85 -#define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN 0x8C88 -#define GL_RASTERIZER_DISCARD 0x8C89 +typedef khronos_int64_t GLint64; +typedef khronos_uint64_t GLuint64; +typedef unsigned int GLenum; +typedef unsigned int GLuint; +typedef char GLchar; +typedef khronos_float_t GLfloat; +typedef khronos_ssize_t GLsizeiptr; +typedef khronos_intptr_t GLintptr; +typedef unsigned int GLbitfield; +typedef int GLint; +typedef unsigned char GLboolean; +typedef int GLsizei; +typedef khronos_uint8_t GLubyte; +#define GL_DEPTH_BUFFER_BIT 0x00000100 +#define GL_STENCIL_BUFFER_BIT 0x00000400 +#define GL_COLOR_BUFFER_BIT 0x00004000 +#define GL_FALSE 0 +#define GL_TRUE 1 +#define GL_POINTS 0x0000 +#define GL_LINES 0x0001 +#define GL_LINE_LOOP 0x0002 +#define GL_LINE_STRIP 0x0003 +#define GL_TRIANGLES 0x0004 +#define GL_TRIANGLE_STRIP 0x0005 +#define GL_TRIANGLE_FAN 0x0006 +#define GL_ZERO 0 +#define GL_ONE 1 +#define GL_SRC_COLOR 0x0300 +#define GL_ONE_MINUS_SRC_COLOR 0x0301 +#define GL_SRC_ALPHA 0x0302 +#define GL_ONE_MINUS_SRC_ALPHA 0x0303 +#define GL_DST_ALPHA 0x0304 +#define GL_ONE_MINUS_DST_ALPHA 0x0305 +#define GL_DST_COLOR 0x0306 +#define GL_ONE_MINUS_DST_COLOR 0x0307 +#define GL_SRC_ALPHA_SATURATE 0x0308 +#define GL_FUNC_ADD 0x8006 +#define GL_BLEND_EQUATION 0x8009 +#define GL_BLEND_EQUATION_RGB 0x8009 +#define GL_BLEND_EQUATION_ALPHA 0x883D +#define GL_FUNC_SUBTRACT 0x800A +#define GL_FUNC_REVERSE_SUBTRACT 0x800B +#define GL_BLEND_DST_RGB 0x80C8 +#define GL_BLEND_SRC_RGB 0x80C9 +#define GL_BLEND_DST_ALPHA 0x80CA +#define GL_BLEND_SRC_ALPHA 0x80CB +#define GL_CONSTANT_COLOR 0x8001 +#define GL_ONE_MINUS_CONSTANT_COLOR 0x8002 +#define GL_CONSTANT_ALPHA 0x8003 +#define GL_ONE_MINUS_CONSTANT_ALPHA 0x8004 +#define GL_BLEND_COLOR 0x8005 +#define GL_ARRAY_BUFFER 0x8892 +#define GL_ELEMENT_ARRAY_BUFFER 0x8893 +#define GL_ARRAY_BUFFER_BINDING 0x8894 +#define GL_ELEMENT_ARRAY_BUFFER_BINDING 0x8895 +#define GL_STREAM_DRAW 0x88E0 +#define GL_STATIC_DRAW 0x88E4 +#define GL_DYNAMIC_DRAW 0x88E8 +#define GL_BUFFER_SIZE 0x8764 +#define GL_BUFFER_USAGE 0x8765 +#define GL_CURRENT_VERTEX_ATTRIB 0x8626 +#define GL_FRONT 0x0404 +#define GL_BACK 0x0405 +#define GL_FRONT_AND_BACK 0x0408 +#define GL_TEXTURE_2D 0x0DE1 +#define GL_CULL_FACE 0x0B44 +#define GL_BLEND 0x0BE2 +#define GL_DITHER 0x0BD0 +#define GL_STENCIL_TEST 0x0B90 +#define GL_DEPTH_TEST 0x0B71 +#define GL_SCISSOR_TEST 0x0C11 +#define GL_POLYGON_OFFSET_FILL 0x8037 +#define GL_SAMPLE_ALPHA_TO_COVERAGE 0x809E +#define GL_SAMPLE_COVERAGE 0x80A0 +#define GL_NO_ERROR 0 +#define GL_INVALID_ENUM 0x0500 +#define GL_INVALID_VALUE 0x0501 +#define GL_INVALID_OPERATION 0x0502 +#define GL_OUT_OF_MEMORY 0x0505 +#define GL_CW 0x0900 +#define GL_CCW 0x0901 +#define GL_LINE_WIDTH 0x0B21 +#define GL_ALIASED_POINT_SIZE_RANGE 0x846D +#define GL_ALIASED_LINE_WIDTH_RANGE 0x846E +#define GL_CULL_FACE_MODE 0x0B45 +#define GL_FRONT_FACE 0x0B46 +#define GL_DEPTH_RANGE 0x0B70 +#define GL_DEPTH_WRITEMASK 0x0B72 +#define GL_DEPTH_CLEAR_VALUE 0x0B73 +#define GL_DEPTH_FUNC 0x0B74 +#define GL_STENCIL_CLEAR_VALUE 0x0B91 +#define GL_STENCIL_FUNC 0x0B92 +#define GL_STENCIL_FAIL 0x0B94 +#define GL_STENCIL_PASS_DEPTH_FAIL 0x0B95 +#define GL_STENCIL_PASS_DEPTH_PASS 0x0B96 +#define GL_STENCIL_REF 0x0B97 +#define GL_STENCIL_VALUE_MASK 0x0B93 +#define GL_STENCIL_WRITEMASK 0x0B98 +#define GL_STENCIL_BACK_FUNC 0x8800 +#define GL_STENCIL_BACK_FAIL 0x8801 +#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_VIEWPORT 0x0BA2 +#define GL_SCISSOR_BOX 0x0C10 +#define GL_COLOR_CLEAR_VALUE 0x0C22 +#define GL_COLOR_WRITEMASK 0x0C23 +#define GL_UNPACK_ALIGNMENT 0x0CF5 +#define GL_PACK_ALIGNMENT 0x0D05 +#define GL_MAX_TEXTURE_SIZE 0x0D33 +#define GL_MAX_VIEWPORT_DIMS 0x0D3A +#define GL_SUBPIXEL_BITS 0x0D50 +#define GL_RED_BITS 0x0D52 +#define GL_GREEN_BITS 0x0D53 +#define GL_BLUE_BITS 0x0D54 +#define GL_ALPHA_BITS 0x0D55 +#define GL_DEPTH_BITS 0x0D56 +#define GL_STENCIL_BITS 0x0D57 +#define GL_POLYGON_OFFSET_UNITS 0x2A00 +#define GL_POLYGON_OFFSET_FACTOR 0x8038 +#define GL_TEXTURE_BINDING_2D 0x8069 +#define GL_SAMPLE_BUFFERS 0x80A8 +#define GL_SAMPLES 0x80A9 +#define GL_SAMPLE_COVERAGE_VALUE 0x80AA +#define GL_SAMPLE_COVERAGE_INVERT 0x80AB +#define GL_NUM_COMPRESSED_TEXTURE_FORMATS 0x86A2 +#define GL_COMPRESSED_TEXTURE_FORMATS 0x86A3 +#define GL_DONT_CARE 0x1100 +#define GL_FASTEST 0x1101 +#define GL_NICEST 0x1102 +#define GL_GENERATE_MIPMAP_HINT 0x8192 +#define GL_BYTE 0x1400 +#define GL_UNSIGNED_BYTE 0x1401 +#define GL_SHORT 0x1402 +#define GL_UNSIGNED_SHORT 0x1403 +#define GL_INT 0x1404 +#define GL_UNSIGNED_INT 0x1405 +#define GL_FLOAT 0x1406 +#define GL_FIXED 0x140C +#define GL_DEPTH_COMPONENT 0x1902 +#define GL_ALPHA 0x1906 +#define GL_RGB 0x1907 +#define GL_RGBA 0x1908 +#define GL_LUMINANCE 0x1909 +#define GL_LUMINANCE_ALPHA 0x190A +#define GL_UNSIGNED_SHORT_4_4_4_4 0x8033 +#define GL_UNSIGNED_SHORT_5_5_5_1 0x8034 +#define GL_UNSIGNED_SHORT_5_6_5 0x8363 +#define GL_FRAGMENT_SHADER 0x8B30 +#define GL_VERTEX_SHADER 0x8B31 +#define GL_MAX_VERTEX_ATTRIBS 0x8869 +#define GL_MAX_VERTEX_UNIFORM_VECTORS 0x8DFB +#define GL_MAX_VARYING_VECTORS 0x8DFC +#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS 0x8B4D +#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS 0x8B4C +#define GL_MAX_TEXTURE_IMAGE_UNITS 0x8872 +#define GL_MAX_FRAGMENT_UNIFORM_VECTORS 0x8DFD +#define GL_SHADER_TYPE 0x8B4F +#define GL_DELETE_STATUS 0x8B80 +#define GL_LINK_STATUS 0x8B82 +#define GL_VALIDATE_STATUS 0x8B83 +#define GL_ATTACHED_SHADERS 0x8B85 +#define GL_ACTIVE_UNIFORMS 0x8B86 +#define GL_ACTIVE_UNIFORM_MAX_LENGTH 0x8B87 +#define GL_ACTIVE_ATTRIBUTES 0x8B89 +#define GL_ACTIVE_ATTRIBUTE_MAX_LENGTH 0x8B8A +#define GL_SHADING_LANGUAGE_VERSION 0x8B8C +#define GL_CURRENT_PROGRAM 0x8B8D +#define GL_NEVER 0x0200 +#define GL_LESS 0x0201 +#define GL_EQUAL 0x0202 +#define GL_LEQUAL 0x0203 +#define GL_GREATER 0x0204 +#define GL_NOTEQUAL 0x0205 +#define GL_GEQUAL 0x0206 +#define GL_ALWAYS 0x0207 +#define GL_KEEP 0x1E00 +#define GL_REPLACE 0x1E01 +#define GL_INCR 0x1E02 +#define GL_DECR 0x1E03 +#define GL_INVERT 0x150A +#define GL_INCR_WRAP 0x8507 +#define GL_DECR_WRAP 0x8508 +#define GL_VENDOR 0x1F00 +#define GL_RENDERER 0x1F01 +#define GL_VERSION 0x1F02 +#define GL_EXTENSIONS 0x1F03 +#define GL_NEAREST 0x2600 +#define GL_LINEAR 0x2601 +#define GL_NEAREST_MIPMAP_NEAREST 0x2700 +#define GL_LINEAR_MIPMAP_NEAREST 0x2701 +#define GL_NEAREST_MIPMAP_LINEAR 0x2702 +#define GL_LINEAR_MIPMAP_LINEAR 0x2703 +#define GL_TEXTURE_MAG_FILTER 0x2800 +#define GL_TEXTURE_MIN_FILTER 0x2801 +#define GL_TEXTURE_WRAP_S 0x2802 +#define GL_TEXTURE_WRAP_T 0x2803 +#define GL_TEXTURE 0x1702 +#define GL_TEXTURE_CUBE_MAP 0x8513 +#define GL_TEXTURE_BINDING_CUBE_MAP 0x8514 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x8515 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x8516 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x8517 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x8518 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x8519 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x851A +#define GL_MAX_CUBE_MAP_TEXTURE_SIZE 0x851C +#define GL_TEXTURE0 0x84C0 +#define GL_TEXTURE1 0x84C1 +#define GL_TEXTURE2 0x84C2 +#define GL_TEXTURE3 0x84C3 +#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_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_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_TEXTURE30 0x84DE +#define GL_TEXTURE31 0x84DF +#define GL_ACTIVE_TEXTURE 0x84E0 +#define GL_REPEAT 0x2901 +#define GL_CLAMP_TO_EDGE 0x812F +#define GL_MIRRORED_REPEAT 0x8370 +#define GL_FLOAT_VEC2 0x8B50 +#define GL_FLOAT_VEC3 0x8B51 +#define GL_FLOAT_VEC4 0x8B52 +#define GL_INT_VEC2 0x8B53 +#define GL_INT_VEC3 0x8B54 +#define GL_INT_VEC4 0x8B55 +#define GL_BOOL 0x8B56 +#define GL_BOOL_VEC2 0x8B57 +#define GL_BOOL_VEC3 0x8B58 +#define GL_BOOL_VEC4 0x8B59 +#define GL_FLOAT_MAT2 0x8B5A +#define GL_FLOAT_MAT3 0x8B5B +#define GL_FLOAT_MAT4 0x8B5C +#define GL_SAMPLER_2D 0x8B5E +#define GL_SAMPLER_CUBE 0x8B60 +#define GL_VERTEX_ATTRIB_ARRAY_ENABLED 0x8622 +#define GL_VERTEX_ATTRIB_ARRAY_SIZE 0x8623 +#define GL_VERTEX_ATTRIB_ARRAY_STRIDE 0x8624 +#define GL_VERTEX_ATTRIB_ARRAY_TYPE 0x8625 +#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED 0x886A +#define GL_VERTEX_ATTRIB_ARRAY_POINTER 0x8645 +#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING 0x889F +#define GL_IMPLEMENTATION_COLOR_READ_TYPE 0x8B9A +#define GL_IMPLEMENTATION_COLOR_READ_FORMAT 0x8B9B +#define GL_COMPILE_STATUS 0x8B81 +#define GL_INFO_LOG_LENGTH 0x8B84 +#define GL_SHADER_SOURCE_LENGTH 0x8B88 +#define GL_SHADER_COMPILER 0x8DFA +#define GL_SHADER_BINARY_FORMATS 0x8DF8 +#define GL_NUM_SHADER_BINARY_FORMATS 0x8DF9 +#define GL_LOW_FLOAT 0x8DF0 +#define GL_MEDIUM_FLOAT 0x8DF1 +#define GL_HIGH_FLOAT 0x8DF2 +#define GL_LOW_INT 0x8DF3 +#define GL_MEDIUM_INT 0x8DF4 +#define GL_HIGH_INT 0x8DF5 +#define GL_FRAMEBUFFER 0x8D40 +#define GL_RENDERBUFFER 0x8D41 +#define GL_RGBA4 0x8056 +#define GL_RGB5_A1 0x8057 +#define GL_RGB565 0x8D62 +#define GL_DEPTH_COMPONENT16 0x81A5 +#define GL_STENCIL_INDEX8 0x8D48 +#define GL_RENDERBUFFER_WIDTH 0x8D42 +#define GL_RENDERBUFFER_HEIGHT 0x8D43 +#define GL_RENDERBUFFER_INTERNAL_FORMAT 0x8D44 +#define GL_RENDERBUFFER_RED_SIZE 0x8D50 +#define GL_RENDERBUFFER_GREEN_SIZE 0x8D51 +#define GL_RENDERBUFFER_BLUE_SIZE 0x8D52 +#define GL_RENDERBUFFER_ALPHA_SIZE 0x8D53 +#define GL_RENDERBUFFER_DEPTH_SIZE 0x8D54 +#define GL_RENDERBUFFER_STENCIL_SIZE 0x8D55 +#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE 0x8CD0 +#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME 0x8CD1 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL 0x8CD2 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE 0x8CD3 +#define GL_COLOR_ATTACHMENT0 0x8CE0 +#define GL_DEPTH_ATTACHMENT 0x8D00 +#define GL_STENCIL_ATTACHMENT 0x8D20 +#define GL_NONE 0 +#define GL_FRAMEBUFFER_COMPLETE 0x8CD5 +#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT 0x8CD6 +#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT 0x8CD7 +#define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS 0x8CD9 +#define GL_FRAMEBUFFER_UNSUPPORTED 0x8CDD +#define GL_FRAMEBUFFER_BINDING 0x8CA6 +#define GL_RENDERBUFFER_BINDING 0x8CA7 +#define GL_MAX_RENDERBUFFER_SIZE 0x84E8 +#define GL_INVALID_FRAMEBUFFER_OPERATION 0x0506 +typedef void (GL_APIENTRYP PFNGLACTIVETEXTUREPROC) (GLenum texture); +typedef void (GL_APIENTRYP PFNGLATTACHSHADERPROC) (GLuint program, GLuint shader); +typedef void (GL_APIENTRYP PFNGLBINDATTRIBLOCATIONPROC) (GLuint program, GLuint index, const GLchar *name); +typedef void (GL_APIENTRYP PFNGLBINDBUFFERPROC) (GLenum target, GLuint buffer); +typedef void (GL_APIENTRYP PFNGLBINDFRAMEBUFFERPROC) (GLenum target, GLuint framebuffer); +typedef void (GL_APIENTRYP PFNGLBINDRENDERBUFFERPROC) (GLenum target, GLuint renderbuffer); +typedef void (GL_APIENTRYP PFNGLBINDTEXTUREPROC) (GLenum target, GLuint texture); +typedef void (GL_APIENTRYP PFNGLBLENDCOLORPROC) (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); +typedef void (GL_APIENTRYP PFNGLBLENDEQUATIONPROC) (GLenum mode); +typedef void (GL_APIENTRYP PFNGLBLENDEQUATIONSEPARATEPROC) (GLenum modeRGB, GLenum modeAlpha); +typedef void (GL_APIENTRYP PFNGLBLENDFUNCPROC) (GLenum sfactor, GLenum dfactor); +typedef void (GL_APIENTRYP PFNGLBLENDFUNCSEPARATEPROC) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); +typedef void (GL_APIENTRYP PFNGLBUFFERDATAPROC) (GLenum target, GLsizeiptr size, const void *data, GLenum usage); +typedef void (GL_APIENTRYP PFNGLBUFFERSUBDATAPROC) (GLenum target, GLintptr offset, GLsizeiptr size, const void *data); +typedef GLenum (GL_APIENTRYP PFNGLCHECKFRAMEBUFFERSTATUSPROC) (GLenum target); +typedef void (GL_APIENTRYP PFNGLCLEARPROC) (GLbitfield mask); +typedef void (GL_APIENTRYP PFNGLCLEARCOLORPROC) (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); +typedef void (GL_APIENTRYP PFNGLCLEARDEPTHFPROC) (GLfloat d); +typedef void (GL_APIENTRYP PFNGLCLEARSTENCILPROC) (GLint s); +typedef void (GL_APIENTRYP PFNGLCOLORMASKPROC) (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); +typedef void (GL_APIENTRYP PFNGLCOMPILESHADERPROC) (GLuint shader); +typedef void (GL_APIENTRYP PFNGLCOMPRESSEDTEXIMAGE2DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void *data); +typedef void (GL_APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *data); +typedef void (GL_APIENTRYP PFNGLCOPYTEXIMAGE2DPROC) (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); +typedef void (GL_APIENTRYP PFNGLCOPYTEXSUBIMAGE2DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); +typedef GLuint (GL_APIENTRYP PFNGLCREATEPROGRAMPROC) (void); +typedef GLuint (GL_APIENTRYP PFNGLCREATESHADERPROC) (GLenum type); +typedef void (GL_APIENTRYP PFNGLCULLFACEPROC) (GLenum mode); +typedef void (GL_APIENTRYP PFNGLDELETEBUFFERSPROC) (GLsizei n, const GLuint *buffers); +typedef void (GL_APIENTRYP PFNGLDELETEFRAMEBUFFERSPROC) (GLsizei n, const GLuint *framebuffers); +typedef void (GL_APIENTRYP PFNGLDELETEPROGRAMPROC) (GLuint program); +typedef void (GL_APIENTRYP PFNGLDELETERENDERBUFFERSPROC) (GLsizei n, const GLuint *renderbuffers); +typedef void (GL_APIENTRYP PFNGLDELETESHADERPROC) (GLuint shader); +typedef void (GL_APIENTRYP PFNGLDELETETEXTURESPROC) (GLsizei n, const GLuint *textures); +typedef void (GL_APIENTRYP PFNGLDEPTHFUNCPROC) (GLenum func); +typedef void (GL_APIENTRYP PFNGLDEPTHMASKPROC) (GLboolean flag); +typedef void (GL_APIENTRYP PFNGLDEPTHRANGEFPROC) (GLfloat n, GLfloat f); +typedef void (GL_APIENTRYP PFNGLDETACHSHADERPROC) (GLuint program, GLuint shader); +typedef void (GL_APIENTRYP PFNGLDISABLEPROC) (GLenum cap); +typedef void (GL_APIENTRYP PFNGLDISABLEVERTEXATTRIBARRAYPROC) (GLuint index); +typedef void (GL_APIENTRYP PFNGLDRAWARRAYSPROC) (GLenum mode, GLint first, GLsizei count); +typedef void (GL_APIENTRYP PFNGLDRAWELEMENTSPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices); +typedef void (GL_APIENTRYP PFNGLENABLEPROC) (GLenum cap); +typedef void (GL_APIENTRYP PFNGLENABLEVERTEXATTRIBARRAYPROC) (GLuint index); +typedef void (GL_APIENTRYP PFNGLFINISHPROC) (void); +typedef void (GL_APIENTRYP PFNGLFLUSHPROC) (void); +typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERRENDERBUFFERPROC) (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); +typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERTEXTURE2DPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +typedef void (GL_APIENTRYP PFNGLFRONTFACEPROC) (GLenum mode); +typedef void (GL_APIENTRYP PFNGLGENBUFFERSPROC) (GLsizei n, GLuint *buffers); +typedef void (GL_APIENTRYP PFNGLGENERATEMIPMAPPROC) (GLenum target); +typedef void (GL_APIENTRYP PFNGLGENFRAMEBUFFERSPROC) (GLsizei n, GLuint *framebuffers); +typedef void (GL_APIENTRYP PFNGLGENRENDERBUFFERSPROC) (GLsizei n, GLuint *renderbuffers); +typedef void (GL_APIENTRYP PFNGLGENTEXTURESPROC) (GLsizei n, GLuint *textures); +typedef void (GL_APIENTRYP PFNGLGETACTIVEATTRIBPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name); +typedef void (GL_APIENTRYP PFNGLGETACTIVEUNIFORMPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name); +typedef void (GL_APIENTRYP PFNGLGETATTACHEDSHADERSPROC) (GLuint program, GLsizei maxCount, GLsizei *count, GLuint *shaders); +typedef GLint (GL_APIENTRYP PFNGLGETATTRIBLOCATIONPROC) (GLuint program, const GLchar *name); +typedef void (GL_APIENTRYP PFNGLGETBOOLEANVPROC) (GLenum pname, GLboolean *data); +typedef void (GL_APIENTRYP PFNGLGETBUFFERPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); +typedef GLenum (GL_APIENTRYP PFNGLGETERRORPROC) (void); +typedef void (GL_APIENTRYP PFNGLGETFLOATVPROC) (GLenum pname, GLfloat *data); +typedef void (GL_APIENTRYP PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC) (GLenum target, GLenum attachment, GLenum pname, GLint *params); +typedef void (GL_APIENTRYP PFNGLGETINTEGERVPROC) (GLenum pname, GLint *data); +typedef void (GL_APIENTRYP PFNGLGETPROGRAMIVPROC) (GLuint program, GLenum pname, GLint *params); +typedef void (GL_APIENTRYP PFNGLGETPROGRAMINFOLOGPROC) (GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog); +typedef void (GL_APIENTRYP PFNGLGETRENDERBUFFERPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (GL_APIENTRYP PFNGLGETSHADERIVPROC) (GLuint shader, GLenum pname, GLint *params); +typedef void (GL_APIENTRYP PFNGLGETSHADERINFOLOGPROC) (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog); +typedef void (GL_APIENTRYP PFNGLGETSHADERPRECISIONFORMATPROC) (GLenum shadertype, GLenum precisiontype, GLint *range, GLint *precision); +typedef void (GL_APIENTRYP PFNGLGETSHADERSOURCEPROC) (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *source); +typedef const GLubyte *(GL_APIENTRYP PFNGLGETSTRINGPROC) (GLenum name); +typedef void (GL_APIENTRYP PFNGLGETTEXPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params); +typedef void (GL_APIENTRYP PFNGLGETTEXPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (GL_APIENTRYP PFNGLGETUNIFORMFVPROC) (GLuint program, GLint location, GLfloat *params); +typedef void (GL_APIENTRYP PFNGLGETUNIFORMIVPROC) (GLuint program, GLint location, GLint *params); +typedef GLint (GL_APIENTRYP PFNGLGETUNIFORMLOCATIONPROC) (GLuint program, const GLchar *name); +typedef void (GL_APIENTRYP PFNGLGETVERTEXATTRIBFVPROC) (GLuint index, GLenum pname, GLfloat *params); +typedef void (GL_APIENTRYP PFNGLGETVERTEXATTRIBIVPROC) (GLuint index, GLenum pname, GLint *params); +typedef void (GL_APIENTRYP PFNGLGETVERTEXATTRIBPOINTERVPROC) (GLuint index, GLenum pname, void **pointer); +typedef void (GL_APIENTRYP PFNGLHINTPROC) (GLenum target, GLenum mode); +typedef GLboolean (GL_APIENTRYP PFNGLISBUFFERPROC) (GLuint buffer); +typedef GLboolean (GL_APIENTRYP PFNGLISENABLEDPROC) (GLenum cap); +typedef GLboolean (GL_APIENTRYP PFNGLISFRAMEBUFFERPROC) (GLuint framebuffer); +typedef GLboolean (GL_APIENTRYP PFNGLISPROGRAMPROC) (GLuint program); +typedef GLboolean (GL_APIENTRYP PFNGLISRENDERBUFFERPROC) (GLuint renderbuffer); +typedef GLboolean (GL_APIENTRYP PFNGLISSHADERPROC) (GLuint shader); +typedef GLboolean (GL_APIENTRYP PFNGLISTEXTUREPROC) (GLuint texture); +typedef void (GL_APIENTRYP PFNGLLINEWIDTHPROC) (GLfloat width); +typedef void (GL_APIENTRYP PFNGLLINKPROGRAMPROC) (GLuint program); +typedef void (GL_APIENTRYP PFNGLPIXELSTOREIPROC) (GLenum pname, GLint param); +typedef void (GL_APIENTRYP PFNGLPOLYGONOFFSETPROC) (GLfloat factor, GLfloat units); +typedef void (GL_APIENTRYP PFNGLREADPIXELSPROC) (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void *pixels); +typedef void (GL_APIENTRYP PFNGLRELEASESHADERCOMPILERPROC) (void); +typedef void (GL_APIENTRYP PFNGLRENDERBUFFERSTORAGEPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (GL_APIENTRYP PFNGLSAMPLECOVERAGEPROC) (GLfloat value, GLboolean invert); +typedef void (GL_APIENTRYP PFNGLSCISSORPROC) (GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (GL_APIENTRYP PFNGLSHADERBINARYPROC) (GLsizei count, const GLuint *shaders, GLenum binaryformat, const void *binary, GLsizei length); +typedef void (GL_APIENTRYP PFNGLSHADERSOURCEPROC) (GLuint shader, GLsizei count, const GLchar *const*string, const GLint *length); +typedef void (GL_APIENTRYP PFNGLSTENCILFUNCPROC) (GLenum func, GLint ref, GLuint mask); +typedef void (GL_APIENTRYP PFNGLSTENCILFUNCSEPARATEPROC) (GLenum face, GLenum func, GLint ref, GLuint mask); +typedef void (GL_APIENTRYP PFNGLSTENCILMASKPROC) (GLuint mask); +typedef void (GL_APIENTRYP PFNGLSTENCILMASKSEPARATEPROC) (GLenum face, GLuint mask); +typedef void (GL_APIENTRYP PFNGLSTENCILOPPROC) (GLenum fail, GLenum zfail, GLenum zpass); +typedef void (GL_APIENTRYP PFNGLSTENCILOPSEPARATEPROC) (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass); +typedef void (GL_APIENTRYP PFNGLTEXIMAGE2DPROC) (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels); +typedef void (GL_APIENTRYP PFNGLTEXPARAMETERFPROC) (GLenum target, GLenum pname, GLfloat param); +typedef void (GL_APIENTRYP PFNGLTEXPARAMETERFVPROC) (GLenum target, GLenum pname, const GLfloat *params); +typedef void (GL_APIENTRYP PFNGLTEXPARAMETERIPROC) (GLenum target, GLenum pname, GLint param); +typedef void (GL_APIENTRYP PFNGLTEXPARAMETERIVPROC) (GLenum target, GLenum pname, const GLint *params); +typedef void (GL_APIENTRYP PFNGLTEXSUBIMAGE2DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels); +typedef void (GL_APIENTRYP PFNGLUNIFORM1FPROC) (GLint location, GLfloat v0); +typedef void (GL_APIENTRYP PFNGLUNIFORM1FVPROC) (GLint location, GLsizei count, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLUNIFORM1IPROC) (GLint location, GLint v0); +typedef void (GL_APIENTRYP PFNGLUNIFORM1IVPROC) (GLint location, GLsizei count, const GLint *value); +typedef void (GL_APIENTRYP PFNGLUNIFORM2FPROC) (GLint location, GLfloat v0, GLfloat v1); +typedef void (GL_APIENTRYP PFNGLUNIFORM2FVPROC) (GLint location, GLsizei count, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLUNIFORM2IPROC) (GLint location, GLint v0, GLint v1); +typedef void (GL_APIENTRYP PFNGLUNIFORM2IVPROC) (GLint location, GLsizei count, const GLint *value); +typedef void (GL_APIENTRYP PFNGLUNIFORM3FPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2); +typedef void (GL_APIENTRYP PFNGLUNIFORM3FVPROC) (GLint location, GLsizei count, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLUNIFORM3IPROC) (GLint location, GLint v0, GLint v1, GLint v2); +typedef void (GL_APIENTRYP PFNGLUNIFORM3IVPROC) (GLint location, GLsizei count, const GLint *value); +typedef void (GL_APIENTRYP PFNGLUNIFORM4FPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); +typedef void (GL_APIENTRYP PFNGLUNIFORM4FVPROC) (GLint location, GLsizei count, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLUNIFORM4IPROC) (GLint location, GLint v0, GLint v1, GLint v2, GLint v3); +typedef void (GL_APIENTRYP PFNGLUNIFORM4IVPROC) (GLint location, GLsizei count, const GLint *value); +typedef void (GL_APIENTRYP PFNGLUNIFORMMATRIX2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLUNIFORMMATRIX3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLUNIFORMMATRIX4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLUSEPROGRAMPROC) (GLuint program); +typedef void (GL_APIENTRYP PFNGLVALIDATEPROGRAMPROC) (GLuint program); +typedef void (GL_APIENTRYP PFNGLVERTEXATTRIB1FPROC) (GLuint index, GLfloat x); +typedef void (GL_APIENTRYP PFNGLVERTEXATTRIB1FVPROC) (GLuint index, const GLfloat *v); +typedef void (GL_APIENTRYP PFNGLVERTEXATTRIB2FPROC) (GLuint index, GLfloat x, GLfloat y); +typedef void (GL_APIENTRYP PFNGLVERTEXATTRIB2FVPROC) (GLuint index, const GLfloat *v); +typedef void (GL_APIENTRYP PFNGLVERTEXATTRIB3FPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z); +typedef void (GL_APIENTRYP PFNGLVERTEXATTRIB3FVPROC) (GLuint index, const GLfloat *v); +typedef void (GL_APIENTRYP PFNGLVERTEXATTRIB4FPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (GL_APIENTRYP PFNGLVERTEXATTRIB4FVPROC) (GLuint index, const GLfloat *v); +typedef void (GL_APIENTRYP PFNGLVERTEXATTRIBPOINTERPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer); +typedef void (GL_APIENTRYP PFNGLVIEWPORTPROC) (GLint x, GLint y, GLsizei width, GLsizei height); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glActiveTexture (GLenum texture); +GL_APICALL void GL_APIENTRY glAttachShader (GLuint program, GLuint shader); +GL_APICALL void GL_APIENTRY glBindAttribLocation (GLuint program, GLuint index, const GLchar *name); +GL_APICALL void GL_APIENTRY glBindBuffer (GLenum target, GLuint buffer); +GL_APICALL void GL_APIENTRY glBindFramebuffer (GLenum target, GLuint framebuffer); +GL_APICALL void GL_APIENTRY glBindRenderbuffer (GLenum target, GLuint renderbuffer); +GL_APICALL void GL_APIENTRY glBindTexture (GLenum target, GLuint texture); +GL_APICALL void GL_APIENTRY glBlendColor (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); +GL_APICALL void GL_APIENTRY glBlendEquation (GLenum mode); +GL_APICALL void GL_APIENTRY glBlendEquationSeparate (GLenum modeRGB, GLenum modeAlpha); +GL_APICALL void GL_APIENTRY glBlendFunc (GLenum sfactor, GLenum dfactor); +GL_APICALL void GL_APIENTRY glBlendFuncSeparate (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); +GL_APICALL void GL_APIENTRY glBufferData (GLenum target, GLsizeiptr size, const void *data, GLenum usage); +GL_APICALL void GL_APIENTRY glBufferSubData (GLenum target, GLintptr offset, GLsizeiptr size, const void *data); +GL_APICALL GLenum GL_APIENTRY glCheckFramebufferStatus (GLenum target); +GL_APICALL void GL_APIENTRY glClear (GLbitfield mask); +GL_APICALL void GL_APIENTRY glClearColor (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); +GL_APICALL void GL_APIENTRY glClearDepthf (GLfloat d); +GL_APICALL void GL_APIENTRY glClearStencil (GLint s); +GL_APICALL void GL_APIENTRY glColorMask (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); +GL_APICALL void GL_APIENTRY glCompileShader (GLuint shader); +GL_APICALL void GL_APIENTRY glCompressedTexImage2D (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void *data); +GL_APICALL void GL_APIENTRY glCompressedTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *data); +GL_APICALL void GL_APIENTRY glCopyTexImage2D (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); +GL_APICALL void GL_APIENTRY glCopyTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); +GL_APICALL GLuint GL_APIENTRY glCreateProgram (void); +GL_APICALL GLuint GL_APIENTRY glCreateShader (GLenum type); +GL_APICALL void GL_APIENTRY glCullFace (GLenum mode); +GL_APICALL void GL_APIENTRY glDeleteBuffers (GLsizei n, const GLuint *buffers); +GL_APICALL void GL_APIENTRY glDeleteFramebuffers (GLsizei n, const GLuint *framebuffers); +GL_APICALL void GL_APIENTRY glDeleteProgram (GLuint program); +GL_APICALL void GL_APIENTRY glDeleteRenderbuffers (GLsizei n, const GLuint *renderbuffers); +GL_APICALL void GL_APIENTRY glDeleteShader (GLuint shader); +GL_APICALL void GL_APIENTRY glDeleteTextures (GLsizei n, const GLuint *textures); +GL_APICALL void GL_APIENTRY glDepthFunc (GLenum func); +GL_APICALL void GL_APIENTRY glDepthMask (GLboolean flag); +GL_APICALL void GL_APIENTRY glDepthRangef (GLfloat n, GLfloat f); +GL_APICALL void GL_APIENTRY glDetachShader (GLuint program, GLuint shader); +GL_APICALL void GL_APIENTRY glDisable (GLenum cap); +GL_APICALL void GL_APIENTRY glDisableVertexAttribArray (GLuint index); +GL_APICALL void GL_APIENTRY glDrawArrays (GLenum mode, GLint first, GLsizei count); +GL_APICALL void GL_APIENTRY glDrawElements (GLenum mode, GLsizei count, GLenum type, const void *indices); +GL_APICALL void GL_APIENTRY glEnable (GLenum cap); +GL_APICALL void GL_APIENTRY glEnableVertexAttribArray (GLuint index); +GL_APICALL void GL_APIENTRY glFinish (void); +GL_APICALL void GL_APIENTRY glFlush (void); +GL_APICALL void GL_APIENTRY glFramebufferRenderbuffer (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); +GL_APICALL void GL_APIENTRY glFramebufferTexture2D (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +GL_APICALL void GL_APIENTRY glFrontFace (GLenum mode); +GL_APICALL void GL_APIENTRY glGenBuffers (GLsizei n, GLuint *buffers); +GL_APICALL void GL_APIENTRY glGenerateMipmap (GLenum target); +GL_APICALL void GL_APIENTRY glGenFramebuffers (GLsizei n, GLuint *framebuffers); +GL_APICALL void GL_APIENTRY glGenRenderbuffers (GLsizei n, GLuint *renderbuffers); +GL_APICALL void GL_APIENTRY glGenTextures (GLsizei n, GLuint *textures); +GL_APICALL void GL_APIENTRY glGetActiveAttrib (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name); +GL_APICALL void GL_APIENTRY glGetActiveUniform (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name); +GL_APICALL void GL_APIENTRY glGetAttachedShaders (GLuint program, GLsizei maxCount, GLsizei *count, GLuint *shaders); +GL_APICALL GLint GL_APIENTRY glGetAttribLocation (GLuint program, const GLchar *name); +GL_APICALL void GL_APIENTRY glGetBooleanv (GLenum pname, GLboolean *data); +GL_APICALL void GL_APIENTRY glGetBufferParameteriv (GLenum target, GLenum pname, GLint *params); +GL_APICALL GLenum GL_APIENTRY glGetError (void); +GL_APICALL void GL_APIENTRY glGetFloatv (GLenum pname, GLfloat *data); +GL_APICALL void GL_APIENTRY glGetFramebufferAttachmentParameteriv (GLenum target, GLenum attachment, GLenum pname, GLint *params); +GL_APICALL void GL_APIENTRY glGetIntegerv (GLenum pname, GLint *data); +GL_APICALL void GL_APIENTRY glGetProgramiv (GLuint program, GLenum pname, GLint *params); +GL_APICALL void GL_APIENTRY glGetProgramInfoLog (GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog); +GL_APICALL void GL_APIENTRY glGetRenderbufferParameteriv (GLenum target, GLenum pname, GLint *params); +GL_APICALL void GL_APIENTRY glGetShaderiv (GLuint shader, GLenum pname, GLint *params); +GL_APICALL void GL_APIENTRY glGetShaderInfoLog (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog); +GL_APICALL void GL_APIENTRY glGetShaderPrecisionFormat (GLenum shadertype, GLenum precisiontype, GLint *range, GLint *precision); +GL_APICALL void GL_APIENTRY glGetShaderSource (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *source); +GL_APICALL const GLubyte *GL_APIENTRY glGetString (GLenum name); +GL_APICALL void GL_APIENTRY glGetTexParameterfv (GLenum target, GLenum pname, GLfloat *params); +GL_APICALL void GL_APIENTRY glGetTexParameteriv (GLenum target, GLenum pname, GLint *params); +GL_APICALL void GL_APIENTRY glGetUniformfv (GLuint program, GLint location, GLfloat *params); +GL_APICALL void GL_APIENTRY glGetUniformiv (GLuint program, GLint location, GLint *params); +GL_APICALL GLint GL_APIENTRY glGetUniformLocation (GLuint program, const GLchar *name); +GL_APICALL void GL_APIENTRY glGetVertexAttribfv (GLuint index, GLenum pname, GLfloat *params); +GL_APICALL void GL_APIENTRY glGetVertexAttribiv (GLuint index, GLenum pname, GLint *params); +GL_APICALL void GL_APIENTRY glGetVertexAttribPointerv (GLuint index, GLenum pname, void **pointer); +GL_APICALL void GL_APIENTRY glHint (GLenum target, GLenum mode); +GL_APICALL GLboolean GL_APIENTRY glIsBuffer (GLuint buffer); +GL_APICALL GLboolean GL_APIENTRY glIsEnabled (GLenum cap); +GL_APICALL GLboolean GL_APIENTRY glIsFramebuffer (GLuint framebuffer); +GL_APICALL GLboolean GL_APIENTRY glIsProgram (GLuint program); +GL_APICALL GLboolean GL_APIENTRY glIsRenderbuffer (GLuint renderbuffer); +GL_APICALL GLboolean GL_APIENTRY glIsShader (GLuint shader); +GL_APICALL GLboolean GL_APIENTRY glIsTexture (GLuint texture); +GL_APICALL void GL_APIENTRY glLineWidth (GLfloat width); +GL_APICALL void GL_APIENTRY glLinkProgram (GLuint program); +GL_APICALL void GL_APIENTRY glPixelStorei (GLenum pname, GLint param); +GL_APICALL void GL_APIENTRY glPolygonOffset (GLfloat factor, GLfloat units); +GL_APICALL void GL_APIENTRY glReadPixels (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void *pixels); +GL_APICALL void GL_APIENTRY glReleaseShaderCompiler (void); +GL_APICALL void GL_APIENTRY glRenderbufferStorage (GLenum target, GLenum internalformat, GLsizei width, GLsizei height); +GL_APICALL void GL_APIENTRY glSampleCoverage (GLfloat value, GLboolean invert); +GL_APICALL void GL_APIENTRY glScissor (GLint x, GLint y, GLsizei width, GLsizei height); +GL_APICALL void GL_APIENTRY glShaderBinary (GLsizei count, const GLuint *shaders, GLenum binaryformat, const void *binary, GLsizei length); +GL_APICALL void GL_APIENTRY glShaderSource (GLuint shader, GLsizei count, const GLchar *const*string, const GLint *length); +GL_APICALL void GL_APIENTRY glStencilFunc (GLenum func, GLint ref, GLuint mask); +GL_APICALL void GL_APIENTRY glStencilFuncSeparate (GLenum face, GLenum func, GLint ref, GLuint mask); +GL_APICALL void GL_APIENTRY glStencilMask (GLuint mask); +GL_APICALL void GL_APIENTRY glStencilMaskSeparate (GLenum face, GLuint mask); +GL_APICALL void GL_APIENTRY glStencilOp (GLenum fail, GLenum zfail, GLenum zpass); +GL_APICALL void GL_APIENTRY glStencilOpSeparate (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass); +GL_APICALL void GL_APIENTRY glTexImage2D (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels); +GL_APICALL void GL_APIENTRY glTexParameterf (GLenum target, GLenum pname, GLfloat param); +GL_APICALL void GL_APIENTRY glTexParameterfv (GLenum target, GLenum pname, const GLfloat *params); +GL_APICALL void GL_APIENTRY glTexParameteri (GLenum target, GLenum pname, GLint param); +GL_APICALL void GL_APIENTRY glTexParameteriv (GLenum target, GLenum pname, const GLint *params); +GL_APICALL void GL_APIENTRY glTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels); +GL_APICALL void GL_APIENTRY glUniform1f (GLint location, GLfloat v0); +GL_APICALL void GL_APIENTRY glUniform1fv (GLint location, GLsizei count, const GLfloat *value); +GL_APICALL void GL_APIENTRY glUniform1i (GLint location, GLint v0); +GL_APICALL void GL_APIENTRY glUniform1iv (GLint location, GLsizei count, const GLint *value); +GL_APICALL void GL_APIENTRY glUniform2f (GLint location, GLfloat v0, GLfloat v1); +GL_APICALL void GL_APIENTRY glUniform2fv (GLint location, GLsizei count, const GLfloat *value); +GL_APICALL void GL_APIENTRY glUniform2i (GLint location, GLint v0, GLint v1); +GL_APICALL void GL_APIENTRY glUniform2iv (GLint location, GLsizei count, const GLint *value); +GL_APICALL void GL_APIENTRY glUniform3f (GLint location, GLfloat v0, GLfloat v1, GLfloat v2); +GL_APICALL void GL_APIENTRY glUniform3fv (GLint location, GLsizei count, const GLfloat *value); +GL_APICALL void GL_APIENTRY glUniform3i (GLint location, GLint v0, GLint v1, GLint v2); +GL_APICALL void GL_APIENTRY glUniform3iv (GLint location, GLsizei count, const GLint *value); +GL_APICALL void GL_APIENTRY glUniform4f (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); +GL_APICALL void GL_APIENTRY glUniform4fv (GLint location, GLsizei count, const GLfloat *value); +GL_APICALL void GL_APIENTRY glUniform4i (GLint location, GLint v0, GLint v1, GLint v2, GLint v3); +GL_APICALL void GL_APIENTRY glUniform4iv (GLint location, GLsizei count, const GLint *value); +GL_APICALL void GL_APIENTRY glUniformMatrix2fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GL_APICALL void GL_APIENTRY glUniformMatrix3fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GL_APICALL void GL_APIENTRY glUniformMatrix4fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GL_APICALL void GL_APIENTRY glUseProgram (GLuint program); +GL_APICALL void GL_APIENTRY glValidateProgram (GLuint program); +GL_APICALL void GL_APIENTRY glVertexAttrib1f (GLuint index, GLfloat x); +GL_APICALL void GL_APIENTRY glVertexAttrib1fv (GLuint index, const GLfloat *v); +GL_APICALL void GL_APIENTRY glVertexAttrib2f (GLuint index, GLfloat x, GLfloat y); +GL_APICALL void GL_APIENTRY glVertexAttrib2fv (GLuint index, const GLfloat *v); +GL_APICALL void GL_APIENTRY glVertexAttrib3f (GLuint index, GLfloat x, GLfloat y, GLfloat z); +GL_APICALL void GL_APIENTRY glVertexAttrib3fv (GLuint index, const GLfloat *v); +GL_APICALL void GL_APIENTRY glVertexAttrib4f (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +GL_APICALL void GL_APIENTRY glVertexAttrib4fv (GLuint index, const GLfloat *v); +GL_APICALL void GL_APIENTRY glVertexAttribPointer (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer); +GL_APICALL void GL_APIENTRY glViewport (GLint x, GLint y, GLsizei width, GLsizei height); +#endif +#endif /* GL_ES_VERSION_2_0 */ + +#ifndef GL_ES_VERSION_3_0 +#define GL_ES_VERSION_3_0 1 +typedef unsigned short GLhalf; +#define GL_READ_BUFFER 0x0C02 +#define GL_UNPACK_ROW_LENGTH 0x0CF2 +#define GL_UNPACK_SKIP_ROWS 0x0CF3 +#define GL_UNPACK_SKIP_PIXELS 0x0CF4 +#define GL_PACK_ROW_LENGTH 0x0D02 +#define GL_PACK_SKIP_ROWS 0x0D03 +#define GL_PACK_SKIP_PIXELS 0x0D04 +#define GL_COLOR 0x1800 +#define GL_DEPTH 0x1801 +#define GL_STENCIL 0x1802 +#define GL_RED 0x1903 +#define GL_RGB8 0x8051 +#define GL_RGBA8 0x8058 +#define GL_RGB10_A2 0x8059 +#define GL_TEXTURE_BINDING_3D 0x806A +#define GL_UNPACK_SKIP_IMAGES 0x806D +#define GL_UNPACK_IMAGE_HEIGHT 0x806E +#define GL_TEXTURE_3D 0x806F +#define GL_TEXTURE_WRAP_R 0x8072 +#define GL_MAX_3D_TEXTURE_SIZE 0x8073 +#define GL_UNSIGNED_INT_2_10_10_10_REV 0x8368 +#define GL_MAX_ELEMENTS_VERTICES 0x80E8 +#define GL_MAX_ELEMENTS_INDICES 0x80E9 +#define GL_TEXTURE_MIN_LOD 0x813A +#define GL_TEXTURE_MAX_LOD 0x813B +#define GL_TEXTURE_BASE_LEVEL 0x813C +#define GL_TEXTURE_MAX_LEVEL 0x813D +#define GL_MIN 0x8007 +#define GL_MAX 0x8008 +#define GL_DEPTH_COMPONENT24 0x81A6 +#define GL_MAX_TEXTURE_LOD_BIAS 0x84FD +#define GL_TEXTURE_COMPARE_MODE 0x884C +#define GL_TEXTURE_COMPARE_FUNC 0x884D +#define GL_CURRENT_QUERY 0x8865 +#define GL_QUERY_RESULT 0x8866 +#define GL_QUERY_RESULT_AVAILABLE 0x8867 +#define GL_BUFFER_MAPPED 0x88BC +#define GL_BUFFER_MAP_POINTER 0x88BD +#define GL_STREAM_READ 0x88E1 +#define GL_STREAM_COPY 0x88E2 +#define GL_STATIC_READ 0x88E5 +#define GL_STATIC_COPY 0x88E6 +#define GL_DYNAMIC_READ 0x88E9 +#define GL_DYNAMIC_COPY 0x88EA +#define GL_MAX_DRAW_BUFFERS 0x8824 +#define GL_DRAW_BUFFER0 0x8825 +#define GL_DRAW_BUFFER1 0x8826 +#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_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_MAX_FRAGMENT_UNIFORM_COMPONENTS 0x8B49 +#define GL_MAX_VERTEX_UNIFORM_COMPONENTS 0x8B4A +#define GL_SAMPLER_3D 0x8B5F +#define GL_SAMPLER_2D_SHADOW 0x8B62 +#define GL_FRAGMENT_SHADER_DERIVATIVE_HINT 0x8B8B +#define GL_PIXEL_PACK_BUFFER 0x88EB +#define GL_PIXEL_UNPACK_BUFFER 0x88EC +#define GL_PIXEL_PACK_BUFFER_BINDING 0x88ED +#define GL_PIXEL_UNPACK_BUFFER_BINDING 0x88EF +#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_SRGB 0x8C40 +#define GL_SRGB8 0x8C41 +#define GL_SRGB8_ALPHA8 0x8C43 +#define GL_COMPARE_REF_TO_TEXTURE 0x884E +#define GL_MAJOR_VERSION 0x821B +#define GL_MINOR_VERSION 0x821C +#define GL_NUM_EXTENSIONS 0x821D +#define GL_RGBA32F 0x8814 +#define GL_RGB32F 0x8815 +#define GL_RGBA16F 0x881A +#define GL_RGB16F 0x881B +#define GL_VERTEX_ATTRIB_ARRAY_INTEGER 0x88FD +#define GL_MAX_ARRAY_TEXTURE_LAYERS 0x88FF +#define GL_MIN_PROGRAM_TEXEL_OFFSET 0x8904 +#define GL_MAX_PROGRAM_TEXEL_OFFSET 0x8905 +#define GL_MAX_VARYING_COMPONENTS 0x8B4B +#define GL_TEXTURE_2D_ARRAY 0x8C1A +#define GL_TEXTURE_BINDING_2D_ARRAY 0x8C1D +#define GL_R11F_G11F_B10F 0x8C3A +#define GL_UNSIGNED_INT_10F_11F_11F_REV 0x8C3B +#define GL_RGB9_E5 0x8C3D +#define GL_UNSIGNED_INT_5_9_9_9_REV 0x8C3E +#define GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH 0x8C76 +#define GL_TRANSFORM_FEEDBACK_BUFFER_MODE 0x8C7F +#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS 0x8C80 +#define GL_TRANSFORM_FEEDBACK_VARYINGS 0x8C83 +#define GL_TRANSFORM_FEEDBACK_BUFFER_START 0x8C84 +#define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE 0x8C85 +#define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN 0x8C88 +#define GL_RASTERIZER_DISCARD 0x8C89 #define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS 0x8C8A -#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS 0x8C8B -#define GL_INTERLEAVED_ATTRIBS 0x8C8C -#define GL_SEPARATE_ATTRIBS 0x8C8D -#define GL_TRANSFORM_FEEDBACK_BUFFER 0x8C8E -#define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING 0x8C8F -#define GL_RGBA32UI 0x8D70 -#define GL_RGB32UI 0x8D71 -#define GL_RGBA16UI 0x8D76 -#define GL_RGB16UI 0x8D77 -#define GL_RGBA8UI 0x8D7C -#define GL_RGB8UI 0x8D7D -#define GL_RGBA32I 0x8D82 -#define GL_RGB32I 0x8D83 -#define GL_RGBA16I 0x8D88 -#define GL_RGB16I 0x8D89 -#define GL_RGBA8I 0x8D8E -#define GL_RGB8I 0x8D8F -#define GL_RED_INTEGER 0x8D94 -#define GL_RGB_INTEGER 0x8D98 -#define GL_RGBA_INTEGER 0x8D99 -#define GL_SAMPLER_2D_ARRAY 0x8DC1 -#define GL_SAMPLER_2D_ARRAY_SHADOW 0x8DC4 -#define GL_SAMPLER_CUBE_SHADOW 0x8DC5 -#define GL_UNSIGNED_INT_VEC2 0x8DC6 -#define GL_UNSIGNED_INT_VEC3 0x8DC7 -#define GL_UNSIGNED_INT_VEC4 0x8DC8 -#define GL_INT_SAMPLER_2D 0x8DCA -#define GL_INT_SAMPLER_3D 0x8DCB -#define GL_INT_SAMPLER_CUBE 0x8DCC -#define GL_INT_SAMPLER_2D_ARRAY 0x8DCF -#define GL_UNSIGNED_INT_SAMPLER_2D 0x8DD2 -#define GL_UNSIGNED_INT_SAMPLER_3D 0x8DD3 -#define GL_UNSIGNED_INT_SAMPLER_CUBE 0x8DD4 -#define GL_UNSIGNED_INT_SAMPLER_2D_ARRAY 0x8DD7 -#define GL_BUFFER_ACCESS_FLAGS 0x911F -#define GL_BUFFER_MAP_LENGTH 0x9120 -#define GL_BUFFER_MAP_OFFSET 0x9121 -#define GL_DEPTH_COMPONENT32F 0x8CAC -#define GL_DEPTH32F_STENCIL8 0x8CAD -#define GL_FLOAT_32_UNSIGNED_INT_24_8_REV 0x8DAD -#define GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING 0x8210 -#define GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE 0x8211 -#define GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE 0x8212 -#define GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE 0x8213 -#define GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE 0x8214 -#define GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE 0x8215 -#define GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE 0x8216 -#define GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE 0x8217 -#define GL_FRAMEBUFFER_DEFAULT 0x8218 -#define GL_FRAMEBUFFER_UNDEFINED 0x8219 -#define GL_DEPTH_STENCIL_ATTACHMENT 0x821A -#define GL_DEPTH_STENCIL 0x84F9 -#define GL_UNSIGNED_INT_24_8 0x84FA -#define GL_DEPTH24_STENCIL8 0x88F0 -#define GL_UNSIGNED_NORMALIZED 0x8C17 -#define GL_DRAW_FRAMEBUFFER_BINDING GL_FRAMEBUFFER_BINDING -#define GL_READ_FRAMEBUFFER 0x8CA8 -#define GL_DRAW_FRAMEBUFFER 0x8CA9 -#define GL_READ_FRAMEBUFFER_BINDING 0x8CAA -#define GL_RENDERBUFFER_SAMPLES 0x8CAB -#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER 0x8CD4 -#define GL_MAX_COLOR_ATTACHMENTS 0x8CDF -#define GL_COLOR_ATTACHMENT1 0x8CE1 -#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_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_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE 0x8D56 -#define GL_MAX_SAMPLES 0x8D57 -#define GL_HALF_FLOAT 0x140B -#define GL_MAP_READ_BIT 0x0001 -#define GL_MAP_WRITE_BIT 0x0002 -#define GL_MAP_INVALIDATE_RANGE_BIT 0x0004 -#define GL_MAP_INVALIDATE_BUFFER_BIT 0x0008 -#define GL_MAP_FLUSH_EXPLICIT_BIT 0x0010 -#define GL_MAP_UNSYNCHRONIZED_BIT 0x0020 -#define GL_RG 0x8227 -#define GL_RG_INTEGER 0x8228 -#define GL_R8 0x8229 -#define GL_RG8 0x822B -#define GL_R16F 0x822D -#define GL_R32F 0x822E -#define GL_RG16F 0x822F -#define GL_RG32F 0x8230 -#define GL_R8I 0x8231 -#define GL_R8UI 0x8232 -#define GL_R16I 0x8233 -#define GL_R16UI 0x8234 -#define GL_R32I 0x8235 -#define GL_R32UI 0x8236 -#define GL_RG8I 0x8237 -#define GL_RG8UI 0x8238 -#define GL_RG16I 0x8239 -#define GL_RG16UI 0x823A -#define GL_RG32I 0x823B -#define GL_RG32UI 0x823C -#define GL_VERTEX_ARRAY_BINDING 0x85B5 -#define GL_R8_SNORM 0x8F94 -#define GL_RG8_SNORM 0x8F95 -#define GL_RGB8_SNORM 0x8F96 -#define GL_RGBA8_SNORM 0x8F97 -#define GL_SIGNED_NORMALIZED 0x8F9C -#define GL_PRIMITIVE_RESTART_FIXED_INDEX 0x8D69 -#define GL_COPY_READ_BUFFER 0x8F36 -#define GL_COPY_WRITE_BUFFER 0x8F37 -#define GL_COPY_READ_BUFFER_BINDING GL_COPY_READ_BUFFER -#define GL_COPY_WRITE_BUFFER_BINDING GL_COPY_WRITE_BUFFER -#define GL_UNIFORM_BUFFER 0x8A11 -#define GL_UNIFORM_BUFFER_BINDING 0x8A28 -#define GL_UNIFORM_BUFFER_START 0x8A29 -#define GL_UNIFORM_BUFFER_SIZE 0x8A2A -#define GL_MAX_VERTEX_UNIFORM_BLOCKS 0x8A2B -#define GL_MAX_FRAGMENT_UNIFORM_BLOCKS 0x8A2D -#define GL_MAX_COMBINED_UNIFORM_BLOCKS 0x8A2E -#define GL_MAX_UNIFORM_BUFFER_BINDINGS 0x8A2F -#define GL_MAX_UNIFORM_BLOCK_SIZE 0x8A30 -#define GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS 0x8A31 -#define GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS 0x8A33 -#define GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT 0x8A34 -#define GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH 0x8A35 -#define GL_ACTIVE_UNIFORM_BLOCKS 0x8A36 -#define GL_UNIFORM_TYPE 0x8A37 -#define GL_UNIFORM_SIZE 0x8A38 -#define GL_UNIFORM_NAME_LENGTH 0x8A39 -#define GL_UNIFORM_BLOCK_INDEX 0x8A3A -#define GL_UNIFORM_OFFSET 0x8A3B -#define GL_UNIFORM_ARRAY_STRIDE 0x8A3C -#define GL_UNIFORM_MATRIX_STRIDE 0x8A3D -#define GL_UNIFORM_IS_ROW_MAJOR 0x8A3E -#define GL_UNIFORM_BLOCK_BINDING 0x8A3F -#define GL_UNIFORM_BLOCK_DATA_SIZE 0x8A40 -#define GL_UNIFORM_BLOCK_NAME_LENGTH 0x8A41 -#define GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS 0x8A42 -#define GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES 0x8A43 -#define GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER 0x8A44 -#define GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER 0x8A46 -#define GL_INVALID_INDEX 0xFFFFFFFFu -#define GL_MAX_VERTEX_OUTPUT_COMPONENTS 0x9122 -#define GL_MAX_FRAGMENT_INPUT_COMPONENTS 0x9125 -#define GL_MAX_SERVER_WAIT_TIMEOUT 0x9111 -#define GL_OBJECT_TYPE 0x9112 -#define GL_SYNC_CONDITION 0x9113 -#define GL_SYNC_STATUS 0x9114 -#define GL_SYNC_FLAGS 0x9115 -#define GL_SYNC_FENCE 0x9116 -#define GL_SYNC_GPU_COMMANDS_COMPLETE 0x9117 -#define GL_UNSIGNALED 0x9118 -#define GL_SIGNALED 0x9119 -#define GL_ALREADY_SIGNALED 0x911A -#define GL_TIMEOUT_EXPIRED 0x911B -#define GL_CONDITION_SATISFIED 0x911C -#define GL_WAIT_FAILED 0x911D -#define GL_SYNC_FLUSH_COMMANDS_BIT 0x00000001 -#define GL_TIMEOUT_IGNORED 0xFFFFFFFFFFFFFFFFull -#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR 0x88FE -#define GL_ANY_SAMPLES_PASSED 0x8C2F -#define GL_ANY_SAMPLES_PASSED_CONSERVATIVE 0x8D6A -#define GL_SAMPLER_BINDING 0x8919 -#define GL_RGB10_A2UI 0x906F -#define GL_TEXTURE_SWIZZLE_R 0x8E42 -#define GL_TEXTURE_SWIZZLE_G 0x8E43 -#define GL_TEXTURE_SWIZZLE_B 0x8E44 -#define GL_TEXTURE_SWIZZLE_A 0x8E45 -#define GL_GREEN 0x1904 -#define GL_BLUE 0x1905 -#define GL_INT_2_10_10_10_REV 0x8D9F -#define GL_TRANSFORM_FEEDBACK 0x8E22 -#define GL_TRANSFORM_FEEDBACK_PAUSED 0x8E23 -#define GL_TRANSFORM_FEEDBACK_ACTIVE 0x8E24 -#define GL_TRANSFORM_FEEDBACK_BINDING 0x8E25 -#define GL_PROGRAM_BINARY_RETRIEVABLE_HINT 0x8257 -#define GL_PROGRAM_BINARY_LENGTH 0x8741 -#define GL_NUM_PROGRAM_BINARY_FORMATS 0x87FE -#define GL_PROGRAM_BINARY_FORMATS 0x87FF -#define GL_COMPRESSED_R11_EAC 0x9270 -#define GL_COMPRESSED_SIGNED_R11_EAC 0x9271 -#define GL_COMPRESSED_RG11_EAC 0x9272 -#define GL_COMPRESSED_SIGNED_RG11_EAC 0x9273 -#define GL_COMPRESSED_RGB8_ETC2 0x9274 -#define GL_COMPRESSED_SRGB8_ETC2 0x9275 -#define GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9276 -#define GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9277 -#define GL_COMPRESSED_RGBA8_ETC2_EAC 0x9278 -#define GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC 0x9279 -#define GL_TEXTURE_IMMUTABLE_FORMAT 0x912F -#define GL_MAX_ELEMENT_INDEX 0x8D6B -#define GL_NUM_SAMPLE_COUNTS 0x9380 -#define GL_TEXTURE_IMMUTABLE_LEVELS 0x82DF - -/*------------------------------------------------------------------------- - * Entrypoint definitions - *-----------------------------------------------------------------------*/ - -/* OpenGL ES 2.0 */ - -GL_APICALL void GL_APIENTRY glActiveTexture (GLenum texture); -GL_APICALL void GL_APIENTRY glAttachShader (GLuint program, GLuint shader); -GL_APICALL void GL_APIENTRY glBindAttribLocation (GLuint program, GLuint index, const GLchar* name); -GL_APICALL void GL_APIENTRY glBindBuffer (GLenum target, GLuint buffer); -GL_APICALL void GL_APIENTRY glBindFramebuffer (GLenum target, GLuint framebuffer); -GL_APICALL void GL_APIENTRY glBindRenderbuffer (GLenum target, GLuint renderbuffer); -GL_APICALL void GL_APIENTRY glBindTexture (GLenum target, GLuint texture); -GL_APICALL void GL_APIENTRY glBlendColor (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); -GL_APICALL void GL_APIENTRY glBlendEquation (GLenum mode); -GL_APICALL void GL_APIENTRY glBlendEquationSeparate (GLenum modeRGB, GLenum modeAlpha); -GL_APICALL void GL_APIENTRY glBlendFunc (GLenum sfactor, GLenum dfactor); -GL_APICALL void GL_APIENTRY glBlendFuncSeparate (GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha); -GL_APICALL void GL_APIENTRY glBufferData (GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage); -GL_APICALL void GL_APIENTRY glBufferSubData (GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data); -GL_APICALL GLenum GL_APIENTRY glCheckFramebufferStatus (GLenum target); -GL_APICALL void GL_APIENTRY glClear (GLbitfield mask); -GL_APICALL void GL_APIENTRY glClearColor (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); -GL_APICALL void GL_APIENTRY glClearDepthf (GLfloat depth); -GL_APICALL void GL_APIENTRY glClearStencil (GLint s); -GL_APICALL void GL_APIENTRY glColorMask (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); -GL_APICALL void GL_APIENTRY glCompileShader (GLuint shader); -GL_APICALL void GL_APIENTRY glCompressedTexImage2D (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid* data); -GL_APICALL void GL_APIENTRY glCompressedTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid* data); -GL_APICALL void GL_APIENTRY glCopyTexImage2D (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); -GL_APICALL void GL_APIENTRY glCopyTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); -GL_APICALL GLuint GL_APIENTRY glCreateProgram (void); -GL_APICALL GLuint GL_APIENTRY glCreateShader (GLenum type); -GL_APICALL void GL_APIENTRY glCullFace (GLenum mode); -GL_APICALL void GL_APIENTRY glDeleteBuffers (GLsizei n, const GLuint* buffers); -GL_APICALL void GL_APIENTRY glDeleteFramebuffers (GLsizei n, const GLuint* framebuffers); -GL_APICALL void GL_APIENTRY glDeleteProgram (GLuint program); -GL_APICALL void GL_APIENTRY glDeleteRenderbuffers (GLsizei n, const GLuint* renderbuffers); -GL_APICALL void GL_APIENTRY glDeleteShader (GLuint shader); -GL_APICALL void GL_APIENTRY glDeleteTextures (GLsizei n, const GLuint* textures); -GL_APICALL void GL_APIENTRY glDepthFunc (GLenum func); -GL_APICALL void GL_APIENTRY glDepthMask (GLboolean flag); -GL_APICALL void GL_APIENTRY glDepthRangef (GLfloat n, GLfloat f); -GL_APICALL void GL_APIENTRY glDetachShader (GLuint program, GLuint shader); -GL_APICALL void GL_APIENTRY glDisable (GLenum cap); -GL_APICALL void GL_APIENTRY glDisableVertexAttribArray (GLuint index); -GL_APICALL void GL_APIENTRY glDrawArrays (GLenum mode, GLint first, GLsizei count); -GL_APICALL void GL_APIENTRY glDrawElements (GLenum mode, GLsizei count, GLenum type, const GLvoid* indices); -GL_APICALL void GL_APIENTRY glEnable (GLenum cap); -GL_APICALL void GL_APIENTRY glEnableVertexAttribArray (GLuint index); -GL_APICALL void GL_APIENTRY glFinish (void); -GL_APICALL void GL_APIENTRY glFlush (void); -GL_APICALL void GL_APIENTRY glFramebufferRenderbuffer (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); -GL_APICALL void GL_APIENTRY glFramebufferTexture2D (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); -GL_APICALL void GL_APIENTRY glFrontFace (GLenum mode); -GL_APICALL void GL_APIENTRY glGenBuffers (GLsizei n, GLuint* buffers); -GL_APICALL void GL_APIENTRY glGenerateMipmap (GLenum target); -GL_APICALL void GL_APIENTRY glGenFramebuffers (GLsizei n, GLuint* framebuffers); -GL_APICALL void GL_APIENTRY glGenRenderbuffers (GLsizei n, GLuint* renderbuffers); -GL_APICALL void GL_APIENTRY glGenTextures (GLsizei n, GLuint* textures); -GL_APICALL void GL_APIENTRY glGetActiveAttrib (GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name); -GL_APICALL void GL_APIENTRY glGetActiveUniform (GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name); -GL_APICALL void GL_APIENTRY glGetAttachedShaders (GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders); -GL_APICALL GLint GL_APIENTRY glGetAttribLocation (GLuint program, const GLchar* name); -GL_APICALL void GL_APIENTRY glGetBooleanv (GLenum pname, GLboolean* params); -GL_APICALL void GL_APIENTRY glGetBufferParameteriv (GLenum target, GLenum pname, GLint* params); -GL_APICALL GLenum GL_APIENTRY glGetError (void); -GL_APICALL void GL_APIENTRY glGetFloatv (GLenum pname, GLfloat* params); -GL_APICALL void GL_APIENTRY glGetFramebufferAttachmentParameteriv (GLenum target, GLenum attachment, GLenum pname, GLint* params); -GL_APICALL void GL_APIENTRY glGetIntegerv (GLenum pname, GLint* params); -GL_APICALL void GL_APIENTRY glGetProgramiv (GLuint program, GLenum pname, GLint* params); -GL_APICALL void GL_APIENTRY glGetProgramInfoLog (GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog); -GL_APICALL void GL_APIENTRY glGetRenderbufferParameteriv (GLenum target, GLenum pname, GLint* params); -GL_APICALL void GL_APIENTRY glGetShaderiv (GLuint shader, GLenum pname, GLint* params); -GL_APICALL void GL_APIENTRY glGetShaderInfoLog (GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog); -GL_APICALL void GL_APIENTRY glGetShaderPrecisionFormat (GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision); -GL_APICALL void GL_APIENTRY glGetShaderSource (GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source); -GL_APICALL const GLubyte* GL_APIENTRY glGetString (GLenum name); -GL_APICALL void GL_APIENTRY glGetTexParameterfv (GLenum target, GLenum pname, GLfloat* params); -GL_APICALL void GL_APIENTRY glGetTexParameteriv (GLenum target, GLenum pname, GLint* params); -GL_APICALL void GL_APIENTRY glGetUniformfv (GLuint program, GLint location, GLfloat* params); -GL_APICALL void GL_APIENTRY glGetUniformiv (GLuint program, GLint location, GLint* params); -GL_APICALL GLint GL_APIENTRY glGetUniformLocation (GLuint program, const GLchar* name); -GL_APICALL void GL_APIENTRY glGetVertexAttribfv (GLuint index, GLenum pname, GLfloat* params); -GL_APICALL void GL_APIENTRY glGetVertexAttribiv (GLuint index, GLenum pname, GLint* params); -GL_APICALL void GL_APIENTRY glGetVertexAttribPointerv (GLuint index, GLenum pname, GLvoid** pointer); -GL_APICALL void GL_APIENTRY glHint (GLenum target, GLenum mode); -GL_APICALL GLboolean GL_APIENTRY glIsBuffer (GLuint buffer); -GL_APICALL GLboolean GL_APIENTRY glIsEnabled (GLenum cap); -GL_APICALL GLboolean GL_APIENTRY glIsFramebuffer (GLuint framebuffer); -GL_APICALL GLboolean GL_APIENTRY glIsProgram (GLuint program); -GL_APICALL GLboolean GL_APIENTRY glIsRenderbuffer (GLuint renderbuffer); -GL_APICALL GLboolean GL_APIENTRY glIsShader (GLuint shader); -GL_APICALL GLboolean GL_APIENTRY glIsTexture (GLuint texture); -GL_APICALL void GL_APIENTRY glLineWidth (GLfloat width); -GL_APICALL void GL_APIENTRY glLinkProgram (GLuint program); -GL_APICALL void GL_APIENTRY glPixelStorei (GLenum pname, GLint param); -GL_APICALL void GL_APIENTRY glPolygonOffset (GLfloat factor, GLfloat units); -GL_APICALL void GL_APIENTRY glReadPixels (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels); -GL_APICALL void GL_APIENTRY glReleaseShaderCompiler (void); -GL_APICALL void GL_APIENTRY glRenderbufferStorage (GLenum target, GLenum internalformat, GLsizei width, GLsizei height); -GL_APICALL void GL_APIENTRY glSampleCoverage (GLfloat value, GLboolean invert); -GL_APICALL void GL_APIENTRY glScissor (GLint x, GLint y, GLsizei width, GLsizei height); -GL_APICALL void GL_APIENTRY glShaderBinary (GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length); -GL_APICALL void GL_APIENTRY glShaderSource (GLuint shader, GLsizei count, const GLchar* const* string, const GLint* length); -GL_APICALL void GL_APIENTRY glStencilFunc (GLenum func, GLint ref, GLuint mask); -GL_APICALL void GL_APIENTRY glStencilFuncSeparate (GLenum face, GLenum func, GLint ref, GLuint mask); -GL_APICALL void GL_APIENTRY glStencilMask (GLuint mask); -GL_APICALL void GL_APIENTRY glStencilMaskSeparate (GLenum face, GLuint mask); -GL_APICALL void GL_APIENTRY glStencilOp (GLenum fail, GLenum zfail, GLenum zpass); -GL_APICALL void GL_APIENTRY glStencilOpSeparate (GLenum face, GLenum fail, GLenum zfail, GLenum zpass); -GL_APICALL void GL_APIENTRY glTexImage2D (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid* pixels); -GL_APICALL void GL_APIENTRY glTexParameterf (GLenum target, GLenum pname, GLfloat param); -GL_APICALL void GL_APIENTRY glTexParameterfv (GLenum target, GLenum pname, const GLfloat* params); -GL_APICALL void GL_APIENTRY glTexParameteri (GLenum target, GLenum pname, GLint param); -GL_APICALL void GL_APIENTRY glTexParameteriv (GLenum target, GLenum pname, const GLint* params); -GL_APICALL void GL_APIENTRY glTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid* pixels); -GL_APICALL void GL_APIENTRY glUniform1f (GLint location, GLfloat x); -GL_APICALL void GL_APIENTRY glUniform1fv (GLint location, GLsizei count, const GLfloat* v); -GL_APICALL void GL_APIENTRY glUniform1i (GLint location, GLint x); -GL_APICALL void GL_APIENTRY glUniform1iv (GLint location, GLsizei count, const GLint* v); -GL_APICALL void GL_APIENTRY glUniform2f (GLint location, GLfloat x, GLfloat y); -GL_APICALL void GL_APIENTRY glUniform2fv (GLint location, GLsizei count, const GLfloat* v); -GL_APICALL void GL_APIENTRY glUniform2i (GLint location, GLint x, GLint y); -GL_APICALL void GL_APIENTRY glUniform2iv (GLint location, GLsizei count, const GLint* v); -GL_APICALL void GL_APIENTRY glUniform3f (GLint location, GLfloat x, GLfloat y, GLfloat z); -GL_APICALL void GL_APIENTRY glUniform3fv (GLint location, GLsizei count, const GLfloat* v); -GL_APICALL void GL_APIENTRY glUniform3i (GLint location, GLint x, GLint y, GLint z); -GL_APICALL void GL_APIENTRY glUniform3iv (GLint location, GLsizei count, const GLint* v); -GL_APICALL void GL_APIENTRY glUniform4f (GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w); -GL_APICALL void GL_APIENTRY glUniform4fv (GLint location, GLsizei count, const GLfloat* v); -GL_APICALL void GL_APIENTRY glUniform4i (GLint location, GLint x, GLint y, GLint z, GLint w); -GL_APICALL void GL_APIENTRY glUniform4iv (GLint location, GLsizei count, const GLint* v); -GL_APICALL void GL_APIENTRY glUniformMatrix2fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); -GL_APICALL void GL_APIENTRY glUniformMatrix3fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); -GL_APICALL void GL_APIENTRY glUniformMatrix4fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); -GL_APICALL void GL_APIENTRY glUseProgram (GLuint program); -GL_APICALL void GL_APIENTRY glValidateProgram (GLuint program); -GL_APICALL void GL_APIENTRY glVertexAttrib1f (GLuint indx, GLfloat x); -GL_APICALL void GL_APIENTRY glVertexAttrib1fv (GLuint indx, const GLfloat* values); -GL_APICALL void GL_APIENTRY glVertexAttrib2f (GLuint indx, GLfloat x, GLfloat y); -GL_APICALL void GL_APIENTRY glVertexAttrib2fv (GLuint indx, const GLfloat* values); -GL_APICALL void GL_APIENTRY glVertexAttrib3f (GLuint indx, GLfloat x, GLfloat y, GLfloat z); -GL_APICALL void GL_APIENTRY glVertexAttrib3fv (GLuint indx, const GLfloat* values); -GL_APICALL void GL_APIENTRY glVertexAttrib4f (GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w); -GL_APICALL void GL_APIENTRY glVertexAttrib4fv (GLuint indx, const GLfloat* values); -GL_APICALL void GL_APIENTRY glVertexAttribPointer (GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr); -GL_APICALL void GL_APIENTRY glViewport (GLint x, GLint y, GLsizei width, GLsizei height); - -/* OpenGL ES 3.0 */ - -GL_APICALL void GL_APIENTRY glReadBuffer (GLenum mode); -GL_APICALL void GL_APIENTRY glDrawRangeElements (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid* indices); -GL_APICALL void GL_APIENTRY glTexImage3D (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid* pixels); -GL_APICALL void GL_APIENTRY glTexSubImage3D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid* pixels); -GL_APICALL void GL_APIENTRY glCopyTexSubImage3D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); -GL_APICALL void GL_APIENTRY glCompressedTexImage3D (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid* data); -GL_APICALL void GL_APIENTRY glCompressedTexSubImage3D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid* data); -GL_APICALL void GL_APIENTRY glGenQueries (GLsizei n, GLuint* ids); -GL_APICALL void GL_APIENTRY glDeleteQueries (GLsizei n, const GLuint* ids); -GL_APICALL GLboolean GL_APIENTRY glIsQuery (GLuint id); -GL_APICALL void GL_APIENTRY glBeginQuery (GLenum target, GLuint id); -GL_APICALL void GL_APIENTRY glEndQuery (GLenum target); -GL_APICALL void GL_APIENTRY glGetQueryiv (GLenum target, GLenum pname, GLint* params); -GL_APICALL void GL_APIENTRY glGetQueryObjectuiv (GLuint id, GLenum pname, GLuint* params); -GL_APICALL GLboolean GL_APIENTRY glUnmapBuffer (GLenum target); -GL_APICALL void GL_APIENTRY glGetBufferPointerv (GLenum target, GLenum pname, GLvoid** params); -GL_APICALL void GL_APIENTRY glDrawBuffers (GLsizei n, const GLenum* bufs); -GL_APICALL void GL_APIENTRY glUniformMatrix2x3fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); -GL_APICALL void GL_APIENTRY glUniformMatrix3x2fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); -GL_APICALL void GL_APIENTRY glUniformMatrix2x4fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); -GL_APICALL void GL_APIENTRY glUniformMatrix4x2fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); -GL_APICALL void GL_APIENTRY glUniformMatrix3x4fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); -GL_APICALL void GL_APIENTRY glUniformMatrix4x3fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); -GL_APICALL void GL_APIENTRY glBlitFramebuffer (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); -GL_APICALL void GL_APIENTRY glRenderbufferStorageMultisample (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); -GL_APICALL void GL_APIENTRY glFramebufferTextureLayer (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); -GL_APICALL GLvoid* GL_APIENTRY glMapBufferRange (GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access); -GL_APICALL void GL_APIENTRY glFlushMappedBufferRange (GLenum target, GLintptr offset, GLsizeiptr length); -GL_APICALL void GL_APIENTRY glBindVertexArray (GLuint array); -GL_APICALL void GL_APIENTRY glDeleteVertexArrays (GLsizei n, const GLuint* arrays); -GL_APICALL void GL_APIENTRY glGenVertexArrays (GLsizei n, GLuint* arrays); -GL_APICALL GLboolean GL_APIENTRY glIsVertexArray (GLuint array); -GL_APICALL void GL_APIENTRY glGetIntegeri_v (GLenum target, GLuint index, GLint* data); -GL_APICALL void GL_APIENTRY glBeginTransformFeedback (GLenum primitiveMode); -GL_APICALL void GL_APIENTRY glEndTransformFeedback (void); -GL_APICALL void GL_APIENTRY glBindBufferRange (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); -GL_APICALL void GL_APIENTRY glBindBufferBase (GLenum target, GLuint index, GLuint buffer); -GL_APICALL void GL_APIENTRY glTransformFeedbackVaryings (GLuint program, GLsizei count, const GLchar* const* varyings, GLenum bufferMode); -GL_APICALL void GL_APIENTRY glGetTransformFeedbackVarying (GLuint program, GLuint index, GLsizei bufSize, GLsizei* length, GLsizei* size, GLenum* type, GLchar* name); -GL_APICALL void GL_APIENTRY glVertexAttribIPointer (GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid* pointer); -GL_APICALL void GL_APIENTRY glGetVertexAttribIiv (GLuint index, GLenum pname, GLint* params); -GL_APICALL void GL_APIENTRY glGetVertexAttribIuiv (GLuint index, GLenum pname, GLuint* params); -GL_APICALL void GL_APIENTRY glVertexAttribI4i (GLuint index, GLint x, GLint y, GLint z, GLint w); -GL_APICALL void GL_APIENTRY glVertexAttribI4ui (GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); -GL_APICALL void GL_APIENTRY glVertexAttribI4iv (GLuint index, const GLint* v); -GL_APICALL void GL_APIENTRY glVertexAttribI4uiv (GLuint index, const GLuint* v); -GL_APICALL void GL_APIENTRY glGetUniformuiv (GLuint program, GLint location, GLuint* params); -GL_APICALL GLint GL_APIENTRY glGetFragDataLocation (GLuint program, const GLchar *name); -GL_APICALL void GL_APIENTRY glUniform1ui (GLint location, GLuint v0); -GL_APICALL void GL_APIENTRY glUniform2ui (GLint location, GLuint v0, GLuint v1); -GL_APICALL void GL_APIENTRY glUniform3ui (GLint location, GLuint v0, GLuint v1, GLuint v2); -GL_APICALL void GL_APIENTRY glUniform4ui (GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); -GL_APICALL void GL_APIENTRY glUniform1uiv (GLint location, GLsizei count, const GLuint* value); -GL_APICALL void GL_APIENTRY glUniform2uiv (GLint location, GLsizei count, const GLuint* value); -GL_APICALL void GL_APIENTRY glUniform3uiv (GLint location, GLsizei count, const GLuint* value); -GL_APICALL void GL_APIENTRY glUniform4uiv (GLint location, GLsizei count, const GLuint* value); -GL_APICALL void GL_APIENTRY glClearBufferiv (GLenum buffer, GLint drawbuffer, const GLint* value); -GL_APICALL void GL_APIENTRY glClearBufferuiv (GLenum buffer, GLint drawbuffer, const GLuint* value); -GL_APICALL void GL_APIENTRY glClearBufferfv (GLenum buffer, GLint drawbuffer, const GLfloat* value); -GL_APICALL void GL_APIENTRY glClearBufferfi (GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil); -GL_APICALL const GLubyte* GL_APIENTRY glGetStringi (GLenum name, GLuint index); -GL_APICALL void GL_APIENTRY glCopyBufferSubData (GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); -GL_APICALL void GL_APIENTRY glGetUniformIndices (GLuint program, GLsizei uniformCount, const GLchar* const* uniformNames, GLuint* uniformIndices); -GL_APICALL void GL_APIENTRY glGetActiveUniformsiv (GLuint program, GLsizei uniformCount, const GLuint* uniformIndices, GLenum pname, GLint* params); -GL_APICALL GLuint GL_APIENTRY glGetUniformBlockIndex (GLuint program, const GLchar* uniformBlockName); -GL_APICALL void GL_APIENTRY glGetActiveUniformBlockiv (GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint* params); -GL_APICALL void GL_APIENTRY glGetActiveUniformBlockName (GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei* length, GLchar* uniformBlockName); -GL_APICALL void GL_APIENTRY glUniformBlockBinding (GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding); -GL_APICALL void GL_APIENTRY glDrawArraysInstanced (GLenum mode, GLint first, GLsizei count, GLsizei instanceCount); -GL_APICALL void GL_APIENTRY glDrawElementsInstanced (GLenum mode, GLsizei count, GLenum type, const GLvoid* indices, GLsizei instanceCount); -GL_APICALL GLsync GL_APIENTRY glFenceSync (GLenum condition, GLbitfield flags); -GL_APICALL GLboolean GL_APIENTRY glIsSync (GLsync sync); -GL_APICALL void GL_APIENTRY glDeleteSync (GLsync sync); -GL_APICALL GLenum GL_APIENTRY glClientWaitSync (GLsync sync, GLbitfield flags, GLuint64 timeout); -GL_APICALL void GL_APIENTRY glWaitSync (GLsync sync, GLbitfield flags, GLuint64 timeout); -GL_APICALL void GL_APIENTRY glGetInteger64v (GLenum pname, GLint64* params); -GL_APICALL void GL_APIENTRY glGetSynciv (GLsync sync, GLenum pname, GLsizei bufSize, GLsizei* length, GLint* values); -GL_APICALL void GL_APIENTRY glGetInteger64i_v (GLenum target, GLuint index, GLint64* data); -GL_APICALL void GL_APIENTRY glGetBufferParameteri64v (GLenum target, GLenum pname, GLint64* params); -GL_APICALL void GL_APIENTRY glGenSamplers (GLsizei count, GLuint* samplers); -GL_APICALL void GL_APIENTRY glDeleteSamplers (GLsizei count, const GLuint* samplers); -GL_APICALL GLboolean GL_APIENTRY glIsSampler (GLuint sampler); -GL_APICALL void GL_APIENTRY glBindSampler (GLuint unit, GLuint sampler); -GL_APICALL void GL_APIENTRY glSamplerParameteri (GLuint sampler, GLenum pname, GLint param); -GL_APICALL void GL_APIENTRY glSamplerParameteriv (GLuint sampler, GLenum pname, const GLint* param); -GL_APICALL void GL_APIENTRY glSamplerParameterf (GLuint sampler, GLenum pname, GLfloat param); -GL_APICALL void GL_APIENTRY glSamplerParameterfv (GLuint sampler, GLenum pname, const GLfloat* param); -GL_APICALL void GL_APIENTRY glGetSamplerParameteriv (GLuint sampler, GLenum pname, GLint* params); -GL_APICALL void GL_APIENTRY glGetSamplerParameterfv (GLuint sampler, GLenum pname, GLfloat* params); -GL_APICALL void GL_APIENTRY glVertexAttribDivisor (GLuint index, GLuint divisor); -GL_APICALL void GL_APIENTRY glBindTransformFeedback (GLenum target, GLuint id); -GL_APICALL void GL_APIENTRY glDeleteTransformFeedbacks (GLsizei n, const GLuint* ids); -GL_APICALL void GL_APIENTRY glGenTransformFeedbacks (GLsizei n, GLuint* ids); -GL_APICALL GLboolean GL_APIENTRY glIsTransformFeedback (GLuint id); -GL_APICALL void GL_APIENTRY glPauseTransformFeedback (void); -GL_APICALL void GL_APIENTRY glResumeTransformFeedback (void); -GL_APICALL void GL_APIENTRY glGetProgramBinary (GLuint program, GLsizei bufSize, GLsizei* length, GLenum* binaryFormat, GLvoid* binary); -GL_APICALL void GL_APIENTRY glProgramBinary (GLuint program, GLenum binaryFormat, const GLvoid* binary, GLsizei length); -GL_APICALL void GL_APIENTRY glProgramParameteri (GLuint program, GLenum pname, GLint value); -GL_APICALL void GL_APIENTRY glInvalidateFramebuffer (GLenum target, GLsizei numAttachments, const GLenum* attachments); -GL_APICALL void GL_APIENTRY glInvalidateSubFramebuffer (GLenum target, GLsizei numAttachments, const GLenum* attachments, GLint x, GLint y, GLsizei width, GLsizei height); -GL_APICALL void GL_APIENTRY glTexStorage2D (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); -GL_APICALL void GL_APIENTRY glTexStorage3D (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); -GL_APICALL void GL_APIENTRY glGetInternalformativ (GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint* params); +#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS 0x8C8B +#define GL_INTERLEAVED_ATTRIBS 0x8C8C +#define GL_SEPARATE_ATTRIBS 0x8C8D +#define GL_TRANSFORM_FEEDBACK_BUFFER 0x8C8E +#define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING 0x8C8F +#define GL_RGBA32UI 0x8D70 +#define GL_RGB32UI 0x8D71 +#define GL_RGBA16UI 0x8D76 +#define GL_RGB16UI 0x8D77 +#define GL_RGBA8UI 0x8D7C +#define GL_RGB8UI 0x8D7D +#define GL_RGBA32I 0x8D82 +#define GL_RGB32I 0x8D83 +#define GL_RGBA16I 0x8D88 +#define GL_RGB16I 0x8D89 +#define GL_RGBA8I 0x8D8E +#define GL_RGB8I 0x8D8F +#define GL_RED_INTEGER 0x8D94 +#define GL_RGB_INTEGER 0x8D98 +#define GL_RGBA_INTEGER 0x8D99 +#define GL_SAMPLER_2D_ARRAY 0x8DC1 +#define GL_SAMPLER_2D_ARRAY_SHADOW 0x8DC4 +#define GL_SAMPLER_CUBE_SHADOW 0x8DC5 +#define GL_UNSIGNED_INT_VEC2 0x8DC6 +#define GL_UNSIGNED_INT_VEC3 0x8DC7 +#define GL_UNSIGNED_INT_VEC4 0x8DC8 +#define GL_INT_SAMPLER_2D 0x8DCA +#define GL_INT_SAMPLER_3D 0x8DCB +#define GL_INT_SAMPLER_CUBE 0x8DCC +#define GL_INT_SAMPLER_2D_ARRAY 0x8DCF +#define GL_UNSIGNED_INT_SAMPLER_2D 0x8DD2 +#define GL_UNSIGNED_INT_SAMPLER_3D 0x8DD3 +#define GL_UNSIGNED_INT_SAMPLER_CUBE 0x8DD4 +#define GL_UNSIGNED_INT_SAMPLER_2D_ARRAY 0x8DD7 +#define GL_BUFFER_ACCESS_FLAGS 0x911F +#define GL_BUFFER_MAP_LENGTH 0x9120 +#define GL_BUFFER_MAP_OFFSET 0x9121 +#define GL_DEPTH_COMPONENT32F 0x8CAC +#define GL_DEPTH32F_STENCIL8 0x8CAD +#define GL_FLOAT_32_UNSIGNED_INT_24_8_REV 0x8DAD +#define GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING 0x8210 +#define GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE 0x8211 +#define GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE 0x8212 +#define GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE 0x8213 +#define GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE 0x8214 +#define GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE 0x8215 +#define GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE 0x8216 +#define GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE 0x8217 +#define GL_FRAMEBUFFER_DEFAULT 0x8218 +#define GL_FRAMEBUFFER_UNDEFINED 0x8219 +#define GL_DEPTH_STENCIL_ATTACHMENT 0x821A +#define GL_DEPTH_STENCIL 0x84F9 +#define GL_UNSIGNED_INT_24_8 0x84FA +#define GL_DEPTH24_STENCIL8 0x88F0 +#define GL_UNSIGNED_NORMALIZED 0x8C17 +#define GL_DRAW_FRAMEBUFFER_BINDING 0x8CA6 +#define GL_READ_FRAMEBUFFER 0x8CA8 +#define GL_DRAW_FRAMEBUFFER 0x8CA9 +#define GL_READ_FRAMEBUFFER_BINDING 0x8CAA +#define GL_RENDERBUFFER_SAMPLES 0x8CAB +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER 0x8CD4 +#define GL_MAX_COLOR_ATTACHMENTS 0x8CDF +#define GL_COLOR_ATTACHMENT1 0x8CE1 +#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_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_ATTACHMENT16 0x8CF0 +#define GL_COLOR_ATTACHMENT17 0x8CF1 +#define GL_COLOR_ATTACHMENT18 0x8CF2 +#define GL_COLOR_ATTACHMENT19 0x8CF3 +#define GL_COLOR_ATTACHMENT20 0x8CF4 +#define GL_COLOR_ATTACHMENT21 0x8CF5 +#define GL_COLOR_ATTACHMENT22 0x8CF6 +#define GL_COLOR_ATTACHMENT23 0x8CF7 +#define GL_COLOR_ATTACHMENT24 0x8CF8 +#define GL_COLOR_ATTACHMENT25 0x8CF9 +#define GL_COLOR_ATTACHMENT26 0x8CFA +#define GL_COLOR_ATTACHMENT27 0x8CFB +#define GL_COLOR_ATTACHMENT28 0x8CFC +#define GL_COLOR_ATTACHMENT29 0x8CFD +#define GL_COLOR_ATTACHMENT30 0x8CFE +#define GL_COLOR_ATTACHMENT31 0x8CFF +#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE 0x8D56 +#define GL_MAX_SAMPLES 0x8D57 +#define GL_HALF_FLOAT 0x140B +#define GL_MAP_READ_BIT 0x0001 +#define GL_MAP_WRITE_BIT 0x0002 +#define GL_MAP_INVALIDATE_RANGE_BIT 0x0004 +#define GL_MAP_INVALIDATE_BUFFER_BIT 0x0008 +#define GL_MAP_FLUSH_EXPLICIT_BIT 0x0010 +#define GL_MAP_UNSYNCHRONIZED_BIT 0x0020 +#define GL_RG 0x8227 +#define GL_RG_INTEGER 0x8228 +#define GL_R8 0x8229 +#define GL_RG8 0x822B +#define GL_R16F 0x822D +#define GL_R32F 0x822E +#define GL_RG16F 0x822F +#define GL_RG32F 0x8230 +#define GL_R8I 0x8231 +#define GL_R8UI 0x8232 +#define GL_R16I 0x8233 +#define GL_R16UI 0x8234 +#define GL_R32I 0x8235 +#define GL_R32UI 0x8236 +#define GL_RG8I 0x8237 +#define GL_RG8UI 0x8238 +#define GL_RG16I 0x8239 +#define GL_RG16UI 0x823A +#define GL_RG32I 0x823B +#define GL_RG32UI 0x823C +#define GL_VERTEX_ARRAY_BINDING 0x85B5 +#define GL_R8_SNORM 0x8F94 +#define GL_RG8_SNORM 0x8F95 +#define GL_RGB8_SNORM 0x8F96 +#define GL_RGBA8_SNORM 0x8F97 +#define GL_SIGNED_NORMALIZED 0x8F9C +#define GL_PRIMITIVE_RESTART_FIXED_INDEX 0x8D69 +#define GL_COPY_READ_BUFFER 0x8F36 +#define GL_COPY_WRITE_BUFFER 0x8F37 +#define GL_COPY_READ_BUFFER_BINDING 0x8F36 +#define GL_COPY_WRITE_BUFFER_BINDING 0x8F37 +#define GL_UNIFORM_BUFFER 0x8A11 +#define GL_UNIFORM_BUFFER_BINDING 0x8A28 +#define GL_UNIFORM_BUFFER_START 0x8A29 +#define GL_UNIFORM_BUFFER_SIZE 0x8A2A +#define GL_MAX_VERTEX_UNIFORM_BLOCKS 0x8A2B +#define GL_MAX_FRAGMENT_UNIFORM_BLOCKS 0x8A2D +#define GL_MAX_COMBINED_UNIFORM_BLOCKS 0x8A2E +#define GL_MAX_UNIFORM_BUFFER_BINDINGS 0x8A2F +#define GL_MAX_UNIFORM_BLOCK_SIZE 0x8A30 +#define GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS 0x8A31 +#define GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS 0x8A33 +#define GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT 0x8A34 +#define GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH 0x8A35 +#define GL_ACTIVE_UNIFORM_BLOCKS 0x8A36 +#define GL_UNIFORM_TYPE 0x8A37 +#define GL_UNIFORM_SIZE 0x8A38 +#define GL_UNIFORM_NAME_LENGTH 0x8A39 +#define GL_UNIFORM_BLOCK_INDEX 0x8A3A +#define GL_UNIFORM_OFFSET 0x8A3B +#define GL_UNIFORM_ARRAY_STRIDE 0x8A3C +#define GL_UNIFORM_MATRIX_STRIDE 0x8A3D +#define GL_UNIFORM_IS_ROW_MAJOR 0x8A3E +#define GL_UNIFORM_BLOCK_BINDING 0x8A3F +#define GL_UNIFORM_BLOCK_DATA_SIZE 0x8A40 +#define GL_UNIFORM_BLOCK_NAME_LENGTH 0x8A41 +#define GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS 0x8A42 +#define GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES 0x8A43 +#define GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER 0x8A44 +#define GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER 0x8A46 +#define GL_INVALID_INDEX 0xFFFFFFFFu +#define GL_MAX_VERTEX_OUTPUT_COMPONENTS 0x9122 +#define GL_MAX_FRAGMENT_INPUT_COMPONENTS 0x9125 +#define GL_MAX_SERVER_WAIT_TIMEOUT 0x9111 +#define GL_OBJECT_TYPE 0x9112 +#define GL_SYNC_CONDITION 0x9113 +#define GL_SYNC_STATUS 0x9114 +#define GL_SYNC_FLAGS 0x9115 +#define GL_SYNC_FENCE 0x9116 +#define GL_SYNC_GPU_COMMANDS_COMPLETE 0x9117 +#define GL_UNSIGNALED 0x9118 +#define GL_SIGNALED 0x9119 +#define GL_ALREADY_SIGNALED 0x911A +#define GL_TIMEOUT_EXPIRED 0x911B +#define GL_CONDITION_SATISFIED 0x911C +#define GL_WAIT_FAILED 0x911D +#define GL_SYNC_FLUSH_COMMANDS_BIT 0x00000001 +#define GL_TIMEOUT_IGNORED 0xFFFFFFFFFFFFFFFFull +#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR 0x88FE +#define GL_ANY_SAMPLES_PASSED 0x8C2F +#define GL_ANY_SAMPLES_PASSED_CONSERVATIVE 0x8D6A +#define GL_SAMPLER_BINDING 0x8919 +#define GL_RGB10_A2UI 0x906F +#define GL_TEXTURE_SWIZZLE_R 0x8E42 +#define GL_TEXTURE_SWIZZLE_G 0x8E43 +#define GL_TEXTURE_SWIZZLE_B 0x8E44 +#define GL_TEXTURE_SWIZZLE_A 0x8E45 +#define GL_GREEN 0x1904 +#define GL_BLUE 0x1905 +#define GL_INT_2_10_10_10_REV 0x8D9F +#define GL_TRANSFORM_FEEDBACK 0x8E22 +#define GL_TRANSFORM_FEEDBACK_PAUSED 0x8E23 +#define GL_TRANSFORM_FEEDBACK_ACTIVE 0x8E24 +#define GL_TRANSFORM_FEEDBACK_BINDING 0x8E25 +#define GL_PROGRAM_BINARY_RETRIEVABLE_HINT 0x8257 +#define GL_PROGRAM_BINARY_LENGTH 0x8741 +#define GL_NUM_PROGRAM_BINARY_FORMATS 0x87FE +#define GL_PROGRAM_BINARY_FORMATS 0x87FF +#define GL_COMPRESSED_R11_EAC 0x9270 +#define GL_COMPRESSED_SIGNED_R11_EAC 0x9271 +#define GL_COMPRESSED_RG11_EAC 0x9272 +#define GL_COMPRESSED_SIGNED_RG11_EAC 0x9273 +#define GL_COMPRESSED_RGB8_ETC2 0x9274 +#define GL_COMPRESSED_SRGB8_ETC2 0x9275 +#define GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9276 +#define GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9277 +#define GL_COMPRESSED_RGBA8_ETC2_EAC 0x9278 +#define GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC 0x9279 +#define GL_TEXTURE_IMMUTABLE_FORMAT 0x912F +#define GL_MAX_ELEMENT_INDEX 0x8D6B +#define GL_NUM_SAMPLE_COUNTS 0x9380 +#define GL_TEXTURE_IMMUTABLE_LEVELS 0x82DF +typedef void (GL_APIENTRYP PFNGLREADBUFFERPROC) (GLenum src); +typedef void (GL_APIENTRYP PFNGLDRAWRANGEELEMENTSPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices); +typedef void (GL_APIENTRYP PFNGLTEXIMAGE3DPROC) (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *pixels); +typedef void (GL_APIENTRYP PFNGLTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels); +typedef void (GL_APIENTRYP PFNGLCOPYTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (GL_APIENTRYP PFNGLCOMPRESSEDTEXIMAGE3DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *data); +typedef void (GL_APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *data); +typedef void (GL_APIENTRYP PFNGLGENQUERIESPROC) (GLsizei n, GLuint *ids); +typedef void (GL_APIENTRYP PFNGLDELETEQUERIESPROC) (GLsizei n, const GLuint *ids); +typedef GLboolean (GL_APIENTRYP PFNGLISQUERYPROC) (GLuint id); +typedef void (GL_APIENTRYP PFNGLBEGINQUERYPROC) (GLenum target, GLuint id); +typedef void (GL_APIENTRYP PFNGLENDQUERYPROC) (GLenum target); +typedef void (GL_APIENTRYP PFNGLGETQUERYIVPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (GL_APIENTRYP PFNGLGETQUERYOBJECTUIVPROC) (GLuint id, GLenum pname, GLuint *params); +typedef GLboolean (GL_APIENTRYP PFNGLUNMAPBUFFERPROC) (GLenum target); +typedef void (GL_APIENTRYP PFNGLGETBUFFERPOINTERVPROC) (GLenum target, GLenum pname, void **params); +typedef void (GL_APIENTRYP PFNGLDRAWBUFFERSPROC) (GLsizei n, const GLenum *bufs); +typedef void (GL_APIENTRYP PFNGLUNIFORMMATRIX2X3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLUNIFORMMATRIX3X2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLUNIFORMMATRIX2X4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLUNIFORMMATRIX4X2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLUNIFORMMATRIX3X4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLUNIFORMMATRIX4X3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLBLITFRAMEBUFFERPROC) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); +typedef void (GL_APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERTEXTURELAYERPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); +typedef void *(GL_APIENTRYP PFNGLMAPBUFFERRANGEPROC) (GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access); +typedef void (GL_APIENTRYP PFNGLFLUSHMAPPEDBUFFERRANGEPROC) (GLenum target, GLintptr offset, GLsizeiptr length); +typedef void (GL_APIENTRYP PFNGLBINDVERTEXARRAYPROC) (GLuint array); +typedef void (GL_APIENTRYP PFNGLDELETEVERTEXARRAYSPROC) (GLsizei n, const GLuint *arrays); +typedef void (GL_APIENTRYP PFNGLGENVERTEXARRAYSPROC) (GLsizei n, GLuint *arrays); +typedef GLboolean (GL_APIENTRYP PFNGLISVERTEXARRAYPROC) (GLuint array); +typedef void (GL_APIENTRYP PFNGLGETINTEGERI_VPROC) (GLenum target, GLuint index, GLint *data); +typedef void (GL_APIENTRYP PFNGLBEGINTRANSFORMFEEDBACKPROC) (GLenum primitiveMode); +typedef void (GL_APIENTRYP PFNGLENDTRANSFORMFEEDBACKPROC) (void); +typedef void (GL_APIENTRYP PFNGLBINDBUFFERRANGEPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); +typedef void (GL_APIENTRYP PFNGLBINDBUFFERBASEPROC) (GLenum target, GLuint index, GLuint buffer); +typedef void (GL_APIENTRYP PFNGLTRANSFORMFEEDBACKVARYINGSPROC) (GLuint program, GLsizei count, const GLchar *const*varyings, GLenum bufferMode); +typedef void (GL_APIENTRYP PFNGLGETTRANSFORMFEEDBACKVARYINGPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name); +typedef void (GL_APIENTRYP PFNGLVERTEXATTRIBIPOINTERPROC) (GLuint index, GLint size, GLenum type, GLsizei stride, const void *pointer); +typedef void (GL_APIENTRYP PFNGLGETVERTEXATTRIBIIVPROC) (GLuint index, GLenum pname, GLint *params); +typedef void (GL_APIENTRYP PFNGLGETVERTEXATTRIBIUIVPROC) (GLuint index, GLenum pname, GLuint *params); +typedef void (GL_APIENTRYP PFNGLVERTEXATTRIBI4IPROC) (GLuint index, GLint x, GLint y, GLint z, GLint w); +typedef void (GL_APIENTRYP PFNGLVERTEXATTRIBI4UIPROC) (GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); +typedef void (GL_APIENTRYP PFNGLVERTEXATTRIBI4IVPROC) (GLuint index, const GLint *v); +typedef void (GL_APIENTRYP PFNGLVERTEXATTRIBI4UIVPROC) (GLuint index, const GLuint *v); +typedef void (GL_APIENTRYP PFNGLGETUNIFORMUIVPROC) (GLuint program, GLint location, GLuint *params); +typedef GLint (GL_APIENTRYP PFNGLGETFRAGDATALOCATIONPROC) (GLuint program, const GLchar *name); +typedef void (GL_APIENTRYP PFNGLUNIFORM1UIPROC) (GLint location, GLuint v0); +typedef void (GL_APIENTRYP PFNGLUNIFORM2UIPROC) (GLint location, GLuint v0, GLuint v1); +typedef void (GL_APIENTRYP PFNGLUNIFORM3UIPROC) (GLint location, GLuint v0, GLuint v1, GLuint v2); +typedef void (GL_APIENTRYP PFNGLUNIFORM4UIPROC) (GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); +typedef void (GL_APIENTRYP PFNGLUNIFORM1UIVPROC) (GLint location, GLsizei count, const GLuint *value); +typedef void (GL_APIENTRYP PFNGLUNIFORM2UIVPROC) (GLint location, GLsizei count, const GLuint *value); +typedef void (GL_APIENTRYP PFNGLUNIFORM3UIVPROC) (GLint location, GLsizei count, const GLuint *value); +typedef void (GL_APIENTRYP PFNGLUNIFORM4UIVPROC) (GLint location, GLsizei count, const GLuint *value); +typedef void (GL_APIENTRYP PFNGLCLEARBUFFERIVPROC) (GLenum buffer, GLint drawbuffer, const GLint *value); +typedef void (GL_APIENTRYP PFNGLCLEARBUFFERUIVPROC) (GLenum buffer, GLint drawbuffer, const GLuint *value); +typedef void (GL_APIENTRYP PFNGLCLEARBUFFERFVPROC) (GLenum buffer, GLint drawbuffer, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLCLEARBUFFERFIPROC) (GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil); +typedef const GLubyte *(GL_APIENTRYP PFNGLGETSTRINGIPROC) (GLenum name, GLuint index); +typedef void (GL_APIENTRYP PFNGLCOPYBUFFERSUBDATAPROC) (GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); +typedef void (GL_APIENTRYP PFNGLGETUNIFORMINDICESPROC) (GLuint program, GLsizei uniformCount, const GLchar *const*uniformNames, GLuint *uniformIndices); +typedef void (GL_APIENTRYP PFNGLGETACTIVEUNIFORMSIVPROC) (GLuint program, GLsizei uniformCount, const GLuint *uniformIndices, GLenum pname, GLint *params); +typedef GLuint (GL_APIENTRYP PFNGLGETUNIFORMBLOCKINDEXPROC) (GLuint program, const GLchar *uniformBlockName); +typedef void (GL_APIENTRYP PFNGLGETACTIVEUNIFORMBLOCKIVPROC) (GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint *params); +typedef void (GL_APIENTRYP PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC) (GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformBlockName); +typedef void (GL_APIENTRYP PFNGLUNIFORMBLOCKBINDINGPROC) (GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding); +typedef void (GL_APIENTRYP PFNGLDRAWARRAYSINSTANCEDPROC) (GLenum mode, GLint first, GLsizei count, GLsizei instancecount); +typedef void (GL_APIENTRYP PFNGLDRAWELEMENTSINSTANCEDPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount); +typedef GLsync (GL_APIENTRYP PFNGLFENCESYNCPROC) (GLenum condition, GLbitfield flags); +typedef GLboolean (GL_APIENTRYP PFNGLISSYNCPROC) (GLsync sync); +typedef void (GL_APIENTRYP PFNGLDELETESYNCPROC) (GLsync sync); +typedef GLenum (GL_APIENTRYP PFNGLCLIENTWAITSYNCPROC) (GLsync sync, GLbitfield flags, GLuint64 timeout); +typedef void (GL_APIENTRYP PFNGLWAITSYNCPROC) (GLsync sync, GLbitfield flags, GLuint64 timeout); +typedef void (GL_APIENTRYP PFNGLGETINTEGER64VPROC) (GLenum pname, GLint64 *data); +typedef void (GL_APIENTRYP PFNGLGETSYNCIVPROC) (GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values); +typedef void (GL_APIENTRYP PFNGLGETINTEGER64I_VPROC) (GLenum target, GLuint index, GLint64 *data); +typedef void (GL_APIENTRYP PFNGLGETBUFFERPARAMETERI64VPROC) (GLenum target, GLenum pname, GLint64 *params); +typedef void (GL_APIENTRYP PFNGLGENSAMPLERSPROC) (GLsizei count, GLuint *samplers); +typedef void (GL_APIENTRYP PFNGLDELETESAMPLERSPROC) (GLsizei count, const GLuint *samplers); +typedef GLboolean (GL_APIENTRYP PFNGLISSAMPLERPROC) (GLuint sampler); +typedef void (GL_APIENTRYP PFNGLBINDSAMPLERPROC) (GLuint unit, GLuint sampler); +typedef void (GL_APIENTRYP PFNGLSAMPLERPARAMETERIPROC) (GLuint sampler, GLenum pname, GLint param); +typedef void (GL_APIENTRYP PFNGLSAMPLERPARAMETERIVPROC) (GLuint sampler, GLenum pname, const GLint *param); +typedef void (GL_APIENTRYP PFNGLSAMPLERPARAMETERFPROC) (GLuint sampler, GLenum pname, GLfloat param); +typedef void (GL_APIENTRYP PFNGLSAMPLERPARAMETERFVPROC) (GLuint sampler, GLenum pname, const GLfloat *param); +typedef void (GL_APIENTRYP PFNGLGETSAMPLERPARAMETERIVPROC) (GLuint sampler, GLenum pname, GLint *params); +typedef void (GL_APIENTRYP PFNGLGETSAMPLERPARAMETERFVPROC) (GLuint sampler, GLenum pname, GLfloat *params); +typedef void (GL_APIENTRYP PFNGLVERTEXATTRIBDIVISORPROC) (GLuint index, GLuint divisor); +typedef void (GL_APIENTRYP PFNGLBINDTRANSFORMFEEDBACKPROC) (GLenum target, GLuint id); +typedef void (GL_APIENTRYP PFNGLDELETETRANSFORMFEEDBACKSPROC) (GLsizei n, const GLuint *ids); +typedef void (GL_APIENTRYP PFNGLGENTRANSFORMFEEDBACKSPROC) (GLsizei n, GLuint *ids); +typedef GLboolean (GL_APIENTRYP PFNGLISTRANSFORMFEEDBACKPROC) (GLuint id); +typedef void (GL_APIENTRYP PFNGLPAUSETRANSFORMFEEDBACKPROC) (void); +typedef void (GL_APIENTRYP PFNGLRESUMETRANSFORMFEEDBACKPROC) (void); +typedef void (GL_APIENTRYP PFNGLGETPROGRAMBINARYPROC) (GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, void *binary); +typedef void (GL_APIENTRYP PFNGLPROGRAMBINARYPROC) (GLuint program, GLenum binaryFormat, const void *binary, GLsizei length); +typedef void (GL_APIENTRYP PFNGLPROGRAMPARAMETERIPROC) (GLuint program, GLenum pname, GLint value); +typedef void (GL_APIENTRYP PFNGLINVALIDATEFRAMEBUFFERPROC) (GLenum target, GLsizei numAttachments, const GLenum *attachments); +typedef void (GL_APIENTRYP PFNGLINVALIDATESUBFRAMEBUFFERPROC) (GLenum target, GLsizei numAttachments, const GLenum *attachments, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (GL_APIENTRYP PFNGLTEXSTORAGE2DPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (GL_APIENTRYP PFNGLTEXSTORAGE3DPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); +typedef void (GL_APIENTRYP PFNGLGETINTERNALFORMATIVPROC) (GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint *params); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glReadBuffer (GLenum src); +GL_APICALL void GL_APIENTRY glDrawRangeElements (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices); +GL_APICALL void GL_APIENTRY glTexImage3D (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *pixels); +GL_APICALL void GL_APIENTRY glTexSubImage3D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels); +GL_APICALL void GL_APIENTRY glCopyTexSubImage3D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); +GL_APICALL void GL_APIENTRY glCompressedTexImage3D (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *data); +GL_APICALL void GL_APIENTRY glCompressedTexSubImage3D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *data); +GL_APICALL void GL_APIENTRY glGenQueries (GLsizei n, GLuint *ids); +GL_APICALL void GL_APIENTRY glDeleteQueries (GLsizei n, const GLuint *ids); +GL_APICALL GLboolean GL_APIENTRY glIsQuery (GLuint id); +GL_APICALL void GL_APIENTRY glBeginQuery (GLenum target, GLuint id); +GL_APICALL void GL_APIENTRY glEndQuery (GLenum target); +GL_APICALL void GL_APIENTRY glGetQueryiv (GLenum target, GLenum pname, GLint *params); +GL_APICALL void GL_APIENTRY glGetQueryObjectuiv (GLuint id, GLenum pname, GLuint *params); +GL_APICALL GLboolean GL_APIENTRY glUnmapBuffer (GLenum target); +GL_APICALL void GL_APIENTRY glGetBufferPointerv (GLenum target, GLenum pname, void **params); +GL_APICALL void GL_APIENTRY glDrawBuffers (GLsizei n, const GLenum *bufs); +GL_APICALL void GL_APIENTRY glUniformMatrix2x3fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GL_APICALL void GL_APIENTRY glUniformMatrix3x2fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GL_APICALL void GL_APIENTRY glUniformMatrix2x4fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GL_APICALL void GL_APIENTRY glUniformMatrix4x2fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GL_APICALL void GL_APIENTRY glUniformMatrix3x4fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GL_APICALL void GL_APIENTRY glUniformMatrix4x3fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GL_APICALL void GL_APIENTRY glBlitFramebuffer (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); +GL_APICALL void GL_APIENTRY glRenderbufferStorageMultisample (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +GL_APICALL void GL_APIENTRY glFramebufferTextureLayer (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); +GL_APICALL void *GL_APIENTRY glMapBufferRange (GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access); +GL_APICALL void GL_APIENTRY glFlushMappedBufferRange (GLenum target, GLintptr offset, GLsizeiptr length); +GL_APICALL void GL_APIENTRY glBindVertexArray (GLuint array); +GL_APICALL void GL_APIENTRY glDeleteVertexArrays (GLsizei n, const GLuint *arrays); +GL_APICALL void GL_APIENTRY glGenVertexArrays (GLsizei n, GLuint *arrays); +GL_APICALL GLboolean GL_APIENTRY glIsVertexArray (GLuint array); +GL_APICALL void GL_APIENTRY glGetIntegeri_v (GLenum target, GLuint index, GLint *data); +GL_APICALL void GL_APIENTRY glBeginTransformFeedback (GLenum primitiveMode); +GL_APICALL void GL_APIENTRY glEndTransformFeedback (void); +GL_APICALL void GL_APIENTRY glBindBufferRange (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); +GL_APICALL void GL_APIENTRY glBindBufferBase (GLenum target, GLuint index, GLuint buffer); +GL_APICALL void GL_APIENTRY glTransformFeedbackVaryings (GLuint program, GLsizei count, const GLchar *const*varyings, GLenum bufferMode); +GL_APICALL void GL_APIENTRY glGetTransformFeedbackVarying (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name); +GL_APICALL void GL_APIENTRY glVertexAttribIPointer (GLuint index, GLint size, GLenum type, GLsizei stride, const void *pointer); +GL_APICALL void GL_APIENTRY glGetVertexAttribIiv (GLuint index, GLenum pname, GLint *params); +GL_APICALL void GL_APIENTRY glGetVertexAttribIuiv (GLuint index, GLenum pname, GLuint *params); +GL_APICALL void GL_APIENTRY glVertexAttribI4i (GLuint index, GLint x, GLint y, GLint z, GLint w); +GL_APICALL void GL_APIENTRY glVertexAttribI4ui (GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); +GL_APICALL void GL_APIENTRY glVertexAttribI4iv (GLuint index, const GLint *v); +GL_APICALL void GL_APIENTRY glVertexAttribI4uiv (GLuint index, const GLuint *v); +GL_APICALL void GL_APIENTRY glGetUniformuiv (GLuint program, GLint location, GLuint *params); +GL_APICALL GLint GL_APIENTRY glGetFragDataLocation (GLuint program, const GLchar *name); +GL_APICALL void GL_APIENTRY glUniform1ui (GLint location, GLuint v0); +GL_APICALL void GL_APIENTRY glUniform2ui (GLint location, GLuint v0, GLuint v1); +GL_APICALL void GL_APIENTRY glUniform3ui (GLint location, GLuint v0, GLuint v1, GLuint v2); +GL_APICALL void GL_APIENTRY glUniform4ui (GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); +GL_APICALL void GL_APIENTRY glUniform1uiv (GLint location, GLsizei count, const GLuint *value); +GL_APICALL void GL_APIENTRY glUniform2uiv (GLint location, GLsizei count, const GLuint *value); +GL_APICALL void GL_APIENTRY glUniform3uiv (GLint location, GLsizei count, const GLuint *value); +GL_APICALL void GL_APIENTRY glUniform4uiv (GLint location, GLsizei count, const GLuint *value); +GL_APICALL void GL_APIENTRY glClearBufferiv (GLenum buffer, GLint drawbuffer, const GLint *value); +GL_APICALL void GL_APIENTRY glClearBufferuiv (GLenum buffer, GLint drawbuffer, const GLuint *value); +GL_APICALL void GL_APIENTRY glClearBufferfv (GLenum buffer, GLint drawbuffer, const GLfloat *value); +GL_APICALL void GL_APIENTRY glClearBufferfi (GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil); +GL_APICALL const GLubyte *GL_APIENTRY glGetStringi (GLenum name, GLuint index); +GL_APICALL void GL_APIENTRY glCopyBufferSubData (GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); +GL_APICALL void GL_APIENTRY glGetUniformIndices (GLuint program, GLsizei uniformCount, const GLchar *const*uniformNames, GLuint *uniformIndices); +GL_APICALL void GL_APIENTRY glGetActiveUniformsiv (GLuint program, GLsizei uniformCount, const GLuint *uniformIndices, GLenum pname, GLint *params); +GL_APICALL GLuint GL_APIENTRY glGetUniformBlockIndex (GLuint program, const GLchar *uniformBlockName); +GL_APICALL void GL_APIENTRY glGetActiveUniformBlockiv (GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint *params); +GL_APICALL void GL_APIENTRY glGetActiveUniformBlockName (GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformBlockName); +GL_APICALL void GL_APIENTRY glUniformBlockBinding (GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding); +GL_APICALL void GL_APIENTRY glDrawArraysInstanced (GLenum mode, GLint first, GLsizei count, GLsizei instancecount); +GL_APICALL void GL_APIENTRY glDrawElementsInstanced (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount); +GL_APICALL GLsync GL_APIENTRY glFenceSync (GLenum condition, GLbitfield flags); +GL_APICALL GLboolean GL_APIENTRY glIsSync (GLsync sync); +GL_APICALL void GL_APIENTRY glDeleteSync (GLsync sync); +GL_APICALL GLenum GL_APIENTRY glClientWaitSync (GLsync sync, GLbitfield flags, GLuint64 timeout); +GL_APICALL void GL_APIENTRY glWaitSync (GLsync sync, GLbitfield flags, GLuint64 timeout); +GL_APICALL void GL_APIENTRY glGetInteger64v (GLenum pname, GLint64 *data); +GL_APICALL void GL_APIENTRY glGetSynciv (GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values); +GL_APICALL void GL_APIENTRY glGetInteger64i_v (GLenum target, GLuint index, GLint64 *data); +GL_APICALL void GL_APIENTRY glGetBufferParameteri64v (GLenum target, GLenum pname, GLint64 *params); +GL_APICALL void GL_APIENTRY glGenSamplers (GLsizei count, GLuint *samplers); +GL_APICALL void GL_APIENTRY glDeleteSamplers (GLsizei count, const GLuint *samplers); +GL_APICALL GLboolean GL_APIENTRY glIsSampler (GLuint sampler); +GL_APICALL void GL_APIENTRY glBindSampler (GLuint unit, GLuint sampler); +GL_APICALL void GL_APIENTRY glSamplerParameteri (GLuint sampler, GLenum pname, GLint param); +GL_APICALL void GL_APIENTRY glSamplerParameteriv (GLuint sampler, GLenum pname, const GLint *param); +GL_APICALL void GL_APIENTRY glSamplerParameterf (GLuint sampler, GLenum pname, GLfloat param); +GL_APICALL void GL_APIENTRY glSamplerParameterfv (GLuint sampler, GLenum pname, const GLfloat *param); +GL_APICALL void GL_APIENTRY glGetSamplerParameteriv (GLuint sampler, GLenum pname, GLint *params); +GL_APICALL void GL_APIENTRY glGetSamplerParameterfv (GLuint sampler, GLenum pname, GLfloat *params); +GL_APICALL void GL_APIENTRY glVertexAttribDivisor (GLuint index, GLuint divisor); +GL_APICALL void GL_APIENTRY glBindTransformFeedback (GLenum target, GLuint id); +GL_APICALL void GL_APIENTRY glDeleteTransformFeedbacks (GLsizei n, const GLuint *ids); +GL_APICALL void GL_APIENTRY glGenTransformFeedbacks (GLsizei n, GLuint *ids); +GL_APICALL GLboolean GL_APIENTRY glIsTransformFeedback (GLuint id); +GL_APICALL void GL_APIENTRY glPauseTransformFeedback (void); +GL_APICALL void GL_APIENTRY glResumeTransformFeedback (void); +GL_APICALL void GL_APIENTRY glGetProgramBinary (GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, void *binary); +GL_APICALL void GL_APIENTRY glProgramBinary (GLuint program, GLenum binaryFormat, const void *binary, GLsizei length); +GL_APICALL void GL_APIENTRY glProgramParameteri (GLuint program, GLenum pname, GLint value); +GL_APICALL void GL_APIENTRY glInvalidateFramebuffer (GLenum target, GLsizei numAttachments, const GLenum *attachments); +GL_APICALL void GL_APIENTRY glInvalidateSubFramebuffer (GLenum target, GLsizei numAttachments, const GLenum *attachments, GLint x, GLint y, GLsizei width, GLsizei height); +GL_APICALL void GL_APIENTRY glTexStorage2D (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); +GL_APICALL void GL_APIENTRY glTexStorage3D (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); +GL_APICALL void GL_APIENTRY glGetInternalformativ (GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint *params); +#endif +#endif /* GL_ES_VERSION_3_0 */ #ifdef __cplusplus } diff --git a/Source/ThirdParty/ANGLE/include/GLES3/gl31.h b/Source/ThirdParty/ANGLE/include/GLES3/gl31.h new file mode 100644 index 000000000000..26f869b781d3 --- /dev/null +++ b/Source/ThirdParty/ANGLE/include/GLES3/gl31.h @@ -0,0 +1,1524 @@ +#ifndef __gl31_h_ +#define __gl31_h_ 1 + +#ifdef __cplusplus +extern "C" { +#endif + +/* +** Copyright (c) 2013-2015 The Khronos Group Inc. +** +** Permission is hereby granted, free of charge, to any person obtaining a +** copy of this software and/or associated documentation files (the +** "Materials"), to deal in the Materials without restriction, including +** without limitation the rights to use, copy, modify, merge, publish, +** distribute, sublicense, and/or sell copies of the Materials, and to +** permit persons to whom the Materials are furnished to do so, subject to +** the following conditions: +** +** The above copyright notice and this permission notice shall be included +** in all copies or substantial portions of the Materials. +** +** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. +*/ +/* +** This header is generated from the Khronos OpenGL / OpenGL ES XML +** API Registry. The current version of the Registry, generator scripts +** used to make the header, and the header can be found at +** http://www.opengl.org/registry/ +** +** Khronos $Revision$ on $Date$ +*/ + +#include + +#ifndef GL_APIENTRYP +#define GL_APIENTRYP GL_APIENTRY* +#endif + +/* Generated on date 20150809 */ + +/* Generated C header for: + * API: gles2 + * Profile: common + * Versions considered: 2\.[0-9]|3\.[01] + * Versions emitted: .* + * Default extensions included: None + * Additional extensions included: _nomatch_^ + * Extensions removed: _nomatch_^ + */ + +#ifndef GL_ES_VERSION_2_0 +#define GL_ES_VERSION_2_0 1 +#include +typedef khronos_int8_t GLbyte; +typedef khronos_float_t GLclampf; +typedef khronos_int32_t GLfixed; +typedef short GLshort; +typedef unsigned short GLushort; +typedef void GLvoid; +typedef struct __GLsync *GLsync; +typedef khronos_int64_t GLint64; +typedef khronos_uint64_t GLuint64; +typedef unsigned int GLenum; +typedef unsigned int GLuint; +typedef char GLchar; +typedef khronos_float_t GLfloat; +typedef khronos_ssize_t GLsizeiptr; +typedef khronos_intptr_t GLintptr; +typedef unsigned int GLbitfield; +typedef int GLint; +typedef unsigned char GLboolean; +typedef int GLsizei; +typedef khronos_uint8_t GLubyte; +#define GL_DEPTH_BUFFER_BIT 0x00000100 +#define GL_STENCIL_BUFFER_BIT 0x00000400 +#define GL_COLOR_BUFFER_BIT 0x00004000 +#define GL_FALSE 0 +#define GL_TRUE 1 +#define GL_POINTS 0x0000 +#define GL_LINES 0x0001 +#define GL_LINE_LOOP 0x0002 +#define GL_LINE_STRIP 0x0003 +#define GL_TRIANGLES 0x0004 +#define GL_TRIANGLE_STRIP 0x0005 +#define GL_TRIANGLE_FAN 0x0006 +#define GL_ZERO 0 +#define GL_ONE 1 +#define GL_SRC_COLOR 0x0300 +#define GL_ONE_MINUS_SRC_COLOR 0x0301 +#define GL_SRC_ALPHA 0x0302 +#define GL_ONE_MINUS_SRC_ALPHA 0x0303 +#define GL_DST_ALPHA 0x0304 +#define GL_ONE_MINUS_DST_ALPHA 0x0305 +#define GL_DST_COLOR 0x0306 +#define GL_ONE_MINUS_DST_COLOR 0x0307 +#define GL_SRC_ALPHA_SATURATE 0x0308 +#define GL_FUNC_ADD 0x8006 +#define GL_BLEND_EQUATION 0x8009 +#define GL_BLEND_EQUATION_RGB 0x8009 +#define GL_BLEND_EQUATION_ALPHA 0x883D +#define GL_FUNC_SUBTRACT 0x800A +#define GL_FUNC_REVERSE_SUBTRACT 0x800B +#define GL_BLEND_DST_RGB 0x80C8 +#define GL_BLEND_SRC_RGB 0x80C9 +#define GL_BLEND_DST_ALPHA 0x80CA +#define GL_BLEND_SRC_ALPHA 0x80CB +#define GL_CONSTANT_COLOR 0x8001 +#define GL_ONE_MINUS_CONSTANT_COLOR 0x8002 +#define GL_CONSTANT_ALPHA 0x8003 +#define GL_ONE_MINUS_CONSTANT_ALPHA 0x8004 +#define GL_BLEND_COLOR 0x8005 +#define GL_ARRAY_BUFFER 0x8892 +#define GL_ELEMENT_ARRAY_BUFFER 0x8893 +#define GL_ARRAY_BUFFER_BINDING 0x8894 +#define GL_ELEMENT_ARRAY_BUFFER_BINDING 0x8895 +#define GL_STREAM_DRAW 0x88E0 +#define GL_STATIC_DRAW 0x88E4 +#define GL_DYNAMIC_DRAW 0x88E8 +#define GL_BUFFER_SIZE 0x8764 +#define GL_BUFFER_USAGE 0x8765 +#define GL_CURRENT_VERTEX_ATTRIB 0x8626 +#define GL_FRONT 0x0404 +#define GL_BACK 0x0405 +#define GL_FRONT_AND_BACK 0x0408 +#define GL_TEXTURE_2D 0x0DE1 +#define GL_CULL_FACE 0x0B44 +#define GL_BLEND 0x0BE2 +#define GL_DITHER 0x0BD0 +#define GL_STENCIL_TEST 0x0B90 +#define GL_DEPTH_TEST 0x0B71 +#define GL_SCISSOR_TEST 0x0C11 +#define GL_POLYGON_OFFSET_FILL 0x8037 +#define GL_SAMPLE_ALPHA_TO_COVERAGE 0x809E +#define GL_SAMPLE_COVERAGE 0x80A0 +#define GL_NO_ERROR 0 +#define GL_INVALID_ENUM 0x0500 +#define GL_INVALID_VALUE 0x0501 +#define GL_INVALID_OPERATION 0x0502 +#define GL_OUT_OF_MEMORY 0x0505 +#define GL_CW 0x0900 +#define GL_CCW 0x0901 +#define GL_LINE_WIDTH 0x0B21 +#define GL_ALIASED_POINT_SIZE_RANGE 0x846D +#define GL_ALIASED_LINE_WIDTH_RANGE 0x846E +#define GL_CULL_FACE_MODE 0x0B45 +#define GL_FRONT_FACE 0x0B46 +#define GL_DEPTH_RANGE 0x0B70 +#define GL_DEPTH_WRITEMASK 0x0B72 +#define GL_DEPTH_CLEAR_VALUE 0x0B73 +#define GL_DEPTH_FUNC 0x0B74 +#define GL_STENCIL_CLEAR_VALUE 0x0B91 +#define GL_STENCIL_FUNC 0x0B92 +#define GL_STENCIL_FAIL 0x0B94 +#define GL_STENCIL_PASS_DEPTH_FAIL 0x0B95 +#define GL_STENCIL_PASS_DEPTH_PASS 0x0B96 +#define GL_STENCIL_REF 0x0B97 +#define GL_STENCIL_VALUE_MASK 0x0B93 +#define GL_STENCIL_WRITEMASK 0x0B98 +#define GL_STENCIL_BACK_FUNC 0x8800 +#define GL_STENCIL_BACK_FAIL 0x8801 +#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_VIEWPORT 0x0BA2 +#define GL_SCISSOR_BOX 0x0C10 +#define GL_COLOR_CLEAR_VALUE 0x0C22 +#define GL_COLOR_WRITEMASK 0x0C23 +#define GL_UNPACK_ALIGNMENT 0x0CF5 +#define GL_PACK_ALIGNMENT 0x0D05 +#define GL_MAX_TEXTURE_SIZE 0x0D33 +#define GL_MAX_VIEWPORT_DIMS 0x0D3A +#define GL_SUBPIXEL_BITS 0x0D50 +#define GL_RED_BITS 0x0D52 +#define GL_GREEN_BITS 0x0D53 +#define GL_BLUE_BITS 0x0D54 +#define GL_ALPHA_BITS 0x0D55 +#define GL_DEPTH_BITS 0x0D56 +#define GL_STENCIL_BITS 0x0D57 +#define GL_POLYGON_OFFSET_UNITS 0x2A00 +#define GL_POLYGON_OFFSET_FACTOR 0x8038 +#define GL_TEXTURE_BINDING_2D 0x8069 +#define GL_SAMPLE_BUFFERS 0x80A8 +#define GL_SAMPLES 0x80A9 +#define GL_SAMPLE_COVERAGE_VALUE 0x80AA +#define GL_SAMPLE_COVERAGE_INVERT 0x80AB +#define GL_NUM_COMPRESSED_TEXTURE_FORMATS 0x86A2 +#define GL_COMPRESSED_TEXTURE_FORMATS 0x86A3 +#define GL_DONT_CARE 0x1100 +#define GL_FASTEST 0x1101 +#define GL_NICEST 0x1102 +#define GL_GENERATE_MIPMAP_HINT 0x8192 +#define GL_BYTE 0x1400 +#define GL_UNSIGNED_BYTE 0x1401 +#define GL_SHORT 0x1402 +#define GL_UNSIGNED_SHORT 0x1403 +#define GL_INT 0x1404 +#define GL_UNSIGNED_INT 0x1405 +#define GL_FLOAT 0x1406 +#define GL_FIXED 0x140C +#define GL_DEPTH_COMPONENT 0x1902 +#define GL_ALPHA 0x1906 +#define GL_RGB 0x1907 +#define GL_RGBA 0x1908 +#define GL_LUMINANCE 0x1909 +#define GL_LUMINANCE_ALPHA 0x190A +#define GL_UNSIGNED_SHORT_4_4_4_4 0x8033 +#define GL_UNSIGNED_SHORT_5_5_5_1 0x8034 +#define GL_UNSIGNED_SHORT_5_6_5 0x8363 +#define GL_FRAGMENT_SHADER 0x8B30 +#define GL_VERTEX_SHADER 0x8B31 +#define GL_MAX_VERTEX_ATTRIBS 0x8869 +#define GL_MAX_VERTEX_UNIFORM_VECTORS 0x8DFB +#define GL_MAX_VARYING_VECTORS 0x8DFC +#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS 0x8B4D +#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS 0x8B4C +#define GL_MAX_TEXTURE_IMAGE_UNITS 0x8872 +#define GL_MAX_FRAGMENT_UNIFORM_VECTORS 0x8DFD +#define GL_SHADER_TYPE 0x8B4F +#define GL_DELETE_STATUS 0x8B80 +#define GL_LINK_STATUS 0x8B82 +#define GL_VALIDATE_STATUS 0x8B83 +#define GL_ATTACHED_SHADERS 0x8B85 +#define GL_ACTIVE_UNIFORMS 0x8B86 +#define GL_ACTIVE_UNIFORM_MAX_LENGTH 0x8B87 +#define GL_ACTIVE_ATTRIBUTES 0x8B89 +#define GL_ACTIVE_ATTRIBUTE_MAX_LENGTH 0x8B8A +#define GL_SHADING_LANGUAGE_VERSION 0x8B8C +#define GL_CURRENT_PROGRAM 0x8B8D +#define GL_NEVER 0x0200 +#define GL_LESS 0x0201 +#define GL_EQUAL 0x0202 +#define GL_LEQUAL 0x0203 +#define GL_GREATER 0x0204 +#define GL_NOTEQUAL 0x0205 +#define GL_GEQUAL 0x0206 +#define GL_ALWAYS 0x0207 +#define GL_KEEP 0x1E00 +#define GL_REPLACE 0x1E01 +#define GL_INCR 0x1E02 +#define GL_DECR 0x1E03 +#define GL_INVERT 0x150A +#define GL_INCR_WRAP 0x8507 +#define GL_DECR_WRAP 0x8508 +#define GL_VENDOR 0x1F00 +#define GL_RENDERER 0x1F01 +#define GL_VERSION 0x1F02 +#define GL_EXTENSIONS 0x1F03 +#define GL_NEAREST 0x2600 +#define GL_LINEAR 0x2601 +#define GL_NEAREST_MIPMAP_NEAREST 0x2700 +#define GL_LINEAR_MIPMAP_NEAREST 0x2701 +#define GL_NEAREST_MIPMAP_LINEAR 0x2702 +#define GL_LINEAR_MIPMAP_LINEAR 0x2703 +#define GL_TEXTURE_MAG_FILTER 0x2800 +#define GL_TEXTURE_MIN_FILTER 0x2801 +#define GL_TEXTURE_WRAP_S 0x2802 +#define GL_TEXTURE_WRAP_T 0x2803 +#define GL_TEXTURE 0x1702 +#define GL_TEXTURE_CUBE_MAP 0x8513 +#define GL_TEXTURE_BINDING_CUBE_MAP 0x8514 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x8515 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x8516 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x8517 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x8518 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x8519 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x851A +#define GL_MAX_CUBE_MAP_TEXTURE_SIZE 0x851C +#define GL_TEXTURE0 0x84C0 +#define GL_TEXTURE1 0x84C1 +#define GL_TEXTURE2 0x84C2 +#define GL_TEXTURE3 0x84C3 +#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_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_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_TEXTURE30 0x84DE +#define GL_TEXTURE31 0x84DF +#define GL_ACTIVE_TEXTURE 0x84E0 +#define GL_REPEAT 0x2901 +#define GL_CLAMP_TO_EDGE 0x812F +#define GL_MIRRORED_REPEAT 0x8370 +#define GL_FLOAT_VEC2 0x8B50 +#define GL_FLOAT_VEC3 0x8B51 +#define GL_FLOAT_VEC4 0x8B52 +#define GL_INT_VEC2 0x8B53 +#define GL_INT_VEC3 0x8B54 +#define GL_INT_VEC4 0x8B55 +#define GL_BOOL 0x8B56 +#define GL_BOOL_VEC2 0x8B57 +#define GL_BOOL_VEC3 0x8B58 +#define GL_BOOL_VEC4 0x8B59 +#define GL_FLOAT_MAT2 0x8B5A +#define GL_FLOAT_MAT3 0x8B5B +#define GL_FLOAT_MAT4 0x8B5C +#define GL_SAMPLER_2D 0x8B5E +#define GL_SAMPLER_CUBE 0x8B60 +#define GL_VERTEX_ATTRIB_ARRAY_ENABLED 0x8622 +#define GL_VERTEX_ATTRIB_ARRAY_SIZE 0x8623 +#define GL_VERTEX_ATTRIB_ARRAY_STRIDE 0x8624 +#define GL_VERTEX_ATTRIB_ARRAY_TYPE 0x8625 +#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED 0x886A +#define GL_VERTEX_ATTRIB_ARRAY_POINTER 0x8645 +#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING 0x889F +#define GL_IMPLEMENTATION_COLOR_READ_TYPE 0x8B9A +#define GL_IMPLEMENTATION_COLOR_READ_FORMAT 0x8B9B +#define GL_COMPILE_STATUS 0x8B81 +#define GL_INFO_LOG_LENGTH 0x8B84 +#define GL_SHADER_SOURCE_LENGTH 0x8B88 +#define GL_SHADER_COMPILER 0x8DFA +#define GL_SHADER_BINARY_FORMATS 0x8DF8 +#define GL_NUM_SHADER_BINARY_FORMATS 0x8DF9 +#define GL_LOW_FLOAT 0x8DF0 +#define GL_MEDIUM_FLOAT 0x8DF1 +#define GL_HIGH_FLOAT 0x8DF2 +#define GL_LOW_INT 0x8DF3 +#define GL_MEDIUM_INT 0x8DF4 +#define GL_HIGH_INT 0x8DF5 +#define GL_FRAMEBUFFER 0x8D40 +#define GL_RENDERBUFFER 0x8D41 +#define GL_RGBA4 0x8056 +#define GL_RGB5_A1 0x8057 +#define GL_RGB565 0x8D62 +#define GL_DEPTH_COMPONENT16 0x81A5 +#define GL_STENCIL_INDEX8 0x8D48 +#define GL_RENDERBUFFER_WIDTH 0x8D42 +#define GL_RENDERBUFFER_HEIGHT 0x8D43 +#define GL_RENDERBUFFER_INTERNAL_FORMAT 0x8D44 +#define GL_RENDERBUFFER_RED_SIZE 0x8D50 +#define GL_RENDERBUFFER_GREEN_SIZE 0x8D51 +#define GL_RENDERBUFFER_BLUE_SIZE 0x8D52 +#define GL_RENDERBUFFER_ALPHA_SIZE 0x8D53 +#define GL_RENDERBUFFER_DEPTH_SIZE 0x8D54 +#define GL_RENDERBUFFER_STENCIL_SIZE 0x8D55 +#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE 0x8CD0 +#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME 0x8CD1 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL 0x8CD2 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE 0x8CD3 +#define GL_COLOR_ATTACHMENT0 0x8CE0 +#define GL_DEPTH_ATTACHMENT 0x8D00 +#define GL_STENCIL_ATTACHMENT 0x8D20 +#define GL_NONE 0 +#define GL_FRAMEBUFFER_COMPLETE 0x8CD5 +#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT 0x8CD6 +#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT 0x8CD7 +#define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS 0x8CD9 +#define GL_FRAMEBUFFER_UNSUPPORTED 0x8CDD +#define GL_FRAMEBUFFER_BINDING 0x8CA6 +#define GL_RENDERBUFFER_BINDING 0x8CA7 +#define GL_MAX_RENDERBUFFER_SIZE 0x84E8 +#define GL_INVALID_FRAMEBUFFER_OPERATION 0x0506 +typedef void (GL_APIENTRYP PFNGLACTIVETEXTUREPROC) (GLenum texture); +typedef void (GL_APIENTRYP PFNGLATTACHSHADERPROC) (GLuint program, GLuint shader); +typedef void (GL_APIENTRYP PFNGLBINDATTRIBLOCATIONPROC) (GLuint program, GLuint index, const GLchar *name); +typedef void (GL_APIENTRYP PFNGLBINDBUFFERPROC) (GLenum target, GLuint buffer); +typedef void (GL_APIENTRYP PFNGLBINDFRAMEBUFFERPROC) (GLenum target, GLuint framebuffer); +typedef void (GL_APIENTRYP PFNGLBINDRENDERBUFFERPROC) (GLenum target, GLuint renderbuffer); +typedef void (GL_APIENTRYP PFNGLBINDTEXTUREPROC) (GLenum target, GLuint texture); +typedef void (GL_APIENTRYP PFNGLBLENDCOLORPROC) (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); +typedef void (GL_APIENTRYP PFNGLBLENDEQUATIONPROC) (GLenum mode); +typedef void (GL_APIENTRYP PFNGLBLENDEQUATIONSEPARATEPROC) (GLenum modeRGB, GLenum modeAlpha); +typedef void (GL_APIENTRYP PFNGLBLENDFUNCPROC) (GLenum sfactor, GLenum dfactor); +typedef void (GL_APIENTRYP PFNGLBLENDFUNCSEPARATEPROC) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); +typedef void (GL_APIENTRYP PFNGLBUFFERDATAPROC) (GLenum target, GLsizeiptr size, const void *data, GLenum usage); +typedef void (GL_APIENTRYP PFNGLBUFFERSUBDATAPROC) (GLenum target, GLintptr offset, GLsizeiptr size, const void *data); +typedef GLenum (GL_APIENTRYP PFNGLCHECKFRAMEBUFFERSTATUSPROC) (GLenum target); +typedef void (GL_APIENTRYP PFNGLCLEARPROC) (GLbitfield mask); +typedef void (GL_APIENTRYP PFNGLCLEARCOLORPROC) (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); +typedef void (GL_APIENTRYP PFNGLCLEARDEPTHFPROC) (GLfloat d); +typedef void (GL_APIENTRYP PFNGLCLEARSTENCILPROC) (GLint s); +typedef void (GL_APIENTRYP PFNGLCOLORMASKPROC) (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); +typedef void (GL_APIENTRYP PFNGLCOMPILESHADERPROC) (GLuint shader); +typedef void (GL_APIENTRYP PFNGLCOMPRESSEDTEXIMAGE2DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void *data); +typedef void (GL_APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *data); +typedef void (GL_APIENTRYP PFNGLCOPYTEXIMAGE2DPROC) (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); +typedef void (GL_APIENTRYP PFNGLCOPYTEXSUBIMAGE2DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); +typedef GLuint (GL_APIENTRYP PFNGLCREATEPROGRAMPROC) (void); +typedef GLuint (GL_APIENTRYP PFNGLCREATESHADERPROC) (GLenum type); +typedef void (GL_APIENTRYP PFNGLCULLFACEPROC) (GLenum mode); +typedef void (GL_APIENTRYP PFNGLDELETEBUFFERSPROC) (GLsizei n, const GLuint *buffers); +typedef void (GL_APIENTRYP PFNGLDELETEFRAMEBUFFERSPROC) (GLsizei n, const GLuint *framebuffers); +typedef void (GL_APIENTRYP PFNGLDELETEPROGRAMPROC) (GLuint program); +typedef void (GL_APIENTRYP PFNGLDELETERENDERBUFFERSPROC) (GLsizei n, const GLuint *renderbuffers); +typedef void (GL_APIENTRYP PFNGLDELETESHADERPROC) (GLuint shader); +typedef void (GL_APIENTRYP PFNGLDELETETEXTURESPROC) (GLsizei n, const GLuint *textures); +typedef void (GL_APIENTRYP PFNGLDEPTHFUNCPROC) (GLenum func); +typedef void (GL_APIENTRYP PFNGLDEPTHMASKPROC) (GLboolean flag); +typedef void (GL_APIENTRYP PFNGLDEPTHRANGEFPROC) (GLfloat n, GLfloat f); +typedef void (GL_APIENTRYP PFNGLDETACHSHADERPROC) (GLuint program, GLuint shader); +typedef void (GL_APIENTRYP PFNGLDISABLEPROC) (GLenum cap); +typedef void (GL_APIENTRYP PFNGLDISABLEVERTEXATTRIBARRAYPROC) (GLuint index); +typedef void (GL_APIENTRYP PFNGLDRAWARRAYSPROC) (GLenum mode, GLint first, GLsizei count); +typedef void (GL_APIENTRYP PFNGLDRAWELEMENTSPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices); +typedef void (GL_APIENTRYP PFNGLENABLEPROC) (GLenum cap); +typedef void (GL_APIENTRYP PFNGLENABLEVERTEXATTRIBARRAYPROC) (GLuint index); +typedef void (GL_APIENTRYP PFNGLFINISHPROC) (void); +typedef void (GL_APIENTRYP PFNGLFLUSHPROC) (void); +typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERRENDERBUFFERPROC) (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); +typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERTEXTURE2DPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +typedef void (GL_APIENTRYP PFNGLFRONTFACEPROC) (GLenum mode); +typedef void (GL_APIENTRYP PFNGLGENBUFFERSPROC) (GLsizei n, GLuint *buffers); +typedef void (GL_APIENTRYP PFNGLGENERATEMIPMAPPROC) (GLenum target); +typedef void (GL_APIENTRYP PFNGLGENFRAMEBUFFERSPROC) (GLsizei n, GLuint *framebuffers); +typedef void (GL_APIENTRYP PFNGLGENRENDERBUFFERSPROC) (GLsizei n, GLuint *renderbuffers); +typedef void (GL_APIENTRYP PFNGLGENTEXTURESPROC) (GLsizei n, GLuint *textures); +typedef void (GL_APIENTRYP PFNGLGETACTIVEATTRIBPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name); +typedef void (GL_APIENTRYP PFNGLGETACTIVEUNIFORMPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name); +typedef void (GL_APIENTRYP PFNGLGETATTACHEDSHADERSPROC) (GLuint program, GLsizei maxCount, GLsizei *count, GLuint *shaders); +typedef GLint (GL_APIENTRYP PFNGLGETATTRIBLOCATIONPROC) (GLuint program, const GLchar *name); +typedef void (GL_APIENTRYP PFNGLGETBOOLEANVPROC) (GLenum pname, GLboolean *data); +typedef void (GL_APIENTRYP PFNGLGETBUFFERPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); +typedef GLenum (GL_APIENTRYP PFNGLGETERRORPROC) (void); +typedef void (GL_APIENTRYP PFNGLGETFLOATVPROC) (GLenum pname, GLfloat *data); +typedef void (GL_APIENTRYP PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC) (GLenum target, GLenum attachment, GLenum pname, GLint *params); +typedef void (GL_APIENTRYP PFNGLGETINTEGERVPROC) (GLenum pname, GLint *data); +typedef void (GL_APIENTRYP PFNGLGETPROGRAMIVPROC) (GLuint program, GLenum pname, GLint *params); +typedef void (GL_APIENTRYP PFNGLGETPROGRAMINFOLOGPROC) (GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog); +typedef void (GL_APIENTRYP PFNGLGETRENDERBUFFERPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (GL_APIENTRYP PFNGLGETSHADERIVPROC) (GLuint shader, GLenum pname, GLint *params); +typedef void (GL_APIENTRYP PFNGLGETSHADERINFOLOGPROC) (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog); +typedef void (GL_APIENTRYP PFNGLGETSHADERPRECISIONFORMATPROC) (GLenum shadertype, GLenum precisiontype, GLint *range, GLint *precision); +typedef void (GL_APIENTRYP PFNGLGETSHADERSOURCEPROC) (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *source); +typedef const GLubyte *(GL_APIENTRYP PFNGLGETSTRINGPROC) (GLenum name); +typedef void (GL_APIENTRYP PFNGLGETTEXPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params); +typedef void (GL_APIENTRYP PFNGLGETTEXPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (GL_APIENTRYP PFNGLGETUNIFORMFVPROC) (GLuint program, GLint location, GLfloat *params); +typedef void (GL_APIENTRYP PFNGLGETUNIFORMIVPROC) (GLuint program, GLint location, GLint *params); +typedef GLint (GL_APIENTRYP PFNGLGETUNIFORMLOCATIONPROC) (GLuint program, const GLchar *name); +typedef void (GL_APIENTRYP PFNGLGETVERTEXATTRIBFVPROC) (GLuint index, GLenum pname, GLfloat *params); +typedef void (GL_APIENTRYP PFNGLGETVERTEXATTRIBIVPROC) (GLuint index, GLenum pname, GLint *params); +typedef void (GL_APIENTRYP PFNGLGETVERTEXATTRIBPOINTERVPROC) (GLuint index, GLenum pname, void **pointer); +typedef void (GL_APIENTRYP PFNGLHINTPROC) (GLenum target, GLenum mode); +typedef GLboolean (GL_APIENTRYP PFNGLISBUFFERPROC) (GLuint buffer); +typedef GLboolean (GL_APIENTRYP PFNGLISENABLEDPROC) (GLenum cap); +typedef GLboolean (GL_APIENTRYP PFNGLISFRAMEBUFFERPROC) (GLuint framebuffer); +typedef GLboolean (GL_APIENTRYP PFNGLISPROGRAMPROC) (GLuint program); +typedef GLboolean (GL_APIENTRYP PFNGLISRENDERBUFFERPROC) (GLuint renderbuffer); +typedef GLboolean (GL_APIENTRYP PFNGLISSHADERPROC) (GLuint shader); +typedef GLboolean (GL_APIENTRYP PFNGLISTEXTUREPROC) (GLuint texture); +typedef void (GL_APIENTRYP PFNGLLINEWIDTHPROC) (GLfloat width); +typedef void (GL_APIENTRYP PFNGLLINKPROGRAMPROC) (GLuint program); +typedef void (GL_APIENTRYP PFNGLPIXELSTOREIPROC) (GLenum pname, GLint param); +typedef void (GL_APIENTRYP PFNGLPOLYGONOFFSETPROC) (GLfloat factor, GLfloat units); +typedef void (GL_APIENTRYP PFNGLREADPIXELSPROC) (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void *pixels); +typedef void (GL_APIENTRYP PFNGLRELEASESHADERCOMPILERPROC) (void); +typedef void (GL_APIENTRYP PFNGLRENDERBUFFERSTORAGEPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (GL_APIENTRYP PFNGLSAMPLECOVERAGEPROC) (GLfloat value, GLboolean invert); +typedef void (GL_APIENTRYP PFNGLSCISSORPROC) (GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (GL_APIENTRYP PFNGLSHADERBINARYPROC) (GLsizei count, const GLuint *shaders, GLenum binaryformat, const void *binary, GLsizei length); +typedef void (GL_APIENTRYP PFNGLSHADERSOURCEPROC) (GLuint shader, GLsizei count, const GLchar *const*string, const GLint *length); +typedef void (GL_APIENTRYP PFNGLSTENCILFUNCPROC) (GLenum func, GLint ref, GLuint mask); +typedef void (GL_APIENTRYP PFNGLSTENCILFUNCSEPARATEPROC) (GLenum face, GLenum func, GLint ref, GLuint mask); +typedef void (GL_APIENTRYP PFNGLSTENCILMASKPROC) (GLuint mask); +typedef void (GL_APIENTRYP PFNGLSTENCILMASKSEPARATEPROC) (GLenum face, GLuint mask); +typedef void (GL_APIENTRYP PFNGLSTENCILOPPROC) (GLenum fail, GLenum zfail, GLenum zpass); +typedef void (GL_APIENTRYP PFNGLSTENCILOPSEPARATEPROC) (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass); +typedef void (GL_APIENTRYP PFNGLTEXIMAGE2DPROC) (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels); +typedef void (GL_APIENTRYP PFNGLTEXPARAMETERFPROC) (GLenum target, GLenum pname, GLfloat param); +typedef void (GL_APIENTRYP PFNGLTEXPARAMETERFVPROC) (GLenum target, GLenum pname, const GLfloat *params); +typedef void (GL_APIENTRYP PFNGLTEXPARAMETERIPROC) (GLenum target, GLenum pname, GLint param); +typedef void (GL_APIENTRYP PFNGLTEXPARAMETERIVPROC) (GLenum target, GLenum pname, const GLint *params); +typedef void (GL_APIENTRYP PFNGLTEXSUBIMAGE2DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels); +typedef void (GL_APIENTRYP PFNGLUNIFORM1FPROC) (GLint location, GLfloat v0); +typedef void (GL_APIENTRYP PFNGLUNIFORM1FVPROC) (GLint location, GLsizei count, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLUNIFORM1IPROC) (GLint location, GLint v0); +typedef void (GL_APIENTRYP PFNGLUNIFORM1IVPROC) (GLint location, GLsizei count, const GLint *value); +typedef void (GL_APIENTRYP PFNGLUNIFORM2FPROC) (GLint location, GLfloat v0, GLfloat v1); +typedef void (GL_APIENTRYP PFNGLUNIFORM2FVPROC) (GLint location, GLsizei count, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLUNIFORM2IPROC) (GLint location, GLint v0, GLint v1); +typedef void (GL_APIENTRYP PFNGLUNIFORM2IVPROC) (GLint location, GLsizei count, const GLint *value); +typedef void (GL_APIENTRYP PFNGLUNIFORM3FPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2); +typedef void (GL_APIENTRYP PFNGLUNIFORM3FVPROC) (GLint location, GLsizei count, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLUNIFORM3IPROC) (GLint location, GLint v0, GLint v1, GLint v2); +typedef void (GL_APIENTRYP PFNGLUNIFORM3IVPROC) (GLint location, GLsizei count, const GLint *value); +typedef void (GL_APIENTRYP PFNGLUNIFORM4FPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); +typedef void (GL_APIENTRYP PFNGLUNIFORM4FVPROC) (GLint location, GLsizei count, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLUNIFORM4IPROC) (GLint location, GLint v0, GLint v1, GLint v2, GLint v3); +typedef void (GL_APIENTRYP PFNGLUNIFORM4IVPROC) (GLint location, GLsizei count, const GLint *value); +typedef void (GL_APIENTRYP PFNGLUNIFORMMATRIX2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLUNIFORMMATRIX3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLUNIFORMMATRIX4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLUSEPROGRAMPROC) (GLuint program); +typedef void (GL_APIENTRYP PFNGLVALIDATEPROGRAMPROC) (GLuint program); +typedef void (GL_APIENTRYP PFNGLVERTEXATTRIB1FPROC) (GLuint index, GLfloat x); +typedef void (GL_APIENTRYP PFNGLVERTEXATTRIB1FVPROC) (GLuint index, const GLfloat *v); +typedef void (GL_APIENTRYP PFNGLVERTEXATTRIB2FPROC) (GLuint index, GLfloat x, GLfloat y); +typedef void (GL_APIENTRYP PFNGLVERTEXATTRIB2FVPROC) (GLuint index, const GLfloat *v); +typedef void (GL_APIENTRYP PFNGLVERTEXATTRIB3FPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z); +typedef void (GL_APIENTRYP PFNGLVERTEXATTRIB3FVPROC) (GLuint index, const GLfloat *v); +typedef void (GL_APIENTRYP PFNGLVERTEXATTRIB4FPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (GL_APIENTRYP PFNGLVERTEXATTRIB4FVPROC) (GLuint index, const GLfloat *v); +typedef void (GL_APIENTRYP PFNGLVERTEXATTRIBPOINTERPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer); +typedef void (GL_APIENTRYP PFNGLVIEWPORTPROC) (GLint x, GLint y, GLsizei width, GLsizei height); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glActiveTexture (GLenum texture); +GL_APICALL void GL_APIENTRY glAttachShader (GLuint program, GLuint shader); +GL_APICALL void GL_APIENTRY glBindAttribLocation (GLuint program, GLuint index, const GLchar *name); +GL_APICALL void GL_APIENTRY glBindBuffer (GLenum target, GLuint buffer); +GL_APICALL void GL_APIENTRY glBindFramebuffer (GLenum target, GLuint framebuffer); +GL_APICALL void GL_APIENTRY glBindRenderbuffer (GLenum target, GLuint renderbuffer); +GL_APICALL void GL_APIENTRY glBindTexture (GLenum target, GLuint texture); +GL_APICALL void GL_APIENTRY glBlendColor (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); +GL_APICALL void GL_APIENTRY glBlendEquation (GLenum mode); +GL_APICALL void GL_APIENTRY glBlendEquationSeparate (GLenum modeRGB, GLenum modeAlpha); +GL_APICALL void GL_APIENTRY glBlendFunc (GLenum sfactor, GLenum dfactor); +GL_APICALL void GL_APIENTRY glBlendFuncSeparate (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); +GL_APICALL void GL_APIENTRY glBufferData (GLenum target, GLsizeiptr size, const void *data, GLenum usage); +GL_APICALL void GL_APIENTRY glBufferSubData (GLenum target, GLintptr offset, GLsizeiptr size, const void *data); +GL_APICALL GLenum GL_APIENTRY glCheckFramebufferStatus (GLenum target); +GL_APICALL void GL_APIENTRY glClear (GLbitfield mask); +GL_APICALL void GL_APIENTRY glClearColor (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); +GL_APICALL void GL_APIENTRY glClearDepthf (GLfloat d); +GL_APICALL void GL_APIENTRY glClearStencil (GLint s); +GL_APICALL void GL_APIENTRY glColorMask (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); +GL_APICALL void GL_APIENTRY glCompileShader (GLuint shader); +GL_APICALL void GL_APIENTRY glCompressedTexImage2D (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void *data); +GL_APICALL void GL_APIENTRY glCompressedTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *data); +GL_APICALL void GL_APIENTRY glCopyTexImage2D (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); +GL_APICALL void GL_APIENTRY glCopyTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); +GL_APICALL GLuint GL_APIENTRY glCreateProgram (void); +GL_APICALL GLuint GL_APIENTRY glCreateShader (GLenum type); +GL_APICALL void GL_APIENTRY glCullFace (GLenum mode); +GL_APICALL void GL_APIENTRY glDeleteBuffers (GLsizei n, const GLuint *buffers); +GL_APICALL void GL_APIENTRY glDeleteFramebuffers (GLsizei n, const GLuint *framebuffers); +GL_APICALL void GL_APIENTRY glDeleteProgram (GLuint program); +GL_APICALL void GL_APIENTRY glDeleteRenderbuffers (GLsizei n, const GLuint *renderbuffers); +GL_APICALL void GL_APIENTRY glDeleteShader (GLuint shader); +GL_APICALL void GL_APIENTRY glDeleteTextures (GLsizei n, const GLuint *textures); +GL_APICALL void GL_APIENTRY glDepthFunc (GLenum func); +GL_APICALL void GL_APIENTRY glDepthMask (GLboolean flag); +GL_APICALL void GL_APIENTRY glDepthRangef (GLfloat n, GLfloat f); +GL_APICALL void GL_APIENTRY glDetachShader (GLuint program, GLuint shader); +GL_APICALL void GL_APIENTRY glDisable (GLenum cap); +GL_APICALL void GL_APIENTRY glDisableVertexAttribArray (GLuint index); +GL_APICALL void GL_APIENTRY glDrawArrays (GLenum mode, GLint first, GLsizei count); +GL_APICALL void GL_APIENTRY glDrawElements (GLenum mode, GLsizei count, GLenum type, const void *indices); +GL_APICALL void GL_APIENTRY glEnable (GLenum cap); +GL_APICALL void GL_APIENTRY glEnableVertexAttribArray (GLuint index); +GL_APICALL void GL_APIENTRY glFinish (void); +GL_APICALL void GL_APIENTRY glFlush (void); +GL_APICALL void GL_APIENTRY glFramebufferRenderbuffer (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); +GL_APICALL void GL_APIENTRY glFramebufferTexture2D (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +GL_APICALL void GL_APIENTRY glFrontFace (GLenum mode); +GL_APICALL void GL_APIENTRY glGenBuffers (GLsizei n, GLuint *buffers); +GL_APICALL void GL_APIENTRY glGenerateMipmap (GLenum target); +GL_APICALL void GL_APIENTRY glGenFramebuffers (GLsizei n, GLuint *framebuffers); +GL_APICALL void GL_APIENTRY glGenRenderbuffers (GLsizei n, GLuint *renderbuffers); +GL_APICALL void GL_APIENTRY glGenTextures (GLsizei n, GLuint *textures); +GL_APICALL void GL_APIENTRY glGetActiveAttrib (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name); +GL_APICALL void GL_APIENTRY glGetActiveUniform (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name); +GL_APICALL void GL_APIENTRY glGetAttachedShaders (GLuint program, GLsizei maxCount, GLsizei *count, GLuint *shaders); +GL_APICALL GLint GL_APIENTRY glGetAttribLocation (GLuint program, const GLchar *name); +GL_APICALL void GL_APIENTRY glGetBooleanv (GLenum pname, GLboolean *data); +GL_APICALL void GL_APIENTRY glGetBufferParameteriv (GLenum target, GLenum pname, GLint *params); +GL_APICALL GLenum GL_APIENTRY glGetError (void); +GL_APICALL void GL_APIENTRY glGetFloatv (GLenum pname, GLfloat *data); +GL_APICALL void GL_APIENTRY glGetFramebufferAttachmentParameteriv (GLenum target, GLenum attachment, GLenum pname, GLint *params); +GL_APICALL void GL_APIENTRY glGetIntegerv (GLenum pname, GLint *data); +GL_APICALL void GL_APIENTRY glGetProgramiv (GLuint program, GLenum pname, GLint *params); +GL_APICALL void GL_APIENTRY glGetProgramInfoLog (GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog); +GL_APICALL void GL_APIENTRY glGetRenderbufferParameteriv (GLenum target, GLenum pname, GLint *params); +GL_APICALL void GL_APIENTRY glGetShaderiv (GLuint shader, GLenum pname, GLint *params); +GL_APICALL void GL_APIENTRY glGetShaderInfoLog (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog); +GL_APICALL void GL_APIENTRY glGetShaderPrecisionFormat (GLenum shadertype, GLenum precisiontype, GLint *range, GLint *precision); +GL_APICALL void GL_APIENTRY glGetShaderSource (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *source); +GL_APICALL const GLubyte *GL_APIENTRY glGetString (GLenum name); +GL_APICALL void GL_APIENTRY glGetTexParameterfv (GLenum target, GLenum pname, GLfloat *params); +GL_APICALL void GL_APIENTRY glGetTexParameteriv (GLenum target, GLenum pname, GLint *params); +GL_APICALL void GL_APIENTRY glGetUniformfv (GLuint program, GLint location, GLfloat *params); +GL_APICALL void GL_APIENTRY glGetUniformiv (GLuint program, GLint location, GLint *params); +GL_APICALL GLint GL_APIENTRY glGetUniformLocation (GLuint program, const GLchar *name); +GL_APICALL void GL_APIENTRY glGetVertexAttribfv (GLuint index, GLenum pname, GLfloat *params); +GL_APICALL void GL_APIENTRY glGetVertexAttribiv (GLuint index, GLenum pname, GLint *params); +GL_APICALL void GL_APIENTRY glGetVertexAttribPointerv (GLuint index, GLenum pname, void **pointer); +GL_APICALL void GL_APIENTRY glHint (GLenum target, GLenum mode); +GL_APICALL GLboolean GL_APIENTRY glIsBuffer (GLuint buffer); +GL_APICALL GLboolean GL_APIENTRY glIsEnabled (GLenum cap); +GL_APICALL GLboolean GL_APIENTRY glIsFramebuffer (GLuint framebuffer); +GL_APICALL GLboolean GL_APIENTRY glIsProgram (GLuint program); +GL_APICALL GLboolean GL_APIENTRY glIsRenderbuffer (GLuint renderbuffer); +GL_APICALL GLboolean GL_APIENTRY glIsShader (GLuint shader); +GL_APICALL GLboolean GL_APIENTRY glIsTexture (GLuint texture); +GL_APICALL void GL_APIENTRY glLineWidth (GLfloat width); +GL_APICALL void GL_APIENTRY glLinkProgram (GLuint program); +GL_APICALL void GL_APIENTRY glPixelStorei (GLenum pname, GLint param); +GL_APICALL void GL_APIENTRY glPolygonOffset (GLfloat factor, GLfloat units); +GL_APICALL void GL_APIENTRY glReadPixels (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void *pixels); +GL_APICALL void GL_APIENTRY glReleaseShaderCompiler (void); +GL_APICALL void GL_APIENTRY glRenderbufferStorage (GLenum target, GLenum internalformat, GLsizei width, GLsizei height); +GL_APICALL void GL_APIENTRY glSampleCoverage (GLfloat value, GLboolean invert); +GL_APICALL void GL_APIENTRY glScissor (GLint x, GLint y, GLsizei width, GLsizei height); +GL_APICALL void GL_APIENTRY glShaderBinary (GLsizei count, const GLuint *shaders, GLenum binaryformat, const void *binary, GLsizei length); +GL_APICALL void GL_APIENTRY glShaderSource (GLuint shader, GLsizei count, const GLchar *const*string, const GLint *length); +GL_APICALL void GL_APIENTRY glStencilFunc (GLenum func, GLint ref, GLuint mask); +GL_APICALL void GL_APIENTRY glStencilFuncSeparate (GLenum face, GLenum func, GLint ref, GLuint mask); +GL_APICALL void GL_APIENTRY glStencilMask (GLuint mask); +GL_APICALL void GL_APIENTRY glStencilMaskSeparate (GLenum face, GLuint mask); +GL_APICALL void GL_APIENTRY glStencilOp (GLenum fail, GLenum zfail, GLenum zpass); +GL_APICALL void GL_APIENTRY glStencilOpSeparate (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass); +GL_APICALL void GL_APIENTRY glTexImage2D (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels); +GL_APICALL void GL_APIENTRY glTexParameterf (GLenum target, GLenum pname, GLfloat param); +GL_APICALL void GL_APIENTRY glTexParameterfv (GLenum target, GLenum pname, const GLfloat *params); +GL_APICALL void GL_APIENTRY glTexParameteri (GLenum target, GLenum pname, GLint param); +GL_APICALL void GL_APIENTRY glTexParameteriv (GLenum target, GLenum pname, const GLint *params); +GL_APICALL void GL_APIENTRY glTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels); +GL_APICALL void GL_APIENTRY glUniform1f (GLint location, GLfloat v0); +GL_APICALL void GL_APIENTRY glUniform1fv (GLint location, GLsizei count, const GLfloat *value); +GL_APICALL void GL_APIENTRY glUniform1i (GLint location, GLint v0); +GL_APICALL void GL_APIENTRY glUniform1iv (GLint location, GLsizei count, const GLint *value); +GL_APICALL void GL_APIENTRY glUniform2f (GLint location, GLfloat v0, GLfloat v1); +GL_APICALL void GL_APIENTRY glUniform2fv (GLint location, GLsizei count, const GLfloat *value); +GL_APICALL void GL_APIENTRY glUniform2i (GLint location, GLint v0, GLint v1); +GL_APICALL void GL_APIENTRY glUniform2iv (GLint location, GLsizei count, const GLint *value); +GL_APICALL void GL_APIENTRY glUniform3f (GLint location, GLfloat v0, GLfloat v1, GLfloat v2); +GL_APICALL void GL_APIENTRY glUniform3fv (GLint location, GLsizei count, const GLfloat *value); +GL_APICALL void GL_APIENTRY glUniform3i (GLint location, GLint v0, GLint v1, GLint v2); +GL_APICALL void GL_APIENTRY glUniform3iv (GLint location, GLsizei count, const GLint *value); +GL_APICALL void GL_APIENTRY glUniform4f (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); +GL_APICALL void GL_APIENTRY glUniform4fv (GLint location, GLsizei count, const GLfloat *value); +GL_APICALL void GL_APIENTRY glUniform4i (GLint location, GLint v0, GLint v1, GLint v2, GLint v3); +GL_APICALL void GL_APIENTRY glUniform4iv (GLint location, GLsizei count, const GLint *value); +GL_APICALL void GL_APIENTRY glUniformMatrix2fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GL_APICALL void GL_APIENTRY glUniformMatrix3fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GL_APICALL void GL_APIENTRY glUniformMatrix4fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GL_APICALL void GL_APIENTRY glUseProgram (GLuint program); +GL_APICALL void GL_APIENTRY glValidateProgram (GLuint program); +GL_APICALL void GL_APIENTRY glVertexAttrib1f (GLuint index, GLfloat x); +GL_APICALL void GL_APIENTRY glVertexAttrib1fv (GLuint index, const GLfloat *v); +GL_APICALL void GL_APIENTRY glVertexAttrib2f (GLuint index, GLfloat x, GLfloat y); +GL_APICALL void GL_APIENTRY glVertexAttrib2fv (GLuint index, const GLfloat *v); +GL_APICALL void GL_APIENTRY glVertexAttrib3f (GLuint index, GLfloat x, GLfloat y, GLfloat z); +GL_APICALL void GL_APIENTRY glVertexAttrib3fv (GLuint index, const GLfloat *v); +GL_APICALL void GL_APIENTRY glVertexAttrib4f (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +GL_APICALL void GL_APIENTRY glVertexAttrib4fv (GLuint index, const GLfloat *v); +GL_APICALL void GL_APIENTRY glVertexAttribPointer (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer); +GL_APICALL void GL_APIENTRY glViewport (GLint x, GLint y, GLsizei width, GLsizei height); +#endif +#endif /* GL_ES_VERSION_2_0 */ + +#ifndef GL_ES_VERSION_3_0 +#define GL_ES_VERSION_3_0 1 +typedef unsigned short GLhalf; +#define GL_READ_BUFFER 0x0C02 +#define GL_UNPACK_ROW_LENGTH 0x0CF2 +#define GL_UNPACK_SKIP_ROWS 0x0CF3 +#define GL_UNPACK_SKIP_PIXELS 0x0CF4 +#define GL_PACK_ROW_LENGTH 0x0D02 +#define GL_PACK_SKIP_ROWS 0x0D03 +#define GL_PACK_SKIP_PIXELS 0x0D04 +#define GL_COLOR 0x1800 +#define GL_DEPTH 0x1801 +#define GL_STENCIL 0x1802 +#define GL_RED 0x1903 +#define GL_RGB8 0x8051 +#define GL_RGBA8 0x8058 +#define GL_RGB10_A2 0x8059 +#define GL_TEXTURE_BINDING_3D 0x806A +#define GL_UNPACK_SKIP_IMAGES 0x806D +#define GL_UNPACK_IMAGE_HEIGHT 0x806E +#define GL_TEXTURE_3D 0x806F +#define GL_TEXTURE_WRAP_R 0x8072 +#define GL_MAX_3D_TEXTURE_SIZE 0x8073 +#define GL_UNSIGNED_INT_2_10_10_10_REV 0x8368 +#define GL_MAX_ELEMENTS_VERTICES 0x80E8 +#define GL_MAX_ELEMENTS_INDICES 0x80E9 +#define GL_TEXTURE_MIN_LOD 0x813A +#define GL_TEXTURE_MAX_LOD 0x813B +#define GL_TEXTURE_BASE_LEVEL 0x813C +#define GL_TEXTURE_MAX_LEVEL 0x813D +#define GL_MIN 0x8007 +#define GL_MAX 0x8008 +#define GL_DEPTH_COMPONENT24 0x81A6 +#define GL_MAX_TEXTURE_LOD_BIAS 0x84FD +#define GL_TEXTURE_COMPARE_MODE 0x884C +#define GL_TEXTURE_COMPARE_FUNC 0x884D +#define GL_CURRENT_QUERY 0x8865 +#define GL_QUERY_RESULT 0x8866 +#define GL_QUERY_RESULT_AVAILABLE 0x8867 +#define GL_BUFFER_MAPPED 0x88BC +#define GL_BUFFER_MAP_POINTER 0x88BD +#define GL_STREAM_READ 0x88E1 +#define GL_STREAM_COPY 0x88E2 +#define GL_STATIC_READ 0x88E5 +#define GL_STATIC_COPY 0x88E6 +#define GL_DYNAMIC_READ 0x88E9 +#define GL_DYNAMIC_COPY 0x88EA +#define GL_MAX_DRAW_BUFFERS 0x8824 +#define GL_DRAW_BUFFER0 0x8825 +#define GL_DRAW_BUFFER1 0x8826 +#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_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_MAX_FRAGMENT_UNIFORM_COMPONENTS 0x8B49 +#define GL_MAX_VERTEX_UNIFORM_COMPONENTS 0x8B4A +#define GL_SAMPLER_3D 0x8B5F +#define GL_SAMPLER_2D_SHADOW 0x8B62 +#define GL_FRAGMENT_SHADER_DERIVATIVE_HINT 0x8B8B +#define GL_PIXEL_PACK_BUFFER 0x88EB +#define GL_PIXEL_UNPACK_BUFFER 0x88EC +#define GL_PIXEL_PACK_BUFFER_BINDING 0x88ED +#define GL_PIXEL_UNPACK_BUFFER_BINDING 0x88EF +#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_SRGB 0x8C40 +#define GL_SRGB8 0x8C41 +#define GL_SRGB8_ALPHA8 0x8C43 +#define GL_COMPARE_REF_TO_TEXTURE 0x884E +#define GL_MAJOR_VERSION 0x821B +#define GL_MINOR_VERSION 0x821C +#define GL_NUM_EXTENSIONS 0x821D +#define GL_RGBA32F 0x8814 +#define GL_RGB32F 0x8815 +#define GL_RGBA16F 0x881A +#define GL_RGB16F 0x881B +#define GL_VERTEX_ATTRIB_ARRAY_INTEGER 0x88FD +#define GL_MAX_ARRAY_TEXTURE_LAYERS 0x88FF +#define GL_MIN_PROGRAM_TEXEL_OFFSET 0x8904 +#define GL_MAX_PROGRAM_TEXEL_OFFSET 0x8905 +#define GL_MAX_VARYING_COMPONENTS 0x8B4B +#define GL_TEXTURE_2D_ARRAY 0x8C1A +#define GL_TEXTURE_BINDING_2D_ARRAY 0x8C1D +#define GL_R11F_G11F_B10F 0x8C3A +#define GL_UNSIGNED_INT_10F_11F_11F_REV 0x8C3B +#define GL_RGB9_E5 0x8C3D +#define GL_UNSIGNED_INT_5_9_9_9_REV 0x8C3E +#define GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH 0x8C76 +#define GL_TRANSFORM_FEEDBACK_BUFFER_MODE 0x8C7F +#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS 0x8C80 +#define GL_TRANSFORM_FEEDBACK_VARYINGS 0x8C83 +#define GL_TRANSFORM_FEEDBACK_BUFFER_START 0x8C84 +#define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE 0x8C85 +#define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN 0x8C88 +#define GL_RASTERIZER_DISCARD 0x8C89 +#define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS 0x8C8A +#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS 0x8C8B +#define GL_INTERLEAVED_ATTRIBS 0x8C8C +#define GL_SEPARATE_ATTRIBS 0x8C8D +#define GL_TRANSFORM_FEEDBACK_BUFFER 0x8C8E +#define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING 0x8C8F +#define GL_RGBA32UI 0x8D70 +#define GL_RGB32UI 0x8D71 +#define GL_RGBA16UI 0x8D76 +#define GL_RGB16UI 0x8D77 +#define GL_RGBA8UI 0x8D7C +#define GL_RGB8UI 0x8D7D +#define GL_RGBA32I 0x8D82 +#define GL_RGB32I 0x8D83 +#define GL_RGBA16I 0x8D88 +#define GL_RGB16I 0x8D89 +#define GL_RGBA8I 0x8D8E +#define GL_RGB8I 0x8D8F +#define GL_RED_INTEGER 0x8D94 +#define GL_RGB_INTEGER 0x8D98 +#define GL_RGBA_INTEGER 0x8D99 +#define GL_SAMPLER_2D_ARRAY 0x8DC1 +#define GL_SAMPLER_2D_ARRAY_SHADOW 0x8DC4 +#define GL_SAMPLER_CUBE_SHADOW 0x8DC5 +#define GL_UNSIGNED_INT_VEC2 0x8DC6 +#define GL_UNSIGNED_INT_VEC3 0x8DC7 +#define GL_UNSIGNED_INT_VEC4 0x8DC8 +#define GL_INT_SAMPLER_2D 0x8DCA +#define GL_INT_SAMPLER_3D 0x8DCB +#define GL_INT_SAMPLER_CUBE 0x8DCC +#define GL_INT_SAMPLER_2D_ARRAY 0x8DCF +#define GL_UNSIGNED_INT_SAMPLER_2D 0x8DD2 +#define GL_UNSIGNED_INT_SAMPLER_3D 0x8DD3 +#define GL_UNSIGNED_INT_SAMPLER_CUBE 0x8DD4 +#define GL_UNSIGNED_INT_SAMPLER_2D_ARRAY 0x8DD7 +#define GL_BUFFER_ACCESS_FLAGS 0x911F +#define GL_BUFFER_MAP_LENGTH 0x9120 +#define GL_BUFFER_MAP_OFFSET 0x9121 +#define GL_DEPTH_COMPONENT32F 0x8CAC +#define GL_DEPTH32F_STENCIL8 0x8CAD +#define GL_FLOAT_32_UNSIGNED_INT_24_8_REV 0x8DAD +#define GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING 0x8210 +#define GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE 0x8211 +#define GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE 0x8212 +#define GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE 0x8213 +#define GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE 0x8214 +#define GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE 0x8215 +#define GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE 0x8216 +#define GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE 0x8217 +#define GL_FRAMEBUFFER_DEFAULT 0x8218 +#define GL_FRAMEBUFFER_UNDEFINED 0x8219 +#define GL_DEPTH_STENCIL_ATTACHMENT 0x821A +#define GL_DEPTH_STENCIL 0x84F9 +#define GL_UNSIGNED_INT_24_8 0x84FA +#define GL_DEPTH24_STENCIL8 0x88F0 +#define GL_UNSIGNED_NORMALIZED 0x8C17 +#define GL_DRAW_FRAMEBUFFER_BINDING 0x8CA6 +#define GL_READ_FRAMEBUFFER 0x8CA8 +#define GL_DRAW_FRAMEBUFFER 0x8CA9 +#define GL_READ_FRAMEBUFFER_BINDING 0x8CAA +#define GL_RENDERBUFFER_SAMPLES 0x8CAB +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER 0x8CD4 +#define GL_MAX_COLOR_ATTACHMENTS 0x8CDF +#define GL_COLOR_ATTACHMENT1 0x8CE1 +#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_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_ATTACHMENT16 0x8CF0 +#define GL_COLOR_ATTACHMENT17 0x8CF1 +#define GL_COLOR_ATTACHMENT18 0x8CF2 +#define GL_COLOR_ATTACHMENT19 0x8CF3 +#define GL_COLOR_ATTACHMENT20 0x8CF4 +#define GL_COLOR_ATTACHMENT21 0x8CF5 +#define GL_COLOR_ATTACHMENT22 0x8CF6 +#define GL_COLOR_ATTACHMENT23 0x8CF7 +#define GL_COLOR_ATTACHMENT24 0x8CF8 +#define GL_COLOR_ATTACHMENT25 0x8CF9 +#define GL_COLOR_ATTACHMENT26 0x8CFA +#define GL_COLOR_ATTACHMENT27 0x8CFB +#define GL_COLOR_ATTACHMENT28 0x8CFC +#define GL_COLOR_ATTACHMENT29 0x8CFD +#define GL_COLOR_ATTACHMENT30 0x8CFE +#define GL_COLOR_ATTACHMENT31 0x8CFF +#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE 0x8D56 +#define GL_MAX_SAMPLES 0x8D57 +#define GL_HALF_FLOAT 0x140B +#define GL_MAP_READ_BIT 0x0001 +#define GL_MAP_WRITE_BIT 0x0002 +#define GL_MAP_INVALIDATE_RANGE_BIT 0x0004 +#define GL_MAP_INVALIDATE_BUFFER_BIT 0x0008 +#define GL_MAP_FLUSH_EXPLICIT_BIT 0x0010 +#define GL_MAP_UNSYNCHRONIZED_BIT 0x0020 +#define GL_RG 0x8227 +#define GL_RG_INTEGER 0x8228 +#define GL_R8 0x8229 +#define GL_RG8 0x822B +#define GL_R16F 0x822D +#define GL_R32F 0x822E +#define GL_RG16F 0x822F +#define GL_RG32F 0x8230 +#define GL_R8I 0x8231 +#define GL_R8UI 0x8232 +#define GL_R16I 0x8233 +#define GL_R16UI 0x8234 +#define GL_R32I 0x8235 +#define GL_R32UI 0x8236 +#define GL_RG8I 0x8237 +#define GL_RG8UI 0x8238 +#define GL_RG16I 0x8239 +#define GL_RG16UI 0x823A +#define GL_RG32I 0x823B +#define GL_RG32UI 0x823C +#define GL_VERTEX_ARRAY_BINDING 0x85B5 +#define GL_R8_SNORM 0x8F94 +#define GL_RG8_SNORM 0x8F95 +#define GL_RGB8_SNORM 0x8F96 +#define GL_RGBA8_SNORM 0x8F97 +#define GL_SIGNED_NORMALIZED 0x8F9C +#define GL_PRIMITIVE_RESTART_FIXED_INDEX 0x8D69 +#define GL_COPY_READ_BUFFER 0x8F36 +#define GL_COPY_WRITE_BUFFER 0x8F37 +#define GL_COPY_READ_BUFFER_BINDING 0x8F36 +#define GL_COPY_WRITE_BUFFER_BINDING 0x8F37 +#define GL_UNIFORM_BUFFER 0x8A11 +#define GL_UNIFORM_BUFFER_BINDING 0x8A28 +#define GL_UNIFORM_BUFFER_START 0x8A29 +#define GL_UNIFORM_BUFFER_SIZE 0x8A2A +#define GL_MAX_VERTEX_UNIFORM_BLOCKS 0x8A2B +#define GL_MAX_FRAGMENT_UNIFORM_BLOCKS 0x8A2D +#define GL_MAX_COMBINED_UNIFORM_BLOCKS 0x8A2E +#define GL_MAX_UNIFORM_BUFFER_BINDINGS 0x8A2F +#define GL_MAX_UNIFORM_BLOCK_SIZE 0x8A30 +#define GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS 0x8A31 +#define GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS 0x8A33 +#define GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT 0x8A34 +#define GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH 0x8A35 +#define GL_ACTIVE_UNIFORM_BLOCKS 0x8A36 +#define GL_UNIFORM_TYPE 0x8A37 +#define GL_UNIFORM_SIZE 0x8A38 +#define GL_UNIFORM_NAME_LENGTH 0x8A39 +#define GL_UNIFORM_BLOCK_INDEX 0x8A3A +#define GL_UNIFORM_OFFSET 0x8A3B +#define GL_UNIFORM_ARRAY_STRIDE 0x8A3C +#define GL_UNIFORM_MATRIX_STRIDE 0x8A3D +#define GL_UNIFORM_IS_ROW_MAJOR 0x8A3E +#define GL_UNIFORM_BLOCK_BINDING 0x8A3F +#define GL_UNIFORM_BLOCK_DATA_SIZE 0x8A40 +#define GL_UNIFORM_BLOCK_NAME_LENGTH 0x8A41 +#define GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS 0x8A42 +#define GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES 0x8A43 +#define GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER 0x8A44 +#define GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER 0x8A46 +#define GL_INVALID_INDEX 0xFFFFFFFFu +#define GL_MAX_VERTEX_OUTPUT_COMPONENTS 0x9122 +#define GL_MAX_FRAGMENT_INPUT_COMPONENTS 0x9125 +#define GL_MAX_SERVER_WAIT_TIMEOUT 0x9111 +#define GL_OBJECT_TYPE 0x9112 +#define GL_SYNC_CONDITION 0x9113 +#define GL_SYNC_STATUS 0x9114 +#define GL_SYNC_FLAGS 0x9115 +#define GL_SYNC_FENCE 0x9116 +#define GL_SYNC_GPU_COMMANDS_COMPLETE 0x9117 +#define GL_UNSIGNALED 0x9118 +#define GL_SIGNALED 0x9119 +#define GL_ALREADY_SIGNALED 0x911A +#define GL_TIMEOUT_EXPIRED 0x911B +#define GL_CONDITION_SATISFIED 0x911C +#define GL_WAIT_FAILED 0x911D +#define GL_SYNC_FLUSH_COMMANDS_BIT 0x00000001 +#define GL_TIMEOUT_IGNORED 0xFFFFFFFFFFFFFFFFull +#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR 0x88FE +#define GL_ANY_SAMPLES_PASSED 0x8C2F +#define GL_ANY_SAMPLES_PASSED_CONSERVATIVE 0x8D6A +#define GL_SAMPLER_BINDING 0x8919 +#define GL_RGB10_A2UI 0x906F +#define GL_TEXTURE_SWIZZLE_R 0x8E42 +#define GL_TEXTURE_SWIZZLE_G 0x8E43 +#define GL_TEXTURE_SWIZZLE_B 0x8E44 +#define GL_TEXTURE_SWIZZLE_A 0x8E45 +#define GL_GREEN 0x1904 +#define GL_BLUE 0x1905 +#define GL_INT_2_10_10_10_REV 0x8D9F +#define GL_TRANSFORM_FEEDBACK 0x8E22 +#define GL_TRANSFORM_FEEDBACK_PAUSED 0x8E23 +#define GL_TRANSFORM_FEEDBACK_ACTIVE 0x8E24 +#define GL_TRANSFORM_FEEDBACK_BINDING 0x8E25 +#define GL_PROGRAM_BINARY_RETRIEVABLE_HINT 0x8257 +#define GL_PROGRAM_BINARY_LENGTH 0x8741 +#define GL_NUM_PROGRAM_BINARY_FORMATS 0x87FE +#define GL_PROGRAM_BINARY_FORMATS 0x87FF +#define GL_COMPRESSED_R11_EAC 0x9270 +#define GL_COMPRESSED_SIGNED_R11_EAC 0x9271 +#define GL_COMPRESSED_RG11_EAC 0x9272 +#define GL_COMPRESSED_SIGNED_RG11_EAC 0x9273 +#define GL_COMPRESSED_RGB8_ETC2 0x9274 +#define GL_COMPRESSED_SRGB8_ETC2 0x9275 +#define GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9276 +#define GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9277 +#define GL_COMPRESSED_RGBA8_ETC2_EAC 0x9278 +#define GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC 0x9279 +#define GL_TEXTURE_IMMUTABLE_FORMAT 0x912F +#define GL_MAX_ELEMENT_INDEX 0x8D6B +#define GL_NUM_SAMPLE_COUNTS 0x9380 +#define GL_TEXTURE_IMMUTABLE_LEVELS 0x82DF +typedef void (GL_APIENTRYP PFNGLREADBUFFERPROC) (GLenum src); +typedef void (GL_APIENTRYP PFNGLDRAWRANGEELEMENTSPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices); +typedef void (GL_APIENTRYP PFNGLTEXIMAGE3DPROC) (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *pixels); +typedef void (GL_APIENTRYP PFNGLTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels); +typedef void (GL_APIENTRYP PFNGLCOPYTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (GL_APIENTRYP PFNGLCOMPRESSEDTEXIMAGE3DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *data); +typedef void (GL_APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *data); +typedef void (GL_APIENTRYP PFNGLGENQUERIESPROC) (GLsizei n, GLuint *ids); +typedef void (GL_APIENTRYP PFNGLDELETEQUERIESPROC) (GLsizei n, const GLuint *ids); +typedef GLboolean (GL_APIENTRYP PFNGLISQUERYPROC) (GLuint id); +typedef void (GL_APIENTRYP PFNGLBEGINQUERYPROC) (GLenum target, GLuint id); +typedef void (GL_APIENTRYP PFNGLENDQUERYPROC) (GLenum target); +typedef void (GL_APIENTRYP PFNGLGETQUERYIVPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (GL_APIENTRYP PFNGLGETQUERYOBJECTUIVPROC) (GLuint id, GLenum pname, GLuint *params); +typedef GLboolean (GL_APIENTRYP PFNGLUNMAPBUFFERPROC) (GLenum target); +typedef void (GL_APIENTRYP PFNGLGETBUFFERPOINTERVPROC) (GLenum target, GLenum pname, void **params); +typedef void (GL_APIENTRYP PFNGLDRAWBUFFERSPROC) (GLsizei n, const GLenum *bufs); +typedef void (GL_APIENTRYP PFNGLUNIFORMMATRIX2X3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLUNIFORMMATRIX3X2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLUNIFORMMATRIX2X4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLUNIFORMMATRIX4X2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLUNIFORMMATRIX3X4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLUNIFORMMATRIX4X3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLBLITFRAMEBUFFERPROC) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); +typedef void (GL_APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERTEXTURELAYERPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); +typedef void *(GL_APIENTRYP PFNGLMAPBUFFERRANGEPROC) (GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access); +typedef void (GL_APIENTRYP PFNGLFLUSHMAPPEDBUFFERRANGEPROC) (GLenum target, GLintptr offset, GLsizeiptr length); +typedef void (GL_APIENTRYP PFNGLBINDVERTEXARRAYPROC) (GLuint array); +typedef void (GL_APIENTRYP PFNGLDELETEVERTEXARRAYSPROC) (GLsizei n, const GLuint *arrays); +typedef void (GL_APIENTRYP PFNGLGENVERTEXARRAYSPROC) (GLsizei n, GLuint *arrays); +typedef GLboolean (GL_APIENTRYP PFNGLISVERTEXARRAYPROC) (GLuint array); +typedef void (GL_APIENTRYP PFNGLGETINTEGERI_VPROC) (GLenum target, GLuint index, GLint *data); +typedef void (GL_APIENTRYP PFNGLBEGINTRANSFORMFEEDBACKPROC) (GLenum primitiveMode); +typedef void (GL_APIENTRYP PFNGLENDTRANSFORMFEEDBACKPROC) (void); +typedef void (GL_APIENTRYP PFNGLBINDBUFFERRANGEPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); +typedef void (GL_APIENTRYP PFNGLBINDBUFFERBASEPROC) (GLenum target, GLuint index, GLuint buffer); +typedef void (GL_APIENTRYP PFNGLTRANSFORMFEEDBACKVARYINGSPROC) (GLuint program, GLsizei count, const GLchar *const*varyings, GLenum bufferMode); +typedef void (GL_APIENTRYP PFNGLGETTRANSFORMFEEDBACKVARYINGPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name); +typedef void (GL_APIENTRYP PFNGLVERTEXATTRIBIPOINTERPROC) (GLuint index, GLint size, GLenum type, GLsizei stride, const void *pointer); +typedef void (GL_APIENTRYP PFNGLGETVERTEXATTRIBIIVPROC) (GLuint index, GLenum pname, GLint *params); +typedef void (GL_APIENTRYP PFNGLGETVERTEXATTRIBIUIVPROC) (GLuint index, GLenum pname, GLuint *params); +typedef void (GL_APIENTRYP PFNGLVERTEXATTRIBI4IPROC) (GLuint index, GLint x, GLint y, GLint z, GLint w); +typedef void (GL_APIENTRYP PFNGLVERTEXATTRIBI4UIPROC) (GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); +typedef void (GL_APIENTRYP PFNGLVERTEXATTRIBI4IVPROC) (GLuint index, const GLint *v); +typedef void (GL_APIENTRYP PFNGLVERTEXATTRIBI4UIVPROC) (GLuint index, const GLuint *v); +typedef void (GL_APIENTRYP PFNGLGETUNIFORMUIVPROC) (GLuint program, GLint location, GLuint *params); +typedef GLint (GL_APIENTRYP PFNGLGETFRAGDATALOCATIONPROC) (GLuint program, const GLchar *name); +typedef void (GL_APIENTRYP PFNGLUNIFORM1UIPROC) (GLint location, GLuint v0); +typedef void (GL_APIENTRYP PFNGLUNIFORM2UIPROC) (GLint location, GLuint v0, GLuint v1); +typedef void (GL_APIENTRYP PFNGLUNIFORM3UIPROC) (GLint location, GLuint v0, GLuint v1, GLuint v2); +typedef void (GL_APIENTRYP PFNGLUNIFORM4UIPROC) (GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); +typedef void (GL_APIENTRYP PFNGLUNIFORM1UIVPROC) (GLint location, GLsizei count, const GLuint *value); +typedef void (GL_APIENTRYP PFNGLUNIFORM2UIVPROC) (GLint location, GLsizei count, const GLuint *value); +typedef void (GL_APIENTRYP PFNGLUNIFORM3UIVPROC) (GLint location, GLsizei count, const GLuint *value); +typedef void (GL_APIENTRYP PFNGLUNIFORM4UIVPROC) (GLint location, GLsizei count, const GLuint *value); +typedef void (GL_APIENTRYP PFNGLCLEARBUFFERIVPROC) (GLenum buffer, GLint drawbuffer, const GLint *value); +typedef void (GL_APIENTRYP PFNGLCLEARBUFFERUIVPROC) (GLenum buffer, GLint drawbuffer, const GLuint *value); +typedef void (GL_APIENTRYP PFNGLCLEARBUFFERFVPROC) (GLenum buffer, GLint drawbuffer, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLCLEARBUFFERFIPROC) (GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil); +typedef const GLubyte *(GL_APIENTRYP PFNGLGETSTRINGIPROC) (GLenum name, GLuint index); +typedef void (GL_APIENTRYP PFNGLCOPYBUFFERSUBDATAPROC) (GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); +typedef void (GL_APIENTRYP PFNGLGETUNIFORMINDICESPROC) (GLuint program, GLsizei uniformCount, const GLchar *const*uniformNames, GLuint *uniformIndices); +typedef void (GL_APIENTRYP PFNGLGETACTIVEUNIFORMSIVPROC) (GLuint program, GLsizei uniformCount, const GLuint *uniformIndices, GLenum pname, GLint *params); +typedef GLuint (GL_APIENTRYP PFNGLGETUNIFORMBLOCKINDEXPROC) (GLuint program, const GLchar *uniformBlockName); +typedef void (GL_APIENTRYP PFNGLGETACTIVEUNIFORMBLOCKIVPROC) (GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint *params); +typedef void (GL_APIENTRYP PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC) (GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformBlockName); +typedef void (GL_APIENTRYP PFNGLUNIFORMBLOCKBINDINGPROC) (GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding); +typedef void (GL_APIENTRYP PFNGLDRAWARRAYSINSTANCEDPROC) (GLenum mode, GLint first, GLsizei count, GLsizei instancecount); +typedef void (GL_APIENTRYP PFNGLDRAWELEMENTSINSTANCEDPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount); +typedef GLsync (GL_APIENTRYP PFNGLFENCESYNCPROC) (GLenum condition, GLbitfield flags); +typedef GLboolean (GL_APIENTRYP PFNGLISSYNCPROC) (GLsync sync); +typedef void (GL_APIENTRYP PFNGLDELETESYNCPROC) (GLsync sync); +typedef GLenum (GL_APIENTRYP PFNGLCLIENTWAITSYNCPROC) (GLsync sync, GLbitfield flags, GLuint64 timeout); +typedef void (GL_APIENTRYP PFNGLWAITSYNCPROC) (GLsync sync, GLbitfield flags, GLuint64 timeout); +typedef void (GL_APIENTRYP PFNGLGETINTEGER64VPROC) (GLenum pname, GLint64 *data); +typedef void (GL_APIENTRYP PFNGLGETSYNCIVPROC) (GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values); +typedef void (GL_APIENTRYP PFNGLGETINTEGER64I_VPROC) (GLenum target, GLuint index, GLint64 *data); +typedef void (GL_APIENTRYP PFNGLGETBUFFERPARAMETERI64VPROC) (GLenum target, GLenum pname, GLint64 *params); +typedef void (GL_APIENTRYP PFNGLGENSAMPLERSPROC) (GLsizei count, GLuint *samplers); +typedef void (GL_APIENTRYP PFNGLDELETESAMPLERSPROC) (GLsizei count, const GLuint *samplers); +typedef GLboolean (GL_APIENTRYP PFNGLISSAMPLERPROC) (GLuint sampler); +typedef void (GL_APIENTRYP PFNGLBINDSAMPLERPROC) (GLuint unit, GLuint sampler); +typedef void (GL_APIENTRYP PFNGLSAMPLERPARAMETERIPROC) (GLuint sampler, GLenum pname, GLint param); +typedef void (GL_APIENTRYP PFNGLSAMPLERPARAMETERIVPROC) (GLuint sampler, GLenum pname, const GLint *param); +typedef void (GL_APIENTRYP PFNGLSAMPLERPARAMETERFPROC) (GLuint sampler, GLenum pname, GLfloat param); +typedef void (GL_APIENTRYP PFNGLSAMPLERPARAMETERFVPROC) (GLuint sampler, GLenum pname, const GLfloat *param); +typedef void (GL_APIENTRYP PFNGLGETSAMPLERPARAMETERIVPROC) (GLuint sampler, GLenum pname, GLint *params); +typedef void (GL_APIENTRYP PFNGLGETSAMPLERPARAMETERFVPROC) (GLuint sampler, GLenum pname, GLfloat *params); +typedef void (GL_APIENTRYP PFNGLVERTEXATTRIBDIVISORPROC) (GLuint index, GLuint divisor); +typedef void (GL_APIENTRYP PFNGLBINDTRANSFORMFEEDBACKPROC) (GLenum target, GLuint id); +typedef void (GL_APIENTRYP PFNGLDELETETRANSFORMFEEDBACKSPROC) (GLsizei n, const GLuint *ids); +typedef void (GL_APIENTRYP PFNGLGENTRANSFORMFEEDBACKSPROC) (GLsizei n, GLuint *ids); +typedef GLboolean (GL_APIENTRYP PFNGLISTRANSFORMFEEDBACKPROC) (GLuint id); +typedef void (GL_APIENTRYP PFNGLPAUSETRANSFORMFEEDBACKPROC) (void); +typedef void (GL_APIENTRYP PFNGLRESUMETRANSFORMFEEDBACKPROC) (void); +typedef void (GL_APIENTRYP PFNGLGETPROGRAMBINARYPROC) (GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, void *binary); +typedef void (GL_APIENTRYP PFNGLPROGRAMBINARYPROC) (GLuint program, GLenum binaryFormat, const void *binary, GLsizei length); +typedef void (GL_APIENTRYP PFNGLPROGRAMPARAMETERIPROC) (GLuint program, GLenum pname, GLint value); +typedef void (GL_APIENTRYP PFNGLINVALIDATEFRAMEBUFFERPROC) (GLenum target, GLsizei numAttachments, const GLenum *attachments); +typedef void (GL_APIENTRYP PFNGLINVALIDATESUBFRAMEBUFFERPROC) (GLenum target, GLsizei numAttachments, const GLenum *attachments, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (GL_APIENTRYP PFNGLTEXSTORAGE2DPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (GL_APIENTRYP PFNGLTEXSTORAGE3DPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); +typedef void (GL_APIENTRYP PFNGLGETINTERNALFORMATIVPROC) (GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint *params); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glReadBuffer (GLenum src); +GL_APICALL void GL_APIENTRY glDrawRangeElements (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices); +GL_APICALL void GL_APIENTRY glTexImage3D (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *pixels); +GL_APICALL void GL_APIENTRY glTexSubImage3D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels); +GL_APICALL void GL_APIENTRY glCopyTexSubImage3D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); +GL_APICALL void GL_APIENTRY glCompressedTexImage3D (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *data); +GL_APICALL void GL_APIENTRY glCompressedTexSubImage3D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *data); +GL_APICALL void GL_APIENTRY glGenQueries (GLsizei n, GLuint *ids); +GL_APICALL void GL_APIENTRY glDeleteQueries (GLsizei n, const GLuint *ids); +GL_APICALL GLboolean GL_APIENTRY glIsQuery (GLuint id); +GL_APICALL void GL_APIENTRY glBeginQuery (GLenum target, GLuint id); +GL_APICALL void GL_APIENTRY glEndQuery (GLenum target); +GL_APICALL void GL_APIENTRY glGetQueryiv (GLenum target, GLenum pname, GLint *params); +GL_APICALL void GL_APIENTRY glGetQueryObjectuiv (GLuint id, GLenum pname, GLuint *params); +GL_APICALL GLboolean GL_APIENTRY glUnmapBuffer (GLenum target); +GL_APICALL void GL_APIENTRY glGetBufferPointerv (GLenum target, GLenum pname, void **params); +GL_APICALL void GL_APIENTRY glDrawBuffers (GLsizei n, const GLenum *bufs); +GL_APICALL void GL_APIENTRY glUniformMatrix2x3fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GL_APICALL void GL_APIENTRY glUniformMatrix3x2fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GL_APICALL void GL_APIENTRY glUniformMatrix2x4fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GL_APICALL void GL_APIENTRY glUniformMatrix4x2fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GL_APICALL void GL_APIENTRY glUniformMatrix3x4fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GL_APICALL void GL_APIENTRY glUniformMatrix4x3fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GL_APICALL void GL_APIENTRY glBlitFramebuffer (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); +GL_APICALL void GL_APIENTRY glRenderbufferStorageMultisample (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +GL_APICALL void GL_APIENTRY glFramebufferTextureLayer (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); +GL_APICALL void *GL_APIENTRY glMapBufferRange (GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access); +GL_APICALL void GL_APIENTRY glFlushMappedBufferRange (GLenum target, GLintptr offset, GLsizeiptr length); +GL_APICALL void GL_APIENTRY glBindVertexArray (GLuint array); +GL_APICALL void GL_APIENTRY glDeleteVertexArrays (GLsizei n, const GLuint *arrays); +GL_APICALL void GL_APIENTRY glGenVertexArrays (GLsizei n, GLuint *arrays); +GL_APICALL GLboolean GL_APIENTRY glIsVertexArray (GLuint array); +GL_APICALL void GL_APIENTRY glGetIntegeri_v (GLenum target, GLuint index, GLint *data); +GL_APICALL void GL_APIENTRY glBeginTransformFeedback (GLenum primitiveMode); +GL_APICALL void GL_APIENTRY glEndTransformFeedback (void); +GL_APICALL void GL_APIENTRY glBindBufferRange (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); +GL_APICALL void GL_APIENTRY glBindBufferBase (GLenum target, GLuint index, GLuint buffer); +GL_APICALL void GL_APIENTRY glTransformFeedbackVaryings (GLuint program, GLsizei count, const GLchar *const*varyings, GLenum bufferMode); +GL_APICALL void GL_APIENTRY glGetTransformFeedbackVarying (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name); +GL_APICALL void GL_APIENTRY glVertexAttribIPointer (GLuint index, GLint size, GLenum type, GLsizei stride, const void *pointer); +GL_APICALL void GL_APIENTRY glGetVertexAttribIiv (GLuint index, GLenum pname, GLint *params); +GL_APICALL void GL_APIENTRY glGetVertexAttribIuiv (GLuint index, GLenum pname, GLuint *params); +GL_APICALL void GL_APIENTRY glVertexAttribI4i (GLuint index, GLint x, GLint y, GLint z, GLint w); +GL_APICALL void GL_APIENTRY glVertexAttribI4ui (GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); +GL_APICALL void GL_APIENTRY glVertexAttribI4iv (GLuint index, const GLint *v); +GL_APICALL void GL_APIENTRY glVertexAttribI4uiv (GLuint index, const GLuint *v); +GL_APICALL void GL_APIENTRY glGetUniformuiv (GLuint program, GLint location, GLuint *params); +GL_APICALL GLint GL_APIENTRY glGetFragDataLocation (GLuint program, const GLchar *name); +GL_APICALL void GL_APIENTRY glUniform1ui (GLint location, GLuint v0); +GL_APICALL void GL_APIENTRY glUniform2ui (GLint location, GLuint v0, GLuint v1); +GL_APICALL void GL_APIENTRY glUniform3ui (GLint location, GLuint v0, GLuint v1, GLuint v2); +GL_APICALL void GL_APIENTRY glUniform4ui (GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); +GL_APICALL void GL_APIENTRY glUniform1uiv (GLint location, GLsizei count, const GLuint *value); +GL_APICALL void GL_APIENTRY glUniform2uiv (GLint location, GLsizei count, const GLuint *value); +GL_APICALL void GL_APIENTRY glUniform3uiv (GLint location, GLsizei count, const GLuint *value); +GL_APICALL void GL_APIENTRY glUniform4uiv (GLint location, GLsizei count, const GLuint *value); +GL_APICALL void GL_APIENTRY glClearBufferiv (GLenum buffer, GLint drawbuffer, const GLint *value); +GL_APICALL void GL_APIENTRY glClearBufferuiv (GLenum buffer, GLint drawbuffer, const GLuint *value); +GL_APICALL void GL_APIENTRY glClearBufferfv (GLenum buffer, GLint drawbuffer, const GLfloat *value); +GL_APICALL void GL_APIENTRY glClearBufferfi (GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil); +GL_APICALL const GLubyte *GL_APIENTRY glGetStringi (GLenum name, GLuint index); +GL_APICALL void GL_APIENTRY glCopyBufferSubData (GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); +GL_APICALL void GL_APIENTRY glGetUniformIndices (GLuint program, GLsizei uniformCount, const GLchar *const*uniformNames, GLuint *uniformIndices); +GL_APICALL void GL_APIENTRY glGetActiveUniformsiv (GLuint program, GLsizei uniformCount, const GLuint *uniformIndices, GLenum pname, GLint *params); +GL_APICALL GLuint GL_APIENTRY glGetUniformBlockIndex (GLuint program, const GLchar *uniformBlockName); +GL_APICALL void GL_APIENTRY glGetActiveUniformBlockiv (GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint *params); +GL_APICALL void GL_APIENTRY glGetActiveUniformBlockName (GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformBlockName); +GL_APICALL void GL_APIENTRY glUniformBlockBinding (GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding); +GL_APICALL void GL_APIENTRY glDrawArraysInstanced (GLenum mode, GLint first, GLsizei count, GLsizei instancecount); +GL_APICALL void GL_APIENTRY glDrawElementsInstanced (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount); +GL_APICALL GLsync GL_APIENTRY glFenceSync (GLenum condition, GLbitfield flags); +GL_APICALL GLboolean GL_APIENTRY glIsSync (GLsync sync); +GL_APICALL void GL_APIENTRY glDeleteSync (GLsync sync); +GL_APICALL GLenum GL_APIENTRY glClientWaitSync (GLsync sync, GLbitfield flags, GLuint64 timeout); +GL_APICALL void GL_APIENTRY glWaitSync (GLsync sync, GLbitfield flags, GLuint64 timeout); +GL_APICALL void GL_APIENTRY glGetInteger64v (GLenum pname, GLint64 *data); +GL_APICALL void GL_APIENTRY glGetSynciv (GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values); +GL_APICALL void GL_APIENTRY glGetInteger64i_v (GLenum target, GLuint index, GLint64 *data); +GL_APICALL void GL_APIENTRY glGetBufferParameteri64v (GLenum target, GLenum pname, GLint64 *params); +GL_APICALL void GL_APIENTRY glGenSamplers (GLsizei count, GLuint *samplers); +GL_APICALL void GL_APIENTRY glDeleteSamplers (GLsizei count, const GLuint *samplers); +GL_APICALL GLboolean GL_APIENTRY glIsSampler (GLuint sampler); +GL_APICALL void GL_APIENTRY glBindSampler (GLuint unit, GLuint sampler); +GL_APICALL void GL_APIENTRY glSamplerParameteri (GLuint sampler, GLenum pname, GLint param); +GL_APICALL void GL_APIENTRY glSamplerParameteriv (GLuint sampler, GLenum pname, const GLint *param); +GL_APICALL void GL_APIENTRY glSamplerParameterf (GLuint sampler, GLenum pname, GLfloat param); +GL_APICALL void GL_APIENTRY glSamplerParameterfv (GLuint sampler, GLenum pname, const GLfloat *param); +GL_APICALL void GL_APIENTRY glGetSamplerParameteriv (GLuint sampler, GLenum pname, GLint *params); +GL_APICALL void GL_APIENTRY glGetSamplerParameterfv (GLuint sampler, GLenum pname, GLfloat *params); +GL_APICALL void GL_APIENTRY glVertexAttribDivisor (GLuint index, GLuint divisor); +GL_APICALL void GL_APIENTRY glBindTransformFeedback (GLenum target, GLuint id); +GL_APICALL void GL_APIENTRY glDeleteTransformFeedbacks (GLsizei n, const GLuint *ids); +GL_APICALL void GL_APIENTRY glGenTransformFeedbacks (GLsizei n, GLuint *ids); +GL_APICALL GLboolean GL_APIENTRY glIsTransformFeedback (GLuint id); +GL_APICALL void GL_APIENTRY glPauseTransformFeedback (void); +GL_APICALL void GL_APIENTRY glResumeTransformFeedback (void); +GL_APICALL void GL_APIENTRY glGetProgramBinary (GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, void *binary); +GL_APICALL void GL_APIENTRY glProgramBinary (GLuint program, GLenum binaryFormat, const void *binary, GLsizei length); +GL_APICALL void GL_APIENTRY glProgramParameteri (GLuint program, GLenum pname, GLint value); +GL_APICALL void GL_APIENTRY glInvalidateFramebuffer (GLenum target, GLsizei numAttachments, const GLenum *attachments); +GL_APICALL void GL_APIENTRY glInvalidateSubFramebuffer (GLenum target, GLsizei numAttachments, const GLenum *attachments, GLint x, GLint y, GLsizei width, GLsizei height); +GL_APICALL void GL_APIENTRY glTexStorage2D (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); +GL_APICALL void GL_APIENTRY glTexStorage3D (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); +GL_APICALL void GL_APIENTRY glGetInternalformativ (GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint *params); +#endif +#endif /* GL_ES_VERSION_3_0 */ + +#ifndef GL_ES_VERSION_3_1 +#define GL_ES_VERSION_3_1 1 +#define GL_COMPUTE_SHADER 0x91B9 +#define GL_MAX_COMPUTE_UNIFORM_BLOCKS 0x91BB +#define GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS 0x91BC +#define GL_MAX_COMPUTE_IMAGE_UNIFORMS 0x91BD +#define GL_MAX_COMPUTE_SHARED_MEMORY_SIZE 0x8262 +#define GL_MAX_COMPUTE_UNIFORM_COMPONENTS 0x8263 +#define GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS 0x8264 +#define GL_MAX_COMPUTE_ATOMIC_COUNTERS 0x8265 +#define GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS 0x8266 +#define GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS 0x90EB +#define GL_MAX_COMPUTE_WORK_GROUP_COUNT 0x91BE +#define GL_MAX_COMPUTE_WORK_GROUP_SIZE 0x91BF +#define GL_COMPUTE_WORK_GROUP_SIZE 0x8267 +#define GL_DISPATCH_INDIRECT_BUFFER 0x90EE +#define GL_DISPATCH_INDIRECT_BUFFER_BINDING 0x90EF +#define GL_COMPUTE_SHADER_BIT 0x00000020 +#define GL_DRAW_INDIRECT_BUFFER 0x8F3F +#define GL_DRAW_INDIRECT_BUFFER_BINDING 0x8F43 +#define GL_MAX_UNIFORM_LOCATIONS 0x826E +#define GL_FRAMEBUFFER_DEFAULT_WIDTH 0x9310 +#define GL_FRAMEBUFFER_DEFAULT_HEIGHT 0x9311 +#define GL_FRAMEBUFFER_DEFAULT_SAMPLES 0x9313 +#define GL_FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS 0x9314 +#define GL_MAX_FRAMEBUFFER_WIDTH 0x9315 +#define GL_MAX_FRAMEBUFFER_HEIGHT 0x9316 +#define GL_MAX_FRAMEBUFFER_SAMPLES 0x9318 +#define GL_UNIFORM 0x92E1 +#define GL_UNIFORM_BLOCK 0x92E2 +#define GL_PROGRAM_INPUT 0x92E3 +#define GL_PROGRAM_OUTPUT 0x92E4 +#define GL_BUFFER_VARIABLE 0x92E5 +#define GL_SHADER_STORAGE_BLOCK 0x92E6 +#define GL_ATOMIC_COUNTER_BUFFER 0x92C0 +#define GL_TRANSFORM_FEEDBACK_VARYING 0x92F4 +#define GL_ACTIVE_RESOURCES 0x92F5 +#define GL_MAX_NAME_LENGTH 0x92F6 +#define GL_MAX_NUM_ACTIVE_VARIABLES 0x92F7 +#define GL_NAME_LENGTH 0x92F9 +#define GL_TYPE 0x92FA +#define GL_ARRAY_SIZE 0x92FB +#define GL_OFFSET 0x92FC +#define GL_BLOCK_INDEX 0x92FD +#define GL_ARRAY_STRIDE 0x92FE +#define GL_MATRIX_STRIDE 0x92FF +#define GL_IS_ROW_MAJOR 0x9300 +#define GL_ATOMIC_COUNTER_BUFFER_INDEX 0x9301 +#define GL_BUFFER_BINDING 0x9302 +#define GL_BUFFER_DATA_SIZE 0x9303 +#define GL_NUM_ACTIVE_VARIABLES 0x9304 +#define GL_ACTIVE_VARIABLES 0x9305 +#define GL_REFERENCED_BY_VERTEX_SHADER 0x9306 +#define GL_REFERENCED_BY_FRAGMENT_SHADER 0x930A +#define GL_REFERENCED_BY_COMPUTE_SHADER 0x930B +#define GL_TOP_LEVEL_ARRAY_SIZE 0x930C +#define GL_TOP_LEVEL_ARRAY_STRIDE 0x930D +#define GL_LOCATION 0x930E +#define GL_VERTEX_SHADER_BIT 0x00000001 +#define GL_FRAGMENT_SHADER_BIT 0x00000002 +#define GL_ALL_SHADER_BITS 0xFFFFFFFF +#define GL_PROGRAM_SEPARABLE 0x8258 +#define GL_ACTIVE_PROGRAM 0x8259 +#define GL_PROGRAM_PIPELINE_BINDING 0x825A +#define GL_ATOMIC_COUNTER_BUFFER_BINDING 0x92C1 +#define GL_ATOMIC_COUNTER_BUFFER_START 0x92C2 +#define GL_ATOMIC_COUNTER_BUFFER_SIZE 0x92C3 +#define GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS 0x92CC +#define GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS 0x92D0 +#define GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS 0x92D1 +#define GL_MAX_VERTEX_ATOMIC_COUNTERS 0x92D2 +#define GL_MAX_FRAGMENT_ATOMIC_COUNTERS 0x92D6 +#define GL_MAX_COMBINED_ATOMIC_COUNTERS 0x92D7 +#define GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE 0x92D8 +#define GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS 0x92DC +#define GL_ACTIVE_ATOMIC_COUNTER_BUFFERS 0x92D9 +#define GL_UNSIGNED_INT_ATOMIC_COUNTER 0x92DB +#define GL_MAX_IMAGE_UNITS 0x8F38 +#define GL_MAX_VERTEX_IMAGE_UNIFORMS 0x90CA +#define GL_MAX_FRAGMENT_IMAGE_UNIFORMS 0x90CE +#define GL_MAX_COMBINED_IMAGE_UNIFORMS 0x90CF +#define GL_IMAGE_BINDING_NAME 0x8F3A +#define GL_IMAGE_BINDING_LEVEL 0x8F3B +#define GL_IMAGE_BINDING_LAYERED 0x8F3C +#define GL_IMAGE_BINDING_LAYER 0x8F3D +#define GL_IMAGE_BINDING_ACCESS 0x8F3E +#define GL_IMAGE_BINDING_FORMAT 0x906E +#define GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT 0x00000001 +#define GL_ELEMENT_ARRAY_BARRIER_BIT 0x00000002 +#define GL_UNIFORM_BARRIER_BIT 0x00000004 +#define GL_TEXTURE_FETCH_BARRIER_BIT 0x00000008 +#define GL_SHADER_IMAGE_ACCESS_BARRIER_BIT 0x00000020 +#define GL_COMMAND_BARRIER_BIT 0x00000040 +#define GL_PIXEL_BUFFER_BARRIER_BIT 0x00000080 +#define GL_TEXTURE_UPDATE_BARRIER_BIT 0x00000100 +#define GL_BUFFER_UPDATE_BARRIER_BIT 0x00000200 +#define GL_FRAMEBUFFER_BARRIER_BIT 0x00000400 +#define GL_TRANSFORM_FEEDBACK_BARRIER_BIT 0x00000800 +#define GL_ATOMIC_COUNTER_BARRIER_BIT 0x00001000 +#define GL_ALL_BARRIER_BITS 0xFFFFFFFF +#define GL_IMAGE_2D 0x904D +#define GL_IMAGE_3D 0x904E +#define GL_IMAGE_CUBE 0x9050 +#define GL_IMAGE_2D_ARRAY 0x9053 +#define GL_INT_IMAGE_2D 0x9058 +#define GL_INT_IMAGE_3D 0x9059 +#define GL_INT_IMAGE_CUBE 0x905B +#define GL_INT_IMAGE_2D_ARRAY 0x905E +#define GL_UNSIGNED_INT_IMAGE_2D 0x9063 +#define GL_UNSIGNED_INT_IMAGE_3D 0x9064 +#define GL_UNSIGNED_INT_IMAGE_CUBE 0x9066 +#define GL_UNSIGNED_INT_IMAGE_2D_ARRAY 0x9069 +#define GL_IMAGE_FORMAT_COMPATIBILITY_TYPE 0x90C7 +#define GL_IMAGE_FORMAT_COMPATIBILITY_BY_SIZE 0x90C8 +#define GL_IMAGE_FORMAT_COMPATIBILITY_BY_CLASS 0x90C9 +#define GL_READ_ONLY 0x88B8 +#define GL_WRITE_ONLY 0x88B9 +#define GL_READ_WRITE 0x88BA +#define GL_SHADER_STORAGE_BUFFER 0x90D2 +#define GL_SHADER_STORAGE_BUFFER_BINDING 0x90D3 +#define GL_SHADER_STORAGE_BUFFER_START 0x90D4 +#define GL_SHADER_STORAGE_BUFFER_SIZE 0x90D5 +#define GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS 0x90D6 +#define GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS 0x90DA +#define GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS 0x90DB +#define GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS 0x90DC +#define GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS 0x90DD +#define GL_MAX_SHADER_STORAGE_BLOCK_SIZE 0x90DE +#define GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT 0x90DF +#define GL_SHADER_STORAGE_BARRIER_BIT 0x00002000 +#define GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES 0x8F39 +#define GL_DEPTH_STENCIL_TEXTURE_MODE 0x90EA +#define GL_STENCIL_INDEX 0x1901 +#define GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET 0x8E5E +#define GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET 0x8E5F +#define GL_SAMPLE_POSITION 0x8E50 +#define GL_SAMPLE_MASK 0x8E51 +#define GL_SAMPLE_MASK_VALUE 0x8E52 +#define GL_TEXTURE_2D_MULTISAMPLE 0x9100 +#define GL_MAX_SAMPLE_MASK_WORDS 0x8E59 +#define GL_MAX_COLOR_TEXTURE_SAMPLES 0x910E +#define GL_MAX_DEPTH_TEXTURE_SAMPLES 0x910F +#define GL_MAX_INTEGER_SAMPLES 0x9110 +#define GL_TEXTURE_BINDING_2D_MULTISAMPLE 0x9104 +#define GL_TEXTURE_SAMPLES 0x9106 +#define GL_TEXTURE_FIXED_SAMPLE_LOCATIONS 0x9107 +#define GL_TEXTURE_WIDTH 0x1000 +#define GL_TEXTURE_HEIGHT 0x1001 +#define GL_TEXTURE_DEPTH 0x8071 +#define GL_TEXTURE_INTERNAL_FORMAT 0x1003 +#define GL_TEXTURE_RED_SIZE 0x805C +#define GL_TEXTURE_GREEN_SIZE 0x805D +#define GL_TEXTURE_BLUE_SIZE 0x805E +#define GL_TEXTURE_ALPHA_SIZE 0x805F +#define GL_TEXTURE_DEPTH_SIZE 0x884A +#define GL_TEXTURE_STENCIL_SIZE 0x88F1 +#define GL_TEXTURE_SHARED_SIZE 0x8C3F +#define GL_TEXTURE_RED_TYPE 0x8C10 +#define GL_TEXTURE_GREEN_TYPE 0x8C11 +#define GL_TEXTURE_BLUE_TYPE 0x8C12 +#define GL_TEXTURE_ALPHA_TYPE 0x8C13 +#define GL_TEXTURE_DEPTH_TYPE 0x8C16 +#define GL_TEXTURE_COMPRESSED 0x86A1 +#define GL_SAMPLER_2D_MULTISAMPLE 0x9108 +#define GL_INT_SAMPLER_2D_MULTISAMPLE 0x9109 +#define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE 0x910A +#define GL_VERTEX_ATTRIB_BINDING 0x82D4 +#define GL_VERTEX_ATTRIB_RELATIVE_OFFSET 0x82D5 +#define GL_VERTEX_BINDING_DIVISOR 0x82D6 +#define GL_VERTEX_BINDING_OFFSET 0x82D7 +#define GL_VERTEX_BINDING_STRIDE 0x82D8 +#define GL_VERTEX_BINDING_BUFFER 0x8F4F +#define GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET 0x82D9 +#define GL_MAX_VERTEX_ATTRIB_BINDINGS 0x82DA +#define GL_MAX_VERTEX_ATTRIB_STRIDE 0x82E5 +typedef void (GL_APIENTRYP PFNGLDISPATCHCOMPUTEPROC) (GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z); +typedef void (GL_APIENTRYP PFNGLDISPATCHCOMPUTEINDIRECTPROC) (GLintptr indirect); +typedef void (GL_APIENTRYP PFNGLDRAWARRAYSINDIRECTPROC) (GLenum mode, const void *indirect); +typedef void (GL_APIENTRYP PFNGLDRAWELEMENTSINDIRECTPROC) (GLenum mode, GLenum type, const void *indirect); +typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERPARAMETERIPROC) (GLenum target, GLenum pname, GLint param); +typedef void (GL_APIENTRYP PFNGLGETFRAMEBUFFERPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (GL_APIENTRYP PFNGLGETPROGRAMINTERFACEIVPROC) (GLuint program, GLenum programInterface, GLenum pname, GLint *params); +typedef GLuint (GL_APIENTRYP PFNGLGETPROGRAMRESOURCEINDEXPROC) (GLuint program, GLenum programInterface, const GLchar *name); +typedef void (GL_APIENTRYP PFNGLGETPROGRAMRESOURCENAMEPROC) (GLuint program, GLenum programInterface, GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name); +typedef void (GL_APIENTRYP PFNGLGETPROGRAMRESOURCEIVPROC) (GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum *props, GLsizei bufSize, GLsizei *length, GLint *params); +typedef GLint (GL_APIENTRYP PFNGLGETPROGRAMRESOURCELOCATIONPROC) (GLuint program, GLenum programInterface, const GLchar *name); +typedef void (GL_APIENTRYP PFNGLUSEPROGRAMSTAGESPROC) (GLuint pipeline, GLbitfield stages, GLuint program); +typedef void (GL_APIENTRYP PFNGLACTIVESHADERPROGRAMPROC) (GLuint pipeline, GLuint program); +typedef GLuint (GL_APIENTRYP PFNGLCREATESHADERPROGRAMVPROC) (GLenum type, GLsizei count, const GLchar *const*strings); +typedef void (GL_APIENTRYP PFNGLBINDPROGRAMPIPELINEPROC) (GLuint pipeline); +typedef void (GL_APIENTRYP PFNGLDELETEPROGRAMPIPELINESPROC) (GLsizei n, const GLuint *pipelines); +typedef void (GL_APIENTRYP PFNGLGENPROGRAMPIPELINESPROC) (GLsizei n, GLuint *pipelines); +typedef GLboolean (GL_APIENTRYP PFNGLISPROGRAMPIPELINEPROC) (GLuint pipeline); +typedef void (GL_APIENTRYP PFNGLGETPROGRAMPIPELINEIVPROC) (GLuint pipeline, GLenum pname, GLint *params); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM1IPROC) (GLuint program, GLint location, GLint v0); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM2IPROC) (GLuint program, GLint location, GLint v0, GLint v1); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM3IPROC) (GLuint program, GLint location, GLint v0, GLint v1, GLint v2); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM4IPROC) (GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM1UIPROC) (GLuint program, GLint location, GLuint v0); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM2UIPROC) (GLuint program, GLint location, GLuint v0, GLuint v1); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM3UIPROC) (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM4UIPROC) (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM1FPROC) (GLuint program, GLint location, GLfloat v0); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM2FPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM3FPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM4FPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM1IVPROC) (GLuint program, GLint location, GLsizei count, const GLint *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM2IVPROC) (GLuint program, GLint location, GLsizei count, const GLint *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM3IVPROC) (GLuint program, GLint location, GLsizei count, const GLint *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM4IVPROC) (GLuint program, GLint location, GLsizei count, const GLint *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM1UIVPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM2UIVPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM3UIVPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM4UIVPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM1FVPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM2FVPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM3FVPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM4FVPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2X3FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3X2FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2X4FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4X2FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3X4FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4X3FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLVALIDATEPROGRAMPIPELINEPROC) (GLuint pipeline); +typedef void (GL_APIENTRYP PFNGLGETPROGRAMPIPELINEINFOLOGPROC) (GLuint pipeline, GLsizei bufSize, GLsizei *length, GLchar *infoLog); +typedef void (GL_APIENTRYP PFNGLBINDIMAGETEXTUREPROC) (GLuint unit, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLenum format); +typedef void (GL_APIENTRYP PFNGLGETBOOLEANI_VPROC) (GLenum target, GLuint index, GLboolean *data); +typedef void (GL_APIENTRYP PFNGLMEMORYBARRIERPROC) (GLbitfield barriers); +typedef void (GL_APIENTRYP PFNGLMEMORYBARRIERBYREGIONPROC) (GLbitfield barriers); +typedef void (GL_APIENTRYP PFNGLTEXSTORAGE2DMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations); +typedef void (GL_APIENTRYP PFNGLGETMULTISAMPLEFVPROC) (GLenum pname, GLuint index, GLfloat *val); +typedef void (GL_APIENTRYP PFNGLSAMPLEMASKIPROC) (GLuint maskNumber, GLbitfield mask); +typedef void (GL_APIENTRYP PFNGLGETTEXLEVELPARAMETERIVPROC) (GLenum target, GLint level, GLenum pname, GLint *params); +typedef void (GL_APIENTRYP PFNGLGETTEXLEVELPARAMETERFVPROC) (GLenum target, GLint level, GLenum pname, GLfloat *params); +typedef void (GL_APIENTRYP PFNGLBINDVERTEXBUFFERPROC) (GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride); +typedef void (GL_APIENTRYP PFNGLVERTEXATTRIBFORMATPROC) (GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset); +typedef void (GL_APIENTRYP PFNGLVERTEXATTRIBIFORMATPROC) (GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); +typedef void (GL_APIENTRYP PFNGLVERTEXATTRIBBINDINGPROC) (GLuint attribindex, GLuint bindingindex); +typedef void (GL_APIENTRYP PFNGLVERTEXBINDINGDIVISORPROC) (GLuint bindingindex, GLuint divisor); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glDispatchCompute (GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z); +GL_APICALL void GL_APIENTRY glDispatchComputeIndirect (GLintptr indirect); +GL_APICALL void GL_APIENTRY glDrawArraysIndirect (GLenum mode, const void *indirect); +GL_APICALL void GL_APIENTRY glDrawElementsIndirect (GLenum mode, GLenum type, const void *indirect); +GL_APICALL void GL_APIENTRY glFramebufferParameteri (GLenum target, GLenum pname, GLint param); +GL_APICALL void GL_APIENTRY glGetFramebufferParameteriv (GLenum target, GLenum pname, GLint *params); +GL_APICALL void GL_APIENTRY glGetProgramInterfaceiv (GLuint program, GLenum programInterface, GLenum pname, GLint *params); +GL_APICALL GLuint GL_APIENTRY glGetProgramResourceIndex (GLuint program, GLenum programInterface, const GLchar *name); +GL_APICALL void GL_APIENTRY glGetProgramResourceName (GLuint program, GLenum programInterface, GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name); +GL_APICALL void GL_APIENTRY glGetProgramResourceiv (GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum *props, GLsizei bufSize, GLsizei *length, GLint *params); +GL_APICALL GLint GL_APIENTRY glGetProgramResourceLocation (GLuint program, GLenum programInterface, const GLchar *name); +GL_APICALL void GL_APIENTRY glUseProgramStages (GLuint pipeline, GLbitfield stages, GLuint program); +GL_APICALL void GL_APIENTRY glActiveShaderProgram (GLuint pipeline, GLuint program); +GL_APICALL GLuint GL_APIENTRY glCreateShaderProgramv (GLenum type, GLsizei count, const GLchar *const*strings); +GL_APICALL void GL_APIENTRY glBindProgramPipeline (GLuint pipeline); +GL_APICALL void GL_APIENTRY glDeleteProgramPipelines (GLsizei n, const GLuint *pipelines); +GL_APICALL void GL_APIENTRY glGenProgramPipelines (GLsizei n, GLuint *pipelines); +GL_APICALL GLboolean GL_APIENTRY glIsProgramPipeline (GLuint pipeline); +GL_APICALL void GL_APIENTRY glGetProgramPipelineiv (GLuint pipeline, GLenum pname, GLint *params); +GL_APICALL void GL_APIENTRY glProgramUniform1i (GLuint program, GLint location, GLint v0); +GL_APICALL void GL_APIENTRY glProgramUniform2i (GLuint program, GLint location, GLint v0, GLint v1); +GL_APICALL void GL_APIENTRY glProgramUniform3i (GLuint program, GLint location, GLint v0, GLint v1, GLint v2); +GL_APICALL void GL_APIENTRY glProgramUniform4i (GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3); +GL_APICALL void GL_APIENTRY glProgramUniform1ui (GLuint program, GLint location, GLuint v0); +GL_APICALL void GL_APIENTRY glProgramUniform2ui (GLuint program, GLint location, GLuint v0, GLuint v1); +GL_APICALL void GL_APIENTRY glProgramUniform3ui (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2); +GL_APICALL void GL_APIENTRY glProgramUniform4ui (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); +GL_APICALL void GL_APIENTRY glProgramUniform1f (GLuint program, GLint location, GLfloat v0); +GL_APICALL void GL_APIENTRY glProgramUniform2f (GLuint program, GLint location, GLfloat v0, GLfloat v1); +GL_APICALL void GL_APIENTRY glProgramUniform3f (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2); +GL_APICALL void GL_APIENTRY glProgramUniform4f (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); +GL_APICALL void GL_APIENTRY glProgramUniform1iv (GLuint program, GLint location, GLsizei count, const GLint *value); +GL_APICALL void GL_APIENTRY glProgramUniform2iv (GLuint program, GLint location, GLsizei count, const GLint *value); +GL_APICALL void GL_APIENTRY glProgramUniform3iv (GLuint program, GLint location, GLsizei count, const GLint *value); +GL_APICALL void GL_APIENTRY glProgramUniform4iv (GLuint program, GLint location, GLsizei count, const GLint *value); +GL_APICALL void GL_APIENTRY glProgramUniform1uiv (GLuint program, GLint location, GLsizei count, const GLuint *value); +GL_APICALL void GL_APIENTRY glProgramUniform2uiv (GLuint program, GLint location, GLsizei count, const GLuint *value); +GL_APICALL void GL_APIENTRY glProgramUniform3uiv (GLuint program, GLint location, GLsizei count, const GLuint *value); +GL_APICALL void GL_APIENTRY glProgramUniform4uiv (GLuint program, GLint location, GLsizei count, const GLuint *value); +GL_APICALL void GL_APIENTRY glProgramUniform1fv (GLuint program, GLint location, GLsizei count, const GLfloat *value); +GL_APICALL void GL_APIENTRY glProgramUniform2fv (GLuint program, GLint location, GLsizei count, const GLfloat *value); +GL_APICALL void GL_APIENTRY glProgramUniform3fv (GLuint program, GLint location, GLsizei count, const GLfloat *value); +GL_APICALL void GL_APIENTRY glProgramUniform4fv (GLuint program, GLint location, GLsizei count, const GLfloat *value); +GL_APICALL void GL_APIENTRY glProgramUniformMatrix2fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GL_APICALL void GL_APIENTRY glProgramUniformMatrix3fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GL_APICALL void GL_APIENTRY glProgramUniformMatrix4fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GL_APICALL void GL_APIENTRY glProgramUniformMatrix2x3fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GL_APICALL void GL_APIENTRY glProgramUniformMatrix3x2fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GL_APICALL void GL_APIENTRY glProgramUniformMatrix2x4fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GL_APICALL void GL_APIENTRY glProgramUniformMatrix4x2fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GL_APICALL void GL_APIENTRY glProgramUniformMatrix3x4fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GL_APICALL void GL_APIENTRY glProgramUniformMatrix4x3fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GL_APICALL void GL_APIENTRY glValidateProgramPipeline (GLuint pipeline); +GL_APICALL void GL_APIENTRY glGetProgramPipelineInfoLog (GLuint pipeline, GLsizei bufSize, GLsizei *length, GLchar *infoLog); +GL_APICALL void GL_APIENTRY glBindImageTexture (GLuint unit, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLenum format); +GL_APICALL void GL_APIENTRY glGetBooleani_v (GLenum target, GLuint index, GLboolean *data); +GL_APICALL void GL_APIENTRY glMemoryBarrier (GLbitfield barriers); +GL_APICALL void GL_APIENTRY glMemoryBarrierByRegion (GLbitfield barriers); +GL_APICALL void GL_APIENTRY glTexStorage2DMultisample (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations); +GL_APICALL void GL_APIENTRY glGetMultisamplefv (GLenum pname, GLuint index, GLfloat *val); +GL_APICALL void GL_APIENTRY glSampleMaski (GLuint maskNumber, GLbitfield mask); +GL_APICALL void GL_APIENTRY glGetTexLevelParameteriv (GLenum target, GLint level, GLenum pname, GLint *params); +GL_APICALL void GL_APIENTRY glGetTexLevelParameterfv (GLenum target, GLint level, GLenum pname, GLfloat *params); +GL_APICALL void GL_APIENTRY glBindVertexBuffer (GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride); +GL_APICALL void GL_APIENTRY glVertexAttribFormat (GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset); +GL_APICALL void GL_APIENTRY glVertexAttribIFormat (GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); +GL_APICALL void GL_APIENTRY glVertexAttribBinding (GLuint attribindex, GLuint bindingindex); +GL_APICALL void GL_APIENTRY glVertexBindingDivisor (GLuint bindingindex, GLuint divisor); +#endif +#endif /* GL_ES_VERSION_3_1 */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Source/ThirdParty/ANGLE/include/GLES3/gl32.h b/Source/ThirdParty/ANGLE/include/GLES3/gl32.h new file mode 100644 index 000000000000..2975a6f4e744 --- /dev/null +++ b/Source/ThirdParty/ANGLE/include/GLES3/gl32.h @@ -0,0 +1,1825 @@ +#ifndef __gl32_h_ +#define __gl32_h_ 1 + +#ifdef __cplusplus +extern "C" { +#endif + +/* +** Copyright (c) 2013-2015 The Khronos Group Inc. +** +** Permission is hereby granted, free of charge, to any person obtaining a +** copy of this software and/or associated documentation files (the +** "Materials"), to deal in the Materials without restriction, including +** without limitation the rights to use, copy, modify, merge, publish, +** distribute, sublicense, and/or sell copies of the Materials, and to +** permit persons to whom the Materials are furnished to do so, subject to +** the following conditions: +** +** The above copyright notice and this permission notice shall be included +** in all copies or substantial portions of the Materials. +** +** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. +*/ +/* +** This header is generated from the Khronos OpenGL / OpenGL ES XML +** API Registry. The current version of the Registry, generator scripts +** used to make the header, and the header can be found at +** http://www.opengl.org/registry/ +** +** Khronos $Revision$ on $Date$ +*/ + +#include + +#ifndef GL_APIENTRYP +#define GL_APIENTRYP GL_APIENTRY* +#endif + +/* Generated on date 20150809 */ + +/* Generated C header for: + * API: gles2 + * Profile: common + * Versions considered: 2\.[0-9]|3\.[012] + * Versions emitted: .* + * Default extensions included: None + * Additional extensions included: _nomatch_^ + * Extensions removed: _nomatch_^ + */ + +#ifndef GL_ES_VERSION_2_0 +#define GL_ES_VERSION_2_0 1 +#include +typedef khronos_int8_t GLbyte; +typedef khronos_float_t GLclampf; +typedef khronos_int32_t GLfixed; +typedef short GLshort; +typedef unsigned short GLushort; +typedef void GLvoid; +typedef struct __GLsync *GLsync; +typedef khronos_int64_t GLint64; +typedef khronos_uint64_t GLuint64; +typedef unsigned int GLenum; +typedef unsigned int GLuint; +typedef char GLchar; +typedef khronos_float_t GLfloat; +typedef khronos_ssize_t GLsizeiptr; +typedef khronos_intptr_t GLintptr; +typedef unsigned int GLbitfield; +typedef int GLint; +typedef unsigned char GLboolean; +typedef int GLsizei; +typedef khronos_uint8_t GLubyte; +#define GL_DEPTH_BUFFER_BIT 0x00000100 +#define GL_STENCIL_BUFFER_BIT 0x00000400 +#define GL_COLOR_BUFFER_BIT 0x00004000 +#define GL_FALSE 0 +#define GL_TRUE 1 +#define GL_POINTS 0x0000 +#define GL_LINES 0x0001 +#define GL_LINE_LOOP 0x0002 +#define GL_LINE_STRIP 0x0003 +#define GL_TRIANGLES 0x0004 +#define GL_TRIANGLE_STRIP 0x0005 +#define GL_TRIANGLE_FAN 0x0006 +#define GL_ZERO 0 +#define GL_ONE 1 +#define GL_SRC_COLOR 0x0300 +#define GL_ONE_MINUS_SRC_COLOR 0x0301 +#define GL_SRC_ALPHA 0x0302 +#define GL_ONE_MINUS_SRC_ALPHA 0x0303 +#define GL_DST_ALPHA 0x0304 +#define GL_ONE_MINUS_DST_ALPHA 0x0305 +#define GL_DST_COLOR 0x0306 +#define GL_ONE_MINUS_DST_COLOR 0x0307 +#define GL_SRC_ALPHA_SATURATE 0x0308 +#define GL_FUNC_ADD 0x8006 +#define GL_BLEND_EQUATION 0x8009 +#define GL_BLEND_EQUATION_RGB 0x8009 +#define GL_BLEND_EQUATION_ALPHA 0x883D +#define GL_FUNC_SUBTRACT 0x800A +#define GL_FUNC_REVERSE_SUBTRACT 0x800B +#define GL_BLEND_DST_RGB 0x80C8 +#define GL_BLEND_SRC_RGB 0x80C9 +#define GL_BLEND_DST_ALPHA 0x80CA +#define GL_BLEND_SRC_ALPHA 0x80CB +#define GL_CONSTANT_COLOR 0x8001 +#define GL_ONE_MINUS_CONSTANT_COLOR 0x8002 +#define GL_CONSTANT_ALPHA 0x8003 +#define GL_ONE_MINUS_CONSTANT_ALPHA 0x8004 +#define GL_BLEND_COLOR 0x8005 +#define GL_ARRAY_BUFFER 0x8892 +#define GL_ELEMENT_ARRAY_BUFFER 0x8893 +#define GL_ARRAY_BUFFER_BINDING 0x8894 +#define GL_ELEMENT_ARRAY_BUFFER_BINDING 0x8895 +#define GL_STREAM_DRAW 0x88E0 +#define GL_STATIC_DRAW 0x88E4 +#define GL_DYNAMIC_DRAW 0x88E8 +#define GL_BUFFER_SIZE 0x8764 +#define GL_BUFFER_USAGE 0x8765 +#define GL_CURRENT_VERTEX_ATTRIB 0x8626 +#define GL_FRONT 0x0404 +#define GL_BACK 0x0405 +#define GL_FRONT_AND_BACK 0x0408 +#define GL_TEXTURE_2D 0x0DE1 +#define GL_CULL_FACE 0x0B44 +#define GL_BLEND 0x0BE2 +#define GL_DITHER 0x0BD0 +#define GL_STENCIL_TEST 0x0B90 +#define GL_DEPTH_TEST 0x0B71 +#define GL_SCISSOR_TEST 0x0C11 +#define GL_POLYGON_OFFSET_FILL 0x8037 +#define GL_SAMPLE_ALPHA_TO_COVERAGE 0x809E +#define GL_SAMPLE_COVERAGE 0x80A0 +#define GL_NO_ERROR 0 +#define GL_INVALID_ENUM 0x0500 +#define GL_INVALID_VALUE 0x0501 +#define GL_INVALID_OPERATION 0x0502 +#define GL_OUT_OF_MEMORY 0x0505 +#define GL_CW 0x0900 +#define GL_CCW 0x0901 +#define GL_LINE_WIDTH 0x0B21 +#define GL_ALIASED_POINT_SIZE_RANGE 0x846D +#define GL_ALIASED_LINE_WIDTH_RANGE 0x846E +#define GL_CULL_FACE_MODE 0x0B45 +#define GL_FRONT_FACE 0x0B46 +#define GL_DEPTH_RANGE 0x0B70 +#define GL_DEPTH_WRITEMASK 0x0B72 +#define GL_DEPTH_CLEAR_VALUE 0x0B73 +#define GL_DEPTH_FUNC 0x0B74 +#define GL_STENCIL_CLEAR_VALUE 0x0B91 +#define GL_STENCIL_FUNC 0x0B92 +#define GL_STENCIL_FAIL 0x0B94 +#define GL_STENCIL_PASS_DEPTH_FAIL 0x0B95 +#define GL_STENCIL_PASS_DEPTH_PASS 0x0B96 +#define GL_STENCIL_REF 0x0B97 +#define GL_STENCIL_VALUE_MASK 0x0B93 +#define GL_STENCIL_WRITEMASK 0x0B98 +#define GL_STENCIL_BACK_FUNC 0x8800 +#define GL_STENCIL_BACK_FAIL 0x8801 +#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_VIEWPORT 0x0BA2 +#define GL_SCISSOR_BOX 0x0C10 +#define GL_COLOR_CLEAR_VALUE 0x0C22 +#define GL_COLOR_WRITEMASK 0x0C23 +#define GL_UNPACK_ALIGNMENT 0x0CF5 +#define GL_PACK_ALIGNMENT 0x0D05 +#define GL_MAX_TEXTURE_SIZE 0x0D33 +#define GL_MAX_VIEWPORT_DIMS 0x0D3A +#define GL_SUBPIXEL_BITS 0x0D50 +#define GL_RED_BITS 0x0D52 +#define GL_GREEN_BITS 0x0D53 +#define GL_BLUE_BITS 0x0D54 +#define GL_ALPHA_BITS 0x0D55 +#define GL_DEPTH_BITS 0x0D56 +#define GL_STENCIL_BITS 0x0D57 +#define GL_POLYGON_OFFSET_UNITS 0x2A00 +#define GL_POLYGON_OFFSET_FACTOR 0x8038 +#define GL_TEXTURE_BINDING_2D 0x8069 +#define GL_SAMPLE_BUFFERS 0x80A8 +#define GL_SAMPLES 0x80A9 +#define GL_SAMPLE_COVERAGE_VALUE 0x80AA +#define GL_SAMPLE_COVERAGE_INVERT 0x80AB +#define GL_NUM_COMPRESSED_TEXTURE_FORMATS 0x86A2 +#define GL_COMPRESSED_TEXTURE_FORMATS 0x86A3 +#define GL_DONT_CARE 0x1100 +#define GL_FASTEST 0x1101 +#define GL_NICEST 0x1102 +#define GL_GENERATE_MIPMAP_HINT 0x8192 +#define GL_BYTE 0x1400 +#define GL_UNSIGNED_BYTE 0x1401 +#define GL_SHORT 0x1402 +#define GL_UNSIGNED_SHORT 0x1403 +#define GL_INT 0x1404 +#define GL_UNSIGNED_INT 0x1405 +#define GL_FLOAT 0x1406 +#define GL_FIXED 0x140C +#define GL_DEPTH_COMPONENT 0x1902 +#define GL_ALPHA 0x1906 +#define GL_RGB 0x1907 +#define GL_RGBA 0x1908 +#define GL_LUMINANCE 0x1909 +#define GL_LUMINANCE_ALPHA 0x190A +#define GL_UNSIGNED_SHORT_4_4_4_4 0x8033 +#define GL_UNSIGNED_SHORT_5_5_5_1 0x8034 +#define GL_UNSIGNED_SHORT_5_6_5 0x8363 +#define GL_FRAGMENT_SHADER 0x8B30 +#define GL_VERTEX_SHADER 0x8B31 +#define GL_MAX_VERTEX_ATTRIBS 0x8869 +#define GL_MAX_VERTEX_UNIFORM_VECTORS 0x8DFB +#define GL_MAX_VARYING_VECTORS 0x8DFC +#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS 0x8B4D +#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS 0x8B4C +#define GL_MAX_TEXTURE_IMAGE_UNITS 0x8872 +#define GL_MAX_FRAGMENT_UNIFORM_VECTORS 0x8DFD +#define GL_SHADER_TYPE 0x8B4F +#define GL_DELETE_STATUS 0x8B80 +#define GL_LINK_STATUS 0x8B82 +#define GL_VALIDATE_STATUS 0x8B83 +#define GL_ATTACHED_SHADERS 0x8B85 +#define GL_ACTIVE_UNIFORMS 0x8B86 +#define GL_ACTIVE_UNIFORM_MAX_LENGTH 0x8B87 +#define GL_ACTIVE_ATTRIBUTES 0x8B89 +#define GL_ACTIVE_ATTRIBUTE_MAX_LENGTH 0x8B8A +#define GL_SHADING_LANGUAGE_VERSION 0x8B8C +#define GL_CURRENT_PROGRAM 0x8B8D +#define GL_NEVER 0x0200 +#define GL_LESS 0x0201 +#define GL_EQUAL 0x0202 +#define GL_LEQUAL 0x0203 +#define GL_GREATER 0x0204 +#define GL_NOTEQUAL 0x0205 +#define GL_GEQUAL 0x0206 +#define GL_ALWAYS 0x0207 +#define GL_KEEP 0x1E00 +#define GL_REPLACE 0x1E01 +#define GL_INCR 0x1E02 +#define GL_DECR 0x1E03 +#define GL_INVERT 0x150A +#define GL_INCR_WRAP 0x8507 +#define GL_DECR_WRAP 0x8508 +#define GL_VENDOR 0x1F00 +#define GL_RENDERER 0x1F01 +#define GL_VERSION 0x1F02 +#define GL_EXTENSIONS 0x1F03 +#define GL_NEAREST 0x2600 +#define GL_LINEAR 0x2601 +#define GL_NEAREST_MIPMAP_NEAREST 0x2700 +#define GL_LINEAR_MIPMAP_NEAREST 0x2701 +#define GL_NEAREST_MIPMAP_LINEAR 0x2702 +#define GL_LINEAR_MIPMAP_LINEAR 0x2703 +#define GL_TEXTURE_MAG_FILTER 0x2800 +#define GL_TEXTURE_MIN_FILTER 0x2801 +#define GL_TEXTURE_WRAP_S 0x2802 +#define GL_TEXTURE_WRAP_T 0x2803 +#define GL_TEXTURE 0x1702 +#define GL_TEXTURE_CUBE_MAP 0x8513 +#define GL_TEXTURE_BINDING_CUBE_MAP 0x8514 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x8515 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x8516 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x8517 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x8518 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x8519 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x851A +#define GL_MAX_CUBE_MAP_TEXTURE_SIZE 0x851C +#define GL_TEXTURE0 0x84C0 +#define GL_TEXTURE1 0x84C1 +#define GL_TEXTURE2 0x84C2 +#define GL_TEXTURE3 0x84C3 +#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_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_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_TEXTURE30 0x84DE +#define GL_TEXTURE31 0x84DF +#define GL_ACTIVE_TEXTURE 0x84E0 +#define GL_REPEAT 0x2901 +#define GL_CLAMP_TO_EDGE 0x812F +#define GL_MIRRORED_REPEAT 0x8370 +#define GL_FLOAT_VEC2 0x8B50 +#define GL_FLOAT_VEC3 0x8B51 +#define GL_FLOAT_VEC4 0x8B52 +#define GL_INT_VEC2 0x8B53 +#define GL_INT_VEC3 0x8B54 +#define GL_INT_VEC4 0x8B55 +#define GL_BOOL 0x8B56 +#define GL_BOOL_VEC2 0x8B57 +#define GL_BOOL_VEC3 0x8B58 +#define GL_BOOL_VEC4 0x8B59 +#define GL_FLOAT_MAT2 0x8B5A +#define GL_FLOAT_MAT3 0x8B5B +#define GL_FLOAT_MAT4 0x8B5C +#define GL_SAMPLER_2D 0x8B5E +#define GL_SAMPLER_CUBE 0x8B60 +#define GL_VERTEX_ATTRIB_ARRAY_ENABLED 0x8622 +#define GL_VERTEX_ATTRIB_ARRAY_SIZE 0x8623 +#define GL_VERTEX_ATTRIB_ARRAY_STRIDE 0x8624 +#define GL_VERTEX_ATTRIB_ARRAY_TYPE 0x8625 +#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED 0x886A +#define GL_VERTEX_ATTRIB_ARRAY_POINTER 0x8645 +#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING 0x889F +#define GL_IMPLEMENTATION_COLOR_READ_TYPE 0x8B9A +#define GL_IMPLEMENTATION_COLOR_READ_FORMAT 0x8B9B +#define GL_COMPILE_STATUS 0x8B81 +#define GL_INFO_LOG_LENGTH 0x8B84 +#define GL_SHADER_SOURCE_LENGTH 0x8B88 +#define GL_SHADER_COMPILER 0x8DFA +#define GL_SHADER_BINARY_FORMATS 0x8DF8 +#define GL_NUM_SHADER_BINARY_FORMATS 0x8DF9 +#define GL_LOW_FLOAT 0x8DF0 +#define GL_MEDIUM_FLOAT 0x8DF1 +#define GL_HIGH_FLOAT 0x8DF2 +#define GL_LOW_INT 0x8DF3 +#define GL_MEDIUM_INT 0x8DF4 +#define GL_HIGH_INT 0x8DF5 +#define GL_FRAMEBUFFER 0x8D40 +#define GL_RENDERBUFFER 0x8D41 +#define GL_RGBA4 0x8056 +#define GL_RGB5_A1 0x8057 +#define GL_RGB565 0x8D62 +#define GL_DEPTH_COMPONENT16 0x81A5 +#define GL_STENCIL_INDEX8 0x8D48 +#define GL_RENDERBUFFER_WIDTH 0x8D42 +#define GL_RENDERBUFFER_HEIGHT 0x8D43 +#define GL_RENDERBUFFER_INTERNAL_FORMAT 0x8D44 +#define GL_RENDERBUFFER_RED_SIZE 0x8D50 +#define GL_RENDERBUFFER_GREEN_SIZE 0x8D51 +#define GL_RENDERBUFFER_BLUE_SIZE 0x8D52 +#define GL_RENDERBUFFER_ALPHA_SIZE 0x8D53 +#define GL_RENDERBUFFER_DEPTH_SIZE 0x8D54 +#define GL_RENDERBUFFER_STENCIL_SIZE 0x8D55 +#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE 0x8CD0 +#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME 0x8CD1 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL 0x8CD2 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE 0x8CD3 +#define GL_COLOR_ATTACHMENT0 0x8CE0 +#define GL_DEPTH_ATTACHMENT 0x8D00 +#define GL_STENCIL_ATTACHMENT 0x8D20 +#define GL_NONE 0 +#define GL_FRAMEBUFFER_COMPLETE 0x8CD5 +#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT 0x8CD6 +#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT 0x8CD7 +#define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS 0x8CD9 +#define GL_FRAMEBUFFER_UNSUPPORTED 0x8CDD +#define GL_FRAMEBUFFER_BINDING 0x8CA6 +#define GL_RENDERBUFFER_BINDING 0x8CA7 +#define GL_MAX_RENDERBUFFER_SIZE 0x84E8 +#define GL_INVALID_FRAMEBUFFER_OPERATION 0x0506 +typedef void (GL_APIENTRYP PFNGLACTIVETEXTUREPROC) (GLenum texture); +typedef void (GL_APIENTRYP PFNGLATTACHSHADERPROC) (GLuint program, GLuint shader); +typedef void (GL_APIENTRYP PFNGLBINDATTRIBLOCATIONPROC) (GLuint program, GLuint index, const GLchar *name); +typedef void (GL_APIENTRYP PFNGLBINDBUFFERPROC) (GLenum target, GLuint buffer); +typedef void (GL_APIENTRYP PFNGLBINDFRAMEBUFFERPROC) (GLenum target, GLuint framebuffer); +typedef void (GL_APIENTRYP PFNGLBINDRENDERBUFFERPROC) (GLenum target, GLuint renderbuffer); +typedef void (GL_APIENTRYP PFNGLBINDTEXTUREPROC) (GLenum target, GLuint texture); +typedef void (GL_APIENTRYP PFNGLBLENDCOLORPROC) (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); +typedef void (GL_APIENTRYP PFNGLBLENDEQUATIONPROC) (GLenum mode); +typedef void (GL_APIENTRYP PFNGLBLENDEQUATIONSEPARATEPROC) (GLenum modeRGB, GLenum modeAlpha); +typedef void (GL_APIENTRYP PFNGLBLENDFUNCPROC) (GLenum sfactor, GLenum dfactor); +typedef void (GL_APIENTRYP PFNGLBLENDFUNCSEPARATEPROC) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); +typedef void (GL_APIENTRYP PFNGLBUFFERDATAPROC) (GLenum target, GLsizeiptr size, const void *data, GLenum usage); +typedef void (GL_APIENTRYP PFNGLBUFFERSUBDATAPROC) (GLenum target, GLintptr offset, GLsizeiptr size, const void *data); +typedef GLenum (GL_APIENTRYP PFNGLCHECKFRAMEBUFFERSTATUSPROC) (GLenum target); +typedef void (GL_APIENTRYP PFNGLCLEARPROC) (GLbitfield mask); +typedef void (GL_APIENTRYP PFNGLCLEARCOLORPROC) (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); +typedef void (GL_APIENTRYP PFNGLCLEARDEPTHFPROC) (GLfloat d); +typedef void (GL_APIENTRYP PFNGLCLEARSTENCILPROC) (GLint s); +typedef void (GL_APIENTRYP PFNGLCOLORMASKPROC) (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); +typedef void (GL_APIENTRYP PFNGLCOMPILESHADERPROC) (GLuint shader); +typedef void (GL_APIENTRYP PFNGLCOMPRESSEDTEXIMAGE2DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void *data); +typedef void (GL_APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *data); +typedef void (GL_APIENTRYP PFNGLCOPYTEXIMAGE2DPROC) (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); +typedef void (GL_APIENTRYP PFNGLCOPYTEXSUBIMAGE2DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); +typedef GLuint (GL_APIENTRYP PFNGLCREATEPROGRAMPROC) (void); +typedef GLuint (GL_APIENTRYP PFNGLCREATESHADERPROC) (GLenum type); +typedef void (GL_APIENTRYP PFNGLCULLFACEPROC) (GLenum mode); +typedef void (GL_APIENTRYP PFNGLDELETEBUFFERSPROC) (GLsizei n, const GLuint *buffers); +typedef void (GL_APIENTRYP PFNGLDELETEFRAMEBUFFERSPROC) (GLsizei n, const GLuint *framebuffers); +typedef void (GL_APIENTRYP PFNGLDELETEPROGRAMPROC) (GLuint program); +typedef void (GL_APIENTRYP PFNGLDELETERENDERBUFFERSPROC) (GLsizei n, const GLuint *renderbuffers); +typedef void (GL_APIENTRYP PFNGLDELETESHADERPROC) (GLuint shader); +typedef void (GL_APIENTRYP PFNGLDELETETEXTURESPROC) (GLsizei n, const GLuint *textures); +typedef void (GL_APIENTRYP PFNGLDEPTHFUNCPROC) (GLenum func); +typedef void (GL_APIENTRYP PFNGLDEPTHMASKPROC) (GLboolean flag); +typedef void (GL_APIENTRYP PFNGLDEPTHRANGEFPROC) (GLfloat n, GLfloat f); +typedef void (GL_APIENTRYP PFNGLDETACHSHADERPROC) (GLuint program, GLuint shader); +typedef void (GL_APIENTRYP PFNGLDISABLEPROC) (GLenum cap); +typedef void (GL_APIENTRYP PFNGLDISABLEVERTEXATTRIBARRAYPROC) (GLuint index); +typedef void (GL_APIENTRYP PFNGLDRAWARRAYSPROC) (GLenum mode, GLint first, GLsizei count); +typedef void (GL_APIENTRYP PFNGLDRAWELEMENTSPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices); +typedef void (GL_APIENTRYP PFNGLENABLEPROC) (GLenum cap); +typedef void (GL_APIENTRYP PFNGLENABLEVERTEXATTRIBARRAYPROC) (GLuint index); +typedef void (GL_APIENTRYP PFNGLFINISHPROC) (void); +typedef void (GL_APIENTRYP PFNGLFLUSHPROC) (void); +typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERRENDERBUFFERPROC) (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); +typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERTEXTURE2DPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +typedef void (GL_APIENTRYP PFNGLFRONTFACEPROC) (GLenum mode); +typedef void (GL_APIENTRYP PFNGLGENBUFFERSPROC) (GLsizei n, GLuint *buffers); +typedef void (GL_APIENTRYP PFNGLGENERATEMIPMAPPROC) (GLenum target); +typedef void (GL_APIENTRYP PFNGLGENFRAMEBUFFERSPROC) (GLsizei n, GLuint *framebuffers); +typedef void (GL_APIENTRYP PFNGLGENRENDERBUFFERSPROC) (GLsizei n, GLuint *renderbuffers); +typedef void (GL_APIENTRYP PFNGLGENTEXTURESPROC) (GLsizei n, GLuint *textures); +typedef void (GL_APIENTRYP PFNGLGETACTIVEATTRIBPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name); +typedef void (GL_APIENTRYP PFNGLGETACTIVEUNIFORMPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name); +typedef void (GL_APIENTRYP PFNGLGETATTACHEDSHADERSPROC) (GLuint program, GLsizei maxCount, GLsizei *count, GLuint *shaders); +typedef GLint (GL_APIENTRYP PFNGLGETATTRIBLOCATIONPROC) (GLuint program, const GLchar *name); +typedef void (GL_APIENTRYP PFNGLGETBOOLEANVPROC) (GLenum pname, GLboolean *data); +typedef void (GL_APIENTRYP PFNGLGETBUFFERPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); +typedef GLenum (GL_APIENTRYP PFNGLGETERRORPROC) (void); +typedef void (GL_APIENTRYP PFNGLGETFLOATVPROC) (GLenum pname, GLfloat *data); +typedef void (GL_APIENTRYP PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC) (GLenum target, GLenum attachment, GLenum pname, GLint *params); +typedef void (GL_APIENTRYP PFNGLGETINTEGERVPROC) (GLenum pname, GLint *data); +typedef void (GL_APIENTRYP PFNGLGETPROGRAMIVPROC) (GLuint program, GLenum pname, GLint *params); +typedef void (GL_APIENTRYP PFNGLGETPROGRAMINFOLOGPROC) (GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog); +typedef void (GL_APIENTRYP PFNGLGETRENDERBUFFERPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (GL_APIENTRYP PFNGLGETSHADERIVPROC) (GLuint shader, GLenum pname, GLint *params); +typedef void (GL_APIENTRYP PFNGLGETSHADERINFOLOGPROC) (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog); +typedef void (GL_APIENTRYP PFNGLGETSHADERPRECISIONFORMATPROC) (GLenum shadertype, GLenum precisiontype, GLint *range, GLint *precision); +typedef void (GL_APIENTRYP PFNGLGETSHADERSOURCEPROC) (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *source); +typedef const GLubyte *(GL_APIENTRYP PFNGLGETSTRINGPROC) (GLenum name); +typedef void (GL_APIENTRYP PFNGLGETTEXPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params); +typedef void (GL_APIENTRYP PFNGLGETTEXPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (GL_APIENTRYP PFNGLGETUNIFORMFVPROC) (GLuint program, GLint location, GLfloat *params); +typedef void (GL_APIENTRYP PFNGLGETUNIFORMIVPROC) (GLuint program, GLint location, GLint *params); +typedef GLint (GL_APIENTRYP PFNGLGETUNIFORMLOCATIONPROC) (GLuint program, const GLchar *name); +typedef void (GL_APIENTRYP PFNGLGETVERTEXATTRIBFVPROC) (GLuint index, GLenum pname, GLfloat *params); +typedef void (GL_APIENTRYP PFNGLGETVERTEXATTRIBIVPROC) (GLuint index, GLenum pname, GLint *params); +typedef void (GL_APIENTRYP PFNGLGETVERTEXATTRIBPOINTERVPROC) (GLuint index, GLenum pname, void **pointer); +typedef void (GL_APIENTRYP PFNGLHINTPROC) (GLenum target, GLenum mode); +typedef GLboolean (GL_APIENTRYP PFNGLISBUFFERPROC) (GLuint buffer); +typedef GLboolean (GL_APIENTRYP PFNGLISENABLEDPROC) (GLenum cap); +typedef GLboolean (GL_APIENTRYP PFNGLISFRAMEBUFFERPROC) (GLuint framebuffer); +typedef GLboolean (GL_APIENTRYP PFNGLISPROGRAMPROC) (GLuint program); +typedef GLboolean (GL_APIENTRYP PFNGLISRENDERBUFFERPROC) (GLuint renderbuffer); +typedef GLboolean (GL_APIENTRYP PFNGLISSHADERPROC) (GLuint shader); +typedef GLboolean (GL_APIENTRYP PFNGLISTEXTUREPROC) (GLuint texture); +typedef void (GL_APIENTRYP PFNGLLINEWIDTHPROC) (GLfloat width); +typedef void (GL_APIENTRYP PFNGLLINKPROGRAMPROC) (GLuint program); +typedef void (GL_APIENTRYP PFNGLPIXELSTOREIPROC) (GLenum pname, GLint param); +typedef void (GL_APIENTRYP PFNGLPOLYGONOFFSETPROC) (GLfloat factor, GLfloat units); +typedef void (GL_APIENTRYP PFNGLREADPIXELSPROC) (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void *pixels); +typedef void (GL_APIENTRYP PFNGLRELEASESHADERCOMPILERPROC) (void); +typedef void (GL_APIENTRYP PFNGLRENDERBUFFERSTORAGEPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (GL_APIENTRYP PFNGLSAMPLECOVERAGEPROC) (GLfloat value, GLboolean invert); +typedef void (GL_APIENTRYP PFNGLSCISSORPROC) (GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (GL_APIENTRYP PFNGLSHADERBINARYPROC) (GLsizei count, const GLuint *shaders, GLenum binaryformat, const void *binary, GLsizei length); +typedef void (GL_APIENTRYP PFNGLSHADERSOURCEPROC) (GLuint shader, GLsizei count, const GLchar *const*string, const GLint *length); +typedef void (GL_APIENTRYP PFNGLSTENCILFUNCPROC) (GLenum func, GLint ref, GLuint mask); +typedef void (GL_APIENTRYP PFNGLSTENCILFUNCSEPARATEPROC) (GLenum face, GLenum func, GLint ref, GLuint mask); +typedef void (GL_APIENTRYP PFNGLSTENCILMASKPROC) (GLuint mask); +typedef void (GL_APIENTRYP PFNGLSTENCILMASKSEPARATEPROC) (GLenum face, GLuint mask); +typedef void (GL_APIENTRYP PFNGLSTENCILOPPROC) (GLenum fail, GLenum zfail, GLenum zpass); +typedef void (GL_APIENTRYP PFNGLSTENCILOPSEPARATEPROC) (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass); +typedef void (GL_APIENTRYP PFNGLTEXIMAGE2DPROC) (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels); +typedef void (GL_APIENTRYP PFNGLTEXPARAMETERFPROC) (GLenum target, GLenum pname, GLfloat param); +typedef void (GL_APIENTRYP PFNGLTEXPARAMETERFVPROC) (GLenum target, GLenum pname, const GLfloat *params); +typedef void (GL_APIENTRYP PFNGLTEXPARAMETERIPROC) (GLenum target, GLenum pname, GLint param); +typedef void (GL_APIENTRYP PFNGLTEXPARAMETERIVPROC) (GLenum target, GLenum pname, const GLint *params); +typedef void (GL_APIENTRYP PFNGLTEXSUBIMAGE2DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels); +typedef void (GL_APIENTRYP PFNGLUNIFORM1FPROC) (GLint location, GLfloat v0); +typedef void (GL_APIENTRYP PFNGLUNIFORM1FVPROC) (GLint location, GLsizei count, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLUNIFORM1IPROC) (GLint location, GLint v0); +typedef void (GL_APIENTRYP PFNGLUNIFORM1IVPROC) (GLint location, GLsizei count, const GLint *value); +typedef void (GL_APIENTRYP PFNGLUNIFORM2FPROC) (GLint location, GLfloat v0, GLfloat v1); +typedef void (GL_APIENTRYP PFNGLUNIFORM2FVPROC) (GLint location, GLsizei count, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLUNIFORM2IPROC) (GLint location, GLint v0, GLint v1); +typedef void (GL_APIENTRYP PFNGLUNIFORM2IVPROC) (GLint location, GLsizei count, const GLint *value); +typedef void (GL_APIENTRYP PFNGLUNIFORM3FPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2); +typedef void (GL_APIENTRYP PFNGLUNIFORM3FVPROC) (GLint location, GLsizei count, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLUNIFORM3IPROC) (GLint location, GLint v0, GLint v1, GLint v2); +typedef void (GL_APIENTRYP PFNGLUNIFORM3IVPROC) (GLint location, GLsizei count, const GLint *value); +typedef void (GL_APIENTRYP PFNGLUNIFORM4FPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); +typedef void (GL_APIENTRYP PFNGLUNIFORM4FVPROC) (GLint location, GLsizei count, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLUNIFORM4IPROC) (GLint location, GLint v0, GLint v1, GLint v2, GLint v3); +typedef void (GL_APIENTRYP PFNGLUNIFORM4IVPROC) (GLint location, GLsizei count, const GLint *value); +typedef void (GL_APIENTRYP PFNGLUNIFORMMATRIX2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLUNIFORMMATRIX3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLUNIFORMMATRIX4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLUSEPROGRAMPROC) (GLuint program); +typedef void (GL_APIENTRYP PFNGLVALIDATEPROGRAMPROC) (GLuint program); +typedef void (GL_APIENTRYP PFNGLVERTEXATTRIB1FPROC) (GLuint index, GLfloat x); +typedef void (GL_APIENTRYP PFNGLVERTEXATTRIB1FVPROC) (GLuint index, const GLfloat *v); +typedef void (GL_APIENTRYP PFNGLVERTEXATTRIB2FPROC) (GLuint index, GLfloat x, GLfloat y); +typedef void (GL_APIENTRYP PFNGLVERTEXATTRIB2FVPROC) (GLuint index, const GLfloat *v); +typedef void (GL_APIENTRYP PFNGLVERTEXATTRIB3FPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z); +typedef void (GL_APIENTRYP PFNGLVERTEXATTRIB3FVPROC) (GLuint index, const GLfloat *v); +typedef void (GL_APIENTRYP PFNGLVERTEXATTRIB4FPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (GL_APIENTRYP PFNGLVERTEXATTRIB4FVPROC) (GLuint index, const GLfloat *v); +typedef void (GL_APIENTRYP PFNGLVERTEXATTRIBPOINTERPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer); +typedef void (GL_APIENTRYP PFNGLVIEWPORTPROC) (GLint x, GLint y, GLsizei width, GLsizei height); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glActiveTexture (GLenum texture); +GL_APICALL void GL_APIENTRY glAttachShader (GLuint program, GLuint shader); +GL_APICALL void GL_APIENTRY glBindAttribLocation (GLuint program, GLuint index, const GLchar *name); +GL_APICALL void GL_APIENTRY glBindBuffer (GLenum target, GLuint buffer); +GL_APICALL void GL_APIENTRY glBindFramebuffer (GLenum target, GLuint framebuffer); +GL_APICALL void GL_APIENTRY glBindRenderbuffer (GLenum target, GLuint renderbuffer); +GL_APICALL void GL_APIENTRY glBindTexture (GLenum target, GLuint texture); +GL_APICALL void GL_APIENTRY glBlendColor (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); +GL_APICALL void GL_APIENTRY glBlendEquation (GLenum mode); +GL_APICALL void GL_APIENTRY glBlendEquationSeparate (GLenum modeRGB, GLenum modeAlpha); +GL_APICALL void GL_APIENTRY glBlendFunc (GLenum sfactor, GLenum dfactor); +GL_APICALL void GL_APIENTRY glBlendFuncSeparate (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); +GL_APICALL void GL_APIENTRY glBufferData (GLenum target, GLsizeiptr size, const void *data, GLenum usage); +GL_APICALL void GL_APIENTRY glBufferSubData (GLenum target, GLintptr offset, GLsizeiptr size, const void *data); +GL_APICALL GLenum GL_APIENTRY glCheckFramebufferStatus (GLenum target); +GL_APICALL void GL_APIENTRY glClear (GLbitfield mask); +GL_APICALL void GL_APIENTRY glClearColor (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); +GL_APICALL void GL_APIENTRY glClearDepthf (GLfloat d); +GL_APICALL void GL_APIENTRY glClearStencil (GLint s); +GL_APICALL void GL_APIENTRY glColorMask (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); +GL_APICALL void GL_APIENTRY glCompileShader (GLuint shader); +GL_APICALL void GL_APIENTRY glCompressedTexImage2D (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void *data); +GL_APICALL void GL_APIENTRY glCompressedTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *data); +GL_APICALL void GL_APIENTRY glCopyTexImage2D (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); +GL_APICALL void GL_APIENTRY glCopyTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); +GL_APICALL GLuint GL_APIENTRY glCreateProgram (void); +GL_APICALL GLuint GL_APIENTRY glCreateShader (GLenum type); +GL_APICALL void GL_APIENTRY glCullFace (GLenum mode); +GL_APICALL void GL_APIENTRY glDeleteBuffers (GLsizei n, const GLuint *buffers); +GL_APICALL void GL_APIENTRY glDeleteFramebuffers (GLsizei n, const GLuint *framebuffers); +GL_APICALL void GL_APIENTRY glDeleteProgram (GLuint program); +GL_APICALL void GL_APIENTRY glDeleteRenderbuffers (GLsizei n, const GLuint *renderbuffers); +GL_APICALL void GL_APIENTRY glDeleteShader (GLuint shader); +GL_APICALL void GL_APIENTRY glDeleteTextures (GLsizei n, const GLuint *textures); +GL_APICALL void GL_APIENTRY glDepthFunc (GLenum func); +GL_APICALL void GL_APIENTRY glDepthMask (GLboolean flag); +GL_APICALL void GL_APIENTRY glDepthRangef (GLfloat n, GLfloat f); +GL_APICALL void GL_APIENTRY glDetachShader (GLuint program, GLuint shader); +GL_APICALL void GL_APIENTRY glDisable (GLenum cap); +GL_APICALL void GL_APIENTRY glDisableVertexAttribArray (GLuint index); +GL_APICALL void GL_APIENTRY glDrawArrays (GLenum mode, GLint first, GLsizei count); +GL_APICALL void GL_APIENTRY glDrawElements (GLenum mode, GLsizei count, GLenum type, const void *indices); +GL_APICALL void GL_APIENTRY glEnable (GLenum cap); +GL_APICALL void GL_APIENTRY glEnableVertexAttribArray (GLuint index); +GL_APICALL void GL_APIENTRY glFinish (void); +GL_APICALL void GL_APIENTRY glFlush (void); +GL_APICALL void GL_APIENTRY glFramebufferRenderbuffer (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); +GL_APICALL void GL_APIENTRY glFramebufferTexture2D (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +GL_APICALL void GL_APIENTRY glFrontFace (GLenum mode); +GL_APICALL void GL_APIENTRY glGenBuffers (GLsizei n, GLuint *buffers); +GL_APICALL void GL_APIENTRY glGenerateMipmap (GLenum target); +GL_APICALL void GL_APIENTRY glGenFramebuffers (GLsizei n, GLuint *framebuffers); +GL_APICALL void GL_APIENTRY glGenRenderbuffers (GLsizei n, GLuint *renderbuffers); +GL_APICALL void GL_APIENTRY glGenTextures (GLsizei n, GLuint *textures); +GL_APICALL void GL_APIENTRY glGetActiveAttrib (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name); +GL_APICALL void GL_APIENTRY glGetActiveUniform (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name); +GL_APICALL void GL_APIENTRY glGetAttachedShaders (GLuint program, GLsizei maxCount, GLsizei *count, GLuint *shaders); +GL_APICALL GLint GL_APIENTRY glGetAttribLocation (GLuint program, const GLchar *name); +GL_APICALL void GL_APIENTRY glGetBooleanv (GLenum pname, GLboolean *data); +GL_APICALL void GL_APIENTRY glGetBufferParameteriv (GLenum target, GLenum pname, GLint *params); +GL_APICALL GLenum GL_APIENTRY glGetError (void); +GL_APICALL void GL_APIENTRY glGetFloatv (GLenum pname, GLfloat *data); +GL_APICALL void GL_APIENTRY glGetFramebufferAttachmentParameteriv (GLenum target, GLenum attachment, GLenum pname, GLint *params); +GL_APICALL void GL_APIENTRY glGetIntegerv (GLenum pname, GLint *data); +GL_APICALL void GL_APIENTRY glGetProgramiv (GLuint program, GLenum pname, GLint *params); +GL_APICALL void GL_APIENTRY glGetProgramInfoLog (GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog); +GL_APICALL void GL_APIENTRY glGetRenderbufferParameteriv (GLenum target, GLenum pname, GLint *params); +GL_APICALL void GL_APIENTRY glGetShaderiv (GLuint shader, GLenum pname, GLint *params); +GL_APICALL void GL_APIENTRY glGetShaderInfoLog (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog); +GL_APICALL void GL_APIENTRY glGetShaderPrecisionFormat (GLenum shadertype, GLenum precisiontype, GLint *range, GLint *precision); +GL_APICALL void GL_APIENTRY glGetShaderSource (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *source); +GL_APICALL const GLubyte *GL_APIENTRY glGetString (GLenum name); +GL_APICALL void GL_APIENTRY glGetTexParameterfv (GLenum target, GLenum pname, GLfloat *params); +GL_APICALL void GL_APIENTRY glGetTexParameteriv (GLenum target, GLenum pname, GLint *params); +GL_APICALL void GL_APIENTRY glGetUniformfv (GLuint program, GLint location, GLfloat *params); +GL_APICALL void GL_APIENTRY glGetUniformiv (GLuint program, GLint location, GLint *params); +GL_APICALL GLint GL_APIENTRY glGetUniformLocation (GLuint program, const GLchar *name); +GL_APICALL void GL_APIENTRY glGetVertexAttribfv (GLuint index, GLenum pname, GLfloat *params); +GL_APICALL void GL_APIENTRY glGetVertexAttribiv (GLuint index, GLenum pname, GLint *params); +GL_APICALL void GL_APIENTRY glGetVertexAttribPointerv (GLuint index, GLenum pname, void **pointer); +GL_APICALL void GL_APIENTRY glHint (GLenum target, GLenum mode); +GL_APICALL GLboolean GL_APIENTRY glIsBuffer (GLuint buffer); +GL_APICALL GLboolean GL_APIENTRY glIsEnabled (GLenum cap); +GL_APICALL GLboolean GL_APIENTRY glIsFramebuffer (GLuint framebuffer); +GL_APICALL GLboolean GL_APIENTRY glIsProgram (GLuint program); +GL_APICALL GLboolean GL_APIENTRY glIsRenderbuffer (GLuint renderbuffer); +GL_APICALL GLboolean GL_APIENTRY glIsShader (GLuint shader); +GL_APICALL GLboolean GL_APIENTRY glIsTexture (GLuint texture); +GL_APICALL void GL_APIENTRY glLineWidth (GLfloat width); +GL_APICALL void GL_APIENTRY glLinkProgram (GLuint program); +GL_APICALL void GL_APIENTRY glPixelStorei (GLenum pname, GLint param); +GL_APICALL void GL_APIENTRY glPolygonOffset (GLfloat factor, GLfloat units); +GL_APICALL void GL_APIENTRY glReadPixels (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void *pixels); +GL_APICALL void GL_APIENTRY glReleaseShaderCompiler (void); +GL_APICALL void GL_APIENTRY glRenderbufferStorage (GLenum target, GLenum internalformat, GLsizei width, GLsizei height); +GL_APICALL void GL_APIENTRY glSampleCoverage (GLfloat value, GLboolean invert); +GL_APICALL void GL_APIENTRY glScissor (GLint x, GLint y, GLsizei width, GLsizei height); +GL_APICALL void GL_APIENTRY glShaderBinary (GLsizei count, const GLuint *shaders, GLenum binaryformat, const void *binary, GLsizei length); +GL_APICALL void GL_APIENTRY glShaderSource (GLuint shader, GLsizei count, const GLchar *const*string, const GLint *length); +GL_APICALL void GL_APIENTRY glStencilFunc (GLenum func, GLint ref, GLuint mask); +GL_APICALL void GL_APIENTRY glStencilFuncSeparate (GLenum face, GLenum func, GLint ref, GLuint mask); +GL_APICALL void GL_APIENTRY glStencilMask (GLuint mask); +GL_APICALL void GL_APIENTRY glStencilMaskSeparate (GLenum face, GLuint mask); +GL_APICALL void GL_APIENTRY glStencilOp (GLenum fail, GLenum zfail, GLenum zpass); +GL_APICALL void GL_APIENTRY glStencilOpSeparate (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass); +GL_APICALL void GL_APIENTRY glTexImage2D (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels); +GL_APICALL void GL_APIENTRY glTexParameterf (GLenum target, GLenum pname, GLfloat param); +GL_APICALL void GL_APIENTRY glTexParameterfv (GLenum target, GLenum pname, const GLfloat *params); +GL_APICALL void GL_APIENTRY glTexParameteri (GLenum target, GLenum pname, GLint param); +GL_APICALL void GL_APIENTRY glTexParameteriv (GLenum target, GLenum pname, const GLint *params); +GL_APICALL void GL_APIENTRY glTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels); +GL_APICALL void GL_APIENTRY glUniform1f (GLint location, GLfloat v0); +GL_APICALL void GL_APIENTRY glUniform1fv (GLint location, GLsizei count, const GLfloat *value); +GL_APICALL void GL_APIENTRY glUniform1i (GLint location, GLint v0); +GL_APICALL void GL_APIENTRY glUniform1iv (GLint location, GLsizei count, const GLint *value); +GL_APICALL void GL_APIENTRY glUniform2f (GLint location, GLfloat v0, GLfloat v1); +GL_APICALL void GL_APIENTRY glUniform2fv (GLint location, GLsizei count, const GLfloat *value); +GL_APICALL void GL_APIENTRY glUniform2i (GLint location, GLint v0, GLint v1); +GL_APICALL void GL_APIENTRY glUniform2iv (GLint location, GLsizei count, const GLint *value); +GL_APICALL void GL_APIENTRY glUniform3f (GLint location, GLfloat v0, GLfloat v1, GLfloat v2); +GL_APICALL void GL_APIENTRY glUniform3fv (GLint location, GLsizei count, const GLfloat *value); +GL_APICALL void GL_APIENTRY glUniform3i (GLint location, GLint v0, GLint v1, GLint v2); +GL_APICALL void GL_APIENTRY glUniform3iv (GLint location, GLsizei count, const GLint *value); +GL_APICALL void GL_APIENTRY glUniform4f (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); +GL_APICALL void GL_APIENTRY glUniform4fv (GLint location, GLsizei count, const GLfloat *value); +GL_APICALL void GL_APIENTRY glUniform4i (GLint location, GLint v0, GLint v1, GLint v2, GLint v3); +GL_APICALL void GL_APIENTRY glUniform4iv (GLint location, GLsizei count, const GLint *value); +GL_APICALL void GL_APIENTRY glUniformMatrix2fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GL_APICALL void GL_APIENTRY glUniformMatrix3fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GL_APICALL void GL_APIENTRY glUniformMatrix4fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GL_APICALL void GL_APIENTRY glUseProgram (GLuint program); +GL_APICALL void GL_APIENTRY glValidateProgram (GLuint program); +GL_APICALL void GL_APIENTRY glVertexAttrib1f (GLuint index, GLfloat x); +GL_APICALL void GL_APIENTRY glVertexAttrib1fv (GLuint index, const GLfloat *v); +GL_APICALL void GL_APIENTRY glVertexAttrib2f (GLuint index, GLfloat x, GLfloat y); +GL_APICALL void GL_APIENTRY glVertexAttrib2fv (GLuint index, const GLfloat *v); +GL_APICALL void GL_APIENTRY glVertexAttrib3f (GLuint index, GLfloat x, GLfloat y, GLfloat z); +GL_APICALL void GL_APIENTRY glVertexAttrib3fv (GLuint index, const GLfloat *v); +GL_APICALL void GL_APIENTRY glVertexAttrib4f (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +GL_APICALL void GL_APIENTRY glVertexAttrib4fv (GLuint index, const GLfloat *v); +GL_APICALL void GL_APIENTRY glVertexAttribPointer (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer); +GL_APICALL void GL_APIENTRY glViewport (GLint x, GLint y, GLsizei width, GLsizei height); +#endif +#endif /* GL_ES_VERSION_2_0 */ + +#ifndef GL_ES_VERSION_3_0 +#define GL_ES_VERSION_3_0 1 +typedef unsigned short GLhalf; +#define GL_READ_BUFFER 0x0C02 +#define GL_UNPACK_ROW_LENGTH 0x0CF2 +#define GL_UNPACK_SKIP_ROWS 0x0CF3 +#define GL_UNPACK_SKIP_PIXELS 0x0CF4 +#define GL_PACK_ROW_LENGTH 0x0D02 +#define GL_PACK_SKIP_ROWS 0x0D03 +#define GL_PACK_SKIP_PIXELS 0x0D04 +#define GL_COLOR 0x1800 +#define GL_DEPTH 0x1801 +#define GL_STENCIL 0x1802 +#define GL_RED 0x1903 +#define GL_RGB8 0x8051 +#define GL_RGBA8 0x8058 +#define GL_RGB10_A2 0x8059 +#define GL_TEXTURE_BINDING_3D 0x806A +#define GL_UNPACK_SKIP_IMAGES 0x806D +#define GL_UNPACK_IMAGE_HEIGHT 0x806E +#define GL_TEXTURE_3D 0x806F +#define GL_TEXTURE_WRAP_R 0x8072 +#define GL_MAX_3D_TEXTURE_SIZE 0x8073 +#define GL_UNSIGNED_INT_2_10_10_10_REV 0x8368 +#define GL_MAX_ELEMENTS_VERTICES 0x80E8 +#define GL_MAX_ELEMENTS_INDICES 0x80E9 +#define GL_TEXTURE_MIN_LOD 0x813A +#define GL_TEXTURE_MAX_LOD 0x813B +#define GL_TEXTURE_BASE_LEVEL 0x813C +#define GL_TEXTURE_MAX_LEVEL 0x813D +#define GL_MIN 0x8007 +#define GL_MAX 0x8008 +#define GL_DEPTH_COMPONENT24 0x81A6 +#define GL_MAX_TEXTURE_LOD_BIAS 0x84FD +#define GL_TEXTURE_COMPARE_MODE 0x884C +#define GL_TEXTURE_COMPARE_FUNC 0x884D +#define GL_CURRENT_QUERY 0x8865 +#define GL_QUERY_RESULT 0x8866 +#define GL_QUERY_RESULT_AVAILABLE 0x8867 +#define GL_BUFFER_MAPPED 0x88BC +#define GL_BUFFER_MAP_POINTER 0x88BD +#define GL_STREAM_READ 0x88E1 +#define GL_STREAM_COPY 0x88E2 +#define GL_STATIC_READ 0x88E5 +#define GL_STATIC_COPY 0x88E6 +#define GL_DYNAMIC_READ 0x88E9 +#define GL_DYNAMIC_COPY 0x88EA +#define GL_MAX_DRAW_BUFFERS 0x8824 +#define GL_DRAW_BUFFER0 0x8825 +#define GL_DRAW_BUFFER1 0x8826 +#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_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_MAX_FRAGMENT_UNIFORM_COMPONENTS 0x8B49 +#define GL_MAX_VERTEX_UNIFORM_COMPONENTS 0x8B4A +#define GL_SAMPLER_3D 0x8B5F +#define GL_SAMPLER_2D_SHADOW 0x8B62 +#define GL_FRAGMENT_SHADER_DERIVATIVE_HINT 0x8B8B +#define GL_PIXEL_PACK_BUFFER 0x88EB +#define GL_PIXEL_UNPACK_BUFFER 0x88EC +#define GL_PIXEL_PACK_BUFFER_BINDING 0x88ED +#define GL_PIXEL_UNPACK_BUFFER_BINDING 0x88EF +#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_SRGB 0x8C40 +#define GL_SRGB8 0x8C41 +#define GL_SRGB8_ALPHA8 0x8C43 +#define GL_COMPARE_REF_TO_TEXTURE 0x884E +#define GL_MAJOR_VERSION 0x821B +#define GL_MINOR_VERSION 0x821C +#define GL_NUM_EXTENSIONS 0x821D +#define GL_RGBA32F 0x8814 +#define GL_RGB32F 0x8815 +#define GL_RGBA16F 0x881A +#define GL_RGB16F 0x881B +#define GL_VERTEX_ATTRIB_ARRAY_INTEGER 0x88FD +#define GL_MAX_ARRAY_TEXTURE_LAYERS 0x88FF +#define GL_MIN_PROGRAM_TEXEL_OFFSET 0x8904 +#define GL_MAX_PROGRAM_TEXEL_OFFSET 0x8905 +#define GL_MAX_VARYING_COMPONENTS 0x8B4B +#define GL_TEXTURE_2D_ARRAY 0x8C1A +#define GL_TEXTURE_BINDING_2D_ARRAY 0x8C1D +#define GL_R11F_G11F_B10F 0x8C3A +#define GL_UNSIGNED_INT_10F_11F_11F_REV 0x8C3B +#define GL_RGB9_E5 0x8C3D +#define GL_UNSIGNED_INT_5_9_9_9_REV 0x8C3E +#define GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH 0x8C76 +#define GL_TRANSFORM_FEEDBACK_BUFFER_MODE 0x8C7F +#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS 0x8C80 +#define GL_TRANSFORM_FEEDBACK_VARYINGS 0x8C83 +#define GL_TRANSFORM_FEEDBACK_BUFFER_START 0x8C84 +#define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE 0x8C85 +#define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN 0x8C88 +#define GL_RASTERIZER_DISCARD 0x8C89 +#define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS 0x8C8A +#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS 0x8C8B +#define GL_INTERLEAVED_ATTRIBS 0x8C8C +#define GL_SEPARATE_ATTRIBS 0x8C8D +#define GL_TRANSFORM_FEEDBACK_BUFFER 0x8C8E +#define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING 0x8C8F +#define GL_RGBA32UI 0x8D70 +#define GL_RGB32UI 0x8D71 +#define GL_RGBA16UI 0x8D76 +#define GL_RGB16UI 0x8D77 +#define GL_RGBA8UI 0x8D7C +#define GL_RGB8UI 0x8D7D +#define GL_RGBA32I 0x8D82 +#define GL_RGB32I 0x8D83 +#define GL_RGBA16I 0x8D88 +#define GL_RGB16I 0x8D89 +#define GL_RGBA8I 0x8D8E +#define GL_RGB8I 0x8D8F +#define GL_RED_INTEGER 0x8D94 +#define GL_RGB_INTEGER 0x8D98 +#define GL_RGBA_INTEGER 0x8D99 +#define GL_SAMPLER_2D_ARRAY 0x8DC1 +#define GL_SAMPLER_2D_ARRAY_SHADOW 0x8DC4 +#define GL_SAMPLER_CUBE_SHADOW 0x8DC5 +#define GL_UNSIGNED_INT_VEC2 0x8DC6 +#define GL_UNSIGNED_INT_VEC3 0x8DC7 +#define GL_UNSIGNED_INT_VEC4 0x8DC8 +#define GL_INT_SAMPLER_2D 0x8DCA +#define GL_INT_SAMPLER_3D 0x8DCB +#define GL_INT_SAMPLER_CUBE 0x8DCC +#define GL_INT_SAMPLER_2D_ARRAY 0x8DCF +#define GL_UNSIGNED_INT_SAMPLER_2D 0x8DD2 +#define GL_UNSIGNED_INT_SAMPLER_3D 0x8DD3 +#define GL_UNSIGNED_INT_SAMPLER_CUBE 0x8DD4 +#define GL_UNSIGNED_INT_SAMPLER_2D_ARRAY 0x8DD7 +#define GL_BUFFER_ACCESS_FLAGS 0x911F +#define GL_BUFFER_MAP_LENGTH 0x9120 +#define GL_BUFFER_MAP_OFFSET 0x9121 +#define GL_DEPTH_COMPONENT32F 0x8CAC +#define GL_DEPTH32F_STENCIL8 0x8CAD +#define GL_FLOAT_32_UNSIGNED_INT_24_8_REV 0x8DAD +#define GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING 0x8210 +#define GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE 0x8211 +#define GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE 0x8212 +#define GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE 0x8213 +#define GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE 0x8214 +#define GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE 0x8215 +#define GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE 0x8216 +#define GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE 0x8217 +#define GL_FRAMEBUFFER_DEFAULT 0x8218 +#define GL_FRAMEBUFFER_UNDEFINED 0x8219 +#define GL_DEPTH_STENCIL_ATTACHMENT 0x821A +#define GL_DEPTH_STENCIL 0x84F9 +#define GL_UNSIGNED_INT_24_8 0x84FA +#define GL_DEPTH24_STENCIL8 0x88F0 +#define GL_UNSIGNED_NORMALIZED 0x8C17 +#define GL_DRAW_FRAMEBUFFER_BINDING 0x8CA6 +#define GL_READ_FRAMEBUFFER 0x8CA8 +#define GL_DRAW_FRAMEBUFFER 0x8CA9 +#define GL_READ_FRAMEBUFFER_BINDING 0x8CAA +#define GL_RENDERBUFFER_SAMPLES 0x8CAB +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER 0x8CD4 +#define GL_MAX_COLOR_ATTACHMENTS 0x8CDF +#define GL_COLOR_ATTACHMENT1 0x8CE1 +#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_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_ATTACHMENT16 0x8CF0 +#define GL_COLOR_ATTACHMENT17 0x8CF1 +#define GL_COLOR_ATTACHMENT18 0x8CF2 +#define GL_COLOR_ATTACHMENT19 0x8CF3 +#define GL_COLOR_ATTACHMENT20 0x8CF4 +#define GL_COLOR_ATTACHMENT21 0x8CF5 +#define GL_COLOR_ATTACHMENT22 0x8CF6 +#define GL_COLOR_ATTACHMENT23 0x8CF7 +#define GL_COLOR_ATTACHMENT24 0x8CF8 +#define GL_COLOR_ATTACHMENT25 0x8CF9 +#define GL_COLOR_ATTACHMENT26 0x8CFA +#define GL_COLOR_ATTACHMENT27 0x8CFB +#define GL_COLOR_ATTACHMENT28 0x8CFC +#define GL_COLOR_ATTACHMENT29 0x8CFD +#define GL_COLOR_ATTACHMENT30 0x8CFE +#define GL_COLOR_ATTACHMENT31 0x8CFF +#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE 0x8D56 +#define GL_MAX_SAMPLES 0x8D57 +#define GL_HALF_FLOAT 0x140B +#define GL_MAP_READ_BIT 0x0001 +#define GL_MAP_WRITE_BIT 0x0002 +#define GL_MAP_INVALIDATE_RANGE_BIT 0x0004 +#define GL_MAP_INVALIDATE_BUFFER_BIT 0x0008 +#define GL_MAP_FLUSH_EXPLICIT_BIT 0x0010 +#define GL_MAP_UNSYNCHRONIZED_BIT 0x0020 +#define GL_RG 0x8227 +#define GL_RG_INTEGER 0x8228 +#define GL_R8 0x8229 +#define GL_RG8 0x822B +#define GL_R16F 0x822D +#define GL_R32F 0x822E +#define GL_RG16F 0x822F +#define GL_RG32F 0x8230 +#define GL_R8I 0x8231 +#define GL_R8UI 0x8232 +#define GL_R16I 0x8233 +#define GL_R16UI 0x8234 +#define GL_R32I 0x8235 +#define GL_R32UI 0x8236 +#define GL_RG8I 0x8237 +#define GL_RG8UI 0x8238 +#define GL_RG16I 0x8239 +#define GL_RG16UI 0x823A +#define GL_RG32I 0x823B +#define GL_RG32UI 0x823C +#define GL_VERTEX_ARRAY_BINDING 0x85B5 +#define GL_R8_SNORM 0x8F94 +#define GL_RG8_SNORM 0x8F95 +#define GL_RGB8_SNORM 0x8F96 +#define GL_RGBA8_SNORM 0x8F97 +#define GL_SIGNED_NORMALIZED 0x8F9C +#define GL_PRIMITIVE_RESTART_FIXED_INDEX 0x8D69 +#define GL_COPY_READ_BUFFER 0x8F36 +#define GL_COPY_WRITE_BUFFER 0x8F37 +#define GL_COPY_READ_BUFFER_BINDING 0x8F36 +#define GL_COPY_WRITE_BUFFER_BINDING 0x8F37 +#define GL_UNIFORM_BUFFER 0x8A11 +#define GL_UNIFORM_BUFFER_BINDING 0x8A28 +#define GL_UNIFORM_BUFFER_START 0x8A29 +#define GL_UNIFORM_BUFFER_SIZE 0x8A2A +#define GL_MAX_VERTEX_UNIFORM_BLOCKS 0x8A2B +#define GL_MAX_FRAGMENT_UNIFORM_BLOCKS 0x8A2D +#define GL_MAX_COMBINED_UNIFORM_BLOCKS 0x8A2E +#define GL_MAX_UNIFORM_BUFFER_BINDINGS 0x8A2F +#define GL_MAX_UNIFORM_BLOCK_SIZE 0x8A30 +#define GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS 0x8A31 +#define GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS 0x8A33 +#define GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT 0x8A34 +#define GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH 0x8A35 +#define GL_ACTIVE_UNIFORM_BLOCKS 0x8A36 +#define GL_UNIFORM_TYPE 0x8A37 +#define GL_UNIFORM_SIZE 0x8A38 +#define GL_UNIFORM_NAME_LENGTH 0x8A39 +#define GL_UNIFORM_BLOCK_INDEX 0x8A3A +#define GL_UNIFORM_OFFSET 0x8A3B +#define GL_UNIFORM_ARRAY_STRIDE 0x8A3C +#define GL_UNIFORM_MATRIX_STRIDE 0x8A3D +#define GL_UNIFORM_IS_ROW_MAJOR 0x8A3E +#define GL_UNIFORM_BLOCK_BINDING 0x8A3F +#define GL_UNIFORM_BLOCK_DATA_SIZE 0x8A40 +#define GL_UNIFORM_BLOCK_NAME_LENGTH 0x8A41 +#define GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS 0x8A42 +#define GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES 0x8A43 +#define GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER 0x8A44 +#define GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER 0x8A46 +#define GL_INVALID_INDEX 0xFFFFFFFFu +#define GL_MAX_VERTEX_OUTPUT_COMPONENTS 0x9122 +#define GL_MAX_FRAGMENT_INPUT_COMPONENTS 0x9125 +#define GL_MAX_SERVER_WAIT_TIMEOUT 0x9111 +#define GL_OBJECT_TYPE 0x9112 +#define GL_SYNC_CONDITION 0x9113 +#define GL_SYNC_STATUS 0x9114 +#define GL_SYNC_FLAGS 0x9115 +#define GL_SYNC_FENCE 0x9116 +#define GL_SYNC_GPU_COMMANDS_COMPLETE 0x9117 +#define GL_UNSIGNALED 0x9118 +#define GL_SIGNALED 0x9119 +#define GL_ALREADY_SIGNALED 0x911A +#define GL_TIMEOUT_EXPIRED 0x911B +#define GL_CONDITION_SATISFIED 0x911C +#define GL_WAIT_FAILED 0x911D +#define GL_SYNC_FLUSH_COMMANDS_BIT 0x00000001 +#define GL_TIMEOUT_IGNORED 0xFFFFFFFFFFFFFFFFull +#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR 0x88FE +#define GL_ANY_SAMPLES_PASSED 0x8C2F +#define GL_ANY_SAMPLES_PASSED_CONSERVATIVE 0x8D6A +#define GL_SAMPLER_BINDING 0x8919 +#define GL_RGB10_A2UI 0x906F +#define GL_TEXTURE_SWIZZLE_R 0x8E42 +#define GL_TEXTURE_SWIZZLE_G 0x8E43 +#define GL_TEXTURE_SWIZZLE_B 0x8E44 +#define GL_TEXTURE_SWIZZLE_A 0x8E45 +#define GL_GREEN 0x1904 +#define GL_BLUE 0x1905 +#define GL_INT_2_10_10_10_REV 0x8D9F +#define GL_TRANSFORM_FEEDBACK 0x8E22 +#define GL_TRANSFORM_FEEDBACK_PAUSED 0x8E23 +#define GL_TRANSFORM_FEEDBACK_ACTIVE 0x8E24 +#define GL_TRANSFORM_FEEDBACK_BINDING 0x8E25 +#define GL_PROGRAM_BINARY_RETRIEVABLE_HINT 0x8257 +#define GL_PROGRAM_BINARY_LENGTH 0x8741 +#define GL_NUM_PROGRAM_BINARY_FORMATS 0x87FE +#define GL_PROGRAM_BINARY_FORMATS 0x87FF +#define GL_COMPRESSED_R11_EAC 0x9270 +#define GL_COMPRESSED_SIGNED_R11_EAC 0x9271 +#define GL_COMPRESSED_RG11_EAC 0x9272 +#define GL_COMPRESSED_SIGNED_RG11_EAC 0x9273 +#define GL_COMPRESSED_RGB8_ETC2 0x9274 +#define GL_COMPRESSED_SRGB8_ETC2 0x9275 +#define GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9276 +#define GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9277 +#define GL_COMPRESSED_RGBA8_ETC2_EAC 0x9278 +#define GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC 0x9279 +#define GL_TEXTURE_IMMUTABLE_FORMAT 0x912F +#define GL_MAX_ELEMENT_INDEX 0x8D6B +#define GL_NUM_SAMPLE_COUNTS 0x9380 +#define GL_TEXTURE_IMMUTABLE_LEVELS 0x82DF +typedef void (GL_APIENTRYP PFNGLREADBUFFERPROC) (GLenum src); +typedef void (GL_APIENTRYP PFNGLDRAWRANGEELEMENTSPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices); +typedef void (GL_APIENTRYP PFNGLTEXIMAGE3DPROC) (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *pixels); +typedef void (GL_APIENTRYP PFNGLTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels); +typedef void (GL_APIENTRYP PFNGLCOPYTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (GL_APIENTRYP PFNGLCOMPRESSEDTEXIMAGE3DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *data); +typedef void (GL_APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *data); +typedef void (GL_APIENTRYP PFNGLGENQUERIESPROC) (GLsizei n, GLuint *ids); +typedef void (GL_APIENTRYP PFNGLDELETEQUERIESPROC) (GLsizei n, const GLuint *ids); +typedef GLboolean (GL_APIENTRYP PFNGLISQUERYPROC) (GLuint id); +typedef void (GL_APIENTRYP PFNGLBEGINQUERYPROC) (GLenum target, GLuint id); +typedef void (GL_APIENTRYP PFNGLENDQUERYPROC) (GLenum target); +typedef void (GL_APIENTRYP PFNGLGETQUERYIVPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (GL_APIENTRYP PFNGLGETQUERYOBJECTUIVPROC) (GLuint id, GLenum pname, GLuint *params); +typedef GLboolean (GL_APIENTRYP PFNGLUNMAPBUFFERPROC) (GLenum target); +typedef void (GL_APIENTRYP PFNGLGETBUFFERPOINTERVPROC) (GLenum target, GLenum pname, void **params); +typedef void (GL_APIENTRYP PFNGLDRAWBUFFERSPROC) (GLsizei n, const GLenum *bufs); +typedef void (GL_APIENTRYP PFNGLUNIFORMMATRIX2X3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLUNIFORMMATRIX3X2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLUNIFORMMATRIX2X4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLUNIFORMMATRIX4X2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLUNIFORMMATRIX3X4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLUNIFORMMATRIX4X3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLBLITFRAMEBUFFERPROC) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); +typedef void (GL_APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERTEXTURELAYERPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); +typedef void *(GL_APIENTRYP PFNGLMAPBUFFERRANGEPROC) (GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access); +typedef void (GL_APIENTRYP PFNGLFLUSHMAPPEDBUFFERRANGEPROC) (GLenum target, GLintptr offset, GLsizeiptr length); +typedef void (GL_APIENTRYP PFNGLBINDVERTEXARRAYPROC) (GLuint array); +typedef void (GL_APIENTRYP PFNGLDELETEVERTEXARRAYSPROC) (GLsizei n, const GLuint *arrays); +typedef void (GL_APIENTRYP PFNGLGENVERTEXARRAYSPROC) (GLsizei n, GLuint *arrays); +typedef GLboolean (GL_APIENTRYP PFNGLISVERTEXARRAYPROC) (GLuint array); +typedef void (GL_APIENTRYP PFNGLGETINTEGERI_VPROC) (GLenum target, GLuint index, GLint *data); +typedef void (GL_APIENTRYP PFNGLBEGINTRANSFORMFEEDBACKPROC) (GLenum primitiveMode); +typedef void (GL_APIENTRYP PFNGLENDTRANSFORMFEEDBACKPROC) (void); +typedef void (GL_APIENTRYP PFNGLBINDBUFFERRANGEPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); +typedef void (GL_APIENTRYP PFNGLBINDBUFFERBASEPROC) (GLenum target, GLuint index, GLuint buffer); +typedef void (GL_APIENTRYP PFNGLTRANSFORMFEEDBACKVARYINGSPROC) (GLuint program, GLsizei count, const GLchar *const*varyings, GLenum bufferMode); +typedef void (GL_APIENTRYP PFNGLGETTRANSFORMFEEDBACKVARYINGPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name); +typedef void (GL_APIENTRYP PFNGLVERTEXATTRIBIPOINTERPROC) (GLuint index, GLint size, GLenum type, GLsizei stride, const void *pointer); +typedef void (GL_APIENTRYP PFNGLGETVERTEXATTRIBIIVPROC) (GLuint index, GLenum pname, GLint *params); +typedef void (GL_APIENTRYP PFNGLGETVERTEXATTRIBIUIVPROC) (GLuint index, GLenum pname, GLuint *params); +typedef void (GL_APIENTRYP PFNGLVERTEXATTRIBI4IPROC) (GLuint index, GLint x, GLint y, GLint z, GLint w); +typedef void (GL_APIENTRYP PFNGLVERTEXATTRIBI4UIPROC) (GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); +typedef void (GL_APIENTRYP PFNGLVERTEXATTRIBI4IVPROC) (GLuint index, const GLint *v); +typedef void (GL_APIENTRYP PFNGLVERTEXATTRIBI4UIVPROC) (GLuint index, const GLuint *v); +typedef void (GL_APIENTRYP PFNGLGETUNIFORMUIVPROC) (GLuint program, GLint location, GLuint *params); +typedef GLint (GL_APIENTRYP PFNGLGETFRAGDATALOCATIONPROC) (GLuint program, const GLchar *name); +typedef void (GL_APIENTRYP PFNGLUNIFORM1UIPROC) (GLint location, GLuint v0); +typedef void (GL_APIENTRYP PFNGLUNIFORM2UIPROC) (GLint location, GLuint v0, GLuint v1); +typedef void (GL_APIENTRYP PFNGLUNIFORM3UIPROC) (GLint location, GLuint v0, GLuint v1, GLuint v2); +typedef void (GL_APIENTRYP PFNGLUNIFORM4UIPROC) (GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); +typedef void (GL_APIENTRYP PFNGLUNIFORM1UIVPROC) (GLint location, GLsizei count, const GLuint *value); +typedef void (GL_APIENTRYP PFNGLUNIFORM2UIVPROC) (GLint location, GLsizei count, const GLuint *value); +typedef void (GL_APIENTRYP PFNGLUNIFORM3UIVPROC) (GLint location, GLsizei count, const GLuint *value); +typedef void (GL_APIENTRYP PFNGLUNIFORM4UIVPROC) (GLint location, GLsizei count, const GLuint *value); +typedef void (GL_APIENTRYP PFNGLCLEARBUFFERIVPROC) (GLenum buffer, GLint drawbuffer, const GLint *value); +typedef void (GL_APIENTRYP PFNGLCLEARBUFFERUIVPROC) (GLenum buffer, GLint drawbuffer, const GLuint *value); +typedef void (GL_APIENTRYP PFNGLCLEARBUFFERFVPROC) (GLenum buffer, GLint drawbuffer, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLCLEARBUFFERFIPROC) (GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil); +typedef const GLubyte *(GL_APIENTRYP PFNGLGETSTRINGIPROC) (GLenum name, GLuint index); +typedef void (GL_APIENTRYP PFNGLCOPYBUFFERSUBDATAPROC) (GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); +typedef void (GL_APIENTRYP PFNGLGETUNIFORMINDICESPROC) (GLuint program, GLsizei uniformCount, const GLchar *const*uniformNames, GLuint *uniformIndices); +typedef void (GL_APIENTRYP PFNGLGETACTIVEUNIFORMSIVPROC) (GLuint program, GLsizei uniformCount, const GLuint *uniformIndices, GLenum pname, GLint *params); +typedef GLuint (GL_APIENTRYP PFNGLGETUNIFORMBLOCKINDEXPROC) (GLuint program, const GLchar *uniformBlockName); +typedef void (GL_APIENTRYP PFNGLGETACTIVEUNIFORMBLOCKIVPROC) (GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint *params); +typedef void (GL_APIENTRYP PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC) (GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformBlockName); +typedef void (GL_APIENTRYP PFNGLUNIFORMBLOCKBINDINGPROC) (GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding); +typedef void (GL_APIENTRYP PFNGLDRAWARRAYSINSTANCEDPROC) (GLenum mode, GLint first, GLsizei count, GLsizei instancecount); +typedef void (GL_APIENTRYP PFNGLDRAWELEMENTSINSTANCEDPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount); +typedef GLsync (GL_APIENTRYP PFNGLFENCESYNCPROC) (GLenum condition, GLbitfield flags); +typedef GLboolean (GL_APIENTRYP PFNGLISSYNCPROC) (GLsync sync); +typedef void (GL_APIENTRYP PFNGLDELETESYNCPROC) (GLsync sync); +typedef GLenum (GL_APIENTRYP PFNGLCLIENTWAITSYNCPROC) (GLsync sync, GLbitfield flags, GLuint64 timeout); +typedef void (GL_APIENTRYP PFNGLWAITSYNCPROC) (GLsync sync, GLbitfield flags, GLuint64 timeout); +typedef void (GL_APIENTRYP PFNGLGETINTEGER64VPROC) (GLenum pname, GLint64 *data); +typedef void (GL_APIENTRYP PFNGLGETSYNCIVPROC) (GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values); +typedef void (GL_APIENTRYP PFNGLGETINTEGER64I_VPROC) (GLenum target, GLuint index, GLint64 *data); +typedef void (GL_APIENTRYP PFNGLGETBUFFERPARAMETERI64VPROC) (GLenum target, GLenum pname, GLint64 *params); +typedef void (GL_APIENTRYP PFNGLGENSAMPLERSPROC) (GLsizei count, GLuint *samplers); +typedef void (GL_APIENTRYP PFNGLDELETESAMPLERSPROC) (GLsizei count, const GLuint *samplers); +typedef GLboolean (GL_APIENTRYP PFNGLISSAMPLERPROC) (GLuint sampler); +typedef void (GL_APIENTRYP PFNGLBINDSAMPLERPROC) (GLuint unit, GLuint sampler); +typedef void (GL_APIENTRYP PFNGLSAMPLERPARAMETERIPROC) (GLuint sampler, GLenum pname, GLint param); +typedef void (GL_APIENTRYP PFNGLSAMPLERPARAMETERIVPROC) (GLuint sampler, GLenum pname, const GLint *param); +typedef void (GL_APIENTRYP PFNGLSAMPLERPARAMETERFPROC) (GLuint sampler, GLenum pname, GLfloat param); +typedef void (GL_APIENTRYP PFNGLSAMPLERPARAMETERFVPROC) (GLuint sampler, GLenum pname, const GLfloat *param); +typedef void (GL_APIENTRYP PFNGLGETSAMPLERPARAMETERIVPROC) (GLuint sampler, GLenum pname, GLint *params); +typedef void (GL_APIENTRYP PFNGLGETSAMPLERPARAMETERFVPROC) (GLuint sampler, GLenum pname, GLfloat *params); +typedef void (GL_APIENTRYP PFNGLVERTEXATTRIBDIVISORPROC) (GLuint index, GLuint divisor); +typedef void (GL_APIENTRYP PFNGLBINDTRANSFORMFEEDBACKPROC) (GLenum target, GLuint id); +typedef void (GL_APIENTRYP PFNGLDELETETRANSFORMFEEDBACKSPROC) (GLsizei n, const GLuint *ids); +typedef void (GL_APIENTRYP PFNGLGENTRANSFORMFEEDBACKSPROC) (GLsizei n, GLuint *ids); +typedef GLboolean (GL_APIENTRYP PFNGLISTRANSFORMFEEDBACKPROC) (GLuint id); +typedef void (GL_APIENTRYP PFNGLPAUSETRANSFORMFEEDBACKPROC) (void); +typedef void (GL_APIENTRYP PFNGLRESUMETRANSFORMFEEDBACKPROC) (void); +typedef void (GL_APIENTRYP PFNGLGETPROGRAMBINARYPROC) (GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, void *binary); +typedef void (GL_APIENTRYP PFNGLPROGRAMBINARYPROC) (GLuint program, GLenum binaryFormat, const void *binary, GLsizei length); +typedef void (GL_APIENTRYP PFNGLPROGRAMPARAMETERIPROC) (GLuint program, GLenum pname, GLint value); +typedef void (GL_APIENTRYP PFNGLINVALIDATEFRAMEBUFFERPROC) (GLenum target, GLsizei numAttachments, const GLenum *attachments); +typedef void (GL_APIENTRYP PFNGLINVALIDATESUBFRAMEBUFFERPROC) (GLenum target, GLsizei numAttachments, const GLenum *attachments, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (GL_APIENTRYP PFNGLTEXSTORAGE2DPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (GL_APIENTRYP PFNGLTEXSTORAGE3DPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); +typedef void (GL_APIENTRYP PFNGLGETINTERNALFORMATIVPROC) (GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint *params); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glReadBuffer (GLenum src); +GL_APICALL void GL_APIENTRY glDrawRangeElements (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices); +GL_APICALL void GL_APIENTRY glTexImage3D (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *pixels); +GL_APICALL void GL_APIENTRY glTexSubImage3D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels); +GL_APICALL void GL_APIENTRY glCopyTexSubImage3D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); +GL_APICALL void GL_APIENTRY glCompressedTexImage3D (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *data); +GL_APICALL void GL_APIENTRY glCompressedTexSubImage3D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *data); +GL_APICALL void GL_APIENTRY glGenQueries (GLsizei n, GLuint *ids); +GL_APICALL void GL_APIENTRY glDeleteQueries (GLsizei n, const GLuint *ids); +GL_APICALL GLboolean GL_APIENTRY glIsQuery (GLuint id); +GL_APICALL void GL_APIENTRY glBeginQuery (GLenum target, GLuint id); +GL_APICALL void GL_APIENTRY glEndQuery (GLenum target); +GL_APICALL void GL_APIENTRY glGetQueryiv (GLenum target, GLenum pname, GLint *params); +GL_APICALL void GL_APIENTRY glGetQueryObjectuiv (GLuint id, GLenum pname, GLuint *params); +GL_APICALL GLboolean GL_APIENTRY glUnmapBuffer (GLenum target); +GL_APICALL void GL_APIENTRY glGetBufferPointerv (GLenum target, GLenum pname, void **params); +GL_APICALL void GL_APIENTRY glDrawBuffers (GLsizei n, const GLenum *bufs); +GL_APICALL void GL_APIENTRY glUniformMatrix2x3fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GL_APICALL void GL_APIENTRY glUniformMatrix3x2fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GL_APICALL void GL_APIENTRY glUniformMatrix2x4fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GL_APICALL void GL_APIENTRY glUniformMatrix4x2fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GL_APICALL void GL_APIENTRY glUniformMatrix3x4fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GL_APICALL void GL_APIENTRY glUniformMatrix4x3fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GL_APICALL void GL_APIENTRY glBlitFramebuffer (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); +GL_APICALL void GL_APIENTRY glRenderbufferStorageMultisample (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +GL_APICALL void GL_APIENTRY glFramebufferTextureLayer (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); +GL_APICALL void *GL_APIENTRY glMapBufferRange (GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access); +GL_APICALL void GL_APIENTRY glFlushMappedBufferRange (GLenum target, GLintptr offset, GLsizeiptr length); +GL_APICALL void GL_APIENTRY glBindVertexArray (GLuint array); +GL_APICALL void GL_APIENTRY glDeleteVertexArrays (GLsizei n, const GLuint *arrays); +GL_APICALL void GL_APIENTRY glGenVertexArrays (GLsizei n, GLuint *arrays); +GL_APICALL GLboolean GL_APIENTRY glIsVertexArray (GLuint array); +GL_APICALL void GL_APIENTRY glGetIntegeri_v (GLenum target, GLuint index, GLint *data); +GL_APICALL void GL_APIENTRY glBeginTransformFeedback (GLenum primitiveMode); +GL_APICALL void GL_APIENTRY glEndTransformFeedback (void); +GL_APICALL void GL_APIENTRY glBindBufferRange (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); +GL_APICALL void GL_APIENTRY glBindBufferBase (GLenum target, GLuint index, GLuint buffer); +GL_APICALL void GL_APIENTRY glTransformFeedbackVaryings (GLuint program, GLsizei count, const GLchar *const*varyings, GLenum bufferMode); +GL_APICALL void GL_APIENTRY glGetTransformFeedbackVarying (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name); +GL_APICALL void GL_APIENTRY glVertexAttribIPointer (GLuint index, GLint size, GLenum type, GLsizei stride, const void *pointer); +GL_APICALL void GL_APIENTRY glGetVertexAttribIiv (GLuint index, GLenum pname, GLint *params); +GL_APICALL void GL_APIENTRY glGetVertexAttribIuiv (GLuint index, GLenum pname, GLuint *params); +GL_APICALL void GL_APIENTRY glVertexAttribI4i (GLuint index, GLint x, GLint y, GLint z, GLint w); +GL_APICALL void GL_APIENTRY glVertexAttribI4ui (GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); +GL_APICALL void GL_APIENTRY glVertexAttribI4iv (GLuint index, const GLint *v); +GL_APICALL void GL_APIENTRY glVertexAttribI4uiv (GLuint index, const GLuint *v); +GL_APICALL void GL_APIENTRY glGetUniformuiv (GLuint program, GLint location, GLuint *params); +GL_APICALL GLint GL_APIENTRY glGetFragDataLocation (GLuint program, const GLchar *name); +GL_APICALL void GL_APIENTRY glUniform1ui (GLint location, GLuint v0); +GL_APICALL void GL_APIENTRY glUniform2ui (GLint location, GLuint v0, GLuint v1); +GL_APICALL void GL_APIENTRY glUniform3ui (GLint location, GLuint v0, GLuint v1, GLuint v2); +GL_APICALL void GL_APIENTRY glUniform4ui (GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); +GL_APICALL void GL_APIENTRY glUniform1uiv (GLint location, GLsizei count, const GLuint *value); +GL_APICALL void GL_APIENTRY glUniform2uiv (GLint location, GLsizei count, const GLuint *value); +GL_APICALL void GL_APIENTRY glUniform3uiv (GLint location, GLsizei count, const GLuint *value); +GL_APICALL void GL_APIENTRY glUniform4uiv (GLint location, GLsizei count, const GLuint *value); +GL_APICALL void GL_APIENTRY glClearBufferiv (GLenum buffer, GLint drawbuffer, const GLint *value); +GL_APICALL void GL_APIENTRY glClearBufferuiv (GLenum buffer, GLint drawbuffer, const GLuint *value); +GL_APICALL void GL_APIENTRY glClearBufferfv (GLenum buffer, GLint drawbuffer, const GLfloat *value); +GL_APICALL void GL_APIENTRY glClearBufferfi (GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil); +GL_APICALL const GLubyte *GL_APIENTRY glGetStringi (GLenum name, GLuint index); +GL_APICALL void GL_APIENTRY glCopyBufferSubData (GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); +GL_APICALL void GL_APIENTRY glGetUniformIndices (GLuint program, GLsizei uniformCount, const GLchar *const*uniformNames, GLuint *uniformIndices); +GL_APICALL void GL_APIENTRY glGetActiveUniformsiv (GLuint program, GLsizei uniformCount, const GLuint *uniformIndices, GLenum pname, GLint *params); +GL_APICALL GLuint GL_APIENTRY glGetUniformBlockIndex (GLuint program, const GLchar *uniformBlockName); +GL_APICALL void GL_APIENTRY glGetActiveUniformBlockiv (GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint *params); +GL_APICALL void GL_APIENTRY glGetActiveUniformBlockName (GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformBlockName); +GL_APICALL void GL_APIENTRY glUniformBlockBinding (GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding); +GL_APICALL void GL_APIENTRY glDrawArraysInstanced (GLenum mode, GLint first, GLsizei count, GLsizei instancecount); +GL_APICALL void GL_APIENTRY glDrawElementsInstanced (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount); +GL_APICALL GLsync GL_APIENTRY glFenceSync (GLenum condition, GLbitfield flags); +GL_APICALL GLboolean GL_APIENTRY glIsSync (GLsync sync); +GL_APICALL void GL_APIENTRY glDeleteSync (GLsync sync); +GL_APICALL GLenum GL_APIENTRY glClientWaitSync (GLsync sync, GLbitfield flags, GLuint64 timeout); +GL_APICALL void GL_APIENTRY glWaitSync (GLsync sync, GLbitfield flags, GLuint64 timeout); +GL_APICALL void GL_APIENTRY glGetInteger64v (GLenum pname, GLint64 *data); +GL_APICALL void GL_APIENTRY glGetSynciv (GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values); +GL_APICALL void GL_APIENTRY glGetInteger64i_v (GLenum target, GLuint index, GLint64 *data); +GL_APICALL void GL_APIENTRY glGetBufferParameteri64v (GLenum target, GLenum pname, GLint64 *params); +GL_APICALL void GL_APIENTRY glGenSamplers (GLsizei count, GLuint *samplers); +GL_APICALL void GL_APIENTRY glDeleteSamplers (GLsizei count, const GLuint *samplers); +GL_APICALL GLboolean GL_APIENTRY glIsSampler (GLuint sampler); +GL_APICALL void GL_APIENTRY glBindSampler (GLuint unit, GLuint sampler); +GL_APICALL void GL_APIENTRY glSamplerParameteri (GLuint sampler, GLenum pname, GLint param); +GL_APICALL void GL_APIENTRY glSamplerParameteriv (GLuint sampler, GLenum pname, const GLint *param); +GL_APICALL void GL_APIENTRY glSamplerParameterf (GLuint sampler, GLenum pname, GLfloat param); +GL_APICALL void GL_APIENTRY glSamplerParameterfv (GLuint sampler, GLenum pname, const GLfloat *param); +GL_APICALL void GL_APIENTRY glGetSamplerParameteriv (GLuint sampler, GLenum pname, GLint *params); +GL_APICALL void GL_APIENTRY glGetSamplerParameterfv (GLuint sampler, GLenum pname, GLfloat *params); +GL_APICALL void GL_APIENTRY glVertexAttribDivisor (GLuint index, GLuint divisor); +GL_APICALL void GL_APIENTRY glBindTransformFeedback (GLenum target, GLuint id); +GL_APICALL void GL_APIENTRY glDeleteTransformFeedbacks (GLsizei n, const GLuint *ids); +GL_APICALL void GL_APIENTRY glGenTransformFeedbacks (GLsizei n, GLuint *ids); +GL_APICALL GLboolean GL_APIENTRY glIsTransformFeedback (GLuint id); +GL_APICALL void GL_APIENTRY glPauseTransformFeedback (void); +GL_APICALL void GL_APIENTRY glResumeTransformFeedback (void); +GL_APICALL void GL_APIENTRY glGetProgramBinary (GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, void *binary); +GL_APICALL void GL_APIENTRY glProgramBinary (GLuint program, GLenum binaryFormat, const void *binary, GLsizei length); +GL_APICALL void GL_APIENTRY glProgramParameteri (GLuint program, GLenum pname, GLint value); +GL_APICALL void GL_APIENTRY glInvalidateFramebuffer (GLenum target, GLsizei numAttachments, const GLenum *attachments); +GL_APICALL void GL_APIENTRY glInvalidateSubFramebuffer (GLenum target, GLsizei numAttachments, const GLenum *attachments, GLint x, GLint y, GLsizei width, GLsizei height); +GL_APICALL void GL_APIENTRY glTexStorage2D (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); +GL_APICALL void GL_APIENTRY glTexStorage3D (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); +GL_APICALL void GL_APIENTRY glGetInternalformativ (GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint *params); +#endif +#endif /* GL_ES_VERSION_3_0 */ + +#ifndef GL_ES_VERSION_3_1 +#define GL_ES_VERSION_3_1 1 +#define GL_COMPUTE_SHADER 0x91B9 +#define GL_MAX_COMPUTE_UNIFORM_BLOCKS 0x91BB +#define GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS 0x91BC +#define GL_MAX_COMPUTE_IMAGE_UNIFORMS 0x91BD +#define GL_MAX_COMPUTE_SHARED_MEMORY_SIZE 0x8262 +#define GL_MAX_COMPUTE_UNIFORM_COMPONENTS 0x8263 +#define GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS 0x8264 +#define GL_MAX_COMPUTE_ATOMIC_COUNTERS 0x8265 +#define GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS 0x8266 +#define GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS 0x90EB +#define GL_MAX_COMPUTE_WORK_GROUP_COUNT 0x91BE +#define GL_MAX_COMPUTE_WORK_GROUP_SIZE 0x91BF +#define GL_COMPUTE_WORK_GROUP_SIZE 0x8267 +#define GL_DISPATCH_INDIRECT_BUFFER 0x90EE +#define GL_DISPATCH_INDIRECT_BUFFER_BINDING 0x90EF +#define GL_COMPUTE_SHADER_BIT 0x00000020 +#define GL_DRAW_INDIRECT_BUFFER 0x8F3F +#define GL_DRAW_INDIRECT_BUFFER_BINDING 0x8F43 +#define GL_MAX_UNIFORM_LOCATIONS 0x826E +#define GL_FRAMEBUFFER_DEFAULT_WIDTH 0x9310 +#define GL_FRAMEBUFFER_DEFAULT_HEIGHT 0x9311 +#define GL_FRAMEBUFFER_DEFAULT_SAMPLES 0x9313 +#define GL_FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS 0x9314 +#define GL_MAX_FRAMEBUFFER_WIDTH 0x9315 +#define GL_MAX_FRAMEBUFFER_HEIGHT 0x9316 +#define GL_MAX_FRAMEBUFFER_SAMPLES 0x9318 +#define GL_UNIFORM 0x92E1 +#define GL_UNIFORM_BLOCK 0x92E2 +#define GL_PROGRAM_INPUT 0x92E3 +#define GL_PROGRAM_OUTPUT 0x92E4 +#define GL_BUFFER_VARIABLE 0x92E5 +#define GL_SHADER_STORAGE_BLOCK 0x92E6 +#define GL_ATOMIC_COUNTER_BUFFER 0x92C0 +#define GL_TRANSFORM_FEEDBACK_VARYING 0x92F4 +#define GL_ACTIVE_RESOURCES 0x92F5 +#define GL_MAX_NAME_LENGTH 0x92F6 +#define GL_MAX_NUM_ACTIVE_VARIABLES 0x92F7 +#define GL_NAME_LENGTH 0x92F9 +#define GL_TYPE 0x92FA +#define GL_ARRAY_SIZE 0x92FB +#define GL_OFFSET 0x92FC +#define GL_BLOCK_INDEX 0x92FD +#define GL_ARRAY_STRIDE 0x92FE +#define GL_MATRIX_STRIDE 0x92FF +#define GL_IS_ROW_MAJOR 0x9300 +#define GL_ATOMIC_COUNTER_BUFFER_INDEX 0x9301 +#define GL_BUFFER_BINDING 0x9302 +#define GL_BUFFER_DATA_SIZE 0x9303 +#define GL_NUM_ACTIVE_VARIABLES 0x9304 +#define GL_ACTIVE_VARIABLES 0x9305 +#define GL_REFERENCED_BY_VERTEX_SHADER 0x9306 +#define GL_REFERENCED_BY_FRAGMENT_SHADER 0x930A +#define GL_REFERENCED_BY_COMPUTE_SHADER 0x930B +#define GL_TOP_LEVEL_ARRAY_SIZE 0x930C +#define GL_TOP_LEVEL_ARRAY_STRIDE 0x930D +#define GL_LOCATION 0x930E +#define GL_VERTEX_SHADER_BIT 0x00000001 +#define GL_FRAGMENT_SHADER_BIT 0x00000002 +#define GL_ALL_SHADER_BITS 0xFFFFFFFF +#define GL_PROGRAM_SEPARABLE 0x8258 +#define GL_ACTIVE_PROGRAM 0x8259 +#define GL_PROGRAM_PIPELINE_BINDING 0x825A +#define GL_ATOMIC_COUNTER_BUFFER_BINDING 0x92C1 +#define GL_ATOMIC_COUNTER_BUFFER_START 0x92C2 +#define GL_ATOMIC_COUNTER_BUFFER_SIZE 0x92C3 +#define GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS 0x92CC +#define GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS 0x92D0 +#define GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS 0x92D1 +#define GL_MAX_VERTEX_ATOMIC_COUNTERS 0x92D2 +#define GL_MAX_FRAGMENT_ATOMIC_COUNTERS 0x92D6 +#define GL_MAX_COMBINED_ATOMIC_COUNTERS 0x92D7 +#define GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE 0x92D8 +#define GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS 0x92DC +#define GL_ACTIVE_ATOMIC_COUNTER_BUFFERS 0x92D9 +#define GL_UNSIGNED_INT_ATOMIC_COUNTER 0x92DB +#define GL_MAX_IMAGE_UNITS 0x8F38 +#define GL_MAX_VERTEX_IMAGE_UNIFORMS 0x90CA +#define GL_MAX_FRAGMENT_IMAGE_UNIFORMS 0x90CE +#define GL_MAX_COMBINED_IMAGE_UNIFORMS 0x90CF +#define GL_IMAGE_BINDING_NAME 0x8F3A +#define GL_IMAGE_BINDING_LEVEL 0x8F3B +#define GL_IMAGE_BINDING_LAYERED 0x8F3C +#define GL_IMAGE_BINDING_LAYER 0x8F3D +#define GL_IMAGE_BINDING_ACCESS 0x8F3E +#define GL_IMAGE_BINDING_FORMAT 0x906E +#define GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT 0x00000001 +#define GL_ELEMENT_ARRAY_BARRIER_BIT 0x00000002 +#define GL_UNIFORM_BARRIER_BIT 0x00000004 +#define GL_TEXTURE_FETCH_BARRIER_BIT 0x00000008 +#define GL_SHADER_IMAGE_ACCESS_BARRIER_BIT 0x00000020 +#define GL_COMMAND_BARRIER_BIT 0x00000040 +#define GL_PIXEL_BUFFER_BARRIER_BIT 0x00000080 +#define GL_TEXTURE_UPDATE_BARRIER_BIT 0x00000100 +#define GL_BUFFER_UPDATE_BARRIER_BIT 0x00000200 +#define GL_FRAMEBUFFER_BARRIER_BIT 0x00000400 +#define GL_TRANSFORM_FEEDBACK_BARRIER_BIT 0x00000800 +#define GL_ATOMIC_COUNTER_BARRIER_BIT 0x00001000 +#define GL_ALL_BARRIER_BITS 0xFFFFFFFF +#define GL_IMAGE_2D 0x904D +#define GL_IMAGE_3D 0x904E +#define GL_IMAGE_CUBE 0x9050 +#define GL_IMAGE_2D_ARRAY 0x9053 +#define GL_INT_IMAGE_2D 0x9058 +#define GL_INT_IMAGE_3D 0x9059 +#define GL_INT_IMAGE_CUBE 0x905B +#define GL_INT_IMAGE_2D_ARRAY 0x905E +#define GL_UNSIGNED_INT_IMAGE_2D 0x9063 +#define GL_UNSIGNED_INT_IMAGE_3D 0x9064 +#define GL_UNSIGNED_INT_IMAGE_CUBE 0x9066 +#define GL_UNSIGNED_INT_IMAGE_2D_ARRAY 0x9069 +#define GL_IMAGE_FORMAT_COMPATIBILITY_TYPE 0x90C7 +#define GL_IMAGE_FORMAT_COMPATIBILITY_BY_SIZE 0x90C8 +#define GL_IMAGE_FORMAT_COMPATIBILITY_BY_CLASS 0x90C9 +#define GL_READ_ONLY 0x88B8 +#define GL_WRITE_ONLY 0x88B9 +#define GL_READ_WRITE 0x88BA +#define GL_SHADER_STORAGE_BUFFER 0x90D2 +#define GL_SHADER_STORAGE_BUFFER_BINDING 0x90D3 +#define GL_SHADER_STORAGE_BUFFER_START 0x90D4 +#define GL_SHADER_STORAGE_BUFFER_SIZE 0x90D5 +#define GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS 0x90D6 +#define GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS 0x90DA +#define GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS 0x90DB +#define GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS 0x90DC +#define GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS 0x90DD +#define GL_MAX_SHADER_STORAGE_BLOCK_SIZE 0x90DE +#define GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT 0x90DF +#define GL_SHADER_STORAGE_BARRIER_BIT 0x00002000 +#define GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES 0x8F39 +#define GL_DEPTH_STENCIL_TEXTURE_MODE 0x90EA +#define GL_STENCIL_INDEX 0x1901 +#define GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET 0x8E5E +#define GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET 0x8E5F +#define GL_SAMPLE_POSITION 0x8E50 +#define GL_SAMPLE_MASK 0x8E51 +#define GL_SAMPLE_MASK_VALUE 0x8E52 +#define GL_TEXTURE_2D_MULTISAMPLE 0x9100 +#define GL_MAX_SAMPLE_MASK_WORDS 0x8E59 +#define GL_MAX_COLOR_TEXTURE_SAMPLES 0x910E +#define GL_MAX_DEPTH_TEXTURE_SAMPLES 0x910F +#define GL_MAX_INTEGER_SAMPLES 0x9110 +#define GL_TEXTURE_BINDING_2D_MULTISAMPLE 0x9104 +#define GL_TEXTURE_SAMPLES 0x9106 +#define GL_TEXTURE_FIXED_SAMPLE_LOCATIONS 0x9107 +#define GL_TEXTURE_WIDTH 0x1000 +#define GL_TEXTURE_HEIGHT 0x1001 +#define GL_TEXTURE_DEPTH 0x8071 +#define GL_TEXTURE_INTERNAL_FORMAT 0x1003 +#define GL_TEXTURE_RED_SIZE 0x805C +#define GL_TEXTURE_GREEN_SIZE 0x805D +#define GL_TEXTURE_BLUE_SIZE 0x805E +#define GL_TEXTURE_ALPHA_SIZE 0x805F +#define GL_TEXTURE_DEPTH_SIZE 0x884A +#define GL_TEXTURE_STENCIL_SIZE 0x88F1 +#define GL_TEXTURE_SHARED_SIZE 0x8C3F +#define GL_TEXTURE_RED_TYPE 0x8C10 +#define GL_TEXTURE_GREEN_TYPE 0x8C11 +#define GL_TEXTURE_BLUE_TYPE 0x8C12 +#define GL_TEXTURE_ALPHA_TYPE 0x8C13 +#define GL_TEXTURE_DEPTH_TYPE 0x8C16 +#define GL_TEXTURE_COMPRESSED 0x86A1 +#define GL_SAMPLER_2D_MULTISAMPLE 0x9108 +#define GL_INT_SAMPLER_2D_MULTISAMPLE 0x9109 +#define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE 0x910A +#define GL_VERTEX_ATTRIB_BINDING 0x82D4 +#define GL_VERTEX_ATTRIB_RELATIVE_OFFSET 0x82D5 +#define GL_VERTEX_BINDING_DIVISOR 0x82D6 +#define GL_VERTEX_BINDING_OFFSET 0x82D7 +#define GL_VERTEX_BINDING_STRIDE 0x82D8 +#define GL_VERTEX_BINDING_BUFFER 0x8F4F +#define GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET 0x82D9 +#define GL_MAX_VERTEX_ATTRIB_BINDINGS 0x82DA +#define GL_MAX_VERTEX_ATTRIB_STRIDE 0x82E5 +typedef void (GL_APIENTRYP PFNGLDISPATCHCOMPUTEPROC) (GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z); +typedef void (GL_APIENTRYP PFNGLDISPATCHCOMPUTEINDIRECTPROC) (GLintptr indirect); +typedef void (GL_APIENTRYP PFNGLDRAWARRAYSINDIRECTPROC) (GLenum mode, const void *indirect); +typedef void (GL_APIENTRYP PFNGLDRAWELEMENTSINDIRECTPROC) (GLenum mode, GLenum type, const void *indirect); +typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERPARAMETERIPROC) (GLenum target, GLenum pname, GLint param); +typedef void (GL_APIENTRYP PFNGLGETFRAMEBUFFERPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (GL_APIENTRYP PFNGLGETPROGRAMINTERFACEIVPROC) (GLuint program, GLenum programInterface, GLenum pname, GLint *params); +typedef GLuint (GL_APIENTRYP PFNGLGETPROGRAMRESOURCEINDEXPROC) (GLuint program, GLenum programInterface, const GLchar *name); +typedef void (GL_APIENTRYP PFNGLGETPROGRAMRESOURCENAMEPROC) (GLuint program, GLenum programInterface, GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name); +typedef void (GL_APIENTRYP PFNGLGETPROGRAMRESOURCEIVPROC) (GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum *props, GLsizei bufSize, GLsizei *length, GLint *params); +typedef GLint (GL_APIENTRYP PFNGLGETPROGRAMRESOURCELOCATIONPROC) (GLuint program, GLenum programInterface, const GLchar *name); +typedef void (GL_APIENTRYP PFNGLUSEPROGRAMSTAGESPROC) (GLuint pipeline, GLbitfield stages, GLuint program); +typedef void (GL_APIENTRYP PFNGLACTIVESHADERPROGRAMPROC) (GLuint pipeline, GLuint program); +typedef GLuint (GL_APIENTRYP PFNGLCREATESHADERPROGRAMVPROC) (GLenum type, GLsizei count, const GLchar *const*strings); +typedef void (GL_APIENTRYP PFNGLBINDPROGRAMPIPELINEPROC) (GLuint pipeline); +typedef void (GL_APIENTRYP PFNGLDELETEPROGRAMPIPELINESPROC) (GLsizei n, const GLuint *pipelines); +typedef void (GL_APIENTRYP PFNGLGENPROGRAMPIPELINESPROC) (GLsizei n, GLuint *pipelines); +typedef GLboolean (GL_APIENTRYP PFNGLISPROGRAMPIPELINEPROC) (GLuint pipeline); +typedef void (GL_APIENTRYP PFNGLGETPROGRAMPIPELINEIVPROC) (GLuint pipeline, GLenum pname, GLint *params); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM1IPROC) (GLuint program, GLint location, GLint v0); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM2IPROC) (GLuint program, GLint location, GLint v0, GLint v1); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM3IPROC) (GLuint program, GLint location, GLint v0, GLint v1, GLint v2); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM4IPROC) (GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM1UIPROC) (GLuint program, GLint location, GLuint v0); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM2UIPROC) (GLuint program, GLint location, GLuint v0, GLuint v1); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM3UIPROC) (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM4UIPROC) (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM1FPROC) (GLuint program, GLint location, GLfloat v0); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM2FPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM3FPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM4FPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM1IVPROC) (GLuint program, GLint location, GLsizei count, const GLint *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM2IVPROC) (GLuint program, GLint location, GLsizei count, const GLint *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM3IVPROC) (GLuint program, GLint location, GLsizei count, const GLint *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM4IVPROC) (GLuint program, GLint location, GLsizei count, const GLint *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM1UIVPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM2UIVPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM3UIVPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM4UIVPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM1FVPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM2FVPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM3FVPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM4FVPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2X3FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3X2FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2X4FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4X2FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3X4FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4X3FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLVALIDATEPROGRAMPIPELINEPROC) (GLuint pipeline); +typedef void (GL_APIENTRYP PFNGLGETPROGRAMPIPELINEINFOLOGPROC) (GLuint pipeline, GLsizei bufSize, GLsizei *length, GLchar *infoLog); +typedef void (GL_APIENTRYP PFNGLBINDIMAGETEXTUREPROC) (GLuint unit, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLenum format); +typedef void (GL_APIENTRYP PFNGLGETBOOLEANI_VPROC) (GLenum target, GLuint index, GLboolean *data); +typedef void (GL_APIENTRYP PFNGLMEMORYBARRIERPROC) (GLbitfield barriers); +typedef void (GL_APIENTRYP PFNGLMEMORYBARRIERBYREGIONPROC) (GLbitfield barriers); +typedef void (GL_APIENTRYP PFNGLTEXSTORAGE2DMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations); +typedef void (GL_APIENTRYP PFNGLGETMULTISAMPLEFVPROC) (GLenum pname, GLuint index, GLfloat *val); +typedef void (GL_APIENTRYP PFNGLSAMPLEMASKIPROC) (GLuint maskNumber, GLbitfield mask); +typedef void (GL_APIENTRYP PFNGLGETTEXLEVELPARAMETERIVPROC) (GLenum target, GLint level, GLenum pname, GLint *params); +typedef void (GL_APIENTRYP PFNGLGETTEXLEVELPARAMETERFVPROC) (GLenum target, GLint level, GLenum pname, GLfloat *params); +typedef void (GL_APIENTRYP PFNGLBINDVERTEXBUFFERPROC) (GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride); +typedef void (GL_APIENTRYP PFNGLVERTEXATTRIBFORMATPROC) (GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset); +typedef void (GL_APIENTRYP PFNGLVERTEXATTRIBIFORMATPROC) (GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); +typedef void (GL_APIENTRYP PFNGLVERTEXATTRIBBINDINGPROC) (GLuint attribindex, GLuint bindingindex); +typedef void (GL_APIENTRYP PFNGLVERTEXBINDINGDIVISORPROC) (GLuint bindingindex, GLuint divisor); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glDispatchCompute (GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z); +GL_APICALL void GL_APIENTRY glDispatchComputeIndirect (GLintptr indirect); +GL_APICALL void GL_APIENTRY glDrawArraysIndirect (GLenum mode, const void *indirect); +GL_APICALL void GL_APIENTRY glDrawElementsIndirect (GLenum mode, GLenum type, const void *indirect); +GL_APICALL void GL_APIENTRY glFramebufferParameteri (GLenum target, GLenum pname, GLint param); +GL_APICALL void GL_APIENTRY glGetFramebufferParameteriv (GLenum target, GLenum pname, GLint *params); +GL_APICALL void GL_APIENTRY glGetProgramInterfaceiv (GLuint program, GLenum programInterface, GLenum pname, GLint *params); +GL_APICALL GLuint GL_APIENTRY glGetProgramResourceIndex (GLuint program, GLenum programInterface, const GLchar *name); +GL_APICALL void GL_APIENTRY glGetProgramResourceName (GLuint program, GLenum programInterface, GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name); +GL_APICALL void GL_APIENTRY glGetProgramResourceiv (GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum *props, GLsizei bufSize, GLsizei *length, GLint *params); +GL_APICALL GLint GL_APIENTRY glGetProgramResourceLocation (GLuint program, GLenum programInterface, const GLchar *name); +GL_APICALL void GL_APIENTRY glUseProgramStages (GLuint pipeline, GLbitfield stages, GLuint program); +GL_APICALL void GL_APIENTRY glActiveShaderProgram (GLuint pipeline, GLuint program); +GL_APICALL GLuint GL_APIENTRY glCreateShaderProgramv (GLenum type, GLsizei count, const GLchar *const*strings); +GL_APICALL void GL_APIENTRY glBindProgramPipeline (GLuint pipeline); +GL_APICALL void GL_APIENTRY glDeleteProgramPipelines (GLsizei n, const GLuint *pipelines); +GL_APICALL void GL_APIENTRY glGenProgramPipelines (GLsizei n, GLuint *pipelines); +GL_APICALL GLboolean GL_APIENTRY glIsProgramPipeline (GLuint pipeline); +GL_APICALL void GL_APIENTRY glGetProgramPipelineiv (GLuint pipeline, GLenum pname, GLint *params); +GL_APICALL void GL_APIENTRY glProgramUniform1i (GLuint program, GLint location, GLint v0); +GL_APICALL void GL_APIENTRY glProgramUniform2i (GLuint program, GLint location, GLint v0, GLint v1); +GL_APICALL void GL_APIENTRY glProgramUniform3i (GLuint program, GLint location, GLint v0, GLint v1, GLint v2); +GL_APICALL void GL_APIENTRY glProgramUniform4i (GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3); +GL_APICALL void GL_APIENTRY glProgramUniform1ui (GLuint program, GLint location, GLuint v0); +GL_APICALL void GL_APIENTRY glProgramUniform2ui (GLuint program, GLint location, GLuint v0, GLuint v1); +GL_APICALL void GL_APIENTRY glProgramUniform3ui (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2); +GL_APICALL void GL_APIENTRY glProgramUniform4ui (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); +GL_APICALL void GL_APIENTRY glProgramUniform1f (GLuint program, GLint location, GLfloat v0); +GL_APICALL void GL_APIENTRY glProgramUniform2f (GLuint program, GLint location, GLfloat v0, GLfloat v1); +GL_APICALL void GL_APIENTRY glProgramUniform3f (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2); +GL_APICALL void GL_APIENTRY glProgramUniform4f (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); +GL_APICALL void GL_APIENTRY glProgramUniform1iv (GLuint program, GLint location, GLsizei count, const GLint *value); +GL_APICALL void GL_APIENTRY glProgramUniform2iv (GLuint program, GLint location, GLsizei count, const GLint *value); +GL_APICALL void GL_APIENTRY glProgramUniform3iv (GLuint program, GLint location, GLsizei count, const GLint *value); +GL_APICALL void GL_APIENTRY glProgramUniform4iv (GLuint program, GLint location, GLsizei count, const GLint *value); +GL_APICALL void GL_APIENTRY glProgramUniform1uiv (GLuint program, GLint location, GLsizei count, const GLuint *value); +GL_APICALL void GL_APIENTRY glProgramUniform2uiv (GLuint program, GLint location, GLsizei count, const GLuint *value); +GL_APICALL void GL_APIENTRY glProgramUniform3uiv (GLuint program, GLint location, GLsizei count, const GLuint *value); +GL_APICALL void GL_APIENTRY glProgramUniform4uiv (GLuint program, GLint location, GLsizei count, const GLuint *value); +GL_APICALL void GL_APIENTRY glProgramUniform1fv (GLuint program, GLint location, GLsizei count, const GLfloat *value); +GL_APICALL void GL_APIENTRY glProgramUniform2fv (GLuint program, GLint location, GLsizei count, const GLfloat *value); +GL_APICALL void GL_APIENTRY glProgramUniform3fv (GLuint program, GLint location, GLsizei count, const GLfloat *value); +GL_APICALL void GL_APIENTRY glProgramUniform4fv (GLuint program, GLint location, GLsizei count, const GLfloat *value); +GL_APICALL void GL_APIENTRY glProgramUniformMatrix2fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GL_APICALL void GL_APIENTRY glProgramUniformMatrix3fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GL_APICALL void GL_APIENTRY glProgramUniformMatrix4fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GL_APICALL void GL_APIENTRY glProgramUniformMatrix2x3fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GL_APICALL void GL_APIENTRY glProgramUniformMatrix3x2fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GL_APICALL void GL_APIENTRY glProgramUniformMatrix2x4fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GL_APICALL void GL_APIENTRY glProgramUniformMatrix4x2fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GL_APICALL void GL_APIENTRY glProgramUniformMatrix3x4fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GL_APICALL void GL_APIENTRY glProgramUniformMatrix4x3fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GL_APICALL void GL_APIENTRY glValidateProgramPipeline (GLuint pipeline); +GL_APICALL void GL_APIENTRY glGetProgramPipelineInfoLog (GLuint pipeline, GLsizei bufSize, GLsizei *length, GLchar *infoLog); +GL_APICALL void GL_APIENTRY glBindImageTexture (GLuint unit, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLenum format); +GL_APICALL void GL_APIENTRY glGetBooleani_v (GLenum target, GLuint index, GLboolean *data); +GL_APICALL void GL_APIENTRY glMemoryBarrier (GLbitfield barriers); +GL_APICALL void GL_APIENTRY glMemoryBarrierByRegion (GLbitfield barriers); +GL_APICALL void GL_APIENTRY glTexStorage2DMultisample (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations); +GL_APICALL void GL_APIENTRY glGetMultisamplefv (GLenum pname, GLuint index, GLfloat *val); +GL_APICALL void GL_APIENTRY glSampleMaski (GLuint maskNumber, GLbitfield mask); +GL_APICALL void GL_APIENTRY glGetTexLevelParameteriv (GLenum target, GLint level, GLenum pname, GLint *params); +GL_APICALL void GL_APIENTRY glGetTexLevelParameterfv (GLenum target, GLint level, GLenum pname, GLfloat *params); +GL_APICALL void GL_APIENTRY glBindVertexBuffer (GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride); +GL_APICALL void GL_APIENTRY glVertexAttribFormat (GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset); +GL_APICALL void GL_APIENTRY glVertexAttribIFormat (GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); +GL_APICALL void GL_APIENTRY glVertexAttribBinding (GLuint attribindex, GLuint bindingindex); +GL_APICALL void GL_APIENTRY glVertexBindingDivisor (GLuint bindingindex, GLuint divisor); +#endif +#endif /* GL_ES_VERSION_3_1 */ + +#ifndef GL_ES_VERSION_3_2 +#define GL_ES_VERSION_3_2 1 +typedef void (GL_APIENTRY *GLDEBUGPROC)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,const void *userParam); +#define GL_MULTISAMPLE_LINE_WIDTH_RANGE 0x9381 +#define GL_MULTISAMPLE_LINE_WIDTH_GRANULARITY 0x9382 +#define GL_MULTIPLY 0x9294 +#define GL_SCREEN 0x9295 +#define GL_OVERLAY 0x9296 +#define GL_DARKEN 0x9297 +#define GL_LIGHTEN 0x9298 +#define GL_COLORDODGE 0x9299 +#define GL_COLORBURN 0x929A +#define GL_HARDLIGHT 0x929B +#define GL_SOFTLIGHT 0x929C +#define GL_DIFFERENCE 0x929E +#define GL_EXCLUSION 0x92A0 +#define GL_HSL_HUE 0x92AD +#define GL_HSL_SATURATION 0x92AE +#define GL_HSL_COLOR 0x92AF +#define GL_HSL_LUMINOSITY 0x92B0 +#define GL_DEBUG_OUTPUT_SYNCHRONOUS 0x8242 +#define GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH 0x8243 +#define GL_DEBUG_CALLBACK_FUNCTION 0x8244 +#define GL_DEBUG_CALLBACK_USER_PARAM 0x8245 +#define GL_DEBUG_SOURCE_API 0x8246 +#define GL_DEBUG_SOURCE_WINDOW_SYSTEM 0x8247 +#define GL_DEBUG_SOURCE_SHADER_COMPILER 0x8248 +#define GL_DEBUG_SOURCE_THIRD_PARTY 0x8249 +#define GL_DEBUG_SOURCE_APPLICATION 0x824A +#define GL_DEBUG_SOURCE_OTHER 0x824B +#define GL_DEBUG_TYPE_ERROR 0x824C +#define GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR 0x824D +#define GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR 0x824E +#define GL_DEBUG_TYPE_PORTABILITY 0x824F +#define GL_DEBUG_TYPE_PERFORMANCE 0x8250 +#define GL_DEBUG_TYPE_OTHER 0x8251 +#define GL_DEBUG_TYPE_MARKER 0x8268 +#define GL_DEBUG_TYPE_PUSH_GROUP 0x8269 +#define GL_DEBUG_TYPE_POP_GROUP 0x826A +#define GL_DEBUG_SEVERITY_NOTIFICATION 0x826B +#define GL_MAX_DEBUG_GROUP_STACK_DEPTH 0x826C +#define GL_DEBUG_GROUP_STACK_DEPTH 0x826D +#define GL_BUFFER 0x82E0 +#define GL_SHADER 0x82E1 +#define GL_PROGRAM 0x82E2 +#define GL_VERTEX_ARRAY 0x8074 +#define GL_QUERY 0x82E3 +#define GL_PROGRAM_PIPELINE 0x82E4 +#define GL_SAMPLER 0x82E6 +#define GL_MAX_LABEL_LENGTH 0x82E8 +#define GL_MAX_DEBUG_MESSAGE_LENGTH 0x9143 +#define GL_MAX_DEBUG_LOGGED_MESSAGES 0x9144 +#define GL_DEBUG_LOGGED_MESSAGES 0x9145 +#define GL_DEBUG_SEVERITY_HIGH 0x9146 +#define GL_DEBUG_SEVERITY_MEDIUM 0x9147 +#define GL_DEBUG_SEVERITY_LOW 0x9148 +#define GL_DEBUG_OUTPUT 0x92E0 +#define GL_CONTEXT_FLAG_DEBUG_BIT 0x00000002 +#define GL_STACK_OVERFLOW 0x0503 +#define GL_STACK_UNDERFLOW 0x0504 +#define GL_GEOMETRY_SHADER 0x8DD9 +#define GL_GEOMETRY_SHADER_BIT 0x00000004 +#define GL_GEOMETRY_VERTICES_OUT 0x8916 +#define GL_GEOMETRY_INPUT_TYPE 0x8917 +#define GL_GEOMETRY_OUTPUT_TYPE 0x8918 +#define GL_GEOMETRY_SHADER_INVOCATIONS 0x887F +#define GL_LAYER_PROVOKING_VERTEX 0x825E +#define GL_LINES_ADJACENCY 0x000A +#define GL_LINE_STRIP_ADJACENCY 0x000B +#define GL_TRIANGLES_ADJACENCY 0x000C +#define GL_TRIANGLE_STRIP_ADJACENCY 0x000D +#define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS 0x8DDF +#define GL_MAX_GEOMETRY_UNIFORM_BLOCKS 0x8A2C +#define GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS 0x8A32 +#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_TOTAL_OUTPUT_COMPONENTS 0x8DE1 +#define GL_MAX_GEOMETRY_SHADER_INVOCATIONS 0x8E5A +#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS 0x8C29 +#define GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS 0x92CF +#define GL_MAX_GEOMETRY_ATOMIC_COUNTERS 0x92D5 +#define GL_MAX_GEOMETRY_IMAGE_UNIFORMS 0x90CD +#define GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS 0x90D7 +#define GL_FIRST_VERTEX_CONVENTION 0x8E4D +#define GL_LAST_VERTEX_CONVENTION 0x8E4E +#define GL_UNDEFINED_VERTEX 0x8260 +#define GL_PRIMITIVES_GENERATED 0x8C87 +#define GL_FRAMEBUFFER_DEFAULT_LAYERS 0x9312 +#define GL_MAX_FRAMEBUFFER_LAYERS 0x9317 +#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS 0x8DA8 +#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED 0x8DA7 +#define GL_REFERENCED_BY_GEOMETRY_SHADER 0x9309 +#define GL_PRIMITIVE_BOUNDING_BOX 0x92BE +#define GL_CONTEXT_FLAG_ROBUST_ACCESS_BIT 0x00000004 +#define GL_CONTEXT_FLAGS 0x821E +#define GL_LOSE_CONTEXT_ON_RESET 0x8252 +#define GL_GUILTY_CONTEXT_RESET 0x8253 +#define GL_INNOCENT_CONTEXT_RESET 0x8254 +#define GL_UNKNOWN_CONTEXT_RESET 0x8255 +#define GL_RESET_NOTIFICATION_STRATEGY 0x8256 +#define GL_NO_RESET_NOTIFICATION 0x8261 +#define GL_CONTEXT_LOST 0x0507 +#define GL_SAMPLE_SHADING 0x8C36 +#define GL_MIN_SAMPLE_SHADING_VALUE 0x8C37 +#define GL_MIN_FRAGMENT_INTERPOLATION_OFFSET 0x8E5B +#define GL_MAX_FRAGMENT_INTERPOLATION_OFFSET 0x8E5C +#define GL_FRAGMENT_INTERPOLATION_OFFSET_BITS 0x8E5D +#define GL_PATCHES 0x000E +#define GL_PATCH_VERTICES 0x8E72 +#define GL_TESS_CONTROL_OUTPUT_VERTICES 0x8E75 +#define GL_TESS_GEN_MODE 0x8E76 +#define GL_TESS_GEN_SPACING 0x8E77 +#define GL_TESS_GEN_VERTEX_ORDER 0x8E78 +#define GL_TESS_GEN_POINT_MODE 0x8E79 +#define GL_ISOLINES 0x8E7A +#define GL_QUADS 0x0007 +#define GL_FRACTIONAL_ODD 0x8E7B +#define GL_FRACTIONAL_EVEN 0x8E7C +#define GL_MAX_PATCH_VERTICES 0x8E7D +#define GL_MAX_TESS_GEN_LEVEL 0x8E7E +#define GL_MAX_TESS_CONTROL_UNIFORM_COMPONENTS 0x8E7F +#define GL_MAX_TESS_EVALUATION_UNIFORM_COMPONENTS 0x8E80 +#define GL_MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS 0x8E81 +#define GL_MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS 0x8E82 +#define GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS 0x8E83 +#define GL_MAX_TESS_PATCH_COMPONENTS 0x8E84 +#define GL_MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS 0x8E85 +#define GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS 0x8E86 +#define GL_MAX_TESS_CONTROL_UNIFORM_BLOCKS 0x8E89 +#define GL_MAX_TESS_EVALUATION_UNIFORM_BLOCKS 0x8E8A +#define GL_MAX_TESS_CONTROL_INPUT_COMPONENTS 0x886C +#define GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS 0x886D +#define GL_MAX_COMBINED_TESS_CONTROL_UNIFORM_COMPONENTS 0x8E1E +#define GL_MAX_COMBINED_TESS_EVALUATION_UNIFORM_COMPONENTS 0x8E1F +#define GL_MAX_TESS_CONTROL_ATOMIC_COUNTER_BUFFERS 0x92CD +#define GL_MAX_TESS_EVALUATION_ATOMIC_COUNTER_BUFFERS 0x92CE +#define GL_MAX_TESS_CONTROL_ATOMIC_COUNTERS 0x92D3 +#define GL_MAX_TESS_EVALUATION_ATOMIC_COUNTERS 0x92D4 +#define GL_MAX_TESS_CONTROL_IMAGE_UNIFORMS 0x90CB +#define GL_MAX_TESS_EVALUATION_IMAGE_UNIFORMS 0x90CC +#define GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS 0x90D8 +#define GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS 0x90D9 +#define GL_PRIMITIVE_RESTART_FOR_PATCHES_SUPPORTED 0x8221 +#define GL_IS_PER_PATCH 0x92E7 +#define GL_REFERENCED_BY_TESS_CONTROL_SHADER 0x9307 +#define GL_REFERENCED_BY_TESS_EVALUATION_SHADER 0x9308 +#define GL_TESS_CONTROL_SHADER 0x8E88 +#define GL_TESS_EVALUATION_SHADER 0x8E87 +#define GL_TESS_CONTROL_SHADER_BIT 0x00000008 +#define GL_TESS_EVALUATION_SHADER_BIT 0x00000010 +#define GL_TEXTURE_BORDER_COLOR 0x1004 +#define GL_CLAMP_TO_BORDER 0x812D +#define GL_TEXTURE_BUFFER 0x8C2A +#define GL_TEXTURE_BUFFER_BINDING 0x8C2A +#define GL_MAX_TEXTURE_BUFFER_SIZE 0x8C2B +#define GL_TEXTURE_BINDING_BUFFER 0x8C2C +#define GL_TEXTURE_BUFFER_DATA_STORE_BINDING 0x8C2D +#define GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT 0x919F +#define GL_SAMPLER_BUFFER 0x8DC2 +#define GL_INT_SAMPLER_BUFFER 0x8DD0 +#define GL_UNSIGNED_INT_SAMPLER_BUFFER 0x8DD8 +#define GL_IMAGE_BUFFER 0x9051 +#define GL_INT_IMAGE_BUFFER 0x905C +#define GL_UNSIGNED_INT_IMAGE_BUFFER 0x9067 +#define GL_TEXTURE_BUFFER_OFFSET 0x919D +#define GL_TEXTURE_BUFFER_SIZE 0x919E +#define GL_COMPRESSED_RGBA_ASTC_4x4 0x93B0 +#define GL_COMPRESSED_RGBA_ASTC_5x4 0x93B1 +#define GL_COMPRESSED_RGBA_ASTC_5x5 0x93B2 +#define GL_COMPRESSED_RGBA_ASTC_6x5 0x93B3 +#define GL_COMPRESSED_RGBA_ASTC_6x6 0x93B4 +#define GL_COMPRESSED_RGBA_ASTC_8x5 0x93B5 +#define GL_COMPRESSED_RGBA_ASTC_8x6 0x93B6 +#define GL_COMPRESSED_RGBA_ASTC_8x8 0x93B7 +#define GL_COMPRESSED_RGBA_ASTC_10x5 0x93B8 +#define GL_COMPRESSED_RGBA_ASTC_10x6 0x93B9 +#define GL_COMPRESSED_RGBA_ASTC_10x8 0x93BA +#define GL_COMPRESSED_RGBA_ASTC_10x10 0x93BB +#define GL_COMPRESSED_RGBA_ASTC_12x10 0x93BC +#define GL_COMPRESSED_RGBA_ASTC_12x12 0x93BD +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4 0x93D0 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4 0x93D1 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5 0x93D2 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5 0x93D3 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6 0x93D4 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5 0x93D5 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6 0x93D6 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8 0x93D7 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5 0x93D8 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6 0x93D9 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8 0x93DA +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10 0x93DB +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10 0x93DC +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12 0x93DD +#define GL_TEXTURE_CUBE_MAP_ARRAY 0x9009 +#define GL_TEXTURE_BINDING_CUBE_MAP_ARRAY 0x900A +#define GL_SAMPLER_CUBE_MAP_ARRAY 0x900C +#define GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW 0x900D +#define GL_INT_SAMPLER_CUBE_MAP_ARRAY 0x900E +#define GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY 0x900F +#define GL_IMAGE_CUBE_MAP_ARRAY 0x9054 +#define GL_INT_IMAGE_CUBE_MAP_ARRAY 0x905F +#define GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY 0x906A +#define GL_TEXTURE_2D_MULTISAMPLE_ARRAY 0x9102 +#define GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY 0x9105 +#define GL_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910B +#define GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910C +#define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910D +typedef void (GL_APIENTRYP PFNGLBLENDBARRIERPROC) (void); +typedef void (GL_APIENTRYP PFNGLCOPYIMAGESUBDATAPROC) (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); +typedef void (GL_APIENTRYP PFNGLDEBUGMESSAGECONTROLPROC) (GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled); +typedef void (GL_APIENTRYP PFNGLDEBUGMESSAGEINSERTPROC) (GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *buf); +typedef void (GL_APIENTRYP PFNGLDEBUGMESSAGECALLBACKPROC) (GLDEBUGPROC callback, const void *userParam); +typedef GLuint (GL_APIENTRYP PFNGLGETDEBUGMESSAGELOGPROC) (GLuint count, GLsizei bufSize, GLenum *sources, GLenum *types, GLuint *ids, GLenum *severities, GLsizei *lengths, GLchar *messageLog); +typedef void (GL_APIENTRYP PFNGLPUSHDEBUGGROUPPROC) (GLenum source, GLuint id, GLsizei length, const GLchar *message); +typedef void (GL_APIENTRYP PFNGLPOPDEBUGGROUPPROC) (void); +typedef void (GL_APIENTRYP PFNGLOBJECTLABELPROC) (GLenum identifier, GLuint name, GLsizei length, const GLchar *label); +typedef void (GL_APIENTRYP PFNGLGETOBJECTLABELPROC) (GLenum identifier, GLuint name, GLsizei bufSize, GLsizei *length, GLchar *label); +typedef void (GL_APIENTRYP PFNGLOBJECTPTRLABELPROC) (const void *ptr, GLsizei length, const GLchar *label); +typedef void (GL_APIENTRYP PFNGLGETOBJECTPTRLABELPROC) (const void *ptr, GLsizei bufSize, GLsizei *length, GLchar *label); +typedef void (GL_APIENTRYP PFNGLGETPOINTERVPROC) (GLenum pname, void **params); +typedef void (GL_APIENTRYP PFNGLENABLEIPROC) (GLenum target, GLuint index); +typedef void (GL_APIENTRYP PFNGLDISABLEIPROC) (GLenum target, GLuint index); +typedef void (GL_APIENTRYP PFNGLBLENDEQUATIONIPROC) (GLuint buf, GLenum mode); +typedef void (GL_APIENTRYP PFNGLBLENDEQUATIONSEPARATEIPROC) (GLuint buf, GLenum modeRGB, GLenum modeAlpha); +typedef void (GL_APIENTRYP PFNGLBLENDFUNCIPROC) (GLuint buf, GLenum src, GLenum dst); +typedef void (GL_APIENTRYP PFNGLBLENDFUNCSEPARATEIPROC) (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha); +typedef void (GL_APIENTRYP PFNGLCOLORMASKIPROC) (GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a); +typedef GLboolean (GL_APIENTRYP PFNGLISENABLEDIPROC) (GLenum target, GLuint index); +typedef void (GL_APIENTRYP PFNGLDRAWELEMENTSBASEVERTEXPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLint basevertex); +typedef void (GL_APIENTRYP PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices, GLint basevertex); +typedef void (GL_APIENTRYP PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLint basevertex); +typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERTEXTUREPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level); +typedef void (GL_APIENTRYP PFNGLPRIMITIVEBOUNDINGBOXPROC) (GLfloat minX, GLfloat minY, GLfloat minZ, GLfloat minW, GLfloat maxX, GLfloat maxY, GLfloat maxZ, GLfloat maxW); +typedef GLenum (GL_APIENTRYP PFNGLGETGRAPHICSRESETSTATUSPROC) (void); +typedef void (GL_APIENTRYP PFNGLREADNPIXELSPROC) (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, void *data); +typedef void (GL_APIENTRYP PFNGLGETNUNIFORMFVPROC) (GLuint program, GLint location, GLsizei bufSize, GLfloat *params); +typedef void (GL_APIENTRYP PFNGLGETNUNIFORMIVPROC) (GLuint program, GLint location, GLsizei bufSize, GLint *params); +typedef void (GL_APIENTRYP PFNGLGETNUNIFORMUIVPROC) (GLuint program, GLint location, GLsizei bufSize, GLuint *params); +typedef void (GL_APIENTRYP PFNGLMINSAMPLESHADINGPROC) (GLfloat value); +typedef void (GL_APIENTRYP PFNGLPATCHPARAMETERIPROC) (GLenum pname, GLint value); +typedef void (GL_APIENTRYP PFNGLTEXPARAMETERIIVPROC) (GLenum target, GLenum pname, const GLint *params); +typedef void (GL_APIENTRYP PFNGLTEXPARAMETERIUIVPROC) (GLenum target, GLenum pname, const GLuint *params); +typedef void (GL_APIENTRYP PFNGLGETTEXPARAMETERIIVPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (GL_APIENTRYP PFNGLGETTEXPARAMETERIUIVPROC) (GLenum target, GLenum pname, GLuint *params); +typedef void (GL_APIENTRYP PFNGLSAMPLERPARAMETERIIVPROC) (GLuint sampler, GLenum pname, const GLint *param); +typedef void (GL_APIENTRYP PFNGLSAMPLERPARAMETERIUIVPROC) (GLuint sampler, GLenum pname, const GLuint *param); +typedef void (GL_APIENTRYP PFNGLGETSAMPLERPARAMETERIIVPROC) (GLuint sampler, GLenum pname, GLint *params); +typedef void (GL_APIENTRYP PFNGLGETSAMPLERPARAMETERIUIVPROC) (GLuint sampler, GLenum pname, GLuint *params); +typedef void (GL_APIENTRYP PFNGLTEXBUFFERPROC) (GLenum target, GLenum internalformat, GLuint buffer); +typedef void (GL_APIENTRYP PFNGLTEXBUFFERRANGEPROC) (GLenum target, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size); +typedef void (GL_APIENTRYP PFNGLTEXSTORAGE3DMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glBlendBarrier (void); +GL_APICALL void GL_APIENTRY glCopyImageSubData (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_APICALL void GL_APIENTRY glDebugMessageControl (GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled); +GL_APICALL void GL_APIENTRY glDebugMessageInsert (GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *buf); +GL_APICALL void GL_APIENTRY glDebugMessageCallback (GLDEBUGPROC callback, const void *userParam); +GL_APICALL GLuint GL_APIENTRY glGetDebugMessageLog (GLuint count, GLsizei bufSize, GLenum *sources, GLenum *types, GLuint *ids, GLenum *severities, GLsizei *lengths, GLchar *messageLog); +GL_APICALL void GL_APIENTRY glPushDebugGroup (GLenum source, GLuint id, GLsizei length, const GLchar *message); +GL_APICALL void GL_APIENTRY glPopDebugGroup (void); +GL_APICALL void GL_APIENTRY glObjectLabel (GLenum identifier, GLuint name, GLsizei length, const GLchar *label); +GL_APICALL void GL_APIENTRY glGetObjectLabel (GLenum identifier, GLuint name, GLsizei bufSize, GLsizei *length, GLchar *label); +GL_APICALL void GL_APIENTRY glObjectPtrLabel (const void *ptr, GLsizei length, const GLchar *label); +GL_APICALL void GL_APIENTRY glGetObjectPtrLabel (const void *ptr, GLsizei bufSize, GLsizei *length, GLchar *label); +GL_APICALL void GL_APIENTRY glGetPointerv (GLenum pname, void **params); +GL_APICALL void GL_APIENTRY glEnablei (GLenum target, GLuint index); +GL_APICALL void GL_APIENTRY glDisablei (GLenum target, GLuint index); +GL_APICALL void GL_APIENTRY glBlendEquationi (GLuint buf, GLenum mode); +GL_APICALL void GL_APIENTRY glBlendEquationSeparatei (GLuint buf, GLenum modeRGB, GLenum modeAlpha); +GL_APICALL void GL_APIENTRY glBlendFunci (GLuint buf, GLenum src, GLenum dst); +GL_APICALL void GL_APIENTRY glBlendFuncSeparatei (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha); +GL_APICALL void GL_APIENTRY glColorMaski (GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a); +GL_APICALL GLboolean GL_APIENTRY glIsEnabledi (GLenum target, GLuint index); +GL_APICALL void GL_APIENTRY glDrawElementsBaseVertex (GLenum mode, GLsizei count, GLenum type, const void *indices, GLint basevertex); +GL_APICALL void GL_APIENTRY glDrawRangeElementsBaseVertex (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices, GLint basevertex); +GL_APICALL void GL_APIENTRY glDrawElementsInstancedBaseVertex (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLint basevertex); +GL_APICALL void GL_APIENTRY glFramebufferTexture (GLenum target, GLenum attachment, GLuint texture, GLint level); +GL_APICALL void GL_APIENTRY glPrimitiveBoundingBox (GLfloat minX, GLfloat minY, GLfloat minZ, GLfloat minW, GLfloat maxX, GLfloat maxY, GLfloat maxZ, GLfloat maxW); +GL_APICALL GLenum GL_APIENTRY glGetGraphicsResetStatus (void); +GL_APICALL void GL_APIENTRY glReadnPixels (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, void *data); +GL_APICALL void GL_APIENTRY glGetnUniformfv (GLuint program, GLint location, GLsizei bufSize, GLfloat *params); +GL_APICALL void GL_APIENTRY glGetnUniformiv (GLuint program, GLint location, GLsizei bufSize, GLint *params); +GL_APICALL void GL_APIENTRY glGetnUniformuiv (GLuint program, GLint location, GLsizei bufSize, GLuint *params); +GL_APICALL void GL_APIENTRY glMinSampleShading (GLfloat value); +GL_APICALL void GL_APIENTRY glPatchParameteri (GLenum pname, GLint value); +GL_APICALL void GL_APIENTRY glTexParameterIiv (GLenum target, GLenum pname, const GLint *params); +GL_APICALL void GL_APIENTRY glTexParameterIuiv (GLenum target, GLenum pname, const GLuint *params); +GL_APICALL void GL_APIENTRY glGetTexParameterIiv (GLenum target, GLenum pname, GLint *params); +GL_APICALL void GL_APIENTRY glGetTexParameterIuiv (GLenum target, GLenum pname, GLuint *params); +GL_APICALL void GL_APIENTRY glSamplerParameterIiv (GLuint sampler, GLenum pname, const GLint *param); +GL_APICALL void GL_APIENTRY glSamplerParameterIuiv (GLuint sampler, GLenum pname, const GLuint *param); +GL_APICALL void GL_APIENTRY glGetSamplerParameterIiv (GLuint sampler, GLenum pname, GLint *params); +GL_APICALL void GL_APIENTRY glGetSamplerParameterIuiv (GLuint sampler, GLenum pname, GLuint *params); +GL_APICALL void GL_APIENTRY glTexBuffer (GLenum target, GLenum internalformat, GLuint buffer); +GL_APICALL void GL_APIENTRY glTexBufferRange (GLenum target, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size); +GL_APICALL void GL_APIENTRY glTexStorage3DMultisample (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations); +#endif +#endif /* GL_ES_VERSION_3_2 */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Source/ThirdParty/ANGLE/include/GLES3/gl3platform.h b/Source/ThirdParty/ANGLE/include/GLES3/gl3platform.h index 1bd1a850fa61..b1e869dd111a 100644 --- a/Source/ThirdParty/ANGLE/include/GLES3/gl3platform.h +++ b/Source/ThirdParty/ANGLE/include/GLES3/gl3platform.h @@ -1,7 +1,7 @@ #ifndef __gl3platform_h_ #define __gl3platform_h_ -/* $Revision: 18437 $ on $Date:: 2012-07-08 23:31:39 -0700 #$ */ +/* $Revision: 23328 $ on $Date:: 2013-10-02 02:28:28 -0700 #$ */ /* * This document is licensed under the SGI Free Software B License Version diff --git a/Source/ThirdParty/ANGLE/include/GLSLANG/ShaderLang.h b/Source/ThirdParty/ANGLE/include/GLSLANG/ShaderLang.h index 7d3f41557013..b7fdf5553b69 100644 --- a/Source/ThirdParty/ANGLE/include/GLSLANG/ShaderLang.h +++ b/Source/ThirdParty/ANGLE/include/GLSLANG/ShaderLang.h @@ -48,7 +48,7 @@ typedef unsigned int GLenum; // Version number for shader translation API. // It is incremented every time the API changes. -#define ANGLE_SH_VERSION 135 +#define ANGLE_SH_VERSION 145 typedef enum { SH_GLES2_SPEC = 0x8B40, @@ -80,23 +80,35 @@ typedef enum { SH_CSS_SHADERS_SPEC = 0x8B42 } ShShaderSpec; -typedef enum { - SH_ESSL_OUTPUT = 0x8B45, - // SH_GLSL_OUTPUT is deprecated. This is to not break the build. - SH_GLSL_OUTPUT = 0x8B46, - SH_GLSL_COMPATIBILITY_OUTPUT = 0x8B46, - // SH_GLSL_CORE_OUTPUT is deprecated. - SH_GLSL_CORE_OUTPUT = 0x8B47, - //Note: GL introduced core profiles in 1.5. However, for compatiblity with Chromium, we treat SH_GLSL_CORE_OUTPUT as GLSL_130_OUTPUT. - //TODO: Remove SH_GLSL_CORE_OUTPUT - SH_GLSL_130_OUTPUT = 0x8B47, - SH_GLSL_410_CORE_OUTPUT = 0x8B84, - SH_GLSL_420_CORE_OUTPUT = 0x8B85, - - // HLSL output only supported in some configurations. - SH_HLSL_OUTPUT = 0x8B48, - SH_HLSL9_OUTPUT = 0x8B48, - SH_HLSL11_OUTPUT = 0x8B49 +typedef enum +{ + // ESSL output only supported in some configurations. + SH_ESSL_OUTPUT = 0x8B45, + + // GLSL output only supported in some configurations. + SH_GLSL_COMPATIBILITY_OUTPUT = 0x8B46, + // Note: GL introduced core profiles in 1.5. + SH_GLSL_130_OUTPUT = 0x8B47, + SH_GLSL_140_OUTPUT = 0x8B80, + SH_GLSL_150_CORE_OUTPUT = 0x8B81, + SH_GLSL_330_CORE_OUTPUT = 0x8B82, + SH_GLSL_400_CORE_OUTPUT = 0x8B83, + SH_GLSL_410_CORE_OUTPUT = 0x8B84, + SH_GLSL_420_CORE_OUTPUT = 0x8B85, + SH_GLSL_430_CORE_OUTPUT = 0x8B86, + SH_GLSL_440_CORE_OUTPUT = 0x8B87, + SH_GLSL_450_CORE_OUTPUT = 0x8B88, + + // HLSL output only supported in some configurations. + // Deprecated: + SH_HLSL_OUTPUT = 0x8B48, + SH_HLSL9_OUTPUT = 0x8B48, + SH_HLSL11_OUTPUT = 0x8B49, + + // Prefer using these to specify HLSL output type: + SH_HLSL_3_0_OUTPUT = 0x8B48, // D3D 9 + SH_HLSL_4_1_OUTPUT = 0x8B49, // D3D 11 + SH_HLSL_4_0_FL9_3_OUTPUT = 0x8B4A // D3D 11 feature level 9_3 } ShShaderOutput; // Compile options. @@ -188,6 +200,14 @@ typedef enum { // compilation process. Pruning coupled with SH_LIMIT_CALL_STACK_DEPTH // helps avoid bad shaders causing stack overflows. SH_DONT_PRUNE_UNUSED_FUNCTIONS = 0x100000, + + // This flag works around a bug in NVIDIA 331 series drivers related + // to pow(x, y) where y is a constant vector. + SH_REMOVE_POW_WITH_CONSTANT_EXPONENT = 0x200000, + + // This flag works around bugs in Mac drivers related to do-while by + // transforming them into an other construct. + SH_REWRITE_DO_WHILE_LOOPS = 0x400000, } ShCompileOptions; // Defines alternate strategies for implementing array index clamping. @@ -236,6 +256,7 @@ typedef struct int OES_standard_derivatives; int OES_EGL_image_external; int ARB_texture_rectangle; + int EXT_blend_func_extended; int EXT_draw_buffers; int EXT_frag_depth; int EXT_shader_texture_lod; @@ -250,7 +271,9 @@ typedef struct // function. This applies to Tegra K1 devices. int NV_draw_buffers; - // Set to 1 if highp precision is supported in the fragment language. + // Set to 1 if highp precision is supported in the ESSL 1.00 version of the + // fragment language. Does not affect versions of the language where highp + // support is mandatory. // Default is 0. int FragmentPrecisionHigh; @@ -260,6 +283,13 @@ typedef struct int MinProgramTexelOffset; int MaxProgramTexelOffset; + // Extension constants. + + // Value of GL_MAX_DUAL_SOURCE_DRAW_BUFFERS_EXT for OpenGL ES output context. + // Value of GL_MAX_DUAL_SOURCE_DRAW_BUFFERS for OpenGL output context. + // GLES SL version 100 gl_MaxDualSourceDrawBuffersEXT value for EXT_blend_func_extended. + int MaxDualSourceDrawBuffers; + // Name Hashing. // Set a 64 bit hash function to enable user-defined name hashing. // Default is NULL. @@ -269,11 +299,15 @@ typedef struct // Default is SH_CLAMP_WITH_CLAMP_INTRINSIC. ShArrayIndexClampingStrategy ArrayIndexClampingStrategy; - // The maximum complexity an expression can be. + // The maximum complexity an expression can be when SH_LIMIT_EXPRESSION_COMPLEXITY is turned on. int MaxExpressionComplexity; // The maximum depth a call stack can be. int MaxCallStackDepth; + + // The maximum number of parameters a function can have when SH_LIMIT_EXPRESSION_COMPLEXITY is + // turned on. + int MaxFunctionParameters; } ShBuiltInResources; // @@ -309,9 +343,9 @@ COMPILER_EXPORT const std::string &ShGetBuiltInResourcesString(const ShHandle ha // type: Specifies the type of shader - GL_FRAGMENT_SHADER or GL_VERTEX_SHADER. // spec: Specifies the language spec the compiler must conform to - // SH_GLES2_SPEC or SH_WEBGL_SPEC. -// output: Specifies the output code type - SH_ESSL_OUTPUT, SH_GLSL_OUTPUT, -// SH_HLSL9_OUTPUT or SH_HLSL11_OUTPUT. Note: HLSL output is only -// supported in some configurations. +// output: Specifies the output code type - for example SH_ESSL_OUTPUT, SH_GLSL_COMPATIBILITY_OUTPUT, +// SH_HLSL_3_0_OUTPUT or SH_HLSL_4_1_OUTPUT. Note: Each output type may only +// be supported in some configurations. // resources: Specifies the built-in resources. COMPILER_EXPORT ShHandle ShConstructCompiler( sh::GLenum type, @@ -350,6 +384,9 @@ COMPILER_EXPORT bool ShCompile( size_t numStrings, int compileOptions); +// Clears the results from the previous compilation. +COMPILER_EXPORT void ShClearResults(const ShHandle handle); + // Return the version of the shader language. COMPILER_EXPORT int ShGetShaderVersion(const ShHandle handle); @@ -384,7 +421,7 @@ COMPILER_EXPORT const std::map *ShGetNameHashingMap( COMPILER_EXPORT const std::vector *ShGetUniforms(const ShHandle handle); COMPILER_EXPORT const std::vector *ShGetVaryings(const ShHandle handle); COMPILER_EXPORT const std::vector *ShGetAttributes(const ShHandle handle); -COMPILER_EXPORT const std::vector *ShGetOutputVariables(const ShHandle handle); +COMPILER_EXPORT const std::vector *ShGetOutputVariables(const ShHandle handle); COMPILER_EXPORT const std::vector *ShGetInterfaceBlocks(const ShHandle handle); typedef struct @@ -417,16 +454,10 @@ COMPILER_EXPORT bool ShGetInterfaceBlockRegister(const ShHandle handle, const std::string &interfaceBlockName, unsigned int *indexOut); -// Gives the compiler-assigned register for uniforms in the default -// interface block. -// The method writes the value to the output variable "indexOut". -// Returns true if it found a valid default uniform, false otherwise. -// Parameters: -// handle: Specifies the compiler -// interfaceBlockName: Specifies the uniform -// indexOut: output variable that stores the assigned register -COMPILER_EXPORT bool ShGetUniformRegister(const ShHandle handle, - const std::string &uniformName, - unsigned int *indexOut); +// Gives a map from uniform names to compiler-assigned registers in the default +// interface block. Note that the map contains also registers of samplers that +// have been extracted from structs. +COMPILER_EXPORT const std::map *ShGetUniformRegisterMap( + const ShHandle handle); #endif // GLSLANG_SHADERLANG_H_ diff --git a/Source/ThirdParty/ANGLE/include/GLSLANG/ShaderVars.h b/Source/ThirdParty/ANGLE/include/GLSLANG/ShaderVars.h index 4b3945eb6047..af9b65b7f572 100644 --- a/Source/ThirdParty/ANGLE/include/GLSLANG/ShaderVars.h +++ b/Source/ThirdParty/ANGLE/include/GLSLANG/ShaderVars.h @@ -110,19 +110,39 @@ struct COMPILER_EXPORT Uniform : public ShaderVariable bool isSameUniformAtLinkTime(const Uniform &other) const; }; -struct COMPILER_EXPORT Attribute : public ShaderVariable +// An interface variable is a variable which passes data between the GL data structures and the +// shader execution: either vertex shader inputs or fragment shader outputs. These variables can +// have integer locations to pass back to the GL API. +struct COMPILER_EXPORT InterfaceVariable : public ShaderVariable +{ + InterfaceVariable(); + ~InterfaceVariable(); + InterfaceVariable(const InterfaceVariable &other); + InterfaceVariable &operator=(const InterfaceVariable &other); + bool operator==(const InterfaceVariable &other) const; + bool operator!=(const InterfaceVariable &other) const { return !operator==(other); } + + int location; +}; + +struct COMPILER_EXPORT Attribute : public InterfaceVariable { Attribute(); ~Attribute(); Attribute(const Attribute &other); Attribute &operator=(const Attribute &other); bool operator==(const Attribute &other) const; - bool operator!=(const Attribute &other) const - { - return !operator==(other); - } + bool operator!=(const Attribute &other) const { return !operator==(other); } +}; - int location; +struct COMPILER_EXPORT OutputVariable : public InterfaceVariable +{ + OutputVariable(); + ~OutputVariable(); + OutputVariable(const OutputVariable &other); + OutputVariable &operator=(const OutputVariable &other); + bool operator==(const OutputVariable &other) const; + bool operator!=(const OutputVariable &other) const { return !operator==(other); } }; struct COMPILER_EXPORT InterfaceBlockField : public ShaderVariable @@ -161,7 +181,12 @@ struct COMPILER_EXPORT Varying : public ShaderVariable // Decide whether two varyings are the same at shader link time, // assuming one from vertex shader and the other from fragment shader. - // See GLSL ES Spec 3.00.3, sec 4.3.9. + // Invariance needs to match only in ESSL1. Relevant spec sections: + // GLSL ES 3.00.4, sections 4.6.1 and 4.3.9. + // GLSL ES 1.00.17, section 4.6.4. + bool isSameVaryingAtLinkTime(const Varying &other, int shaderVersion) const; + + // Deprecated version of isSameVaryingAtLinkTime, which assumes ESSL1. bool isSameVaryingAtLinkTime(const Varying &other) const; InterpolationType interpolation; @@ -175,6 +200,9 @@ struct COMPILER_EXPORT InterfaceBlock InterfaceBlock(const InterfaceBlock &other); InterfaceBlock &operator=(const InterfaceBlock &other); + // Fields from blocks with non-empty instance names are prefixed with the block name. + std::string fieldPrefix() const; + std::string name; std::string mappedName; std::string instanceName; @@ -185,6 +213,6 @@ struct COMPILER_EXPORT InterfaceBlock std::vector fields; }; -} +} // namespace sh #endif // GLSLANG_SHADERVARS_H_ diff --git a/Source/ThirdParty/ANGLE/include/angle_gl.h b/Source/ThirdParty/ANGLE/include/angle_gl.h index e7ecdbd2f0a5..18de80b60b11 100644 --- a/Source/ThirdParty/ANGLE/include/angle_gl.h +++ b/Source/ThirdParty/ANGLE/include/angle_gl.h @@ -13,7 +13,8 @@ #include "GLES2/gl2.h" #include "GLES2/gl2ext.h" #include "GLES3/gl3.h" -#include "GLES3/gl3ext.h" +#include "GLES3/gl31.h" +#include "GLES3/gl32.h" // The following enum is used in ANGLE, but is from desktop GL #ifndef GL_SAMPLER_2D_RECT_ARB diff --git a/Source/ThirdParty/ANGLE/include/angle_windowsstore.h b/Source/ThirdParty/ANGLE/include/angle_windowsstore.h index 53ec93e037d5..b8f76dec396e 100644 --- a/Source/ThirdParty/ANGLE/include/angle_windowsstore.h +++ b/Source/ThirdParty/ANGLE/include/angle_windowsstore.h @@ -28,10 +28,24 @@ const wchar_t EGLNativeWindowTypeProperty[] = L"EGLNativeWindowTypeProperty"; // Description: Set this property to specify a preferred size in pixels of the render surface. // The render surface size width and height must be greater than 0. // If this property is set, then the render surface size is fixed. +// The render surface will then be scaled to the window dimensions. // If this property is missing, a default behavior will be provided. // The default behavior uses the window size if a CoreWindow is specified or // the size of the SwapChainPanel control if one is specified. // const wchar_t EGLRenderSurfaceSizeProperty[] = L"EGLRenderSurfaceSizeProperty"; +// +// Property: EGLRenderResolutionScaleProperty +// Type: Single +// Description: Use this to specify a preferred scale for the render surface compared to the window. +// For example, if the window is 800x480, and: +// - scale is set to 0.5f then the surface will be 400x240 +// - scale is set to 1.2f then the surface will be 960x576 +// If the window resizes or rotates then the surface will resize accordingly. +// EGLRenderResolutionScaleProperty and EGLRenderSurfaceSizeProperty cannot both be set. +// The scale factor should be > 0.0f. +// +const wchar_t EGLRenderResolutionScaleProperty[] = L"EGLRenderResolutionScaleProperty"; + #endif // ANGLE_WINDOWSSTORE_H_ diff --git a/Source/ThirdParty/ANGLE/include/platform/Platform.h b/Source/ThirdParty/ANGLE/include/platform/Platform.h index f8110f618dac..0e8cdf477ffe 100644 --- a/Source/ThirdParty/ANGLE/include/platform/Platform.h +++ b/Source/ThirdParty/ANGLE/include/platform/Platform.h @@ -11,7 +11,24 @@ #include -#include "../export.h" +#if defined(_WIN32) +# if !defined(LIBANGLE_IMPLEMENTATION) +# define ANGLE_PLATFORM_EXPORT __declspec(dllimport) +# endif +#elif defined(__GNUC__) +# if defined(LIBANGLE_IMPLEMENTATION) +# define ANGLE_PLATFORM_EXPORT __attribute__((visibility ("default"))) +# endif +#endif +#if !defined(ANGLE_PLATFORM_EXPORT) +# define ANGLE_PLATFORM_EXPORT +#endif + +#if defined(_WIN32) +# define ANGLE_APIENTRY __stdcall +#else +# define ANGLE_APIENTRY +#endif namespace angle { @@ -31,6 +48,17 @@ class Platform // it is recommended that the fixed point be no further in the past than the epoch. virtual double monotonicallyIncreasingTime() { return 0; } + // Logging ------------------------------------------------------------ + + // Log an error message within the platform implementation. + virtual void logError(const char *errorMessage) {} + + // Log a warning message within the platform implementation. + virtual void logWarning(const char *warningMessage) {} + + // Log an info message within the platform implementation. + virtual void logInfo(const char *infoMessage) {} + // Tracing -------- // Get a pointer to the enabled state of the given trace category. The @@ -114,6 +142,8 @@ class Platform virtual void histogramEnumeration(const char *name, int sample, int boundaryValue) { } // Unlike enumeration histograms, sparse histograms only allocate memory for non-empty buckets. virtual void histogramSparse(const char *name, int sample) { } + // Boolean histograms track two-state variables. + virtual void histogramBoolean(const char *name, bool sample) { } protected: virtual ~Platform() { } @@ -121,13 +151,18 @@ class Platform } -typedef void(*ANGLEPlatformInitializeFunc)(angle::Platform*); -ANGLE_EXPORT void ANGLEPlatformInitialize(angle::Platform*); +extern "C" +{ + +typedef void (ANGLE_APIENTRY *ANGLEPlatformInitializeFunc)(angle::Platform*); +ANGLE_PLATFORM_EXPORT void ANGLE_APIENTRY ANGLEPlatformInitialize(angle::Platform*); -typedef void (*ANGLEPlatformShutdownFunc)(); -ANGLE_EXPORT void ANGLEPlatformShutdown(); +typedef void (ANGLE_APIENTRY *ANGLEPlatformShutdownFunc)(); +ANGLE_PLATFORM_EXPORT void ANGLE_APIENTRY ANGLEPlatformShutdown(); -typedef angle::Platform *(*ANGLEPlatformCurrentFunc)(); -ANGLE_EXPORT angle::Platform *ANGLEPlatformCurrent(); +typedef angle::Platform *(ANGLE_APIENTRY *ANGLEPlatformCurrentFunc)(); +ANGLE_PLATFORM_EXPORT angle::Platform *ANGLE_APIENTRY ANGLEPlatformCurrent(); + +} #endif // ANGLE_PLATFORM_H diff --git a/Source/ThirdParty/ANGLE/src/angle.gyp b/Source/ThirdParty/ANGLE/src/angle.gyp index 4095547f84cc..ba73c9246a9e 100644 --- a/Source/ThirdParty/ANGLE/src/angle.gyp +++ b/Source/ThirdParty/ANGLE/src/angle.gyp @@ -16,7 +16,11 @@ 'angle_enable_d3d9%': 0, 'angle_enable_d3d11%': 0, 'angle_enable_gl%': 0, + 'angle_enable_essl%': 1, # Enable this for all configs by default + 'angle_enable_glsl%': 1, # Enable this for all configs by default 'angle_enable_hlsl%': 0, + 'angle_link_glx%': 0, + 'angle_gl_library_type%': 'shared_library', 'conditions': [ ['OS=="win"', @@ -26,6 +30,18 @@ 'angle_enable_d3d11%': 1, 'angle_enable_hlsl%': 1, }], + ['OS=="linux" and use_x11==1 and chromeos==0', + { + 'angle_enable_gl%': 1, + }], + ['OS=="mac"', + { + 'angle_enable_gl%': 1, + }], + ['use_ozone==1', + { + 'angle_enable_gl%': 1, + }], ], }, 'includes': @@ -50,6 +66,10 @@ '.', '../include', ], + 'dependencies': + [ + 'commit_id', + ], 'direct_dependent_settings': { 'include_dirs': @@ -57,16 +77,37 @@ '<(angle_path)/src', '<(angle_path)/include', ], + 'conditions': + [ + ['OS=="win"', + { + 'configurations': + { + 'Debug_Base': + { + 'defines': + [ + 'ANGLE_ENABLE_DEBUG_ANNOTATIONS' + ], + }, + }, + }], + ], }, 'conditions': [ - ['angle_build_winrt==1', + ['OS=="win"', { - 'msvs_enable_winrt' : '1', - }], - ['angle_build_winphone==1', - { - 'msvs_enable_winphone' : '1', + 'configurations': + { + 'Debug_Base': + { + 'defines': + [ + 'ANGLE_ENABLE_DEBUG_ANNOTATIONS' + ], + }, + }, }], ], }, @@ -87,13 +128,8 @@ [ ['angle_build_winrt==1', { - 'msvs_enable_winrt' : '1', 'type' : 'shared_library', }], - ['angle_build_winphone==1', - { - 'msvs_enable_winphone' : '1', - }], ], }, ], @@ -135,13 +171,8 @@ [ ['angle_build_winrt==1', { - 'msvs_enable_winrt' : '1', 'type' : 'shared_library', }], - ['angle_build_winphone==1', - { - 'msvs_enable_winphone' : '1', - }], ], } ] @@ -172,13 +203,8 @@ [ ['angle_build_winrt==1', { - 'msvs_enable_winrt' : '1', 'type' : 'shared_library', }], - ['angle_build_winphone==1', - { - 'msvs_enable_winphone' : '1', - }], ], } ] @@ -216,13 +242,8 @@ }], ['angle_build_winrt==1', { - 'msvs_enable_winrt' : '1', 'type' : 'shared_library', }], - ['angle_build_winphone==1', - { - 'msvs_enable_winphone' : '1', - }], ] }, ], # targets diff --git a/Source/ThirdParty/ANGLE/src/common/BitSetIterator.h b/Source/ThirdParty/ANGLE/src/common/BitSetIterator.h new file mode 100644 index 000000000000..3248ce44c9f9 --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/common/BitSetIterator.h @@ -0,0 +1,156 @@ +// +// 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. +// +// BitSetIterator: +// A helper class to quickly bitscan bitsets for set bits. +// + +#ifndef COMMON_BITSETITERATOR_H_ +#define COMMON_BITSETITERATOR_H_ + +#include + +#include + +#include "common/angleutils.h" +#include "common/debug.h" +#include "common/mathutil.h" +#include "common/platform.h" + +namespace angle +{ +template +class BitSetIterator final +{ + public: + BitSetIterator(const std::bitset &bitset); + BitSetIterator(const BitSetIterator &other); + BitSetIterator &operator=(const BitSetIterator &other); + + class Iterator final + { + public: + Iterator(const std::bitset &bits); + Iterator &operator++(); + + bool operator==(const Iterator &other) const; + bool operator!=(const Iterator &other) const; + unsigned long operator*() const { return mCurrentBit; } + + private: + unsigned long getNextBit(); + + static const size_t BitsPerWord = sizeof(unsigned long) * 8; + std::bitset mBits; + unsigned long mCurrentBit; + unsigned long mOffset; + }; + + Iterator begin() const { return Iterator(mBits); } + Iterator end() const { return Iterator(std::bitset(0)); } + + private: + const std::bitset mBits; +}; + +template +BitSetIterator::BitSetIterator(const std::bitset &bitset) + : mBits(bitset) +{ +} + +template +BitSetIterator::BitSetIterator(const BitSetIterator &other) + : mBits(other.mBits) +{ +} + +template +BitSetIterator &BitSetIterator::operator=(const BitSetIterator &other) +{ + mBits = other.mBits; + return *this; +} + +template +BitSetIterator::Iterator::Iterator(const std::bitset &bits) + : mBits(bits), mCurrentBit(0), mOffset(0) +{ + if (bits.any()) + { + mCurrentBit = getNextBit(); + } + else + { + mOffset = static_cast(rx::roundUp(N, BitsPerWord)); + } +} + +template +typename BitSetIterator::Iterator &BitSetIterator::Iterator::operator++() +{ + ASSERT(mBits.any()); + mBits.set(mCurrentBit - mOffset, 0); + mCurrentBit = getNextBit(); + return *this; +} + +inline unsigned long ScanForward(unsigned long bits) +{ + ASSERT(bits != 0); +#if defined(ANGLE_PLATFORM_WINDOWS) + unsigned long firstBitIndex = 0ul; + unsigned char ret = _BitScanForward(&firstBitIndex, bits); + ASSERT(ret != 0); + UNUSED_ASSERTION_VARIABLE(ret); + return firstBitIndex; +#elif defined(ANGLE_PLATFORM_POSIX) + return static_cast(__builtin_ctzl(bits)); +#else +#error Please implement bit-scan-forward for your platform! +#endif +} + +template +bool BitSetIterator::Iterator::operator==(const Iterator &other) const +{ + return mOffset == other.mOffset && mBits == other.mBits; +} + +template +bool BitSetIterator::Iterator::operator!=(const Iterator &other) const +{ + return !(*this == other); +} + +template +unsigned long BitSetIterator::Iterator::getNextBit() +{ + static std::bitset wordMask(std::numeric_limits::max()); + + while (mOffset < N) + { + unsigned long wordBits = (mBits & wordMask).to_ulong(); + if (wordBits != 0ul) + { + return ScanForward(wordBits) + mOffset; + } + + mBits >>= BitsPerWord; + mOffset += BitsPerWord; + } + return 0; +} + +// Helper to avoid needing to specify the template parameter size +template +BitSetIterator IterateBitSet(const std::bitset &bitset) +{ + return BitSetIterator(bitset); +} + +} // angle + +#endif // COMMON_BITSETITERATOR_H_ diff --git a/Source/ThirdParty/ANGLE/src/common/BitSetIterator_unittest.cpp b/Source/ThirdParty/ANGLE/src/common/BitSetIterator_unittest.cpp new file mode 100644 index 000000000000..e965f2c567e5 --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/common/BitSetIterator_unittest.cpp @@ -0,0 +1,91 @@ +// +// 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. +// +// BitSetIteratorTest: +// Test the IterableBitSet class. +// + +#include + +#include "common/BitSetIterator.h" + +using namespace angle; + +namespace +{ +class BitSetIteratorTest : public testing::Test +{ + protected: + std::bitset<40> mStateBits; +}; + +// Simple iterator test. +TEST_F(BitSetIteratorTest, Iterator) +{ + std::set originalValues; + originalValues.insert(2); + originalValues.insert(6); + originalValues.insert(8); + originalValues.insert(35); + + for (unsigned long value : originalValues) + { + mStateBits.set(value); + } + + std::set readValues; + for (unsigned long bit : IterateBitSet(mStateBits)) + { + EXPECT_EQ(1u, originalValues.count(bit)); + EXPECT_EQ(0u, readValues.count(bit)); + readValues.insert(bit); + } + + EXPECT_EQ(originalValues.size(), readValues.size()); +} + +// Test an empty iterator. +TEST_F(BitSetIteratorTest, EmptySet) +{ + // We don't use the FAIL gtest macro here since it returns immediately, + // causing an unreachable code warning in MSVS + bool sawBit = false; + for (unsigned long bit : IterateBitSet(mStateBits)) + { + sawBit = true; + UNUSED_VARIABLE(bit); + } + EXPECT_FALSE(sawBit); +} + +// Test iterating a result of combining two bitsets. +TEST_F(BitSetIteratorTest, NonLValueBitset) +{ + std::bitset<40> otherBits; + + mStateBits.set(1); + mStateBits.set(2); + mStateBits.set(3); + mStateBits.set(4); + + otherBits.set(0); + otherBits.set(1); + otherBits.set(3); + otherBits.set(5); + + std::set seenBits; + + for (unsigned long bit : IterateBitSet(mStateBits & otherBits)) + { + EXPECT_EQ(0u, seenBits.count(bit)); + seenBits.insert(bit); + EXPECT_TRUE(mStateBits[bit]); + EXPECT_TRUE(otherBits[bit]); + } + + EXPECT_EQ((mStateBits & otherBits).count(), seenBits.size()); +} + +} // anonymous namespace diff --git a/Source/ThirdParty/ANGLE/src/common/Float16ToFloat32.cpp b/Source/ThirdParty/ANGLE/src/common/Float16ToFloat32.cpp new file mode 100644 index 000000000000..acd0d88b6074 --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/common/Float16ToFloat32.cpp @@ -0,0 +1,2205 @@ +// +// Copyright (c) 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. +// + +// This file is automatically generated. + +#include "common/mathutil.h" + +namespace gl +{ + +const static unsigned g_mantissa[2048] = { + 0x00000000, + 0x33800000, + 0x34000000, + 0x34400000, + 0x34800000, + 0x34a00000, + 0x34c00000, + 0x34e00000, + 0x35000000, + 0x35100000, + 0x35200000, + 0x35300000, + 0x35400000, + 0x35500000, + 0x35600000, + 0x35700000, + 0x35800000, + 0x35880000, + 0x35900000, + 0x35980000, + 0x35a00000, + 0x35a80000, + 0x35b00000, + 0x35b80000, + 0x35c00000, + 0x35c80000, + 0x35d00000, + 0x35d80000, + 0x35e00000, + 0x35e80000, + 0x35f00000, + 0x35f80000, + 0x36000000, + 0x36040000, + 0x36080000, + 0x360c0000, + 0x36100000, + 0x36140000, + 0x36180000, + 0x361c0000, + 0x36200000, + 0x36240000, + 0x36280000, + 0x362c0000, + 0x36300000, + 0x36340000, + 0x36380000, + 0x363c0000, + 0x36400000, + 0x36440000, + 0x36480000, + 0x364c0000, + 0x36500000, + 0x36540000, + 0x36580000, + 0x365c0000, + 0x36600000, + 0x36640000, + 0x36680000, + 0x366c0000, + 0x36700000, + 0x36740000, + 0x36780000, + 0x367c0000, + 0x36800000, + 0x36820000, + 0x36840000, + 0x36860000, + 0x36880000, + 0x368a0000, + 0x368c0000, + 0x368e0000, + 0x36900000, + 0x36920000, + 0x36940000, + 0x36960000, + 0x36980000, + 0x369a0000, + 0x369c0000, + 0x369e0000, + 0x36a00000, + 0x36a20000, + 0x36a40000, + 0x36a60000, + 0x36a80000, + 0x36aa0000, + 0x36ac0000, + 0x36ae0000, + 0x36b00000, + 0x36b20000, + 0x36b40000, + 0x36b60000, + 0x36b80000, + 0x36ba0000, + 0x36bc0000, + 0x36be0000, + 0x36c00000, + 0x36c20000, + 0x36c40000, + 0x36c60000, + 0x36c80000, + 0x36ca0000, + 0x36cc0000, + 0x36ce0000, + 0x36d00000, + 0x36d20000, + 0x36d40000, + 0x36d60000, + 0x36d80000, + 0x36da0000, + 0x36dc0000, + 0x36de0000, + 0x36e00000, + 0x36e20000, + 0x36e40000, + 0x36e60000, + 0x36e80000, + 0x36ea0000, + 0x36ec0000, + 0x36ee0000, + 0x36f00000, + 0x36f20000, + 0x36f40000, + 0x36f60000, + 0x36f80000, + 0x36fa0000, + 0x36fc0000, + 0x36fe0000, + 0x37000000, + 0x37010000, + 0x37020000, + 0x37030000, + 0x37040000, + 0x37050000, + 0x37060000, + 0x37070000, + 0x37080000, + 0x37090000, + 0x370a0000, + 0x370b0000, + 0x370c0000, + 0x370d0000, + 0x370e0000, + 0x370f0000, + 0x37100000, + 0x37110000, + 0x37120000, + 0x37130000, + 0x37140000, + 0x37150000, + 0x37160000, + 0x37170000, + 0x37180000, + 0x37190000, + 0x371a0000, + 0x371b0000, + 0x371c0000, + 0x371d0000, + 0x371e0000, + 0x371f0000, + 0x37200000, + 0x37210000, + 0x37220000, + 0x37230000, + 0x37240000, + 0x37250000, + 0x37260000, + 0x37270000, + 0x37280000, + 0x37290000, + 0x372a0000, + 0x372b0000, + 0x372c0000, + 0x372d0000, + 0x372e0000, + 0x372f0000, + 0x37300000, + 0x37310000, + 0x37320000, + 0x37330000, + 0x37340000, + 0x37350000, + 0x37360000, + 0x37370000, + 0x37380000, + 0x37390000, + 0x373a0000, + 0x373b0000, + 0x373c0000, + 0x373d0000, + 0x373e0000, + 0x373f0000, + 0x37400000, + 0x37410000, + 0x37420000, + 0x37430000, + 0x37440000, + 0x37450000, + 0x37460000, + 0x37470000, + 0x37480000, + 0x37490000, + 0x374a0000, + 0x374b0000, + 0x374c0000, + 0x374d0000, + 0x374e0000, + 0x374f0000, + 0x37500000, + 0x37510000, + 0x37520000, + 0x37530000, + 0x37540000, + 0x37550000, + 0x37560000, + 0x37570000, + 0x37580000, + 0x37590000, + 0x375a0000, + 0x375b0000, + 0x375c0000, + 0x375d0000, + 0x375e0000, + 0x375f0000, + 0x37600000, + 0x37610000, + 0x37620000, + 0x37630000, + 0x37640000, + 0x37650000, + 0x37660000, + 0x37670000, + 0x37680000, + 0x37690000, + 0x376a0000, + 0x376b0000, + 0x376c0000, + 0x376d0000, + 0x376e0000, + 0x376f0000, + 0x37700000, + 0x37710000, + 0x37720000, + 0x37730000, + 0x37740000, + 0x37750000, + 0x37760000, + 0x37770000, + 0x37780000, + 0x37790000, + 0x377a0000, + 0x377b0000, + 0x377c0000, + 0x377d0000, + 0x377e0000, + 0x377f0000, + 0x37800000, + 0x37808000, + 0x37810000, + 0x37818000, + 0x37820000, + 0x37828000, + 0x37830000, + 0x37838000, + 0x37840000, + 0x37848000, + 0x37850000, + 0x37858000, + 0x37860000, + 0x37868000, + 0x37870000, + 0x37878000, + 0x37880000, + 0x37888000, + 0x37890000, + 0x37898000, + 0x378a0000, + 0x378a8000, + 0x378b0000, + 0x378b8000, + 0x378c0000, + 0x378c8000, + 0x378d0000, + 0x378d8000, + 0x378e0000, + 0x378e8000, + 0x378f0000, + 0x378f8000, + 0x37900000, + 0x37908000, + 0x37910000, + 0x37918000, + 0x37920000, + 0x37928000, + 0x37930000, + 0x37938000, + 0x37940000, + 0x37948000, + 0x37950000, + 0x37958000, + 0x37960000, + 0x37968000, + 0x37970000, + 0x37978000, + 0x37980000, + 0x37988000, + 0x37990000, + 0x37998000, + 0x379a0000, + 0x379a8000, + 0x379b0000, + 0x379b8000, + 0x379c0000, + 0x379c8000, + 0x379d0000, + 0x379d8000, + 0x379e0000, + 0x379e8000, + 0x379f0000, + 0x379f8000, + 0x37a00000, + 0x37a08000, + 0x37a10000, + 0x37a18000, + 0x37a20000, + 0x37a28000, + 0x37a30000, + 0x37a38000, + 0x37a40000, + 0x37a48000, + 0x37a50000, + 0x37a58000, + 0x37a60000, + 0x37a68000, + 0x37a70000, + 0x37a78000, + 0x37a80000, + 0x37a88000, + 0x37a90000, + 0x37a98000, + 0x37aa0000, + 0x37aa8000, + 0x37ab0000, + 0x37ab8000, + 0x37ac0000, + 0x37ac8000, + 0x37ad0000, + 0x37ad8000, + 0x37ae0000, + 0x37ae8000, + 0x37af0000, + 0x37af8000, + 0x37b00000, + 0x37b08000, + 0x37b10000, + 0x37b18000, + 0x37b20000, + 0x37b28000, + 0x37b30000, + 0x37b38000, + 0x37b40000, + 0x37b48000, + 0x37b50000, + 0x37b58000, + 0x37b60000, + 0x37b68000, + 0x37b70000, + 0x37b78000, + 0x37b80000, + 0x37b88000, + 0x37b90000, + 0x37b98000, + 0x37ba0000, + 0x37ba8000, + 0x37bb0000, + 0x37bb8000, + 0x37bc0000, + 0x37bc8000, + 0x37bd0000, + 0x37bd8000, + 0x37be0000, + 0x37be8000, + 0x37bf0000, + 0x37bf8000, + 0x37c00000, + 0x37c08000, + 0x37c10000, + 0x37c18000, + 0x37c20000, + 0x37c28000, + 0x37c30000, + 0x37c38000, + 0x37c40000, + 0x37c48000, + 0x37c50000, + 0x37c58000, + 0x37c60000, + 0x37c68000, + 0x37c70000, + 0x37c78000, + 0x37c80000, + 0x37c88000, + 0x37c90000, + 0x37c98000, + 0x37ca0000, + 0x37ca8000, + 0x37cb0000, + 0x37cb8000, + 0x37cc0000, + 0x37cc8000, + 0x37cd0000, + 0x37cd8000, + 0x37ce0000, + 0x37ce8000, + 0x37cf0000, + 0x37cf8000, + 0x37d00000, + 0x37d08000, + 0x37d10000, + 0x37d18000, + 0x37d20000, + 0x37d28000, + 0x37d30000, + 0x37d38000, + 0x37d40000, + 0x37d48000, + 0x37d50000, + 0x37d58000, + 0x37d60000, + 0x37d68000, + 0x37d70000, + 0x37d78000, + 0x37d80000, + 0x37d88000, + 0x37d90000, + 0x37d98000, + 0x37da0000, + 0x37da8000, + 0x37db0000, + 0x37db8000, + 0x37dc0000, + 0x37dc8000, + 0x37dd0000, + 0x37dd8000, + 0x37de0000, + 0x37de8000, + 0x37df0000, + 0x37df8000, + 0x37e00000, + 0x37e08000, + 0x37e10000, + 0x37e18000, + 0x37e20000, + 0x37e28000, + 0x37e30000, + 0x37e38000, + 0x37e40000, + 0x37e48000, + 0x37e50000, + 0x37e58000, + 0x37e60000, + 0x37e68000, + 0x37e70000, + 0x37e78000, + 0x37e80000, + 0x37e88000, + 0x37e90000, + 0x37e98000, + 0x37ea0000, + 0x37ea8000, + 0x37eb0000, + 0x37eb8000, + 0x37ec0000, + 0x37ec8000, + 0x37ed0000, + 0x37ed8000, + 0x37ee0000, + 0x37ee8000, + 0x37ef0000, + 0x37ef8000, + 0x37f00000, + 0x37f08000, + 0x37f10000, + 0x37f18000, + 0x37f20000, + 0x37f28000, + 0x37f30000, + 0x37f38000, + 0x37f40000, + 0x37f48000, + 0x37f50000, + 0x37f58000, + 0x37f60000, + 0x37f68000, + 0x37f70000, + 0x37f78000, + 0x37f80000, + 0x37f88000, + 0x37f90000, + 0x37f98000, + 0x37fa0000, + 0x37fa8000, + 0x37fb0000, + 0x37fb8000, + 0x37fc0000, + 0x37fc8000, + 0x37fd0000, + 0x37fd8000, + 0x37fe0000, + 0x37fe8000, + 0x37ff0000, + 0x37ff8000, + 0x38000000, + 0x38004000, + 0x38008000, + 0x3800c000, + 0x38010000, + 0x38014000, + 0x38018000, + 0x3801c000, + 0x38020000, + 0x38024000, + 0x38028000, + 0x3802c000, + 0x38030000, + 0x38034000, + 0x38038000, + 0x3803c000, + 0x38040000, + 0x38044000, + 0x38048000, + 0x3804c000, + 0x38050000, + 0x38054000, + 0x38058000, + 0x3805c000, + 0x38060000, + 0x38064000, + 0x38068000, + 0x3806c000, + 0x38070000, + 0x38074000, + 0x38078000, + 0x3807c000, + 0x38080000, + 0x38084000, + 0x38088000, + 0x3808c000, + 0x38090000, + 0x38094000, + 0x38098000, + 0x3809c000, + 0x380a0000, + 0x380a4000, + 0x380a8000, + 0x380ac000, + 0x380b0000, + 0x380b4000, + 0x380b8000, + 0x380bc000, + 0x380c0000, + 0x380c4000, + 0x380c8000, + 0x380cc000, + 0x380d0000, + 0x380d4000, + 0x380d8000, + 0x380dc000, + 0x380e0000, + 0x380e4000, + 0x380e8000, + 0x380ec000, + 0x380f0000, + 0x380f4000, + 0x380f8000, + 0x380fc000, + 0x38100000, + 0x38104000, + 0x38108000, + 0x3810c000, + 0x38110000, + 0x38114000, + 0x38118000, + 0x3811c000, + 0x38120000, + 0x38124000, + 0x38128000, + 0x3812c000, + 0x38130000, + 0x38134000, + 0x38138000, + 0x3813c000, + 0x38140000, + 0x38144000, + 0x38148000, + 0x3814c000, + 0x38150000, + 0x38154000, + 0x38158000, + 0x3815c000, + 0x38160000, + 0x38164000, + 0x38168000, + 0x3816c000, + 0x38170000, + 0x38174000, + 0x38178000, + 0x3817c000, + 0x38180000, + 0x38184000, + 0x38188000, + 0x3818c000, + 0x38190000, + 0x38194000, + 0x38198000, + 0x3819c000, + 0x381a0000, + 0x381a4000, + 0x381a8000, + 0x381ac000, + 0x381b0000, + 0x381b4000, + 0x381b8000, + 0x381bc000, + 0x381c0000, + 0x381c4000, + 0x381c8000, + 0x381cc000, + 0x381d0000, + 0x381d4000, + 0x381d8000, + 0x381dc000, + 0x381e0000, + 0x381e4000, + 0x381e8000, + 0x381ec000, + 0x381f0000, + 0x381f4000, + 0x381f8000, + 0x381fc000, + 0x38200000, + 0x38204000, + 0x38208000, + 0x3820c000, + 0x38210000, + 0x38214000, + 0x38218000, + 0x3821c000, + 0x38220000, + 0x38224000, + 0x38228000, + 0x3822c000, + 0x38230000, + 0x38234000, + 0x38238000, + 0x3823c000, + 0x38240000, + 0x38244000, + 0x38248000, + 0x3824c000, + 0x38250000, + 0x38254000, + 0x38258000, + 0x3825c000, + 0x38260000, + 0x38264000, + 0x38268000, + 0x3826c000, + 0x38270000, + 0x38274000, + 0x38278000, + 0x3827c000, + 0x38280000, + 0x38284000, + 0x38288000, + 0x3828c000, + 0x38290000, + 0x38294000, + 0x38298000, + 0x3829c000, + 0x382a0000, + 0x382a4000, + 0x382a8000, + 0x382ac000, + 0x382b0000, + 0x382b4000, + 0x382b8000, + 0x382bc000, + 0x382c0000, + 0x382c4000, + 0x382c8000, + 0x382cc000, + 0x382d0000, + 0x382d4000, + 0x382d8000, + 0x382dc000, + 0x382e0000, + 0x382e4000, + 0x382e8000, + 0x382ec000, + 0x382f0000, + 0x382f4000, + 0x382f8000, + 0x382fc000, + 0x38300000, + 0x38304000, + 0x38308000, + 0x3830c000, + 0x38310000, + 0x38314000, + 0x38318000, + 0x3831c000, + 0x38320000, + 0x38324000, + 0x38328000, + 0x3832c000, + 0x38330000, + 0x38334000, + 0x38338000, + 0x3833c000, + 0x38340000, + 0x38344000, + 0x38348000, + 0x3834c000, + 0x38350000, + 0x38354000, + 0x38358000, + 0x3835c000, + 0x38360000, + 0x38364000, + 0x38368000, + 0x3836c000, + 0x38370000, + 0x38374000, + 0x38378000, + 0x3837c000, + 0x38380000, + 0x38384000, + 0x38388000, + 0x3838c000, + 0x38390000, + 0x38394000, + 0x38398000, + 0x3839c000, + 0x383a0000, + 0x383a4000, + 0x383a8000, + 0x383ac000, + 0x383b0000, + 0x383b4000, + 0x383b8000, + 0x383bc000, + 0x383c0000, + 0x383c4000, + 0x383c8000, + 0x383cc000, + 0x383d0000, + 0x383d4000, + 0x383d8000, + 0x383dc000, + 0x383e0000, + 0x383e4000, + 0x383e8000, + 0x383ec000, + 0x383f0000, + 0x383f4000, + 0x383f8000, + 0x383fc000, + 0x38400000, + 0x38404000, + 0x38408000, + 0x3840c000, + 0x38410000, + 0x38414000, + 0x38418000, + 0x3841c000, + 0x38420000, + 0x38424000, + 0x38428000, + 0x3842c000, + 0x38430000, + 0x38434000, + 0x38438000, + 0x3843c000, + 0x38440000, + 0x38444000, + 0x38448000, + 0x3844c000, + 0x38450000, + 0x38454000, + 0x38458000, + 0x3845c000, + 0x38460000, + 0x38464000, + 0x38468000, + 0x3846c000, + 0x38470000, + 0x38474000, + 0x38478000, + 0x3847c000, + 0x38480000, + 0x38484000, + 0x38488000, + 0x3848c000, + 0x38490000, + 0x38494000, + 0x38498000, + 0x3849c000, + 0x384a0000, + 0x384a4000, + 0x384a8000, + 0x384ac000, + 0x384b0000, + 0x384b4000, + 0x384b8000, + 0x384bc000, + 0x384c0000, + 0x384c4000, + 0x384c8000, + 0x384cc000, + 0x384d0000, + 0x384d4000, + 0x384d8000, + 0x384dc000, + 0x384e0000, + 0x384e4000, + 0x384e8000, + 0x384ec000, + 0x384f0000, + 0x384f4000, + 0x384f8000, + 0x384fc000, + 0x38500000, + 0x38504000, + 0x38508000, + 0x3850c000, + 0x38510000, + 0x38514000, + 0x38518000, + 0x3851c000, + 0x38520000, + 0x38524000, + 0x38528000, + 0x3852c000, + 0x38530000, + 0x38534000, + 0x38538000, + 0x3853c000, + 0x38540000, + 0x38544000, + 0x38548000, + 0x3854c000, + 0x38550000, + 0x38554000, + 0x38558000, + 0x3855c000, + 0x38560000, + 0x38564000, + 0x38568000, + 0x3856c000, + 0x38570000, + 0x38574000, + 0x38578000, + 0x3857c000, + 0x38580000, + 0x38584000, + 0x38588000, + 0x3858c000, + 0x38590000, + 0x38594000, + 0x38598000, + 0x3859c000, + 0x385a0000, + 0x385a4000, + 0x385a8000, + 0x385ac000, + 0x385b0000, + 0x385b4000, + 0x385b8000, + 0x385bc000, + 0x385c0000, + 0x385c4000, + 0x385c8000, + 0x385cc000, + 0x385d0000, + 0x385d4000, + 0x385d8000, + 0x385dc000, + 0x385e0000, + 0x385e4000, + 0x385e8000, + 0x385ec000, + 0x385f0000, + 0x385f4000, + 0x385f8000, + 0x385fc000, + 0x38600000, + 0x38604000, + 0x38608000, + 0x3860c000, + 0x38610000, + 0x38614000, + 0x38618000, + 0x3861c000, + 0x38620000, + 0x38624000, + 0x38628000, + 0x3862c000, + 0x38630000, + 0x38634000, + 0x38638000, + 0x3863c000, + 0x38640000, + 0x38644000, + 0x38648000, + 0x3864c000, + 0x38650000, + 0x38654000, + 0x38658000, + 0x3865c000, + 0x38660000, + 0x38664000, + 0x38668000, + 0x3866c000, + 0x38670000, + 0x38674000, + 0x38678000, + 0x3867c000, + 0x38680000, + 0x38684000, + 0x38688000, + 0x3868c000, + 0x38690000, + 0x38694000, + 0x38698000, + 0x3869c000, + 0x386a0000, + 0x386a4000, + 0x386a8000, + 0x386ac000, + 0x386b0000, + 0x386b4000, + 0x386b8000, + 0x386bc000, + 0x386c0000, + 0x386c4000, + 0x386c8000, + 0x386cc000, + 0x386d0000, + 0x386d4000, + 0x386d8000, + 0x386dc000, + 0x386e0000, + 0x386e4000, + 0x386e8000, + 0x386ec000, + 0x386f0000, + 0x386f4000, + 0x386f8000, + 0x386fc000, + 0x38700000, + 0x38704000, + 0x38708000, + 0x3870c000, + 0x38710000, + 0x38714000, + 0x38718000, + 0x3871c000, + 0x38720000, + 0x38724000, + 0x38728000, + 0x3872c000, + 0x38730000, + 0x38734000, + 0x38738000, + 0x3873c000, + 0x38740000, + 0x38744000, + 0x38748000, + 0x3874c000, + 0x38750000, + 0x38754000, + 0x38758000, + 0x3875c000, + 0x38760000, + 0x38764000, + 0x38768000, + 0x3876c000, + 0x38770000, + 0x38774000, + 0x38778000, + 0x3877c000, + 0x38780000, + 0x38784000, + 0x38788000, + 0x3878c000, + 0x38790000, + 0x38794000, + 0x38798000, + 0x3879c000, + 0x387a0000, + 0x387a4000, + 0x387a8000, + 0x387ac000, + 0x387b0000, + 0x387b4000, + 0x387b8000, + 0x387bc000, + 0x387c0000, + 0x387c4000, + 0x387c8000, + 0x387cc000, + 0x387d0000, + 0x387d4000, + 0x387d8000, + 0x387dc000, + 0x387e0000, + 0x387e4000, + 0x387e8000, + 0x387ec000, + 0x387f0000, + 0x387f4000, + 0x387f8000, + 0x387fc000, + 0x38000000, + 0x38002000, + 0x38004000, + 0x38006000, + 0x38008000, + 0x3800a000, + 0x3800c000, + 0x3800e000, + 0x38010000, + 0x38012000, + 0x38014000, + 0x38016000, + 0x38018000, + 0x3801a000, + 0x3801c000, + 0x3801e000, + 0x38020000, + 0x38022000, + 0x38024000, + 0x38026000, + 0x38028000, + 0x3802a000, + 0x3802c000, + 0x3802e000, + 0x38030000, + 0x38032000, + 0x38034000, + 0x38036000, + 0x38038000, + 0x3803a000, + 0x3803c000, + 0x3803e000, + 0x38040000, + 0x38042000, + 0x38044000, + 0x38046000, + 0x38048000, + 0x3804a000, + 0x3804c000, + 0x3804e000, + 0x38050000, + 0x38052000, + 0x38054000, + 0x38056000, + 0x38058000, + 0x3805a000, + 0x3805c000, + 0x3805e000, + 0x38060000, + 0x38062000, + 0x38064000, + 0x38066000, + 0x38068000, + 0x3806a000, + 0x3806c000, + 0x3806e000, + 0x38070000, + 0x38072000, + 0x38074000, + 0x38076000, + 0x38078000, + 0x3807a000, + 0x3807c000, + 0x3807e000, + 0x38080000, + 0x38082000, + 0x38084000, + 0x38086000, + 0x38088000, + 0x3808a000, + 0x3808c000, + 0x3808e000, + 0x38090000, + 0x38092000, + 0x38094000, + 0x38096000, + 0x38098000, + 0x3809a000, + 0x3809c000, + 0x3809e000, + 0x380a0000, + 0x380a2000, + 0x380a4000, + 0x380a6000, + 0x380a8000, + 0x380aa000, + 0x380ac000, + 0x380ae000, + 0x380b0000, + 0x380b2000, + 0x380b4000, + 0x380b6000, + 0x380b8000, + 0x380ba000, + 0x380bc000, + 0x380be000, + 0x380c0000, + 0x380c2000, + 0x380c4000, + 0x380c6000, + 0x380c8000, + 0x380ca000, + 0x380cc000, + 0x380ce000, + 0x380d0000, + 0x380d2000, + 0x380d4000, + 0x380d6000, + 0x380d8000, + 0x380da000, + 0x380dc000, + 0x380de000, + 0x380e0000, + 0x380e2000, + 0x380e4000, + 0x380e6000, + 0x380e8000, + 0x380ea000, + 0x380ec000, + 0x380ee000, + 0x380f0000, + 0x380f2000, + 0x380f4000, + 0x380f6000, + 0x380f8000, + 0x380fa000, + 0x380fc000, + 0x380fe000, + 0x38100000, + 0x38102000, + 0x38104000, + 0x38106000, + 0x38108000, + 0x3810a000, + 0x3810c000, + 0x3810e000, + 0x38110000, + 0x38112000, + 0x38114000, + 0x38116000, + 0x38118000, + 0x3811a000, + 0x3811c000, + 0x3811e000, + 0x38120000, + 0x38122000, + 0x38124000, + 0x38126000, + 0x38128000, + 0x3812a000, + 0x3812c000, + 0x3812e000, + 0x38130000, + 0x38132000, + 0x38134000, + 0x38136000, + 0x38138000, + 0x3813a000, + 0x3813c000, + 0x3813e000, + 0x38140000, + 0x38142000, + 0x38144000, + 0x38146000, + 0x38148000, + 0x3814a000, + 0x3814c000, + 0x3814e000, + 0x38150000, + 0x38152000, + 0x38154000, + 0x38156000, + 0x38158000, + 0x3815a000, + 0x3815c000, + 0x3815e000, + 0x38160000, + 0x38162000, + 0x38164000, + 0x38166000, + 0x38168000, + 0x3816a000, + 0x3816c000, + 0x3816e000, + 0x38170000, + 0x38172000, + 0x38174000, + 0x38176000, + 0x38178000, + 0x3817a000, + 0x3817c000, + 0x3817e000, + 0x38180000, + 0x38182000, + 0x38184000, + 0x38186000, + 0x38188000, + 0x3818a000, + 0x3818c000, + 0x3818e000, + 0x38190000, + 0x38192000, + 0x38194000, + 0x38196000, + 0x38198000, + 0x3819a000, + 0x3819c000, + 0x3819e000, + 0x381a0000, + 0x381a2000, + 0x381a4000, + 0x381a6000, + 0x381a8000, + 0x381aa000, + 0x381ac000, + 0x381ae000, + 0x381b0000, + 0x381b2000, + 0x381b4000, + 0x381b6000, + 0x381b8000, + 0x381ba000, + 0x381bc000, + 0x381be000, + 0x381c0000, + 0x381c2000, + 0x381c4000, + 0x381c6000, + 0x381c8000, + 0x381ca000, + 0x381cc000, + 0x381ce000, + 0x381d0000, + 0x381d2000, + 0x381d4000, + 0x381d6000, + 0x381d8000, + 0x381da000, + 0x381dc000, + 0x381de000, + 0x381e0000, + 0x381e2000, + 0x381e4000, + 0x381e6000, + 0x381e8000, + 0x381ea000, + 0x381ec000, + 0x381ee000, + 0x381f0000, + 0x381f2000, + 0x381f4000, + 0x381f6000, + 0x381f8000, + 0x381fa000, + 0x381fc000, + 0x381fe000, + 0x38200000, + 0x38202000, + 0x38204000, + 0x38206000, + 0x38208000, + 0x3820a000, + 0x3820c000, + 0x3820e000, + 0x38210000, + 0x38212000, + 0x38214000, + 0x38216000, + 0x38218000, + 0x3821a000, + 0x3821c000, + 0x3821e000, + 0x38220000, + 0x38222000, + 0x38224000, + 0x38226000, + 0x38228000, + 0x3822a000, + 0x3822c000, + 0x3822e000, + 0x38230000, + 0x38232000, + 0x38234000, + 0x38236000, + 0x38238000, + 0x3823a000, + 0x3823c000, + 0x3823e000, + 0x38240000, + 0x38242000, + 0x38244000, + 0x38246000, + 0x38248000, + 0x3824a000, + 0x3824c000, + 0x3824e000, + 0x38250000, + 0x38252000, + 0x38254000, + 0x38256000, + 0x38258000, + 0x3825a000, + 0x3825c000, + 0x3825e000, + 0x38260000, + 0x38262000, + 0x38264000, + 0x38266000, + 0x38268000, + 0x3826a000, + 0x3826c000, + 0x3826e000, + 0x38270000, + 0x38272000, + 0x38274000, + 0x38276000, + 0x38278000, + 0x3827a000, + 0x3827c000, + 0x3827e000, + 0x38280000, + 0x38282000, + 0x38284000, + 0x38286000, + 0x38288000, + 0x3828a000, + 0x3828c000, + 0x3828e000, + 0x38290000, + 0x38292000, + 0x38294000, + 0x38296000, + 0x38298000, + 0x3829a000, + 0x3829c000, + 0x3829e000, + 0x382a0000, + 0x382a2000, + 0x382a4000, + 0x382a6000, + 0x382a8000, + 0x382aa000, + 0x382ac000, + 0x382ae000, + 0x382b0000, + 0x382b2000, + 0x382b4000, + 0x382b6000, + 0x382b8000, + 0x382ba000, + 0x382bc000, + 0x382be000, + 0x382c0000, + 0x382c2000, + 0x382c4000, + 0x382c6000, + 0x382c8000, + 0x382ca000, + 0x382cc000, + 0x382ce000, + 0x382d0000, + 0x382d2000, + 0x382d4000, + 0x382d6000, + 0x382d8000, + 0x382da000, + 0x382dc000, + 0x382de000, + 0x382e0000, + 0x382e2000, + 0x382e4000, + 0x382e6000, + 0x382e8000, + 0x382ea000, + 0x382ec000, + 0x382ee000, + 0x382f0000, + 0x382f2000, + 0x382f4000, + 0x382f6000, + 0x382f8000, + 0x382fa000, + 0x382fc000, + 0x382fe000, + 0x38300000, + 0x38302000, + 0x38304000, + 0x38306000, + 0x38308000, + 0x3830a000, + 0x3830c000, + 0x3830e000, + 0x38310000, + 0x38312000, + 0x38314000, + 0x38316000, + 0x38318000, + 0x3831a000, + 0x3831c000, + 0x3831e000, + 0x38320000, + 0x38322000, + 0x38324000, + 0x38326000, + 0x38328000, + 0x3832a000, + 0x3832c000, + 0x3832e000, + 0x38330000, + 0x38332000, + 0x38334000, + 0x38336000, + 0x38338000, + 0x3833a000, + 0x3833c000, + 0x3833e000, + 0x38340000, + 0x38342000, + 0x38344000, + 0x38346000, + 0x38348000, + 0x3834a000, + 0x3834c000, + 0x3834e000, + 0x38350000, + 0x38352000, + 0x38354000, + 0x38356000, + 0x38358000, + 0x3835a000, + 0x3835c000, + 0x3835e000, + 0x38360000, + 0x38362000, + 0x38364000, + 0x38366000, + 0x38368000, + 0x3836a000, + 0x3836c000, + 0x3836e000, + 0x38370000, + 0x38372000, + 0x38374000, + 0x38376000, + 0x38378000, + 0x3837a000, + 0x3837c000, + 0x3837e000, + 0x38380000, + 0x38382000, + 0x38384000, + 0x38386000, + 0x38388000, + 0x3838a000, + 0x3838c000, + 0x3838e000, + 0x38390000, + 0x38392000, + 0x38394000, + 0x38396000, + 0x38398000, + 0x3839a000, + 0x3839c000, + 0x3839e000, + 0x383a0000, + 0x383a2000, + 0x383a4000, + 0x383a6000, + 0x383a8000, + 0x383aa000, + 0x383ac000, + 0x383ae000, + 0x383b0000, + 0x383b2000, + 0x383b4000, + 0x383b6000, + 0x383b8000, + 0x383ba000, + 0x383bc000, + 0x383be000, + 0x383c0000, + 0x383c2000, + 0x383c4000, + 0x383c6000, + 0x383c8000, + 0x383ca000, + 0x383cc000, + 0x383ce000, + 0x383d0000, + 0x383d2000, + 0x383d4000, + 0x383d6000, + 0x383d8000, + 0x383da000, + 0x383dc000, + 0x383de000, + 0x383e0000, + 0x383e2000, + 0x383e4000, + 0x383e6000, + 0x383e8000, + 0x383ea000, + 0x383ec000, + 0x383ee000, + 0x383f0000, + 0x383f2000, + 0x383f4000, + 0x383f6000, + 0x383f8000, + 0x383fa000, + 0x383fc000, + 0x383fe000, + 0x38400000, + 0x38402000, + 0x38404000, + 0x38406000, + 0x38408000, + 0x3840a000, + 0x3840c000, + 0x3840e000, + 0x38410000, + 0x38412000, + 0x38414000, + 0x38416000, + 0x38418000, + 0x3841a000, + 0x3841c000, + 0x3841e000, + 0x38420000, + 0x38422000, + 0x38424000, + 0x38426000, + 0x38428000, + 0x3842a000, + 0x3842c000, + 0x3842e000, + 0x38430000, + 0x38432000, + 0x38434000, + 0x38436000, + 0x38438000, + 0x3843a000, + 0x3843c000, + 0x3843e000, + 0x38440000, + 0x38442000, + 0x38444000, + 0x38446000, + 0x38448000, + 0x3844a000, + 0x3844c000, + 0x3844e000, + 0x38450000, + 0x38452000, + 0x38454000, + 0x38456000, + 0x38458000, + 0x3845a000, + 0x3845c000, + 0x3845e000, + 0x38460000, + 0x38462000, + 0x38464000, + 0x38466000, + 0x38468000, + 0x3846a000, + 0x3846c000, + 0x3846e000, + 0x38470000, + 0x38472000, + 0x38474000, + 0x38476000, + 0x38478000, + 0x3847a000, + 0x3847c000, + 0x3847e000, + 0x38480000, + 0x38482000, + 0x38484000, + 0x38486000, + 0x38488000, + 0x3848a000, + 0x3848c000, + 0x3848e000, + 0x38490000, + 0x38492000, + 0x38494000, + 0x38496000, + 0x38498000, + 0x3849a000, + 0x3849c000, + 0x3849e000, + 0x384a0000, + 0x384a2000, + 0x384a4000, + 0x384a6000, + 0x384a8000, + 0x384aa000, + 0x384ac000, + 0x384ae000, + 0x384b0000, + 0x384b2000, + 0x384b4000, + 0x384b6000, + 0x384b8000, + 0x384ba000, + 0x384bc000, + 0x384be000, + 0x384c0000, + 0x384c2000, + 0x384c4000, + 0x384c6000, + 0x384c8000, + 0x384ca000, + 0x384cc000, + 0x384ce000, + 0x384d0000, + 0x384d2000, + 0x384d4000, + 0x384d6000, + 0x384d8000, + 0x384da000, + 0x384dc000, + 0x384de000, + 0x384e0000, + 0x384e2000, + 0x384e4000, + 0x384e6000, + 0x384e8000, + 0x384ea000, + 0x384ec000, + 0x384ee000, + 0x384f0000, + 0x384f2000, + 0x384f4000, + 0x384f6000, + 0x384f8000, + 0x384fa000, + 0x384fc000, + 0x384fe000, + 0x38500000, + 0x38502000, + 0x38504000, + 0x38506000, + 0x38508000, + 0x3850a000, + 0x3850c000, + 0x3850e000, + 0x38510000, + 0x38512000, + 0x38514000, + 0x38516000, + 0x38518000, + 0x3851a000, + 0x3851c000, + 0x3851e000, + 0x38520000, + 0x38522000, + 0x38524000, + 0x38526000, + 0x38528000, + 0x3852a000, + 0x3852c000, + 0x3852e000, + 0x38530000, + 0x38532000, + 0x38534000, + 0x38536000, + 0x38538000, + 0x3853a000, + 0x3853c000, + 0x3853e000, + 0x38540000, + 0x38542000, + 0x38544000, + 0x38546000, + 0x38548000, + 0x3854a000, + 0x3854c000, + 0x3854e000, + 0x38550000, + 0x38552000, + 0x38554000, + 0x38556000, + 0x38558000, + 0x3855a000, + 0x3855c000, + 0x3855e000, + 0x38560000, + 0x38562000, + 0x38564000, + 0x38566000, + 0x38568000, + 0x3856a000, + 0x3856c000, + 0x3856e000, + 0x38570000, + 0x38572000, + 0x38574000, + 0x38576000, + 0x38578000, + 0x3857a000, + 0x3857c000, + 0x3857e000, + 0x38580000, + 0x38582000, + 0x38584000, + 0x38586000, + 0x38588000, + 0x3858a000, + 0x3858c000, + 0x3858e000, + 0x38590000, + 0x38592000, + 0x38594000, + 0x38596000, + 0x38598000, + 0x3859a000, + 0x3859c000, + 0x3859e000, + 0x385a0000, + 0x385a2000, + 0x385a4000, + 0x385a6000, + 0x385a8000, + 0x385aa000, + 0x385ac000, + 0x385ae000, + 0x385b0000, + 0x385b2000, + 0x385b4000, + 0x385b6000, + 0x385b8000, + 0x385ba000, + 0x385bc000, + 0x385be000, + 0x385c0000, + 0x385c2000, + 0x385c4000, + 0x385c6000, + 0x385c8000, + 0x385ca000, + 0x385cc000, + 0x385ce000, + 0x385d0000, + 0x385d2000, + 0x385d4000, + 0x385d6000, + 0x385d8000, + 0x385da000, + 0x385dc000, + 0x385de000, + 0x385e0000, + 0x385e2000, + 0x385e4000, + 0x385e6000, + 0x385e8000, + 0x385ea000, + 0x385ec000, + 0x385ee000, + 0x385f0000, + 0x385f2000, + 0x385f4000, + 0x385f6000, + 0x385f8000, + 0x385fa000, + 0x385fc000, + 0x385fe000, + 0x38600000, + 0x38602000, + 0x38604000, + 0x38606000, + 0x38608000, + 0x3860a000, + 0x3860c000, + 0x3860e000, + 0x38610000, + 0x38612000, + 0x38614000, + 0x38616000, + 0x38618000, + 0x3861a000, + 0x3861c000, + 0x3861e000, + 0x38620000, + 0x38622000, + 0x38624000, + 0x38626000, + 0x38628000, + 0x3862a000, + 0x3862c000, + 0x3862e000, + 0x38630000, + 0x38632000, + 0x38634000, + 0x38636000, + 0x38638000, + 0x3863a000, + 0x3863c000, + 0x3863e000, + 0x38640000, + 0x38642000, + 0x38644000, + 0x38646000, + 0x38648000, + 0x3864a000, + 0x3864c000, + 0x3864e000, + 0x38650000, + 0x38652000, + 0x38654000, + 0x38656000, + 0x38658000, + 0x3865a000, + 0x3865c000, + 0x3865e000, + 0x38660000, + 0x38662000, + 0x38664000, + 0x38666000, + 0x38668000, + 0x3866a000, + 0x3866c000, + 0x3866e000, + 0x38670000, + 0x38672000, + 0x38674000, + 0x38676000, + 0x38678000, + 0x3867a000, + 0x3867c000, + 0x3867e000, + 0x38680000, + 0x38682000, + 0x38684000, + 0x38686000, + 0x38688000, + 0x3868a000, + 0x3868c000, + 0x3868e000, + 0x38690000, + 0x38692000, + 0x38694000, + 0x38696000, + 0x38698000, + 0x3869a000, + 0x3869c000, + 0x3869e000, + 0x386a0000, + 0x386a2000, + 0x386a4000, + 0x386a6000, + 0x386a8000, + 0x386aa000, + 0x386ac000, + 0x386ae000, + 0x386b0000, + 0x386b2000, + 0x386b4000, + 0x386b6000, + 0x386b8000, + 0x386ba000, + 0x386bc000, + 0x386be000, + 0x386c0000, + 0x386c2000, + 0x386c4000, + 0x386c6000, + 0x386c8000, + 0x386ca000, + 0x386cc000, + 0x386ce000, + 0x386d0000, + 0x386d2000, + 0x386d4000, + 0x386d6000, + 0x386d8000, + 0x386da000, + 0x386dc000, + 0x386de000, + 0x386e0000, + 0x386e2000, + 0x386e4000, + 0x386e6000, + 0x386e8000, + 0x386ea000, + 0x386ec000, + 0x386ee000, + 0x386f0000, + 0x386f2000, + 0x386f4000, + 0x386f6000, + 0x386f8000, + 0x386fa000, + 0x386fc000, + 0x386fe000, + 0x38700000, + 0x38702000, + 0x38704000, + 0x38706000, + 0x38708000, + 0x3870a000, + 0x3870c000, + 0x3870e000, + 0x38710000, + 0x38712000, + 0x38714000, + 0x38716000, + 0x38718000, + 0x3871a000, + 0x3871c000, + 0x3871e000, + 0x38720000, + 0x38722000, + 0x38724000, + 0x38726000, + 0x38728000, + 0x3872a000, + 0x3872c000, + 0x3872e000, + 0x38730000, + 0x38732000, + 0x38734000, + 0x38736000, + 0x38738000, + 0x3873a000, + 0x3873c000, + 0x3873e000, + 0x38740000, + 0x38742000, + 0x38744000, + 0x38746000, + 0x38748000, + 0x3874a000, + 0x3874c000, + 0x3874e000, + 0x38750000, + 0x38752000, + 0x38754000, + 0x38756000, + 0x38758000, + 0x3875a000, + 0x3875c000, + 0x3875e000, + 0x38760000, + 0x38762000, + 0x38764000, + 0x38766000, + 0x38768000, + 0x3876a000, + 0x3876c000, + 0x3876e000, + 0x38770000, + 0x38772000, + 0x38774000, + 0x38776000, + 0x38778000, + 0x3877a000, + 0x3877c000, + 0x3877e000, + 0x38780000, + 0x38782000, + 0x38784000, + 0x38786000, + 0x38788000, + 0x3878a000, + 0x3878c000, + 0x3878e000, + 0x38790000, + 0x38792000, + 0x38794000, + 0x38796000, + 0x38798000, + 0x3879a000, + 0x3879c000, + 0x3879e000, + 0x387a0000, + 0x387a2000, + 0x387a4000, + 0x387a6000, + 0x387a8000, + 0x387aa000, + 0x387ac000, + 0x387ae000, + 0x387b0000, + 0x387b2000, + 0x387b4000, + 0x387b6000, + 0x387b8000, + 0x387ba000, + 0x387bc000, + 0x387be000, + 0x387c0000, + 0x387c2000, + 0x387c4000, + 0x387c6000, + 0x387c8000, + 0x387ca000, + 0x387cc000, + 0x387ce000, + 0x387d0000, + 0x387d2000, + 0x387d4000, + 0x387d6000, + 0x387d8000, + 0x387da000, + 0x387dc000, + 0x387de000, + 0x387e0000, + 0x387e2000, + 0x387e4000, + 0x387e6000, + 0x387e8000, + 0x387ea000, + 0x387ec000, + 0x387ee000, + 0x387f0000, + 0x387f2000, + 0x387f4000, + 0x387f6000, + 0x387f8000, + 0x387fa000, + 0x387fc000, + 0x387fe000, +}; + +const static unsigned g_exponent[64] = { + 0x00000000, + 0x00800000, + 0x01000000, + 0x01800000, + 0x02000000, + 0x02800000, + 0x03000000, + 0x03800000, + 0x04000000, + 0x04800000, + 0x05000000, + 0x05800000, + 0x06000000, + 0x06800000, + 0x07000000, + 0x07800000, + 0x08000000, + 0x08800000, + 0x09000000, + 0x09800000, + 0x0a000000, + 0x0a800000, + 0x0b000000, + 0x0b800000, + 0x0c000000, + 0x0c800000, + 0x0d000000, + 0x0d800000, + 0x0e000000, + 0x0e800000, + 0x0f000000, + 0x47800000, + 0x80000000, + 0x80800000, + 0x81000000, + 0x81800000, + 0x82000000, + 0x82800000, + 0x83000000, + 0x83800000, + 0x84000000, + 0x84800000, + 0x85000000, + 0x85800000, + 0x86000000, + 0x86800000, + 0x87000000, + 0x87800000, + 0x88000000, + 0x88800000, + 0x89000000, + 0x89800000, + 0x8a000000, + 0x8a800000, + 0x8b000000, + 0x8b800000, + 0x8c000000, + 0x8c800000, + 0x8d000000, + 0x8d800000, + 0x8e000000, + 0x8e800000, + 0x8f000000, + 0xc7800000, +}; + +const static unsigned g_offset[64] = { + 0x00000000, + 0x00000400, + 0x00000400, + 0x00000400, + 0x00000400, + 0x00000400, + 0x00000400, + 0x00000400, + 0x00000400, + 0x00000400, + 0x00000400, + 0x00000400, + 0x00000400, + 0x00000400, + 0x00000400, + 0x00000400, + 0x00000400, + 0x00000400, + 0x00000400, + 0x00000400, + 0x00000400, + 0x00000400, + 0x00000400, + 0x00000400, + 0x00000400, + 0x00000400, + 0x00000400, + 0x00000400, + 0x00000400, + 0x00000400, + 0x00000400, + 0x00000400, + 0x00000000, + 0x00000400, + 0x00000400, + 0x00000400, + 0x00000400, + 0x00000400, + 0x00000400, + 0x00000400, + 0x00000400, + 0x00000400, + 0x00000400, + 0x00000400, + 0x00000400, + 0x00000400, + 0x00000400, + 0x00000400, + 0x00000400, + 0x00000400, + 0x00000400, + 0x00000400, + 0x00000400, + 0x00000400, + 0x00000400, + 0x00000400, + 0x00000400, + 0x00000400, + 0x00000400, + 0x00000400, + 0x00000400, + 0x00000400, + 0x00000400, + 0x00000400, +}; + +float float16ToFloat32(unsigned short h) +{ + unsigned i32 = g_mantissa[g_offset[h >> 10] + (h & 0x3ff)] + g_exponent[h >> 10]; + return bitCast(i32); +} +} + diff --git a/Source/ThirdParty/ANGLE/src/common/Float16ToFloat32.py b/Source/ThirdParty/ANGLE/src/common/Float16ToFloat32.py new file mode 100644 index 000000000000..7705f7b6192d --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/common/Float16ToFloat32.py @@ -0,0 +1,80 @@ +# Copyright (c) 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. +# + +# This script generates a function that converts 16-bit precision floating +# point numbers to 32-bit. +# It is based on ftp://ftp.fox-toolkit.org/pub/fasthalffloatconversion.pdf. + +#include "common/mathutil.h" + +def convertMantissa(i): + if i == 0: + return 0 + elif i < 1024: + m = i << 13 + e = 0 + while not (m & 0x00800000): + e -= 0x00800000 + m = m << 1 + m &= ~0x00800000 + e += 0x38800000 + return m | e + else: + return 0x38000000 + ((i - 1024) << 13) + +def convertExponent(i): + if i == 0: + return 0 + elif i in range(1, 31): + return i << 23 + elif i == 31: + return 0x47800000 + elif i == 32: + return 0x80000000 + elif i in range(33, 63): + return 0x80000000 + ((i - 32) << 23) + else: + return 0xC7800000 + +def convertOffset(i): + if i == 0 or i == 32: + return 0 + else: + return 1024 + +print """// +// Copyright (c) 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. +// + +// This file is automatically generated. + +namespace gl +{ +""" + +print "const static unsigned g_mantissa[2048] = {" +for i in range(0, 2048): + print " %#010x," % convertMantissa(i) +print "};\n" + +print "const static unsigned g_exponent[64] = {" +for i in range(0, 64): + print " %#010x," % convertExponent(i) +print "};\n" + +print "const static unsigned g_offset[64] = {" +for i in range(0, 64): + print " %#010x," % convertOffset(i) +print "};\n" + +print """float float16ToFloat32(unsigned short h) +{ + unsigned i32 = g_mantissa[g_offset[h >> 10] + (h & 0x3ff)] + g_exponent[h >> 10]; + return bitCast(i32); +} +} +""" diff --git a/Source/ThirdParty/ANGLE/src/common/Optional.h b/Source/ThirdParty/ANGLE/src/common/Optional.h index d3ccd13cf411..256f38f3290d 100644 --- a/Source/ThirdParty/ANGLE/src/common/Optional.h +++ b/Source/ThirdParty/ANGLE/src/common/Optional.h @@ -42,16 +42,20 @@ struct Optional return *this; } - void reset() + Optional &operator=(T &&value) { - mValid = false; + mValue = std::move(value); + mValid = true; + return *this; } - static Optional None() + void reset() { - return Optional(); + mValid = false; } + static Optional Invalid() { return Optional(); } + bool valid() const { return mValid; } const T &value() const { return mValue; } diff --git a/Source/ThirdParty/ANGLE/src/common/Optional_unittest.cpp b/Source/ThirdParty/ANGLE/src/common/Optional_unittest.cpp index 2d3821b488e6..810046184621 100644 --- a/Source/ThirdParty/ANGLE/src/common/Optional_unittest.cpp +++ b/Source/ThirdParty/ANGLE/src/common/Optional_unittest.cpp @@ -18,7 +18,7 @@ TEST(OptionalTest, BasicInvalid) { Optional testInvalid; ASSERT_FALSE(testInvalid.valid()); - ASSERT_EQ(Optional::None(), testInvalid); + ASSERT_EQ(Optional::Invalid(), testInvalid); } TEST(OptionalTest, BasicValid) @@ -26,7 +26,7 @@ TEST(OptionalTest, BasicValid) Optional testValid(3); ASSERT_TRUE(testValid.valid()); ASSERT_EQ(3, testValid.value()); - ASSERT_NE(Optional::None(), testValid); + ASSERT_NE(Optional::Invalid(), testValid); } TEST(OptionalTest, Copies) diff --git a/Source/ThirdParty/ANGLE/src/common/angleutils.cpp b/Source/ThirdParty/ANGLE/src/common/angleutils.cpp index af5eb6c4471f..7099c2173003 100644 --- a/Source/ThirdParty/ANGLE/src/common/angleutils.cpp +++ b/Source/ThirdParty/ANGLE/src/common/angleutils.cpp @@ -8,8 +8,15 @@ #include "common/debug.h" #include + +#include #include +namespace angle +{ +const uintptr_t DirtyPointer = std::numeric_limits::max(); +} + size_t FormatStringIntoVector(const char *fmt, va_list vararg, std::vector& outBuffer) { // Attempt to just print to the current buffer diff --git a/Source/ThirdParty/ANGLE/src/common/angleutils.h b/Source/ThirdParty/ANGLE/src/common/angleutils.h index f3d201993a71..a0178fd414bf 100644 --- a/Source/ThirdParty/ANGLE/src/common/angleutils.h +++ b/Source/ThirdParty/ANGLE/src/common/angleutils.h @@ -33,6 +33,7 @@ class NonCopyable void operator=(const NonCopyable&) = delete; }; +extern const uintptr_t DirtyPointer; } template @@ -70,9 +71,9 @@ void SafeDelete(T*& resource) template void SafeDeleteContainer(T& resource) { - for (typename T::iterator i = resource.begin(); i != resource.end(); i++) + for (auto &element : resource) { - SafeDelete(*i); + SafeDelete(element); } resource.clear(); } diff --git a/Source/ThirdParty/ANGLE/src/common/debug.cpp b/Source/ThirdParty/ANGLE/src/common/debug.cpp index 2fc0a2984a60..1fcc0629084a 100644 --- a/Source/ThirdParty/ANGLE/src/common/debug.cpp +++ b/Source/ThirdParty/ANGLE/src/common/debug.cpp @@ -44,16 +44,16 @@ void output(bool traceInDebugOnly, MessageType messageType, DebugTraceOutputType case DebugTraceOutputTypeNone: break; case DebugTraceOutputTypeBeginEvent: - g_debugAnnotator->beginEvent(formattedWideMessage); + g_debugAnnotator->beginEvent(formattedWideMessage.c_str()); break; case DebugTraceOutputTypeSetMarker: - g_debugAnnotator->setMarker(formattedWideMessage); + g_debugAnnotator->setMarker(formattedWideMessage.c_str()); break; } } std::string formattedMessage; - UNUSED_TRACE_VARIABLE(formattedMessage); + UNUSED_VARIABLE(formattedMessage); #if !defined(NDEBUG) && defined(_MSC_VER) if (messageType == MESSAGE_ERR) diff --git a/Source/ThirdParty/ANGLE/src/common/debug.h b/Source/ThirdParty/ANGLE/src/common/debug.h index 90b6f2b5b341..64cfef4cd944 100644 --- a/Source/ThirdParty/ANGLE/src/common/debug.h +++ b/Source/ThirdParty/ANGLE/src/common/debug.h @@ -16,7 +16,7 @@ #include "common/angleutils.h" #if !defined(TRACE_OUTPUT_FILE) -#define TRACE_OUTPUT_FILE "debug.txt" +#define TRACE_OUTPUT_FILE "angle_debug.txt" #endif namespace gl @@ -47,9 +47,9 @@ class DebugAnnotator : angle::NonCopyable public: DebugAnnotator() { }; virtual ~DebugAnnotator() { }; - virtual void beginEvent(const std::wstring &eventName) = 0; + virtual void beginEvent(const wchar_t *eventName) = 0; virtual void endEvent() = 0; - virtual void setMarker(const std::wstring &markerName) = 0; + virtual void setMarker(const wchar_t *markerName) = 0; virtual bool getStatus() = 0; }; @@ -63,6 +63,8 @@ bool DebugAnnotationsActive(); #define ANGLE_TRACE_ENABLED #endif +#define ANGLE_EMPTY_STATEMENT for (;;) break + // A macro to output a trace of a function call and its arguments to the debugging log #if defined(ANGLE_TRACE_ENABLED) #define TRACE(message, ...) gl::trace(true, gl::MESSAGE_TRACE, "trace: %s(%d): " message "\n", __FUNCTION__, __LINE__, ##__VA_ARGS__) @@ -89,7 +91,7 @@ bool DebugAnnotationsActive(); #if defined(_MSC_VER) #define EVENT(message, ...) gl::ScopedPerfEventHelper scopedPerfEventHelper ## __LINE__("%s" message "\n", __FUNCTION__, __VA_ARGS__); #else -#define EVENT(message, ...) gl::ScopedPerfEventHelper scopedPerfEventHelper(message "\n", ##__VA_ARGS__); +#define EVENT(message, ...) gl::ScopedPerfEventHelper scopedPerfEventHelper("%s" message "\n", __FUNCTION__, ##__VA_ARGS__); #endif // _MSC_VER #else #define EVENT(message, ...) (void(0)) @@ -101,22 +103,18 @@ bool DebugAnnotationsActive(); // A macro asserting a condition and outputting failures to the debug log #if !defined(NDEBUG) -#define ASSERT(expression) do { \ +#define ASSERT(expression) { \ if(!(expression)) \ - ERR("\t! Assert failed in %s(%d): "#expression"\n", __FUNCTION__, __LINE__); \ + ERR("\t! Assert failed in %s(%d): %s\n", __FUNCTION__, __LINE__, #expression); \ assert(expression); \ - } while(0) + } ANGLE_EMPTY_STATEMENT #define UNUSED_ASSERTION_VARIABLE(variable) #else #define ASSERT(expression) (void(0)) #define UNUSED_ASSERTION_VARIABLE(variable) ((void)variable) #endif -#ifndef ANGLE_ENABLE_DEBUG_TRACE -#define UNUSED_TRACE_VARIABLE(variable) ((void)variable) -#else -#define UNUSED_TRACE_VARIABLE(variable) -#endif +#define UNUSED_VARIABLE(variable) ((void)variable) // A macro to indicate unimplemented functionality @@ -131,20 +129,20 @@ bool DebugAnnotationsActive(); #endif #if !defined(NDEBUG) -#define UNIMPLEMENTED() do { \ +#define UNIMPLEMENTED() { \ FIXME("\t! Unimplemented: %s(%d)\n", __FUNCTION__, __LINE__); \ assert(NOASSERT_UNIMPLEMENTED); \ - } while(0) + } ANGLE_EMPTY_STATEMENT #else #define UNIMPLEMENTED() FIXME("\t! Unimplemented: %s(%d)\n", __FUNCTION__, __LINE__) #endif // A macro for code which is not expected to be reached under valid assumptions #if !defined(NDEBUG) -#define UNREACHABLE() do { \ +#define UNREACHABLE() { \ ERR("\t! Unreachable reached: %s(%d)\n", __FUNCTION__, __LINE__); \ assert(false); \ - } while(0) + } ANGLE_EMPTY_STATEMENT #else #define UNREACHABLE() ERR("\t! Unreachable reached: %s(%d)\n", __FUNCTION__, __LINE__) #endif diff --git a/Source/ThirdParty/ANGLE/src/common/mathutil.cpp b/Source/ThirdParty/ANGLE/src/common/mathutil.cpp index bb54736dc725..927b6ebebe27 100644 --- a/Source/ThirdParty/ANGLE/src/common/mathutil.cpp +++ b/Source/ThirdParty/ANGLE/src/common/mathutil.cpp @@ -52,7 +52,7 @@ unsigned int convertRGBFloatsTo999E5(float red, float green, float blue) output.B = static_cast(floor((blue_c / (pow(2.0f, exp_s - g_sharedexp_bias - g_sharedexp_mantissabits))) + 0.5f)); output.E = exp_s; - return *reinterpret_cast(&output); + return bitCast(output); } void convert999E5toRGBFloats(unsigned int input, float *red, float *green, float *blue) diff --git a/Source/ThirdParty/ANGLE/src/common/mathutil.h b/Source/ThirdParty/ANGLE/src/common/mathutil.h index 7959da8bdcbc..3de62aef1054 100644 --- a/Source/ThirdParty/ANGLE/src/common/mathutil.h +++ b/Source/ThirdParty/ANGLE/src/common/mathutil.h @@ -14,7 +14,9 @@ #include #include +#include #include +#include #include namespace gl @@ -67,14 +69,29 @@ inline int clampToInt(unsigned int x) template inline DestT clampCast(SrcT value) { - // This assumes SrcT can properly represent DestT::min/max - // Unfortunately we can't use META_ASSERT without C++11 constexpr support - ASSERT(static_cast(static_cast(std::numeric_limits::min())) == std::numeric_limits::min()); - ASSERT(static_cast(static_cast(std::numeric_limits::max())) == std::numeric_limits::max()); - - SrcT lo = static_cast(std::numeric_limits::min()); - SrcT hi = static_cast(std::numeric_limits::max()); - return static_cast(value > lo ? (value > hi ? hi : value) : lo); + static const DestT destLo = std::numeric_limits::min(); + static const DestT destHi = std::numeric_limits::max(); + static const SrcT srcLo = static_cast(destLo); + static const SrcT srcHi = static_cast(destHi); + + // When value is outside of or equal to the limits for DestT we use the DestT limit directly. + // This avoids undefined behaviors due to loss of precision when converting from floats to + // integers: + // destHi for ints is 2147483647 but the closest float number is around 2147483648, so when + // doing a conversion from float to int we run into an UB because the float is outside of the + // range representable by the int. + if (value <= srcLo) + { + return destLo; + } + else if (value >= srcHi) + { + return destHi; + } + else + { + return static_cast(value); + } } template @@ -149,7 +166,7 @@ destType bitCast(const sourceType &source) inline unsigned short float32ToFloat16(float fp32) { - unsigned int fp32i = (unsigned int&)fp32; + unsigned int fp32i = bitCast(fp32); unsigned int sign = (fp32i & 0x80000000) >> 16; unsigned int abs = fp32i & 0x7FFFFFFF; @@ -476,9 +493,10 @@ inline unsigned int average(unsigned int a, unsigned int b) return ((a ^ b) >> 1) + (a & b); } -inline signed int average(signed int a, signed int b) +inline int average(int a, int b) { - return (signed int)((long long)a + (long long)b) / 2; + long long average = (static_cast(a) + static_cast(b)) / 2ll; + return static_cast(average); } inline float average(float a, float b) @@ -501,12 +519,6 @@ inline unsigned int averageFloat10(unsigned int a, unsigned int b) return float32ToFloat10((float10ToFloat32(static_cast(a)) + float10ToFloat32(static_cast(b))) * 0.5f); } -} - -namespace rx -{ - -// Represents intervals of the type [a, b) template struct Range { @@ -529,11 +541,146 @@ struct Range return start < other.end; } } + + void extend(T value) + { + start = value > start ? value : start; + end = value < end ? value : end; + } + + bool empty() const + { + return end <= start; + } }; typedef Range RangeI; typedef Range RangeUI; +struct IndexRange +{ + IndexRange() : IndexRange(0, 0, 0) {} + IndexRange(size_t start_, size_t end_, size_t vertexIndexCount_) + : start(start_), end(end_), vertexIndexCount(vertexIndexCount_) + { + ASSERT(start <= end); + } + + // Number of vertices in the range. + size_t vertexCount() const { return (end - start) + 1; } + + // Inclusive range of indices that are not primitive restart + size_t start; + size_t end; + + // Number of non-primitive restart indices + size_t vertexIndexCount; +}; + +// First, both normalized floating-point values are converted into 16-bit integer values. +// Then, the results are packed into the returned 32-bit unsigned integer. +// The first float value will be written to the least significant bits of the output; +// the last float value will be written to the most significant bits. +// The conversion of each value to fixed point is done as follows : +// packSnorm2x16 : round(clamp(c, -1, +1) * 32767.0) +inline uint32_t packSnorm2x16(float f1, float f2) +{ + int16_t leastSignificantBits = static_cast(roundf(clamp(f1, -1.0f, 1.0f) * 32767.0f)); + int16_t mostSignificantBits = static_cast(roundf(clamp(f2, -1.0f, 1.0f) * 32767.0f)); + return static_cast(mostSignificantBits) << 16 | + (static_cast(leastSignificantBits) & 0xFFFF); +} + +// First, unpacks a single 32-bit unsigned integer u into a pair of 16-bit unsigned integers. Then, each +// component is converted to a normalized floating-point value to generate the returned two float values. +// The first float value will be extracted from the least significant bits of the input; +// the last float value will be extracted from the most-significant bits. +// The conversion for unpacked fixed-point value to floating point is done as follows: +// unpackSnorm2x16 : clamp(f / 32767.0, -1, +1) +inline void unpackSnorm2x16(uint32_t u, float *f1, float *f2) +{ + int16_t leastSignificantBits = static_cast(u & 0xFFFF); + int16_t mostSignificantBits = static_cast(u >> 16); + *f1 = clamp(static_cast(leastSignificantBits) / 32767.0f, -1.0f, 1.0f); + *f2 = clamp(static_cast(mostSignificantBits) / 32767.0f, -1.0f, 1.0f); +} + +// First, both normalized floating-point values are converted into 16-bit integer values. +// Then, the results are packed into the returned 32-bit unsigned integer. +// The first float value will be written to the least significant bits of the output; +// the last float value will be written to the most significant bits. +// The conversion of each value to fixed point is done as follows: +// packUnorm2x16 : round(clamp(c, 0, +1) * 65535.0) +inline uint32_t packUnorm2x16(float f1, float f2) +{ + uint16_t leastSignificantBits = static_cast(roundf(clamp(f1, 0.0f, 1.0f) * 65535.0f)); + uint16_t mostSignificantBits = static_cast(roundf(clamp(f2, 0.0f, 1.0f) * 65535.0f)); + return static_cast(mostSignificantBits) << 16 | static_cast(leastSignificantBits); +} + +// First, unpacks a single 32-bit unsigned integer u into a pair of 16-bit unsigned integers. Then, each +// component is converted to a normalized floating-point value to generate the returned two float values. +// The first float value will be extracted from the least significant bits of the input; +// the last float value will be extracted from the most-significant bits. +// The conversion for unpacked fixed-point value to floating point is done as follows: +// unpackUnorm2x16 : f / 65535.0 +inline void unpackUnorm2x16(uint32_t u, float *f1, float *f2) +{ + uint16_t leastSignificantBits = static_cast(u & 0xFFFF); + uint16_t mostSignificantBits = static_cast(u >> 16); + *f1 = static_cast(leastSignificantBits) / 65535.0f; + *f2 = static_cast(mostSignificantBits) / 65535.0f; +} + +// Returns an unsigned integer obtained by converting the two floating-point values to the 16-bit +// floating-point representation found in the OpenGL ES Specification, and then packing these +// two 16-bit integers into a 32-bit unsigned integer. +// f1: The 16 least-significant bits of the result; +// f2: The 16 most-significant bits. +inline uint32_t packHalf2x16(float f1, float f2) +{ + uint16_t leastSignificantBits = static_cast(float32ToFloat16(f1)); + uint16_t mostSignificantBits = static_cast(float32ToFloat16(f2)); + return static_cast(mostSignificantBits) << 16 | static_cast(leastSignificantBits); +} + +// Returns two floating-point values obtained by unpacking a 32-bit unsigned integer into a pair of 16-bit values, +// interpreting those values as 16-bit floating-point numbers according to the OpenGL ES Specification, +// and converting them to 32-bit floating-point values. +// The first float value is obtained from the 16 least-significant bits of u; +// the second component is obtained from the 16 most-significant bits of u. +inline void unpackHalf2x16(uint32_t u, float *f1, float *f2) +{ + uint16_t leastSignificantBits = static_cast(u & 0xFFFF); + uint16_t mostSignificantBits = static_cast(u >> 16); + + *f1 = float16ToFloat32(leastSignificantBits); + *f2 = float16ToFloat32(mostSignificantBits); +} + +// Returns whether the argument is Not a Number. +// IEEE 754 single precision NaN representation: Exponent(8 bits) - 255, Mantissa(23 bits) - non-zero. +inline bool isNaN(float f) +{ + // Exponent mask: ((1u << 8) - 1u) << 23 = 0x7f800000u + // Mantissa mask: ((1u << 23) - 1u) = 0x7fffffu + return ((bitCast(f) & 0x7f800000u) == 0x7f800000u) && (bitCast(f) & 0x7fffffu); +} + +// Returns whether the argument is infinity. +// IEEE 754 single precision infinity representation: Exponent(8 bits) - 255, Mantissa(23 bits) - zero. +inline bool isInf(float f) +{ + // Exponent mask: ((1u << 8) - 1u) << 23 = 0x7f800000u + // Mantissa mask: ((1u << 23) - 1u) = 0x7fffffu + return ((bitCast(f) & 0x7f800000u) == 0x7f800000u) && !(bitCast(f) & 0x7fffffu); +} + +} + +namespace rx +{ + template T roundUp(const T value, const T alignment) { @@ -569,6 +716,7 @@ inline bool IsIntegerCastSafe(BigIntT bigValue) #if defined(_MSC_VER) #define ANGLE_ROTL(x,y) _rotl(x,y) +#define ANGLE_ROTR16(x,y) _rotr16(x,y) #else @@ -577,7 +725,13 @@ inline uint32_t RotL(uint32_t x, int8_t r) return (x << r) | (x >> (32 - r)); } +inline uint16_t RotR16(uint16_t x, int8_t r) +{ + return (x >> r) | (x << (16 - r)); +} + #define ANGLE_ROTL(x,y) RotL(x,y) +#define ANGLE_ROTR16(x,y) RotR16(x,y) #endif // namespace rx diff --git a/Source/ThirdParty/ANGLE/src/common/mathutil_unittest.cpp b/Source/ThirdParty/ANGLE/src/common/mathutil_unittest.cpp new file mode 100644 index 000000000000..6c0608d98ba8 --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/common/mathutil_unittest.cpp @@ -0,0 +1,172 @@ +// +// 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. +// +// mathutil_unittest: +// Unit tests for the utils defined in mathutil.h +// + +#include "mathutil.h" + +#include + +using namespace gl; + +namespace +{ + +// Test the correctness of packSnorm2x16 and unpackSnorm2x16 functions. +// For floats f1 and f2, unpackSnorm2x16(packSnorm2x16(f1, f2)) should be same as f1 and f2. +TEST(MathUtilTest, packAndUnpackSnorm2x16) +{ + const float input[8][2] = + { + { 0.0f, 0.0f }, + { 1.0f, 1.0f }, + { -1.0f, 1.0f }, + { -1.0f, -1.0f }, + { 0.875f, 0.75f }, + { 0.00392f, -0.99215f }, + { -0.000675f, 0.004954f }, + { -0.6937f, -0.02146f } + }; + const float floatFaultTolerance = 0.0001f; + float outputVal1, outputVal2; + + for (size_t i = 0; i < 8; i++) + { + unpackSnorm2x16(packSnorm2x16(input[i][0], input[i][1]), &outputVal1, &outputVal2); + EXPECT_NEAR(input[i][0], outputVal1, floatFaultTolerance); + EXPECT_NEAR(input[i][1], outputVal2, floatFaultTolerance); + } +} + +// Test the correctness of packSnorm2x16 and unpackSnorm2x16 functions with infinity values, +// result should be clamped to [-1, 1]. +TEST(MathUtilTest, packAndUnpackSnorm2x16Infinity) +{ + const float floatFaultTolerance = 0.0001f; + float outputVal1, outputVal2; + + unpackSnorm2x16(packSnorm2x16(std::numeric_limits::infinity(), + std::numeric_limits::infinity()), &outputVal1, &outputVal2); + EXPECT_NEAR(1.0f, outputVal1, floatFaultTolerance); + EXPECT_NEAR(1.0f, outputVal2, floatFaultTolerance); + + unpackSnorm2x16(packSnorm2x16(std::numeric_limits::infinity(), + -std::numeric_limits::infinity()), &outputVal1, &outputVal2); + EXPECT_NEAR(1.0f, outputVal1, floatFaultTolerance); + EXPECT_NEAR(-1.0f, outputVal2, floatFaultTolerance); + + unpackSnorm2x16(packSnorm2x16(-std::numeric_limits::infinity(), + -std::numeric_limits::infinity()), &outputVal1, &outputVal2); + EXPECT_NEAR(-1.0f, outputVal1, floatFaultTolerance); + EXPECT_NEAR(-1.0f, outputVal2, floatFaultTolerance); +} + +// Test the correctness of packUnorm2x16 and unpackUnorm2x16 functions. +// For floats f1 and f2, unpackUnorm2x16(packUnorm2x16(f1, f2)) should be same as f1 and f2. +TEST(MathUtilTest, packAndUnpackUnorm2x16) +{ + const float input[8][2] = + { + { 0.0f, 0.0f }, + { 1.0f, 1.0f }, + { -1.0f, 1.0f }, + { -1.0f, -1.0f }, + { 0.875f, 0.75f }, + { 0.00392f, -0.99215f }, + { -0.000675f, 0.004954f }, + { -0.6937f, -0.02146f } + }; + const float floatFaultTolerance = 0.0001f; + float outputVal1, outputVal2; + + for (size_t i = 0; i < 8; i++) + { + unpackUnorm2x16(packUnorm2x16(input[i][0], input[i][1]), &outputVal1, &outputVal2); + float expected = input[i][0] < 0.0f ? 0.0f : input[i][0]; + EXPECT_NEAR(expected, outputVal1, floatFaultTolerance); + expected = input[i][1] < 0.0f ? 0.0f : input[i][1]; + EXPECT_NEAR(expected, outputVal2, floatFaultTolerance); + } +} + +// Test the correctness of packUnorm2x16 and unpackUnorm2x16 functions with infinity values, +// result should be clamped to [0, 1]. +TEST(MathUtilTest, packAndUnpackUnorm2x16Infinity) +{ + const float floatFaultTolerance = 0.0001f; + float outputVal1, outputVal2; + + unpackUnorm2x16(packUnorm2x16(std::numeric_limits::infinity(), + std::numeric_limits::infinity()), &outputVal1, &outputVal2); + EXPECT_NEAR(1.0f, outputVal1, floatFaultTolerance); + EXPECT_NEAR(1.0f, outputVal2, floatFaultTolerance); + + unpackUnorm2x16(packUnorm2x16(std::numeric_limits::infinity(), + -std::numeric_limits::infinity()), &outputVal1, &outputVal2); + EXPECT_NEAR(1.0f, outputVal1, floatFaultTolerance); + EXPECT_NEAR(0.0f, outputVal2, floatFaultTolerance); + + unpackUnorm2x16(packUnorm2x16(-std::numeric_limits::infinity(), + -std::numeric_limits::infinity()), &outputVal1, &outputVal2); + EXPECT_NEAR(0.0f, outputVal1, floatFaultTolerance); + EXPECT_NEAR(0.0f, outputVal2, floatFaultTolerance); +} + +// Test the correctness of packHalf2x16 and unpackHalf2x16 functions. +// For floats f1 and f2, unpackHalf2x16(packHalf2x16(f1, f2)) should be same as f1 and f2. +TEST(MathUtilTest, packAndUnpackHalf2x16) +{ + const float input[8][2] = + { + { 0.0f, 0.0f }, + { 1.0f, 1.0f }, + { -1.0f, 1.0f }, + { -1.0f, -1.0f }, + { 0.875f, 0.75f }, + { 0.00392f, -0.99215f }, + { -0.000675f, 0.004954f }, + { -0.6937f, -0.02146f }, + }; + const float floatFaultTolerance = 0.0005f; + float outputVal1, outputVal2; + + for (size_t i = 0; i < 8; i++) + { + unpackHalf2x16(packHalf2x16(input[i][0], input[i][1]), &outputVal1, &outputVal2); + EXPECT_NEAR(input[i][0], outputVal1, floatFaultTolerance); + EXPECT_NEAR(input[i][1], outputVal2, floatFaultTolerance); + } +} + +// Test the correctness of gl::isNaN function. +TEST(MathUtilTest, isNaN) +{ + EXPECT_TRUE(isNaN(bitCast(0xffu << 23 | 1u))); + EXPECT_TRUE(isNaN(bitCast(1u << 31 | 0xffu << 23 | 1u))); + EXPECT_TRUE(isNaN(bitCast(1u << 31 | 0xffu << 23 | 0x400000u))); + EXPECT_TRUE(isNaN(bitCast(1u << 31 | 0xffu << 23 | 0x7fffffu))); + EXPECT_FALSE(isNaN(0.0f)); + EXPECT_FALSE(isNaN(bitCast(1u << 31 | 0xffu << 23))); + EXPECT_FALSE(isNaN(bitCast(0xffu << 23))); +} + +// Test the correctness of gl::isInf function. +TEST(MathUtilTest, isInf) +{ + EXPECT_TRUE(isInf(bitCast(0xffu << 23))); + EXPECT_TRUE(isInf(bitCast(1u << 31 | 0xffu << 23))); + EXPECT_FALSE(isInf(0.0f)); + EXPECT_FALSE(isInf(bitCast(0xffu << 23 | 1u))); + EXPECT_FALSE(isInf(bitCast(1u << 31 | 0xffu << 23 | 1u))); + EXPECT_FALSE(isInf(bitCast(1u << 31 | 0xffu << 23 | 0x400000u))); + EXPECT_FALSE(isInf(bitCast(1u << 31 | 0xffu << 23 | 0x7fffffu))); + EXPECT_FALSE(isInf(bitCast(0xfeu << 23 | 0x7fffffu))); + EXPECT_FALSE(isInf(bitCast(1u << 31 | 0xfeu << 23 | 0x7fffffu))); +} + +} + diff --git a/Source/ThirdParty/ANGLE/src/common/matrix_utils.h b/Source/ThirdParty/ANGLE/src/common/matrix_utils.h new file mode 100644 index 000000000000..6f3187c3e8fc --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/common/matrix_utils.h @@ -0,0 +1,349 @@ +// +// 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. +// +// Matrix: +// Utility class implementing various matrix operations. +// Supports matrices with minimum 2 and maximum 4 number of rows/columns. +// +// TODO: Check if we can merge Matrix.h in sample_util with this and replace it with this implementation. +// TODO: Rename this file to Matrix.h once we remove Matrix.h in sample_util. + +#ifndef COMMON_MATRIX_UTILS_H_ +#define COMMON_MATRIX_UTILS_H_ + +#include + +#include "common/debug.h" + +namespace angle +{ + +template +class Matrix +{ + public: + Matrix(const std::vector &elements, const unsigned int &numRows, const unsigned int &numCols) + : mElements(elements), + mRows(numRows), + mCols(numCols) + { + ASSERT(rows() >= 1 && rows() <= 4); + ASSERT(columns() >= 1 && columns() <= 4); + } + + Matrix(const std::vector &elements, const unsigned int &size) + : mElements(elements), + mRows(size), + mCols(size) + { + ASSERT(rows() >= 1 && rows() <= 4); + ASSERT(columns() >= 1 && columns() <= 4); + } + + Matrix(const T *elements, const unsigned int &size) + : mRows(size), + mCols(size) + { + ASSERT(rows() >= 1 && rows() <= 4); + ASSERT(columns() >= 1 && columns() <= 4); + for (size_t i = 0; i < size * size; i++) + mElements.push_back(elements[i]); + } + + const T &operator()(const unsigned int &rowIndex, const unsigned int &columnIndex) const + { + return mElements[rowIndex * columns() + columnIndex]; + } + + T &operator()(const unsigned int &rowIndex, const unsigned int &columnIndex) + { + return mElements[rowIndex * columns() + columnIndex]; + } + + const T &at(const unsigned int &rowIndex, const unsigned int &columnIndex) const + { + return operator()(rowIndex, columnIndex); + } + + Matrix operator*(const Matrix &m) + { + ASSERT(columns() == m.rows()); + + unsigned int resultRows = rows(); + unsigned int resultCols = m.columns(); + Matrix result(std::vector(resultRows * resultCols), resultRows, resultCols); + for (unsigned int i = 0; i < resultRows; i++) + { + for (unsigned int j = 0; j < resultCols; j++) + { + T tmp = 0.0f; + for (unsigned int k = 0; k < columns(); k++) + tmp += at(i, k) * m(k, j); + result(i, j) = tmp; + } + } + + return result; + } + + unsigned int size() const + { + ASSERT(rows() == columns()); + return rows(); + } + + unsigned int rows() const { return mRows; } + + unsigned int columns() const { return mCols; } + + std::vector elements() const { return mElements; } + + Matrix compMult(const Matrix &mat1) const + { + Matrix result(std::vector(mElements.size()), size()); + for (unsigned int i = 0; i < columns(); i++) + for (unsigned int j = 0; j < rows(); j++) + result(i, j) = at(i, j) * mat1(i, j); + + return result; + } + + Matrix outerProduct(const Matrix &mat1) const + { + unsigned int cols = mat1.columns(); + Matrix result(std::vector(rows() * cols), rows(), cols); + for (unsigned int i = 0; i < rows(); i++) + for (unsigned int j = 0; j < cols; j++) + result(i, j) = at(i, 0) * mat1(0, j); + + return result; + } + + Matrix transpose() const + { + Matrix result(std::vector(mElements.size()), columns(), rows()); + for (unsigned int i = 0; i < columns(); i++) + for (unsigned int j = 0; j < rows(); j++) + result(i, j) = at(j, i); + + return result; + } + + T determinant() const + { + ASSERT(rows() == columns()); + + switch (size()) + { + case 2: + return at(0, 0) * at(1, 1) - at(0, 1) * at(1, 0); + + case 3: + return at(0, 0) * at(1, 1) * at(2, 2) + + at(0, 1) * at(1, 2) * at(2, 0) + + at(0, 2) * at(1, 0) * at(2, 1) - + at(0, 2) * at(1, 1) * at(2, 0) - + at(0, 1) * at(1, 0) * at(2, 2) - + at(0, 0) * at(1, 2) * at(2, 1); + + case 4: + { + const float minorMatrices[4][3 * 3] = + { + { + at(1, 1), at(2, 1), at(3, 1), + at(1, 2), at(2, 2), at(3, 2), + at(1, 3), at(2, 3), at(3, 3), + }, + { + at(1, 0), at(2, 0), at(3, 0), + at(1, 2), at(2, 2), at(3, 2), + at(1, 3), at(2, 3), at(3, 3), + }, + { + at(1, 0), at(2, 0), at(3, 0), + at(1, 1), at(2, 1), at(3, 1), + at(1, 3), at(2, 3), at(3, 3), + }, + { + at(1, 0), at(2, 0), at(3, 0), + at(1, 1), at(2, 1), at(3, 1), + at(1, 2), at(2, 2), at(3, 2), + } + }; + return at(0, 0) * Matrix(minorMatrices[0], 3).determinant() - + at(0, 1) * Matrix(minorMatrices[1], 3).determinant() + + at(0, 2) * Matrix(minorMatrices[2], 3).determinant() - + at(0, 3) * Matrix(minorMatrices[3], 3).determinant(); + } + + default: + UNREACHABLE(); + break; + } + + return T(); + } + + Matrix inverse() const + { + ASSERT(rows() == columns()); + + Matrix cof(std::vector(mElements.size()), rows(), columns()); + switch (size()) + { + case 2: + cof(0, 0) = at(1, 1); + cof(0, 1) = -at(1, 0); + cof(1, 0) = -at(0, 1); + cof(1, 1) = at(0, 0); + break; + + case 3: + cof(0, 0) = at(1, 1) * at(2, 2) - + at(2, 1) * at(1, 2); + cof(0, 1) = -(at(1, 0) * at(2, 2) - + at(2, 0) * at(1, 2)); + cof(0, 2) = at(1, 0) * at(2, 1) - + at(2, 0) * at(1, 1); + cof(1, 0) = -(at(0, 1) * at(2, 2) - + at(2, 1) * at(0, 2)); + cof(1, 1) = at(0, 0) * at(2, 2) - + at(2, 0) * at(0, 2); + cof(1, 2) = -(at(0, 0) * at(2, 1) - + at(2, 0) * at(0, 1)); + cof(2, 0) = at(0, 1) * at(1, 2) - + at(1, 1) * at(0, 2); + cof(2, 1) = -(at(0, 0) * at(1, 2) - + at(1, 0) * at(0, 2)); + cof(2, 2) = at(0, 0) * at(1, 1) - + at(1, 0) * at(0, 1); + break; + + case 4: + cof(0, 0) = at(1, 1) * at(2, 2) * at(3, 3) + + at(2, 1) * at(3, 2) * at(1, 3) + + at(3, 1) * at(1, 2) * at(2, 3) - + at(1, 1) * at(3, 2) * at(2, 3) - + at(2, 1) * at(1, 2) * at(3, 3) - + at(3, 1) * at(2, 2) * at(1, 3); + cof(0, 1) = -(at(1, 0) * at(2, 2) * at(3, 3) + + at(2, 0) * at(3, 2) * at(1, 3) + + at(3, 0) * at(1, 2) * at(2, 3) - + at(1, 0) * at(3, 2) * at(2, 3) - + at(2, 0) * at(1, 2) * at(3, 3) - + at(3, 0) * at(2, 2) * at(1, 3)); + cof(0, 2) = at(1, 0) * at(2, 1) * at(3, 3) + + at(2, 0) * at(3, 1) * at(1, 3) + + at(3, 0) * at(1, 1) * at(2, 3) - + at(1, 0) * at(3, 1) * at(2, 3) - + at(2, 0) * at(1, 1) * at(3, 3) - + at(3, 0) * at(2, 1) * at(1, 3); + cof(0, 3) = -(at(1, 0) * at(2, 1) * at(3, 2) + + at(2, 0) * at(3, 1) * at(1, 2) + + at(3, 0) * at(1, 1) * at(2, 2) - + at(1, 0) * at(3, 1) * at(2, 2) - + at(2, 0) * at(1, 1) * at(3, 2) - + at(3, 0) * at(2, 1) * at(1, 2)); + cof(1, 0) = -(at(0, 1) * at(2, 2) * at(3, 3) + + at(2, 1) * at(3, 2) * at(0, 3) + + at(3, 1) * at(0, 2) * at(2, 3) - + at(0, 1) * at(3, 2) * at(2, 3) - + at(2, 1) * at(0, 2) * at(3, 3) - + at(3, 1) * at(2, 2) * at(0, 3)); + cof(1, 1) = at(0, 0) * at(2, 2) * at(3, 3) + + at(2, 0) * at(3, 2) * at(0, 3) + + at(3, 0) * at(0, 2) * at(2, 3) - + at(0, 0) * at(3, 2) * at(2, 3) - + at(2, 0) * at(0, 2) * at(3, 3) - + at(3, 0) * at(2, 2) * at(0, 3); + cof(1, 2) = -(at(0, 0) * at(2, 1) * at(3, 3) + + at(2, 0) * at(3, 1) * at(0, 3) + + at(3, 0) * at(0, 1) * at(2, 3) - + at(0, 0) * at(3, 1) * at(2, 3) - + at(2, 0) * at(0, 1) * at(3, 3) - + at(3, 0) * at(2, 1) * at(0, 3)); + cof(1, 3) = at(0, 0) * at(2, 1) * at(3, 2) + + at(2, 0) * at(3, 1) * at(0, 2) + + at(3, 0) * at(0, 1) * at(2, 2) - + at(0, 0) * at(3, 1) * at(2, 2) - + at(2, 0) * at(0, 1) * at(3, 2) - + at(3, 0) * at(2, 1) * at(0, 2); + cof(2, 0) = at(0, 1) * at(1, 2) * at(3, 3) + + at(1, 1) * at(3, 2) * at(0, 3) + + at(3, 1) * at(0, 2) * at(1, 3) - + at(0, 1) * at(3, 2) * at(1, 3) - + at(1, 1) * at(0, 2) * at(3, 3) - + at(3, 1) * at(1, 2) * at(0, 3); + cof(2, 1) = -(at(0, 0) * at(1, 2) * at(3, 3) + + at(1, 0) * at(3, 2) * at(0, 3) + + at(3, 0) * at(0, 2) * at(1, 3) - + at(0, 0) * at(3, 2) * at(1, 3) - + at(1, 0) * at(0, 2) * at(3, 3) - + at(3, 0) * at(1, 2) * at(0, 3)); + cof(2, 2) = at(0, 0) * at(1, 1) * at(3, 3) + + at(1, 0) * at(3, 1) * at(0, 3) + + at(3, 0) * at(0, 1) * at(1, 3) - + at(0, 0) * at(3, 1) * at(1, 3) - + at(1, 0) * at(0, 1) * at(3, 3) - + at(3, 0) * at(1, 1) * at(0, 3); + cof(2, 3) = -(at(0, 0) * at(1, 1) * at(3, 2) + + at(1, 0) * at(3, 1) * at(0, 2) + + at(3, 0) * at(0, 1) * at(1, 2) - + at(0, 0) * at(3, 1) * at(1, 2) - + at(1, 0) * at(0, 1) * at(3, 2) - + at(3, 0) * at(1, 1) * at(0, 2)); + cof(3, 0) = -(at(0, 1) * at(1, 2) * at(2, 3) + + at(1, 1) * at(2, 2) * at(0, 3) + + at(2, 1) * at(0, 2) * at(1, 3) - + at(0, 1) * at(2, 2) * at(1, 3) - + at(1, 1) * at(0, 2) * at(2, 3) - + at(2, 1) * at(1, 2) * at(0, 3)); + cof(3, 1) = at(0, 0) * at(1, 2) * at(2, 3) + + at(1, 0) * at(2, 2) * at(0, 3) + + at(2, 0) * at(0, 2) * at(1, 3) - + at(0, 0) * at(2, 2) * at(1, 3) - + at(1, 0) * at(0, 2) * at(2, 3) - + at(2, 0) * at(1, 2) * at(0, 3); + cof(3, 2) = -(at(0, 0) * at(1, 1) * at(2, 3) + + at(1, 0) * at(2, 1) * at(0, 3) + + at(2, 0) * at(0, 1) * at(1, 3) - + at(0, 0) * at(2, 1) * at(1, 3) - + at(1, 0) * at(0, 1) * at(2, 3) - + at(2, 0) * at(1, 1) * at(0, 3)); + cof(3, 3) = at(0, 0) * at(1, 1) * at(2, 2) + + at(1, 0) * at(2, 1) * at(0, 2) + + at(2, 0) * at(0, 1) * at(1, 2) - + at(0, 0) * at(2, 1) * at(1, 2) - + at(1, 0) * at(0, 1) * at(2, 2) - + at(2, 0) * at(1, 1) * at(0, 2); + break; + + default: + UNREACHABLE(); + break; + } + + // The inverse of A is the transpose of the cofactor matrix times the reciprocal of the determinant of A. + Matrix adjugateMatrix(cof.transpose()); + T det = determinant(); + Matrix result(std::vector(mElements.size()), rows(), columns()); + for (unsigned int i = 0; i < rows(); i++) + for (unsigned int j = 0; j < columns(); j++) + result(i, j) = det ? adjugateMatrix(i, j) / det : T(); + + return result; + } + + private: + std::vector mElements; + unsigned int mRows; + unsigned int mCols; +}; + +} // namespace angle + +#endif // COMMON_MATRIX_UTILS_H_ + diff --git a/Source/ThirdParty/ANGLE/src/common/matrix_utils_unittest.cpp b/Source/ThirdParty/ANGLE/src/common/matrix_utils_unittest.cpp new file mode 100644 index 000000000000..6e9f92d9a82b --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/common/matrix_utils_unittest.cpp @@ -0,0 +1,184 @@ +// +// 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. +// +// matrix_utils_unittests: +// Unit tests for the matrix utils. +// + +#include "matrix_utils.h" + +#include + +using namespace angle; + +namespace +{ + +const unsigned int minDimensions = 2; +const unsigned int maxDimensions = 4; + +TEST(MatrixUtilsTest, MatrixConstructorTest) +{ + for (unsigned int i = minDimensions; i <= maxDimensions; i++) + { + for (unsigned int j = minDimensions; j <= maxDimensions; j++) + { + unsigned int numElements = i * j; + Matrix m(std::vector(numElements, 1.0f), i, j); + EXPECT_EQ(m.rows(), i); + EXPECT_EQ(m.columns(), j); + EXPECT_EQ(m.elements(), std::vector(numElements, 1.0f)); + } + } + + for (unsigned int i = minDimensions; i <= maxDimensions; i++) + { + unsigned int numElements = i * i; + Matrix m(std::vector(numElements, 1.0f), i); + EXPECT_EQ(m.size(), i); + EXPECT_EQ(m.columns(), m.columns()); + EXPECT_EQ(m.elements(), std::vector(numElements, 1.0f)); + } +} + +TEST(MatrixUtilsTest, MatrixCompMultTest) +{ + for (unsigned int i = minDimensions; i <= maxDimensions; i++) + { + unsigned int numElements = i * i; + Matrix m1(std::vector(numElements, 2.0f), i); + Matrix actualResult = m1.compMult(m1); + std::vector actualResultElements = actualResult.elements(); + std::vector expectedResultElements(numElements, 4.0f); + EXPECT_EQ(expectedResultElements, actualResultElements); + } +} + +TEST(MatrixUtilsTest, MatrixOuterProductTest) +{ + for (unsigned int i = minDimensions; i <= maxDimensions; i++) + { + for (unsigned int j = minDimensions; j <= maxDimensions; j++) + { + unsigned int numElements = i * j; + Matrix m1(std::vector(numElements, 2.0f), i, 1); + Matrix m2(std::vector(numElements, 2.0f), 1, j); + Matrix actualResult = m1.outerProduct(m2); + EXPECT_EQ(actualResult.rows(), i); + EXPECT_EQ(actualResult.columns(), j); + std::vector actualResultElements = actualResult.elements(); + std::vector expectedResultElements(numElements, 4.0f); + EXPECT_EQ(expectedResultElements, actualResultElements); + } + } +} + +TEST(MatrixUtilsTest, MatrixTransposeTest) +{ + for (unsigned int i = minDimensions; i <= maxDimensions; i++) + { + for (unsigned int j = minDimensions; j <= maxDimensions; j++) + { + unsigned int numElements = i * j; + Matrix m1(std::vector(numElements, 2.0f), i, j); + Matrix expectedResult = Matrix(std::vector(numElements, 2.0f), j, i); + Matrix actualResult = m1.transpose(); + EXPECT_EQ(expectedResult.elements(), actualResult.elements()); + EXPECT_EQ(actualResult.rows(), expectedResult.rows()); + EXPECT_EQ(actualResult.columns(), expectedResult.columns()); + // transpose(transpose(A)) = A + Matrix m2 = actualResult.transpose(); + EXPECT_EQ(m1.elements(), m2.elements()); + } + } +} + +TEST(MatrixUtilsTest, MatrixDeterminantTest) +{ + for (unsigned int i = minDimensions; i <= maxDimensions; i++) + { + unsigned int numElements = i * i; + Matrix m(std::vector(numElements, 2.0f), i); + EXPECT_EQ(m.determinant(), 0.0f); + } +} + +TEST(MatrixUtilsTest, 2x2MatrixInverseTest) +{ + float inputElements[] = + { + 2.0f, 5.0f, + 3.0f, 7.0f + }; + unsigned int numElements = 4; + std::vector input(inputElements, inputElements + numElements); + Matrix inputMatrix(input, 2); + float identityElements[] = + { + 1.0f, 0.0f, + 0.0f, 1.0f + }; + std::vector identityMatrix(identityElements, identityElements + numElements); + // A * inverse(A) = I, where I is identity matrix. + Matrix result = inputMatrix * inputMatrix.inverse(); + EXPECT_EQ(identityMatrix, result.elements()); +} + +TEST(MatrixUtilsTest, 3x3MatrixInverseTest) +{ + float inputElements[] = + { + 11.0f, 23.0f, 37.0f, + 13.0f, 29.0f, 41.0f, + 19.0f, 31.0f, 43.0f + }; + unsigned int numElements = 9; + std::vector input(inputElements, inputElements + numElements); + Matrix inputMatrix(input, 3); + float identityElements[] = + { + 1.0f, 0.0f, 0.0f, + 0.0f, 1.0f, 0.0f, + 0.0f, 0.0f, 1.0f + }; + std::vector identityMatrix(identityElements, identityElements + numElements); + // A * inverse(A) = I, where I is identity matrix. + Matrix result = inputMatrix * inputMatrix.inverse(); + std::vector resultElements = result.elements(); + const float floatFaultTolarance = 0.000001f; + for (size_t i = 0; i < numElements; i++) + EXPECT_NEAR(resultElements[i], identityMatrix[i], floatFaultTolarance); +} + +TEST(MatrixUtilsTest, 4x4MatrixInverseTest) +{ + float inputElements[] = + { + 29.0f, 43.0f, 61.0f, 79.0f, + 31.0f, 47.0f, 67.0f, 83.0f, + 37.0f, 53.0f, 71.0f, 89.0f, + 41.0f, 59.0f, 73.0f, 97.0f + }; + unsigned int numElements = 16; + std::vector input(inputElements, inputElements + numElements); + Matrix inputMatrix(input, 4); + float identityElements[] = + { + 1.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 1.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 1.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f, + }; + std::vector identityMatrix(identityElements, identityElements + numElements); + // A * inverse(A) = I, where I is identity matrix. + Matrix result = inputMatrix * inputMatrix.inverse(); + std::vector resultElements = result.elements(); + const float floatFaultTolarance = 0.00001f; + for (unsigned int i = 0; i < numElements; i++) + EXPECT_NEAR(resultElements[i], identityMatrix[i], floatFaultTolarance); +} + +} + diff --git a/Source/ThirdParty/ANGLE/src/common/string_utils.cpp b/Source/ThirdParty/ANGLE/src/common/string_utils.cpp new file mode 100644 index 000000000000..acb0376bf9b0 --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/common/string_utils.cpp @@ -0,0 +1,136 @@ +// +// 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. +// +// string_utils: +// String helper functions. +// + +#include "string_utils.h" + +#include +#include + +namespace angle +{ + +const char kWhitespaceASCII[] = " \f\n\r\t\v"; + +std::vector SplitString(const std::string &input, + const std::string &delimiters, + WhitespaceHandling whitespace, + SplitResult resultType) +{ + std::vector result; + if (input.empty()) + { + return result; + } + + std::string::size_type start = 0; + while (start != std::string::npos) + { + auto end = input.find_first_of(delimiters, start); + + std::string piece; + if (end == std::string::npos) + { + piece = input.substr(start); + start = std::string::npos; + } + else + { + piece = input.substr(start, end - start); + start = end + 1; + } + + if (whitespace == TRIM_WHITESPACE) + { + piece = TrimString(piece, kWhitespaceASCII); + } + + if (resultType == SPLIT_WANT_ALL || !piece.empty()) + { + result.push_back(piece); + } + } + + return result; +} + +void SplitStringAlongWhitespace(const std::string &input, + std::vector *tokensOut) +{ + + std::istringstream stream(input); + std::string line; + + while (std::getline(stream, line)) + { + size_t prev = 0, pos; + while ((pos = line.find_first_of(kWhitespaceASCII, prev)) != std::string::npos) + { + if (pos > prev) + tokensOut->push_back(line.substr(prev, pos - prev)); + prev = pos + 1; + } + if (prev < line.length()) + tokensOut->push_back(line.substr(prev, std::string::npos)); + } +} + +std::string TrimString(const std::string &input, const std::string &trimChars) +{ + auto begin = input.find_first_not_of(trimChars); + if (begin == std::string::npos) + { + return ""; + } + + std::string::size_type end = input.find_last_not_of(trimChars); + if (end == std::string::npos) + { + return input.substr(begin); + } + + return input.substr(begin, end - begin + 1); +} + +bool HexStringToUInt(const std::string &input, unsigned int *uintOut) +{ + unsigned int offset = 0; + + if (input.size() >= 2 && input[0] == '0' && input[1] == 'x') + { + offset = 2u; + } + + // Simple validity check + if (input.find_first_not_of("0123456789ABCDEFabcdef", offset) != std::string::npos) + { + return false; + } + + std::stringstream inStream(input); + inStream >> std::hex >> *uintOut; + return !inStream.fail(); +} + +bool ReadFileToString(const std::string &path, std::string *stringOut) +{ + std::ifstream inFile(path.c_str()); + if (inFile.fail()) + { + return false; + } + + inFile.seekg(0, std::ios::end); + stringOut->reserve(static_cast(inFile.tellg())); + inFile.seekg(0, std::ios::beg); + + stringOut->assign(std::istreambuf_iterator(inFile), std::istreambuf_iterator()); + return !inFile.fail(); +} + +} diff --git a/Source/ThirdParty/ANGLE/src/common/string_utils.h b/Source/ThirdParty/ANGLE/src/common/string_utils.h new file mode 100644 index 000000000000..131b17e086ac --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/common/string_utils.h @@ -0,0 +1,49 @@ +// +// 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. +// +// string_utils: +// String helper functions. +// + +#ifndef LIBANGLE_STRING_UTILS_H_ +#define LIBANGLE_STRING_UTILS_H_ + +#include +#include + +namespace angle +{ + +extern const char kWhitespaceASCII[]; + +enum WhitespaceHandling +{ + KEEP_WHITESPACE, + TRIM_WHITESPACE, +}; + +enum SplitResult +{ + SPLIT_WANT_ALL, + SPLIT_WANT_NONEMPTY, +}; + +std::vector SplitString(const std::string &input, + const std::string &delimiters, + WhitespaceHandling whitespace, + SplitResult resultType); + +void SplitStringAlongWhitespace(const std::string &input, + std::vector *tokensOut); + +std::string TrimString(const std::string &input, const std::string &trimChars); + +bool HexStringToUInt(const std::string &input, unsigned int *uintOut); + +bool ReadFileToString(const std::string &path, std::string *stringOut); + +} + +#endif // LIBANGLE_STRING_UTILS_H_ diff --git a/Source/ThirdParty/ANGLE/src/common/string_utils_unittest.cpp b/Source/ThirdParty/ANGLE/src/common/string_utils_unittest.cpp new file mode 100644 index 000000000000..1ab03d003a51 --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/common/string_utils_unittest.cpp @@ -0,0 +1,141 @@ +// +// 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. +// +// string_utils_unittests: +// Unit tests for the string utils. +// + +#include "string_utils.h" + +#include + +using namespace angle; + +namespace +{ + +// Basic SplitString tests +TEST(StringUtilsTest, SplitString_Basics) +{ + std::vector r; + + r = SplitString(std::string(), ",:;", KEEP_WHITESPACE, SPLIT_WANT_ALL); + EXPECT_TRUE(r.empty()); + + // Empty separator list + r = SplitString("hello, world", "", KEEP_WHITESPACE, SPLIT_WANT_ALL); + ASSERT_EQ(1u, r.size()); + EXPECT_EQ("hello, world", r[0]); + + // Should split on any of the separators. + r = SplitString("::,,;;", ",:;", KEEP_WHITESPACE, SPLIT_WANT_ALL); + ASSERT_EQ(7u, r.size()); + for (auto str : r) + ASSERT_TRUE(str.empty()); + + r = SplitString("red, green; blue:", ",:;", TRIM_WHITESPACE, SPLIT_WANT_NONEMPTY); + ASSERT_EQ(3u, r.size()); + EXPECT_EQ("red", r[0]); + EXPECT_EQ("green", r[1]); + EXPECT_EQ("blue", r[2]); + + // Want to split a string along whitespace sequences. + r = SplitString(" red green \tblue\n", " \t\n", TRIM_WHITESPACE, SPLIT_WANT_NONEMPTY); + ASSERT_EQ(3u, r.size()); + EXPECT_EQ("red", r[0]); + EXPECT_EQ("green", r[1]); + EXPECT_EQ("blue", r[2]); + + // Weird case of splitting on spaces but not trimming. + r = SplitString(" red ", " ", TRIM_WHITESPACE, SPLIT_WANT_ALL); + ASSERT_EQ(3u, r.size()); + EXPECT_EQ("", r[0]); // Before the first space. + EXPECT_EQ("red", r[1]); + EXPECT_EQ("", r[2]); // After the last space. +} + +// Check different whitespace and result types for SplitString +TEST(StringUtilsTest, SplitString_WhitespaceAndResultType) +{ + std::vector r; + + // Empty input handling. + r = SplitString(std::string(), ",", KEEP_WHITESPACE, SPLIT_WANT_ALL); + EXPECT_TRUE(r.empty()); + r = SplitString(std::string(), ",", KEEP_WHITESPACE, SPLIT_WANT_NONEMPTY); + EXPECT_TRUE(r.empty()); + + // Input string is space and we're trimming. + r = SplitString(" ", ",", TRIM_WHITESPACE, SPLIT_WANT_ALL); + ASSERT_EQ(1u, r.size()); + EXPECT_EQ("", r[0]); + r = SplitString(" ", ",", TRIM_WHITESPACE, SPLIT_WANT_NONEMPTY); + EXPECT_TRUE(r.empty()); + + // Test all 4 combinations of flags on ", ,". + r = SplitString(", ,", ",", KEEP_WHITESPACE, SPLIT_WANT_ALL); + ASSERT_EQ(3u, r.size()); + EXPECT_EQ("", r[0]); + EXPECT_EQ(" ", r[1]); + EXPECT_EQ("", r[2]); + r = SplitString(", ,", ",", KEEP_WHITESPACE, SPLIT_WANT_NONEMPTY); + ASSERT_EQ(1u, r.size()); + ASSERT_EQ(" ", r[0]); + r = SplitString(", ,", ",", TRIM_WHITESPACE, SPLIT_WANT_ALL); + ASSERT_EQ(3u, r.size()); + EXPECT_EQ("", r[0]); + EXPECT_EQ("", r[1]); + EXPECT_EQ("", r[2]); + r = SplitString(", ,", ",", TRIM_WHITESPACE, SPLIT_WANT_NONEMPTY); + ASSERT_TRUE(r.empty()); +} + +// Tests for TrimString +TEST(StringUtilsTest, TrimString) +{ + // Basic tests + EXPECT_EQ("a", TrimString("a", kWhitespaceASCII)); + EXPECT_EQ("a", TrimString(" a", kWhitespaceASCII)); + EXPECT_EQ("a", TrimString("a ", kWhitespaceASCII)); + EXPECT_EQ("a", TrimString(" a ", kWhitespaceASCII)); + + // Tests with empty strings + EXPECT_EQ("", TrimString("", kWhitespaceASCII)); + EXPECT_EQ("", TrimString(" \n\r\t", kWhitespaceASCII)); + EXPECT_EQ(" foo ", TrimString(" foo ", "")); + + // Tests it doesn't removes characters in the middle + EXPECT_EQ("foo bar", TrimString(" foo bar ", kWhitespaceASCII)); + + // Test with non-whitespace trimChars + EXPECT_EQ(" ", TrimString("foo bar", "abcdefghijklmnopqrstuvwxyz")); +} + +// Basic functionality tests for HexStringToUInt +TEST(StringUtilsTest, HexStringToUIntBasic) +{ + unsigned int uintValue; + + std::string emptyString; + ASSERT_FALSE(HexStringToUInt(emptyString, &uintValue)); + + std::string testStringA("0xBADF00D"); + ASSERT_TRUE(HexStringToUInt(testStringA, &uintValue)); + EXPECT_EQ(0xBADF00Du, uintValue); + + std::string testStringB("0xBADFOOD"); + EXPECT_FALSE(HexStringToUInt(testStringB, &uintValue)); + + std::string testStringC("BADF00D"); + EXPECT_TRUE(HexStringToUInt(testStringC, &uintValue)); + EXPECT_EQ(0xBADF00Du, uintValue); + + std::string testStringD("0x BADF00D"); + EXPECT_FALSE(HexStringToUInt(testStringD, &uintValue)); +} + +// Note: ReadFileToString is harder to test + +} diff --git a/Source/ThirdParty/ANGLE/src/common/utilities.cpp b/Source/ThirdParty/ANGLE/src/common/utilities.cpp index a5332e3a8323..2ab913b10fff 100644 --- a/Source/ThirdParty/ANGLE/src/common/utilities.cpp +++ b/Source/ThirdParty/ANGLE/src/common/utilities.cpp @@ -19,6 +19,78 @@ # include #endif +namespace +{ + +template +gl::IndexRange ComputeTypedIndexRange(const IndexType *indices, + size_t count, + bool primitiveRestartEnabled, + GLuint primitiveRestartIndex) +{ + ASSERT(count > 0); + + IndexType minIndex = 0; + IndexType maxIndex = 0; + size_t nonPrimitiveRestartIndices = 0; + + if (primitiveRestartEnabled) + { + // Find the first non-primitive restart index to initialize the min and max values + size_t i = 0; + for (; i < count; i++) + { + if (indices[i] != primitiveRestartIndex) + { + minIndex = indices[i]; + maxIndex = indices[i]; + nonPrimitiveRestartIndices++; + break; + } + } + + // Loop over the rest of the indices + for (; i < count; i++) + { + if (indices[i] != primitiveRestartIndex) + { + if (minIndex > indices[i]) + { + minIndex = indices[i]; + } + if (maxIndex < indices[i]) + { + maxIndex = indices[i]; + } + nonPrimitiveRestartIndices++; + } + } + } + else + { + minIndex = indices[0]; + maxIndex = indices[0]; + nonPrimitiveRestartIndices = count; + + for (size_t i = 1; i < count; i++) + { + if (minIndex > indices[i]) + { + minIndex = indices[i]; + } + if (maxIndex < indices[i]) + { + maxIndex = indices[i]; + } + } + } + + return gl::IndexRange(static_cast(minIndex), static_cast(maxIndex), + nonPrimitiveRestartIndices); +} + +} // anonymous namespace + namespace gl { @@ -279,6 +351,39 @@ bool IsSamplerType(GLenum type) return false; } +GLenum SamplerTypeToTextureType(GLenum samplerType) +{ + switch (samplerType) + { + case GL_SAMPLER_2D: + case GL_INT_SAMPLER_2D: + case GL_UNSIGNED_INT_SAMPLER_2D: + case GL_SAMPLER_2D_SHADOW: + return GL_TEXTURE_2D; + + case GL_SAMPLER_CUBE: + case GL_INT_SAMPLER_CUBE: + case GL_UNSIGNED_INT_SAMPLER_CUBE: + case GL_SAMPLER_CUBE_SHADOW: + return GL_TEXTURE_CUBE_MAP; + + case GL_SAMPLER_2D_ARRAY: + case GL_INT_SAMPLER_2D_ARRAY: + case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY: + case GL_SAMPLER_2D_ARRAY_SHADOW: + return GL_TEXTURE_2D_ARRAY; + + case GL_SAMPLER_3D: + case GL_INT_SAMPLER_3D: + case GL_UNSIGNED_INT_SAMPLER_3D: + return GL_TEXTURE_3D; + + default: + UNREACHABLE(); + return 0; + } +} + bool IsMatrixType(GLenum type) { return VariableRowCount(type) > 1; @@ -366,6 +471,47 @@ GLenum LayerIndexToCubeMapTextureTarget(size_t index) return FirstCubeMapTextureTarget + static_cast(index); } +IndexRange ComputeIndexRange(GLenum indexType, + const GLvoid *indices, + size_t count, + bool primitiveRestartEnabled) +{ + switch (indexType) + { + case GL_UNSIGNED_BYTE: + return ComputeTypedIndexRange(static_cast(indices), count, + primitiveRestartEnabled, + GetPrimitiveRestartIndex(indexType)); + case GL_UNSIGNED_SHORT: + return ComputeTypedIndexRange(static_cast(indices), count, + primitiveRestartEnabled, + GetPrimitiveRestartIndex(indexType)); + case GL_UNSIGNED_INT: + return ComputeTypedIndexRange(static_cast(indices), count, + primitiveRestartEnabled, + GetPrimitiveRestartIndex(indexType)); + default: + UNREACHABLE(); + return IndexRange(); + } +} + +GLuint GetPrimitiveRestartIndex(GLenum indexType) +{ + switch (indexType) + { + case GL_UNSIGNED_BYTE: + return 0xFF; + case GL_UNSIGNED_SHORT: + return 0xFFFF; + case GL_UNSIGNED_INT: + return 0xFFFFFFFF; + default: + UNREACHABLE(); + return 0; + } +} + bool IsTriangleMode(GLenum drawMode) { switch (drawMode) @@ -493,6 +639,115 @@ std::string ParseUniformName(const std::string &name, size_t *outSubscript) return name.substr(0, open); } +unsigned int ParseAndStripArrayIndex(std::string *name) +{ + unsigned int subscript = GL_INVALID_INDEX; + + // Strip any trailing array operator and retrieve the subscript + size_t open = name->find_last_of('['); + size_t close = name->find_last_of(']'); + if (open != std::string::npos && close == name->length() - 1) + { + subscript = atoi(name->c_str() + open + 1); + name->erase(open); + } + + return subscript; +} + +} // namespace gl + +namespace egl +{ +static_assert(EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR - EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR == 1, + "Unexpected EGL cube map enum value."); +static_assert(EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR - EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR == 2, + "Unexpected EGL cube map enum value."); +static_assert(EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR - EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR == 3, + "Unexpected EGL cube map enum value."); +static_assert(EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR - EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR == 4, + "Unexpected EGL cube map enum value."); +static_assert(EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR - EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR == 5, + "Unexpected EGL cube map enum value."); + +bool IsCubeMapTextureTarget(EGLenum target) +{ + return (target >= FirstCubeMapTextureTarget && target <= LastCubeMapTextureTarget); +} + +size_t CubeMapTextureTargetToLayerIndex(EGLenum target) +{ + ASSERT(IsCubeMapTextureTarget(target)); + return target - static_cast(FirstCubeMapTextureTarget); +} + +EGLenum LayerIndexToCubeMapTextureTarget(size_t index) +{ + ASSERT(index <= (LastCubeMapTextureTarget - FirstCubeMapTextureTarget)); + return FirstCubeMapTextureTarget + static_cast(index); +} + +bool IsTextureTarget(EGLenum target) +{ + switch (target) + { + case EGL_GL_TEXTURE_2D_KHR: + case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR: + case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR: + case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR: + case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR: + case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR: + case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR: + case EGL_GL_TEXTURE_3D_KHR: + return true; + + default: + return false; + } +} + +bool IsRenderbufferTarget(EGLenum target) +{ + return target == EGL_GL_RENDERBUFFER_KHR; +} +} + +namespace egl_gl +{ +GLenum EGLCubeMapTargetToGLCubeMapTarget(EGLenum eglTarget) +{ + ASSERT(egl::IsCubeMapTextureTarget(eglTarget)); + return gl::LayerIndexToCubeMapTextureTarget(egl::CubeMapTextureTargetToLayerIndex(eglTarget)); +} + +GLenum EGLImageTargetToGLTextureTarget(EGLenum eglTarget) +{ + switch (eglTarget) + { + case EGL_GL_TEXTURE_2D_KHR: + return GL_TEXTURE_2D; + + case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR: + case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR: + case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR: + case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR: + case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR: + case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR: + return EGLCubeMapTargetToGLCubeMapTarget(eglTarget); + + case EGL_GL_TEXTURE_3D_KHR: + return GL_TEXTURE_3D; + + default: + UNREACHABLE(); + return GL_NONE; + } +} + +GLuint EGLClientBufferToGLObjectHandle(EGLClientBuffer buffer) +{ + return static_cast(reinterpret_cast(buffer)); +} } #if !defined(ANGLE_ENABLE_WINDOWS_STORE) @@ -542,32 +797,7 @@ void writeFile(const char* path, const void* content, size_t size) // to run, the function returns immediately, and the thread continues execution. void ScheduleYield() { -#if defined(ANGLE_ENABLE_WINDOWS_STORE) - // This implementation of Sleep exists because it is not available prior to Update 4. - static HANDLE singletonEvent = nullptr; - HANDLE sleepEvent = singletonEvent; - if (!sleepEvent) - { - sleepEvent = CreateEventEx(nullptr, nullptr, CREATE_EVENT_MANUAL_RESET, EVENT_ALL_ACCESS); - - if (!sleepEvent) - return; - - HANDLE previousEvent = InterlockedCompareExchangePointerRelease(&singletonEvent, sleepEvent, nullptr); - - if (previousEvent) - { - // Back out if multiple threads try to demand create at the same time. - CloseHandle(sleepEvent); - sleepEvent = previousEvent; - } - } - - // Emulate sleep by waiting with timeout on an event that is never signalled. - WaitForSingleObjectEx(sleepEvent, 0, false); -#else Sleep(0); -#endif } #endif diff --git a/Source/ThirdParty/ANGLE/src/common/utilities.h b/Source/ThirdParty/ANGLE/src/common/utilities.h index 731d984f63ad..dc09011a2623 100644 --- a/Source/ThirdParty/ANGLE/src/common/utilities.h +++ b/Source/ThirdParty/ANGLE/src/common/utilities.h @@ -9,10 +9,15 @@ #ifndef COMMON_UTILITIES_H_ #define COMMON_UTILITIES_H_ +#include +#include + #include "angle_gl.h" #include #include +#include "common/mathutil.h" + namespace gl { @@ -25,6 +30,7 @@ GLenum VariableBoolVectorType(GLenum type); int VariableRowCount(GLenum type); int VariableColumnCount(GLenum type); bool IsSamplerType(GLenum type); +GLenum SamplerTypeToTextureType(GLenum samplerType); bool IsMatrixType(GLenum type); GLenum TransposeMatrixType(GLenum type); int VariableRegisterCount(GLenum type); @@ -44,6 +50,16 @@ GLenum LayerIndexToCubeMapTextureTarget(size_t index); // set to GL_INVALID_INDEX if the provided name is not an array or the array index is invalid. std::string ParseUniformName(const std::string &name, size_t *outSubscript); +// Find the range of index values in the provided indices pointer. Primitive restart indices are +// only counted in the range if primitive restart is disabled. +IndexRange ComputeIndexRange(GLenum indexType, + const GLvoid *indices, + size_t count, + bool primitiveRestartEnabled); + +// Get the primitive restart index value for the given index type. +GLuint GetPrimitiveRestartIndex(GLenum indexType); + bool IsTriangleMode(GLenum drawMode); // [OpenGL ES 3.0.2] Section 2.3.1 page 14 @@ -52,6 +68,26 @@ bool IsTriangleMode(GLenum drawMode); template outT iround(GLfloat value) { return static_cast(value > 0.0f ? floor(value + 0.5f) : ceil(value - 0.5f)); } template outT uiround(GLfloat value) { return static_cast(value + 0.5f); } +unsigned int ParseAndStripArrayIndex(std::string *name); + +} // namespace gl + +namespace egl +{ +static const EGLenum FirstCubeMapTextureTarget = EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR; +static const EGLenum LastCubeMapTextureTarget = EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR; +bool IsCubeMapTextureTarget(EGLenum target); +size_t CubeMapTextureTargetToLayerIndex(EGLenum target); +EGLenum LayerIndexToCubeMapTextureTarget(size_t index); +bool IsTextureTarget(EGLenum target); +bool IsRenderbufferTarget(EGLenum target); +} + +namespace egl_gl +{ +GLenum EGLCubeMapTargetToGLCubeMapTarget(EGLenum eglTarget); +GLenum EGLImageTargetToGLTextureTarget(EGLenum eglTarget); +GLuint EGLClientBufferToGLObjectHandle(EGLClientBuffer buffer); } #if !defined(ANGLE_ENABLE_WINDOWS_STORE) diff --git a/Source/ThirdParty/ANGLE/src/common/version.h b/Source/ThirdParty/ANGLE/src/common/version.h index 2a44709d7ce8..b653ae39c9ad 100644 --- a/Source/ThirdParty/ANGLE/src/common/version.h +++ b/Source/ThirdParty/ANGLE/src/common/version.h @@ -12,12 +12,17 @@ #define ANGLE_MAJOR_VERSION 2 #define ANGLE_MINOR_VERSION 1 +#ifndef ANGLE_REVISION +#define ANGLE_REVISION 0 +#endif + #define ANGLE_STRINGIFY(x) #x #define ANGLE_MACRO_STRINGIFY(x) ANGLE_STRINGIFY(x) #define ANGLE_VERSION_STRING \ ANGLE_MACRO_STRINGIFY(ANGLE_MAJOR_VERSION) "." \ ANGLE_MACRO_STRINGIFY(ANGLE_MINOR_VERSION) "." \ + ANGLE_MACRO_STRINGIFY(ANGLE_REVISION) "." \ ANGLE_COMMIT_HASH #endif // COMMON_VERSION_H_ diff --git a/Source/ThirdParty/ANGLE/src/compiler.gypi b/Source/ThirdParty/ANGLE/src/compiler.gypi index c23b6a3f6a4f..29e6d08c946f 100644 --- a/Source/ThirdParty/ANGLE/src/compiler.gypi +++ b/Source/ThirdParty/ANGLE/src/compiler.gypi @@ -15,8 +15,9 @@ '../include/GLES2/gl2ext.h', '../include/GLES2/gl2platform.h', '../include/GLES3/gl3.h', - '../include/GLES3/gl3ext.h', '../include/GLES3/gl3platform.h', + '../include/GLES3/gl31.h', + '../include/GLES3/gl32.h', '../include/GLSLANG/ShaderLang.h', '../include/GLSLANG/ShaderVars.h', '../include/KHR/khrplatform.h', @@ -24,8 +25,8 @@ 'compiler/translator/BaseTypes.h', 'compiler/translator/BuiltInFunctionEmulator.cpp', 'compiler/translator/BuiltInFunctionEmulator.h', - 'compiler/translator/BuiltInFunctionEmulatorGLSL.cpp', - 'compiler/translator/BuiltInFunctionEmulatorGLSL.h', + 'compiler/translator/Cache.cpp', + 'compiler/translator/Cache.h', 'compiler/translator/CallDAG.cpp', 'compiler/translator/CallDAG.h', 'compiler/translator/CodeGen.cpp', @@ -33,6 +34,8 @@ 'compiler/translator/Compiler.cpp', 'compiler/translator/Compiler.h', 'compiler/translator/ConstantUnion.h', + 'compiler/translator/DeferGlobalInitializers.cpp', + 'compiler/translator/DeferGlobalInitializers.h', 'compiler/translator/Diagnostics.cpp', 'compiler/translator/Diagnostics.h', 'compiler/translator/DirectiveHandler.cpp', @@ -67,12 +70,6 @@ 'compiler/translator/NodeSearch.h', 'compiler/translator/Operator.cpp', 'compiler/translator/Operator.h', - 'compiler/translator/OutputESSL.cpp', - 'compiler/translator/OutputESSL.h', - 'compiler/translator/OutputGLSL.cpp', - 'compiler/translator/OutputGLSL.h', - 'compiler/translator/OutputGLSLBase.cpp', - 'compiler/translator/OutputGLSLBase.h', 'compiler/translator/ParseContext.cpp', 'compiler/translator/ParseContext.h', 'compiler/translator/PoolAlloc.cpp', @@ -80,10 +77,14 @@ 'compiler/translator/Pragma.h', 'compiler/translator/PruneEmptyDeclarations.cpp', 'compiler/translator/PruneEmptyDeclarations.h', - 'compiler/translator/QualifierAlive.cpp', - 'compiler/translator/QualifierAlive.h', + 'compiler/translator/RecordConstantPrecision.cpp', + 'compiler/translator/RecordConstantPrecision.h', 'compiler/translator/RegenerateStructNames.cpp', 'compiler/translator/RegenerateStructNames.h', + 'compiler/translator/RemovePow.cpp', + 'compiler/translator/RemovePow.h', + 'compiler/translator/RewriteDoWhile.cpp', + 'compiler/translator/RewriteDoWhile.h', 'compiler/translator/RenameFunction.h', 'compiler/translator/ScalarizeVecAndMatConstructorArgs.cpp', 'compiler/translator/ScalarizeVecAndMatConstructorArgs.h', @@ -91,16 +92,16 @@ 'compiler/translator/SearchSymbol.h', 'compiler/translator/SymbolTable.cpp', 'compiler/translator/SymbolTable.h', - 'compiler/translator/TranslatorESSL.cpp', - 'compiler/translator/TranslatorESSL.h', - 'compiler/translator/TranslatorGLSL.cpp', - 'compiler/translator/TranslatorGLSL.h', 'compiler/translator/Types.cpp', 'compiler/translator/Types.h', 'compiler/translator/UnfoldShortCircuitAST.cpp', 'compiler/translator/UnfoldShortCircuitAST.h', + 'compiler/translator/ValidateGlobalInitializer.cpp', + 'compiler/translator/ValidateGlobalInitializer.h', 'compiler/translator/ValidateLimitations.cpp', 'compiler/translator/ValidateLimitations.h', + 'compiler/translator/ValidateMaxParameters.h', + 'compiler/translator/ValidateMaxParameters.cpp', 'compiler/translator/ValidateOutputs.cpp', 'compiler/translator/ValidateOutputs.h', 'compiler/translator/ValidateSwitch.cpp', @@ -109,8 +110,6 @@ 'compiler/translator/VariableInfo.h', 'compiler/translator/VariablePacker.cpp', 'compiler/translator/VariablePacker.h', - 'compiler/translator/VersionGLSL.cpp', - 'compiler/translator/VersionGLSL.h', 'compiler/translator/blocklayout.cpp', 'compiler/translator/blocklayout.h', 'compiler/translator/depgraph/DependencyGraph.cpp', @@ -127,9 +126,7 @@ 'compiler/translator/glslang_tab.cpp', 'compiler/translator/glslang_tab.h', 'compiler/translator/intermOut.cpp', - 'compiler/translator/intermediate.h', 'compiler/translator/length_limits.h', - 'compiler/translator/parseConst.cpp', 'compiler/translator/timing/RestrictFragmentShaderTiming.cpp', 'compiler/translator/timing/RestrictFragmentShaderTiming.h', 'compiler/translator/timing/RestrictVertexShaderTiming.cpp', @@ -139,6 +136,28 @@ 'third_party/compiler/ArrayBoundsClamper.cpp', 'third_party/compiler/ArrayBoundsClamper.h', ], + 'angle_translator_lib_essl_sources': + [ + 'compiler/translator/OutputESSL.cpp', + 'compiler/translator/OutputESSL.h', + 'compiler/translator/TranslatorESSL.cpp', + 'compiler/translator/TranslatorESSL.h', + ], + 'angle_translator_lib_glsl_sources': + [ + 'compiler/translator/BuiltInFunctionEmulatorGLSL.cpp', + 'compiler/translator/BuiltInFunctionEmulatorGLSL.h', + 'compiler/translator/ExtensionGLSL.cpp', + 'compiler/translator/ExtensionGLSL.h', + 'compiler/translator/OutputGLSL.cpp', + 'compiler/translator/OutputGLSL.h', + 'compiler/translator/OutputGLSLBase.cpp', + 'compiler/translator/OutputGLSLBase.h', + 'compiler/translator/TranslatorGLSL.cpp', + 'compiler/translator/TranslatorGLSL.h', + 'compiler/translator/VersionGLSL.cpp', + 'compiler/translator/VersionGLSL.h', + ], 'angle_translator_lib_hlsl_sources': [ 'compiler/translator/ArrayReturnValueToOutParameter.cpp', @@ -151,6 +170,8 @@ 'compiler/translator/BuiltInFunctionEmulatorHLSL.h', 'compiler/translator/OutputHLSL.cpp', 'compiler/translator/OutputHLSL.h', + 'compiler/translator/RemoveDynamicIndexing.cpp', + 'compiler/translator/RemoveDynamicIndexing.h', 'compiler/translator/RemoveSwitchFallThrough.cpp', 'compiler/translator/RemoveSwitchFallThrough.h', 'compiler/translator/RewriteElseBlocks.cpp', @@ -159,14 +180,14 @@ 'compiler/translator/SeparateArrayInitialization.h', 'compiler/translator/SeparateDeclarations.cpp', 'compiler/translator/SeparateDeclarations.h', - 'compiler/translator/SimplifyArrayAssignment.cpp', - 'compiler/translator/SimplifyArrayAssignment.h', + 'compiler/translator/SeparateExpressionsReturningArrays.cpp', + 'compiler/translator/SeparateExpressionsReturningArrays.h', 'compiler/translator/StructureHLSL.cpp', 'compiler/translator/StructureHLSL.h', 'compiler/translator/TranslatorHLSL.cpp', 'compiler/translator/TranslatorHLSL.h', - 'compiler/translator/UnfoldShortCircuit.cpp', - 'compiler/translator/UnfoldShortCircuit.h', + 'compiler/translator/UnfoldShortCircuitToIf.cpp', + 'compiler/translator/UnfoldShortCircuitToIf.h', 'compiler/translator/UniformHLSL.cpp', 'compiler/translator/UniformHLSL.h', 'compiler/translator/UtilsHLSL.cpp', @@ -212,17 +233,6 @@ 'type': 'static_library', 'includes': [ '../build/common_defines.gypi', ], 'sources': [ '<@(angle_preprocessor_sources)', ], - 'conditions': - [ - ['angle_build_winrt==1', - { - 'msvs_enable_winrt' : '1', - }], - ['angle_build_winphone==1', - { - 'msvs_enable_winphone' : '1', - }], - ], }, { 'target_name': 'translator_lib', @@ -253,13 +263,41 @@ }, 'conditions': [ - ['angle_build_winrt==1', + ['angle_enable_essl==1', { - 'msvs_enable_winrt' : '1', + 'defines': + [ + 'ANGLE_ENABLE_ESSL', + ], + 'direct_dependent_settings': + { + 'defines': + [ + 'ANGLE_ENABLE_ESSL', + ], + }, + 'sources': + [ + '<@(angle_translator_lib_essl_sources)', + ], }], - ['angle_build_winphone==1', + ['angle_enable_glsl==1', { - 'msvs_enable_winphone' : '1', + 'defines': + [ + 'ANGLE_ENABLE_GLSL', + ], + 'direct_dependent_settings': + { + 'defines': + [ + 'ANGLE_ENABLE_GLSL', + ], + }, + 'sources': + [ + '<@(angle_translator_lib_glsl_sources)', + ], }], ['angle_enable_hlsl==1', { @@ -301,17 +339,6 @@ 'compiler/translator/ShaderLang.cpp', 'compiler/translator/ShaderVars.cpp' ], - 'conditions': - [ - ['angle_build_winrt==1', - { - 'msvs_enable_winrt' : '1', - }], - ['angle_build_winphone==1', - { - 'msvs_enable_winphone' : '1', - }], - ], }, { @@ -340,17 +367,6 @@ 'compiler/translator/ShaderLang.cpp', 'compiler/translator/ShaderVars.cpp' ], - 'conditions': - [ - ['angle_build_winrt==1', - { - 'msvs_enable_winrt' : '1', - }], - ['angle_build_winphone==1', - { - 'msvs_enable_winphone' : '1', - }], - ], }, ], } diff --git a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/DiagnosticsBase.cpp b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/DiagnosticsBase.cpp index 4bcdfec5ed64..68c6e9cea48a 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/DiagnosticsBase.cpp +++ b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/DiagnosticsBase.cpp @@ -105,16 +105,16 @@ std::string Diagnostics::message(ID id) case PP_VERSION_NOT_FIRST_STATEMENT: return "#version directive must occur before anything else, " "except for comments and white space"; + case PP_VERSION_NOT_FIRST_LINE_ESSL3: + return "#version directive must occur on the first line of the shader"; case PP_INVALID_LINE_NUMBER: return "invalid line number"; case PP_INVALID_FILE_NUMBER: return "invalid file number"; case PP_INVALID_LINE_DIRECTIVE: return "invalid line directive"; - case PP_INVALID_PRAGMA: - return "invalid pragma"; - case PP_INVALID_PRAGMA_VALUE: - return "invalid pragma value, must be 'on' or 'off'"; + case PP_NON_PP_TOKEN_BEFORE_EXTENSION_ESSL3: + return "extension directive must occur before any non-preprocessor tokens in ESSL3"; // Errors end. // Warnings begin. case PP_EOF_IN_DIRECTIVE: @@ -123,6 +123,10 @@ std::string Diagnostics::message(ID id) return "unexpected token after conditional expression"; case PP_UNRECOGNIZED_PRAGMA: return "unrecognized pragma"; + case PP_NON_PP_TOKEN_BEFORE_EXTENSION_ESSL1: + return "extension directive should occur before any non-preprocessor tokens"; + case PP_WARNING_MACRO_NAME_RESERVED: + return "macro name with a double underscore is reserved - unintented behavior is possible"; // Warnings end. default: assert(false); diff --git a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/DiagnosticsBase.h b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/DiagnosticsBase.h index a76ccb3fbf28..d26c174f01c2 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/DiagnosticsBase.h +++ b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/DiagnosticsBase.h @@ -60,16 +60,18 @@ class Diagnostics PP_INVALID_VERSION_NUMBER, PP_INVALID_VERSION_DIRECTIVE, PP_VERSION_NOT_FIRST_STATEMENT, + PP_VERSION_NOT_FIRST_LINE_ESSL3, PP_INVALID_LINE_NUMBER, PP_INVALID_FILE_NUMBER, PP_INVALID_LINE_DIRECTIVE, - PP_INVALID_PRAGMA, - PP_INVALID_PRAGMA_VALUE, + PP_NON_PP_TOKEN_BEFORE_EXTENSION_ESSL3, PP_ERROR_END, PP_WARNING_BEGIN, PP_EOF_IN_DIRECTIVE, PP_UNRECOGNIZED_PRAGMA, + PP_NON_PP_TOKEN_BEFORE_EXTENSION_ESSL1, + PP_WARNING_MACRO_NAME_RESERVED, PP_WARNING_END }; diff --git a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/DirectiveParser.cpp b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/DirectiveParser.cpp index b38f33256f5b..2faa33137811 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/DirectiveParser.cpp +++ b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/DirectiveParser.cpp @@ -119,14 +119,12 @@ void skipUntilEOD(pp::Lexer *lexer, pp::Token *token) bool isMacroNameReserved(const std::string &name) { // Names prefixed with "GL_" are reserved. - if (name.substr(0, 3) == "GL_") - return true; - - // Names containing two consecutive underscores are reserved. - if (name.find("__") != std::string::npos) - return true; + return (name.substr(0, 3) == "GL_"); +} - return false; +bool hasDoubleUnderscores(const std::string &name) +{ + return (name.find("__") != std::string::npos); } bool isMacroPredefined(const std::string &name, @@ -141,80 +139,17 @@ bool isMacroPredefined(const std::string &name, namespace pp { -class DefinedParser : public Lexer -{ - public: - DefinedParser(Lexer *lexer, - const MacroSet *macroSet, - Diagnostics *diagnostics) - : mLexer(lexer), - mMacroSet(macroSet), - mDiagnostics(diagnostics) - { - } - - protected: - virtual void lex(Token *token) - { - const char kDefined[] = "defined"; - - mLexer->lex(token); - if (token->type != Token::IDENTIFIER) - return; - if (token->text != kDefined) - return; - - bool paren = false; - mLexer->lex(token); - if (token->type == '(') - { - paren = true; - mLexer->lex(token); - } - - if (token->type != Token::IDENTIFIER) - { - mDiagnostics->report(Diagnostics::PP_UNEXPECTED_TOKEN, - token->location, token->text); - skipUntilEOD(mLexer, token); - return; - } - MacroSet::const_iterator iter = mMacroSet->find(token->text); - std::string expression = iter != mMacroSet->end() ? "1" : "0"; - - if (paren) - { - mLexer->lex(token); - if (token->type != ')') - { - mDiagnostics->report(Diagnostics::PP_UNEXPECTED_TOKEN, - token->location, token->text); - skipUntilEOD(mLexer, token); - return; - } - } - - // We have a valid defined operator. - // Convert the current token into a CONST_INT token. - token->type = Token::CONST_INT; - token->text = expression; - } - - private: - Lexer *mLexer; - const MacroSet *mMacroSet; - Diagnostics *mDiagnostics; -}; - DirectiveParser::DirectiveParser(Tokenizer *tokenizer, MacroSet *macroSet, Diagnostics *diagnostics, DirectiveHandler *directiveHandler) : mPastFirstStatement(false), + mSeenNonPreprocessorToken(false), mTokenizer(tokenizer), mMacroSet(macroSet), mDiagnostics(diagnostics), - mDirectiveHandler(directiveHandler) + mDirectiveHandler(directiveHandler), + mShaderVersion(100) { } @@ -229,6 +164,10 @@ void DirectiveParser::lex(Token *token) parseDirective(token); mPastFirstStatement = true; } + else if (!isEOD(token)) + { + mSeenNonPreprocessorToken = true; + } if (token->type == Token::LAST) { @@ -350,6 +289,16 @@ void DirectiveParser::parseDefine(Token *token) token->location, token->text); return; } + // Using double underscores is allowed, but may result in unintended + // behavior, so a warning is issued. At the time of writing this was + // specified in ESSL 3.10, but the intent judging from Khronos + // discussions and dEQP tests was that double underscores should be + // allowed in earlier ESSL versions too. + if (hasDoubleUnderscores(token->text)) + { + mDiagnostics->report(Diagnostics::PP_WARNING_MACRO_NAME_RESERVED, token->location, + token->text); + } Macro macro; macro.type = Macro::kTypeObj; @@ -625,8 +574,7 @@ void DirectiveParser::parsePragma(Token *token) break; case PRAGMA_VALUE: value = token->text; - // Pragma value validation is handled in DirectiveHandler::handlePragma - // because the proper pragma value is dependent on the pragma name. + valid = valid && (token->type == Token::IDENTIFIER); break; case RIGHT_PAREN: valid = valid && (token->type == ')'); @@ -643,7 +591,7 @@ void DirectiveParser::parsePragma(Token *token) (state == RIGHT_PAREN + 1)); // With value. if (!valid) { - mDiagnostics->report(Diagnostics::PP_INVALID_PRAGMA, + mDiagnostics->report(Diagnostics::PP_UNRECOGNIZED_PRAGMA, token->location, name); } else if (state > PRAGMA_NAME) // Do not notify for empty pragma. @@ -715,6 +663,20 @@ void DirectiveParser::parseExtension(Token *token) token->location, token->text); valid = false; } + if (valid && mSeenNonPreprocessorToken) + { + if (mShaderVersion >= 300) + { + mDiagnostics->report(Diagnostics::PP_NON_PP_TOKEN_BEFORE_EXTENSION_ESSL3, + token->location, token->text); + valid = false; + } + else + { + mDiagnostics->report(Diagnostics::PP_NON_PP_TOKEN_BEFORE_EXTENSION_ESSL1, + token->location, token->text); + } + } if (valid) mDirectiveHandler->handleExtension(token->location, name, behavior); } @@ -791,9 +753,18 @@ void DirectiveParser::parseVersion(Token *token) valid = false; } + if (valid && version >= 300 && token->location.line > 1) + { + mDiagnostics->report(Diagnostics::PP_VERSION_NOT_FIRST_LINE_ESSL3, + token->location, token->text); + valid = false; + } + if (valid) { mDirectiveHandler->handleVersion(token->location, version); + mShaderVersion = version; + PredefineMacro(mMacroSet, "__VERSION__", version); } } @@ -801,72 +772,60 @@ void DirectiveParser::parseLine(Token *token) { assert(getDirective(token) == DIRECTIVE_LINE); - enum State - { - LINE_NUMBER, - FILE_NUMBER - }; - bool valid = true; + bool parsedFileNumber = false; int line = 0, file = 0; - int state = LINE_NUMBER; - MacroExpander macroExpander(mTokenizer, mMacroSet, mDiagnostics); + MacroExpander macroExpander(mTokenizer, mMacroSet, mDiagnostics, false); + + // Lex the first token after "#line" so we can check it for EOD. macroExpander.lex(token); - while ((token->type != '\n') && (token->type != Token::LAST)) + + if (isEOD(token)) { - switch (state++) + mDiagnostics->report(Diagnostics::PP_INVALID_LINE_DIRECTIVE, token->location, token->text); + valid = false; + } + else + { + ExpressionParser expressionParser(¯oExpander, mDiagnostics); + ExpressionParser::ErrorSettings errorSettings; + + // See GLES3 section 12.42 + errorSettings.integerLiteralsMustFit32BitSignedRange = true; + + errorSettings.unexpectedIdentifier = Diagnostics::PP_INVALID_LINE_NUMBER; + // The first token was lexed earlier to check if it was EOD. Include + // the token in parsing for a second time by setting the + // parsePresetToken flag to true. + expressionParser.parse(token, &line, true, errorSettings, &valid); + if (!isEOD(token) && valid) + { + errorSettings.unexpectedIdentifier = Diagnostics::PP_INVALID_FILE_NUMBER; + // After parsing the line expression expressionParser has also + // advanced to the first token of the file expression - this is the + // token that makes the parser reduce the "input" rule for the line + // expression and stop. So we're using parsePresetToken = true here + // as well. + expressionParser.parse(token, &file, true, errorSettings, &valid); + parsedFileNumber = true; + } + if (!isEOD(token)) { - case LINE_NUMBER: - if (valid && (token->type != Token::CONST_INT)) - { - mDiagnostics->report(Diagnostics::PP_INVALID_LINE_NUMBER, - token->location, token->text); - valid = false; - } - if (valid && !token->iValue(&line)) - { - mDiagnostics->report(Diagnostics::PP_INTEGER_OVERFLOW, - token->location, token->text); - valid = false; - } - break; - case FILE_NUMBER: - if (valid && (token->type != Token::CONST_INT)) - { - mDiagnostics->report(Diagnostics::PP_INVALID_FILE_NUMBER, - token->location, token->text); - valid = false; - } - if (valid && !token->iValue(&file)) - { - mDiagnostics->report(Diagnostics::PP_INTEGER_OVERFLOW, - token->location, token->text); - valid = false; - } - break; - default: if (valid) { mDiagnostics->report(Diagnostics::PP_UNEXPECTED_TOKEN, token->location, token->text); valid = false; } - break; + skipUntilEOD(mTokenizer, token); } - macroExpander.lex(token); } - if (valid && (state != FILE_NUMBER) && (state != FILE_NUMBER + 1)) - { - mDiagnostics->report(Diagnostics::PP_INVALID_LINE_DIRECTIVE, - token->location, token->text); - valid = false; - } if (valid) { mTokenizer->setLineNumber(line); - if (state == FILE_NUMBER + 1) + if (parsedFileNumber) mTokenizer->setFileNumber(file); } } @@ -926,13 +885,16 @@ int DirectiveParser::parseExpressionIf(Token *token) assert((getDirective(token) == DIRECTIVE_IF) || (getDirective(token) == DIRECTIVE_ELIF)); - DefinedParser definedParser(mTokenizer, mMacroSet, mDiagnostics); - MacroExpander macroExpander(&definedParser, mMacroSet, mDiagnostics); + MacroExpander macroExpander(mTokenizer, mMacroSet, mDiagnostics, true); ExpressionParser expressionParser(¯oExpander, mDiagnostics); int expression = 0; - macroExpander.lex(token); - expressionParser.parse(token, &expression); + ExpressionParser::ErrorSettings errorSettings; + errorSettings.integerLiteralsMustFit32BitSignedRange = false; + errorSettings.unexpectedIdentifier = Diagnostics::PP_CONDITIONAL_UNEXPECTED_TOKEN; + + bool valid = true; + expressionParser.parse(token, &expression, false, errorSettings, &valid); // Check if there are tokens after #if expression. if (!isEOD(token)) diff --git a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/DirectiveParser.h b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/DirectiveParser.h index e1acdbb8d0a3..2888e289cee4 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/DirectiveParser.h +++ b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/DirectiveParser.h @@ -27,7 +27,7 @@ class DirectiveParser : public Lexer Diagnostics *diagnostics, DirectiveHandler *directiveHandler); - virtual void lex(Token *token); + void lex(Token *token) override; private: PP_DISALLOW_COPY_AND_ASSIGN(DirectiveParser); @@ -70,11 +70,14 @@ class DirectiveParser : public Lexer } }; bool mPastFirstStatement; + bool mSeenNonPreprocessorToken; // Tracks if a non-preprocessor token has been seen yet. Some macros, such as + // #extension must be declared before all shader code. std::vector mConditionalStack; Tokenizer *mTokenizer; MacroSet *mMacroSet; Diagnostics *mDiagnostics; DirectiveHandler *mDirectiveHandler; + int mShaderVersion; }; } // namespace pp diff --git a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/ExpressionParser.cpp b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/ExpressionParser.cpp index 851183e4f3b3..b38b7ae5b263 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/ExpressionParser.cpp +++ b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/ExpressionParser.cpp @@ -1,6 +1,6 @@ /* A Bison parser, made by GNU Bison 3.0.4. */ -/* Apple Note: For the avoidance of doubt, Apple elects to distribute this file under the terms of the BSD license. */ +/* Apple Note: For the avoidance of doubt, Apple elects to distribute this file under the terms of the BSD license. */ /* Bison implementation for Yacc-like parsers in C @@ -112,6 +112,7 @@ typedef __int64 YYSTYPE; #include typedef intmax_t YYSTYPE; #endif // _MSC_VER + #define YYENABLE_NLS 0 #define YYLTYPE_IS_TRIVIAL 1 #define YYSTYPE_IS_TRIVIAL 1 @@ -124,6 +125,17 @@ struct Context pp::Lexer* lexer; pp::Token* token; int* result; + bool parsePresetToken; + + pp::ExpressionParser::ErrorSettings errorSettings; + bool *valid; + + void startIgnoreErrors() { ++ignoreErrors; } + void endIgnoreErrors() { --ignoreErrors; } + + bool isIgnoringErrors() { return ignoreErrors > 0; } + + int ignoreErrors; }; } // namespace @@ -164,15 +176,16 @@ extern int ppdebug; enum yytokentype { TOK_CONST_INT = 258, - TOK_OP_OR = 259, - TOK_OP_AND = 260, - TOK_OP_EQ = 261, - TOK_OP_NE = 262, - TOK_OP_LE = 263, - TOK_OP_GE = 264, - TOK_OP_LEFT = 265, - TOK_OP_RIGHT = 266, - TOK_UNARY = 267 + TOK_IDENTIFIER = 259, + TOK_OP_OR = 260, + TOK_OP_AND = 261, + TOK_OP_EQ = 262, + TOK_OP_NE = 263, + TOK_OP_LE = 264, + TOK_OP_GE = 265, + TOK_OP_LEFT = 266, + TOK_OP_RIGHT = 267, + TOK_UNARY = 268 }; #endif @@ -431,23 +444,23 @@ union yyalloc #endif /* !YYCOPY_NEEDED */ /* YYFINAL -- State number of the termination state. */ -#define YYFINAL 14 +#define YYFINAL 15 /* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 175 +#define YYLAST 176 /* YYNTOKENS -- Number of terminals. */ -#define YYNTOKENS 27 +#define YYNTOKENS 28 /* YYNNTS -- Number of nonterminals. */ -#define YYNNTS 3 +#define YYNNTS 5 /* YYNRULES -- Number of rules. */ -#define YYNRULES 26 +#define YYNRULES 29 /* YYNSTATES -- Number of states. */ -#define YYNSTATES 52 +#define YYNSTATES 55 /* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned by yylex, with out-of-bounds checking. */ #define YYUNDEFTOK 2 -#define YYMAXUTOK 267 +#define YYMAXUTOK 268 #define YYTRANSLATE(YYX) \ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) @@ -459,16 +472,16 @@ static const yytype_uint8 yytranslate[] = 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 23, 2, 2, 2, 21, 8, 2, - 25, 26, 19, 17, 2, 18, 2, 20, 2, 2, + 2, 2, 2, 24, 2, 2, 2, 22, 9, 2, + 26, 27, 20, 18, 2, 19, 2, 21, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 11, 2, 12, 2, 2, 2, 2, 2, 2, 2, + 12, 2, 13, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 7, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 8, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 6, 2, 24, 2, 2, 2, + 2, 2, 2, 2, 7, 2, 25, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, @@ -482,16 +495,16 @@ static const yytype_uint8 yytranslate[] = 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, - 5, 9, 10, 13, 14, 15, 16, 22 + 5, 6, 10, 11, 14, 15, 16, 17, 23 }; #if YYDEBUG /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ -static const yytype_uint8 yyrline[] = +static const yytype_uint16 yyrline[] = { - 0, 97, 97, 104, 105, 108, 111, 114, 117, 120, - 123, 126, 129, 132, 135, 138, 141, 144, 147, 150, - 163, 176, 179, 182, 185, 188, 191 + 0, 110, 110, 117, 118, 129, 129, 150, 150, 171, + 174, 177, 180, 183, 186, 189, 192, 195, 198, 201, + 204, 207, 210, 230, 250, 253, 256, 259, 262, 265 }; #endif @@ -500,11 +513,11 @@ static const yytype_uint8 yyrline[] = First, the terminals, then, starting at YYNTOKENS, nonterminals. */ static const char *const yytname[] = { - "$end", "error", "$undefined", "TOK_CONST_INT", "TOK_OP_OR", - "TOK_OP_AND", "'|'", "'^'", "'&'", "TOK_OP_EQ", "TOK_OP_NE", "'<'", - "'>'", "TOK_OP_LE", "TOK_OP_GE", "TOK_OP_LEFT", "TOK_OP_RIGHT", "'+'", - "'-'", "'*'", "'/'", "'%'", "TOK_UNARY", "'!'", "'~'", "'('", "')'", - "$accept", "input", "expression", YY_NULLPTR + "$end", "error", "$undefined", "TOK_CONST_INT", "TOK_IDENTIFIER", + "TOK_OP_OR", "TOK_OP_AND", "'|'", "'^'", "'&'", "TOK_OP_EQ", "TOK_OP_NE", + "'<'", "'>'", "TOK_OP_LE", "TOK_OP_GE", "TOK_OP_LEFT", "TOK_OP_RIGHT", + "'+'", "'-'", "'*'", "'/'", "'%'", "TOK_UNARY", "'!'", "'~'", "'('", + "')'", "$accept", "input", "expression", "$@1", "$@2", YY_NULLPTR }; #endif @@ -513,16 +526,16 @@ static const char *const yytname[] = (internal) symbol number NUM (which must be that of a token). */ static const yytype_uint16 yytoknum[] = { - 0, 256, 257, 258, 259, 260, 124, 94, 38, 261, - 262, 60, 62, 263, 264, 265, 266, 43, 45, 42, - 47, 37, 267, 33, 126, 40, 41 + 0, 256, 257, 258, 259, 260, 261, 124, 94, 38, + 262, 263, 60, 62, 264, 265, 266, 267, 43, 45, + 42, 47, 37, 268, 33, 126, 40, 41 }; # endif -#define YYPACT_NINF -11 +#define YYPACT_NINF -12 #define yypact_value_is_default(Yystate) \ - (!!((Yystate) == (-11))) + (!!((Yystate) == (-12))) #define YYTABLE_NINF -1 @@ -533,12 +546,12 @@ static const yytype_uint16 yytoknum[] = STATE-NUM. */ static const yytype_int16 yypact[] = { - 46, -11, 46, 46, 46, 46, 46, 12, 68, -11, - -11, -11, -11, 27, -11, 46, 46, 46, 46, 46, - 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, -11, 85, 101, 116, 130, 143, 154, - 154, -10, -10, -10, -10, 37, 37, 31, 31, -11, - -11, -11 + 31, -12, -12, 31, 31, 31, 31, 31, 51, 76, + -12, -12, -12, -12, 53, -12, -12, -12, 31, 31, + 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, + 31, 31, 31, 31, -12, 31, 31, 124, 138, 26, + 149, 149, -11, -11, -11, -11, 154, 154, -8, -8, + -12, -12, -12, 93, 109 }; /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM. @@ -546,24 +559,24 @@ static const yytype_int16 yypact[] = means the default is an error. */ static const yytype_uint8 yydefact[] = { - 0, 3, 0, 0, 0, 0, 0, 0, 2, 25, - 24, 22, 23, 0, 1, 0, 0, 0, 0, 0, + 0, 3, 4, 0, 0, 0, 0, 0, 0, 2, + 28, 27, 25, 26, 0, 1, 5, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 26, 4, 5, 6, 7, 8, 10, - 9, 14, 13, 12, 11, 16, 15, 18, 17, 21, - 20, 19 + 0, 0, 0, 0, 29, 0, 0, 9, 10, 11, + 13, 12, 17, 16, 15, 14, 19, 18, 21, 20, + 24, 23, 22, 6, 8 }; /* YYPGOTO[NTERM-NUM]. */ static const yytype_int8 yypgoto[] = { - -11, -11, -2 + -12, -12, -3, -12, -12 }; /* YYDEFGOTO[NTERM-NUM]. */ static const yytype_int8 yydefgoto[] = { - -1, 7, 8 + -1, 8, 9, 35, 36 }; /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If @@ -571,74 +584,74 @@ static const yytype_int8 yydefgoto[] = number is the opposite. If YYTABLE_NINF, syntax error. */ static const yytype_uint8 yytable[] = { - 9, 10, 11, 12, 13, 26, 27, 28, 29, 30, - 31, 32, 14, 34, 35, 36, 37, 38, 39, 40, - 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, - 51, 15, 16, 17, 18, 19, 20, 21, 22, 23, - 24, 25, 26, 27, 28, 29, 30, 31, 32, 1, - 30, 31, 32, 33, 28, 29, 30, 31, 32, 0, - 0, 0, 0, 2, 3, 0, 0, 0, 0, 4, - 5, 6, 15, 16, 17, 18, 19, 20, 21, 22, + 10, 11, 12, 13, 14, 27, 28, 29, 30, 31, + 32, 33, 31, 32, 33, 37, 38, 39, 40, 41, + 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, + 52, 0, 53, 54, 1, 2, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 31, 32, 33, 3, + 4, 15, 0, 0, 0, 5, 6, 7, 16, 17, + 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, + 28, 29, 30, 31, 32, 33, 0, 0, 0, 0, + 34, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 31, 32, 33, 17, + 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, + 28, 29, 30, 31, 32, 33, 18, 19, 20, 21, + 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, + 32, 33, 19, 20, 21, 22, 23, 24, 25, 26, + 27, 28, 29, 30, 31, 32, 33, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, - 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, - 26, 27, 28, 29, 30, 31, 32, 17, 18, 19, - 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, - 30, 31, 32, 18, 19, 20, 21, 22, 23, 24, - 25, 26, 27, 28, 29, 30, 31, 32, 19, 20, - 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, - 31, 32, 20, 21, 22, 23, 24, 25, 26, 27, - 28, 29, 30, 31, 32, 22, 23, 24, 25, 26, - 27, 28, 29, 30, 31, 32 + 33, 23, 24, 25, 26, 27, 28, 29, 30, 31, + 32, 33, 29, 30, 31, 32, 33 }; static const yytype_int8 yycheck[] = { - 2, 3, 4, 5, 6, 15, 16, 17, 18, 19, - 20, 21, 0, 15, 16, 17, 18, 19, 20, 21, - 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, - 32, 4, 5, 6, 7, 8, 9, 10, 11, 12, - 13, 14, 15, 16, 17, 18, 19, 20, 21, 3, - 19, 20, 21, 26, 17, 18, 19, 20, 21, -1, - -1, -1, -1, 17, 18, -1, -1, -1, -1, 23, - 24, 25, 4, 5, 6, 7, 8, 9, 10, 11, + 3, 4, 5, 6, 7, 16, 17, 18, 19, 20, + 21, 22, 20, 21, 22, 18, 19, 20, 21, 22, + 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, + 33, -1, 35, 36, 3, 4, 10, 11, 12, 13, + 14, 15, 16, 17, 18, 19, 20, 21, 22, 18, + 19, 0, -1, -1, -1, 24, 25, 26, 5, 6, + 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, + 17, 18, 19, 20, 21, 22, -1, -1, -1, -1, + 27, 5, 6, 7, 8, 9, 10, 11, 12, 13, + 14, 15, 16, 17, 18, 19, 20, 21, 22, 6, + 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, + 17, 18, 19, 20, 21, 22, 7, 8, 9, 10, + 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, + 21, 22, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, - 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 16, 17, 18, 19, 20, 21, 6, 7, 8, - 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, - 19, 20, 21, 7, 8, 9, 10, 11, 12, 13, - 14, 15, 16, 17, 18, 19, 20, 21, 8, 9, - 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, - 20, 21, 9, 10, 11, 12, 13, 14, 15, 16, - 17, 18, 19, 20, 21, 11, 12, 13, 14, 15, - 16, 17, 18, 19, 20, 21 + 22, 12, 13, 14, 15, 16, 17, 18, 19, 20, + 21, 22, 18, 19, 20, 21, 22 }; /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing symbol of state STATE-NUM. */ static const yytype_uint8 yystos[] = { - 0, 3, 17, 18, 23, 24, 25, 28, 29, 29, - 29, 29, 29, 29, 0, 4, 5, 6, 7, 8, + 0, 3, 4, 18, 19, 24, 25, 26, 29, 30, + 30, 30, 30, 30, 30, 0, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, - 19, 20, 21, 26, 29, 29, 29, 29, 29, 29, - 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, - 29, 29 + 19, 20, 21, 22, 27, 31, 32, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30 }; /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ static const yytype_uint8 yyr1[] = { - 0, 27, 28, 29, 29, 29, 29, 29, 29, 29, - 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, - 29, 29, 29, 29, 29, 29, 29 + 0, 28, 29, 30, 30, 31, 30, 32, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30 }; /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */ static const yytype_uint8 yyr2[] = { - 0, 2, 1, 1, 3, 3, 3, 3, 3, 3, + 0, 2, 1, 1, 1, 0, 4, 0, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 2, 2, 2, 2, 3 + 3, 3, 3, 3, 3, 2, 2, 2, 2, 3 }; @@ -1332,7 +1345,15 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); case 4: { - (yyval) = (yyvsp[-2]) || (yyvsp[0]); + if (!context->isIgnoringErrors()) + { + // This rule should be applied right after the token is lexed, so we can + // refer to context->token in the error message. + context->diagnostics->report(context->errorSettings.unexpectedIdentifier, + context->token->location, context->token->text); + *(context->valid) = false; + } + (yyval) = (yyvsp[0]); } break; @@ -1340,7 +1361,15 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); case 5: { - (yyval) = (yyvsp[-2]) && (yyvsp[0]); + if ((yyvsp[-1]) != 0) + { + // Ignore errors in the short-circuited part of the expression. + // ESSL3.00 section 3.4: + // If an operand is not evaluated, the presence of undefined identifiers + // in the operand will not cause an error. + // Unevaluated division by zero should not cause an error either. + context->startIgnoreErrors(); + } } break; @@ -1348,7 +1377,15 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); case 6: { - (yyval) = (yyvsp[-2]) | (yyvsp[0]); + if ((yyvsp[-3]) != 0) + { + context->endIgnoreErrors(); + (yyval) = static_cast(1); + } + else + { + (yyval) = (yyvsp[-3]) || (yyvsp[0]); + } } break; @@ -1356,7 +1393,15 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); case 7: { - (yyval) = (yyvsp[-2]) ^ (yyvsp[0]); + if ((yyvsp[-1]) == 0) + { + // Ignore errors in the short-circuited part of the expression. + // ESSL3.00 section 3.4: + // If an operand is not evaluated, the presence of undefined identifiers + // in the operand will not cause an error. + // Unevaluated division by zero should not cause an error either. + context->startIgnoreErrors(); + } } break; @@ -1364,7 +1409,15 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); case 8: { - (yyval) = (yyvsp[-2]) & (yyvsp[0]); + if ((yyvsp[-3]) == 0) + { + context->endIgnoreErrors(); + (yyval) = static_cast(0); + } + else + { + (yyval) = (yyvsp[-3]) && (yyvsp[0]); + } } break; @@ -1372,7 +1425,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); case 9: { - (yyval) = (yyvsp[-2]) != (yyvsp[0]); + (yyval) = (yyvsp[-2]) | (yyvsp[0]); } break; @@ -1380,7 +1433,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); case 10: { - (yyval) = (yyvsp[-2]) == (yyvsp[0]); + (yyval) = (yyvsp[-2]) ^ (yyvsp[0]); } break; @@ -1388,7 +1441,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); case 11: { - (yyval) = (yyvsp[-2]) >= (yyvsp[0]); + (yyval) = (yyvsp[-2]) & (yyvsp[0]); } break; @@ -1396,7 +1449,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); case 12: { - (yyval) = (yyvsp[-2]) <= (yyvsp[0]); + (yyval) = (yyvsp[-2]) != (yyvsp[0]); } break; @@ -1404,7 +1457,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); case 13: { - (yyval) = (yyvsp[-2]) > (yyvsp[0]); + (yyval) = (yyvsp[-2]) == (yyvsp[0]); } break; @@ -1412,7 +1465,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); case 14: { - (yyval) = (yyvsp[-2]) < (yyvsp[0]); + (yyval) = (yyvsp[-2]) >= (yyvsp[0]); } break; @@ -1420,7 +1473,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); case 15: { - (yyval) = (yyvsp[-2]) >> (yyvsp[0]); + (yyval) = (yyvsp[-2]) <= (yyvsp[0]); } break; @@ -1428,7 +1481,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); case 16: { - (yyval) = (yyvsp[-2]) << (yyvsp[0]); + (yyval) = (yyvsp[-2]) > (yyvsp[0]); } break; @@ -1436,7 +1489,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); case 17: { - (yyval) = (yyvsp[-2]) - (yyvsp[0]); + (yyval) = (yyvsp[-2]) < (yyvsp[0]); } break; @@ -1444,7 +1497,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); case 18: { - (yyval) = (yyvsp[-2]) + (yyvsp[0]); + (yyval) = (yyvsp[-2]) >> (yyvsp[0]); } break; @@ -1452,40 +1505,78 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); case 19: { - if ((yyvsp[0]) == 0) { - std::ostringstream stream; - stream << (yyvsp[-2]) << " % " << (yyvsp[0]); - std::string text = stream.str(); - context->diagnostics->report(pp::Diagnostics::PP_DIVISION_BY_ZERO, - context->token->location, - text.c_str()); - YYABORT; - } else { + (yyval) = (yyvsp[-2]) << (yyvsp[0]); + } + + break; + + case 20: + + { + (yyval) = (yyvsp[-2]) - (yyvsp[0]); + } + + break; + + case 21: + + { + (yyval) = (yyvsp[-2]) + (yyvsp[0]); + } + + break; + + case 22: + + { + if ((yyvsp[0]) == 0) + { + if (!context->isIgnoringErrors()) + { + std::ostringstream stream; + stream << (yyvsp[-2]) << " % " << (yyvsp[0]); + std::string text = stream.str(); + context->diagnostics->report(pp::Diagnostics::PP_DIVISION_BY_ZERO, + context->token->location, + text.c_str()); + *(context->valid) = false; + } + (yyval) = static_cast(0); + } + else + { (yyval) = (yyvsp[-2]) % (yyvsp[0]); } } break; - case 20: + case 23: { - if ((yyvsp[0]) == 0) { - std::ostringstream stream; - stream << (yyvsp[-2]) << " / " << (yyvsp[0]); - std::string text = stream.str(); - context->diagnostics->report(pp::Diagnostics::PP_DIVISION_BY_ZERO, - context->token->location, - text.c_str()); - YYABORT; - } else { + if ((yyvsp[0]) == 0) + { + if (!context->isIgnoringErrors()) + { + std::ostringstream stream; + stream << (yyvsp[-2]) << " / " << (yyvsp[0]); + std::string text = stream.str(); + context->diagnostics->report(pp::Diagnostics::PP_DIVISION_BY_ZERO, + context->token->location, + text.c_str()); + *(context->valid) = false; + } + (yyval) = static_cast(0); + } + else + { (yyval) = (yyvsp[-2]) / (yyvsp[0]); } } break; - case 21: + case 24: { (yyval) = (yyvsp[-2]) * (yyvsp[0]); @@ -1493,7 +1584,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); break; - case 22: + case 25: { (yyval) = ! (yyvsp[0]); @@ -1501,7 +1592,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); break; - case 23: + case 26: { (yyval) = ~ (yyvsp[0]); @@ -1509,7 +1600,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); break; - case 24: + case 27: { (yyval) = - (yyvsp[0]); @@ -1517,7 +1608,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); break; - case 25: + case 28: { (yyval) = + (yyvsp[0]); @@ -1525,7 +1616,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); break; - case 26: + case 29: { (yyval) = (yyvsp[-1]); @@ -1767,22 +1858,35 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); int yylex(YYSTYPE *lvalp, Context *context) { + pp::Token *token = context->token; + if (!context->parsePresetToken) + { + context->lexer->lex(token); + } + context->parsePresetToken = false; + int type = 0; - pp::Token *token = context->token; switch (token->type) { case pp::Token::CONST_INT: { unsigned int val = 0; - if (!token->uValue(&val)) + int testVal = 0; + if (!token->uValue(&val) || (!token->iValue(&testVal) && + context->errorSettings.integerLiteralsMustFit32BitSignedRange)) { context->diagnostics->report(pp::Diagnostics::PP_INTEGER_OVERFLOW, token->location, token->text); + *(context->valid) = false; } *lvalp = static_cast(val); type = TOK_CONST_INT; break; } + case pp::Token::IDENTIFIER: + *lvalp = static_cast(-1); + type = TOK_IDENTIFIER; + break; case pp::Token::OP_OR: type = TOK_OP_OR; break; @@ -1828,10 +1932,6 @@ int yylex(YYSTYPE *lvalp, Context *context) break; } - // Advance to the next token if the current one is valid. - if (type != 0) - context->lexer->lex(token); - return type; } @@ -1850,13 +1950,21 @@ ExpressionParser::ExpressionParser(Lexer *lexer, Diagnostics *diagnostics) { } -bool ExpressionParser::parse(Token *token, int *result) +bool ExpressionParser::parse(Token *token, + int *result, + bool parsePresetToken, + const ErrorSettings &errorSettings, + bool *valid) { Context context; context.diagnostics = mDiagnostics; context.lexer = mLexer; context.token = token; context.result = result; + context.ignoreErrors = 0; + context.parsePresetToken = parsePresetToken; + context.errorSettings = errorSettings; + context.valid = valid; int ret = yyparse(&context); switch (ret) { diff --git a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/ExpressionParser.h b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/ExpressionParser.h index 4b80ba7261ab..841c67b61cdb 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/ExpressionParser.h +++ b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/ExpressionParser.h @@ -7,21 +7,31 @@ #ifndef COMPILER_PREPROCESSOR_EXPRESSIONPARSER_H_ #define COMPILER_PREPROCESSOR_EXPRESSIONPARSER_H_ +#include "DiagnosticsBase.h" #include "pp_utils.h" namespace pp { -class Diagnostics; class Lexer; struct Token; class ExpressionParser { public: + struct ErrorSettings + { + Diagnostics::ID unexpectedIdentifier; + bool integerLiteralsMustFit32BitSignedRange; + }; + ExpressionParser(Lexer *lexer, Diagnostics *diagnostics); - bool parse(Token *token, int *result); + bool parse(Token *token, + int *result, + bool parsePresetToken, + const ErrorSettings &errorSettings, + bool *valid); private: PP_DISALLOW_COPY_AND_ASSIGN(ExpressionParser); diff --git a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/ExpressionParser.y b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/ExpressionParser.y index 09337365301c..7b5d9e9cee96 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/ExpressionParser.y +++ b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/ExpressionParser.y @@ -52,6 +52,7 @@ typedef __int64 YYSTYPE; #include typedef intmax_t YYSTYPE; #endif // _MSC_VER + #define YYENABLE_NLS 0 #define YYLTYPE_IS_TRIVIAL 1 #define YYSTYPE_IS_TRIVIAL 1 @@ -64,6 +65,17 @@ struct Context pp::Lexer* lexer; pp::Token* token; int* result; + bool parsePresetToken; + + pp::ExpressionParser::ErrorSettings errorSettings; + bool *valid; + + void startIgnoreErrors() { ++ignoreErrors; } + void endIgnoreErrors() { --ignoreErrors; } + + bool isIgnoringErrors() { return ignoreErrors > 0; } + + int ignoreErrors; }; } // namespace %} @@ -79,6 +91,7 @@ static void yyerror(Context* context, const char* reason); %} %token TOK_CONST_INT +%token TOK_IDENTIFIER %left TOK_OP_OR %left TOK_OP_AND %left '|' @@ -102,11 +115,58 @@ input expression : TOK_CONST_INT - | expression TOK_OP_OR expression { - $$ = $1 || $3; + | TOK_IDENTIFIER { + if (!context->isIgnoringErrors()) + { + // This rule should be applied right after the token is lexed, so we can + // refer to context->token in the error message. + context->diagnostics->report(context->errorSettings.unexpectedIdentifier, + context->token->location, context->token->text); + *(context->valid) = false; + } + $$ = $1; } - | expression TOK_OP_AND expression { - $$ = $1 && $3; + | expression TOK_OP_OR { + if ($1 != 0) + { + // Ignore errors in the short-circuited part of the expression. + // ESSL3.00 section 3.4: + // If an operand is not evaluated, the presence of undefined identifiers + // in the operand will not cause an error. + // Unevaluated division by zero should not cause an error either. + context->startIgnoreErrors(); + } + } expression { + if ($1 != 0) + { + context->endIgnoreErrors(); + $$ = static_cast(1); + } + else + { + $$ = $1 || $4; + } + } + | expression TOK_OP_AND { + if ($1 == 0) + { + // Ignore errors in the short-circuited part of the expression. + // ESSL3.00 section 3.4: + // If an operand is not evaluated, the presence of undefined identifiers + // in the operand will not cause an error. + // Unevaluated division by zero should not cause an error either. + context->startIgnoreErrors(); + } + } expression { + if ($1 == 0) + { + context->endIgnoreErrors(); + $$ = static_cast(0); + } + else + { + $$ = $1 && $4; + } } | expression '|' expression { $$ = $1 | $3; @@ -148,28 +208,42 @@ expression $$ = $1 + $3; } | expression '%' expression { - if ($3 == 0) { - std::ostringstream stream; - stream << $1 << " % " << $3; - std::string text = stream.str(); - context->diagnostics->report(pp::Diagnostics::PP_DIVISION_BY_ZERO, - context->token->location, - text.c_str()); - YYABORT; - } else { + if ($3 == 0) + { + if (!context->isIgnoringErrors()) + { + std::ostringstream stream; + stream << $1 << " % " << $3; + std::string text = stream.str(); + context->diagnostics->report(pp::Diagnostics::PP_DIVISION_BY_ZERO, + context->token->location, + text.c_str()); + *(context->valid) = false; + } + $$ = static_cast(0); + } + else + { $$ = $1 % $3; } } | expression '/' expression { - if ($3 == 0) { - std::ostringstream stream; - stream << $1 << " / " << $3; - std::string text = stream.str(); - context->diagnostics->report(pp::Diagnostics::PP_DIVISION_BY_ZERO, - context->token->location, - text.c_str()); - YYABORT; - } else { + if ($3 == 0) + { + if (!context->isIgnoringErrors()) + { + std::ostringstream stream; + stream << $1 << " / " << $3; + std::string text = stream.str(); + context->diagnostics->report(pp::Diagnostics::PP_DIVISION_BY_ZERO, + context->token->location, + text.c_str()); + *(context->valid) = false; + } + $$ = static_cast(0); + } + else + { $$ = $1 / $3; } } @@ -197,22 +271,35 @@ expression int yylex(YYSTYPE *lvalp, Context *context) { + pp::Token *token = context->token; + if (!context->parsePresetToken) + { + context->lexer->lex(token); + } + context->parsePresetToken = false; + int type = 0; - pp::Token *token = context->token; switch (token->type) { case pp::Token::CONST_INT: { unsigned int val = 0; - if (!token->uValue(&val)) + int testVal = 0; + if (!token->uValue(&val) || (!token->iValue(&testVal) && + context->errorSettings.integerLiteralsMustFit32BitSignedRange)) { context->diagnostics->report(pp::Diagnostics::PP_INTEGER_OVERFLOW, token->location, token->text); + *(context->valid) = false; } *lvalp = static_cast(val); type = TOK_CONST_INT; break; } + case pp::Token::IDENTIFIER: + *lvalp = static_cast(-1); + type = TOK_IDENTIFIER; + break; case pp::Token::OP_OR: type = TOK_OP_OR; break; @@ -258,10 +345,6 @@ int yylex(YYSTYPE *lvalp, Context *context) break; } - // Advance to the next token if the current one is valid. - if (type != 0) - context->lexer->lex(token); - return type; } @@ -280,13 +363,21 @@ ExpressionParser::ExpressionParser(Lexer *lexer, Diagnostics *diagnostics) { } -bool ExpressionParser::parse(Token *token, int *result) +bool ExpressionParser::parse(Token *token, + int *result, + bool parsePresetToken, + const ErrorSettings &errorSettings, + bool *valid) { Context context; context.diagnostics = mDiagnostics; context.lexer = mLexer; context.token = token; context.result = result; + context.ignoreErrors = 0; + context.parsePresetToken = parsePresetToken; + context.errorSettings = errorSettings; + context.valid = valid; int ret = yyparse(&context); switch (ret) { diff --git a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/Input.cpp b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/Input.cpp index f9910a6cc315..5541d46f7291 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/Input.cpp +++ b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/Input.cpp @@ -29,13 +29,75 @@ Input::Input(size_t count, const char *const string[], const int length[]) : } } -size_t Input::read(char *buf, size_t maxSize) +const char *Input::skipChar() +{ + // This function should only be called when there is a character to skip. + assert(mReadLoc.cIndex < mLength[mReadLoc.sIndex]); + ++mReadLoc.cIndex; + if (mReadLoc.cIndex == mLength[mReadLoc.sIndex]) + { + ++mReadLoc.sIndex; + mReadLoc.cIndex = 0; + } + if (mReadLoc.sIndex >= mCount) + { + return nullptr; + } + return mString[mReadLoc.sIndex] + mReadLoc.cIndex; +} + +size_t Input::read(char *buf, size_t maxSize, int *lineNo) { size_t nRead = 0; - while ((nRead < maxSize) && (mReadLoc.sIndex < mCount)) + // The previous call to read might have stopped copying the string when encountering a line + // continuation. Check for this possibility first. + if (mReadLoc.sIndex < mCount && maxSize > 0) + { + const char *c = mString[mReadLoc.sIndex] + mReadLoc.cIndex; + if ((*c) == '\\') + { + c = skipChar(); + if (c != nullptr && (*c) == '\n') + { + // Line continuation of backslash + newline. + skipChar(); + ++(*lineNo); + } + else if (c != nullptr && (*c) == '\r') + { + // Line continuation. Could be backslash + '\r\n' or just backslash + '\r'. + c = skipChar(); + if (c != nullptr && (*c) == '\n') + { + skipChar(); + } + ++(*lineNo); + } + else + { + // Not line continuation, so write the skipped backslash to buf. + *buf = '\\'; + ++nRead; + } + } + } + + size_t maxRead = maxSize; + while ((nRead < maxRead) && (mReadLoc.sIndex < mCount)) { size_t size = mLength[mReadLoc.sIndex] - mReadLoc.cIndex; size = std::min(size, maxSize); + for (size_t i = 0; i < size; ++i) + { + // Stop if a possible line continuation is encountered. + // It will be processed on the next call on input, which skips it + // and increments line number if necessary. + if (*(mString[mReadLoc.sIndex] + mReadLoc.cIndex + i) == '\\') + { + size = i; + maxRead = nRead + size; // Stop reading right before the backslash. + } + } std::memcpy(buf + nRead, mString[mReadLoc.sIndex] + mReadLoc.cIndex, size); nRead += size; mReadLoc.cIndex += size; diff --git a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/Input.h b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/Input.h index e951cb4d5fe0..a1de7ddd86b5 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/Input.h +++ b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/Input.h @@ -33,7 +33,7 @@ class Input return mLength[index]; } - size_t read(char *buf, size_t maxSize); + size_t read(char *buf, size_t maxSize, int *lineNo); struct Location { @@ -49,6 +49,10 @@ class Input const Location &readLoc() const { return mReadLoc; } private: + // Skip a character and return the next character after the one that was skipped. + // Return nullptr if data runs out. + const char *skipChar(); + // Input. size_t mCount; const char * const *mString; diff --git a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/Macro.cpp b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/Macro.cpp index 13cb14e3dc8c..4c4d5fd2e29f 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/Macro.cpp +++ b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/Macro.cpp @@ -6,6 +6,8 @@ #include "Macro.h" +#include + #include "Token.h" namespace pp @@ -19,5 +21,23 @@ bool Macro::equals(const Macro &other) const (replacements == other.replacements); } +void PredefineMacro(MacroSet *macroSet, const char *name, int value) +{ + std::ostringstream stream; + stream << value; + + Token token; + token.type = Token::CONST_INT; + token.text = stream.str(); + + Macro macro; + macro.predefined = true; + macro.type = Macro::kTypeObj; + macro.name = name; + macro.replacements.push_back(token); + + (*macroSet)[name] = macro; +} + } // namespace pp diff --git a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/Macro.h b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/Macro.h index 7662a9c5a292..31ee22c26a2b 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/Macro.h +++ b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/Macro.h @@ -45,6 +45,8 @@ struct Macro typedef std::map MacroSet; +void PredefineMacro(MacroSet *macroSet, const char *name, int value); + } // namespace pp #endif // COMPILER_PREPROCESSOR_MACRO_H_ diff --git a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/MacroExpander.cpp b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/MacroExpander.cpp index 69e2f3906931..e878ee345a6d 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/MacroExpander.cpp +++ b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/MacroExpander.cpp @@ -26,7 +26,7 @@ class TokenLexer : public Lexer mIter = mTokens.begin(); } - virtual void lex(Token *token) + void lex(Token *token) override { if (mIter == mTokens.end()) { @@ -48,10 +48,9 @@ class TokenLexer : public Lexer MacroExpander::MacroExpander(Lexer *lexer, MacroSet *macroSet, - Diagnostics *diagnostics) - : mLexer(lexer), - mMacroSet(macroSet), - mDiagnostics(diagnostics) + Diagnostics *diagnostics, + bool parseDefined) + : mLexer(lexer), mMacroSet(macroSet), mDiagnostics(diagnostics), mParseDefined(parseDefined) { } @@ -67,11 +66,54 @@ void MacroExpander::lex(Token *token) { while (true) { + const char kDefined[] = "defined"; + getToken(token); if (token->type != Token::IDENTIFIER) break; + // Defined operator is parsed here since it may be generated by macro expansion. + // Defined operator produced by macro expansion has undefined behavior according to C++ + // spec, which the GLSL spec references (see C++14 draft spec section 16.1.4), but this + // behavior is needed for passing dEQP tests, which enforce stricter compatibility between + // implementations. + if (mParseDefined && token->text == kDefined) + { + bool paren = false; + getToken(token); + if (token->type == '(') + { + paren = true; + getToken(token); + } + if (token->type != Token::IDENTIFIER) + { + mDiagnostics->report(Diagnostics::PP_UNEXPECTED_TOKEN, token->location, + token->text); + break; + } + auto iter = mMacroSet->find(token->text); + std::string expression = iter != mMacroSet->end() ? "1" : "0"; + + if (paren) + { + getToken(token); + if (token->type != ')') + { + mDiagnostics->report(Diagnostics::PP_UNEXPECTED_TOKEN, token->location, + token->text); + break; + } + } + + // We have a valid defined operator. + // Convert the current token into a CONST_INT token. + token->type = Token::CONST_INT; + token->text = expression; + break; + } + if (token->expansionDisabled()) break; @@ -187,6 +229,12 @@ bool MacroExpander::expandMacro(const Macro ¯o, std::vector *replacements) { replacements->clear(); + + // In the case of an object-like macro, the replacement list gets its location + // from the identifier, but in the case of a function-like macro, the replacement + // list gets its location from the closing parenthesis of the macro invocation. + // This is tested by dEQP-GLES3.functional.shaders.preprocessor.predefined_macros.* + SourceLocation replacementLocation = identifier.location; if (macro.type == Macro::kTypeObj) { replacements->assign(macro.replacements.begin(), @@ -218,7 +266,7 @@ bool MacroExpander::expandMacro(const Macro ¯o, assert(macro.type == Macro::kTypeFunc); std::vector args; args.reserve(macro.parameters.size()); - if (!collectMacroArgs(macro, identifier, &args)) + if (!collectMacroArgs(macro, identifier, &args, &replacementLocation)) return false; replaceMacroParams(macro, args, replacements); @@ -234,14 +282,15 @@ bool MacroExpander::expandMacro(const Macro ¯o, repl.setAtStartOfLine(identifier.atStartOfLine()); repl.setHasLeadingSpace(identifier.hasLeadingSpace()); } - repl.location = identifier.location; + repl.location = replacementLocation; } return true; } bool MacroExpander::collectMacroArgs(const Macro ¯o, const Token &identifier, - std::vector *args) + std::vector *args, + SourceLocation *closingParenthesisLocation) { Token token; getToken(&token); @@ -271,6 +320,7 @@ bool MacroExpander::collectMacroArgs(const Macro ¯o, case ')': --openParens; isArg = openParens != 0; + *closingParenthesisLocation = token.location; break; case ',': // The individual arguments are separated by comma tokens, but @@ -317,7 +367,7 @@ bool MacroExpander::collectMacroArgs(const Macro ¯o, { MacroArg &arg = args->at(i); TokenLexer lexer(&arg); - MacroExpander expander(&lexer, mMacroSet, mDiagnostics); + MacroExpander expander(&lexer, mMacroSet, mDiagnostics, mParseDefined); arg.clear(); expander.lex(&token); diff --git a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/MacroExpander.h b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/MacroExpander.h index c3ac43257d87..3cc860d75358 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/MacroExpander.h +++ b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/MacroExpander.h @@ -19,14 +19,15 @@ namespace pp { class Diagnostics; +struct SourceLocation; class MacroExpander : public Lexer { public: - MacroExpander(Lexer *lexer, MacroSet *macroSet, Diagnostics *diagnostics); - virtual ~MacroExpander(); + MacroExpander(Lexer *lexer, MacroSet *macroSet, Diagnostics *diagnostics, bool parseDefined); + ~MacroExpander() override; - virtual void lex(Token *token); + void lex(Token *token) override; private: PP_DISALLOW_COPY_AND_ASSIGN(MacroExpander); @@ -45,7 +46,8 @@ class MacroExpander : public Lexer typedef std::vector MacroArg; bool collectMacroArgs(const Macro ¯o, const Token &identifier, - std::vector *args); + std::vector *args, + SourceLocation *closingParenthesisLocation); void replaceMacroParams(const Macro ¯o, const std::vector &args, std::vector *replacements); @@ -79,8 +81,9 @@ class MacroExpander : public Lexer Lexer *mLexer; MacroSet *mMacroSet; Diagnostics *mDiagnostics; + bool mParseDefined; - std::unique_ptr mReserveToken; + std::auto_ptr mReserveToken; std::vector mContextStack; }; diff --git a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/Preprocessor.cpp b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/Preprocessor.cpp index 3522fa1abb9e..aeb9c46f9dc3 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/Preprocessor.cpp +++ b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/Preprocessor.cpp @@ -7,7 +7,6 @@ #include "Preprocessor.h" #include -#include #include "DiagnosticsBase.h" #include "DirectiveParser.h" @@ -27,12 +26,11 @@ struct PreprocessorImpl DirectiveParser directiveParser; MacroExpander macroExpander; - PreprocessorImpl(Diagnostics *diag, - DirectiveHandler *directiveHandler) + PreprocessorImpl(Diagnostics *diag, DirectiveHandler *directiveHandler) : diagnostics(diag), tokenizer(diag), directiveParser(&tokenizer, ¯oSet, diag, directiveHandler), - macroExpander(&directiveParser, ¯oSet, diag) + macroExpander(&directiveParser, ¯oSet, diag, false) { } }; @@ -52,12 +50,12 @@ bool Preprocessor::init(size_t count, const char * const string[], const int length[]) { - static const int kGLSLVersion = 100; + static const int kDefaultGLSLVersion = 100; // Add standard pre-defined macros. predefineMacro("__LINE__", 0); predefineMacro("__FILE__", 0); - predefineMacro("__VERSION__", kGLSLVersion); + predefineMacro("__VERSION__", kDefaultGLSLVersion); predefineMacro("GL_ES", 1); return mImpl->tokenizer.init(count, string, length); @@ -65,20 +63,7 @@ bool Preprocessor::init(size_t count, void Preprocessor::predefineMacro(const char *name, int value) { - std::ostringstream stream; - stream << value; - - Token token; - token.type = Token::CONST_INT; - token.text = stream.str(); - - Macro macro; - macro.predefined = true; - macro.type = Macro::kTypeObj; - macro.name = name; - macro.replacements.push_back(token); - - mImpl->macroSet[name] = macro; + PredefineMacro(&mImpl->macroSet, name, value); } void Preprocessor::lex(Token *token) diff --git a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/Tokenizer.cpp b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/Tokenizer.cpp index dd9d41a19c1d..1caee4757d92 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/Tokenizer.cpp +++ b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/Tokenizer.cpp @@ -6,11 +6,6 @@ // // This file is auto-generated by generate_parser.sh. DO NOT EDIT! -// This file was edited anyways to ignore clang warnings. -#if defined(__clang__) -#pragma clang diagnostic push -#pragma GCC diagnostic ignored "-Wunneeded-internal-declaration" -#endif @@ -599,7 +594,7 @@ typedef pp::SourceLocation YYLTYPE; } while(0); #define YY_INPUT(buf, result, maxSize) \ - result = yyextra->input.read(buf, maxSize); + result = yyextra->input.read(buf, maxSize, &yylineno); #define INITIAL 0 #define COMMENT 1 @@ -717,7 +712,7 @@ static void yy_flex_strncpy (char *,yyconst char *,int ,yyscan_t yyscanner); static int yy_flex_strlen (yyconst char * ,yyscan_t yyscanner); #endif -#ifndef YY_NO_INPUT +#if 0 //#ifndef YY_NO_INPUT #ifdef __cplusplus static int yyinput (yyscan_t yyscanner ); @@ -1531,7 +1526,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner) return yy_is_jam ? 0 : yy_current_state; } -#ifndef YY_NO_INPUT +#if 0 //#ifndef YY_NO_INPUT #ifdef __cplusplus static int yyinput (yyscan_t yyscanner) #else diff --git a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/Tokenizer.h b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/Tokenizer.h index 78eb86dd3ba5..49e64fa209f2 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/Tokenizer.h +++ b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/Tokenizer.h @@ -42,7 +42,7 @@ class Tokenizer : public Lexer void setLineNumber(int line); void setMaxTokenSize(size_t maxTokenSize); - virtual void lex(Token *token); + void lex(Token *token) override; private: PP_DISALLOW_COPY_AND_ASSIGN(Tokenizer); diff --git a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/Tokenizer.l b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/Tokenizer.l index 25c938d60869..d316da88b1d7 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/Tokenizer.l +++ b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/Tokenizer.l @@ -77,7 +77,7 @@ typedef pp::SourceLocation YYLTYPE; } while(0); #define YY_INPUT(buf, result, maxSize) \ - result = yyextra->input.read(buf, maxSize); + result = yyextra->input.read(buf, maxSize, &yylineno); %} diff --git a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/numeric_lex.h b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/numeric_lex.h index 58c51b0961c0..b32e42253f2d 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/numeric_lex.h +++ b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/numeric_lex.h @@ -48,6 +48,15 @@ bool numeric_lex_int(const std::string &str, IntType *value) template bool numeric_lex_float(const std::string &str, FloatType *value) { +// On 64-bit Intel Android, istringstream is broken. Until this is fixed in +// a newer NDK, don't use it. Android doesn't have locale support, so this +// doesn't have to force the C locale. +// TODO(thakis): Remove this once this bug has been fixed in the NDK and +// that NDK has been rolled into chromium. +#if defined(ANGLE_PLATFORM_ANDROID) && __x86_64__ + *value = strtod(str.c_str(), nullptr); + return errno != ERANGE; +#else std::istringstream stream(str); // Force "C" locale so that decimal character is always '.', and // not dependent on the current locale. @@ -55,6 +64,7 @@ bool numeric_lex_float(const std::string &str, FloatType *value) stream >> (*value); return !stream.fail(); +#endif } } // namespace pp. diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/ASTMetadataHLSL.cpp b/Source/ThirdParty/ANGLE/src/compiler/translator/ASTMetadataHLSL.cpp index 1b48dc7c38e0..31bfae9966f8 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/ASTMetadataHLSL.cpp +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/ASTMetadataHLSL.cpp @@ -105,6 +105,7 @@ class PullGradient : public TIntermTraverser { size_t calleeIndex = mDag.findIndex(node); ASSERT(calleeIndex != CallDAG::InvalidIndex && calleeIndex < mIndex); + UNUSED_ASSERTION_VARIABLE(mIndex); if ((*mMetadataList)[calleeIndex].mUsesGradient) { onGradient(); @@ -138,13 +139,16 @@ class PullGradient : public TIntermTraverser std::vector mParents; }; -// Traverses the AST of a function definition, assuming it has already been used to -// traverse the callees of that function; computes the discontinuous loops and the if -// statements that contain a discontinuous loop in their call graph. -class PullComputeDiscontinuousLoops : public TIntermTraverser +// Traverses the AST of a function definition to compute the the discontinuous loops +// and the if statements containing gradient loops. It assumes that the gradient loops +// (loops that contain a gradient) have already been computed and that it has already +// traversed the current function's callees. +class PullComputeDiscontinuousAndGradientLoops : public TIntermTraverser { public: - PullComputeDiscontinuousLoops(MetadataList *metadataList, size_t index, const CallDAG &dag) + PullComputeDiscontinuousAndGradientLoops(MetadataList *metadataList, + size_t index, + const CallDAG &dag) : TIntermTraverser(true, false, true), mMetadataList(metadataList), mMetadata(&(*metadataList)[index]), @@ -160,15 +164,15 @@ class PullComputeDiscontinuousLoops : public TIntermTraverser ASSERT(mIfs.empty()); } - // Called when a discontinuous loop or a call to a function with a discontinuous loop - // in its call graph is found. - void onDiscontinuousLoop() + // Called when traversing a gradient loop or a call to a function with a + // gradient loop in its call graph. + void onGradientLoop() { - mMetadata->mHasDiscontinuousLoopInCallGraph = true; + mMetadata->mHasGradientLoopInCallGraph = true; // Mark the latest if as using a discontinuous loop. if (!mIfs.empty()) { - mMetadata->mIfsContainingDiscontinuousLoop.insert(mIfs.back()); + mMetadata->mIfsContainingGradientLoop.insert(mIfs.back()); } } @@ -177,6 +181,11 @@ class PullComputeDiscontinuousLoops : public TIntermTraverser if (visit == PreVisit) { mLoopsAndSwitches.push_back(loop); + + if (mMetadata->hasGradientInCallGraph(loop)) + { + onGradientLoop(); + } } else if (visit == PostVisit) { @@ -198,9 +207,9 @@ class PullComputeDiscontinuousLoops : public TIntermTraverser ASSERT(mIfs.back() == node); mIfs.pop_back(); // An if using a discontinuous loop means its parents ifs are also discontinuous. - if (mMetadata->mIfsContainingDiscontinuousLoop.count(node) > 0 && !mIfs.empty()) + if (mMetadata->mIfsContainingGradientLoop.count(node) > 0 && !mIfs.empty()) { - mMetadata->mIfsContainingDiscontinuousLoop.insert(mIfs.back()); + mMetadata->mIfsContainingGradientLoop.insert(mIfs.back()); } } @@ -220,7 +229,6 @@ class PullComputeDiscontinuousLoops : public TIntermTraverser if (loop != nullptr) { mMetadata->mDiscontinuousLoops.insert(loop); - onDiscontinuousLoop(); } } break; @@ -236,7 +244,6 @@ class PullComputeDiscontinuousLoops : public TIntermTraverser } ASSERT(loop != nullptr); mMetadata->mDiscontinuousLoops.insert(loop); - onDiscontinuousLoop(); } break; case EOpKill: @@ -244,15 +251,14 @@ class PullComputeDiscontinuousLoops : public TIntermTraverser // A return or discard jumps out of all the enclosing loops if (!mLoopsAndSwitches.empty()) { - for (TIntermNode* node : mLoopsAndSwitches) + for (TIntermNode *intermNode : mLoopsAndSwitches) { - TIntermLoop *loop = node->getAsLoopNode(); + TIntermLoop *loop = intermNode->getAsLoopNode(); if (loop) { mMetadata->mDiscontinuousLoops.insert(loop); } } - onDiscontinuousLoop(); } break; default: @@ -271,10 +277,11 @@ class PullComputeDiscontinuousLoops : public TIntermTraverser { size_t calleeIndex = mDag.findIndex(node); ASSERT(calleeIndex != CallDAG::InvalidIndex && calleeIndex < mIndex); + UNUSED_ASSERTION_VARIABLE(mIndex); - if ((*mMetadataList)[calleeIndex].mHasDiscontinuousLoopInCallGraph) + if ((*mMetadataList)[calleeIndex].mHasGradientLoopInCallGraph) { - onDiscontinuousLoop(); + onGradientLoop(); } } } @@ -351,6 +358,7 @@ class PushDiscontinuousLoops : public TIntermTraverser { size_t calleeIndex = mDag.findIndex(node); ASSERT(calleeIndex != CallDAG::InvalidIndex && calleeIndex < mIndex); + UNUSED_ASSERTION_VARIABLE(mIndex); (*mMetadataList)[calleeIndex].mCalledInDiscontinuousLoop = true; } @@ -372,19 +380,14 @@ class PushDiscontinuousLoops : public TIntermTraverser } -bool ASTMetadataHLSL::hasGradientInCallGraph(TIntermSelection *node) -{ - return mControlFlowsContainingGradient.count(node) > 0; -} - bool ASTMetadataHLSL::hasGradientInCallGraph(TIntermLoop *node) { return mControlFlowsContainingGradient.count(node) > 0; } -bool ASTMetadataHLSL::hasDiscontinuousLoop(TIntermSelection *node) +bool ASTMetadataHLSL::hasGradientLoop(TIntermSelection *node) { - return mIfsContainingDiscontinuousLoop.count(node) > 0; + return mIfsContainingGradientLoop.count(node) > 0; } MetadataList CreateASTMetadataHLSL(TIntermNode *root, const CallDAG &callDag) @@ -421,10 +424,10 @@ MetadataList CreateASTMetadataHLSL(TIntermNode *root, const CallDAG &callDag) // of callgraph analysis as for the gradient. // First compute which loops are discontinuous (no specific order) and pull - // the ifs and functions using a discontinuous loop. + // the ifs and functions using a gradient loop. for (size_t i = 0; i < callDag.size(); i++) { - PullComputeDiscontinuousLoops pull(&metadataList, i, callDag); + PullComputeDiscontinuousAndGradientLoops pull(&metadataList, i, callDag); pull.traverse(callDag.getRecordFromIndex(i).node); } diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/ASTMetadataHLSL.h b/Source/ThirdParty/ANGLE/src/compiler/translator/ASTMetadataHLSL.h index b9b334dbeb92..39e671e3e026 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/ASTMetadataHLSL.h +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/ASTMetadataHLSL.h @@ -22,16 +22,15 @@ struct ASTMetadataHLSL ASTMetadataHLSL() : mUsesGradient(false), mCalledInDiscontinuousLoop(false), - mHasDiscontinuousLoopInCallGraph(false), + mHasGradientLoopInCallGraph(false), mNeedsLod0(false) { } // Here "something uses a gradient" means here that it either contains a // gradient operation, or a call to a function that uses a gradient. - bool hasGradientInCallGraph(TIntermSelection *node); bool hasGradientInCallGraph(TIntermLoop *node); - bool hasDiscontinuousLoop(TIntermSelection *node); + bool hasGradientLoop(TIntermSelection *node); // Does the function use a gradient. bool mUsesGradient; @@ -43,9 +42,9 @@ struct ASTMetadataHLSL // Remember information about the discontinuous loops and which functions // are called in such loops. bool mCalledInDiscontinuousLoop; - bool mHasDiscontinuousLoopInCallGraph; + bool mHasGradientLoopInCallGraph; std::set mDiscontinuousLoops; - std::set mIfsContainingDiscontinuousLoop; + std::set mIfsContainingGradientLoop; // Will we need to generate a Lod0 version of the function. bool mNeedsLod0; diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/ArrayReturnValueToOutParameter.cpp b/Source/ThirdParty/ANGLE/src/compiler/translator/ArrayReturnValueToOutParameter.cpp index 4a283a543f7a..510ade84c1f1 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/ArrayReturnValueToOutParameter.cpp +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/ArrayReturnValueToOutParameter.cpp @@ -36,10 +36,28 @@ TIntermSymbol *CreateReturnValueOutSymbol(const TType &type) return CreateReturnValueSymbol(outType); } +TIntermAggregate *CreateReplacementCall(TIntermAggregate *originalCall, TIntermTyped *returnValueTarget) +{ + TIntermAggregate *replacementCall = new TIntermAggregate(EOpFunctionCall); + replacementCall->setType(TType(EbtVoid)); + replacementCall->setUserDefined(); + replacementCall->setNameObj(originalCall->getNameObj()); + replacementCall->setFunctionId(originalCall->getFunctionId()); + replacementCall->setLine(originalCall->getLine()); + TIntermSequence *replacementParameters = replacementCall->getSequence(); + TIntermSequence *originalParameters = originalCall->getSequence(); + for (auto ¶m : *originalParameters) + { + replacementParameters->push_back(param); + } + replacementParameters->push_back(returnValueTarget); + return replacementCall; +} + class ArrayReturnValueToOutParameterTraverser : private TIntermTraverser { public: - static void apply(TIntermNode *root); + static void apply(TIntermNode *root, unsigned int *temporaryIndex); private: ArrayReturnValueToOutParameterTraverser(); @@ -50,9 +68,10 @@ class ArrayReturnValueToOutParameterTraverser : private TIntermTraverser bool mInFunctionWithArrayReturnValue; }; -void ArrayReturnValueToOutParameterTraverser::apply(TIntermNode *root) +void ArrayReturnValueToOutParameterTraverser::apply(TIntermNode *root, unsigned int *temporaryIndex) { ArrayReturnValueToOutParameterTraverser arrayReturnValueToOutParam; + arrayReturnValueToOutParam.useTemporaryIndex(temporaryIndex); root->traverse(&arrayReturnValueToOutParam); arrayReturnValueToOutParam.updateTree(); } @@ -98,7 +117,7 @@ bool ArrayReturnValueToOutParameterTraverser::visitAggregate(Visit visit, TInter CopyAggregateChildren(node, replacement); replacement->getSequence()->push_back(CreateReturnValueOutSymbol(node->getType())); replacement->setUserDefined(); - replacement->setName(node->getName()); + replacement->setNameObj(node->getNameObj()); replacement->setFunctionId(node->getFunctionId()); replacement->setLine(node->getLine()); replacement->setType(TType(EbtVoid)); @@ -107,18 +126,32 @@ bool ArrayReturnValueToOutParameterTraverser::visitAggregate(Visit visit, TInter } else if (node->getOp() == EOpFunctionCall) { - // TODO (oetuaho@nvidia.com): Call sites where the returned array is not assigned are not handled yet. + // Handle call sites where the returned array is not assigned. // Examples where f() is a function returning an array: - // f(); - // another_function(f()); - // another_array == f(); - UNIMPLEMENTED(); + // 1. f(); + // 2. another_array == f(); + // 3. another_function(f()); + // 4. return f(); + // Cases 2 to 4 are already converted to simpler cases by SeparateExpressionsReturningArrays, so we + // only need to worry about the case where a function call returning an array forms an expression by + // itself. + TIntermAggregate *parentAgg = getParentNode()->getAsAggregate(); + if (parentAgg != nullptr && parentAgg->getOp() == EOpSequence) + { + nextTemporaryIndex(); + TIntermSequence replacements; + replacements.push_back(createTempDeclaration(node->getType())); + TIntermSymbol *returnSymbol = createTempSymbol(node->getType()); + replacements.push_back(CreateReplacementCall(node, returnSymbol)); + mMultiReplacements.push_back(NodeReplaceWithMultipleEntry(parentAgg, node, replacements)); + } + return false; } } } else if (visit == PostVisit) { - if (node->getOp() == EOpFunction && node->isArray()) + if (node->getOp() == EOpFunction) { mInFunctionWithArrayReturnValue = false; } @@ -158,19 +191,7 @@ bool ArrayReturnValueToOutParameterTraverser::visitBinary(Visit visit, TIntermBi TIntermAggregate *rightAgg = node->getRight()->getAsAggregate(); if (rightAgg != nullptr && rightAgg->getOp() == EOpFunctionCall && rightAgg->isUserDefined()) { - TIntermAggregate *replacementCall = new TIntermAggregate(EOpFunctionCall); - replacementCall->setType(TType(EbtVoid)); - replacementCall->setUserDefined(); - replacementCall->setName(rightAgg->getName()); - replacementCall->setFunctionId(rightAgg->getFunctionId()); - replacementCall->setLine(rightAgg->getLine()); - TIntermSequence *replacementParameters = replacementCall->getSequence(); - TIntermSequence *originalParameters = rightAgg->getSequence(); - for (auto ¶m : *originalParameters) - { - replacementParameters->push_back(param); - } - replacementParameters->push_back(node->getLeft()); + TIntermAggregate *replacementCall = CreateReplacementCall(rightAgg, node->getLeft()); mReplacements.push_back(NodeUpdateEntry(getParentNode(), node, replacementCall, false)); } } @@ -179,7 +200,7 @@ bool ArrayReturnValueToOutParameterTraverser::visitBinary(Visit visit, TIntermBi } // namespace -void ArrayReturnValueToOutParameter(TIntermNode *root) +void ArrayReturnValueToOutParameter(TIntermNode *root, unsigned int *temporaryIndex) { - ArrayReturnValueToOutParameterTraverser::apply(root); + ArrayReturnValueToOutParameterTraverser::apply(root, temporaryIndex); } diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/ArrayReturnValueToOutParameter.h b/Source/ThirdParty/ANGLE/src/compiler/translator/ArrayReturnValueToOutParameter.h index 3ae7dc1606bb..983e203e6281 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/ArrayReturnValueToOutParameter.h +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/ArrayReturnValueToOutParameter.h @@ -11,6 +11,6 @@ class TIntermNode; -void ArrayReturnValueToOutParameter(TIntermNode *root); +void ArrayReturnValueToOutParameter(TIntermNode *root, unsigned int *temporaryIndex); #endif // COMPILER_TRANSLATOR_ARRAYRETURNVALUETOOUTPARAMETER_H_ diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/BaseTypes.h b/Source/ThirdParty/ANGLE/src/compiler/translator/BaseTypes.h index c174dfc49c9c..69dd60f0d694 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/BaseTypes.h +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/BaseTypes.h @@ -18,7 +18,10 @@ enum TPrecision EbpUndefined, EbpLow, EbpMedium, - EbpHigh + EbpHigh, + + // end of list + EbpLast }; inline const char* getPrecisionString(TPrecision p) @@ -77,6 +80,9 @@ enum TBasicType EbtStruct, EbtInterfaceBlock, EbtAddress, // should be deprecated?? + + // end of list + EbtLast }; const char* getBasicString(TBasicType t); @@ -284,20 +290,18 @@ inline bool SupportsPrecision(TBasicType type) // enum TQualifier { - EvqTemporary, // For temporaries (within a function), read/write - EvqGlobal, // For globals read/write - EvqConst, // User defined constants and non-output parameters in functions - EvqAttribute, // Readonly - EvqVaryingIn, // readonly, fragment shaders only - EvqVaryingOut, // vertex shaders only read/write - EvqInvariantVaryingIn, // readonly, fragment shaders only - EvqInvariantVaryingOut, // vertex shaders only read/write - EvqUniform, // Readonly, vertex and fragment - - EvqVertexIn, // Vertex shader input - EvqFragmentOut, // Fragment shader output - EvqVertexOut, // Vertex shader output - EvqFragmentIn, // Fragment shader input + EvqTemporary, // For temporaries (within a function), read/write + EvqGlobal, // For globals read/write + EvqConst, // User defined constants and non-output parameters in functions + EvqAttribute, // Readonly + EvqVaryingIn, // readonly, fragment shaders only + EvqVaryingOut, // vertex shaders only read/write + EvqUniform, // Readonly, vertex and fragment + + EvqVertexIn, // Vertex shader input + EvqFragmentOut, // Fragment shader output + EvqVertexOut, // Vertex shader output + EvqFragmentIn, // Fragment shader input // parameters EvqIn, @@ -307,6 +311,7 @@ enum TQualifier // built-ins read by vertex shader EvqInstanceID, + EvqVertexID, // built-ins written by vertex shader EvqPosition, @@ -320,21 +325,26 @@ enum TQualifier // built-ins written by fragment shader EvqFragColor, EvqFragData, - EvqFragDepth, + + EvqFragDepth, // gl_FragDepth for ESSL300. + EvqFragDepthEXT, // gl_FragDepthEXT for ESSL100, EXT_frag_depth. + + EvqSecondaryFragColorEXT, // EXT_blend_func_extended + EvqSecondaryFragDataEXT, // EXT_blend_func_extended // built-ins written by the shader_framebuffer_fetch extension(s) EvqLastFragColor, EvqLastFragData, // GLSL ES 3.0 vertex output and fragment input - EvqSmooth, // Incomplete qualifier, smooth is the default - EvqFlat, // Incomplete qualifier + EvqSmooth, // Incomplete qualifier, smooth is the default + EvqFlat, // Incomplete qualifier EvqSmoothOut = EvqSmooth, - EvqFlatOut = EvqFlat, - EvqCentroidOut, // Implies smooth + EvqFlatOut = EvqFlat, + EvqCentroidOut, // Implies smooth EvqSmoothIn, EvqFlatIn, - EvqCentroidIn, // Implies smooth + EvqCentroidIn, // Implies smooth // end of list EvqLast @@ -383,43 +393,48 @@ struct TLayoutQualifier // inline const char* getQualifierString(TQualifier q) { + // clang-format off switch(q) { - case EvqTemporary: return "Temporary"; break; - case EvqGlobal: return "Global"; break; - case EvqConst: return "const"; break; - case EvqConstReadOnly: return "const"; break; - case EvqAttribute: return "attribute"; break; - case EvqVaryingIn: return "varying"; break; - case EvqVaryingOut: return "varying"; break; - case EvqInvariantVaryingIn: return "invariant varying"; break; - case EvqInvariantVaryingOut:return "invariant varying"; break; - case EvqUniform: return "uniform"; break; - case EvqVertexIn: return "in"; break; - case EvqFragmentOut: return "out"; break; - case EvqVertexOut: return "out"; break; - case EvqFragmentIn: return "in"; break; - case EvqIn: return "in"; break; - case EvqOut: return "out"; break; - case EvqInOut: return "inout"; break; - case EvqInstanceID: return "InstanceID"; break; - case EvqPosition: return "Position"; break; - case EvqPointSize: return "PointSize"; break; - case EvqFragCoord: return "FragCoord"; break; - case EvqFrontFacing: return "FrontFacing"; break; - case EvqFragColor: return "FragColor"; break; - case EvqFragData: return "FragData"; break; - case EvqFragDepth: return "FragDepth"; break; - case EvqSmoothOut: return "smooth out"; break; - case EvqCentroidOut: return "centroid out"; break; - case EvqFlatOut: return "flat out"; break; - case EvqSmoothIn: return "smooth in"; break; - case EvqCentroidIn: return "centroid in"; break; - case EvqFlatIn: return "flat in"; break; - case EvqLastFragColor: return "LastFragColor"; break; - case EvqLastFragData: return "LastFragData"; break; - default: UNREACHABLE(); return "unknown qualifier"; + case EvqTemporary: return "Temporary"; + case EvqGlobal: return "Global"; + case EvqConst: return "const"; + case EvqAttribute: return "attribute"; + case EvqVaryingIn: return "varying"; + case EvqVaryingOut: return "varying"; + case EvqUniform: return "uniform"; + case EvqVertexIn: return "in"; + case EvqFragmentOut: return "out"; + case EvqVertexOut: return "out"; + case EvqFragmentIn: return "in"; + case EvqIn: return "in"; + case EvqOut: return "out"; + case EvqInOut: return "inout"; + case EvqConstReadOnly: return "const"; + case EvqInstanceID: return "InstanceID"; + case EvqVertexID: return "VertexID"; + case EvqPosition: return "Position"; + case EvqPointSize: return "PointSize"; + case EvqFragCoord: return "FragCoord"; + case EvqFrontFacing: return "FrontFacing"; + case EvqPointCoord: return "PointCoord"; + case EvqFragColor: return "FragColor"; + case EvqFragData: return "FragData"; + case EvqFragDepthEXT: return "FragDepth"; + case EvqFragDepth: return "FragDepth"; + case EvqSecondaryFragColorEXT: return "SecondaryFragColorEXT"; + case EvqSecondaryFragDataEXT: return "SecondaryFragDataEXT"; + case EvqLastFragColor: return "LastFragColor"; + case EvqLastFragData: return "LastFragData"; + case EvqSmoothOut: return "smooth out"; + case EvqCentroidOut: return "centroid out"; + case EvqFlatOut: return "flat out"; + case EvqSmoothIn: return "smooth in"; + case EvqFlatIn: return "flat in"; + case EvqCentroidIn: return "centroid in"; + default: UNREACHABLE(); return "unknown qualifier"; } + // clang-format on } inline const char* getMatrixPackingString(TLayoutMatrixPacking mpq) diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/BuiltInFunctionEmulator.cpp b/Source/ThirdParty/ANGLE/src/compiler/translator/BuiltInFunctionEmulator.cpp index 51461207c5d4..0c7f149ee667 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/BuiltInFunctionEmulator.cpp +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/BuiltInFunctionEmulator.cpp @@ -11,28 +11,31 @@ class BuiltInFunctionEmulator::BuiltInFunctionEmulationMarker : public TIntermTraverser { public: - BuiltInFunctionEmulationMarker(BuiltInFunctionEmulator& emulator) - : mEmulator(emulator) + BuiltInFunctionEmulationMarker(BuiltInFunctionEmulator &emulator) + : TIntermTraverser(true, false, false), + mEmulator(emulator) { } - virtual bool visitUnary(Visit visit, TIntermUnary* node) + bool visitUnary(Visit visit, TIntermUnary *node) override { - if (visit == PreVisit) { - bool needToEmulate = mEmulator.SetFunctionCalled( - node->getOp(), node->getOperand()->getType()); + if (visit == PreVisit) + { + bool needToEmulate = mEmulator.SetFunctionCalled(node->getOp(), node->getOperand()->getType()); if (needToEmulate) node->setUseEmulatedFunction(); } return true; } - virtual bool visitAggregate(Visit visit, TIntermAggregate* node) + bool visitAggregate(Visit visit, TIntermAggregate *node) override { - if (visit == PreVisit) { + if (visit == PreVisit) + { // Here we handle all the built-in functions instead of the ones we // currently identified as problematic. - switch (node->getOp()) { + switch (node->getOp()) + { case EOpLessThan: case EOpGreaterThan: case EOpLessThanEqual: @@ -59,14 +62,14 @@ class BuiltInFunctionEmulator::BuiltInFunctionEmulationMarker : public TIntermTr break; default: return true; - }; - const TIntermSequence& sequence = *(node->getSequence()); + } + const TIntermSequence &sequence = *(node->getSequence()); bool needToEmulate = false; // Right now we only handle built-in functions with two or three parameters. if (sequence.size() == 2) { - TIntermTyped* param1 = sequence[0]->getAsTyped(); - TIntermTyped* param2 = sequence[1]->getAsTyped(); + TIntermTyped *param1 = sequence[0]->getAsTyped(); + TIntermTyped *param2 = sequence[1]->getAsTyped(); if (!param1 || !param2) return true; needToEmulate = mEmulator.SetFunctionCalled( @@ -74,9 +77,9 @@ class BuiltInFunctionEmulator::BuiltInFunctionEmulationMarker : public TIntermTr } else if (sequence.size() == 3) { - TIntermTyped* param1 = sequence[0]->getAsTyped(); - TIntermTyped* param2 = sequence[1]->getAsTyped(); - TIntermTyped* param3 = sequence[2]->getAsTyped(); + TIntermTyped *param1 = sequence[0]->getAsTyped(); + TIntermTyped *param2 = sequence[1]->getAsTyped(); + TIntermTyped *param3 = sequence[2]->getAsTyped(); if (!param1 || !param2 || !param3) return true; needToEmulate = mEmulator.SetFunctionCalled( @@ -94,34 +97,28 @@ class BuiltInFunctionEmulator::BuiltInFunctionEmulationMarker : public TIntermTr } private: - BuiltInFunctionEmulator& mEmulator; + BuiltInFunctionEmulator &mEmulator; }; BuiltInFunctionEmulator::BuiltInFunctionEmulator() {} -void BuiltInFunctionEmulator::addEmulatedFunction( - TOperator op, const TType& param, - const char* emulatedFunctionDefinition) +void BuiltInFunctionEmulator::addEmulatedFunction(TOperator op, const TType *param, + const char *emulatedFunctionDefinition) { - mEmulatedFunctions[FunctionId(op, param)] = - std::string(emulatedFunctionDefinition); + mEmulatedFunctions[FunctionId(op, param)] = std::string(emulatedFunctionDefinition); } -void BuiltInFunctionEmulator::addEmulatedFunction( - TOperator op, const TType& param1, const TType& param2, - const char* emulatedFunctionDefinition) +void BuiltInFunctionEmulator::addEmulatedFunction(TOperator op, const TType *param1, const TType *param2, + const char *emulatedFunctionDefinition) { - mEmulatedFunctions[FunctionId(op, param1, param2)] = - std::string(emulatedFunctionDefinition); + mEmulatedFunctions[FunctionId(op, param1, param2)] = std::string(emulatedFunctionDefinition); } -void BuiltInFunctionEmulator::addEmulatedFunction( - TOperator op, const TType& param1, const TType& param2, const TType& param3, - const char* emulatedFunctionDefinition) +void BuiltInFunctionEmulator::addEmulatedFunction(TOperator op, const TType *param1, const TType *param2, + const TType *param3, const char *emulatedFunctionDefinition) { - mEmulatedFunctions[FunctionId(op, param1, param2, param3)] = - std::string(emulatedFunctionDefinition); + mEmulatedFunctions[FunctionId(op, param1, param2, param3)] = std::string(emulatedFunctionDefinition); } bool BuiltInFunctionEmulator::IsOutputEmpty() const @@ -129,48 +126,48 @@ bool BuiltInFunctionEmulator::IsOutputEmpty() const return (mFunctions.size() == 0); } -void BuiltInFunctionEmulator::OutputEmulatedFunctions( - TInfoSinkBase& out) const +void BuiltInFunctionEmulator::OutputEmulatedFunctions(TInfoSinkBase &out) const { - for (size_t i = 0; i < mFunctions.size(); ++i) { + for (size_t i = 0; i < mFunctions.size(); ++i) + { out << mEmulatedFunctions.find(mFunctions[i])->second << "\n\n"; } } -bool BuiltInFunctionEmulator::SetFunctionCalled( - TOperator op, const TType& param) +bool BuiltInFunctionEmulator::SetFunctionCalled(TOperator op, const TType ¶m) { - return SetFunctionCalled(FunctionId(op, param)); + return SetFunctionCalled(FunctionId(op, ¶m)); } -bool BuiltInFunctionEmulator::SetFunctionCalled( - TOperator op, const TType& param1, const TType& param2) +bool BuiltInFunctionEmulator::SetFunctionCalled(TOperator op, const TType ¶m1, const TType ¶m2) { - return SetFunctionCalled(FunctionId(op, param1, param2)); + return SetFunctionCalled(FunctionId(op, ¶m1, ¶m2)); } -bool BuiltInFunctionEmulator::SetFunctionCalled( - TOperator op, const TType& param1, const TType& param2, const TType& param3) +bool BuiltInFunctionEmulator::SetFunctionCalled(TOperator op, + const TType ¶m1, const TType ¶m2, const TType ¶m3) { - return SetFunctionCalled(FunctionId(op, param1, param2, param3)); + return SetFunctionCalled(FunctionId(op, ¶m1, ¶m2, ¶m3)); } -bool BuiltInFunctionEmulator::SetFunctionCalled( - const FunctionId& functionId) { +bool BuiltInFunctionEmulator::SetFunctionCalled(const FunctionId &functionId) +{ if (mEmulatedFunctions.find(functionId) != mEmulatedFunctions.end()) { - for (size_t i = 0; i < mFunctions.size(); ++i) { + for (size_t i = 0; i < mFunctions.size(); ++i) + { if (mFunctions[i] == functionId) return true; } - mFunctions.push_back(functionId); + // Copy the functionId if it needs to be stored, to make sure that the TType pointers inside + // remain valid and constant. + mFunctions.push_back(functionId.getCopy()); return true; } return false; } -void BuiltInFunctionEmulator::MarkBuiltInFunctionsForEmulation( - TIntermNode* root) +void BuiltInFunctionEmulator::MarkBuiltInFunctionsForEmulation(TIntermNode *root) { ASSERT(root); @@ -188,32 +185,30 @@ void BuiltInFunctionEmulator::Cleanup() //static TString BuiltInFunctionEmulator::GetEmulatedFunctionName( - const TString& name) + const TString &name) { ASSERT(name[name.length() - 1] == '('); return "webgl_" + name.substr(0, name.length() - 1) + "_emu("; } -BuiltInFunctionEmulator::FunctionId::FunctionId - (TOperator op, const TType& param) +BuiltInFunctionEmulator::FunctionId::FunctionId(TOperator op, const TType *param) : mOp(op), mParam1(param), - mParam2(EbtVoid), - mParam3(EbtVoid) + mParam2(new TType(EbtVoid)), + mParam3(new TType(EbtVoid)) { } -BuiltInFunctionEmulator::FunctionId::FunctionId - (TOperator op, const TType& param1, const TType& param2) +BuiltInFunctionEmulator::FunctionId::FunctionId(TOperator op, const TType *param1, const TType *param2) : mOp(op), mParam1(param1), mParam2(param2), - mParam3(EbtVoid) + mParam3(new TType(EbtVoid)) { } -BuiltInFunctionEmulator::FunctionId::FunctionId - (TOperator op, const TType& param1, const TType& param2, const TType& param3) +BuiltInFunctionEmulator::FunctionId::FunctionId(TOperator op, + const TType *param1, const TType *param2, const TType *param3) : mOp(op), mParam1(param1), mParam2(param2), @@ -221,25 +216,28 @@ BuiltInFunctionEmulator::FunctionId::FunctionId { } -bool BuiltInFunctionEmulator::FunctionId::operator== - (const BuiltInFunctionEmulator::FunctionId& other) const +bool BuiltInFunctionEmulator::FunctionId::operator==(const BuiltInFunctionEmulator::FunctionId &other) const { return (mOp == other.mOp && - mParam1 == other.mParam1 && - mParam2 == other.mParam2 && - mParam3 == other.mParam3); + *mParam1 == *other.mParam1 && + *mParam2 == *other.mParam2 && + *mParam3 == *other.mParam3); } -bool BuiltInFunctionEmulator::FunctionId::operator< - (const BuiltInFunctionEmulator::FunctionId& other) const +bool BuiltInFunctionEmulator::FunctionId::operator<(const BuiltInFunctionEmulator::FunctionId &other) const { if (mOp != other.mOp) return mOp < other.mOp; - if (mParam1 != other.mParam1) - return mParam1 < other.mParam1; - if (mParam2 != other.mParam2) - return mParam2 < other.mParam2; - if (mParam3 != other.mParam3) - return mParam3 < other.mParam3; + if (*mParam1 != *other.mParam1) + return *mParam1 < *other.mParam1; + if (*mParam2 != *other.mParam2) + return *mParam2 < *other.mParam2; + if (*mParam3 != *other.mParam3) + return *mParam3 < *other.mParam3; return false; // all fields are equal } + +BuiltInFunctionEmulator::FunctionId BuiltInFunctionEmulator::FunctionId::getCopy() const +{ + return FunctionId(mOp, new TType(*mParam1), new TType(*mParam2), new TType(*mParam3)); +} diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/BuiltInFunctionEmulator.h b/Source/ThirdParty/ANGLE/src/compiler/translator/BuiltInFunctionEmulator.h index df556985e106..6976edfd570a 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/BuiltInFunctionEmulator.h +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/BuiltInFunctionEmulator.h @@ -21,23 +21,25 @@ class BuiltInFunctionEmulator public: BuiltInFunctionEmulator(); - void MarkBuiltInFunctionsForEmulation(TIntermNode* root); + void MarkBuiltInFunctionsForEmulation(TIntermNode *root); void Cleanup(); // "name(" becomes "webgl_name_emu(". - static TString GetEmulatedFunctionName(const TString& name); + static TString GetEmulatedFunctionName(const TString &name); bool IsOutputEmpty() const; // Output function emulation definition. This should be before any other // shader source. - void OutputEmulatedFunctions(TInfoSinkBase& out) const; + void OutputEmulatedFunctions(TInfoSinkBase &out) const; // Add functions that need to be emulated. - void addEmulatedFunction(TOperator op, const TType& param, const char* emulatedFunctionDefinition); - void addEmulatedFunction(TOperator op, const TType& param1, const TType& param2, const char* emulatedFunctionDefinition); - void addEmulatedFunction(TOperator op, const TType& param1, const TType& param2, const TType& param3, const char* emulatedFunctionDefinition); + void addEmulatedFunction(TOperator op, const TType *param, const char *emulatedFunctionDefinition); + void addEmulatedFunction(TOperator op, const TType *param1, const TType *param2, + const char *emulatedFunctionDefinition); + void addEmulatedFunction(TOperator op, const TType *param1, const TType *param2, const TType *param3, + const char *emulatedFunctionDefinition); private: class BuiltInFunctionEmulationMarker; @@ -46,28 +48,32 @@ class BuiltInFunctionEmulator // emulated. If the function is not in mEmulatedFunctions, this becomes a // no-op. Returns true if the function call needs to be replaced with an // emulated one. - bool SetFunctionCalled(TOperator op, const TType& param); - bool SetFunctionCalled( - TOperator op, const TType& param1, const TType& param2); - bool SetFunctionCalled( - TOperator op, const TType& param1, const TType& param2, const TType& param3); + bool SetFunctionCalled(TOperator op, const TType ¶m); + bool SetFunctionCalled(TOperator op, const TType ¶m1, const TType ¶m2); + bool SetFunctionCalled(TOperator op, const TType ¶m1, const TType ¶m2, const TType ¶m3); class FunctionId { public: - FunctionId(TOperator op, const TType& param); - FunctionId(TOperator op, const TType& param1, const TType& param2); - FunctionId(TOperator op, const TType& param1, const TType& param2, const TType& param3); + FunctionId(TOperator op, const TType *param); + FunctionId(TOperator op, const TType *param1, const TType *param2); + FunctionId(TOperator op, const TType *param1, const TType *param2, const TType *param3); - bool operator==(const FunctionId& other) const; - bool operator<(const FunctionId& other) const; + bool operator==(const FunctionId &other) const; + bool operator<(const FunctionId &other) const; + + FunctionId getCopy() const; private: TOperator mOp; - TType mParam1; - TType mParam2; - TType mParam3; + + // The memory that these TType objects use is freed by PoolAllocator. The BuiltInFunctionEmulator's lifetime + // can extend until after the memory pool is freed, but that's not an issue since this class never destructs + // these objects. + const TType *mParam1; + const TType *mParam2; + const TType *mParam3; }; - bool SetFunctionCalled(const FunctionId& functionId); + bool SetFunctionCalled(const FunctionId &functionId); // Map from function id to emulated function definition std::map mEmulatedFunctions; diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/BuiltInFunctionEmulatorGLSL.cpp b/Source/ThirdParty/ANGLE/src/compiler/translator/BuiltInFunctionEmulatorGLSL.cpp index 9de99831ad6b..098560d1107e 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/BuiltInFunctionEmulatorGLSL.cpp +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/BuiltInFunctionEmulatorGLSL.cpp @@ -7,9 +7,11 @@ #include "angle_gl.h" #include "compiler/translator/BuiltInFunctionEmulator.h" #include "compiler/translator/BuiltInFunctionEmulatorGLSL.h" +#include "compiler/translator/Cache.h" #include "compiler/translator/SymbolTable.h" +#include "compiler/translator/VersionGLSL.h" -void InitBuiltInFunctionEmulatorForGLSL(BuiltInFunctionEmulator *emu, sh::GLenum shaderType) +void InitBuiltInFunctionEmulatorForGLSLWorkarounds(BuiltInFunctionEmulator *emu, sh::GLenum shaderType) { // we use macros here instead of function definitions to work around more GLSL // compiler bugs, in particular on NVIDIA hardware on Mac OSX. Macros are @@ -17,10 +19,10 @@ void InitBuiltInFunctionEmulatorForGLSL(BuiltInFunctionEmulator *emu, sh::GLenum // evaluated. This is unlikely to show up in real shaders, but is something to // consider. - TType float1(EbtFloat); - TType float2(EbtFloat, 2); - TType float3(EbtFloat, 3); - TType float4(EbtFloat, 4); + const TType *float1 = TCache::getType(EbtFloat); + const TType *float2 = TCache::getType(EbtFloat, 2); + const TType *float3 = TCache::getType(EbtFloat, 3); + const TType *float4 = TCache::getType(EbtFloat, 4); if (shaderType == GL_FRAGMENT_SHADER) { @@ -35,3 +37,153 @@ void InitBuiltInFunctionEmulatorForGLSL(BuiltInFunctionEmulator *emu, sh::GLenum emu->addEmulatedFunction(EOpNormalize, float1, "#define webgl_normalize_emu(x) ((x) == 0.0 ? 0.0 : ((x) > 0.0 ? 1.0 : -1.0))"); emu->addEmulatedFunction(EOpReflect, float1, float1, "#define webgl_reflect_emu(I, N) ((I) - 2.0 * (N) * (I) * (N))"); } + +// Emulate built-in functions missing from GLSL 1.30 and higher +void InitBuiltInFunctionEmulatorForGLSLMissingFunctions(BuiltInFunctionEmulator *emu, sh::GLenum shaderType, + int targetGLSLVersion) +{ + // Emulate packSnorm2x16, packHalf2x16, unpackSnorm2x16, and unpackHalf2x16 (GLSL 4.20) + // by using floatBitsToInt, floatBitsToUint, intBitsToFloat, and uintBitsToFloat (GLSL 3.30). + if (targetGLSLVersion >= GLSL_VERSION_330 && targetGLSLVersion < GLSL_VERSION_420) + { + const TType *float2 = TCache::getType(EbtFloat, 2); + const TType *uint1 = TCache::getType(EbtUInt); + + // clang-format off + emu->addEmulatedFunction(EOpPackSnorm2x16, float2, + "uint webgl_packSnorm2x16_emu(vec2 v)\n" + "{\n" + " #if defined(GL_ARB_shading_language_packing)\n" + " return packSnorm2x16(v);\n" + " #else\n" + " int x = int(round(clamp(v.x, -1.0, 1.0) * 32767.0));\n" + " int y = int(round(clamp(v.y, -1.0, 1.0) * 32767.0));\n" + " return uint((y << 16) | (x & 0xFFFF));\n" + " #endif\n" + "}\n"); + emu->addEmulatedFunction(EOpUnpackSnorm2x16, uint1, + "#if !defined(GL_ARB_shading_language_packing)\n" + " float webgl_fromSnorm(uint x)\n" + " {\n" + " int xi = (int(x) & 0x7FFF) - (int(x) & 0x8000);\n" + " return clamp(float(xi) / 32767.0, -1.0, 1.0);\n" + " }\n" + "#endif\n" + "\n" + "vec2 webgl_unpackSnorm2x16_emu(uint u)\n" + "{\n" + " #if defined(GL_ARB_shading_language_packing)\n" + " return unpackSnorm2x16(u);\n" + " #else\n" + " uint y = (u >> 16);\n" + " uint x = u;\n" + " return vec2(webgl_fromSnorm(x), webgl_fromSnorm(y));\n" + " #endif\n" + "}\n"); + // Functions uint webgl_f32tof16(float val) and float webgl_f16tof32(uint val) are + // based on the OpenGL redbook Appendix Session "Floating-Point Formats Used in OpenGL". + emu->addEmulatedFunction(EOpPackHalf2x16, float2, + "#if !defined(GL_ARB_shading_language_packing)\n" + " uint webgl_f32tof16(float val)\n" + " {\n" + " uint f32 = floatBitsToUint(val);\n" + " uint f16 = 0u;\n" + " uint sign = (f32 >> 16) & 0x8000u;\n" + " int exponent = int((f32 >> 23) & 0xFFu) - 127;\n" + " uint mantissa = f32 & 0x007FFFFFu;\n" + " if (exponent == 128)\n" + " {\n" + " // Infinity or NaN\n" + " // NaN bits that are masked out by 0x3FF get discarded.\n" + " // This can turn some NaNs to infinity, but this is allowed by the spec.\n" + " f16 = sign | (0x1Fu << 10);\n" + " f16 |= (mantissa & 0x3FFu);\n" + " }\n" + " else if (exponent > 15)\n" + " {\n" + " // Overflow - flush to Infinity\n" + " f16 = sign | (0x1Fu << 10);\n" + " }\n" + " else if (exponent > -15)\n" + " {\n" + " // Representable value\n" + " exponent += 15;\n" + " mantissa >>= 13;\n" + " f16 = sign | uint(exponent << 10) | mantissa;\n" + " }\n" + " else\n" + " {\n" + " f16 = sign;\n" + " }\n" + " return f16;\n" + " }\n" + "#endif\n" + "\n" + "uint webgl_packHalf2x16_emu(vec2 v)\n" + "{\n" + " #if defined(GL_ARB_shading_language_packing)\n" + " return packHalf2x16(v);\n" + " #else\n" + " uint x = webgl_f32tof16(v.x);\n" + " uint y = webgl_f32tof16(v.y);\n" + " return (y << 16) | x;\n" + " #endif\n" + "}\n"); + emu->addEmulatedFunction(EOpUnpackHalf2x16, uint1, + "#if !defined(GL_ARB_shading_language_packing)\n" + " float webgl_f16tof32(uint val)\n" + " {\n" + " uint sign = (val & 0x8000u) << 16;\n" + " int exponent = int((val & 0x7C00u) >> 10);\n" + " uint mantissa = val & 0x03FFu;\n" + " float f32 = 0.0;\n" + " if(exponent == 0)\n" + " {\n" + " if (mantissa != 0u)\n" + " {\n" + " const float scale = 1.0 / (1 << 24);\n" + " f32 = scale * mantissa;\n" + " }\n" + " }\n" + " else if (exponent == 31)\n" + " {\n" + " return uintBitsToFloat(sign | 0x7F800000u | mantissa);\n" + " }\n" + " else\n" + " {\n" + " exponent -= 15;\n" + " float scale;\n" + " if(exponent < 0)\n" + " {\n" + " scale = 1.0 / (1 << -exponent);\n" + " }\n" + " else\n" + " {\n" + " scale = 1 << exponent;\n" + " }\n" + " float decimal = 1.0 + float(mantissa) / float(1 << 10);\n" + " f32 = scale * decimal;\n" + " }\n" + "\n" + " if (sign != 0u)\n" + " {\n" + " f32 = -f32;\n" + " }\n" + "\n" + " return f32;\n" + " }\n" + "#endif\n" + "\n" + "vec2 webgl_unpackHalf2x16_emu(uint u)\n" + "{\n" + " #if defined(GL_ARB_shading_language_packing)\n" + " return unpackHalf2x16(u);\n" + " #else\n" + " uint y = (u >> 16);\n" + " uint x = u & 0xFFFFu;\n" + " return vec2(webgl_f16tof32(x), webgl_f16tof32(y));\n" + " #endif\n" + "}\n"); + // clang-format on + } +} diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/BuiltInFunctionEmulatorGLSL.h b/Source/ThirdParty/ANGLE/src/compiler/translator/BuiltInFunctionEmulatorGLSL.h index 5707a4b35a2f..56242598af5a 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/BuiltInFunctionEmulatorGLSL.h +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/BuiltInFunctionEmulatorGLSL.h @@ -14,6 +14,12 @@ class BuiltInFunctionEmulator; // // This is only a workaround for OpenGL driver bugs, and isn't needed in general. // -void InitBuiltInFunctionEmulatorForGLSL(BuiltInFunctionEmulator *emu, sh::GLenum shaderType); +void InitBuiltInFunctionEmulatorForGLSLWorkarounds(BuiltInFunctionEmulator *emu, sh::GLenum shaderType); + +// +// This function is emulating built-in functions missing from GLSL 1.30 and higher. +// +void InitBuiltInFunctionEmulatorForGLSLMissingFunctions(BuiltInFunctionEmulator *emu, sh::GLenum shaderType, + int targetGLSLVersion); #endif // COMPILER_TRANSLATOR_BUILTINFUNCTIONEMULATORGLSL_H_ diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/BuiltInFunctionEmulatorHLSL.cpp b/Source/ThirdParty/ANGLE/src/compiler/translator/BuiltInFunctionEmulatorHLSL.cpp index 7123a0d5c0d3..50e15cbc2828 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/BuiltInFunctionEmulatorHLSL.cpp +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/BuiltInFunctionEmulatorHLSL.cpp @@ -11,10 +11,10 @@ void InitBuiltInFunctionEmulatorForHLSL(BuiltInFunctionEmulator *emu) { - TType float1(EbtFloat); - TType float2(EbtFloat, 2); - TType float3(EbtFloat, 3); - TType float4(EbtFloat, 4); + TType *float1 = new TType(EbtFloat); + TType *float2 = new TType(EbtFloat, 2); + TType *float3 = new TType(EbtFloat, 3); + TType *float4 = new TType(EbtFloat, 4); emu->addEmulatedFunction(EOpMod, float1, float1, "float webgl_mod_emu(float x, float y)\n" @@ -250,7 +250,7 @@ void InitBuiltInFunctionEmulatorForHLSL(BuiltInFunctionEmulator *emu) " return (y << 16) | x;\n" "}\n"); - TType uint1(EbtUInt); + TType *uint1 = new TType(EbtUInt); emu->addEmulatedFunction(EOpUnpackSnorm2x16, uint1, "float webgl_fromSnorm(in uint x) {\n" @@ -327,9 +327,9 @@ void InitBuiltInFunctionEmulatorForHLSL(BuiltInFunctionEmulator *emu) " return mul(float4x1(r), float1x3(c));\n" "}\n"); - TType mat2(EbtFloat, 2, 2); - TType mat3(EbtFloat, 3, 3); - TType mat4(EbtFloat, 4, 4); + TType *mat2 = new TType(EbtFloat, 2, 2); + TType *mat3 = new TType(EbtFloat, 3, 3); + TType *mat4 = new TType(EbtFloat, 4, 4); // Remember here that the parameter matrix is actually the transpose // of the matrix that we're trying to invert, and the resulting matrix @@ -407,4 +407,35 @@ void InitBuiltInFunctionEmulatorForHLSL(BuiltInFunctionEmulator *emu) " cof02, cof12, cof22, cof32, cof03, cof13, cof23, cof33 };\n" " return cof / determinant(transpose(m));\n" "}\n"); + + TType *bool1 = new TType(EbtBool); + TType *bool2 = new TType(EbtBool, 2); + TType *bool3 = new TType(EbtBool, 3); + TType *bool4 = new TType(EbtBool, 4); + + // Emulate ESSL3 variant of mix that takes last argument as boolean vector. + // genType mix (genType x, genType y, genBType a): Selects which vector each returned component comes from. + // For a component of 'a' that is false, the corresponding component of 'x' is returned.For a component of 'a' that is true, + // the corresponding component of 'y' is returned. + emu->addEmulatedFunction(EOpMix, float1, float1, bool1, + "float webgl_mix_emu(float x, float y, bool a)\n" + "{\n" + " return a ? y : x;\n" + "}\n"); + emu->addEmulatedFunction(EOpMix, float2, float2, bool2, + "float2 webgl_mix_emu(float2 x, float2 y, bool2 a)\n" + "{\n" + " return a ? y : x;\n" + "}\n"); + emu->addEmulatedFunction(EOpMix, float3, float3, bool3, + "float3 webgl_mix_emu(float3 x, float3 y, bool3 a)\n" + "{\n" + " return a ? y : x;\n" + "}\n"); + emu->addEmulatedFunction(EOpMix, float4, float4, bool4, + "float4 webgl_mix_emu(float4 x, float4 y, bool4 a)\n" + "{\n" + " return a ? y : x;\n" + "}\n"); + } diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/Cache.cpp b/Source/ThirdParty/ANGLE/src/compiler/translator/Cache.cpp new file mode 100644 index 000000000000..57a43700cac0 --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/Cache.cpp @@ -0,0 +1,100 @@ +// +// Copyright (c) 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. +// + +// Cache.cpp: Implements a cache for various commonly created objects. + +#include + +#include "common/angleutils.h" +#include "common/debug.h" +#include "compiler/translator/Cache.h" + +namespace +{ + +class TScopedAllocator : angle::NonCopyable +{ + public: + TScopedAllocator(TPoolAllocator *allocator) + : mPreviousAllocator(GetGlobalPoolAllocator()) + { + SetGlobalPoolAllocator(allocator); + } + ~TScopedAllocator() + { + SetGlobalPoolAllocator(mPreviousAllocator); + } + + private: + TPoolAllocator *mPreviousAllocator; +}; + +} // namespace + +TCache::TypeKey::TypeKey(TBasicType basicType, + TPrecision precision, + TQualifier qualifier, + unsigned char primarySize, + unsigned char secondarySize) +{ + static_assert(sizeof(components) <= sizeof(value), + "TypeKey::value is too small"); + + const size_t MaxEnumValue = std::numeric_limits::max(); + UNUSED_ASSERTION_VARIABLE(MaxEnumValue); + + // TODO: change to static_assert() once we deprecate MSVC 2013 support + ASSERT(MaxEnumValue >= EbtLast && + MaxEnumValue >= EbpLast && + MaxEnumValue >= EvqLast && + "TypeKey::EnumComponentType is too small"); + + value = 0; + components.basicType = static_cast(basicType); + components.precision = static_cast(precision); + components.qualifier = static_cast(qualifier); + components.primarySize = primarySize; + components.secondarySize = secondarySize; +} + +TCache *TCache::sCache = nullptr; + +void TCache::initialize() +{ + if (sCache == nullptr) + { + sCache = new TCache(); + } +} + +void TCache::destroy() +{ + SafeDelete(sCache); +} + +const TType *TCache::getType(TBasicType basicType, + TPrecision precision, + TQualifier qualifier, + unsigned char primarySize, + unsigned char secondarySize) +{ + TypeKey key(basicType, precision, qualifier, + primarySize, secondarySize); + auto it = sCache->mTypes.find(key); + if (it != sCache->mTypes.end()) + { + return it->second; + } + + TScopedAllocator scopedAllocator(&sCache->mAllocator); + + TType *type = new TType(basicType, precision, qualifier, + primarySize, secondarySize); + type->realize(); + sCache->mTypes.insert(std::make_pair(key, type)); + + return type; +} diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/Cache.h b/Source/ThirdParty/ANGLE/src/compiler/translator/Cache.h new file mode 100644 index 000000000000..1d2abb77e1cf --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/Cache.h @@ -0,0 +1,90 @@ +// +// Copyright (c) 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. +// + +// Cache.h: Implements a cache for various commonly created objects. + +#ifndef COMPILER_TRANSLATOR_CACHE_H_ +#define COMPILER_TRANSLATOR_CACHE_H_ + +#include +#include +#include + +#include "compiler/translator/Types.h" +#include "compiler/translator/PoolAlloc.h" + +class TCache +{ + public: + + static void initialize(); + static void destroy(); + + static const TType *getType(TBasicType basicType, + TPrecision precision) + { + return getType(basicType, precision, EvqTemporary, + 1, 1); + } + static const TType *getType(TBasicType basicType, + unsigned char primarySize = 1, + unsigned char secondarySize = 1) + { + return getType(basicType, EbpUndefined, EvqGlobal, + primarySize, secondarySize); + } + static const TType *getType(TBasicType basicType, + TQualifier qualifier, + unsigned char primarySize = 1, + unsigned char secondarySize = 1) + { + return getType(basicType, EbpUndefined, qualifier, + primarySize, secondarySize); + } + static const TType *getType(TBasicType basicType, + TPrecision precision, + TQualifier qualifier, + unsigned char primarySize, + unsigned char secondarySize); + + private: + TCache() + { + } + + union TypeKey + { + TypeKey(TBasicType basicType, + TPrecision precision, + TQualifier qualifier, + unsigned char primarySize, + unsigned char secondarySize); + + typedef uint8_t EnumComponentType; + struct + { + EnumComponentType basicType; + EnumComponentType precision; + EnumComponentType qualifier; + unsigned char primarySize; + unsigned char secondarySize; + } components; + uint64_t value; + + bool operator < (const TypeKey &other) const + { + return value < other.value; + } + }; + typedef std::map TypeMap; + + TypeMap mTypes; + TPoolAllocator mAllocator; + + static TCache *sCache; +}; + +#endif // COMPILER_TRANSLATOR_CACHE_H_ diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/CallDAG.cpp b/Source/ThirdParty/ANGLE/src/compiler/translator/CallDAG.cpp index 95dbea11eafe..10f0eb937c41 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/CallDAG.cpp +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/CallDAG.cpp @@ -18,9 +18,9 @@ class CallDAG::CallDAGCreator : public TIntermTraverser public: CallDAGCreator(TInfoSinkBase *info) : TIntermTraverser(true, false, true), + mCreationInfo(info), mCurrentFunction(nullptr), - mCurrentIndex(0), - mCreationInfo(info) + mCurrentIndex(0) { } @@ -35,6 +35,7 @@ class CallDAG::CallDAGCreator : public TIntermTraverser InitResult result = assignIndicesInternal(&it.second); if (result != INITDAG_SUCCESS) { + *mCreationInfo << "\n"; return result; } } @@ -107,7 +108,8 @@ class CallDAG::CallDAGCreator : public TIntermTraverser if (visit == PreVisit) { // Function declaration, create an empty record. - mFunctions[node->getName()]; + auto& record = mFunctions[node->getName()]; + record.name = node->getName(); } break; case EOpFunction: @@ -169,7 +171,8 @@ class CallDAG::CallDAGCreator : public TIntermTraverser if (!function->node) { - *mCreationInfo << "Undefined function: " << function->name; + *mCreationInfo << "Undefined function '" << function->name + << ")' used in the following call chain:"; return INITDAG_UNDEFINED; } @@ -182,7 +185,7 @@ class CallDAG::CallDAGCreator : public TIntermTraverser { if (mCreationInfo) { - *mCreationInfo << "Recursive function call in the following call chain: " << function->name; + *mCreationInfo << "Recursive function call in the following call chain:" << function->name; } return INITDAG_RECURSION; } @@ -191,19 +194,15 @@ class CallDAG::CallDAGCreator : public TIntermTraverser for (auto &callee : function->callees) { InitResult result = assignIndicesInternal(callee); - if (result == INITDAG_RECURSION) + if (result != INITDAG_SUCCESS) { - // We know that there is a recursive function call chain in the AST, + // We know that there is an issue with the call chain in the AST, // print the link of the chain we were processing. if (mCreationInfo) { - *mCreationInfo << " <- " << function->name; + *mCreationInfo << " <- " << function->name << ")"; } - return INITDAG_RECURSION; - } - else if (result == INITDAG_UNDEFINED) - { - return INITDAG_UNDEFINED; + return result; } } diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/CodeGen.cpp b/Source/ThirdParty/ANGLE/src/compiler/translator/CodeGen.cpp index f1eb887f57f4..fe7c4f1a2bfb 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/CodeGen.cpp +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/CodeGen.cpp @@ -4,8 +4,16 @@ // found in the LICENSE file. // +#include "compiler/translator/Compiler.h" + +#ifdef ANGLE_ENABLE_ESSL #include "compiler/translator/TranslatorESSL.h" +#endif + +#ifdef ANGLE_ENABLE_GLSL #include "compiler/translator/TranslatorGLSL.h" +#endif + #ifdef ANGLE_ENABLE_HLSL #include "compiler/translator/TranslatorHLSL.h" #endif // ANGLE_ENABLE_HLSL @@ -20,24 +28,44 @@ TCompiler* ConstructCompiler( { switch (output) { case SH_ESSL_OUTPUT: +#ifdef ANGLE_ENABLE_ESSL return new TranslatorESSL(type, spec); +#else + // This compiler is not supported in this + // configuration. Return NULL per the ShConstructCompiler API. + return nullptr; +#endif // ANGLE_ENABLE_ESSL case SH_GLSL_130_OUTPUT: + case SH_GLSL_140_OUTPUT: + case SH_GLSL_150_CORE_OUTPUT: + case SH_GLSL_330_CORE_OUTPUT: + case SH_GLSL_400_CORE_OUTPUT: case SH_GLSL_410_CORE_OUTPUT: case SH_GLSL_420_CORE_OUTPUT: + case SH_GLSL_430_CORE_OUTPUT: + case SH_GLSL_440_CORE_OUTPUT: + case SH_GLSL_450_CORE_OUTPUT: case SH_GLSL_COMPATIBILITY_OUTPUT: +#ifdef ANGLE_ENABLE_GLSL return new TranslatorGLSL(type, spec, output); - case SH_HLSL9_OUTPUT: - case SH_HLSL11_OUTPUT: +#else + // This compiler is not supported in this + // configuration. Return NULL per the ShConstructCompiler API. + return nullptr; +#endif // ANGLE_ENABLE_GLSL + case SH_HLSL_3_0_OUTPUT: + case SH_HLSL_4_1_OUTPUT: + case SH_HLSL_4_0_FL9_3_OUTPUT: #ifdef ANGLE_ENABLE_HLSL return new TranslatorHLSL(type, spec, output); #else // This compiler is not supported in this // configuration. Return NULL per the ShConstructCompiler API. - return NULL; + return nullptr; #endif // ANGLE_ENABLE_HLSL default: // Unknown format. Return NULL per the ShConstructCompiler API. - return NULL; + return nullptr; } } diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/Common.h b/Source/ThirdParty/ANGLE/src/compiler/translator/Common.h index 575930224316..60223232afc1 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/Common.h +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/Common.h @@ -60,18 +60,21 @@ inline TString* NewPoolTString(const char* s) // // Pool allocator versions of vectors, lists, and maps // -template class TVector : public std::vector > { -public: - typedef typename std::vector >::size_type size_type; - TVector() : std::vector >() {} - TVector(const pool_allocator& a) : std::vector >(a) {} - TVector(size_type i): std::vector >(i) {} +template +class TVector : public std::vector> +{ + public: + typedef typename std::vector>::size_type size_type; + TVector() : std::vector>() {} + TVector(const pool_allocator &a) : std::vector>(a) {} + TVector(size_type i) : std::vector>(i) {} }; -template > -class TMap : public std::map > > { -public: - typedef pool_allocator > tAllocator; +template > +class TMap : public std::map>> +{ + public: + typedef pool_allocator> tAllocator; TMap() : std::map() {} // use correct two-stage name lookup supported in gcc 3.4 and above diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/Compiler.cpp b/Source/ThirdParty/ANGLE/src/compiler/translator/Compiler.cpp index 5c029ba86c15..66da0c2d6f6a 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/Compiler.cpp +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/Compiler.cpp @@ -4,8 +4,10 @@ // found in the LICENSE file. // +#include "compiler/translator/Cache.h" #include "compiler/translator/Compiler.h" #include "compiler/translator/CallDAG.h" +#include "compiler/translator/DeferGlobalInitializers.h" #include "compiler/translator/ForLoopUnroll.h" #include "compiler/translator/Initialize.h" #include "compiler/translator/InitializeParseContext.h" @@ -13,10 +15,13 @@ #include "compiler/translator/ParseContext.h" #include "compiler/translator/PruneEmptyDeclarations.h" #include "compiler/translator/RegenerateStructNames.h" +#include "compiler/translator/RemovePow.h" #include "compiler/translator/RenameFunction.h" +#include "compiler/translator/RewriteDoWhile.h" #include "compiler/translator/ScalarizeVecAndMatConstructorArgs.h" #include "compiler/translator/UnfoldShortCircuitAST.h" #include "compiler/translator/ValidateLimitations.h" +#include "compiler/translator/ValidateMaxParameters.h" #include "compiler/translator/ValidateOutputs.h" #include "compiler/translator/VariablePacker.h" #include "compiler/translator/depgraph/DependencyGraph.h" @@ -37,8 +42,15 @@ bool IsWebGLBasedSpec(ShShaderSpec spec) bool IsGLSL130OrNewer(ShShaderOutput output) { return (output == SH_GLSL_130_OUTPUT || + output == SH_GLSL_140_OUTPUT || + output == SH_GLSL_150_CORE_OUTPUT || + output == SH_GLSL_330_CORE_OUTPUT || + output == SH_GLSL_400_CORE_OUTPUT || output == SH_GLSL_410_CORE_OUTPUT || - output == SH_GLSL_420_CORE_OUTPUT); + output == SH_GLSL_420_CORE_OUTPUT || + output == SH_GLSL_430_CORE_OUTPUT || + output == SH_GLSL_440_CORE_OUTPUT || + output == SH_GLSL_450_CORE_OUTPUT); } size_t GetGlobalMaxTokenSize(ShShaderSpec spec) @@ -131,10 +143,12 @@ TCompiler::TCompiler(sh::GLenum type, ShShaderSpec spec, ShShaderOutput output) maxUniformVectors(0), maxExpressionComplexity(0), maxCallStackDepth(0), + maxFunctionParameters(0), fragmentPrecisionHigh(false), clampingStrategy(SH_CLAMP_WITH_CLAMP_INTRINSIC), builtInFunctionEmulator(), - mSourcePath(NULL) + mSourcePath(NULL), + mTemporaryIndex(0) { } @@ -142,6 +156,15 @@ TCompiler::~TCompiler() { } +bool TCompiler::shouldRunLoopAndIndexingValidation(int compileOptions) const +{ + // If compiling an ESSL 1.00 shader for WebGL, or if its been requested through the API, + // validate loop and indexing as well (to verify that the shader only uses minimal functionality + // of ESSL 1.00 as in Appendix A of the spec). + return (IsWebGLBasedSpec(shaderSpec) && shaderVersion == 100) || + (compileOptions & SH_VALIDATE_LOOP_INDEXING); +} + bool TCompiler::Init(const ShBuiltInResources& resources) { shaderVersion = 100; @@ -149,7 +172,8 @@ bool TCompiler::Init(const ShBuiltInResources& resources) resources.MaxVertexUniformVectors : resources.MaxFragmentUniformVectors; maxExpressionComplexity = resources.MaxExpressionComplexity; - maxCallStackDepth = resources.MaxCallStackDepth; + maxCallStackDepth = resources.MaxCallStackDepth; + maxFunctionParameters = resources.MaxFunctionParameters; SetGlobalPoolAllocator(&allocator); @@ -173,8 +197,9 @@ TIntermNode *TCompiler::compileTreeForTesting(const char* const shaderStrings[], return compileTreeImpl(shaderStrings, numStrings, compileOptions); } -TIntermNode *TCompiler::compileTreeImpl(const char* const shaderStrings[], - size_t numStrings, int compileOptions) +TIntermNode *TCompiler::compileTreeImpl(const char *const shaderStrings[], + size_t numStrings, + const int compileOptions) { clearResults(); @@ -184,10 +209,6 @@ TIntermNode *TCompiler::compileTreeImpl(const char* const shaderStrings[], // Reset the extension behavior for each compilation unit. ResetExtensionBehavior(extensionBehavior); - // If compiling for WebGL, validate loop and indexing as well. - if (IsWebGLBasedSpec(shaderSpec)) - compileOptions |= SH_VALIDATE_LOOP_INDEXING; - // First string is path of source file if flag is set. The actual source follows. size_t firstSource = 0; if (compileOptions & SH_SOURCE_PATH) @@ -196,13 +217,11 @@ TIntermNode *TCompiler::compileTreeImpl(const char* const shaderStrings[], ++firstSource; } - bool debugShaderPrecision = getResources().WEBGL_debug_shader_precision == 1; TIntermediate intermediate(infoSink); - TParseContext parseContext(symbolTable, extensionBehavior, intermediate, - shaderType, shaderSpec, compileOptions, true, - infoSink, debugShaderPrecision); + TParseContext parseContext(symbolTable, extensionBehavior, intermediate, shaderType, shaderSpec, + compileOptions, true, infoSink, getResources()); - parseContext.fragmentPrecisionHigh = fragmentPrecisionHigh; + parseContext.setFragmentPrecisionHighOnESSL1(fragmentPrecisionHigh); SetGlobalParseContext(&parseContext); // We preserve symbols at the built-in level from compile-to-compile. @@ -211,8 +230,8 @@ TIntermNode *TCompiler::compileTreeImpl(const char* const shaderStrings[], // Parse shader. bool success = - (PaParseStrings(numStrings - firstSource, &shaderStrings[firstSource], NULL, &parseContext) == 0) && - (parseContext.treeRoot != NULL); + (PaParseStrings(numStrings - firstSource, &shaderStrings[firstSource], nullptr, &parseContext) == 0) && + (parseContext.getTreeRoot() != nullptr); shaderVersion = parseContext.getShaderVersion(); if (success && MapSpecToShaderVersion(shaderSpec) < shaderVersion) @@ -222,7 +241,7 @@ TIntermNode *TCompiler::compileTreeImpl(const char* const shaderStrings[], success = false; } - TIntermNode *root = NULL; + TIntermNode *root = nullptr; if (success) { @@ -232,8 +251,11 @@ TIntermNode *TCompiler::compileTreeImpl(const char* const shaderStrings[], symbolTable.setGlobalInvariant(); } - root = parseContext.treeRoot; - success = intermediate.postProcess(root); + root = parseContext.getTreeRoot(); + root = intermediate.postProcess(root); + + // Highp might have been auto-enabled based on shader version + fragmentPrecisionHigh = parseContext.getFragmentPrecisionHigh(); // Disallow expressions deemed too complex. if (success && (compileOptions & SH_LIMIT_EXPRESSION_COMPLEXITY)) @@ -264,7 +286,7 @@ TIntermNode *TCompiler::compileTreeImpl(const char* const shaderStrings[], if (success && shaderVersion == 300 && shaderType == GL_FRAGMENT_SHADER) success = validateOutputs(root); - if (success && (compileOptions & SH_VALIDATE_LOOP_INDEXING)) + if (success && shouldRunLoopAndIndexingValidation(compileOptions)) success = validateLimitations(root); if (success && (compileOptions & SH_TIMING_RESTRICTIONS)) @@ -276,12 +298,14 @@ TIntermNode *TCompiler::compileTreeImpl(const char* const shaderStrings[], // Unroll for-loop markup needs to happen after validateLimitations pass. if (success && (compileOptions & SH_UNROLL_FOR_LOOP_WITH_INTEGER_INDEX)) { - ForLoopUnrollMarker marker(ForLoopUnrollMarker::kIntegerIndex); + ForLoopUnrollMarker marker(ForLoopUnrollMarker::kIntegerIndex, + shouldRunLoopAndIndexingValidation(compileOptions)); root->traverse(&marker); } if (success && (compileOptions & SH_UNROLL_FOR_LOOP_WITH_SAMPLER_ARRAY_INDEX)) { - ForLoopUnrollMarker marker(ForLoopUnrollMarker::kSamplerArrayIndex); + ForLoopUnrollMarker marker(ForLoopUnrollMarker::kSamplerArrayIndex, + shouldRunLoopAndIndexingValidation(compileOptions)); root->traverse(&marker); if (marker.samplerArrayIndexIsFloatLoopIndex()) { @@ -302,9 +326,16 @@ TIntermNode *TCompiler::compileTreeImpl(const char* const shaderStrings[], if (success && (compileOptions & SH_CLAMP_INDIRECT_ARRAY_BOUNDS)) arrayBoundsClamper.MarkIndirectArrayBoundsForClamping(root); - if (success && shaderType == GL_VERTEX_SHADER && (compileOptions & SH_INIT_GL_POSITION)) + // gl_Position is always written in compatibility output mode + if (success && shaderType == GL_VERTEX_SHADER && + ((compileOptions & SH_INIT_GL_POSITION) || + (outputType == SH_GLSL_COMPATIBILITY_OUTPUT))) initializeGLPosition(root); + // This pass might emit short circuits so keep it before the short circuit unfolding + if (success && (compileOptions & SH_REWRITE_DO_WHILE_LOOPS)) + RewriteDoWhile(root, getTemporaryIndex()); + if (success && (compileOptions & SH_UNFOLD_SHORT_CIRCUIT)) { UnfoldShortCircuitAST unfoldShortCircuit; @@ -312,7 +343,12 @@ TIntermNode *TCompiler::compileTreeImpl(const char* const shaderStrings[], unfoldShortCircuit.updateTree(); } - if (success && (compileOptions & SH_VARIABLES)) + if (success && (compileOptions & SH_REMOVE_POW_WITH_CONSTANT_EXPONENT)) + { + RemovePow(root); + } + + if (success && shouldCollectVariables(compileOptions)) { collectVariables(root); if (compileOptions & SH_ENFORCE_PACKING_RESTRICTIONS) @@ -341,6 +377,11 @@ TIntermNode *TCompiler::compileTreeImpl(const char* const shaderStrings[], RegenerateStructNames gen(symbolTable, shaderVersion); root->traverse(&gen); } + + if (success) + { + DeferGlobalInitializers(root); + } } SetGlobalParseContext(NULL); @@ -396,11 +437,6 @@ bool TCompiler::InitBuiltInSymbolTable(const ShBuiltInResources &resources) floatingPoint.secondarySize = 1; floatingPoint.array = false; - TPublicType sampler; - sampler.primarySize = 1; - sampler.secondarySize = 1; - sampler.array = false; - switch(shaderType) { case GL_FRAGMENT_SHADER: @@ -413,14 +449,15 @@ bool TCompiler::InitBuiltInSymbolTable(const ShBuiltInResources &resources) default: assert(false && "Language not supported"); } - // We set defaults for all the sampler types, even those that are + // Set defaults for sampler types that have default precision, even those that are // only available if an extension exists. - for (int samplerType = EbtGuardSamplerBegin + 1; - samplerType < EbtGuardSamplerEnd; ++samplerType) - { - sampler.type = static_cast(samplerType); - symbolTable.setDefaultPrecision(sampler, EbpLow); - } + // New sampler types in ESSL3 don't have default precision. ESSL1 types do. + initSamplerDefaultPrecision(EbtSampler2D); + initSamplerDefaultPrecision(EbtSamplerCube); + // SamplerExternalOES is specified in the extension to have default precision. + initSamplerDefaultPrecision(EbtSamplerExternalOES); + // It isn't specified whether Sampler2DRect has default precision. + initSamplerDefaultPrecision(EbtSampler2DRect); InsertBuiltInFunctions(shaderType, shaderSpec, resources, symbolTable); @@ -429,6 +466,17 @@ bool TCompiler::InitBuiltInSymbolTable(const ShBuiltInResources &resources) return true; } +void TCompiler::initSamplerDefaultPrecision(TBasicType samplerType) +{ + ASSERT(samplerType > EbtGuardSamplerBegin && samplerType < EbtGuardSamplerEnd); + TPublicType sampler; + sampler.primarySize = 1; + sampler.secondarySize = 1; + sampler.array = false; + sampler.type = samplerType; + symbolTable.setDefaultPrecision(sampler, EbpLow); +} + void TCompiler::setResourceString() { std::ostringstream strstream; @@ -447,6 +495,8 @@ void TCompiler::setResourceString() << ":FragmentPrecisionHigh:" << compileResources.FragmentPrecisionHigh << ":MaxExpressionComplexity:" << compileResources.MaxExpressionComplexity << ":MaxCallStackDepth:" << compileResources.MaxCallStackDepth + << ":MaxFunctionParameters:" << compileResources.MaxFunctionParameters + << ":EXT_blend_func_extended:" << compileResources.EXT_blend_func_extended << ":EXT_frag_depth:" << compileResources.EXT_frag_depth << ":EXT_shader_texture_lod:" << compileResources.EXT_shader_texture_lod << ":EXT_shader_framebuffer_fetch:" << compileResources.EXT_shader_framebuffer_fetch @@ -456,6 +506,7 @@ void TCompiler::setResourceString() << ":MaxFragmentInputVectors:" << compileResources.MaxFragmentInputVectors << ":MinProgramTexelOffset:" << compileResources.MinProgramTexelOffset << ":MaxProgramTexelOffset:" << compileResources.MaxProgramTexelOffset + << ":MaxDualSourceDrawBuffers:" << compileResources.MaxDualSourceDrawBuffers << ":NV_draw_buffers:" << compileResources.NV_draw_buffers << ":WEBGL_debug_shader_precision:" << compileResources.WEBGL_debug_shader_precision; @@ -481,6 +532,7 @@ void TCompiler::clearResults() nameMap.clear(); mSourcePath = NULL; + mTemporaryIndex = 0; } bool TCompiler::initCallDag(TIntermNode *root) @@ -528,15 +580,15 @@ bool TCompiler::checkCallDepth() infoSink.info << "Call stack too deep (larger than " << maxCallStackDepth << ") with the following call chain: " << record.name; - signed long long currentFunction = i; + int currentFunction = static_cast(i); int currentDepth = depth; while (currentFunction != -1) { - infoSink.info << " -> " << mCallDag.getRecordFromIndex(static_cast(currentFunction)).name; + infoSink.info << " -> " << mCallDag.getRecordFromIndex(currentFunction).name; int nextFunction = -1; - for (auto& calleeIndex : mCallDag.getRecordFromIndex(static_cast(currentFunction)).callees) + for (auto& calleeIndex : mCallDag.getRecordFromIndex(currentFunction).callees) { if (depths[calleeIndex] == currentDepth - 1) { @@ -558,7 +610,7 @@ bool TCompiler::checkCallDepth() bool TCompiler::tagUsedFunctions() { // Search from main, starting from the end of the DAG as it usually is the root. - for (size_t i = mCallDag.size(); i--;) + for (size_t i = mCallDag.size(); i-- > 0;) { if (mCallDag.getRecordFromIndex(i).name == "main(") { @@ -568,7 +620,7 @@ bool TCompiler::tagUsedFunctions() } infoSink.info.prefix(EPrefixError); - infoSink.info << "Missing main()"; + infoSink.info << "Missing main()\n"; return false; } @@ -635,16 +687,20 @@ bool TCompiler::pruneUnusedFunctions(TIntermNode *root) UnusedPredicate isUnused(&mCallDag, &functionMetadata); TIntermSequence *sequence = rootNode->getSequence(); - sequence->erase(std::remove_if(sequence->begin(), sequence->end(), isUnused), sequence->end()); + + if (!sequence->empty()) + { + sequence->erase(std::remove_if(sequence->begin(), sequence->end(), isUnused), sequence->end()); + } return true; } bool TCompiler::validateOutputs(TIntermNode* root) { - ValidateOutputs validateOutputs(infoSink.info, compileResources.MaxDrawBuffers); + ValidateOutputs validateOutputs(getExtensionBehavior(), compileResources.MaxDrawBuffers); root->traverse(&validateOutputs); - return (validateOutputs.numErrors() == 0); + return (validateOutputs.validateAndCountErrors(infoSink.info) == 0); } void TCompiler::rewriteCSSShader(TIntermNode* root) @@ -655,7 +711,7 @@ void TCompiler::rewriteCSSShader(TIntermNode* root) bool TCompiler::validateLimitations(TIntermNode* root) { - ValidateLimitations validate(shaderType, infoSink.info); + ValidateLimitations validate(shaderType, &infoSink.info); root->traverse(&validate); return validate.numErrors() == 0; } @@ -701,15 +757,10 @@ bool TCompiler::limitExpressionComplexity(TIntermNode* root) return false; } - TDependencyGraph graph(root); - - for (TFunctionCallVector::const_iterator iter = graph.beginUserDefinedFunctionCalls(); - iter != graph.endUserDefinedFunctionCalls(); - ++iter) + if (!ValidateMaxParameters::validate(root, maxFunctionParameters)) { - TGraphFunctionCall* samplerSymbol = *iter; - TDependencyGraphTraverser graphTraverser; - samplerSymbol->traverse(&graphTraverser); + infoSink.info << "Function has too many parameters."; + return false; } return true; diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/Compiler.h b/Source/ThirdParty/ANGLE/src/compiler/translator/Compiler.h index e2cb58e0e068..99c155c33dfd 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/Compiler.h +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/Compiler.h @@ -67,8 +67,8 @@ class TCompiler : public TShHandleBase { public: TCompiler(sh::GLenum type, ShShaderSpec spec, ShShaderOutput output); - virtual ~TCompiler(); - virtual TCompiler* getAsCompiler() { return this; } + ~TCompiler() override; + TCompiler *getAsCompiler() override { return this; } bool Init(const ShBuiltInResources& resources); @@ -85,8 +85,11 @@ class TCompiler : public TShHandleBase int getShaderVersion() const { return shaderVersion; } TInfoSink& getInfoSink() { return infoSink; } + // Clears the results from the previous compilation. + void clearResults(); + const std::vector &getAttributes() const { return attributes; } - const std::vector &getOutputVariables() const { return outputVariables; } + const std::vector &getOutputVariables() const { return outputVariables; } const std::vector &getUniforms() const { return uniforms; } const std::vector &getVaryings() const { return varyings; } const std::vector &getInterfaceBlocks() const { return interfaceBlocks; } @@ -98,6 +101,8 @@ class TCompiler : public TShHandleBase ShShaderOutput getOutputType() const { return outputType; } const std::string &getBuiltInResourcesString() const { return builtInResourcesString; } + bool shouldRunLoopAndIndexingValidation(int compileOptions) const; + // Get the resources set by InitBuiltInSymbolTable const ShBuiltInResources& getResources() const; @@ -107,8 +112,6 @@ class TCompiler : public TShHandleBase bool InitBuiltInSymbolTable(const ShBuiltInResources& resources); // Compute the string representation of the built-in resources void setResourceString(); - // Clears the results from the previous compilation. - void clearResults(); // Return false if the call depth is exceeded. bool checkCallDepth(); // Returns true if a program has no conflicting or missing fragment outputs @@ -151,18 +154,24 @@ class TCompiler : public TShHandleBase const char *getSourcePath() const; const TPragma& getPragma() const { return mPragma; } void writePragma(); + unsigned int *getTemporaryIndex() { return &mTemporaryIndex; } const ArrayBoundsClamper& getArrayBoundsClamper() const; ShArrayIndexClampingStrategy getArrayIndexClampingStrategy() const; const BuiltInFunctionEmulator& getBuiltInFunctionEmulator() const; std::vector attributes; - std::vector outputVariables; + std::vector outputVariables; std::vector uniforms; std::vector expandedUniforms; std::vector varyings; std::vector interfaceBlocks; + virtual bool shouldCollectVariables(int compileOptions) + { + return (compileOptions & SH_VARIABLES) != 0; + } + private: // Creates the function call DAG for further analysis, returning false if there is a recursion bool initCallDag(TIntermNode *root); @@ -170,12 +179,15 @@ class TCompiler : public TShHandleBase bool tagUsedFunctions(); void internalTagUsedFunction(size_t index); + void initSamplerDefaultPrecision(TBasicType samplerType); + // Removes unused function declarations and prototypes from the AST class UnusedPredicate; bool pruneUnusedFunctions(TIntermNode *root); - TIntermNode *compileTreeImpl(const char* const shaderStrings[], - size_t numStrings, int compileOptions); + TIntermNode *compileTreeImpl(const char *const shaderStrings[], + size_t numStrings, + const int compileOptions); sh::GLenum shaderType; ShShaderSpec shaderSpec; @@ -196,6 +208,7 @@ class TCompiler : public TShHandleBase int maxUniformVectors; int maxExpressionComplexity; int maxCallStackDepth; + int maxFunctionParameters; ShBuiltInResources compileResources; std::string builtInResourcesString; @@ -221,6 +234,8 @@ class TCompiler : public TShHandleBase NameMap nameMap; TPragma mPragma; + + unsigned int mTemporaryIndex; }; // diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/DeferGlobalInitializers.cpp b/Source/ThirdParty/ANGLE/src/compiler/translator/DeferGlobalInitializers.cpp new file mode 100644 index 000000000000..12c7a9f73a39 --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/DeferGlobalInitializers.cpp @@ -0,0 +1,166 @@ +// +// Copyright (c) 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. +// +// DeferGlobalInitializers is an AST traverser that moves global initializers into a function, and +// adds a function call to that function in the beginning of main(). +// This enables initialization of globals with uniforms or non-constant globals, as allowed by +// the WebGL spec. Some initializers referencing non-constants may need to be unfolded into if +// statements in HLSL - this kind of steps should be done after DeferGlobalInitializers is run. +// + +#include "compiler/translator/DeferGlobalInitializers.h" + +#include "compiler/translator/IntermNode.h" +#include "compiler/translator/SymbolTable.h" + +namespace +{ + +void SetInternalFunctionName(TIntermAggregate *functionNode, const char *name) +{ + TString nameStr(name); + nameStr = TFunction::mangleName(nameStr); + TName nameObj(nameStr); + nameObj.setInternal(true); + functionNode->setNameObj(nameObj); +} + +TIntermAggregate *CreateFunctionPrototypeNode(const char *name) +{ + TIntermAggregate *functionNode = new TIntermAggregate(EOpPrototype); + + SetInternalFunctionName(functionNode, name); + TType returnType(EbtVoid); + functionNode->setType(returnType); + return functionNode; +} + +TIntermAggregate *CreateFunctionDefinitionNode(const char *name, TIntermAggregate *functionBody) +{ + TIntermAggregate *functionNode = new TIntermAggregate(EOpFunction); + TIntermAggregate *paramsNode = new TIntermAggregate(EOpParameters); + functionNode->getSequence()->push_back(paramsNode); + functionNode->getSequence()->push_back(functionBody); + + SetInternalFunctionName(functionNode, name); + TType returnType(EbtVoid); + functionNode->setType(returnType); + return functionNode; +} + +TIntermAggregate *CreateFunctionCallNode(const char *name) +{ + TIntermAggregate *functionNode = new TIntermAggregate(EOpFunctionCall); + + SetInternalFunctionName(functionNode, name); + TType returnType(EbtVoid); + functionNode->setType(returnType); + return functionNode; +} + +class DeferGlobalInitializersTraverser : public TIntermTraverser +{ + public: + DeferGlobalInitializersTraverser(); + + bool visitBinary(Visit visit, TIntermBinary *node) override; + + void insertInitFunction(TIntermNode *root); + + private: + TIntermSequence mDeferredInitializers; +}; + +DeferGlobalInitializersTraverser::DeferGlobalInitializersTraverser() + : TIntermTraverser(true, false, false) +{ +} + +bool DeferGlobalInitializersTraverser::visitBinary(Visit visit, TIntermBinary *node) +{ + if (node->getOp() == EOpInitialize) + { + TIntermSymbol *symbolNode = node->getLeft()->getAsSymbolNode(); + ASSERT(symbolNode); + TIntermTyped *expression = node->getRight(); + + if (symbolNode->getQualifier() == EvqGlobal && + (expression->getQualifier() != EvqConst || expression->getAsConstantUnion() == nullptr)) + { + // For variables which are not constant, defer their real initialization until + // after we initialize uniforms. + // Deferral is done also in any cases where the variable has not been constant folded, + // since otherwise there's a chance that HLSL output will generate extra statements + // from the initializer expression. + TIntermBinary *deferredInit = new TIntermBinary(EOpAssign); + deferredInit->setLeft(node->getLeft()->deepCopy()); + deferredInit->setRight(node->getRight()); + deferredInit->setType(node->getType()); + mDeferredInitializers.push_back(deferredInit); + + // Remove the initializer from the global scope and just declare the global instead. + mReplacements.push_back(NodeUpdateEntry(getParentNode(), node, node->getLeft(), false)); + } + } + return false; +} + +void DeferGlobalInitializersTraverser::insertInitFunction(TIntermNode *root) +{ + if (mDeferredInitializers.empty()) + { + return; + } + TIntermAggregate *rootAgg = root->getAsAggregate(); + ASSERT(rootAgg != nullptr && rootAgg->getOp() == EOpSequence); + + const char *functionName = "initializeDeferredGlobals"; + + // Add function prototype to the beginning of the shader + TIntermAggregate *functionPrototypeNode = CreateFunctionPrototypeNode(functionName); + rootAgg->getSequence()->insert(rootAgg->getSequence()->begin(), functionPrototypeNode); + + // Add function definition to the end of the shader + TIntermAggregate *functionBodyNode = new TIntermAggregate(EOpSequence); + TIntermSequence *functionBody = functionBodyNode->getSequence(); + for (const auto &deferredInit : mDeferredInitializers) + { + functionBody->push_back(deferredInit); + } + TIntermAggregate *functionDefinition = + CreateFunctionDefinitionNode(functionName, functionBodyNode); + rootAgg->getSequence()->push_back(functionDefinition); + + // Insert call into main function + for (TIntermNode *node : *rootAgg->getSequence()) + { + TIntermAggregate *nodeAgg = node->getAsAggregate(); + if (nodeAgg != nullptr && nodeAgg->getOp() == EOpFunction && + TFunction::unmangleName(nodeAgg->getName()) == "main") + { + TIntermAggregate *functionCallNode = CreateFunctionCallNode(functionName); + + TIntermNode *mainBody = nodeAgg->getSequence()->back(); + TIntermAggregate *mainBodyAgg = mainBody->getAsAggregate(); + ASSERT(mainBodyAgg != nullptr && mainBodyAgg->getOp() == EOpSequence); + mainBodyAgg->getSequence()->insert(mainBodyAgg->getSequence()->begin(), + functionCallNode); + } + } +} + +} // namespace + +void DeferGlobalInitializers(TIntermNode *root) +{ + DeferGlobalInitializersTraverser traverser; + root->traverse(&traverser); + + // Replace the initializers of the global variables. + traverser.updateTree(); + + // Add the function with initialization and the call to that. + traverser.insertInitFunction(root); +} diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/DeferGlobalInitializers.h b/Source/ThirdParty/ANGLE/src/compiler/translator/DeferGlobalInitializers.h new file mode 100644 index 000000000000..14f25539c3b5 --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/DeferGlobalInitializers.h @@ -0,0 +1,20 @@ +// +// Copyright (c) 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. +// +// DeferGlobalInitializers is an AST traverser that moves global initializers into a function, and +// adds a function call to that function in the beginning of main(). +// This enables initialization of globals with uniforms or non-constant globals, as allowed by +// the WebGL spec. Some initializers referencing non-constants may need to be unfolded into if +// statements in HLSL - this kind of steps should be done after DeferGlobalInitializers is run. +// + +#ifndef COMPILER_TRANSLATOR_DEFERGLOBALINITIALIZERS_H_ +#define COMPILER_TRANSLATOR_DEFERGLOBALINITIALIZERS_H_ + +class TIntermNode; + +void DeferGlobalInitializers(TIntermNode *root); + +#endif // COMPILER_TRANSLATOR_DEFERGLOBALINITIALIZERS_H_ diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/Diagnostics.h b/Source/ThirdParty/ANGLE/src/compiler/translator/Diagnostics.h index df65968b99cd..bc26e4584fa1 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/Diagnostics.h +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/Diagnostics.h @@ -16,7 +16,7 @@ class TDiagnostics : public pp::Diagnostics, angle::NonCopyable { public: TDiagnostics(TInfoSink& infoSink); - virtual ~TDiagnostics(); + ~TDiagnostics() override; TInfoSink& infoSink() { return mInfoSink; } @@ -30,9 +30,7 @@ class TDiagnostics : public pp::Diagnostics, angle::NonCopyable const std::string& extra); protected: - virtual void print(ID id, - const pp::SourceLocation& loc, - const std::string& text); + void print(ID id, const pp::SourceLocation &loc, const std::string &text) override; private: TInfoSink& mInfoSink; diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/DirectiveHandler.cpp b/Source/ThirdParty/ANGLE/src/compiler/translator/DirectiveHandler.cpp index 5bdecd55e23f..ff8a69efa52f 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/DirectiveHandler.cpp +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/DirectiveHandler.cpp @@ -8,6 +8,7 @@ #include +#include "angle_gl.h" #include "common/debug.h" #include "compiler/translator/Diagnostics.h" @@ -25,13 +26,15 @@ static TBehavior getBehavior(const std::string& str) return EBhUndefined; } -TDirectiveHandler::TDirectiveHandler(TExtensionBehavior& extBehavior, - TDiagnostics& diagnostics, - int& shaderVersion, +TDirectiveHandler::TDirectiveHandler(TExtensionBehavior &extBehavior, + TDiagnostics &diagnostics, + int &shaderVersion, + sh::GLenum shaderType, bool debugShaderPrecisionSupported) : mExtensionBehavior(extBehavior), mDiagnostics(diagnostics), mShaderVersion(shaderVersion), + mShaderType(shaderType), mDebugShaderPrecisionSupported(debugShaderPrecisionSupported) { } @@ -57,7 +60,16 @@ void TDirectiveHandler::handlePragma(const pp::SourceLocation& loc, const char kAll[] = "all"; if (name == kInvariant && value == kAll) + { + if (mShaderVersion == 300 && mShaderType == GL_FRAGMENT_SHADER) + { + // ESSL 3.00.4 section 4.6.1 + mDiagnostics.writeInfo( + pp::Diagnostics::PP_ERROR, loc, + "#pragma STDGL invariant(all) can not be used in fragment shader", name, value); + } mPragma.stdgl.invariantAll = true; + } // The STDGL pragma is used to reserve pragmas for use by future // revisions of GLSL. Do not generate an error on unexpected // name and value. @@ -98,8 +110,9 @@ void TDirectiveHandler::handlePragma(const pp::SourceLocation& loc, if (invalidValue) { - mDiagnostics.report(pp::Diagnostics::PP_INVALID_PRAGMA_VALUE, loc, value); - return; + mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, loc, + "invalid pragma value", value, + "'on' or 'off' expected"); } } } diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/DirectiveHandler.h b/Source/ThirdParty/ANGLE/src/compiler/translator/DirectiveHandler.h index 2a81ee570748..00eb49114e5e 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/DirectiveHandler.h +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/DirectiveHandler.h @@ -11,41 +11,42 @@ #include "compiler/translator/ExtensionBehavior.h" #include "compiler/translator/Pragma.h" #include "compiler/preprocessor/DirectiveHandlerBase.h" +#include "GLSLANG/ShaderLang.h" class TDiagnostics; class TDirectiveHandler : public pp::DirectiveHandler, angle::NonCopyable { public: - TDirectiveHandler(TExtensionBehavior& extBehavior, - TDiagnostics& diagnostics, - int& shaderVersion, + TDirectiveHandler(TExtensionBehavior &extBehavior, + TDiagnostics &diagnostics, + int &shaderVersion, + sh::GLenum shaderType, bool debugShaderPrecisionSupported); - virtual ~TDirectiveHandler(); + ~TDirectiveHandler() override; const TPragma& pragma() const { return mPragma; } const TExtensionBehavior& extensionBehavior() const { return mExtensionBehavior; } - virtual void handleError(const pp::SourceLocation& loc, - const std::string& msg); + void handleError(const pp::SourceLocation &loc, const std::string &msg) override; - virtual void handlePragma(const pp::SourceLocation& loc, - const std::string& name, - const std::string& value, - bool stdgl); + void handlePragma(const pp::SourceLocation &loc, + const std::string &name, + const std::string &value, + bool stdgl) override; - virtual void handleExtension(const pp::SourceLocation& loc, - const std::string& name, - const std::string& behavior); + void handleExtension(const pp::SourceLocation &loc, + const std::string &name, + const std::string &behavior) override; - virtual void handleVersion(const pp::SourceLocation& loc, - int version); + void handleVersion(const pp::SourceLocation &loc, int version) override; private: TPragma mPragma; TExtensionBehavior& mExtensionBehavior; TDiagnostics& mDiagnostics; int& mShaderVersion; + sh::GLenum mShaderType; bool mDebugShaderPrecisionSupported; }; diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/EmulatePrecision.cpp b/Source/ThirdParty/ANGLE/src/compiler/translator/EmulatePrecision.cpp index 184b84ee4d41..4a7fa5415583 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/EmulatePrecision.cpp +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/EmulatePrecision.cpp @@ -179,11 +179,50 @@ const char *getFloatTypeStr(const TType& type) case 1: return "float"; case 2: - return type.getSecondarySize() > 1 ? "mat2" : "vec2"; + switch(type.getSecondarySize()) + { + case 1: + return "vec2"; + case 2: + return "mat2"; + case 3: + return "mat2x3"; + case 4: + return "mat2x4"; + default: + UNREACHABLE(); + return NULL; + } case 3: - return type.getSecondarySize() > 1 ? "mat3" : "vec3"; + switch(type.getSecondarySize()) + { + case 1: + return "vec3"; + case 2: + return "mat3x2"; + case 3: + return "mat3"; + case 4: + return "mat3x4"; + default: + UNREACHABLE(); + return NULL; + } case 4: - return type.getSecondarySize() > 1 ? "mat4" : "vec4"; + switch(type.getSecondarySize()) + { + case 1: + return "vec4"; + case 2: + return "mat4x2"; + case 3: + return "mat4x3"; + case 4: + return "mat4"; + default: + UNREACHABLE(); + return NULL; + } default: UNREACHABLE(); return NULL; @@ -199,8 +238,10 @@ bool canRoundFloat(const TType &type) TIntermAggregate *createInternalFunctionCallNode(TString name, TIntermNode *child) { TIntermAggregate *callNode = new TIntermAggregate(); - callNode->setOp(EOpInternalFunctionCall); - callNode->setName(name); + callNode->setOp(EOpFunctionCall); + TName nameObj(TFunction::mangleName(name)); + nameObj.setInternal(true); + callNode->setNameObj(nameObj); callNode->getSequence()->push_back(child); return callNode; } @@ -252,17 +293,14 @@ bool parentUsesResult(TIntermNode* parent, TIntermNode* node) } // namespace anonymous -EmulatePrecision::EmulatePrecision() - : TIntermTraverser(true, true, true), - mDeclaringVariables(false), - mInLValue(false), - mInFunctionCallOutParameter(false) +EmulatePrecision::EmulatePrecision(const TSymbolTable &symbolTable, int shaderVersion) + : TLValueTrackingTraverser(true, true, true, symbolTable, shaderVersion), + mDeclaringVariables(false) {} void EmulatePrecision::visitSymbol(TIntermSymbol *node) { - if (canRoundFloat(node->getType()) && - !mDeclaringVariables && !mInLValue && !mInFunctionCallOutParameter) + if (canRoundFloat(node->getType()) && !mDeclaringVariables && !isLValueRequiredHere()) { TIntermNode *parent = getParentNode(); TIntermNode *replacement = createRoundingFunctionCallNode(node); @@ -275,14 +313,6 @@ bool EmulatePrecision::visitBinary(Visit visit, TIntermBinary *node) { bool visitChildren = true; - if (node->isAssignment()) - { - if (visit == PreVisit) - mInLValue = true; - else if (visit == InVisit) - mInLValue = false; - } - TOperator op = node->getOp(); // RHS of initialize is not being declared. @@ -376,22 +406,9 @@ bool EmulatePrecision::visitAggregate(Visit visit, TIntermAggregate *node) { case EOpSequence: case EOpConstructStruct: - // No special handling - break; case EOpFunction: - if (visit == PreVisit) - { - const TIntermSequence &sequence = *(node->getSequence()); - TIntermSequence::const_iterator seqIter = sequence.begin(); - TIntermAggregate *params = (*seqIter)->getAsAggregate(); - ASSERT(params != NULL); - ASSERT(params->getOp() == EOpParameters); - mFunctionMap[node->getName()] = params->getSequence(); - } break; case EOpPrototype: - if (visit == PreVisit) - mFunctionMap[node->getName()] = node->getSequence(); visitChildren = false; break; case EOpParameters: @@ -418,50 +435,17 @@ bool EmulatePrecision::visitAggregate(Visit visit, TIntermAggregate *node) case EOpFunctionCall: { // Function call. - bool inFunctionMap = (mFunctionMap.find(node->getName()) != mFunctionMap.end()); if (visit == PreVisit) { // User-defined function return values are not rounded, this relies on that // calculations producing the value were rounded. TIntermNode *parent = getParentNode(); - if (canRoundFloat(node->getType()) && !inFunctionMap && parentUsesResult(parent, node)) + if (canRoundFloat(node->getType()) && !isInFunctionMap(node) && + parentUsesResult(parent, node)) { TIntermNode *replacement = createRoundingFunctionCallNode(node); mReplacements.push_back(NodeUpdateEntry(parent, node, replacement, true)); } - - if (inFunctionMap) - { - mSeqIterStack.push_back(mFunctionMap[node->getName()]->begin()); - if (mSeqIterStack.back() != mFunctionMap[node->getName()]->end()) - { - TQualifier qualifier = (*mSeqIterStack.back())->getAsTyped()->getQualifier(); - mInFunctionCallOutParameter = (qualifier == EvqOut || qualifier == EvqInOut); - } - } - else - { - // The function is not user-defined - it is likely built-in texture function. - // Assume that those do not have out parameters. - mInFunctionCallOutParameter = false; - } - } - else if (visit == InVisit) - { - if (inFunctionMap) - { - ++mSeqIterStack.back(); - TQualifier qualifier = (*mSeqIterStack.back())->getAsTyped()->getQualifier(); - mInFunctionCallOutParameter = (qualifier == EvqOut || qualifier == EvqInOut); - } - } - else - { - if (inFunctionMap) - { - mSeqIterStack.pop_back(); - mInFunctionCallOutParameter = false; - } } break; } @@ -484,15 +468,10 @@ bool EmulatePrecision::visitUnary(Visit visit, TIntermUnary *node) case EOpNegative: case EOpVectorLogicalNot: case EOpLogicalNot: - break; case EOpPostIncrement: case EOpPostDecrement: case EOpPreIncrement: case EOpPreDecrement: - if (visit == PreVisit) - mInLValue = true; - else if (visit == PostVisit) - mInLValue = false; break; default: if (canRoundFloat(node->getType()) && visit == PreVisit) diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/EmulatePrecision.h b/Source/ThirdParty/ANGLE/src/compiler/translator/EmulatePrecision.h index 62cea67852d9..08177b3414f6 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/EmulatePrecision.h +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/EmulatePrecision.h @@ -18,15 +18,15 @@ // need to write a huge number of variations of the emulated compound assignment // to every translated shader with emulation enabled. -class EmulatePrecision : public TIntermTraverser +class EmulatePrecision : public TLValueTrackingTraverser { public: - EmulatePrecision(); + EmulatePrecision(const TSymbolTable &symbolTable, int shaderVersion); - virtual void visitSymbol(TIntermSymbol *node); - virtual bool visitBinary(Visit visit, TIntermBinary *node); - virtual bool visitUnary(Visit visit, TIntermUnary *node); - virtual bool visitAggregate(Visit visit, TIntermAggregate *node); + void visitSymbol(TIntermSymbol *node) override; + bool visitBinary(Visit visit, TIntermBinary *node) override; + bool visitUnary(Visit visit, TIntermUnary *node) override; + bool visitAggregate(Visit visit, TIntermAggregate *node) override; void writeEmulationHelpers(TInfoSinkBase& sink, ShShaderOutput outputLanguage); @@ -56,20 +56,7 @@ class EmulatePrecision : public TIntermTraverser EmulationSet mEmulateCompoundMul; EmulationSet mEmulateCompoundDiv; - // Stack of function call parameter iterators - std::vector mSeqIterStack; - bool mDeclaringVariables; - bool mInLValue; - bool mInFunctionCallOutParameter; - - struct TStringComparator - { - bool operator() (const TString& a, const TString& b) const { return a.compare(b) < 0; } - }; - - // Map from function names to their parameter sequences - std::map mFunctionMap; }; #endif // COMPILER_TRANSLATOR_EMULATE_PRECISION_H_ diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/ExtensionBehavior.h b/Source/ThirdParty/ANGLE/src/compiler/translator/ExtensionBehavior.h index cf4d7fba3122..782c1c92178a 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/ExtensionBehavior.h +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/ExtensionBehavior.h @@ -34,4 +34,10 @@ inline const char* getBehaviorString(TBehavior b) // Mapping between extension name and behavior. typedef std::map TExtensionBehavior; +inline bool IsExtensionEnabled(const TExtensionBehavior &extBehavior, const char *extension) +{ + auto iter = extBehavior.find(extension); + return iter != extBehavior.end() && (iter->second == EBhEnable || iter->second == EBhRequire); +} + #endif // COMPILER_TRANSLATOR_EXTENSIONBEHAVIOR_H_ diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/ExtensionGLSL.cpp b/Source/ThirdParty/ANGLE/src/compiler/translator/ExtensionGLSL.cpp new file mode 100644 index 000000000000..d7f45f7eef62 --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/ExtensionGLSL.cpp @@ -0,0 +1,100 @@ +// +// Copyright (c) 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. +// +// ExtensionGLSL.cpp: Implements the TExtensionGLSL class that tracks GLSL extension requirements +// of shaders. + +#include "compiler/translator/ExtensionGLSL.h" + +#include "compiler/translator/VersionGLSL.h" + +TExtensionGLSL::TExtensionGLSL(ShShaderOutput output) + : TIntermTraverser(true, false, false), mTargetVersion(ShaderOutputTypeToGLSLVersion(output)) +{ +} + +const std::set &TExtensionGLSL::getEnabledExtensions() const +{ + return mEnabledExtensions; +} + +const std::set &TExtensionGLSL::getRequiredExtensions() const +{ + return mRequiredExtensions; +} + +bool TExtensionGLSL::visitUnary(Visit, TIntermUnary *node) +{ + checkOperator(node); + + return true; +} + +bool TExtensionGLSL::visitAggregate(Visit, TIntermAggregate *node) +{ + checkOperator(node); + + return true; +} + +void TExtensionGLSL::checkOperator(TIntermOperator *node) +{ + if (mTargetVersion < GLSL_VERSION_130) + { + return; + } + + switch (node->getOp()) + { + case EOpAbs: + break; + + case EOpSign: + break; + + case EOpMix: + break; + + case EOpFloatBitsToInt: + case EOpFloatBitsToUint: + case EOpIntBitsToFloat: + case EOpUintBitsToFloat: + if (mTargetVersion < GLSL_VERSION_330) + { + // Bit conversion functions cannot be emulated. + mRequiredExtensions.insert("GL_ARB_shader_bit_encoding"); + } + break; + + case EOpPackSnorm2x16: + case EOpPackHalf2x16: + case EOpUnpackSnorm2x16: + case EOpUnpackHalf2x16: + if (mTargetVersion < GLSL_VERSION_420) + { + mEnabledExtensions.insert("GL_ARB_shading_language_packing"); + + if (mTargetVersion < GLSL_VERSION_330) + { + // floatBitsToUint and uintBitsToFloat are needed to emulate + // packHalf2x16 and unpackHalf2x16 respectively and cannot be + // emulated themselves. + mRequiredExtensions.insert("GL_ARB_shader_bit_encoding"); + } + } + break; + + case EOpPackUnorm2x16: + case EOpUnpackUnorm2x16: + if (mTargetVersion < GLSL_VERSION_410) + { + mEnabledExtensions.insert("GL_ARB_shading_language_packing"); + } + break; + + default: + break; + } +} diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/ExtensionGLSL.h b/Source/ThirdParty/ANGLE/src/compiler/translator/ExtensionGLSL.h new file mode 100644 index 000000000000..6bb84d612daf --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/ExtensionGLSL.h @@ -0,0 +1,39 @@ +// +// Copyright (c) 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. +// +// ExtensionGLSL.h: Defines the TExtensionGLSL class that tracks GLSL extension requirements of +// shaders. + +#ifndef COMPILER_TRANSLATOR_EXTENSIONGLSL_H_ +#define COMPILER_TRANSLATOR_EXTENSIONGLSL_H_ + +#include +#include + +#include "compiler/translator/IntermNode.h" + +// Traverses the intermediate tree to determine which GLSL extensions are required +// to support the shader. +class TExtensionGLSL : public TIntermTraverser +{ + public: + TExtensionGLSL(ShShaderOutput output); + + const std::set &getEnabledExtensions() const; + const std::set &getRequiredExtensions() const; + + bool visitUnary(Visit visit, TIntermUnary *node) override; + bool visitAggregate(Visit visit, TIntermAggregate *node) override; + + private: + void checkOperator(TIntermOperator *node); + + int mTargetVersion; + + std::set mEnabledExtensions; + std::set mRequiredExtensions; +}; + +#endif // COMPILER_TRANSLATOR_EXTENSIONGLSL_H_ diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/FlagStd140Structs.h b/Source/ThirdParty/ANGLE/src/compiler/translator/FlagStd140Structs.h index 07b9a72c5c65..cfcd775af740 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/FlagStd140Structs.h +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/FlagStd140Structs.h @@ -18,11 +18,17 @@ namespace sh class FlagStd140Structs : public TIntermTraverser { public: + + FlagStd140Structs() + : TIntermTraverser(true, false, false) + { + } + const std::vector getFlaggedNodes() const { return mFlaggedNodes; } protected: - virtual bool visitBinary(Visit visit, TIntermBinary *binaryNode); - virtual void visitSymbol(TIntermSymbol *symbol); + bool visitBinary(Visit visit, TIntermBinary *binaryNode) override; + void visitSymbol(TIntermSymbol *symbol) override; private: bool isInStd140InterfaceBlock(TIntermTyped *node) const; diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/ForLoopUnroll.cpp b/Source/ThirdParty/ANGLE/src/compiler/translator/ForLoopUnroll.cpp index f3be20d9783b..4cc1c26a135b 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/ForLoopUnroll.cpp +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/ForLoopUnroll.cpp @@ -6,6 +6,9 @@ #include "compiler/translator/ForLoopUnroll.h" +#include "compiler/translator/ValidateLimitations.h" +#include "angle_gl.h" + bool ForLoopUnrollMarker::visitBinary(Visit, TIntermBinary *node) { if (mUnrollCondition != kSamplerArrayIndex) @@ -38,11 +41,16 @@ bool ForLoopUnrollMarker::visitBinary(Visit, TIntermBinary *node) bool ForLoopUnrollMarker::visitLoop(Visit, TIntermLoop *node) { - if (mUnrollCondition == kIntegerIndex) + bool canBeUnrolled = mHasRunLoopValidation; + if (!mHasRunLoopValidation) + { + canBeUnrolled = ValidateLimitations::IsLimitedForLoop(node); + } + if (mUnrollCondition == kIntegerIndex && canBeUnrolled) { // Check if loop index type is integer. - // This is called after ValidateLimitations pass, so all the calls - // should be valid. See ValidateLimitations::validateForLoopInit(). + // This is called after ValidateLimitations pass, so the loop has the limited form specified + // in ESSL 1.00 appendix A. TIntermSequence *declSeq = node->getInit()->getAsAggregate()->getSequence(); TIntermSymbol *symbol = (*declSeq)[0]->getAsBinaryNode()->getLeft()->getAsSymbolNode(); if (symbol->getBasicType() == EbtInt) @@ -50,11 +58,18 @@ bool ForLoopUnrollMarker::visitLoop(Visit, TIntermLoop *node) } TIntermNode *body = node->getBody(); - if (body != NULL) + if (body != nullptr) { - mLoopStack.push(node); - body->traverse(this); - mLoopStack.pop(); + if (canBeUnrolled) + { + mLoopStack.push(node); + body->traverse(this); + mLoopStack.pop(); + } + else + { + body->traverse(this); + } } // The loop is fully processed - no need to visit children. return false; diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/ForLoopUnroll.h b/Source/ThirdParty/ANGLE/src/compiler/translator/ForLoopUnroll.h index c8787d55a0ea..9c49ecad33e7 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/ForLoopUnroll.h +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/ForLoopUnroll.h @@ -24,16 +24,18 @@ class ForLoopUnrollMarker : public TIntermTraverser kSamplerArrayIndex }; - ForLoopUnrollMarker(UnrollCondition condition) - : mUnrollCondition(condition), + ForLoopUnrollMarker(UnrollCondition condition, bool hasRunLoopValidation) + : TIntermTraverser(true, false, false), + mUnrollCondition(condition), mSamplerArrayIndexIsFloatLoopIndex(false), - mVisitSamplerArrayIndexNodeInsideLoop(false) + mVisitSamplerArrayIndexNodeInsideLoop(false), + mHasRunLoopValidation(hasRunLoopValidation) { } - virtual bool visitBinary(Visit, TIntermBinary *node); - virtual bool visitLoop(Visit, TIntermLoop *node); - virtual void visitSymbol(TIntermSymbol *node); + bool visitBinary(Visit, TIntermBinary *node) override; + bool visitLoop(Visit, TIntermLoop *node) override; + void visitSymbol(TIntermSymbol *node) override; bool samplerArrayIndexIsFloatLoopIndex() const { @@ -45,6 +47,7 @@ class ForLoopUnrollMarker : public TIntermTraverser TLoopStack mLoopStack; bool mSamplerArrayIndexIsFloatLoopIndex; bool mVisitSamplerArrayIndexNodeInsideLoop; + bool mHasRunLoopValidation; }; #endif // COMPILER_TRANSLATOR_FORLOOPUNROLL_H_ diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/InfoSink.cpp b/Source/ThirdParty/ANGLE/src/compiler/translator/InfoSink.cpp index 8376223001a7..cd59658ff76c 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/InfoSink.cpp +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/InfoSink.cpp @@ -26,7 +26,7 @@ void TInfoSinkBase::prefix(TPrefixType p) { sink.append("NOTE: "); break; default: - sink.append("UNKNOWN ERROR: "); + sink.append("UNKOWN ERROR: "); break; } } diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/Initialize.cpp b/Source/ThirdParty/ANGLE/src/compiler/translator/Initialize.cpp index 9e114057582b..410d6df90299 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/Initialize.cpp +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/Initialize.cpp @@ -11,25 +11,26 @@ // #include "compiler/translator/Initialize.h" +#include "compiler/translator/Cache.h" #include "compiler/translator/IntermNode.h" #include "angle_gl.h" void InsertBuiltInFunctions(sh::GLenum type, ShShaderSpec spec, const ShBuiltInResources &resources, TSymbolTable &symbolTable) { - TType *float1 = new TType(EbtFloat); - TType *float2 = new TType(EbtFloat, 2); - TType *float3 = new TType(EbtFloat, 3); - TType *float4 = new TType(EbtFloat, 4); - TType *int1 = new TType(EbtInt); - TType *int2 = new TType(EbtInt, 2); - TType *int3 = new TType(EbtInt, 3); - TType *uint1 = new TType(EbtUInt); - TType *bool1 = new TType(EbtBool); - TType *genType = new TType(EbtGenType); - TType *genIType = new TType(EbtGenIType); - TType *genUType = new TType(EbtGenUType); - TType *genBType = new TType(EbtGenBType); + const TType *float1 = TCache::getType(EbtFloat); + const TType *float2 = TCache::getType(EbtFloat, 2); + const TType *float3 = TCache::getType(EbtFloat, 3); + const TType *float4 = TCache::getType(EbtFloat, 4); + const TType *int1 = TCache::getType(EbtInt); + const TType *int2 = TCache::getType(EbtInt, 2); + const TType *int3 = TCache::getType(EbtInt, 3); + const TType *uint1 = TCache::getType(EbtUInt); + const TType *bool1 = TCache::getType(EbtBool); + const TType *genType = TCache::getType(EbtGenType); + const TType *genIType = TCache::getType(EbtGenIType); + const TType *genUType = TCache::getType(EbtGenUType); + const TType *genBType = TCache::getType(EbtGenBType); // // Angle and Trigonometric Functions. @@ -96,19 +97,16 @@ void InsertBuiltInFunctions(sh::GLenum type, ShShaderSpec spec, const ShBuiltInR symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpClamp, genUType, "clamp", genUType, genUType, genUType); symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpMix, genType, "mix", genType, genType, float1); symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpMix, genType, "mix", genType, genType, genType); + symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpMix, genType, "mix", genType, genType, genBType); symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpStep, genType, "step", genType, genType); symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpStep, genType, "step", float1, genType); symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpSmoothStep, genType, "smoothstep", genType, genType, genType); symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpSmoothStep, genType, "smoothstep", float1, float1, genType); - TType *outFloat1 = new TType(EbtFloat); - TType *outFloat2 = new TType(EbtFloat, 2); - TType *outFloat3 = new TType(EbtFloat, 3); - TType *outFloat4 = new TType(EbtFloat, 4); - outFloat1->setQualifier(EvqOut); - outFloat2->setQualifier(EvqOut); - outFloat3->setQualifier(EvqOut); - outFloat4->setQualifier(EvqOut); + const TType *outFloat1 = TCache::getType(EbtFloat, EvqOut); + const TType *outFloat2 = TCache::getType(EbtFloat, EvqOut, 2); + const TType *outFloat3 = TCache::getType(EbtFloat, EvqOut, 3); + const TType *outFloat4 = TCache::getType(EbtFloat, EvqOut, 4); symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpModf, float1, "modf", float1, outFloat1); symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpModf, float2, "modf", float2, outFloat2); @@ -141,15 +139,15 @@ void InsertBuiltInFunctions(sh::GLenum type, ShShaderSpec spec, const ShBuiltInR symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpReflect, genType, "reflect", genType, genType); symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpRefract, genType, "refract", genType, genType, float1); - TType *mat2 = new TType(EbtFloat, 2, 2); - TType *mat3 = new TType(EbtFloat, 3, 3); - TType *mat4 = new TType(EbtFloat, 4, 4); - TType *mat2x3 = new TType(EbtFloat, 2, 3); - TType *mat3x2 = new TType(EbtFloat, 3, 2); - TType *mat2x4 = new TType(EbtFloat, 2, 4); - TType *mat4x2 = new TType(EbtFloat, 4, 2); - TType *mat3x4 = new TType(EbtFloat, 3, 4); - TType *mat4x3 = new TType(EbtFloat, 4, 3); + const TType *mat2 = TCache::getType(EbtFloat, 2, 2); + const TType *mat3 = TCache::getType(EbtFloat, 3, 3); + const TType *mat4 = TCache::getType(EbtFloat, 4, 4); + const TType *mat2x3 = TCache::getType(EbtFloat, 2, 3); + const TType *mat3x2 = TCache::getType(EbtFloat, 3, 2); + const TType *mat2x4 = TCache::getType(EbtFloat, 2, 4); + const TType *mat4x2 = TCache::getType(EbtFloat, 4, 2); + const TType *mat3x4 = TCache::getType(EbtFloat, 3, 4); + const TType *mat4x3 = TCache::getType(EbtFloat, 4, 3); // // Matrix Functions. @@ -192,10 +190,10 @@ void InsertBuiltInFunctions(sh::GLenum type, ShShaderSpec spec, const ShBuiltInR symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpInverse, mat3, "inverse", mat3); symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpInverse, mat4, "inverse", mat4); - TType *vec = new TType(EbtVec); - TType *ivec = new TType(EbtIVec); - TType *uvec = new TType(EbtUVec); - TType *bvec = new TType(EbtBVec); + const TType *vec = TCache::getType(EbtVec); + const TType *ivec = TCache::getType(EbtIVec); + const TType *uvec = TCache::getType(EbtUVec); + const TType *bvec = TCache::getType(EbtBVec); // // Vector relational functions. @@ -224,8 +222,8 @@ void InsertBuiltInFunctions(sh::GLenum type, ShShaderSpec spec, const ShBuiltInR symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpAll, bool1, "all", bvec); symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpVectorLogicalNot, bvec, "not", bvec); - TType *sampler2D = new TType(EbtSampler2D); - TType *samplerCube = new TType(EbtSamplerCube); + const TType *sampler2D = TCache::getType(EbtSampler2D); + const TType *samplerCube = TCache::getType(EbtSamplerCube); // // Texture Functions for GLSL ES 1.0 @@ -237,7 +235,7 @@ void InsertBuiltInFunctions(sh::GLenum type, ShShaderSpec spec, const ShBuiltInR if (resources.OES_EGL_image_external) { - TType *samplerExternalOES = new TType(EbtSamplerExternalOES); + const TType *samplerExternalOES = TCache::getType(EbtSamplerExternalOES); symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "texture2D", samplerExternalOES, float2); symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "texture2DProj", samplerExternalOES, float3); @@ -246,7 +244,7 @@ void InsertBuiltInFunctions(sh::GLenum type, ShShaderSpec spec, const ShBuiltInR if (resources.ARB_texture_rectangle) { - TType *sampler2DRect = new TType(EbtSampler2DRect); + const TType *sampler2DRect = TCache::getType(EbtSampler2DRect); symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "texture2DRect", sampler2DRect, float2); symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "texture2DRectProj", sampler2DRect, float3); @@ -295,12 +293,12 @@ void InsertBuiltInFunctions(sh::GLenum type, ShShaderSpec spec, const ShBuiltInR symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "textureCubeLod", samplerCube, float3, float1); } - TType *gvec4 = new TType(EbtGVec4); + const TType *gvec4 = TCache::getType(EbtGVec4); - TType *gsampler2D = new TType(EbtGSampler2D); - TType *gsamplerCube = new TType(EbtGSamplerCube); - TType *gsampler3D = new TType(EbtGSampler3D); - TType *gsampler2DArray = new TType(EbtGSampler2DArray); + const TType *gsampler2D = TCache::getType(EbtGSampler2D); + const TType *gsamplerCube = TCache::getType(EbtGSamplerCube); + const TType *gsampler3D = TCache::getType(EbtGSampler3D); + const TType *gsampler2DArray = TCache::getType(EbtGSampler2DArray); // // Texture Functions for GLSL ES 3.0 @@ -328,9 +326,9 @@ void InsertBuiltInFunctions(sh::GLenum type, ShShaderSpec spec, const ShBuiltInR symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProj", gsampler3D, float4, float1); } - TType *sampler2DShadow = new TType(EbtSampler2DShadow); - TType *samplerCubeShadow = new TType(EbtSamplerCubeShadow); - TType *sampler2DArrayShadow = new TType(EbtSampler2DArrayShadow); + const TType *sampler2DShadow = TCache::getType(EbtSampler2DShadow); + const TType *samplerCubeShadow = TCache::getType(EbtSamplerCubeShadow); + const TType *sampler2DArrayShadow = TCache::getType(EbtSampler2DArrayShadow); symbolTable.insertBuiltIn(ESSL3_BUILTINS, float1, "texture", sampler2DShadow, float3); symbolTable.insertBuiltIn(ESSL3_BUILTINS, float1, "texture", samplerCubeShadow, float4); @@ -466,6 +464,12 @@ void InsertBuiltInFunctions(sh::GLenum type, ShShaderSpec spec, const ShBuiltInR if (spec != SH_CSS_SHADERS_SPEC) { symbolTable.insertConstInt(COMMON_BUILTINS, "gl_MaxDrawBuffers", resources.MaxDrawBuffers); + if (resources.EXT_blend_func_extended) + { + symbolTable.insertConstIntExt(COMMON_BUILTINS, "GL_EXT_blend_func_extended", + "gl_MaxDualSourceDrawBuffersEXT", + resources.MaxDualSourceDrawBuffers); + } } symbolTable.insertConstInt(ESSL3_BUILTINS, "gl_MaxVertexOutputVectors", resources.MaxVertexOutputVectors); @@ -504,12 +508,33 @@ void IdentifyBuiltIns(sh::GLenum type, ShShaderSpec spec, fragData.setArraySize(resources.MaxDrawBuffers); symbolTable.insert(ESSL1_BUILTINS, new TVariable(NewPoolTString("gl_FragData"), fragData)); + if (resources.EXT_blend_func_extended) + { + symbolTable.insert( + ESSL1_BUILTINS, "GL_EXT_blend_func_extended", + new TVariable(NewPoolTString("gl_SecondaryFragColorEXT"), + TType(EbtFloat, EbpMedium, EvqSecondaryFragColorEXT, 4))); + TType secondaryFragData(EbtFloat, EbpMedium, EvqSecondaryFragDataEXT, 4, 1, true); + secondaryFragData.setArraySize(resources.MaxDualSourceDrawBuffers); + symbolTable.insert( + ESSL1_BUILTINS, "GL_EXT_blend_func_extended", + new TVariable(NewPoolTString("gl_SecondaryFragDataEXT"), secondaryFragData)); + } + if (resources.EXT_frag_depth) { - symbolTable.insert(ESSL1_BUILTINS, "GL_EXT_frag_depth", new TVariable(NewPoolTString("gl_FragDepthEXT"), - TType(EbtFloat, resources.FragmentPrecisionHigh ? EbpHigh : EbpMedium, EvqFragDepth, 1))); + symbolTable.insert( + ESSL1_BUILTINS, "GL_EXT_frag_depth", + new TVariable( + NewPoolTString("gl_FragDepthEXT"), + TType(EbtFloat, resources.FragmentPrecisionHigh ? EbpHigh : EbpMedium, + EvqFragDepthEXT, 1))); } + symbolTable.insert(ESSL3_BUILTINS, + new TVariable(NewPoolTString("gl_FragDepth"), + TType(EbtFloat, EbpHigh, EvqFragDepth, 1))); + if (resources.EXT_shader_framebuffer_fetch || resources.NV_shader_framebuffer_fetch) { TType lastFragData(EbtFloat, EbpMedium, EvqLastFragData, 4, 1, true); @@ -553,6 +578,8 @@ void IdentifyBuiltIns(sh::GLenum type, ShShaderSpec spec, TType(EbtFloat, EbpMedium, EvqPointSize, 1))); symbolTable.insert(ESSL3_BUILTINS, new TVariable(NewPoolTString("gl_InstanceID"), TType(EbtInt, EbpHigh, EvqInstanceID, 1))); + symbolTable.insert(ESSL3_BUILTINS, new TVariable(NewPoolTString("gl_VertexID"), + TType(EbtInt, EbpHigh, EvqVertexID, 1))); break; default: @@ -569,6 +596,8 @@ void InitExtensionBehavior(const ShBuiltInResources& resources, extBehavior["GL_OES_EGL_image_external"] = EBhUndefined; if (resources.ARB_texture_rectangle) extBehavior["GL_ARB_texture_rectangle"] = EBhUndefined; + if (resources.EXT_blend_func_extended) + extBehavior["GL_EXT_blend_func_extended"] = EBhUndefined; if (resources.EXT_draw_buffers) extBehavior["GL_EXT_draw_buffers"] = EBhUndefined; if (resources.EXT_frag_depth) diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/InitializeDll.cpp b/Source/ThirdParty/ANGLE/src/compiler/translator/InitializeDll.cpp index c98430662aab..713965389fab 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/InitializeDll.cpp +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/InitializeDll.cpp @@ -4,6 +4,7 @@ // found in the LICENSE file. // +#include "compiler/translator/Cache.h" #include "compiler/translator/InitializeDll.h" #include "compiler/translator/InitializeGlobals.h" #include "compiler/translator/InitializeParseContext.h" @@ -24,6 +25,8 @@ bool InitProcess() return false; } + TCache::initialize(); + return true; } @@ -31,4 +34,5 @@ void DetachProcess() { FreeParseContextIndex(); FreePoolIndex(); + TCache::destroy(); } diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/InitializeParseContext.h b/Source/ThirdParty/ANGLE/src/compiler/translator/InitializeParseContext.h index fa9b885e80e1..70dac702e231 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/InitializeParseContext.h +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/InitializeParseContext.h @@ -10,7 +10,7 @@ bool InitializeParseContextIndex(); void FreeParseContextIndex(); -struct TParseContext; +class TParseContext; extern void SetGlobalParseContext(TParseContext* context); extern TParseContext* GetGlobalParseContext(); diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/InitializeVariables.h b/Source/ThirdParty/ANGLE/src/compiler/translator/InitializeVariables.h index 4a81266498cb..2a141ec91cfd 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/InitializeVariables.h +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/InitializeVariables.h @@ -26,19 +26,20 @@ class InitializeVariables : public TIntermTraverser typedef TVector InitVariableInfoList; InitializeVariables(const InitVariableInfoList &vars) - : mCodeInserted(false), - mVariables(vars) + : TIntermTraverser(true, false, false), + mVariables(vars), + mCodeInserted(false) { } protected: - virtual bool visitBinary(Visit, TIntermBinary *node) { return false; } - virtual bool visitUnary(Visit, TIntermUnary *node) { return false; } - virtual bool visitSelection(Visit, TIntermSelection *node) { return false; } - virtual bool visitLoop(Visit, TIntermLoop *node) { return false; } - virtual bool visitBranch(Visit, TIntermBranch *node) { return false; } + bool visitBinary(Visit, TIntermBinary *node) override { return false; } + bool visitUnary(Visit, TIntermUnary *node) override { return false; } + bool visitSelection(Visit, TIntermSelection *node) override { return false; } + bool visitLoop(Visit, TIntermLoop *node) override { return false; } + bool visitBranch(Visit, TIntermBranch *node) override { return false; } - virtual bool visitAggregate(Visit visit, TIntermAggregate* node); + bool visitAggregate(Visit visit, TIntermAggregate *node) override; private: void insertInitCode(TIntermSequence *sequence); diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/IntermNode.cpp b/Source/ThirdParty/ANGLE/src/compiler/translator/IntermNode.cpp index b339798404a3..2a9286008892 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/IntermNode.cpp +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/IntermNode.cpp @@ -13,7 +13,10 @@ #include #include #include +#include +#include "common/mathutil.h" +#include "common/matrix_utils.h" #include "compiler/translator/HashNames.h" #include "compiler/translator/IntermNode.h" #include "compiler/translator/SymbolTable.h" @@ -63,71 +66,107 @@ bool ValidateMultiplication(TOperator op, const TType &left, const TType &right) } } -bool CompareStructure(const TType& leftNodeType, - const TConstantUnion *rightUnionArray, - const TConstantUnion *leftUnionArray); - -bool CompareStruct(const TType &leftNodeType, - const TConstantUnion *rightUnionArray, - const TConstantUnion *leftUnionArray) +TConstantUnion *Vectorize(const TConstantUnion &constant, size_t size) { - const TFieldList &fields = leftNodeType.getStruct()->fields(); + TConstantUnion *constUnion = new TConstantUnion[size]; + for (unsigned int i = 0; i < size; ++i) + constUnion[i] = constant; + + return constUnion; +} - size_t structSize = fields.size(); - size_t index = 0; +void UndefinedConstantFoldingError(const TSourceLoc &loc, TOperator op, TBasicType basicType, + TInfoSink &infoSink, TConstantUnion *result) +{ + std::stringstream constantFoldingErrorStream; + constantFoldingErrorStream << "'" << GetOperatorString(op) + << "' operation result is undefined for the values passed in"; + infoSink.info.message(EPrefixWarning, loc, constantFoldingErrorStream.str().c_str()); - for (size_t j = 0; j < structSize; j++) + switch (basicType) { - size_t size = fields[j]->type()->getObjectSize(); - for (size_t i = 0; i < size; i++) - { - if (fields[j]->type()->getBasicType() == EbtStruct) - { - if (!CompareStructure(*fields[j]->type(), - &rightUnionArray[index], - &leftUnionArray[index])) - { - return false; - } - } - else - { - if (leftUnionArray[index] != rightUnionArray[index]) - return false; - index++; - } - } + case EbtFloat : + result->setFConst(0.0f); + break; + case EbtInt: + result->setIConst(0); + break; + case EbtUInt: + result->setUConst(0u); + break; + case EbtBool: + result->setBConst(false); + break; + default: + break; } - return true; } -bool CompareStructure(const TType &leftNodeType, - const TConstantUnion *rightUnionArray, - const TConstantUnion *leftUnionArray) +float VectorLength(const TConstantUnion *paramArray, size_t paramArraySize) { - if (leftNodeType.isArray()) + float result = 0.0f; + for (size_t i = 0; i < paramArraySize; i++) { - TType typeWithoutArrayness = leftNodeType; - typeWithoutArrayness.clearArrayness(); + float f = paramArray[i].getFConst(); + result += f * f; + } + return sqrtf(result); +} - size_t arraySize = leftNodeType.getArraySize(); +float VectorDotProduct(const TConstantUnion *paramArray1, + const TConstantUnion *paramArray2, + size_t paramArraySize) +{ + float result = 0.0f; + for (size_t i = 0; i < paramArraySize; i++) + result += paramArray1[i].getFConst() * paramArray2[i].getFConst(); + return result; +} - for (size_t i = 0; i < arraySize; ++i) - { - size_t offset = typeWithoutArrayness.getObjectSize() * i; - if (!CompareStruct(typeWithoutArrayness, - &rightUnionArray[offset], - &leftUnionArray[offset])) - { - return false; - } - } - } - else +TIntermTyped *CreateFoldedNode(TConstantUnion *constArray, + const TIntermTyped *originalNode, + TQualifier qualifier) +{ + if (constArray == nullptr) { - return CompareStruct(leftNodeType, rightUnionArray, leftUnionArray); + return nullptr; } - return true; + TIntermTyped *folded = new TIntermConstantUnion(constArray, originalNode->getType()); + folded->getTypePointer()->setQualifier(qualifier); + folded->setLine(originalNode->getLine()); + return folded; +} + +angle::Matrix GetMatrix(const TConstantUnion *paramArray, + const unsigned int &rows, + const unsigned int &cols) +{ + std::vector elements; + for (size_t i = 0; i < rows * cols; i++) + elements.push_back(paramArray[i].getFConst()); + // Transpose is used since the Matrix constructor expects arguments in row-major order, + // whereas the paramArray is in column-major order. + return angle::Matrix(elements, rows, cols).transpose(); +} + +angle::Matrix GetMatrix(const TConstantUnion *paramArray, const unsigned int &size) +{ + std::vector elements; + for (size_t i = 0; i < size * size; i++) + elements.push_back(paramArray[i].getFConst()); + // Transpose is used since the Matrix constructor expects arguments in row-major order, + // whereas the paramArray is in column-major order. + return angle::Matrix(elements, size).transpose(); +} + +void SetUnionArrayFromMatrix(const angle::Matrix &m, TConstantUnion *resultArray) +{ + // Transpose is used since the input Matrix is in row-major order, + // whereas the actual result should be in column-major order. + angle::Matrix result = m.transpose(); + std::vector resultElements = result.elements(); + for (size_t i = 0; i < resultElements.size(); i++) + resultArray[i].setFConst(resultElements[i]); } } // namespace anonymous @@ -159,7 +198,7 @@ bool TIntermLoop::replaceChildNode( REPLACE_IF_IS(mInit, TIntermNode, original, replacement); REPLACE_IF_IS(mCond, TIntermTyped, original, replacement); REPLACE_IF_IS(mExpr, TIntermTyped, original, replacement); - REPLACE_IF_IS(mBody, TIntermNode, original, replacement); + REPLACE_IF_IS(mBody, TIntermAggregate, original, replacement); return false; } @@ -209,8 +248,33 @@ bool TIntermAggregate::replaceChildNodeWithMultiple(TIntermNode *original, TInte return false; } +bool TIntermAggregate::insertChildNodes(TIntermSequence::size_type position, TIntermSequence insertions) +{ + if (position > mSequence.size()) + { + return false; + } + auto it = mSequence.begin() + position; + mSequence.insert(it, insertions.begin(), insertions.end()); + return true; +} + +bool TIntermAggregate::areChildrenConstQualified() +{ + for (TIntermNode *&child : mSequence) + { + TIntermTyped *typed = child->getAsTyped(); + if (typed && typed->getQualifier() != EvqConst) + { + return false; + } + } + return true; +} + void TIntermAggregate::setPrecisionFromChildren() { + mGotPrecisionFromChildren = true; if (getBasicType() == EbtBool) { mType.setPrecision(EbpUndefined); @@ -249,7 +313,7 @@ void TIntermAggregate::setBuiltInFunctionPrecision() } // ESSL 3.0 spec section 8: textureSize always gets highp precision. // All other functions that take a sampler are assumed to be texture functions. - if (mName.find("textureSize") == 0) + if (mName.getString().find("textureSize") == 0) mType.setPrecision(EbpHigh); else mType.setPrecision(precision); @@ -279,6 +343,70 @@ bool TIntermCase::replaceChildNode( return false; } +TIntermTyped::TIntermTyped(const TIntermTyped &node) : TIntermNode(), mType(node.mType) +{ + // Copy constructor is disallowed for TIntermNode in order to disallow it for subclasses that + // don't explicitly allow it, so normal TIntermNode constructor is used to construct the copy. + // We need to manually copy any fields of TIntermNode besides handling fields in TIntermTyped. + mLine = node.mLine; +} + +TIntermConstantUnion::TIntermConstantUnion(const TIntermConstantUnion &node) : TIntermTyped(node) +{ + mUnionArrayPointer = node.mUnionArrayPointer; +} + +TIntermAggregate::TIntermAggregate(const TIntermAggregate &node) + : TIntermOperator(node), + mName(node.mName), + mUserDefined(node.mUserDefined), + mFunctionId(node.mFunctionId), + mUseEmulatedFunction(node.mUseEmulatedFunction), + mGotPrecisionFromChildren(node.mGotPrecisionFromChildren) +{ + for (TIntermNode *child : node.mSequence) + { + TIntermTyped *typedChild = child->getAsTyped(); + ASSERT(typedChild != nullptr); + TIntermTyped *childCopy = typedChild->deepCopy(); + mSequence.push_back(childCopy); + } +} + +TIntermBinary::TIntermBinary(const TIntermBinary &node) + : TIntermOperator(node), mAddIndexClamp(node.mAddIndexClamp) +{ + TIntermTyped *leftCopy = node.mLeft->deepCopy(); + TIntermTyped *rightCopy = node.mRight->deepCopy(); + ASSERT(leftCopy != nullptr && rightCopy != nullptr); + mLeft = leftCopy; + mRight = rightCopy; +} + +TIntermUnary::TIntermUnary(const TIntermUnary &node) + : TIntermOperator(node), mUseEmulatedFunction(node.mUseEmulatedFunction) +{ + TIntermTyped *operandCopy = node.mOperand->deepCopy(); + ASSERT(operandCopy != nullptr); + mOperand = operandCopy; +} + +TIntermSelection::TIntermSelection(const TIntermSelection &node) : TIntermTyped(node) +{ + // Only supported for ternary nodes, not if statements. + TIntermTyped *trueTyped = node.mTrueBlock->getAsTyped(); + TIntermTyped *falseTyped = node.mFalseBlock->getAsTyped(); + ASSERT(trueTyped != nullptr); + ASSERT(falseTyped != nullptr); + TIntermTyped *conditionCopy = node.mCondition->deepCopy(); + TIntermTyped *trueCopy = trueTyped->deepCopy(); + TIntermTyped *falseCopy = falseTyped->deepCopy(); + ASSERT(conditionCopy != nullptr && trueCopy != nullptr && falseCopy != nullptr); + mCondition = conditionCopy; + mTrueBlock = trueCopy; + mFalseBlock = falseCopy; +} + // // Say whether or not an operation node changes the value of a variable. // @@ -311,6 +439,22 @@ bool TIntermOperator::isAssignment() const } } +bool TIntermOperator::isMultiplication() const +{ + switch (mOp) + { + case EOpMul: + case EOpMatrixTimesMatrix: + case EOpMatrixTimesVector: + case EOpMatrixTimesScalar: + case EOpVectorTimesMatrix: + case EOpVectorTimesScalar: + return true; + default: + return false; + } +} + // // returns true if the operator is for one of the constructors // @@ -322,7 +466,13 @@ bool TIntermOperator::isConstructor() const case EOpConstructVec3: case EOpConstructVec4: case EOpConstructMat2: + case EOpConstructMat2x3: + case EOpConstructMat2x4: + case EOpConstructMat3x2: case EOpConstructMat3: + case EOpConstructMat3x4: + case EOpConstructMat4x2: + case EOpConstructMat4x3: case EOpConstructMat4: case EOpConstructFloat: case EOpConstructIVec2: @@ -384,7 +534,10 @@ void TIntermUnary::promote(const TType *funcReturnType) } } - mType.setQualifier(EvqTemporary); + if (mOperand->getQualifier() == EvqConst) + mType.setQualifier(EvqConst); + else + mType.setQualifier(EvqTemporary); } // @@ -409,10 +562,12 @@ bool TIntermBinary::promote(TInfoSink &infoSink) mLeft->getPrecision(), mRight->getPrecision()); getTypePointer()->setPrecision(higherPrecision); + TQualifier resultQualifier = EvqConst; // Binary operations results in temporary variables unless both // operands are const. if (mLeft->getQualifier() != EvqConst || mRight->getQualifier() != EvqConst) { + resultQualifier = EvqTemporary; getTypePointer()->setQualifier(EvqTemporary); } @@ -467,14 +622,15 @@ bool TIntermBinary::promote(TInfoSink &infoSink) if (mLeft->isVector()) { mOp = EOpVectorTimesMatrix; - setType(TType(basicType, higherPrecision, EvqTemporary, + setType(TType(basicType, higherPrecision, resultQualifier, static_cast(mRight->getCols()), 1)); } else { mOp = EOpMatrixTimesScalar; - setType(TType(basicType, higherPrecision, EvqTemporary, - static_cast(mRight->getCols()), static_cast(mRight->getRows()))); + setType(TType(basicType, higherPrecision, resultQualifier, + static_cast(mRight->getCols()), + static_cast(mRight->getRows()))); } } else if (mLeft->isMatrix() && !mRight->isMatrix()) @@ -482,7 +638,7 @@ bool TIntermBinary::promote(TInfoSink &infoSink) if (mRight->isVector()) { mOp = EOpMatrixTimesVector; - setType(TType(basicType, higherPrecision, EvqTemporary, + setType(TType(basicType, higherPrecision, resultQualifier, static_cast(mLeft->getRows()), 1)); } else @@ -493,8 +649,9 @@ bool TIntermBinary::promote(TInfoSink &infoSink) else if (mLeft->isMatrix() && mRight->isMatrix()) { mOp = EOpMatrixTimesMatrix; - setType(TType(basicType, higherPrecision, EvqTemporary, - static_cast(mRight->getCols()), static_cast(mLeft->getRows()))); + setType(TType(basicType, higherPrecision, resultQualifier, + static_cast(mRight->getCols()), + static_cast(mLeft->getRows()))); } else if (!mLeft->isMatrix() && !mRight->isMatrix()) { @@ -505,7 +662,7 @@ bool TIntermBinary::promote(TInfoSink &infoSink) else if (mLeft->isVector() || mRight->isVector()) { mOp = EOpVectorTimesScalar; - setType(TType(basicType, higherPrecision, EvqTemporary, + setType(TType(basicType, higherPrecision, resultQualifier, static_cast(nominalSize), 1)); } } @@ -548,8 +705,9 @@ bool TIntermBinary::promote(TInfoSink &infoSink) else if (mLeft->isMatrix() && mRight->isMatrix()) { mOp = EOpMatrixTimesMatrixAssign; - setType(TType(basicType, higherPrecision, EvqTemporary, - static_cast(mRight->getCols()), static_cast(mLeft->getRows()))); + setType(TType(basicType, higherPrecision, resultQualifier, + static_cast(mRight->getCols()), + static_cast(mLeft->getRows()))); } else if (!mLeft->isMatrix() && !mRight->isMatrix()) { @@ -562,7 +720,7 @@ bool TIntermBinary::promote(TInfoSink &infoSink) if (!mLeft->isVector()) return false; mOp = EOpVectorTimesScalarAssign; - setType(TType(basicType, higherPrecision, EvqTemporary, + setType(TType(basicType, higherPrecision, resultQualifier, static_cast(mLeft->getNominalSize()), 1)); } } @@ -632,8 +790,9 @@ bool TIntermBinary::promote(TInfoSink &infoSink) { const int secondarySize = std::max( mLeft->getSecondarySize(), mRight->getSecondarySize()); - setType(TType(basicType, higherPrecision, EvqTemporary, - static_cast(nominalSize), static_cast(secondarySize))); + setType(TType(basicType, higherPrecision, resultQualifier, + static_cast(nominalSize), + static_cast(secondarySize))); if (mLeft->isArray()) { ASSERT(mLeft->getArraySize() == mRight->getArraySize()); @@ -659,307 +818,1308 @@ bool TIntermBinary::promote(TInfoSink &infoSink) return true; } +TIntermTyped *TIntermBinary::fold(TInfoSink &infoSink) +{ + TIntermConstantUnion *leftConstant = mLeft->getAsConstantUnion(); + TIntermConstantUnion *rightConstant = mRight->getAsConstantUnion(); + if (leftConstant == nullptr || rightConstant == nullptr) + { + return nullptr; + } + TConstantUnion *constArray = leftConstant->foldBinary(mOp, rightConstant, infoSink); + + // Nodes may be constant folded without being qualified as constant. + TQualifier resultQualifier = EvqConst; + if (mLeft->getQualifier() != EvqConst || mRight->getQualifier() != EvqConst) + { + resultQualifier = EvqTemporary; + } + return CreateFoldedNode(constArray, this, resultQualifier); +} + +TIntermTyped *TIntermUnary::fold(TInfoSink &infoSink) +{ + TIntermConstantUnion *operandConstant = mOperand->getAsConstantUnion(); + if (operandConstant == nullptr) + { + return nullptr; + } + + TConstantUnion *constArray = nullptr; + switch (mOp) + { + case EOpAny: + case EOpAll: + case EOpLength: + case EOpTranspose: + case EOpDeterminant: + case EOpInverse: + case EOpPackSnorm2x16: + case EOpUnpackSnorm2x16: + case EOpPackUnorm2x16: + case EOpUnpackUnorm2x16: + case EOpPackHalf2x16: + case EOpUnpackHalf2x16: + constArray = operandConstant->foldUnaryWithDifferentReturnType(mOp, infoSink); + break; + default: + constArray = operandConstant->foldUnaryWithSameReturnType(mOp, infoSink); + break; + } + + // Nodes may be constant folded without being qualified as constant. + TQualifier resultQualifier = mOperand->getQualifier() == EvqConst ? EvqConst : EvqTemporary; + return CreateFoldedNode(constArray, this, resultQualifier); +} + +TIntermTyped *TIntermAggregate::fold(TInfoSink &infoSink) +{ + // Make sure that all params are constant before actual constant folding. + for (auto *param : *getSequence()) + { + if (param->getAsConstantUnion() == nullptr) + { + return nullptr; + } + } + TConstantUnion *constArray = nullptr; + if (isConstructor()) + constArray = TIntermConstantUnion::FoldAggregateConstructor(this, infoSink); + else + constArray = TIntermConstantUnion::FoldAggregateBuiltIn(this, infoSink); + + // Nodes may be constant folded without being qualified as constant. + TQualifier resultQualifier = areChildrenConstQualified() ? EvqConst : EvqTemporary; + return CreateFoldedNode(constArray, this, resultQualifier); +} + // // The fold functions see if an operation on a constant can be done in place, // without generating run-time code. // -// Returns the node to keep using, which may or may not be the node passed in. +// Returns the constant value to keep using or nullptr. // -TIntermTyped *TIntermConstantUnion::fold( - TOperator op, TIntermConstantUnion *rightNode, TInfoSink &infoSink) +TConstantUnion *TIntermConstantUnion::foldBinary(TOperator op, TIntermConstantUnion *rightNode, TInfoSink &infoSink) { - TConstantUnion *unionArray = getUnionArrayPointer(); + const TConstantUnion *leftArray = getUnionArrayPointer(); + const TConstantUnion *rightArray = rightNode->getUnionArrayPointer(); - if (!unionArray) + if (!leftArray) + return nullptr; + if (!rightArray) return nullptr; size_t objectSize = getType().getObjectSize(); - if (rightNode) + // for a case like float f = vec4(2, 3, 4, 5) + 1.2; + if (rightNode->getType().getObjectSize() == 1 && objectSize > 1) + { + rightArray = Vectorize(*rightNode->getUnionArrayPointer(), objectSize); + } + else if (rightNode->getType().getObjectSize() > 1 && objectSize == 1) { - // binary operations - TConstantUnion *rightUnionArray = rightNode->getUnionArrayPointer(); - TType returnType = getType(); + // for a case like float f = 1.2 + vec4(2, 3, 4, 5); + leftArray = Vectorize(*getUnionArrayPointer(), rightNode->getType().getObjectSize()); + objectSize = rightNode->getType().getObjectSize(); + } - if (!rightUnionArray) - return nullptr; + TConstantUnion *resultArray = nullptr; - // for a case like float f = vec4(2, 3, 4, 5) + 1.2; - if (rightNode->getType().getObjectSize() == 1 && objectSize > 1) - { - rightUnionArray = new TConstantUnion[objectSize]; - for (size_t i = 0; i < objectSize; ++i) - { - rightUnionArray[i] = *rightNode->getUnionArrayPointer(); - } - returnType = getType(); - } - else if (rightNode->getType().getObjectSize() > 1 && objectSize == 1) - { - // for a case like float f = 1.2 + vec4(2, 3, 4, 5); - unionArray = new TConstantUnion[rightNode->getType().getObjectSize()]; - for (size_t i = 0; i < rightNode->getType().getObjectSize(); ++i) - { - unionArray[i] = *getUnionArrayPointer(); - } - returnType = rightNode->getType(); - objectSize = rightNode->getType().getObjectSize(); - } + switch(op) + { + case EOpAdd: + resultArray = new TConstantUnion[objectSize]; + for (size_t i = 0; i < objectSize; i++) + resultArray[i] = leftArray[i] + rightArray[i]; + break; + case EOpSub: + resultArray = new TConstantUnion[objectSize]; + for (size_t i = 0; i < objectSize; i++) + resultArray[i] = leftArray[i] - rightArray[i]; + break; - TConstantUnion *tempConstArray = nullptr; - TIntermConstantUnion *tempNode; + case EOpMul: + case EOpVectorTimesScalar: + case EOpMatrixTimesScalar: + resultArray = new TConstantUnion[objectSize]; + for (size_t i = 0; i < objectSize; i++) + resultArray[i] = leftArray[i] * rightArray[i]; + break; - bool boolNodeFlag = false; - switch(op) + case EOpMatrixTimesMatrix: { - case EOpAdd: - tempConstArray = new TConstantUnion[objectSize]; - for (size_t i = 0; i < objectSize; i++) - tempConstArray[i] = unionArray[i] + rightUnionArray[i]; - break; - case EOpSub: - tempConstArray = new TConstantUnion[objectSize]; - for (size_t i = 0; i < objectSize; i++) - tempConstArray[i] = unionArray[i] - rightUnionArray[i]; - break; - - case EOpMul: - case EOpVectorTimesScalar: - case EOpMatrixTimesScalar: - tempConstArray = new TConstantUnion[objectSize]; - for (size_t i = 0; i < objectSize; i++) - tempConstArray[i] = unionArray[i] * rightUnionArray[i]; - break; - - case EOpMatrixTimesMatrix: + if (getType().getBasicType() != EbtFloat || + rightNode->getBasicType() != EbtFloat) { - if (getType().getBasicType() != EbtFloat || - rightNode->getBasicType() != EbtFloat) - { - infoSink.info.message( - EPrefixInternalError, getLine(), - "Constant Folding cannot be done for matrix multiply"); - return nullptr; - } + infoSink.info.message( + EPrefixInternalError, getLine(), + "Constant Folding cannot be done for matrix multiply"); + return nullptr; + } - const int leftCols = getCols(); - const int leftRows = getRows(); - const int rightCols = rightNode->getType().getCols(); - const int rightRows = rightNode->getType().getRows(); - const int resultCols = rightCols; - const int resultRows = leftRows; + const int leftCols = getCols(); + const int leftRows = getRows(); + const int rightCols = rightNode->getType().getCols(); + const int rightRows = rightNode->getType().getRows(); + const int resultCols = rightCols; + const int resultRows = leftRows; - tempConstArray = new TConstantUnion[resultCols * resultRows]; - for (int row = 0; row < resultRows; row++) + resultArray = new TConstantUnion[resultCols * resultRows]; + for (int row = 0; row < resultRows; row++) + { + for (int column = 0; column < resultCols; column++) { - for (int column = 0; column < resultCols; column++) + resultArray[resultRows * column + row].setFConst(0.0f); + for (int i = 0; i < leftCols; i++) { - tempConstArray[resultRows * column + row].setFConst(0.0f); - for (int i = 0; i < leftCols; i++) - { - tempConstArray[resultRows * column + row].setFConst( - tempConstArray[resultRows * column + row].getFConst() + - unionArray[i * leftRows + row].getFConst() * - rightUnionArray[column * rightRows + i].getFConst()); - } + resultArray[resultRows * column + row].setFConst( + resultArray[resultRows * column + row].getFConst() + + leftArray[i * leftRows + row].getFConst() * + rightArray[column * rightRows + i].getFConst()); } } - - // update return type for matrix product - returnType.setPrimarySize(static_cast(resultCols)); - returnType.setSecondarySize(static_cast(resultRows)); } - break; + } + break; - case EOpDiv: - case EOpIMod: + case EOpDiv: + case EOpIMod: + { + resultArray = new TConstantUnion[objectSize]; + for (size_t i = 0; i < objectSize; i++) { - tempConstArray = new TConstantUnion[objectSize]; - for (size_t i = 0; i < objectSize; i++) + switch (getType().getBasicType()) { - switch (getType().getBasicType()) + case EbtFloat: + if (rightArray[i] == 0.0f) { - case EbtFloat: - if (rightUnionArray[i] == 0.0f) - { - infoSink.info.message( - EPrefixWarning, getLine(), - "Divide by zero error during constant folding"); - tempConstArray[i].setFConst( - unionArray[i].getFConst() < 0 ? -FLT_MAX : FLT_MAX); - } - else - { - ASSERT(op == EOpDiv); - tempConstArray[i].setFConst( - unionArray[i].getFConst() / - rightUnionArray[i].getFConst()); - } - break; + infoSink.info.message(EPrefixWarning, getLine(), + "Divide by zero error during constant folding"); + resultArray[i].setFConst(leftArray[i].getFConst() < 0 ? -FLT_MAX : FLT_MAX); + } + else + { + ASSERT(op == EOpDiv); + resultArray[i].setFConst(leftArray[i].getFConst() / rightArray[i].getFConst()); + } + break; - case EbtInt: - if (rightUnionArray[i] == 0) + case EbtInt: + if (rightArray[i] == 0) + { + infoSink.info.message(EPrefixWarning, getLine(), + "Divide by zero error during constant folding"); + resultArray[i].setIConst(INT_MAX); + } + else + { + if (op == EOpDiv) { - infoSink.info.message( - EPrefixWarning, getLine(), - "Divide by zero error during constant folding"); - tempConstArray[i].setIConst(INT_MAX); + resultArray[i].setIConst(leftArray[i].getIConst() / rightArray[i].getIConst()); } else { - if (op == EOpDiv) - { - tempConstArray[i].setIConst( - unionArray[i].getIConst() / - rightUnionArray[i].getIConst()); - } - else - { - ASSERT(op == EOpIMod); - tempConstArray[i].setIConst( - unionArray[i].getIConst() % - rightUnionArray[i].getIConst()); - } + ASSERT(op == EOpIMod); + resultArray[i].setIConst(leftArray[i].getIConst() % rightArray[i].getIConst()); } - break; + } + break; - case EbtUInt: - if (rightUnionArray[i] == 0) + case EbtUInt: + if (rightArray[i] == 0) + { + infoSink.info.message(EPrefixWarning, getLine(), + "Divide by zero error during constant folding"); + resultArray[i].setUConst(UINT_MAX); + } + else + { + if (op == EOpDiv) { - infoSink.info.message( - EPrefixWarning, getLine(), - "Divide by zero error during constant folding"); - tempConstArray[i].setUConst(UINT_MAX); + resultArray[i].setUConst(leftArray[i].getUConst() / rightArray[i].getUConst()); } else { - if (op == EOpDiv) - { - tempConstArray[i].setUConst( - unionArray[i].getUConst() / - rightUnionArray[i].getUConst()); - } - else - { - ASSERT(op == EOpIMod); - tempConstArray[i].setUConst( - unionArray[i].getUConst() % - rightUnionArray[i].getUConst()); - } + ASSERT(op == EOpIMod); + resultArray[i].setUConst(leftArray[i].getUConst() % rightArray[i].getUConst()); } - break; - - default: - infoSink.info.message( - EPrefixInternalError, getLine(), - "Constant folding cannot be done for \"/\""); - return nullptr; } + break; + + default: + infoSink.info.message(EPrefixInternalError, getLine(), + "Constant folding cannot be done for \"/\""); + return nullptr; } } - break; + } + break; - case EOpMatrixTimesVector: + case EOpMatrixTimesVector: + { + if (rightNode->getBasicType() != EbtFloat) { - if (rightNode->getBasicType() != EbtFloat) - { - infoSink.info.message( - EPrefixInternalError, getLine(), - "Constant Folding cannot be done for matrix times vector"); - return nullptr; - } + infoSink.info.message(EPrefixInternalError, getLine(), + "Constant Folding cannot be done for matrix times vector"); + return nullptr; + } - const int matrixCols = getCols(); - const int matrixRows = getRows(); + const int matrixCols = getCols(); + const int matrixRows = getRows(); - tempConstArray = new TConstantUnion[matrixRows]; + resultArray = new TConstantUnion[matrixRows]; - for (int matrixRow = 0; matrixRow < matrixRows; matrixRow++) + for (int matrixRow = 0; matrixRow < matrixRows; matrixRow++) + { + resultArray[matrixRow].setFConst(0.0f); + for (int col = 0; col < matrixCols; col++) { - tempConstArray[matrixRow].setFConst(0.0f); - for (int col = 0; col < matrixCols; col++) - { - tempConstArray[matrixRow].setFConst( - tempConstArray[matrixRow].getFConst() + - unionArray[col * matrixRows + matrixRow].getFConst() * - rightUnionArray[col].getFConst()); - } + resultArray[matrixRow].setFConst(resultArray[matrixRow].getFConst() + + leftArray[col * matrixRows + matrixRow].getFConst() * + rightArray[col].getFConst()); } + } + } + break; - returnType = rightNode->getType(); - returnType.setPrimarySize(static_cast(matrixRows)); + case EOpVectorTimesMatrix: + { + if (getType().getBasicType() != EbtFloat) + { + infoSink.info.message(EPrefixInternalError, getLine(), + "Constant Folding cannot be done for vector times matrix"); + return nullptr; + } - tempNode = new TIntermConstantUnion(tempConstArray, returnType); - tempNode->setLine(getLine()); + const int matrixCols = rightNode->getType().getCols(); + const int matrixRows = rightNode->getType().getRows(); - return tempNode; - } + resultArray = new TConstantUnion[matrixCols]; - case EOpVectorTimesMatrix: + for (int matrixCol = 0; matrixCol < matrixCols; matrixCol++) { - if (getType().getBasicType() != EbtFloat) + resultArray[matrixCol].setFConst(0.0f); + for (int matrixRow = 0; matrixRow < matrixRows; matrixRow++) { - infoSink.info.message( - EPrefixInternalError, getLine(), - "Constant Folding cannot be done for vector times matrix"); - return nullptr; + resultArray[matrixCol].setFConst(resultArray[matrixCol].getFConst() + + leftArray[matrixRow].getFConst() * + rightArray[matrixCol * matrixRows + matrixRow].getFConst()); } + } + } + break; + + case EOpLogicalAnd: + { + resultArray = new TConstantUnion[objectSize]; + for (size_t i = 0; i < objectSize; i++) + { + resultArray[i] = leftArray[i] && rightArray[i]; + } + } + break; + + case EOpLogicalOr: + { + resultArray = new TConstantUnion[objectSize]; + for (size_t i = 0; i < objectSize; i++) + { + resultArray[i] = leftArray[i] || rightArray[i]; + } + } + break; + + case EOpLogicalXor: + { + resultArray = new TConstantUnion[objectSize]; + for (size_t i = 0; i < objectSize; i++) + { + switch (getType().getBasicType()) + { + case EbtBool: + resultArray[i].setBConst(leftArray[i] != rightArray[i]); + break; + default: + UNREACHABLE(); + break; + } + } + } + break; + + case EOpBitwiseAnd: + resultArray = new TConstantUnion[objectSize]; + for (size_t i = 0; i < objectSize; i++) + resultArray[i] = leftArray[i] & rightArray[i]; + break; + case EOpBitwiseXor: + resultArray = new TConstantUnion[objectSize]; + for (size_t i = 0; i < objectSize; i++) + resultArray[i] = leftArray[i] ^ rightArray[i]; + break; + case EOpBitwiseOr: + resultArray = new TConstantUnion[objectSize]; + for (size_t i = 0; i < objectSize; i++) + resultArray[i] = leftArray[i] | rightArray[i]; + break; + case EOpBitShiftLeft: + resultArray = new TConstantUnion[objectSize]; + for (size_t i = 0; i < objectSize; i++) + resultArray[i] = leftArray[i] << rightArray[i]; + break; + case EOpBitShiftRight: + resultArray = new TConstantUnion[objectSize]; + for (size_t i = 0; i < objectSize; i++) + resultArray[i] = leftArray[i] >> rightArray[i]; + break; + + case EOpLessThan: + ASSERT(objectSize == 1); + resultArray = new TConstantUnion[1]; + resultArray->setBConst(*leftArray < *rightArray); + break; + + case EOpGreaterThan: + ASSERT(objectSize == 1); + resultArray = new TConstantUnion[1]; + resultArray->setBConst(*leftArray > *rightArray); + break; + + case EOpLessThanEqual: + ASSERT(objectSize == 1); + resultArray = new TConstantUnion[1]; + resultArray->setBConst(!(*leftArray > *rightArray)); + break; + + case EOpGreaterThanEqual: + ASSERT(objectSize == 1); + resultArray = new TConstantUnion[1]; + resultArray->setBConst(!(*leftArray < *rightArray)); + break; + + case EOpEqual: + case EOpNotEqual: + { + resultArray = new TConstantUnion[1]; + bool equal = true; + for (size_t i = 0; i < objectSize; i++) + { + if (leftArray[i] != rightArray[i]) + { + equal = false; + break; // break out of for loop + } + } + if (op == EOpEqual) + { + resultArray->setBConst(equal); + } + else + { + resultArray->setBConst(!equal); + } + } + break; + + default: + infoSink.info.message( + EPrefixInternalError, getLine(), + "Invalid operator for constant folding"); + return nullptr; + } + return resultArray; +} + +// +// The fold functions see if an operation on a constant can be done in place, +// without generating run-time code. +// +// Returns the constant value to keep using or nullptr. +// +TConstantUnion *TIntermConstantUnion::foldUnaryWithDifferentReturnType(TOperator op, TInfoSink &infoSink) +{ + // + // Do operations where the return type has a different number of components compared to the operand type. + // + + const TConstantUnion *operandArray = getUnionArrayPointer(); + if (!operandArray) + return nullptr; + + size_t objectSize = getType().getObjectSize(); + TConstantUnion *resultArray = nullptr; + switch (op) + { + case EOpAny: + if (getType().getBasicType() == EbtBool) + { + resultArray = new TConstantUnion(); + resultArray->setBConst(false); + for (size_t i = 0; i < objectSize; i++) + { + if (operandArray[i].getBConst()) + { + resultArray->setBConst(true); + break; + } + } + break; + } + else + { + infoSink.info.message(EPrefixInternalError, getLine(), "Unary operation not folded into constant"); + return nullptr; + } + + case EOpAll: + if (getType().getBasicType() == EbtBool) + { + resultArray = new TConstantUnion(); + resultArray->setBConst(true); + for (size_t i = 0; i < objectSize; i++) + { + if (!operandArray[i].getBConst()) + { + resultArray->setBConst(false); + break; + } + } + break; + } + else + { + infoSink.info.message(EPrefixInternalError, getLine(), "Unary operation not folded into constant"); + return nullptr; + } + + case EOpLength: + if (getType().getBasicType() == EbtFloat) + { + resultArray = new TConstantUnion(); + resultArray->setFConst(VectorLength(operandArray, objectSize)); + break; + } + else + { + infoSink.info.message(EPrefixInternalError, getLine(), "Unary operation not folded into constant"); + return nullptr; + } + + case EOpTranspose: + if (getType().getBasicType() == EbtFloat) + { + resultArray = new TConstantUnion[objectSize]; + angle::Matrix result = + GetMatrix(operandArray, getType().getNominalSize(), getType().getSecondarySize()).transpose(); + SetUnionArrayFromMatrix(result, resultArray); + break; + } + else + { + infoSink.info.message(EPrefixInternalError, getLine(), "Unary operation not folded into constant"); + return nullptr; + } + + case EOpDeterminant: + if (getType().getBasicType() == EbtFloat) + { + unsigned int size = getType().getNominalSize(); + ASSERT(size >= 2 && size <= 4); + resultArray = new TConstantUnion(); + resultArray->setFConst(GetMatrix(operandArray, size).determinant()); + break; + } + else + { + infoSink.info.message(EPrefixInternalError, getLine(), "Unary operation not folded into constant"); + return nullptr; + } + + case EOpInverse: + if (getType().getBasicType() == EbtFloat) + { + unsigned int size = getType().getNominalSize(); + ASSERT(size >= 2 && size <= 4); + resultArray = new TConstantUnion[objectSize]; + angle::Matrix result = GetMatrix(operandArray, size).inverse(); + SetUnionArrayFromMatrix(result, resultArray); + break; + } + else + { + infoSink.info.message(EPrefixInternalError, getLine(), "Unary operation not folded into constant"); + return nullptr; + } + + case EOpPackSnorm2x16: + if (getType().getBasicType() == EbtFloat) + { + ASSERT(getType().getNominalSize() == 2); + resultArray = new TConstantUnion(); + resultArray->setUConst(gl::packSnorm2x16(operandArray[0].getFConst(), operandArray[1].getFConst())); + break; + } + else + { + infoSink.info.message(EPrefixInternalError, getLine(), "Unary operation not folded into constant"); + return nullptr; + } + + case EOpUnpackSnorm2x16: + if (getType().getBasicType() == EbtUInt) + { + resultArray = new TConstantUnion[2]; + float f1, f2; + gl::unpackSnorm2x16(operandArray[0].getUConst(), &f1, &f2); + resultArray[0].setFConst(f1); + resultArray[1].setFConst(f2); + break; + } + else + { + infoSink.info.message(EPrefixInternalError, getLine(), "Unary operation not folded into constant"); + return nullptr; + } + + case EOpPackUnorm2x16: + if (getType().getBasicType() == EbtFloat) + { + ASSERT(getType().getNominalSize() == 2); + resultArray = new TConstantUnion(); + resultArray->setUConst(gl::packUnorm2x16(operandArray[0].getFConst(), operandArray[1].getFConst())); + break; + } + else + { + infoSink.info.message(EPrefixInternalError, getLine(), "Unary operation not folded into constant"); + return nullptr; + } + + case EOpUnpackUnorm2x16: + if (getType().getBasicType() == EbtUInt) + { + resultArray = new TConstantUnion[2]; + float f1, f2; + gl::unpackUnorm2x16(operandArray[0].getUConst(), &f1, &f2); + resultArray[0].setFConst(f1); + resultArray[1].setFConst(f2); + break; + } + else + { + infoSink.info.message(EPrefixInternalError, getLine(), "Unary operation not folded into constant"); + return nullptr; + } + + case EOpPackHalf2x16: + if (getType().getBasicType() == EbtFloat) + { + ASSERT(getType().getNominalSize() == 2); + resultArray = new TConstantUnion(); + resultArray->setUConst(gl::packHalf2x16(operandArray[0].getFConst(), operandArray[1].getFConst())); + break; + } + else + { + infoSink.info.message(EPrefixInternalError, getLine(), "Unary operation not folded into constant"); + return nullptr; + } + + case EOpUnpackHalf2x16: + if (getType().getBasicType() == EbtUInt) + { + resultArray = new TConstantUnion[2]; + float f1, f2; + gl::unpackHalf2x16(operandArray[0].getUConst(), &f1, &f2); + resultArray[0].setFConst(f1); + resultArray[1].setFConst(f2); + break; + } + else + { + infoSink.info.message(EPrefixInternalError, getLine(), "Unary operation not folded into constant"); + return nullptr; + } + break; + + default: + break; + } + + return resultArray; +} + +TConstantUnion *TIntermConstantUnion::foldUnaryWithSameReturnType(TOperator op, TInfoSink &infoSink) +{ + // + // Do unary operations where the return type is the same as operand type. + // + + const TConstantUnion *operandArray = getUnionArrayPointer(); + if (!operandArray) + return nullptr; + + size_t objectSize = getType().getObjectSize(); + + TConstantUnion *resultArray = new TConstantUnion[objectSize]; + for (size_t i = 0; i < objectSize; i++) + { + switch(op) + { + case EOpNegative: + switch (getType().getBasicType()) + { + case EbtFloat: + resultArray[i].setFConst(-operandArray[i].getFConst()); + break; + case EbtInt: + resultArray[i].setIConst(-operandArray[i].getIConst()); + break; + case EbtUInt: + resultArray[i].setUConst(static_cast( + -static_cast(operandArray[i].getUConst()))); + break; + default: + infoSink.info.message( + EPrefixInternalError, getLine(), + "Unary operation not folded into constant"); + return nullptr; + } + break; + + case EOpPositive: + switch (getType().getBasicType()) + { + case EbtFloat: + resultArray[i].setFConst(operandArray[i].getFConst()); + break; + case EbtInt: + resultArray[i].setIConst(operandArray[i].getIConst()); + break; + case EbtUInt: + resultArray[i].setUConst(static_cast( + static_cast(operandArray[i].getUConst()))); + break; + default: + infoSink.info.message( + EPrefixInternalError, getLine(), + "Unary operation not folded into constant"); + return nullptr; + } + break; + + case EOpLogicalNot: + // this code is written for possible future use, + // will not get executed currently + switch (getType().getBasicType()) + { + case EbtBool: + resultArray[i].setBConst(!operandArray[i].getBConst()); + break; + default: + infoSink.info.message( + EPrefixInternalError, getLine(), + "Unary operation not folded into constant"); + return nullptr; + } + break; + + case EOpBitwiseNot: + switch (getType().getBasicType()) + { + case EbtInt: + resultArray[i].setIConst(~operandArray[i].getIConst()); + break; + case EbtUInt: + resultArray[i].setUConst(~operandArray[i].getUConst()); + break; + default: + infoSink.info.message( + EPrefixInternalError, getLine(), + "Unary operation not folded into constant"); + return nullptr; + } + break; + + case EOpRadians: + if (getType().getBasicType() == EbtFloat) + { + resultArray[i].setFConst(kDegreesToRadiansMultiplier * operandArray[i].getFConst()); + break; + } + infoSink.info.message( + EPrefixInternalError, getLine(), + "Unary operation not folded into constant"); + return nullptr; + + case EOpDegrees: + if (getType().getBasicType() == EbtFloat) + { + resultArray[i].setFConst(kRadiansToDegreesMultiplier * operandArray[i].getFConst()); + break; + } + infoSink.info.message( + EPrefixInternalError, getLine(), + "Unary operation not folded into constant"); + return nullptr; + + case EOpSin: + if (!foldFloatTypeUnary(operandArray[i], &sinf, infoSink, &resultArray[i])) + return nullptr; + break; + + case EOpCos: + if (!foldFloatTypeUnary(operandArray[i], &cosf, infoSink, &resultArray[i])) + return nullptr; + break; + + case EOpTan: + if (!foldFloatTypeUnary(operandArray[i], &tanf, infoSink, &resultArray[i])) + return nullptr; + break; + + case EOpAsin: + // For asin(x), results are undefined if |x| > 1, we are choosing to set result to 0. + if (getType().getBasicType() == EbtFloat && fabsf(operandArray[i].getFConst()) > 1.0f) + UndefinedConstantFoldingError(getLine(), op, getType().getBasicType(), infoSink, &resultArray[i]); + else if (!foldFloatTypeUnary(operandArray[i], &asinf, infoSink, &resultArray[i])) + return nullptr; + break; + + case EOpAcos: + // For acos(x), results are undefined if |x| > 1, we are choosing to set result to 0. + if (getType().getBasicType() == EbtFloat && fabsf(operandArray[i].getFConst()) > 1.0f) + UndefinedConstantFoldingError(getLine(), op, getType().getBasicType(), infoSink, &resultArray[i]); + else if (!foldFloatTypeUnary(operandArray[i], &acosf, infoSink, &resultArray[i])) + return nullptr; + break; + + case EOpAtan: + if (!foldFloatTypeUnary(operandArray[i], &atanf, infoSink, &resultArray[i])) + return nullptr; + break; + + case EOpSinh: + if (!foldFloatTypeUnary(operandArray[i], &sinhf, infoSink, &resultArray[i])) + return nullptr; + break; + + case EOpCosh: + if (!foldFloatTypeUnary(operandArray[i], &coshf, infoSink, &resultArray[i])) + return nullptr; + break; + + case EOpTanh: + if (!foldFloatTypeUnary(operandArray[i], &tanhf, infoSink, &resultArray[i])) + return nullptr; + break; + + case EOpAsinh: + if (!foldFloatTypeUnary(operandArray[i], &asinhf, infoSink, &resultArray[i])) + return nullptr; + break; + + case EOpAcosh: + // For acosh(x), results are undefined if x < 1, we are choosing to set result to 0. + if (getType().getBasicType() == EbtFloat && operandArray[i].getFConst() < 1.0f) + UndefinedConstantFoldingError(getLine(), op, getType().getBasicType(), infoSink, &resultArray[i]); + else if (!foldFloatTypeUnary(operandArray[i], &acoshf, infoSink, &resultArray[i])) + return nullptr; + break; + + case EOpAtanh: + // For atanh(x), results are undefined if |x| >= 1, we are choosing to set result to 0. + if (getType().getBasicType() == EbtFloat && fabsf(operandArray[i].getFConst()) >= 1.0f) + UndefinedConstantFoldingError(getLine(), op, getType().getBasicType(), infoSink, &resultArray[i]); + else if (!foldFloatTypeUnary(operandArray[i], &atanhf, infoSink, &resultArray[i])) + return nullptr; + break; + + case EOpAbs: + switch (getType().getBasicType()) + { + case EbtFloat: + resultArray[i].setFConst(fabsf(operandArray[i].getFConst())); + break; + case EbtInt: + resultArray[i].setIConst(abs(operandArray[i].getIConst())); + break; + default: + infoSink.info.message( + EPrefixInternalError, getLine(), + "Unary operation not folded into constant"); + return nullptr; + } + break; + + case EOpSign: + switch (getType().getBasicType()) + { + case EbtFloat: + { + float fConst = operandArray[i].getFConst(); + float fResult = 0.0f; + if (fConst > 0.0f) + fResult = 1.0f; + else if (fConst < 0.0f) + fResult = -1.0f; + resultArray[i].setFConst(fResult); + } + break; + case EbtInt: + { + int iConst = operandArray[i].getIConst(); + int iResult = 0; + if (iConst > 0) + iResult = 1; + else if (iConst < 0) + iResult = -1; + resultArray[i].setIConst(iResult); + } + break; + default: + infoSink.info.message( + EPrefixInternalError, getLine(), + "Unary operation not folded into constant"); + return nullptr; + } + break; + + case EOpFloor: + if (!foldFloatTypeUnary(operandArray[i], &floorf, infoSink, &resultArray[i])) + return nullptr; + break; + + case EOpTrunc: + if (!foldFloatTypeUnary(operandArray[i], &truncf, infoSink, &resultArray[i])) + return nullptr; + break; + + case EOpRound: + if (!foldFloatTypeUnary(operandArray[i], &roundf, infoSink, &resultArray[i])) + return nullptr; + break; + + case EOpRoundEven: + if (getType().getBasicType() == EbtFloat) + { + float x = operandArray[i].getFConst(); + float result; + float fractPart = modff(x, &result); + if (fabsf(fractPart) == 0.5f) + result = 2.0f * roundf(x / 2.0f); + else + result = roundf(x); + resultArray[i].setFConst(result); + break; + } + infoSink.info.message( + EPrefixInternalError, getLine(), + "Unary operation not folded into constant"); + return nullptr; + + case EOpCeil: + if (!foldFloatTypeUnary(operandArray[i], &ceilf, infoSink, &resultArray[i])) + return nullptr; + break; + + case EOpFract: + if (getType().getBasicType() == EbtFloat) + { + float x = operandArray[i].getFConst(); + resultArray[i].setFConst(x - floorf(x)); + break; + } + infoSink.info.message( + EPrefixInternalError, getLine(), + "Unary operation not folded into constant"); + return nullptr; + + case EOpIsNan: + if (getType().getBasicType() == EbtFloat) + { + resultArray[i].setBConst(gl::isNaN(operandArray[0].getFConst())); + break; + } + infoSink.info.message(EPrefixInternalError, getLine(), "Unary operation not folded into constant"); + return nullptr; + + case EOpIsInf: + if (getType().getBasicType() == EbtFloat) + { + resultArray[i].setBConst(gl::isInf(operandArray[0].getFConst())); + break; + } + infoSink.info.message(EPrefixInternalError, getLine(), "Unary operation not folded into constant"); + return nullptr; + + case EOpFloatBitsToInt: + if (getType().getBasicType() == EbtFloat) + { + resultArray[i].setIConst(gl::bitCast(operandArray[0].getFConst())); + break; + } + infoSink.info.message(EPrefixInternalError, getLine(), "Unary operation not folded into constant"); + return nullptr; + + case EOpFloatBitsToUint: + if (getType().getBasicType() == EbtFloat) + { + resultArray[i].setUConst(gl::bitCast(operandArray[0].getFConst())); + break; + } + infoSink.info.message(EPrefixInternalError, getLine(), "Unary operation not folded into constant"); + return nullptr; + + case EOpIntBitsToFloat: + if (getType().getBasicType() == EbtInt) + { + resultArray[i].setFConst(gl::bitCast(operandArray[0].getIConst())); + break; + } + infoSink.info.message(EPrefixInternalError, getLine(), "Unary operation not folded into constant"); + return nullptr; + + case EOpUintBitsToFloat: + if (getType().getBasicType() == EbtUInt) + { + resultArray[i].setFConst(gl::bitCast(operandArray[0].getUConst())); + break; + } + infoSink.info.message(EPrefixInternalError, getLine(), "Unary operation not folded into constant"); + return nullptr; + + case EOpExp: + if (!foldFloatTypeUnary(operandArray[i], &expf, infoSink, &resultArray[i])) + return nullptr; + break; + + case EOpLog: + // For log(x), results are undefined if x <= 0, we are choosing to set result to 0. + if (getType().getBasicType() == EbtFloat && operandArray[i].getFConst() <= 0.0f) + UndefinedConstantFoldingError(getLine(), op, getType().getBasicType(), infoSink, &resultArray[i]); + else if (!foldFloatTypeUnary(operandArray[i], &logf, infoSink, &resultArray[i])) + return nullptr; + break; + + case EOpExp2: + if (!foldFloatTypeUnary(operandArray[i], &exp2f, infoSink, &resultArray[i])) + return nullptr; + break; + + case EOpLog2: + // For log2(x), results are undefined if x <= 0, we are choosing to set result to 0. + // And log2f is not available on some plarforms like old android, so just using log(x)/log(2) here. + if (getType().getBasicType() == EbtFloat && operandArray[i].getFConst() <= 0.0f) + UndefinedConstantFoldingError(getLine(), op, getType().getBasicType(), infoSink, &resultArray[i]); + else if (!foldFloatTypeUnary(operandArray[i], &logf, infoSink, &resultArray[i])) + return nullptr; + else + resultArray[i].setFConst(resultArray[i].getFConst() / logf(2.0f)); + break; + + case EOpSqrt: + // For sqrt(x), results are undefined if x < 0, we are choosing to set result to 0. + if (getType().getBasicType() == EbtFloat && operandArray[i].getFConst() < 0.0f) + UndefinedConstantFoldingError(getLine(), op, getType().getBasicType(), infoSink, &resultArray[i]); + else if (!foldFloatTypeUnary(operandArray[i], &sqrtf, infoSink, &resultArray[i])) + return nullptr; + break; - const int matrixCols = rightNode->getType().getCols(); - const int matrixRows = rightNode->getType().getRows(); - - tempConstArray = new TConstantUnion[matrixCols]; - - for (int matrixCol = 0; matrixCol < matrixCols; matrixCol++) + case EOpInverseSqrt: + // There is no stdlib built-in function equavalent for GLES built-in inversesqrt(), + // so getting the square root first using builtin function sqrt() and then taking its inverse. + // Also, for inversesqrt(x), results are undefined if x <= 0, we are choosing to set result to 0. + if (getType().getBasicType() == EbtFloat && operandArray[i].getFConst() <= 0.0f) + UndefinedConstantFoldingError(getLine(), op, getType().getBasicType(), infoSink, &resultArray[i]); + else if (!foldFloatTypeUnary(operandArray[i], &sqrtf, infoSink, &resultArray[i])) + return nullptr; + else + resultArray[i].setFConst(1.0f / resultArray[i].getFConst()); + break; + + case EOpVectorLogicalNot: + if (getType().getBasicType() == EbtBool) + { + resultArray[i].setBConst(!operandArray[i].getBConst()); + break; + } + infoSink.info.message( + EPrefixInternalError, getLine(), + "Unary operation not folded into constant"); + return nullptr; + + case EOpNormalize: + if (getType().getBasicType() == EbtFloat) + { + float x = operandArray[i].getFConst(); + float length = VectorLength(operandArray, objectSize); + if (length) + resultArray[i].setFConst(x / length); + else + UndefinedConstantFoldingError(getLine(), op, getType().getBasicType(), infoSink, + &resultArray[i]); + break; + } + infoSink.info.message(EPrefixInternalError, getLine(), "Unary operation not folded into constant"); + return nullptr; + + case EOpDFdx: + case EOpDFdy: + case EOpFwidth: + if (getType().getBasicType() == EbtFloat) + { + // Derivatives of constant arguments should be 0. + resultArray[i].setFConst(0.0f); + break; + } + infoSink.info.message(EPrefixInternalError, getLine(), "Unary operation not folded into constant"); + return nullptr; + + default: + return nullptr; + } + } + + return resultArray; +} + +bool TIntermConstantUnion::foldFloatTypeUnary(const TConstantUnion ¶meter, FloatTypeUnaryFunc builtinFunc, + TInfoSink &infoSink, TConstantUnion *result) const +{ + ASSERT(builtinFunc); + + if (getType().getBasicType() == EbtFloat) + { + result->setFConst(builtinFunc(parameter.getFConst())); + return true; + } + + infoSink.info.message( + EPrefixInternalError, getLine(), + "Unary operation not folded into constant"); + return false; +} + +// static +TConstantUnion *TIntermConstantUnion::FoldAggregateConstructor(TIntermAggregate *aggregate, + TInfoSink &infoSink) +{ + ASSERT(aggregate->getSequence()->size() > 0u); + size_t resultSize = aggregate->getType().getObjectSize(); + TConstantUnion *resultArray = new TConstantUnion[resultSize]; + TBasicType basicType = aggregate->getBasicType(); + + size_t resultIndex = 0u; + + if (aggregate->getSequence()->size() == 1u) + { + TIntermNode *argument = aggregate->getSequence()->front(); + TIntermConstantUnion *argumentConstant = argument->getAsConstantUnion(); + const TConstantUnion *argumentUnionArray = argumentConstant->getUnionArrayPointer(); + // Check the special case of constructing a matrix diagonal from a single scalar, + // or a vector from a single scalar. + if (argumentConstant->getType().getObjectSize() == 1u) + { + if (aggregate->isMatrix()) + { + int resultCols = aggregate->getType().getCols(); + int resultRows = aggregate->getType().getRows(); + for (int col = 0; col < resultCols; ++col) + { + for (int row = 0; row < resultRows; ++row) + { + if (col == row) + { + resultArray[resultIndex].cast(basicType, argumentUnionArray[0]); + } + else + { + resultArray[resultIndex].setFConst(0.0f); + } + ++resultIndex; + } + } + } + else + { + while (resultIndex < resultSize) + { + resultArray[resultIndex].cast(basicType, argumentUnionArray[0]); + ++resultIndex; + } + } + ASSERT(resultIndex == resultSize); + return resultArray; + } + else if (aggregate->isMatrix() && argumentConstant->isMatrix()) + { + // The special case of constructing a matrix from a matrix. + int argumentCols = argumentConstant->getType().getCols(); + int argumentRows = argumentConstant->getType().getRows(); + int resultCols = aggregate->getType().getCols(); + int resultRows = aggregate->getType().getRows(); + for (int col = 0; col < resultCols; ++col) + { + for (int row = 0; row < resultRows; ++row) { - tempConstArray[matrixCol].setFConst(0.0f); - for (int matrixRow = 0; matrixRow < matrixRows; matrixRow++) + if (col < argumentCols && row < argumentRows) + { + resultArray[resultIndex].cast(basicType, + argumentUnionArray[col * argumentRows + row]); + } + else if (col == row) + { + resultArray[resultIndex].setFConst(1.0f); + } + else { - tempConstArray[matrixCol].setFConst( - tempConstArray[matrixCol].getFConst() + - unionArray[matrixRow].getFConst() * - rightUnionArray[matrixCol * matrixRows + matrixRow].getFConst()); + resultArray[resultIndex].setFConst(0.0f); } + ++resultIndex; } + } + ASSERT(resultIndex == resultSize); + return resultArray; + } + } + + for (TIntermNode *&argument : *aggregate->getSequence()) + { + TIntermConstantUnion *argumentConstant = argument->getAsConstantUnion(); + size_t argumentSize = argumentConstant->getType().getObjectSize(); + const TConstantUnion *argumentUnionArray = argumentConstant->getUnionArrayPointer(); + for (size_t i = 0u; i < argumentSize; ++i) + { + if (resultIndex >= resultSize) + break; + resultArray[resultIndex].cast(basicType, argumentUnionArray[i]); + ++resultIndex; + } + } + ASSERT(resultIndex == resultSize); + return resultArray; +} + +// static +TConstantUnion *TIntermConstantUnion::FoldAggregateBuiltIn(TIntermAggregate *aggregate, TInfoSink &infoSink) +{ + TOperator op = aggregate->getOp(); + TIntermSequence *sequence = aggregate->getSequence(); + unsigned int paramsCount = static_cast(sequence->size()); + std::vector unionArrays(paramsCount); + std::vector objectSizes(paramsCount); + size_t maxObjectSize = 0; + TBasicType basicType = EbtVoid; + TSourceLoc loc; + for (unsigned int i = 0; i < paramsCount; i++) + { + TIntermConstantUnion *paramConstant = (*sequence)[i]->getAsConstantUnion(); + ASSERT(paramConstant != nullptr); // Should be checked already. + + if (i == 0) + { + basicType = paramConstant->getType().getBasicType(); + loc = paramConstant->getLine(); + } + unionArrays[i] = paramConstant->getUnionArrayPointer(); + objectSizes[i] = paramConstant->getType().getObjectSize(); + if (objectSizes[i] > maxObjectSize) + maxObjectSize = objectSizes[i]; + } + + if (!(*sequence)[0]->getAsTyped()->isMatrix()) + { + for (unsigned int i = 0; i < paramsCount; i++) + if (objectSizes[i] != maxObjectSize) + unionArrays[i] = Vectorize(*unionArrays[i], maxObjectSize); + } - returnType.setPrimarySize(static_cast(matrixCols)); + TConstantUnion *resultArray = nullptr; + if (paramsCount == 2) + { + // + // Binary built-in + // + switch (op) + { + case EOpAtan: + { + if (basicType == EbtFloat) + { + resultArray = new TConstantUnion[maxObjectSize]; + for (size_t i = 0; i < maxObjectSize; i++) + { + float y = unionArrays[0][i].getFConst(); + float x = unionArrays[1][i].getFConst(); + // Results are undefined if x and y are both 0. + if (x == 0.0f && y == 0.0f) + UndefinedConstantFoldingError(loc, op, basicType, infoSink, &resultArray[i]); + else + resultArray[i].setFConst(atan2f(y, x)); + } + } + else + UNREACHABLE(); } break; - case EOpLogicalAnd: - // this code is written for possible future use, - // will not get executed currently + case EOpPow: { - tempConstArray = new TConstantUnion[objectSize]; - for (size_t i = 0; i < objectSize; i++) + if (basicType == EbtFloat) { - tempConstArray[i] = unionArray[i] && rightUnionArray[i]; + resultArray = new TConstantUnion[maxObjectSize]; + for (size_t i = 0; i < maxObjectSize; i++) + { + float x = unionArrays[0][i].getFConst(); + float y = unionArrays[1][i].getFConst(); + // Results are undefined if x < 0. + // Results are undefined if x = 0 and y <= 0. + if (x < 0.0f) + UndefinedConstantFoldingError(loc, op, basicType, infoSink, &resultArray[i]); + else if (x == 0.0f && y <= 0.0f) + UndefinedConstantFoldingError(loc, op, basicType, infoSink, &resultArray[i]); + else + resultArray[i].setFConst(powf(x, y)); + } } + else + UNREACHABLE(); } break; - case EOpLogicalOr: - // this code is written for possible future use, - // will not get executed currently + case EOpMod: { - tempConstArray = new TConstantUnion[objectSize]; - for (size_t i = 0; i < objectSize; i++) + if (basicType == EbtFloat) { - tempConstArray[i] = unionArray[i] || rightUnionArray[i]; + resultArray = new TConstantUnion[maxObjectSize]; + for (size_t i = 0; i < maxObjectSize; i++) + { + float x = unionArrays[0][i].getFConst(); + float y = unionArrays[1][i].getFConst(); + resultArray[i].setFConst(x - y * floorf(x / y)); + } } + else + UNREACHABLE(); } break; - case EOpLogicalXor: + case EOpMin: { - tempConstArray = new TConstantUnion[objectSize]; - for (size_t i = 0; i < objectSize; i++) + resultArray = new TConstantUnion[maxObjectSize]; + for (size_t i = 0; i < maxObjectSize; i++) { - switch (getType().getBasicType()) + switch (basicType) { - case EbtBool: - tempConstArray[i].setBConst( - unionArray[i] == rightUnionArray[i] ? false : true); + case EbtFloat: + resultArray[i].setFConst(std::min(unionArrays[0][i].getFConst(), unionArrays[1][i].getFConst())); + break; + case EbtInt: + resultArray[i].setIConst(std::min(unionArrays[0][i].getIConst(), unionArrays[1][i].getIConst())); + break; + case EbtUInt: + resultArray[i].setUConst(std::min(unionArrays[0][i].getUConst(), unionArrays[1][i].getUConst())); break; default: UNREACHABLE(); @@ -969,509 +2129,467 @@ TIntermTyped *TIntermConstantUnion::fold( } break; - case EOpBitwiseAnd: - tempConstArray = new TConstantUnion[objectSize]; - for (size_t i = 0; i < objectSize; i++) - tempConstArray[i] = unionArray[i] & rightUnionArray[i]; - break; - case EOpBitwiseXor: - tempConstArray = new TConstantUnion[objectSize]; - for (size_t i = 0; i < objectSize; i++) - tempConstArray[i] = unionArray[i] ^ rightUnionArray[i]; - break; - case EOpBitwiseOr: - tempConstArray = new TConstantUnion[objectSize]; - for (size_t i = 0; i < objectSize; i++) - tempConstArray[i] = unionArray[i] | rightUnionArray[i]; - break; - case EOpBitShiftLeft: - tempConstArray = new TConstantUnion[objectSize]; - for (size_t i = 0; i < objectSize; i++) - tempConstArray[i] = unionArray[i] << rightUnionArray[i]; + case EOpMax: + { + resultArray = new TConstantUnion[maxObjectSize]; + for (size_t i = 0; i < maxObjectSize; i++) + { + switch (basicType) + { + case EbtFloat: + resultArray[i].setFConst(std::max(unionArrays[0][i].getFConst(), unionArrays[1][i].getFConst())); + break; + case EbtInt: + resultArray[i].setIConst(std::max(unionArrays[0][i].getIConst(), unionArrays[1][i].getIConst())); + break; + case EbtUInt: + resultArray[i].setUConst(std::max(unionArrays[0][i].getUConst(), unionArrays[1][i].getUConst())); + break; + default: + UNREACHABLE(); + break; + } + } + } break; - case EOpBitShiftRight: - tempConstArray = new TConstantUnion[objectSize]; - for (size_t i = 0; i < objectSize; i++) - tempConstArray[i] = unionArray[i] >> rightUnionArray[i]; + + case EOpStep: + { + if (basicType == EbtFloat) + { + resultArray = new TConstantUnion[maxObjectSize]; + for (size_t i = 0; i < maxObjectSize; i++) + resultArray[i].setFConst(unionArrays[1][i].getFConst() < unionArrays[0][i].getFConst() ? 0.0f : 1.0f); + } + else + UNREACHABLE(); + } break; case EOpLessThan: - ASSERT(objectSize == 1); - tempConstArray = new TConstantUnion[1]; - tempConstArray->setBConst(*unionArray < *rightUnionArray); - returnType = TType(EbtBool, EbpUndefined, EvqConst); + { + resultArray = new TConstantUnion[maxObjectSize]; + for (size_t i = 0; i < maxObjectSize; i++) + { + switch (basicType) + { + case EbtFloat: + resultArray[i].setBConst(unionArrays[0][i].getFConst() < unionArrays[1][i].getFConst()); + break; + case EbtInt: + resultArray[i].setBConst(unionArrays[0][i].getIConst() < unionArrays[1][i].getIConst()); + break; + case EbtUInt: + resultArray[i].setBConst(unionArrays[0][i].getUConst() < unionArrays[1][i].getUConst()); + break; + default: + UNREACHABLE(); + break; + } + } + } break; - case EOpGreaterThan: - ASSERT(objectSize == 1); - tempConstArray = new TConstantUnion[1]; - tempConstArray->setBConst(*unionArray > *rightUnionArray); - returnType = TType(EbtBool, EbpUndefined, EvqConst); + case EOpLessThanEqual: + { + resultArray = new TConstantUnion[maxObjectSize]; + for (size_t i = 0; i < maxObjectSize; i++) + { + switch (basicType) + { + case EbtFloat: + resultArray[i].setBConst(unionArrays[0][i].getFConst() <= unionArrays[1][i].getFConst()); + break; + case EbtInt: + resultArray[i].setBConst(unionArrays[0][i].getIConst() <= unionArrays[1][i].getIConst()); + break; + case EbtUInt: + resultArray[i].setBConst(unionArrays[0][i].getUConst() <= unionArrays[1][i].getUConst()); + break; + default: + UNREACHABLE(); + break; + } + } + } break; - case EOpLessThanEqual: + case EOpGreaterThan: { - ASSERT(objectSize == 1); - TConstantUnion constant; - constant.setBConst(*unionArray > *rightUnionArray); - tempConstArray = new TConstantUnion[1]; - tempConstArray->setBConst(!constant.getBConst()); - returnType = TType(EbtBool, EbpUndefined, EvqConst); - break; + resultArray = new TConstantUnion[maxObjectSize]; + for (size_t i = 0; i < maxObjectSize; i++) + { + switch (basicType) + { + case EbtFloat: + resultArray[i].setBConst(unionArrays[0][i].getFConst() > unionArrays[1][i].getFConst()); + break; + case EbtInt: + resultArray[i].setBConst(unionArrays[0][i].getIConst() > unionArrays[1][i].getIConst()); + break; + case EbtUInt: + resultArray[i].setBConst(unionArrays[0][i].getUConst() > unionArrays[1][i].getUConst()); + break; + default: + UNREACHABLE(); + break; + } + } } + break; case EOpGreaterThanEqual: { - ASSERT(objectSize == 1); - TConstantUnion constant; - constant.setBConst(*unionArray < *rightUnionArray); - tempConstArray = new TConstantUnion[1]; - tempConstArray->setBConst(!constant.getBConst()); - returnType = TType(EbtBool, EbpUndefined, EvqConst); - break; + resultArray = new TConstantUnion[maxObjectSize]; + for (size_t i = 0; i < maxObjectSize; i++) + { + switch (basicType) + { + case EbtFloat: + resultArray[i].setBConst(unionArrays[0][i].getFConst() >= unionArrays[1][i].getFConst()); + break; + case EbtInt: + resultArray[i].setBConst(unionArrays[0][i].getIConst() >= unionArrays[1][i].getIConst()); + break; + case EbtUInt: + resultArray[i].setBConst(unionArrays[0][i].getUConst() >= unionArrays[1][i].getUConst()); + break; + default: + UNREACHABLE(); + break; + } + } } + break; - case EOpEqual: - if (getType().getBasicType() == EbtStruct) + case EOpVectorEqual: { - if (!CompareStructure(rightNode->getType(), - rightNode->getUnionArrayPointer(), - unionArray)) + resultArray = new TConstantUnion[maxObjectSize]; + for (size_t i = 0; i < maxObjectSize; i++) { - boolNodeFlag = true; + switch (basicType) + { + case EbtFloat: + resultArray[i].setBConst(unionArrays[0][i].getFConst() == unionArrays[1][i].getFConst()); + break; + case EbtInt: + resultArray[i].setBConst(unionArrays[0][i].getIConst() == unionArrays[1][i].getIConst()); + break; + case EbtUInt: + resultArray[i].setBConst(unionArrays[0][i].getUConst() == unionArrays[1][i].getUConst()); + break; + case EbtBool: + resultArray[i].setBConst(unionArrays[0][i].getBConst() == unionArrays[1][i].getBConst()); + break; + default: + UNREACHABLE(); + break; + } } } - else + break; + + case EOpVectorNotEqual: { - for (size_t i = 0; i < objectSize; i++) + resultArray = new TConstantUnion[maxObjectSize]; + for (size_t i = 0; i < maxObjectSize; i++) { - if (unionArray[i] != rightUnionArray[i]) + switch (basicType) { - boolNodeFlag = true; - break; // break out of for loop + case EbtFloat: + resultArray[i].setBConst(unionArrays[0][i].getFConst() != unionArrays[1][i].getFConst()); + break; + case EbtInt: + resultArray[i].setBConst(unionArrays[0][i].getIConst() != unionArrays[1][i].getIConst()); + break; + case EbtUInt: + resultArray[i].setBConst(unionArrays[0][i].getUConst() != unionArrays[1][i].getUConst()); + break; + case EbtBool: + resultArray[i].setBConst(unionArrays[0][i].getBConst() != unionArrays[1][i].getBConst()); + break; + default: + UNREACHABLE(); + break; } } } + break; - tempConstArray = new TConstantUnion[1]; - if (!boolNodeFlag) + case EOpDistance: + if (basicType == EbtFloat) { - tempConstArray->setBConst(true); + TConstantUnion *distanceArray = new TConstantUnion[maxObjectSize]; + resultArray = new TConstantUnion(); + for (size_t i = 0; i < maxObjectSize; i++) + { + float x = unionArrays[0][i].getFConst(); + float y = unionArrays[1][i].getFConst(); + distanceArray[i].setFConst(x - y); + } + resultArray->setFConst(VectorLength(distanceArray, maxObjectSize)); } else - { - tempConstArray->setBConst(false); - } + UNREACHABLE(); + break; - tempNode = new TIntermConstantUnion( - tempConstArray, TType(EbtBool, EbpUndefined, EvqConst)); - tempNode->setLine(getLine()); + case EOpDot: - return tempNode; + if (basicType == EbtFloat) + { + resultArray = new TConstantUnion(); + resultArray->setFConst(VectorDotProduct(unionArrays[0], unionArrays[1], maxObjectSize)); + } + else + UNREACHABLE(); + break; - case EOpNotEqual: - if (getType().getBasicType() == EbtStruct) + case EOpCross: + if (basicType == EbtFloat && maxObjectSize == 3) { - if (CompareStructure(rightNode->getType(), - rightNode->getUnionArrayPointer(), - unionArray)) - { - boolNodeFlag = true; - } + resultArray = new TConstantUnion[maxObjectSize]; + float x0 = unionArrays[0][0].getFConst(); + float x1 = unionArrays[0][1].getFConst(); + float x2 = unionArrays[0][2].getFConst(); + float y0 = unionArrays[1][0].getFConst(); + float y1 = unionArrays[1][1].getFConst(); + float y2 = unionArrays[1][2].getFConst(); + resultArray[0].setFConst(x1 * y2 - y1 * x2); + resultArray[1].setFConst(x2 * y0 - y2 * x0); + resultArray[2].setFConst(x0 * y1 - y0 * x1); } else + UNREACHABLE(); + break; + + case EOpReflect: + if (basicType == EbtFloat) { - for (size_t i = 0; i < objectSize; i++) + // genType reflect (genType I, genType N) : + // For the incident vector I and surface orientation N, returns the reflection direction: + // I - 2 * dot(N, I) * N. + resultArray = new TConstantUnion[maxObjectSize]; + float dotProduct = VectorDotProduct(unionArrays[1], unionArrays[0], maxObjectSize); + for (size_t i = 0; i < maxObjectSize; i++) { - if (unionArray[i] == rightUnionArray[i]) - { - boolNodeFlag = true; - break; // break out of for loop - } + float result = unionArrays[0][i].getFConst() - + 2.0f * dotProduct * unionArrays[1][i].getFConst(); + resultArray[i].setFConst(result); } } + else + UNREACHABLE(); + break; - tempConstArray = new TConstantUnion[1]; - if (!boolNodeFlag) + case EOpMul: + if (basicType == EbtFloat && (*sequence)[0]->getAsTyped()->isMatrix() && + (*sequence)[1]->getAsTyped()->isMatrix()) { - tempConstArray->setBConst(true); + // Perform component-wise matrix multiplication. + resultArray = new TConstantUnion[maxObjectSize]; + int size = (*sequence)[0]->getAsTyped()->getNominalSize(); + angle::Matrix result = + GetMatrix(unionArrays[0], size).compMult(GetMatrix(unionArrays[1], size)); + SetUnionArrayFromMatrix(result, resultArray); } else + UNREACHABLE(); + break; + + case EOpOuterProduct: + if (basicType == EbtFloat) { - tempConstArray->setBConst(false); + size_t numRows = (*sequence)[0]->getAsTyped()->getType().getObjectSize(); + size_t numCols = (*sequence)[1]->getAsTyped()->getType().getObjectSize(); + resultArray = new TConstantUnion[numRows * numCols]; + angle::Matrix result = + GetMatrix(unionArrays[0], 1, static_cast(numCols)) + .outerProduct(GetMatrix(unionArrays[1], static_cast(numRows), 1)); + SetUnionArrayFromMatrix(result, resultArray); } - - tempNode = new TIntermConstantUnion( - tempConstArray, TType(EbtBool, EbpUndefined, EvqConst)); - tempNode->setLine(getLine()); - - return tempNode; + else + UNREACHABLE(); + break; default: - infoSink.info.message( - EPrefixInternalError, getLine(), - "Invalid operator for constant folding"); + UNREACHABLE(); + // TODO: Add constant folding support for other built-in operations that take 2 parameters and not handled above. return nullptr; } - tempNode = new TIntermConstantUnion(tempConstArray, returnType); - tempNode->setLine(getLine()); - - return tempNode; } - else + else if (paramsCount == 3) { // - // Do unary operations + // Ternary built-in // - TIntermConstantUnion *newNode = 0; - TConstantUnion* tempConstArray = new TConstantUnion[objectSize]; - for (size_t i = 0; i < objectSize; i++) + switch (op) { - switch(op) + case EOpClamp: { - case EOpNegative: - switch (getType().getBasicType()) - { - case EbtFloat: - tempConstArray[i].setFConst(-unionArray[i].getFConst()); - break; - case EbtInt: - tempConstArray[i].setIConst(-unionArray[i].getIConst()); - break; - case EbtUInt: - tempConstArray[i].setUConst(static_cast( - -static_cast(unionArray[i].getUConst()))); - break; - default: - infoSink.info.message( - EPrefixInternalError, getLine(), - "Unary operation not folded into constant"); - return nullptr; - } - break; - - case EOpPositive: - switch (getType().getBasicType()) - { - case EbtFloat: - tempConstArray[i].setFConst(unionArray[i].getFConst()); - break; - case EbtInt: - tempConstArray[i].setIConst(unionArray[i].getIConst()); - break; - case EbtUInt: - tempConstArray[i].setUConst(static_cast( - static_cast(unionArray[i].getUConst()))); - break; - default: - infoSink.info.message( - EPrefixInternalError, getLine(), - "Unary operation not folded into constant"); - return nullptr; - } - break; - - case EOpLogicalNot: - // this code is written for possible future use, - // will not get executed currently - switch (getType().getBasicType()) - { - case EbtBool: - tempConstArray[i].setBConst(!unionArray[i].getBConst()); - break; - default: - infoSink.info.message( - EPrefixInternalError, getLine(), - "Unary operation not folded into constant"); - return nullptr; - } - break; - - case EOpBitwiseNot: - switch (getType().getBasicType()) - { - case EbtInt: - tempConstArray[i].setIConst(~unionArray[i].getIConst()); - break; - case EbtUInt: - tempConstArray[i].setUConst(~unionArray[i].getUConst()); - break; - default: - infoSink.info.message( - EPrefixInternalError, getLine(), - "Unary operation not folded into constant"); - return nullptr; - } - break; - - case EOpRadians: - if (getType().getBasicType() == EbtFloat) - { - tempConstArray[i].setFConst(kDegreesToRadiansMultiplier * unionArray[i].getFConst()); - break; - } - infoSink.info.message( - EPrefixInternalError, getLine(), - "Unary operation not folded into constant"); - return nullptr; - - case EOpDegrees: - if (getType().getBasicType() == EbtFloat) + resultArray = new TConstantUnion[maxObjectSize]; + for (size_t i = 0; i < maxObjectSize; i++) { - tempConstArray[i].setFConst(kRadiansToDegreesMultiplier * unionArray[i].getFConst()); - break; + switch (basicType) + { + case EbtFloat: + { + float x = unionArrays[0][i].getFConst(); + float min = unionArrays[1][i].getFConst(); + float max = unionArrays[2][i].getFConst(); + // Results are undefined if min > max. + if (min > max) + UndefinedConstantFoldingError(loc, op, basicType, infoSink, &resultArray[i]); + else + resultArray[i].setFConst(gl::clamp(x, min, max)); + } + break; + case EbtInt: + { + int x = unionArrays[0][i].getIConst(); + int min = unionArrays[1][i].getIConst(); + int max = unionArrays[2][i].getIConst(); + // Results are undefined if min > max. + if (min > max) + UndefinedConstantFoldingError(loc, op, basicType, infoSink, &resultArray[i]); + else + resultArray[i].setIConst(gl::clamp(x, min, max)); + } + break; + case EbtUInt: + { + unsigned int x = unionArrays[0][i].getUConst(); + unsigned int min = unionArrays[1][i].getUConst(); + unsigned int max = unionArrays[2][i].getUConst(); + // Results are undefined if min > max. + if (min > max) + UndefinedConstantFoldingError(loc, op, basicType, infoSink, &resultArray[i]); + else + resultArray[i].setUConst(gl::clamp(x, min, max)); + } + break; + default: + UNREACHABLE(); + break; + } } - infoSink.info.message( - EPrefixInternalError, getLine(), - "Unary operation not folded into constant"); - return nullptr; - - case EOpSin: - if (!foldFloatTypeUnary(unionArray[i], &sinf, infoSink, &tempConstArray[i])) - return nullptr; - break; - - case EOpCos: - if (!foldFloatTypeUnary(unionArray[i], &cosf, infoSink, &tempConstArray[i])) - return nullptr; - break; - - case EOpTan: - if (!foldFloatTypeUnary(unionArray[i], &tanf, infoSink, &tempConstArray[i])) - return nullptr; - break; - - case EOpAsin: - // For asin(x), results are undefined if |x| > 1, we are choosing to set result to 0. - if (getType().getBasicType() == EbtFloat && fabsf(unionArray[i].getFConst()) > 1.0f) - tempConstArray[i].setFConst(0.0f); - else if (!foldFloatTypeUnary(unionArray[i], &asinf, infoSink, &tempConstArray[i])) - return nullptr; - break; - - case EOpAcos: - // For acos(x), results are undefined if |x| > 1, we are choosing to set result to 0. - if (getType().getBasicType() == EbtFloat && fabsf(unionArray[i].getFConst()) > 1.0f) - tempConstArray[i].setFConst(0.0f); - else if (!foldFloatTypeUnary(unionArray[i], &acosf, infoSink, &tempConstArray[i])) - return nullptr; - break; - - case EOpAtan: - if (!foldFloatTypeUnary(unionArray[i], &atanf, infoSink, &tempConstArray[i])) - return nullptr; - break; - - case EOpSinh: - if (!foldFloatTypeUnary(unionArray[i], &sinhf, infoSink, &tempConstArray[i])) - return nullptr; - break; - - case EOpCosh: - if (!foldFloatTypeUnary(unionArray[i], &coshf, infoSink, &tempConstArray[i])) - return nullptr; - break; - - case EOpTanh: - if (!foldFloatTypeUnary(unionArray[i], &tanhf, infoSink, &tempConstArray[i])) - return nullptr; - break; - - case EOpAsinh: - if (!foldFloatTypeUnary(unionArray[i], &asinhf, infoSink, &tempConstArray[i])) - return nullptr; - break; - - case EOpAcosh: - // For acosh(x), results are undefined if x < 1, we are choosing to set result to 0. - if (getType().getBasicType() == EbtFloat && unionArray[i].getFConst() < 1.0f) - tempConstArray[i].setFConst(0.0f); - else if (!foldFloatTypeUnary(unionArray[i], &acoshf, infoSink, &tempConstArray[i])) - return nullptr; - break; - - case EOpAtanh: - // For atanh(x), results are undefined if |x| >= 1, we are choosing to set result to 0. - if (getType().getBasicType() == EbtFloat && fabsf(unionArray[i].getFConst()) >= 1.0f) - tempConstArray[i].setFConst(0.0f); - else if (!foldFloatTypeUnary(unionArray[i], &atanhf, infoSink, &tempConstArray[i])) - return nullptr; - break; + } + break; - case EOpAbs: - switch (getType().getBasicType()) + case EOpMix: + { + if (basicType == EbtFloat) { - case EbtFloat: - tempConstArray[i].setFConst(fabsf(unionArray[i].getFConst())); - break; - case EbtInt: - tempConstArray[i].setIConst(abs(unionArray[i].getIConst())); - break; - default: - infoSink.info.message( - EPrefixInternalError, getLine(), - "Unary operation not folded into constant"); - return nullptr; + resultArray = new TConstantUnion[maxObjectSize]; + for (size_t i = 0; i < maxObjectSize; i++) + { + float x = unionArrays[0][i].getFConst(); + float y = unionArrays[1][i].getFConst(); + TBasicType type = (*sequence)[2]->getAsTyped()->getType().getBasicType(); + if (type == EbtFloat) + { + // Returns the linear blend of x and y, i.e., x * (1 - a) + y * a. + float a = unionArrays[2][i].getFConst(); + resultArray[i].setFConst(x * (1.0f - a) + y * a); + } + else // 3rd parameter is EbtBool + { + ASSERT(type == EbtBool); + // Selects which vector each returned component comes from. + // For a component of a that is false, the corresponding component of x is returned. + // For a component of a that is true, the corresponding component of y is returned. + bool a = unionArrays[2][i].getBConst(); + resultArray[i].setFConst(a ? y : x); + } + } } - break; + else + UNREACHABLE(); + } + break; - case EOpSign: - switch (getType().getBasicType()) + case EOpSmoothStep: + { + if (basicType == EbtFloat) { - case EbtFloat: - { - float fConst = unionArray[i].getFConst(); - float fResult = 0.0f; - if (fConst > 0.0f) - fResult = 1.0f; - else if (fConst < 0.0f) - fResult = -1.0f; - tempConstArray[i].setFConst(fResult); - } - break; - case EbtInt: + resultArray = new TConstantUnion[maxObjectSize]; + for (size_t i = 0; i < maxObjectSize; i++) { - int iConst = unionArray[i].getIConst(); - int iResult = 0; - if (iConst > 0) - iResult = 1; - else if (iConst < 0) - iResult = -1; - tempConstArray[i].setIConst(iResult); + float edge0 = unionArrays[0][i].getFConst(); + float edge1 = unionArrays[1][i].getFConst(); + float x = unionArrays[2][i].getFConst(); + // Results are undefined if edge0 >= edge1. + if (edge0 >= edge1) + { + UndefinedConstantFoldingError(loc, op, basicType, infoSink, &resultArray[i]); + } + else + { + // Returns 0.0 if x <= edge0 and 1.0 if x >= edge1 and performs smooth + // Hermite interpolation between 0 and 1 when edge0 < x < edge1. + float t = gl::clamp((x - edge0) / (edge1 - edge0), 0.0f, 1.0f); + resultArray[i].setFConst(t * t * (3.0f - 2.0f * t)); + } } - break; - default: - infoSink.info.message( - EPrefixInternalError, getLine(), - "Unary operation not folded into constant"); - return nullptr; } - break; - - case EOpFloor: - if (!foldFloatTypeUnary(unionArray[i], &floorf, infoSink, &tempConstArray[i])) - return nullptr; - break; - - case EOpTrunc: - if (!foldFloatTypeUnary(unionArray[i], &truncf, infoSink, &tempConstArray[i])) - return nullptr; - break; - - case EOpRound: - if (!foldFloatTypeUnary(unionArray[i], &roundf, infoSink, &tempConstArray[i])) - return nullptr; - break; + else + UNREACHABLE(); + } + break; - case EOpRoundEven: - if (getType().getBasicType() == EbtFloat) + case EOpFaceForward: + if (basicType == EbtFloat) + { + // genType faceforward(genType N, genType I, genType Nref) : + // If dot(Nref, I) < 0 return N, otherwise return -N. + resultArray = new TConstantUnion[maxObjectSize]; + float dotProduct = VectorDotProduct(unionArrays[2], unionArrays[1], maxObjectSize); + for (size_t i = 0; i < maxObjectSize; i++) { - float x = unionArray[i].getFConst(); - float result; - float fractPart = modff(x, &result); - if (fabsf(fractPart) == 0.5f) - result = 2.0f * roundf(x / 2.0f); + if (dotProduct < 0) + resultArray[i].setFConst(unionArrays[0][i].getFConst()); else - result = roundf(x); - tempConstArray[i].setFConst(result); - break; + resultArray[i].setFConst(-unionArrays[0][i].getFConst()); } - infoSink.info.message( - EPrefixInternalError, getLine(), - "Unary operation not folded into constant"); - return nullptr; - - case EOpCeil: - if (!foldFloatTypeUnary(unionArray[i], &ceilf, infoSink, &tempConstArray[i])) - return nullptr; - break; + } + else + UNREACHABLE(); + break; - case EOpFract: - if (getType().getBasicType() == EbtFloat) + case EOpRefract: + if (basicType == EbtFloat) + { + // genType refract(genType I, genType N, float eta) : + // For the incident vector I and surface normal N, and the ratio of indices of refraction eta, + // return the refraction vector. The result is computed by + // k = 1.0 - eta * eta * (1.0 - dot(N, I) * dot(N, I)) + // if (k < 0.0) + // return genType(0.0) + // else + // return eta * I - (eta * dot(N, I) + sqrt(k)) * N + resultArray = new TConstantUnion[maxObjectSize]; + float dotProduct = VectorDotProduct(unionArrays[1], unionArrays[0], maxObjectSize); + for (size_t i = 0; i < maxObjectSize; i++) { - float x = unionArray[i].getFConst(); - tempConstArray[i].setFConst(x - floorf(x)); - break; + float eta = unionArrays[2][i].getFConst(); + float k = 1.0f - eta * eta * (1.0f - dotProduct * dotProduct); + if (k < 0.0f) + resultArray[i].setFConst(0.0f); + else + resultArray[i].setFConst(eta * unionArrays[0][i].getFConst() - + (eta * dotProduct + sqrtf(k)) * unionArrays[1][i].getFConst()); } - infoSink.info.message( - EPrefixInternalError, getLine(), - "Unary operation not folded into constant"); - return nullptr; - - case EOpExp: - if (!foldFloatTypeUnary(unionArray[i], &expf, infoSink, &tempConstArray[i])) - return nullptr; - break; - - case EOpLog: - // For log(x), results are undefined if x <= 0, we are choosing to set result to 0. - if (getType().getBasicType() == EbtFloat && unionArray[i].getFConst() <= 0.0f) - tempConstArray[i].setFConst(0.0f); - else if (!foldFloatTypeUnary(unionArray[i], &logf, infoSink, &tempConstArray[i])) - return nullptr; - break; - - case EOpExp2: - if (!foldFloatTypeUnary(unionArray[i], &exp2f, infoSink, &tempConstArray[i])) - return nullptr; - break; - - case EOpLog2: - // For log2(x), results are undefined if x <= 0, we are choosing to set result to 0. - // And log2f is not available on some plarforms like old android, so just using log(x)/log(2) here. - if (getType().getBasicType() == EbtFloat && unionArray[i].getFConst() <= 0.0f) - tempConstArray[i].setFConst(0.0f); - else if (!foldFloatTypeUnary(unionArray[i], &logf, infoSink, &tempConstArray[i])) - return nullptr; - else - tempConstArray[i].setFConst(tempConstArray[i].getFConst() / logf(2.0f)); - break; - - case EOpSqrt: - // For sqrt(x), results are undefined if x < 0, we are choosing to set result to 0. - if (getType().getBasicType() == EbtFloat && unionArray[i].getFConst() < 0.0f) - tempConstArray[i].setFConst(0.0f); - else if (!foldFloatTypeUnary(unionArray[i], &sqrtf, infoSink, &tempConstArray[i])) - return nullptr; - break; - - case EOpInverseSqrt: - // There is no stdlib built-in function equavalent for GLES built-in inversesqrt(), - // so getting the square root first using builtin function sqrt() and then taking its inverse. - // Also, for inversesqrt(x), results are undefined if x <= 0, we are choosing to set result to 0. - if (getType().getBasicType() == EbtFloat && unionArray[i].getFConst() <= 0.0f) - tempConstArray[i].setFConst(0.0f); - else if (!foldFloatTypeUnary(unionArray[i], &sqrtf, infoSink, &tempConstArray[i])) - return nullptr; - else - tempConstArray[i].setFConst(1.0f / tempConstArray[i].getFConst()); - break; - - default: - return nullptr; } - } - newNode = new TIntermConstantUnion(tempConstArray, getType()); - newNode->setLine(getLine()); - return newNode; - } -} - -bool TIntermConstantUnion::foldFloatTypeUnary(const TConstantUnion ¶meter, FloatTypeUnaryFunc builtinFunc, - TInfoSink &infoSink, TConstantUnion *result) const -{ - ASSERT(builtinFunc); + else + UNREACHABLE(); + break; - if (getType().getBasicType() == EbtFloat) - { - result->setFConst(builtinFunc(parameter.getFConst())); - return true; + default: + UNREACHABLE(); + // TODO: Add constant folding support for other built-in operations that take 3 parameters and not handled above. + return nullptr; + } } - - infoSink.info.message( - EPrefixInternalError, getLine(), - "Unary operation not folded into constant"); - return false; + return resultArray; } // static @@ -1488,6 +2606,25 @@ TString TIntermTraverser::hash(const TString &name, ShHashFunction64 hashFunctio void TIntermTraverser::updateTree() { + for (size_t ii = 0; ii < mInsertions.size(); ++ii) + { + const NodeInsertMultipleEntry &insertion = mInsertions[ii]; + ASSERT(insertion.parent); + if (!insertion.insertionsAfter.empty()) + { + bool inserted = insertion.parent->insertChildNodes(insertion.position + 1, + insertion.insertionsAfter); + ASSERT(inserted); + UNUSED_ASSERTION_VARIABLE(inserted); + } + if (!insertion.insertionsBefore.empty()) + { + bool inserted = + insertion.parent->insertChildNodes(insertion.position, insertion.insertionsBefore); + ASSERT(inserted); + UNUSED_ASSERTION_VARIABLE(inserted); + } + } for (size_t ii = 0; ii < mReplacements.size(); ++ii) { const NodeUpdateEntry &replacement = mReplacements[ii]; @@ -1520,4 +2657,8 @@ void TIntermTraverser::updateTree() ASSERT(replaced); UNUSED_ASSERTION_VARIABLE(replaced); } + + mInsertions.clear(); + mReplacements.clear(); + mMultiReplacements.clear(); } diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/IntermNode.h b/Source/ThirdParty/ANGLE/src/compiler/translator/IntermNode.h index 2fffe0985499..32ac97ffa7b4 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/IntermNode.h +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/IntermNode.h @@ -41,11 +41,35 @@ class TIntermLoop; class TInfoSink; class TInfoSinkBase; class TIntermRaw; +class TIntermBranch; + +class TSymbolTable; + +// Encapsulate an identifier string and track whether it is coming from the original shader code +// (not internal) or from ANGLE (internal). Usually internal names shouldn't be decorated or hashed. +class TName +{ + public: + POOL_ALLOCATOR_NEW_DELETE(); + explicit TName(const TString &name) : mName(name), mIsInternal(false) {} + TName() : mName(), mIsInternal(false) {} + TName(const TName &) = default; + TName &operator=(const TName &) = default; + + const TString &getString() const { return mName; } + void setString(const TString &string) { mName = string; } + bool isInternal() const { return mIsInternal; } + void setInternal(bool isInternal) { mIsInternal = isInternal; } + + private: + TString mName; + bool mIsInternal; +}; // // Base class for the tree nodes // -class TIntermNode +class TIntermNode : angle::NonCopyable { public: POOL_ALLOCATOR_NEW_DELETE(); @@ -73,6 +97,7 @@ class TIntermNode virtual TIntermSymbol *getAsSymbolNode() { return 0; } virtual TIntermLoop *getAsLoopNode() { return 0; } virtual TIntermRaw *getAsRawNode() { return 0; } + virtual TIntermBranch *getAsBranchNode() { return 0; } // Replace a child node. Return true if |original| is a child // node and it is replaced; otherwise, return false. @@ -99,7 +124,10 @@ class TIntermTyped : public TIntermNode { public: TIntermTyped(const TType &t) : mType(t) { } - virtual TIntermTyped *getAsTyped() { return this; } + + virtual TIntermTyped *deepCopy() const = 0; + + TIntermTyped *getAsTyped() override { return this; } virtual bool hasSideEffects() const = 0; @@ -123,13 +151,14 @@ class TIntermTyped : public TIntermNode bool isScalar() const { return mType.isScalar(); } bool isScalarInt() const { return mType.isScalarInt(); } const char *getBasicString() const { return mType.getBasicString(); } - const char *getQualifierString() const { return mType.getQualifierString(); } TString getCompleteString() const { return mType.getCompleteString(); } int getArraySize() const { return mType.getArraySize(); } protected: TType mType; + + TIntermTyped(const TIntermTyped &node); }; // @@ -146,25 +175,23 @@ class TIntermLoop : public TIntermNode { public: TIntermLoop(TLoopType type, - TIntermNode *init, TIntermTyped *cond, TIntermTyped *expr, - TIntermNode *body) - : mType(type), - mInit(init), - mCond(cond), - mExpr(expr), - mBody(body), - mUnrollFlag(false) { } + TIntermNode *init, + TIntermTyped *cond, + TIntermTyped *expr, + TIntermAggregate *body) + : mType(type), mInit(init), mCond(cond), mExpr(expr), mBody(body), mUnrollFlag(false) + { + } - virtual TIntermLoop *getAsLoopNode() { return this; } - virtual void traverse(TIntermTraverser *); - virtual bool replaceChildNode( - TIntermNode *original, TIntermNode *replacement); + TIntermLoop *getAsLoopNode() override { return this; } + void traverse(TIntermTraverser *it) override; + bool replaceChildNode(TIntermNode *original, TIntermNode *replacement) override; TLoopType getType() const { return mType; } TIntermNode *getInit() { return mInit; } TIntermTyped *getCondition() { return mCond; } TIntermTyped *getExpression() { return mExpr; } - TIntermNode *getBody() { return mBody; } + TIntermAggregate *getBody() { return mBody; } void setUnrollFlag(bool flag) { mUnrollFlag = flag; } bool getUnrollFlag() const { return mUnrollFlag; } @@ -174,7 +201,7 @@ class TIntermLoop : public TIntermNode TIntermNode *mInit; // for-loop initialization TIntermTyped *mCond; // loop exit condition TIntermTyped *mExpr; // for-loop expression - TIntermNode *mBody; // loop body + TIntermAggregate *mBody; // loop body bool mUnrollFlag; // Whether the loop should be unrolled or not. }; @@ -189,9 +216,9 @@ class TIntermBranch : public TIntermNode : mFlowOp(op), mExpression(e) { } - virtual void traverse(TIntermTraverser *); - virtual bool replaceChildNode( - TIntermNode *original, TIntermNode *replacement); + void traverse(TIntermTraverser *it) override; + TIntermBranch *getAsBranchNode() override { return this; } + bool replaceChildNode(TIntermNode *original, TIntermNode *replacement) override; TOperator getFlowOp() { return mFlowOp; } TIntermTyped* getExpression() { return mExpression; } @@ -211,31 +238,32 @@ class TIntermSymbol : public TIntermTyped // If sym comes from per process globalpoolallocator, then it causes increased memory usage // per compile it is essential to use "symbol = sym" to assign to symbol TIntermSymbol(int id, const TString &symbol, const TType &type) - : TIntermTyped(type), - mId(id), - mInternal(false) + : TIntermTyped(type), mId(id), mSymbol(symbol) { - mSymbol = symbol; } - virtual bool hasSideEffects() const { return false; } + TIntermTyped *deepCopy() const override { return new TIntermSymbol(*this); } + + bool hasSideEffects() const override { return false; } int getId() const { return mId; } - const TString &getSymbol() const { return mSymbol; } + const TString &getSymbol() const { return mSymbol.getString(); } + const TName &getName() const { return mSymbol; } void setId(int newId) { mId = newId; } - bool isInternal() const { return mInternal; } - void setInternal(bool isInternal) { mInternal = isInternal; } + void setInternal(bool internal) { mSymbol.setInternal(internal); } - virtual void traverse(TIntermTraverser *); - virtual TIntermSymbol *getAsSymbolNode() { return this; } - virtual bool replaceChildNode(TIntermNode *, TIntermNode *) { return false; } + void traverse(TIntermTraverser *it) override; + TIntermSymbol *getAsSymbolNode() override { return this; } + bool replaceChildNode(TIntermNode *, TIntermNode *) override { return false; } protected: int mId; - bool mInternal; - TString mSymbol; + TName mSymbol; + + private: + TIntermSymbol(const TIntermSymbol &) = default; // Note: not deleted, just private! }; // A Raw node stores raw code, that the translator will insert verbatim @@ -247,31 +275,46 @@ class TIntermRaw : public TIntermTyped TIntermRaw(const TType &type, const TString &rawText) : TIntermTyped(type), mRawText(rawText) { } + TIntermRaw(const TIntermRaw &) = delete; + + TIntermTyped *deepCopy() const override + { + UNREACHABLE(); + return nullptr; + } - virtual bool hasSideEffects() const { return false; } + bool hasSideEffects() const override { return false; } TString getRawText() const { return mRawText; } - virtual void traverse(TIntermTraverser *); + void traverse(TIntermTraverser *it) override; - virtual TIntermRaw *getAsRawNode() { return this; } - virtual bool replaceChildNode(TIntermNode *, TIntermNode *) { return false; } + TIntermRaw *getAsRawNode() override { return this; } + bool replaceChildNode(TIntermNode *, TIntermNode *) override { return false; } protected: TString mRawText; }; +// Constant folded node. +// Note that nodes may be constant folded and not be constant expressions with the EvqConst +// qualifier. This happens for example when the following expression is processed: +// "true ? 1.0 : non_constant" +// Other nodes than TIntermConstantUnion may also be constant expressions. +// class TIntermConstantUnion : public TIntermTyped { public: - TIntermConstantUnion(TConstantUnion *unionPointer, const TType &type) - : TIntermTyped(type), - mUnionArrayPointer(unionPointer) { } + TIntermConstantUnion(const TConstantUnion *unionPointer, const TType &type) + : TIntermTyped(type), mUnionArrayPointer(unionPointer) + { + } + + TIntermTyped *deepCopy() const override { return new TIntermConstantUnion(*this); } - virtual bool hasSideEffects() const { return false; } + bool hasSideEffects() const override { return false; } const TConstantUnion *getUnionArrayPointer() const { return mUnionArrayPointer; } - TConstantUnion *getUnionArrayPointer() { return mUnionArrayPointer; } int getIConst(size_t index) const { @@ -290,24 +333,33 @@ class TIntermConstantUnion : public TIntermTyped return mUnionArrayPointer ? mUnionArrayPointer[index].getBConst() : false; } - void replaceConstantUnion(TConstantUnion *safeConstantUnion) + void replaceConstantUnion(const TConstantUnion *safeConstantUnion) { // Previous union pointer freed on pool deallocation. mUnionArrayPointer = safeConstantUnion; } - virtual TIntermConstantUnion *getAsConstantUnion() { return this; } - virtual void traverse(TIntermTraverser *); - virtual bool replaceChildNode(TIntermNode *, TIntermNode *) { return false; } + TIntermConstantUnion *getAsConstantUnion() override { return this; } + void traverse(TIntermTraverser *it) override; + bool replaceChildNode(TIntermNode *, TIntermNode *) override { return false; } + + TConstantUnion *foldBinary(TOperator op, TIntermConstantUnion *rightNode, TInfoSink &infoSink); + TConstantUnion *foldUnaryWithDifferentReturnType(TOperator op, TInfoSink &infoSink); + TConstantUnion *foldUnaryWithSameReturnType(TOperator op, TInfoSink &infoSink); - TIntermTyped *fold(TOperator op, TIntermConstantUnion *rightNode, TInfoSink &infoSink); + static TConstantUnion *FoldAggregateConstructor(TIntermAggregate *aggregate, + TInfoSink &infoSink); + static TConstantUnion *FoldAggregateBuiltIn(TIntermAggregate *aggregate, TInfoSink &infoSink); protected: - TConstantUnion *mUnionArrayPointer; + // Same data may be shared between multiple constant unions, so it can't be modified. + const TConstantUnion *mUnionArrayPointer; private: typedef float(*FloatTypeUnaryFunc) (float); bool foldFloatTypeUnary(const TConstantUnion ¶meter, FloatTypeUnaryFunc builtinFunc, TInfoSink &infoSink, TConstantUnion *result) const; + + TIntermConstantUnion(const TIntermConstantUnion &node); // Note: not deleted, just private! }; // @@ -320,9 +372,10 @@ class TIntermOperator : public TIntermTyped void setOp(TOperator op) { mOp = op; } bool isAssignment() const; + bool isMultiplication() const; bool isConstructor() const; - virtual bool hasSideEffects() const { return isAssignment(); } + bool hasSideEffects() const override { return isAssignment(); } protected: TIntermOperator(TOperator op) @@ -332,6 +385,8 @@ class TIntermOperator : public TIntermTyped : TIntermTyped(type), mOp(op) {} + TIntermOperator(const TIntermOperator &) = default; + TOperator mOp; }; @@ -345,12 +400,13 @@ class TIntermBinary : public TIntermOperator : TIntermOperator(op), mAddIndexClamp(false) {} - virtual TIntermBinary *getAsBinaryNode() { return this; } - virtual void traverse(TIntermTraverser *); - virtual bool replaceChildNode( - TIntermNode *original, TIntermNode *replacement); + TIntermTyped *deepCopy() const override { return new TIntermBinary(*this); } + + TIntermBinary *getAsBinaryNode() override { return this; }; + void traverse(TIntermTraverser *it) override; + bool replaceChildNode(TIntermNode *original, TIntermNode *replacement) override; - virtual bool hasSideEffects() const + bool hasSideEffects() const override { return isAssignment() || mLeft->hasSideEffects() || mRight->hasSideEffects(); } @@ -360,6 +416,7 @@ class TIntermBinary : public TIntermOperator TIntermTyped *getLeft() const { return mLeft; } TIntermTyped *getRight() const { return mRight; } bool promote(TInfoSink &); + TIntermTyped *fold(TInfoSink &infoSink); void setAddIndexClamp() { mAddIndexClamp = true; } bool getAddIndexClamp() { return mAddIndexClamp; } @@ -370,6 +427,9 @@ class TIntermBinary : public TIntermOperator // If set to true, wrap any EOpIndexIndirect with a clamp to bounds. bool mAddIndexClamp; + + private: + TIntermBinary(const TIntermBinary &node); // Note: not deleted, just private! }; // @@ -387,19 +447,18 @@ class TIntermUnary : public TIntermOperator mOperand(NULL), mUseEmulatedFunction(false) {} - virtual void traverse(TIntermTraverser *); - virtual TIntermUnary *getAsUnaryNode() { return this; } - virtual bool replaceChildNode( - TIntermNode *original, TIntermNode *replacement); + TIntermTyped *deepCopy() const override { return new TIntermUnary(*this); } - virtual bool hasSideEffects() const - { - return isAssignment() || mOperand->hasSideEffects(); - } + void traverse(TIntermTraverser *it) override; + TIntermUnary *getAsUnaryNode() override { return this; } + bool replaceChildNode(TIntermNode *original, TIntermNode *replacement) override; + + bool hasSideEffects() const override { return isAssignment() || mOperand->hasSideEffects(); } void setOperand(TIntermTyped *operand) { mOperand = operand; } TIntermTyped *getOperand() { return mOperand; } void promote(const TType *funcReturnType); + TIntermTyped *fold(TInfoSink &infoSink); void setUseEmulatedFunction() { mUseEmulatedFunction = true; } bool getUseEmulatedFunction() { return mUseEmulatedFunction; } @@ -410,6 +469,9 @@ class TIntermUnary : public TIntermOperator // If set to true, replace the built-in function call with an emulated one // to work around driver bugs. bool mUseEmulatedFunction; + + private: + TIntermUnary(const TIntermUnary &node); // note: not deleted, just private! }; typedef TVector TIntermSequence; @@ -424,56 +486,68 @@ class TIntermAggregate : public TIntermOperator TIntermAggregate() : TIntermOperator(EOpNull), mUserDefined(false), - mUseEmulatedFunction(false) { } + mUseEmulatedFunction(false), + mGotPrecisionFromChildren(false) + { + } TIntermAggregate(TOperator op) : TIntermOperator(op), - mUseEmulatedFunction(false) { } + mUseEmulatedFunction(false), + mGotPrecisionFromChildren(false) + { + } ~TIntermAggregate() { } - virtual TIntermAggregate *getAsAggregate() { return this; } - virtual void traverse(TIntermTraverser *); - virtual bool replaceChildNode( - TIntermNode *original, TIntermNode *replacement); + // Note: only supported for nodes that can be a part of an expression. + TIntermTyped *deepCopy() const override { return new TIntermAggregate(*this); } + + TIntermAggregate *getAsAggregate() override { return this; } + void traverse(TIntermTraverser *it) override; + bool replaceChildNode(TIntermNode *original, TIntermNode *replacement) override; bool replaceChildNodeWithMultiple(TIntermNode *original, TIntermSequence replacements); + bool insertChildNodes(TIntermSequence::size_type position, TIntermSequence insertions); // Conservatively assume function calls and other aggregate operators have side-effects - virtual bool hasSideEffects() const { return true; } + bool hasSideEffects() const override { return true; } + TIntermTyped *fold(TInfoSink &infoSink); TIntermSequence *getSequence() { return &mSequence; } - void setName(const TString &name) { mName = name; } - const TString &getName() const { return mName; } + void setNameObj(const TName &name) { mName = name; } + const TName &getNameObj() const { return mName; } + + void setName(const TString &name) { mName.setString(name); } + const TString &getName() const { return mName.getString(); } void setUserDefined() { mUserDefined = true; } bool isUserDefined() const { return mUserDefined; } - void setOptimize(bool optimize) { mOptimize = optimize; } - bool getOptimize() const { return mOptimize; } - void setDebug(bool debug) { mDebug = debug; } - bool getDebug() const { return mDebug; } - void setFunctionId(int functionId) { mFunctionId = functionId; } int getFunctionId() const { return mFunctionId; } void setUseEmulatedFunction() { mUseEmulatedFunction = true; } bool getUseEmulatedFunction() { return mUseEmulatedFunction; } + bool areChildrenConstQualified(); void setPrecisionFromChildren(); void setBuiltInFunctionPrecision(); + // Returns true if changing parameter precision may affect the return value. + bool gotPrecisionFromChildren() const { return mGotPrecisionFromChildren; } + protected: - TIntermAggregate(const TIntermAggregate &); // disallow copy constructor - TIntermAggregate &operator=(const TIntermAggregate &); // disallow assignment operator TIntermSequence mSequence; - TString mName; + TName mName; bool mUserDefined; // used for user defined function names int mFunctionId; - bool mOptimize; - bool mDebug; - // If set to true, replace the built-in function call with an emulated one // to work around driver bugs. bool mUseEmulatedFunction; + + bool mGotPrecisionFromChildren; + + private: + TIntermAggregate(const TIntermAggregate &node); // note: not deleted, just private! }; // @@ -494,23 +568,28 @@ class TIntermSelection : public TIntermTyped mTrueBlock(trueB), mFalseBlock(falseB) {} - virtual void traverse(TIntermTraverser *); - virtual bool replaceChildNode( - TIntermNode *original, TIntermNode *replacement); + // Note: only supported for ternary operator nodes. + TIntermTyped *deepCopy() const override { return new TIntermSelection(*this); } + + void traverse(TIntermTraverser *it) override; + bool replaceChildNode(TIntermNode *original, TIntermNode *replacement) override; // Conservatively assume selections have side-effects - virtual bool hasSideEffects() const { return true; } + bool hasSideEffects() const override { return true; } bool usesTernaryOperator() const { return getBasicType() != EbtVoid; } TIntermNode *getCondition() const { return mCondition; } TIntermNode *getTrueBlock() const { return mTrueBlock; } TIntermNode *getFalseBlock() const { return mFalseBlock; } - TIntermSelection *getAsSelectionNode() { return this; } + TIntermSelection *getAsSelectionNode() override { return this; } -protected: + protected: TIntermTyped *mCondition; TIntermNode *mTrueBlock; TIntermNode *mFalseBlock; + + private: + TIntermSelection(const TIntermSelection &node); // Note: not deleted, just private! }; // @@ -532,6 +611,7 @@ class TIntermSwitch : public TIntermNode TIntermSwitch *getAsSwitchNode() override { return this; } + TIntermTyped *getInit() { return mInit; } TIntermAggregate *getStatementList() { return mStatementList; } void setStatementList(TIntermAggregate *statementList) { mStatementList = statementList; } @@ -573,9 +653,12 @@ enum Visit }; // -// For traversing the tree. User should derive from this, -// put their traversal specific data in it, and then pass -// it to a Traverse method. +// For traversing the tree. User should derive from this class overriding the visit functions, +// and then pass an object of the subclass to a traverse method of a node. +// +// The traverse*() functions may also be overridden do other bookkeeping on the tree to provide +// contextual information to the visit functions, such as whether the node is the target of an +// assignment. // // When using this, just fill in the methods for nodes you want visited. // Return false from a pre-visit to skip visiting that node's subtree. @@ -584,31 +667,59 @@ class TIntermTraverser : angle::NonCopyable { public: POOL_ALLOCATOR_NEW_DELETE(); - // TODO(zmo): remove default values. - TIntermTraverser(bool preVisit = true, bool inVisit = false, bool postVisit = false, - bool rightToLeft = false) + TIntermTraverser(bool preVisit, bool inVisit, bool postVisit) : preVisit(preVisit), inVisit(inVisit), postVisit(postVisit), - rightToLeft(rightToLeft), mDepth(0), - mMaxDepth(0) {} + mMaxDepth(0), + mTemporaryIndex(nullptr) + { + } virtual ~TIntermTraverser() {} - virtual void visitSymbol(TIntermSymbol *) {} - virtual void visitRaw(TIntermRaw *) {} - virtual void visitConstantUnion(TIntermConstantUnion *) {} - virtual bool visitBinary(Visit, TIntermBinary *) { return true; } - virtual bool visitUnary(Visit, TIntermUnary *) { return true; } - virtual bool visitSelection(Visit, TIntermSelection *) { return true; } - virtual bool visitSwitch(Visit, TIntermSwitch *) { return true; } - virtual bool visitCase(Visit, TIntermCase *) { return true; } - virtual bool visitAggregate(Visit, TIntermAggregate *) { return true; } - virtual bool visitLoop(Visit, TIntermLoop *) { return true; } - virtual bool visitBranch(Visit, TIntermBranch *) { return true; } + virtual void visitSymbol(TIntermSymbol *node) {} + virtual void visitRaw(TIntermRaw *node) {} + virtual void visitConstantUnion(TIntermConstantUnion *node) {} + virtual bool visitBinary(Visit visit, TIntermBinary *node) { return true; } + virtual bool visitUnary(Visit visit, TIntermUnary *node) { return true; } + virtual bool visitSelection(Visit visit, TIntermSelection *node) { return true; } + virtual bool visitSwitch(Visit visit, TIntermSwitch *node) { return true; } + virtual bool visitCase(Visit visit, TIntermCase *node) { return true; } + virtual bool visitAggregate(Visit visit, TIntermAggregate *node) { return true; } + virtual bool visitLoop(Visit visit, TIntermLoop *node) { return true; } + virtual bool visitBranch(Visit visit, TIntermBranch *node) { return true; } + + // The traverse functions contain logic for iterating over the children of the node + // and calling the visit functions in the appropriate places. They also track some + // context that may be used by the visit functions. + virtual void traverseSymbol(TIntermSymbol *node); + virtual void traverseRaw(TIntermRaw *node); + virtual void traverseConstantUnion(TIntermConstantUnion *node); + virtual void traverseBinary(TIntermBinary *node); + virtual void traverseUnary(TIntermUnary *node); + virtual void traverseSelection(TIntermSelection *node); + virtual void traverseSwitch(TIntermSwitch *node); + virtual void traverseCase(TIntermCase *node); + virtual void traverseAggregate(TIntermAggregate *node); + virtual void traverseLoop(TIntermLoop *node); + virtual void traverseBranch(TIntermBranch *node); int getMaxDepth() const { return mMaxDepth; } + // Return the original name if hash function pointer is NULL; + // otherwise return the hashed name. + static TString hash(const TString &name, ShHashFunction64 hashFunction); + + // If traversers need to replace nodes, they can add the replacements in + // mReplacements/mMultiReplacements during traversal and the user of the traverser should call + // this function after traversal to perform them. + void updateTree(); + + // Start creating temporary symbols from the given temporary symbol index + 1. + void useTemporaryIndex(unsigned int *temporaryIndex); + + protected: void incrementDepth(TIntermNode *current) { mDepth++; @@ -627,21 +738,29 @@ class TIntermTraverser : angle::NonCopyable return mPath.size() == 0 ? NULL : mPath.back(); } - // Return the original name if hash function pointer is NULL; - // otherwise return the hashed name. - static TString hash(const TString& name, ShHashFunction64 hashFunction); + // Return the nth ancestor of the node being traversed. getAncestorNode(0) == getParentNode() + TIntermNode *getAncestorNode(unsigned int n) + { + if (mPath.size() > n) + { + return mPath[mPath.size() - n - 1u]; + } + return nullptr; + } + + void pushParentBlock(TIntermAggregate *node); + void incrementParentBlockPos(); + void popParentBlock(); + + bool parentNodeIsBlock() + { + return !mParentBlockStack.empty() && getParentNode() == mParentBlockStack.back().node; + } const bool preVisit; const bool inVisit; const bool postVisit; - const bool rightToLeft; - - // If traversers need to replace nodes, they can add the replacements in - // mReplacements/mMultiReplacements during traversal and the user of the traverser should call - // this function after traversal to perform them. - void updateTree(); - protected: int mDepth; int mMaxDepth; @@ -681,11 +800,151 @@ class TIntermTraverser : angle::NonCopyable TIntermSequence replacements; }; + // To insert multiple nodes on the parent aggregate node + struct NodeInsertMultipleEntry + { + NodeInsertMultipleEntry(TIntermAggregate *_parent, + TIntermSequence::size_type _position, + TIntermSequence _insertionsBefore, + TIntermSequence _insertionsAfter) + : parent(_parent), + position(_position), + insertionsBefore(_insertionsBefore), + insertionsAfter(_insertionsAfter) + { + } + + TIntermAggregate *parent; + TIntermSequence::size_type position; + TIntermSequence insertionsBefore; + TIntermSequence insertionsAfter; + }; + // During traversing, save all the changes that need to happen into // mReplacements/mMultiReplacements, then do them by calling updateTree(). // Multi replacements are processed after single replacements. std::vector mReplacements; std::vector mMultiReplacements; + std::vector mInsertions; + + // Helper to insert statements in the parent block (sequence) of the node currently being traversed. + // The statements will be inserted before the node being traversed once updateTree is called. + // Should only be called during PreVisit or PostVisit from sequence nodes. + // Note that inserting more than one set of nodes to the same parent node on a single updateTree call is not + // supported. + void insertStatementsInParentBlock(const TIntermSequence &insertions); + + // Same as above, but supports simultaneous insertion of statements before and after the node + // currently being traversed. + void insertStatementsInParentBlock(const TIntermSequence &insertionsBefore, + const TIntermSequence &insertionsAfter); + + // Helper to create a temporary symbol node with the given qualifier. + TIntermSymbol *createTempSymbol(const TType &type, TQualifier qualifier); + // Helper to create a temporary symbol node. + TIntermSymbol *createTempSymbol(const TType &type); + // Create a node that declares but doesn't initialize a temporary symbol. + TIntermAggregate *createTempDeclaration(const TType &type); + // Create a node that initializes the current temporary symbol with initializer having the given qualifier. + TIntermAggregate *createTempInitDeclaration(TIntermTyped *initializer, TQualifier qualifier); + // Create a node that initializes the current temporary symbol with initializer. + TIntermAggregate *createTempInitDeclaration(TIntermTyped *initializer); + // Create a node that assigns rightNode to the current temporary symbol. + TIntermBinary *createTempAssignment(TIntermTyped *rightNode); + // Increment temporary symbol index. + void nextTemporaryIndex(); + + private: + struct ParentBlock + { + ParentBlock(TIntermAggregate *nodeIn, TIntermSequence::size_type posIn) + : node(nodeIn), + pos(posIn) + { + } + + TIntermAggregate *node; + TIntermSequence::size_type pos; + }; + // All the code blocks from the root to the current node's parent during traversal. + std::vector mParentBlockStack; + + unsigned int *mTemporaryIndex; +}; + +// Traverser parent class that tracks where a node is a destination of a write operation and so is +// required to be an l-value. +class TLValueTrackingTraverser : public TIntermTraverser +{ + public: + TLValueTrackingTraverser(bool preVisit, + bool inVisit, + bool postVisit, + const TSymbolTable &symbolTable, + int shaderVersion) + : TIntermTraverser(preVisit, inVisit, postVisit), + mOperatorRequiresLValue(false), + mInFunctionCallOutParameter(false), + mSymbolTable(symbolTable), + mShaderVersion(shaderVersion) + { + } + virtual ~TLValueTrackingTraverser() {} + + void traverseBinary(TIntermBinary *node) override; + void traverseUnary(TIntermUnary *node) override; + void traverseAggregate(TIntermAggregate *node) override; + + protected: + bool isLValueRequiredHere() const + { + return mOperatorRequiresLValue || mInFunctionCallOutParameter; + } + + // Return true if the prototype or definition of the function being called has been encountered + // during traversal. + bool isInFunctionMap(const TIntermAggregate *callNode) const; + + private: + // Track whether an l-value is required in the node that is currently being traversed by the + // surrounding operator. + // Use isLValueRequiredHere to check all conditions which require an l-value. + void setOperatorRequiresLValue(bool lValueRequired) + { + mOperatorRequiresLValue = lValueRequired; + } + bool operatorRequiresLValue() const { return mOperatorRequiresLValue; } + + // Add a function encountered during traversal to the function map. + void addToFunctionMap(const TName &name, TIntermSequence *paramSequence); + + // Return the parameters sequence from the function definition or prototype. + TIntermSequence *getFunctionParameters(const TIntermAggregate *callNode); + + // Track whether an l-value is required inside a function call. + void setInFunctionCallOutParameter(bool inOutParameter); + bool isInFunctionCallOutParameter() const; + + bool mOperatorRequiresLValue; + bool mInFunctionCallOutParameter; + + struct TNameComparator + { + bool operator()(const TName &a, const TName &b) const + { + int compareResult = a.getString().compare(b.getString()); + if (compareResult != 0) + return compareResult < 0; + // Internal functions may have same names as non-internal functions. + return !a.isInternal() && b.isInternal(); + } + }; + + // Map from mangled function names to their parameter sequences + TMap mFunctionMap; + + const TSymbolTable &mSymbolTable; + const int mShaderVersion; }; // @@ -697,15 +956,15 @@ class TMaxDepthTraverser : public TIntermTraverser public: POOL_ALLOCATOR_NEW_DELETE(); TMaxDepthTraverser(int depthLimit) - : TIntermTraverser(true, true, false, false), + : TIntermTraverser(true, true, false), mDepthLimit(depthLimit) { } - virtual bool visitBinary(Visit, TIntermBinary *) { return depthCheck(); } - virtual bool visitUnary(Visit, TIntermUnary *) { return depthCheck(); } - virtual bool visitSelection(Visit, TIntermSelection *) { return depthCheck(); } - virtual bool visitAggregate(Visit, TIntermAggregate *) { return depthCheck(); } - virtual bool visitLoop(Visit, TIntermLoop *) { return depthCheck(); } - virtual bool visitBranch(Visit, TIntermBranch *) { return depthCheck(); } + bool visitBinary(Visit, TIntermBinary *) override { return depthCheck(); } + bool visitUnary(Visit, TIntermUnary *) override { return depthCheck(); } + bool visitSelection(Visit, TIntermSelection *) override { return depthCheck(); } + bool visitAggregate(Visit, TIntermAggregate *) override { return depthCheck(); } + bool visitLoop(Visit, TIntermLoop *) override { return depthCheck(); } + bool visitBranch(Visit, TIntermBranch *) override { return depthCheck(); } protected: bool depthCheck() const { return mMaxDepth < mDepthLimit; } diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/IntermTraverse.cpp b/Source/ThirdParty/ANGLE/src/compiler/translator/IntermTraverse.cpp index 7a7efb71f5f0..7b588ca5a312 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/IntermTraverse.cpp +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/IntermTraverse.cpp @@ -5,6 +5,187 @@ // #include "compiler/translator/IntermNode.h" +#include "compiler/translator/InfoSink.h" +#include "compiler/translator/SymbolTable.h" + +void TIntermSymbol::traverse(TIntermTraverser *it) +{ + it->traverseSymbol(this); +} + +void TIntermRaw::traverse(TIntermTraverser *it) +{ + it->traverseRaw(this); +} + +void TIntermConstantUnion::traverse(TIntermTraverser *it) +{ + it->traverseConstantUnion(this); +} + +void TIntermBinary::traverse(TIntermTraverser *it) +{ + it->traverseBinary(this); +} + +void TIntermUnary::traverse(TIntermTraverser *it) +{ + it->traverseUnary(this); +} + +void TIntermSelection::traverse(TIntermTraverser *it) +{ + it->traverseSelection(this); +} + +void TIntermSwitch::traverse(TIntermTraverser *it) +{ + it->traverseSwitch(this); +} + +void TIntermCase::traverse(TIntermTraverser *it) +{ + it->traverseCase(this); +} + +void TIntermAggregate::traverse(TIntermTraverser *it) +{ + it->traverseAggregate(this); +} + +void TIntermLoop::traverse(TIntermTraverser *it) +{ + it->traverseLoop(this); +} + +void TIntermBranch::traverse(TIntermTraverser *it) +{ + it->traverseBranch(this); +} + +void TIntermTraverser::pushParentBlock(TIntermAggregate *node) +{ + mParentBlockStack.push_back(ParentBlock(node, 0)); +} + +void TIntermTraverser::incrementParentBlockPos() +{ + ++mParentBlockStack.back().pos; +} + +void TIntermTraverser::popParentBlock() +{ + ASSERT(!mParentBlockStack.empty()); + mParentBlockStack.pop_back(); +} + +void TIntermTraverser::insertStatementsInParentBlock(const TIntermSequence &insertions) +{ + TIntermSequence emptyInsertionsAfter; + insertStatementsInParentBlock(insertions, emptyInsertionsAfter); +} + +void TIntermTraverser::insertStatementsInParentBlock(const TIntermSequence &insertionsBefore, + const TIntermSequence &insertionsAfter) +{ + ASSERT(!mParentBlockStack.empty()); + NodeInsertMultipleEntry insert(mParentBlockStack.back().node, mParentBlockStack.back().pos, + insertionsBefore, insertionsAfter); + mInsertions.push_back(insert); +} + +TIntermSymbol *TIntermTraverser::createTempSymbol(const TType &type, TQualifier qualifier) +{ + // Each traversal uses at most one temporary variable, so the index stays the same within a single traversal. + TInfoSinkBase symbolNameOut; + ASSERT(mTemporaryIndex != nullptr); + symbolNameOut << "s" << (*mTemporaryIndex); + TString symbolName = symbolNameOut.c_str(); + + TIntermSymbol *node = new TIntermSymbol(0, symbolName, type); + node->setInternal(true); + node->getTypePointer()->setQualifier(qualifier); + return node; +} + +TIntermSymbol *TIntermTraverser::createTempSymbol(const TType &type) +{ + return createTempSymbol(type, EvqTemporary); +} + +TIntermAggregate *TIntermTraverser::createTempDeclaration(const TType &type) +{ + TIntermAggregate *tempDeclaration = new TIntermAggregate(EOpDeclaration); + tempDeclaration->getSequence()->push_back(createTempSymbol(type)); + return tempDeclaration; +} + +TIntermAggregate *TIntermTraverser::createTempInitDeclaration(TIntermTyped *initializer, TQualifier qualifier) +{ + ASSERT(initializer != nullptr); + TIntermSymbol *tempSymbol = createTempSymbol(initializer->getType(), qualifier); + TIntermAggregate *tempDeclaration = new TIntermAggregate(EOpDeclaration); + TIntermBinary *tempInit = new TIntermBinary(EOpInitialize); + tempInit->setLeft(tempSymbol); + tempInit->setRight(initializer); + tempInit->setType(tempSymbol->getType()); + tempDeclaration->getSequence()->push_back(tempInit); + return tempDeclaration; +} + +TIntermAggregate *TIntermTraverser::createTempInitDeclaration(TIntermTyped *initializer) +{ + return createTempInitDeclaration(initializer, EvqTemporary); +} + +TIntermBinary *TIntermTraverser::createTempAssignment(TIntermTyped *rightNode) +{ + ASSERT(rightNode != nullptr); + TIntermSymbol *tempSymbol = createTempSymbol(rightNode->getType()); + TIntermBinary *assignment = new TIntermBinary(EOpAssign); + assignment->setLeft(tempSymbol); + assignment->setRight(rightNode); + assignment->setType(tempSymbol->getType()); + return assignment; +} + +void TIntermTraverser::useTemporaryIndex(unsigned int *temporaryIndex) +{ + mTemporaryIndex = temporaryIndex; +} + +void TIntermTraverser::nextTemporaryIndex() +{ + ASSERT(mTemporaryIndex != nullptr); + ++(*mTemporaryIndex); +} + +void TLValueTrackingTraverser::addToFunctionMap(const TName &name, TIntermSequence *paramSequence) +{ + mFunctionMap[name] = paramSequence; +} + +bool TLValueTrackingTraverser::isInFunctionMap(const TIntermAggregate *callNode) const +{ + ASSERT(callNode->getOp() == EOpFunctionCall); + return (mFunctionMap.find(callNode->getNameObj()) != mFunctionMap.end()); +} + +TIntermSequence *TLValueTrackingTraverser::getFunctionParameters(const TIntermAggregate *callNode) +{ + ASSERT(isInFunctionMap(callNode)); + return mFunctionMap[callNode->getNameObj()]; +} + +void TLValueTrackingTraverser::setInFunctionCallOutParameter(bool inOutParameter) +{ + mInFunctionCallOutParameter = inOutParameter; +} + +bool TLValueTrackingTraverser::isInFunctionCallOutParameter() const +{ + return mInFunctionCallOutParameter; +} // // Traverse the intermediate representation tree, and @@ -16,308 +197,473 @@ // if preVisit is turned on and the type specific function // returns false. // -// preVisit, postVisit, and rightToLeft control what order -// nodes are visited in. -// // // Traversal functions for terminals are straighforward.... // -void TIntermSymbol::traverse(TIntermTraverser *it) +void TIntermTraverser::traverseSymbol(TIntermSymbol *node) { - it->visitSymbol(this); + visitSymbol(node); } -void TIntermConstantUnion::traverse(TIntermTraverser *it) +void TIntermTraverser::traverseConstantUnion(TIntermConstantUnion *node) { - it->visitConstantUnion(this); + visitConstantUnion(node); } // // Traverse a binary node. // -void TIntermBinary::traverse(TIntermTraverser *it) +void TIntermTraverser::traverseBinary(TIntermBinary *node) { bool visit = true; // // visit the node before children if pre-visiting. // - if (it->preVisit) - visit = it->visitBinary(PreVisit, this); + if (preVisit) + visit = visitBinary(PreVisit, node); // // Visit the children, in the right order. // if (visit) { - it->incrementDepth(this); + incrementDepth(node); - if (it->rightToLeft) - { - if (mRight) - mRight->traverse(it); + if (node->getLeft()) + node->getLeft()->traverse(this); - if (it->inVisit) - visit = it->visitBinary(InVisit, this); + if (inVisit) + visit = visitBinary(InVisit, node); - if (visit && mLeft) - mLeft->traverse(it); - } - else + if (visit && node->getRight()) + node->getRight()->traverse(this); + + decrementDepth(); + } + + // + // Visit the node after the children, if requested and the traversal + // hasn't been cancelled yet. + // + if (visit && postVisit) + visitBinary(PostVisit, node); +} + +void TLValueTrackingTraverser::traverseBinary(TIntermBinary *node) +{ + bool visit = true; + + // + // visit the node before children if pre-visiting. + // + if (preVisit) + visit = visitBinary(PreVisit, node); + + // + // Visit the children, in the right order. + // + if (visit) + { + incrementDepth(node); + + // Some binary operations like indexing can be inside an expression which must be an + // l-value. + bool parentOperatorRequiresLValue = operatorRequiresLValue(); + bool parentInFunctionCallOutParameter = isInFunctionCallOutParameter(); + if (node->isAssignment()) { - if (mLeft) - mLeft->traverse(it); + ASSERT(!isLValueRequiredHere()); + setOperatorRequiresLValue(true); + } - if (it->inVisit) - visit = it->visitBinary(InVisit, this); + if (node->getLeft()) + node->getLeft()->traverse(this); - if (visit && mRight) - mRight->traverse(it); + if (inVisit) + visit = visitBinary(InVisit, node); + + if (node->isAssignment()) + setOperatorRequiresLValue(false); + + // Index is not required to be an l-value even when the surrounding expression is required + // to be an l-value. + TOperator op = node->getOp(); + if (op == EOpIndexDirect || op == EOpIndexDirectInterfaceBlock || + op == EOpIndexDirectStruct || op == EOpIndexIndirect) + { + setOperatorRequiresLValue(false); + setInFunctionCallOutParameter(false); } - it->decrementDepth(); + if (visit && node->getRight()) + node->getRight()->traverse(this); + + setOperatorRequiresLValue(parentOperatorRequiresLValue); + setInFunctionCallOutParameter(parentInFunctionCallOutParameter); + + decrementDepth(); } // // Visit the node after the children, if requested and the traversal // hasn't been cancelled yet. // - if (visit && it->postVisit) - it->visitBinary(PostVisit, this); + if (visit && postVisit) + visitBinary(PostVisit, node); } // // Traverse a unary node. Same comments in binary node apply here. // -void TIntermUnary::traverse(TIntermTraverser *it) +void TIntermTraverser::traverseUnary(TIntermUnary *node) { bool visit = true; - if (it->preVisit) - visit = it->visitUnary(PreVisit, this); + if (preVisit) + visit = visitUnary(PreVisit, node); + + if (visit) + { + incrementDepth(node); - if (visit) { - it->incrementDepth(this); - mOperand->traverse(it); - it->decrementDepth(); + node->getOperand()->traverse(this); + + decrementDepth(); } - if (visit && it->postVisit) - it->visitUnary(PostVisit, this); + if (visit && postVisit) + visitUnary(PostVisit, node); +} + +void TLValueTrackingTraverser::traverseUnary(TIntermUnary *node) +{ + bool visit = true; + + if (preVisit) + visit = visitUnary(PreVisit, node); + + if (visit) + { + incrementDepth(node); + + ASSERT(!operatorRequiresLValue()); + switch (node->getOp()) + { + case EOpPostIncrement: + case EOpPostDecrement: + case EOpPreIncrement: + case EOpPreDecrement: + setOperatorRequiresLValue(true); + break; + default: + break; + } + + node->getOperand()->traverse(this); + + setOperatorRequiresLValue(false); + + decrementDepth(); + } + + if (visit && postVisit) + visitUnary(PostVisit, node); } // // Traverse an aggregate node. Same comments in binary node apply here. // -void TIntermAggregate::traverse(TIntermTraverser *it) +void TIntermTraverser::traverseAggregate(TIntermAggregate *node) { bool visit = true; - if (it->preVisit) - visit = it->visitAggregate(PreVisit, this); + TIntermSequence *sequence = node->getSequence(); + + if (preVisit) + visit = visitAggregate(PreVisit, node); if (visit) { - it->incrementDepth(this); + incrementDepth(node); - if (it->rightToLeft) + if (node->getOp() == EOpSequence) + pushParentBlock(node); + + for (auto *child : *sequence) { - for (TIntermSequence::reverse_iterator sit = mSequence.rbegin(); - sit != mSequence.rend(); sit++) + child->traverse(this); + if (visit && inVisit) { - (*sit)->traverse(it); + if (child != sequence->back()) + visit = visitAggregate(InVisit, node); + } + + if (node->getOp() == EOpSequence) + incrementParentBlockPos(); + } + + if (node->getOp() == EOpSequence) + popParentBlock(); + + decrementDepth(); + } - if (visit && it->inVisit) + if (visit && postVisit) + visitAggregate(PostVisit, node); +} + +void TLValueTrackingTraverser::traverseAggregate(TIntermAggregate *node) +{ + bool visit = true; + + TIntermSequence *sequence = node->getSequence(); + switch (node->getOp()) + { + case EOpFunction: + { + TIntermAggregate *params = sequence->front()->getAsAggregate(); + ASSERT(params != nullptr); + ASSERT(params->getOp() == EOpParameters); + addToFunctionMap(node->getNameObj(), params->getSequence()); + break; + } + case EOpPrototype: + addToFunctionMap(node->getNameObj(), sequence); + break; + default: + break; + } + + if (preVisit) + visit = visitAggregate(PreVisit, node); + + if (visit) + { + bool inFunctionMap = false; + if (node->getOp() == EOpFunctionCall) + { + inFunctionMap = isInFunctionMap(node); + if (!inFunctionMap) + { + // The function is not user-defined - it is likely built-in texture function. + // Assume that those do not have out parameters. + setInFunctionCallOutParameter(false); + } + } + + incrementDepth(node); + + if (inFunctionMap) + { + TIntermSequence *params = getFunctionParameters(node); + TIntermSequence::iterator paramIter = params->begin(); + for (auto *child : *sequence) + { + ASSERT(paramIter != params->end()); + TQualifier qualifier = (*paramIter)->getAsTyped()->getQualifier(); + setInFunctionCallOutParameter(qualifier == EvqOut || qualifier == EvqInOut); + + child->traverse(this); + if (visit && inVisit) { - if (*sit != mSequence.front()) - visit = it->visitAggregate(InVisit, this); + if (child != sequence->back()) + visit = visitAggregate(InVisit, node); } + + ++paramIter; } + + setInFunctionCallOutParameter(false); } else { - for (TIntermSequence::iterator sit = mSequence.begin(); - sit != mSequence.end(); sit++) + if (node->getOp() == EOpSequence) + pushParentBlock(node); + + // Find the built-in function corresponding to this op so that we can determine the + // in/out qualifiers of its parameters. + TFunction *builtInFunc = nullptr; + TString opString = GetOperatorString(node->getOp()); + if (!node->isConstructor() && !opString.empty()) + { + // The return type doesn't affect the mangled name of the function, which is used + // to look it up from the symbol table. + TType dummyReturnType; + TFunction call(&opString, &dummyReturnType, node->getOp()); + for (auto *child : *sequence) + { + TType *paramType = child->getAsTyped()->getTypePointer(); + TConstParameter p(paramType); + call.addParameter(p); + } + + TSymbol *sym = mSymbolTable.findBuiltIn(call.getMangledName(), mShaderVersion); + if (sym != nullptr && sym->isFunction()) + { + builtInFunc = static_cast(sym); + ASSERT(builtInFunc->getParamCount() == sequence->size()); + } + } + + size_t paramIndex = 0; + + for (auto *child : *sequence) { - (*sit)->traverse(it); + TQualifier qualifier = EvqIn; + if (builtInFunc != nullptr) + qualifier = builtInFunc->getParam(paramIndex).type->getQualifier(); + setInFunctionCallOutParameter(qualifier == EvqOut || qualifier == EvqInOut); + child->traverse(this); - if (visit && it->inVisit) + if (visit && inVisit) { - if (*sit != mSequence.back()) - visit = it->visitAggregate(InVisit, this); + if (child != sequence->back()) + visit = visitAggregate(InVisit, node); } + + if (node->getOp() == EOpSequence) + incrementParentBlockPos(); + + ++paramIndex; } + + setInFunctionCallOutParameter(false); + + if (node->getOp() == EOpSequence) + popParentBlock(); } - it->decrementDepth(); + decrementDepth(); } - if (visit && it->postVisit) - it->visitAggregate(PostVisit, this); + if (visit && postVisit) + visitAggregate(PostVisit, node); } // // Traverse a selection node. Same comments in binary node apply here. // -void TIntermSelection::traverse(TIntermTraverser *it) +void TIntermTraverser::traverseSelection(TIntermSelection *node) { bool visit = true; - if (it->preVisit) - visit = it->visitSelection(PreVisit, this); + if (preVisit) + visit = visitSelection(PreVisit, node); if (visit) { - it->incrementDepth(this); - if (it->rightToLeft) - { - if (mFalseBlock) - mFalseBlock->traverse(it); - if (mTrueBlock) - mTrueBlock->traverse(it); - mCondition->traverse(it); - } - else - { - mCondition->traverse(it); - if (mTrueBlock) - mTrueBlock->traverse(it); - if (mFalseBlock) - mFalseBlock->traverse(it); - } - it->decrementDepth(); + incrementDepth(node); + node->getCondition()->traverse(this); + if (node->getTrueBlock()) + node->getTrueBlock()->traverse(this); + if (node->getFalseBlock()) + node->getFalseBlock()->traverse(this); + decrementDepth(); } - if (visit && it->postVisit) - it->visitSelection(PostVisit, this); + if (visit && postVisit) + visitSelection(PostVisit, node); } // // Traverse a switch node. Same comments in binary node apply here. // -void TIntermSwitch::traverse(TIntermTraverser *it) +void TIntermTraverser::traverseSwitch(TIntermSwitch *node) { bool visit = true; - if (it->preVisit) - visit = it->visitSwitch(PreVisit, this); + if (preVisit) + visit = visitSwitch(PreVisit, node); if (visit) { - it->incrementDepth(this); - if (it->rightToLeft) - { - if (mStatementList) - mStatementList->traverse(it); - if (it->inVisit) - visit = it->visitSwitch(InVisit, this); - if (visit) - mInit->traverse(it); - } - else - { - mInit->traverse(it); - if (it->inVisit) - visit = it->visitSwitch(InVisit, this); - if (visit && mStatementList) - mStatementList->traverse(it); - } - it->decrementDepth(); + incrementDepth(node); + node->getInit()->traverse(this); + if (inVisit) + visit = visitSwitch(InVisit, node); + if (visit && node->getStatementList()) + node->getStatementList()->traverse(this); + decrementDepth(); } - if (visit && it->postVisit) - it->visitSwitch(PostVisit, this); + if (visit && postVisit) + visitSwitch(PostVisit, node); } // -// Traverse a switch node. Same comments in binary node apply here. +// Traverse a case node. Same comments in binary node apply here. // -void TIntermCase::traverse(TIntermTraverser *it) +void TIntermTraverser::traverseCase(TIntermCase *node) { bool visit = true; - if (it->preVisit) - visit = it->visitCase(PreVisit, this); + if (preVisit) + visit = visitCase(PreVisit, node); - if (visit && mCondition) - mCondition->traverse(it); + if (visit && node->getCondition()) + node->getCondition()->traverse(this); - if (visit && it->postVisit) - it->visitCase(PostVisit, this); + if (visit && postVisit) + visitCase(PostVisit, node); } // // Traverse a loop node. Same comments in binary node apply here. // -void TIntermLoop::traverse(TIntermTraverser *it) +void TIntermTraverser::traverseLoop(TIntermLoop *node) { bool visit = true; - if (it->preVisit) - visit = it->visitLoop(PreVisit, this); + if (preVisit) + visit = visitLoop(PreVisit, node); if (visit) { - it->incrementDepth(this); - - if (it->rightToLeft) - { - if (mExpr) - mExpr->traverse(it); - - if (mBody) - mBody->traverse(it); - - if (mCond) - mCond->traverse(it); + incrementDepth(node); - if (mInit) - mInit->traverse(it); - } - else - { - if (mInit) - mInit->traverse(it); + if (node->getInit()) + node->getInit()->traverse(this); - if (mCond) - mCond->traverse(it); + if (node->getCondition()) + node->getCondition()->traverse(this); - if (mBody) - mBody->traverse(it); + if (node->getBody()) + node->getBody()->traverse(this); - if (mExpr) - mExpr->traverse(it); - } + if (node->getExpression()) + node->getExpression()->traverse(this); - it->decrementDepth(); + decrementDepth(); } - if (visit && it->postVisit) - it->visitLoop(PostVisit, this); + if (visit && postVisit) + visitLoop(PostVisit, node); } // // Traverse a branch node. Same comments in binary node apply here. // -void TIntermBranch::traverse(TIntermTraverser *it) +void TIntermTraverser::traverseBranch(TIntermBranch *node) { bool visit = true; - if (it->preVisit) - visit = it->visitBranch(PreVisit, this); + if (preVisit) + visit = visitBranch(PreVisit, node); - if (visit && mExpression) { - it->incrementDepth(this); - mExpression->traverse(it); - it->decrementDepth(); + if (visit && node->getExpression()) + { + incrementDepth(node); + node->getExpression()->traverse(this); + decrementDepth(); } - if (visit && it->postVisit) - it->visitBranch(PostVisit, this); + if (visit && postVisit) + visitBranch(PostVisit, node); } -void TIntermRaw::traverse(TIntermTraverser *it) +void TIntermTraverser::traverseRaw(TIntermRaw *node) { - it->visitRaw(this); + visitRaw(node); } diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/Intermediate.cpp b/Source/ThirdParty/ANGLE/src/compiler/translator/Intermediate.cpp index a44f5b74af38..0adb7212b767 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/Intermediate.cpp +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/Intermediate.cpp @@ -12,7 +12,7 @@ #include #include -#include "compiler/translator/intermediate.h" +#include "compiler/translator/Intermediate.h" #include "compiler/translator/SymbolTable.h" //////////////////////////////////////////////////////////////////////////// @@ -57,19 +57,10 @@ TIntermTyped *TIntermediate::addBinaryMath( if (!node->promote(mInfoSink)) return NULL; - // // See if we can fold constants. - // - TIntermConstantUnion *leftTempConstant = left->getAsConstantUnion(); - TIntermConstantUnion *rightTempConstant = right->getAsConstantUnion(); - if (leftTempConstant && rightTempConstant) - { - TIntermTyped *typedReturnNode = - leftTempConstant->fold(node->getOp(), rightTempConstant, mInfoSink); - - if (typedReturnNode) - return typedReturnNode; - } + TIntermTyped *foldedNode = node->fold(mInfoSink); + if (foldedNode) + return foldedNode; return node; } @@ -129,10 +120,6 @@ TIntermTyped *TIntermediate::addIndex( TIntermTyped *TIntermediate::addUnaryMath( TOperator op, TIntermTyped *child, const TSourceLoc &line, const TType *funcReturnType) { - TIntermConstantUnion *childTempConstant = 0; - if (child->getAsConstantUnion()) - childTempConstant = child->getAsConstantUnion(); - // // Make a new node for the operator. // @@ -141,13 +128,9 @@ TIntermTyped *TIntermediate::addUnaryMath( node->setOperand(child); node->promote(funcReturnType); - if (childTempConstant) - { - TIntermTyped *newChild = childTempConstant->fold(op, nullptr, mInfoSink); - - if (newChild) - return newChild; - } + TIntermTyped *foldedNode = node->fold(mInfoSink); + if (foldedNode) + return foldedNode; return node; } @@ -246,6 +229,22 @@ TIntermAggregate *TIntermediate::makeAggregate( return aggNode; } +// If the input node is nullptr, return nullptr. +// If the input node is a sequence (block) node, return it. +// If the input node is not a sequence node, put it inside a sequence node and return that. +TIntermAggregate *TIntermediate::ensureSequence(TIntermNode *node) +{ + if (node == nullptr) + return nullptr; + TIntermAggregate *aggNode = node->getAsAggregate(); + if (aggNode != nullptr && aggNode->getOp() == EOpSequence) + return aggNode; + + aggNode = makeAggregate(node, node->getLine()); + aggNode->setOp(EOpSequence); + return aggNode; +} + // // For "if" test nodes. There are three children; a condition, // a true path, and a false path. The two paths are in the @@ -261,7 +260,7 @@ TIntermNode *TIntermediate::addSelection( // test now. // - if (cond->getAsTyped() && cond->getAsTyped()->getAsConstantUnion()) + if (cond->getAsConstantUnion()) { if (cond->getAsConstantUnion()->getBConst(0) == true) { @@ -276,28 +275,38 @@ TIntermNode *TIntermediate::addSelection( } TIntermSelection *node = new TIntermSelection( - cond, nodePair.node1, nodePair.node2); + cond, ensureSequence(nodePair.node1), ensureSequence(nodePair.node2)); node->setLine(line); return node; } -TIntermTyped *TIntermediate::addComma( - TIntermTyped *left, TIntermTyped *right, const TSourceLoc &line) +TIntermTyped *TIntermediate::addComma(TIntermTyped *left, + TIntermTyped *right, + const TSourceLoc &line, + int shaderVersion) { - if (left->getType().getQualifier() == EvqConst && - right->getType().getQualifier() == EvqConst) + TQualifier resultQualifier = EvqConst; + // ESSL3.00 section 12.43: The result of a sequence operator is not a constant-expression. + if (shaderVersion >= 300 || left->getQualifier() != EvqConst || + right->getQualifier() != EvqConst) + { + resultQualifier = EvqTemporary; + } + + TIntermTyped *commaNode = nullptr; + if (!left->hasSideEffects()) { - return right; + commaNode = right; } else { - TIntermTyped *commaAggregate = growAggregate(left, right, line); - commaAggregate->getAsAggregate()->setOp(EOpComma); - commaAggregate->setType(right->getType()); - commaAggregate->getTypePointer()->setQualifier(EvqTemporary); - return commaAggregate; + commaNode = growAggregate(left, right, line); + commaNode->getAsAggregate()->setOp(EOpComma); + commaNode->setType(right->getType()); } + commaNode->getTypePointer()->setQualifier(resultQualifier); + return commaNode; } // @@ -310,27 +319,33 @@ TIntermTyped *TIntermediate::addComma( TIntermTyped *TIntermediate::addSelection(TIntermTyped *cond, TIntermTyped *trueBlock, TIntermTyped *falseBlock, const TSourceLoc &line) { - // Right now it's safe to fold ternary operators only when all operands - // are constant. If only the condition is constant, it's theoretically - // possible to fold the ternary operator, but that requires making sure - // that the node returned from here won't be treated as a constant - // expression in case the node that gets eliminated was not a constant - // expression. - if (cond->getAsConstantUnion() && - trueBlock->getAsConstantUnion() && - falseBlock->getAsConstantUnion()) + TQualifier resultQualifier = EvqTemporary; + if (cond->getQualifier() == EvqConst && trueBlock->getQualifier() == EvqConst && + falseBlock->getQualifier() == EvqConst) + { + resultQualifier = EvqConst; + } + // Note that the node resulting from here can be a constant union without being qualified as + // constant. + if (cond->getAsConstantUnion()) { if (cond->getAsConstantUnion()->getBConst(0)) + { + trueBlock->getTypePointer()->setQualifier(resultQualifier); return trueBlock; + } else + { + falseBlock->getTypePointer()->setQualifier(resultQualifier); return falseBlock; + } } // // Make a selection node. // TIntermSelection *node = new TIntermSelection(cond, trueBlock, falseBlock, trueBlock->getType()); - node->getTypePointer()->setQualifier(EvqTemporary); + node->getTypePointer()->setQualifier(resultQualifier); node->setLine(line); return node; @@ -360,8 +375,9 @@ TIntermCase *TIntermediate::addCase( // Returns the constant union node created. // -TIntermConstantUnion *TIntermediate::addConstantUnion( - TConstantUnion *constantUnion, const TType &type, const TSourceLoc &line) +TIntermConstantUnion *TIntermediate::addConstantUnion(const TConstantUnion *constantUnion, + const TType &type, + const TSourceLoc &line) { TIntermConstantUnion *node = new TIntermConstantUnion(constantUnion, type); node->setLine(line); @@ -399,7 +415,7 @@ TIntermNode *TIntermediate::addLoop( TLoopType type, TIntermNode *init, TIntermTyped *cond, TIntermTyped *expr, TIntermNode *body, const TSourceLoc &line) { - TIntermNode *node = new TIntermLoop(type, init, cond, expr, body); + TIntermNode *node = new TIntermLoop(type, init, cond, expr, ensureSequence(body)); node->setLine(line); return node; @@ -427,17 +443,66 @@ TIntermBranch* TIntermediate::addBranch( // This is to be executed once the final root is put on top by the parsing // process. // -bool TIntermediate::postProcess(TIntermNode *root) +TIntermAggregate *TIntermediate::postProcess(TIntermNode *root) { - if (root == NULL) - return true; + if (root == nullptr) + return nullptr; // - // First, finish off the top level sequence, if any + // Finish off the top level sequence, if any // TIntermAggregate *aggRoot = root->getAsAggregate(); - if (aggRoot && aggRoot->getOp() == EOpNull) + if (aggRoot != nullptr && aggRoot->getOp() == EOpNull) + { aggRoot->setOp(EOpSequence); + } + else if (aggRoot == nullptr || aggRoot->getOp() != EOpSequence) + { + aggRoot = new TIntermAggregate(EOpSequence); + aggRoot->setLine(root->getLine()); + aggRoot->getSequence()->push_back(root); + } + + return aggRoot; +} + +TIntermTyped *TIntermediate::foldAggregateBuiltIn(TIntermAggregate *aggregate) +{ + switch (aggregate->getOp()) + { + case EOpAtan: + case EOpPow: + case EOpMod: + case EOpMin: + case EOpMax: + case EOpClamp: + case EOpMix: + case EOpStep: + case EOpSmoothStep: + case EOpMul: + case EOpOuterProduct: + case EOpLessThan: + case EOpLessThanEqual: + case EOpGreaterThan: + case EOpGreaterThanEqual: + case EOpVectorEqual: + case EOpVectorNotEqual: + case EOpDistance: + case EOpDot: + case EOpCross: + case EOpFaceForward: + case EOpReflect: + case EOpRefract: + return aggregate->fold(mInfoSink); + default: + // TODO: Add support for folding array constructors + if (aggregate->isConstructor() && !aggregate->isArray()) + { + return aggregate->fold(mInfoSink); + } + // Constant folding not supported for the built-in. + return nullptr; + } - return true; + return nullptr; } diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/NodeSearch.h b/Source/ThirdParty/ANGLE/src/compiler/translator/NodeSearch.h index 8ffed614c3b8..b13b1baabb08 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/NodeSearch.h +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/NodeSearch.h @@ -19,7 +19,8 @@ class NodeSearchTraverser : public TIntermTraverser { public: NodeSearchTraverser() - : mFound(false) + : TIntermTraverser(true, false, false), + mFound(false) {} bool found() const { return mFound; } @@ -53,28 +54,6 @@ class FindDiscard : public NodeSearchTraverser } }; -class FindSideEffectRewriting : public NodeSearchTraverser -{ - public: - virtual bool visitBinary(Visit visit, TIntermBinary *node) - { - switch (node->getOp()) - { - case EOpLogicalOr: - case EOpLogicalAnd: - if (node->getRight()->hasSideEffects()) - { - mFound = true; - } - break; - - default: break; - } - - return !mFound; - } -}; - } #endif // COMPILER_TRANSLATOR_NODESEARCH_H_ diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/Operator.cpp b/Source/ThirdParty/ANGLE/src/compiler/translator/Operator.cpp index ae4512bd44de..20e47f290e15 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/Operator.cpp +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/Operator.cpp @@ -164,7 +164,13 @@ const char *GetOperatorString(TOperator op) case EOpConstructUVec3: return "uvec3"; case EOpConstructUVec4: return "uvec4"; case EOpConstructMat2: return "mat2"; + case EOpConstructMat2x3: return "mat2x3"; + case EOpConstructMat2x4: return "mat2x4"; + case EOpConstructMat3x2: return "mat3x2"; case EOpConstructMat3: return "mat3"; + case EOpConstructMat3x4: return "mat3x4"; + case EOpConstructMat4x2: return "mat4x2"; + case EOpConstructMat4x3: return "mat4x3"; case EOpConstructMat4: return "mat4"; // Note: EOpConstructStruct can't be handled here diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/Operator.h b/Source/ThirdParty/ANGLE/src/compiler/translator/Operator.h index 8290f952fc57..b0efb8f48bd4 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/Operator.h +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/Operator.h @@ -15,7 +15,6 @@ enum TOperator EOpNull, // if in a node, should only mean a node is still being built EOpSequence, // denotes a list of statements, or parameters, etc. EOpFunctionCall, - EOpInternalFunctionCall, // Call to an internal helper function EOpFunction, // For function definition EOpParameters, // an aggregate listing the parameters to a function @@ -192,7 +191,13 @@ enum TOperator EOpConstructUVec3, EOpConstructUVec4, EOpConstructMat2, + EOpConstructMat2x3, + EOpConstructMat2x4, + EOpConstructMat3x2, EOpConstructMat3, + EOpConstructMat3x4, + EOpConstructMat4x2, + EOpConstructMat4x3, EOpConstructMat4, EOpConstructStruct, diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/OutputESSL.h b/Source/ThirdParty/ANGLE/src/compiler/translator/OutputESSL.h index 813f1e944bda..c5a963499e86 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/OutputESSL.h +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/OutputESSL.h @@ -21,7 +21,8 @@ class TOutputESSL : public TOutputGLSLBase bool forceHighp); protected: - virtual bool writeVariablePrecision(TPrecision precision); + bool writeVariablePrecision(TPrecision precision) override; + private: bool mForceHighp; }; diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/OutputGLSL.cpp b/Source/ThirdParty/ANGLE/src/compiler/translator/OutputGLSL.cpp index e9266ee6b53c..431425020a74 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/OutputGLSL.cpp +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/OutputGLSL.cpp @@ -45,6 +45,14 @@ void TOutputGLSL::visitSymbol(TIntermSymbol *node) { out << "webgl_FragData"; } + else if (symbol == "gl_SecondaryFragColorEXT") + { + out << "angle_SecondaryFragColor"; + } + else if (symbol == "gl_SecondaryFragDataEXT") + { + out << "angle_SecondaryFragData"; + } else { TOutputGLSLBase::visitSymbol(node); @@ -67,6 +75,7 @@ TString TOutputGLSL::translateTextureFunction(TString &name) "texture2DProj", "textureProj", "texture2DLod", "textureLod", "texture2DProjLod", "textureProjLod", + "texture2DRect", "texture", "textureCube", "texture", "textureCubeLod", "textureLod", // Extensions diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/OutputGLSL.h b/Source/ThirdParty/ANGLE/src/compiler/translator/OutputGLSL.h index 21b2d079d39d..9b1aca4eabe9 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/OutputGLSL.h +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/OutputGLSL.h @@ -21,9 +21,9 @@ class TOutputGLSL : public TOutputGLSLBase ShShaderOutput output); protected: - virtual bool writeVariablePrecision(TPrecision); - virtual void visitSymbol(TIntermSymbol* node); - virtual TString translateTextureFunction(TString& name); + bool writeVariablePrecision(TPrecision) override; + void visitSymbol(TIntermSymbol *node) override; + TString translateTextureFunction(TString &name) override; }; #endif // COMPILER_TRANSLATOR_OUTPUTGLSL_H_ diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/OutputGLSLBase.cpp b/Source/ThirdParty/ANGLE/src/compiler/translator/OutputGLSLBase.cpp index 5bf6bb25bc34..f048b050b7eb 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/OutputGLSLBase.cpp +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/OutputGLSLBase.cpp @@ -89,9 +89,31 @@ void TOutputGLSLBase::writeBuiltInFunctionTriplet( writeTriplet(visit, preString.c_str(), ", ", ")"); } +void TOutputGLSLBase::writeLayoutQualifier(const TType &type) +{ + if (type.getQualifier() == EvqFragmentOut || type.getQualifier() == EvqVertexIn) + { + const TLayoutQualifier &layoutQualifier = type.getLayoutQualifier(); + if (layoutQualifier.location >= 0) + { + TInfoSinkBase &out = objSink(); + out << "layout(location = " << layoutQualifier.location << ") "; + } + } +} + void TOutputGLSLBase::writeVariableType(const TType &type) { TInfoSinkBase &out = objSink(); + if (type.isInvariant()) + { + out << "invariant "; + } + if (type.getBasicType() == EbtInterfaceBlock) + { + TInterfaceBlock *interfaceBlock = type.getInterfaceBlock(); + declareInterfaceBlockLayout(interfaceBlock); + } TQualifier qualifier = type.getQualifier(); if (qualifier != EvqTemporary && qualifier != EvqGlobal) { @@ -100,19 +122,13 @@ void TOutputGLSLBase::writeVariableType(const TType &type) switch (qualifier) { case EvqAttribute: - out << "in" << " "; + out << "in "; break; case EvqVaryingIn: - out << "in" << " "; + out << "in "; break; case EvqVaryingOut: - out << "out" << " "; - break; - case EvqInvariantVaryingIn: - out << "invariant in" << " "; - break; - case EvqInvariantVaryingOut: - out << "invariant out" << " "; + out << "out "; break; default: out << type.getQualifierString() << " "; @@ -136,6 +152,11 @@ void TOutputGLSLBase::writeVariableType(const TType &type) mDeclaredStructs.insert(structure->uniqueId()); } } + else if (type.getBasicType() == EbtInterfaceBlock) + { + TInterfaceBlock *interfaceBlock = type.getInterfaceBlock(); + declareInterfaceBlock(interfaceBlock); + } else { if (writeVariablePrecision(type.getPrecision())) @@ -375,6 +396,22 @@ bool TOutputGLSLBase::visitBinary(Visit visit, TIntermBinary *node) visitChildren = false; } break; + case EOpIndexDirectInterfaceBlock: + if (visit == InVisit) + { + out << "."; + const TInterfaceBlock *interfaceBlock = node->getLeft()->getType().getInterfaceBlock(); + const TIntermConstantUnion *index = node->getRight()->getAsConstantUnion(); + const TField *field = interfaceBlock->fields()[index->getIConst(0)]; + + TString fieldName = field->name(); + ASSERT(!mSymbolTable.findBuiltIn(interfaceBlock->name(), mShaderVersion)); + fieldName = hashName(fieldName); + + out << fieldName; + visitChildren = false; + } + break; case EOpVectorSwizzle: if (visit == InVisit) { @@ -785,7 +822,7 @@ bool TOutputGLSLBase::visitAggregate(Visit visit, TIntermAggregate *node) out << arrayBrackets(type); } - out << " " << hashFunctionName(node->getName()); + out << " " << hashFunctionNameIfNeeded(node->getNameObj()); out << "("; writeFunctionParameters(*(node->getSequence())); @@ -803,7 +840,7 @@ bool TOutputGLSLBase::visitAggregate(Visit visit, TIntermAggregate *node) out << arrayBrackets(type); } - out << " " << hashFunctionName(node->getName()); + out << " " << hashFunctionNameIfNeeded(node->getNameObj()); incrementDepth(node); // Function definition node contains one or two children nodes @@ -832,16 +869,7 @@ bool TOutputGLSLBase::visitAggregate(Visit visit, TIntermAggregate *node) case EOpFunctionCall: // Function call. if (visit == PreVisit) - out << hashFunctionName(node->getName()) << "("; - else if (visit == InVisit) - out << ", "; - else - out << ")"; - break; - case EOpInternalFunctionCall: - // Function call to an internal helper function. - if (visit == PreVisit) - out << node->getName() << "("; + out << hashFunctionNameIfNeeded(node->getNameObj()) << "("; else if (visit == InVisit) out << ", "; else @@ -861,6 +889,7 @@ bool TOutputGLSLBase::visitAggregate(Visit visit, TIntermAggregate *node) { const TIntermSequence &sequence = *(node->getSequence()); const TIntermTyped *variable = sequence.front()->getAsTyped(); + writeLayoutQualifier(variable->getType()); writeVariableType(variable->getType()); out << " "; mDeclaringVariables = true; @@ -923,12 +952,42 @@ bool TOutputGLSLBase::visitAggregate(Visit visit, TIntermAggregate *node) case EOpConstructIVec4: writeConstructorTriplet(visit, node->getType(), "ivec4"); break; + case EOpConstructUInt: + writeConstructorTriplet(visit, node->getType(), "uint"); + break; + case EOpConstructUVec2: + writeConstructorTriplet(visit, node->getType(), "uvec2"); + break; + case EOpConstructUVec3: + writeConstructorTriplet(visit, node->getType(), "uvec3"); + break; + case EOpConstructUVec4: + writeConstructorTriplet(visit, node->getType(), "uvec4"); + break; case EOpConstructMat2: writeConstructorTriplet(visit, node->getType(), "mat2"); break; + case EOpConstructMat2x3: + writeConstructorTriplet(visit, node->getType(), "mat2x3"); + break; + case EOpConstructMat2x4: + writeConstructorTriplet(visit, node->getType(), "mat2x4"); + break; + case EOpConstructMat3x2: + writeConstructorTriplet(visit, node->getType(), "mat3x2"); + break; case EOpConstructMat3: writeConstructorTriplet(visit, node->getType(), "mat3"); break; + case EOpConstructMat3x4: + writeConstructorTriplet(visit, node->getType(), "mat3x4"); + break; + case EOpConstructMat4x2: + writeConstructorTriplet(visit, node->getType(), "mat4x2"); + break; + case EOpConstructMat4x3: + writeConstructorTriplet(visit, node->getType(), "mat4x3"); + break; case EOpConstructMat4: writeConstructorTriplet(visit, node->getType(), "mat4"); break; @@ -1030,8 +1089,12 @@ bool TOutputGLSLBase::visitLoop(Visit visit, TIntermLoop *node) TInfoSinkBase &out = objSink(); incrementDepth(node); - // Loop header. + TLoopType loopType = node->getType(); + + // Only for loops can be unrolled + ASSERT(!node->getUnrollFlag() || loopType == ELoopFor); + if (loopType == ELoopFor) // for loop { if (!node->getUnrollFlag()) @@ -1048,6 +1111,8 @@ bool TOutputGLSLBase::visitLoop(Visit visit, TIntermLoop *node) if (node->getExpression()) node->getExpression()->traverse(this); out << ")\n"; + + visitCodeBlock(node->getBody()); } else { @@ -1060,6 +1125,16 @@ bool TOutputGLSLBase::visitLoop(Visit visit, TIntermLoop *node) out << "for (int " << name << " = 0; " << name << " < 1; " << "++" << name << ")\n"; + + out << "{\n"; + mLoopUnrollStack.push(node); + while (mLoopUnrollStack.satisfiesLoopCondition()) + { + visitCodeBlock(node->getBody()); + mLoopUnrollStack.step(); + } + mLoopUnrollStack.pop(); + out << "}\n"; } } else if (loopType == ELoopWhile) // while loop @@ -1068,39 +1143,22 @@ bool TOutputGLSLBase::visitLoop(Visit visit, TIntermLoop *node) ASSERT(node->getCondition() != NULL); node->getCondition()->traverse(this); out << ")\n"; + + visitCodeBlock(node->getBody()); } else // do-while loop { ASSERT(loopType == ELoopDoWhile); out << "do\n"; - } - // Loop body. - if (node->getUnrollFlag()) - { - out << "{\n"; - mLoopUnrollStack.push(node); - while (mLoopUnrollStack.satisfiesLoopCondition()) - { - visitCodeBlock(node->getBody()); - mLoopUnrollStack.step(); - } - mLoopUnrollStack.pop(); - out << "}\n"; - } - else - { visitCodeBlock(node->getBody()); - } - // Loop footer. - if (loopType == ELoopDoWhile) // do-while loop - { out << "while ("; ASSERT(node->getCondition() != NULL); node->getCondition()->traverse(this); out << ");\n"; } + decrementDepth(); // No need to visit children. They have been already processed in @@ -1155,6 +1213,10 @@ TString TOutputGLSLBase::getTypeName(const TType &type) { out << "mat"; out << type.getNominalSize(); + if (type.getSecondarySize() != type.getNominalSize()) + { + out << "x" << type.getSecondarySize(); + } } else if (type.isVector()) { @@ -1169,6 +1231,9 @@ TString TOutputGLSLBase::getTypeName(const TType &type) case EbtBool: out << "bvec"; break; + case EbtUInt: + out << "uvec"; + break; default: UNREACHABLE(); } @@ -1203,12 +1268,16 @@ TString TOutputGLSLBase::hashVariableName(const TString &name) return hashName(name); } -TString TOutputGLSLBase::hashFunctionName(const TString &mangled_name) +TString TOutputGLSLBase::hashFunctionNameIfNeeded(const TName &mangledName) { - TString name = TFunction::unmangleName(mangled_name); - if (mSymbolTable.findBuiltIn(mangled_name, mShaderVersion) != NULL || name == "main") + TString mangledStr = mangledName.getString(); + TString name = TFunction::unmangleName(mangledStr); + if (mSymbolTable.findBuiltIn(mangledStr, mShaderVersion) != nullptr || name == "main") return translateTextureFunction(name); - return hashName(name); + if (mangledName.isInternal()) + return name; + else + return hashName(name); } bool TOutputGLSLBase::structDeclared(const TStructure *structure) const @@ -1241,3 +1310,70 @@ void TOutputGLSLBase::declareStruct(const TStructure *structure) out << "}"; } +void TOutputGLSLBase::declareInterfaceBlockLayout(const TInterfaceBlock *interfaceBlock) +{ + TInfoSinkBase &out = objSink(); + + out << "layout("; + + switch (interfaceBlock->blockStorage()) + { + case EbsUnspecified: + case EbsShared: + // Default block storage is shared. + out << "shared"; + break; + + case EbsPacked: + out << "packed"; + break; + + case EbsStd140: + out << "std140"; + break; + + default: + UNREACHABLE(); + break; + } + + out << ", "; + + switch (interfaceBlock->matrixPacking()) + { + case EmpUnspecified: + case EmpColumnMajor: + // Default matrix packing is column major. + out << "column_major"; + break; + + case EmpRowMajor: + out << "row_major"; + break; + + default: + UNREACHABLE(); + break; + } + + out << ") "; +} + +void TOutputGLSLBase::declareInterfaceBlock(const TInterfaceBlock *interfaceBlock) +{ + TInfoSinkBase &out = objSink(); + + out << hashName(interfaceBlock->name()) << "{\n"; + const TFieldList &fields = interfaceBlock->fields(); + for (size_t i = 0; i < fields.size(); ++i) + { + const TField *field = fields[i]; + if (writeVariablePrecision(field->type()->getPrecision())) + out << " "; + out << getTypeName(*field->type()) << " " << hashName(field->name()); + if (field->type()->isArray()) + out << arrayBrackets(*field->type()); + out << ";\n"; + } + out << "}"; +} diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/OutputGLSLBase.h b/Source/ThirdParty/ANGLE/src/compiler/translator/OutputGLSLBase.h index 1f3558eeeb38..2ae82d15b214 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/OutputGLSLBase.h +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/OutputGLSLBase.h @@ -32,6 +32,7 @@ class TOutputGLSLBase : public TIntermTraverser protected: TInfoSinkBase &objSink() { return mObjSink; } void writeTriplet(Visit visit, const char *preStr, const char *inStr, const char *postStr); + void writeLayoutQualifier(const TType &type); void writeVariableType(const TType &type); virtual bool writeVariablePrecision(TPrecision precision) = 0; void writeFunctionParameters(const TIntermSequence &args); @@ -39,16 +40,16 @@ class TOutputGLSLBase : public TIntermTraverser void writeConstructorTriplet(Visit visit, const TType &type, const char *constructorBaseType); TString getTypeName(const TType &type); - virtual void visitSymbol(TIntermSymbol *node); - virtual void visitConstantUnion(TIntermConstantUnion *node); - virtual bool visitBinary(Visit visit, TIntermBinary *node); - virtual bool visitUnary(Visit visit, TIntermUnary *node); - virtual bool visitSelection(Visit visit, TIntermSelection *node); - virtual bool visitSwitch(Visit visit, TIntermSwitch *node); - virtual bool visitCase(Visit visit, TIntermCase *node); - virtual bool visitAggregate(Visit visit, TIntermAggregate *node); - virtual bool visitLoop(Visit visit, TIntermLoop *node); - virtual bool visitBranch(Visit visit, TIntermBranch *node); + void visitSymbol(TIntermSymbol *node) override; + void visitConstantUnion(TIntermConstantUnion *node) override; + bool visitBinary(Visit visit, TIntermBinary *node) override; + bool visitUnary(Visit visit, TIntermUnary *node) override; + bool visitSelection(Visit visit, TIntermSelection *node) override; + bool visitSwitch(Visit visit, TIntermSwitch *node) override; + bool visitCase(Visit visit, TIntermCase *node) override; + bool visitAggregate(Visit visit, TIntermAggregate *node) override; + bool visitLoop(Visit visit, TIntermLoop *node) override; + bool visitBranch(Visit visit, TIntermBranch *node) override; void visitCodeBlock(TIntermNode *node); @@ -57,8 +58,8 @@ class TOutputGLSLBase : public TIntermTraverser TString hashName(const TString &name); // Same as hashName(), but without hashing built-in variables. TString hashVariableName(const TString &name); - // Same as hashName(), but without hashing built-in functions. - TString hashFunctionName(const TString &mangled_name); + // Same as hashName(), but without hashing built-in functions and with unmangling. + TString hashFunctionNameIfNeeded(const TName &mangledName); // Used to translate function names for differences between ESSL and GLSL virtual TString translateTextureFunction(TString &name) { return name; } @@ -66,6 +67,9 @@ class TOutputGLSLBase : public TIntermTraverser bool structDeclared(const TStructure *structure) const; void declareStruct(const TStructure *structure); + void declareInterfaceBlockLayout(const TInterfaceBlock *interfaceBlock); + void declareInterfaceBlock(const TInterfaceBlock *interfaceBlock); + void writeBuiltInFunctionTriplet(Visit visit, const char *preStr, bool useEmulatedFunction); TInfoSinkBase &mObjSink; diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/OutputHLSL.cpp b/Source/ThirdParty/ANGLE/src/compiler/translator/OutputHLSL.cpp index cb7931ae2efa..cd95b02fd048 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/OutputHLSL.cpp +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/OutputHLSL.cpp @@ -19,36 +19,109 @@ #include "compiler/translator/InfoSink.h" #include "compiler/translator/NodeSearch.h" #include "compiler/translator/RemoveSwitchFallThrough.h" -#include "compiler/translator/RewriteElseBlocks.h" #include "compiler/translator/SearchSymbol.h" #include "compiler/translator/StructureHLSL.h" #include "compiler/translator/TranslatorHLSL.h" -#include "compiler/translator/UnfoldShortCircuit.h" #include "compiler/translator/UniformHLSL.h" #include "compiler/translator/UtilsHLSL.h" #include "compiler/translator/blocklayout.h" #include "compiler/translator/util.h" -namespace sh +namespace { -TString OutputHLSL::TextureFunction::name() const +bool IsSequence(TIntermNode *node) { - TString name = "gl_texture"; + return node->getAsAggregate() != nullptr && node->getAsAggregate()->getOp() == EOpSequence; +} - if (IsSampler2D(sampler)) - { - name += "2D"; - } - else if (IsSampler3D(sampler)) - { - name += "3D"; +void WriteSingleConstant(TInfoSinkBase &out, const TConstantUnion *const constUnion) +{ + ASSERT(constUnion != nullptr); + switch (constUnion->getType()) + { + case EbtFloat: + out << std::min(FLT_MAX, std::max(-FLT_MAX, constUnion->getFConst())); + break; + case EbtInt: + out << constUnion->getIConst(); + break; + case EbtUInt: + out << constUnion->getUConst(); + break; + case EbtBool: + out << constUnion->getBConst(); + break; + default: + UNREACHABLE(); } - else if (IsSamplerCube(sampler)) +} + +const TConstantUnion *WriteConstantUnionArray(TInfoSinkBase &out, + const TConstantUnion *const constUnion, + const size_t size) +{ + const TConstantUnion *constUnionIterated = constUnion; + for (size_t i = 0; i < size; i++, constUnionIterated++) { - name += "Cube"; + WriteSingleConstant(out, constUnionIterated); + + if (i != size - 1) + { + out << ", "; + } } - else UNREACHABLE(); + return constUnionIterated; +} + +void OutputIntTexCoordWrap(TInfoSinkBase &out, + const char *wrapMode, + const char *size, + const TString &texCoord, + const TString &texCoordOffset, + const char *texCoordOutName) +{ + // GLES 3.0.4 table 3.22 specifies how the wrap modes work. We don't use the formulas verbatim + // but rather use equivalent formulas that map better to HLSL. + out << "int " << texCoordOutName << ";\n"; + out << "float " << texCoordOutName << "Offset = " << texCoord << " + float(" << texCoordOffset + << ") / " << size << ";\n"; + + // CLAMP_TO_EDGE + out << "if (" << wrapMode << " == 1)\n"; + out << "{\n"; + out << " " << texCoordOutName << " = clamp(int(floor(" << size << " * " << texCoordOutName + << "Offset)), 0, int(" << size << ") - 1);\n"; + out << "}\n"; + + // MIRRORED_REPEAT + out << "else if (" << wrapMode << " == 3)\n"; + out << "{\n"; + out << " float coordWrapped = 1.0 - abs(frac(abs(" << texCoordOutName + << "Offset) * 0.5) * 2.0 - 1.0);\n"; + out << " " << texCoordOutName << " = int(floor(" << size << " * coordWrapped));\n"; + out << "}\n"; + + // REPEAT + out << "else\n"; + out << "{\n"; + out << " " << texCoordOutName << " = int(floor(" << size << " * frac(" << texCoordOutName + << "Offset)));\n"; + out << "}\n"; +} + +} // namespace + +namespace sh +{ + +TString OutputHLSL::TextureFunction::name() const +{ + TString name = "gl_texture"; + + // We need to include full the sampler type in the function name to make the signature unique + // on D3D11, where samplers are passed to texture functions as indices. + name += TextureTypeSuffix(this->sampler); if (proj) { @@ -107,11 +180,10 @@ OutputHLSL::OutputHLSL(sh::GLenum shaderType, int shaderVersion, mExtensionBehavior(extensionBehavior), mSourcePath(sourcePath), mOutputType(outputType), - mNumRenderTargets(numRenderTargets), mCompileOptions(compileOptions), + mNumRenderTargets(numRenderTargets), mCurrentFunctionMetadata(nullptr) { - mUnfoldShortCircuit = new UnfoldShortCircuit(this); mInsideFunction = false; mUsesFragColor = false; @@ -122,6 +194,7 @@ OutputHLSL::OutputHLSL(sh::GLenum shaderType, int shaderVersion, mUsesFrontFacing = false; mUsesPointSize = false; mUsesInstanceID = false; + mUsesVertexID = false; mUsesFragDepth = false; mUsesXor = false; mUsesDiscardRewriting = false; @@ -139,7 +212,7 @@ OutputHLSL::OutputHLSL(sh::GLenum shaderType, int shaderVersion, mStructureHLSL = new StructureHLSL; mUniformHLSL = new UniformHLSL(mStructureHLSL, outputType, uniforms); - if (mOutputType == SH_HLSL9_OUTPUT) + if (mOutputType == SH_HLSL_3_0_OUTPUT) { // Fragment shaders need dx_DepthRange, dx_ViewCoords and dx_DepthFront. // Vertex shaders need a slightly different set: dx_DepthRange, dx_ViewCoords and dx_ViewAdjust. @@ -153,7 +226,6 @@ OutputHLSL::OutputHLSL(sh::GLenum shaderType, int shaderVersion, OutputHLSL::~OutputHLSL() { - SafeDelete(mUnfoldShortCircuit); SafeDelete(mStructureHLSL); SafeDelete(mUniformHLSL); for (auto &eqFunction : mStructEqualityFunctions) @@ -171,13 +243,6 @@ void OutputHLSL::output(TIntermNode *treeRoot, TInfoSinkBase &objSink) const std::vector &flaggedStructs = FlagStd140ValueStructs(treeRoot); makeFlaggedStructMaps(flaggedStructs); - // Work around D3D9 bug that would manifest in vertex shaders with selection blocks which - // use a vertex attribute as a condition, and some related computation in the else block. - if (mOutputType == SH_HLSL9_OUTPUT && mShaderType == GL_VERTEX_SHADER) - { - RewriteElseBlocks(treeRoot); - } - BuiltInFunctionEmulator builtInFunctionEmulator; InitBuiltInFunctionEmulatorForHLSL(&builtInFunctionEmulator); builtInFunctionEmulator.MarkBuiltInFunctionsForEmulation(treeRoot); @@ -194,14 +259,10 @@ void OutputHLSL::output(TIntermNode *treeRoot, TInfoSinkBase &objSink) mInfoSinkStack.pop(); mInfoSinkStack.push(&mFooter); - if (!mDeferredGlobalInitializers.empty()) - { - writeDeferredGlobalInitializers(mFooter); - } mInfoSinkStack.pop(); mInfoSinkStack.push(&mHeader); - header(&builtInFunctionEmulator); + header(mHeader, &builtInFunctionEmulator); mInfoSinkStack.pop(); objSink << mHeader.c_str(); @@ -296,10 +357,8 @@ TString OutputHLSL::structInitializerString(int indent, const TStructure &struct return init; } -void OutputHLSL::header(const BuiltInFunctionEmulator *builtInFunctionEmulator) +void OutputHLSL::header(TInfoSinkBase &out, const BuiltInFunctionEmulator *builtInFunctionEmulator) { - TInfoSinkBase &out = getInfoSink(); - TString varyings; TString attributes; TString flaggedStructs; @@ -336,7 +395,7 @@ void OutputHLSL::header(const BuiltInFunctionEmulator *builtInFunctionEmulator) out << mStructureHLSL->structsHeader(); - out << mUniformHLSL->uniformsHeader(mOutputType, mReferencedUniforms); + mUniformHLSL->uniformsHeader(out, mOutputType, mReferencedUniforms); out << mUniformHLSL->interfaceBlocksHeader(mReferencedInterfaceBlocks); if (!mEqualityFunctions.empty()) @@ -459,7 +518,7 @@ void OutputHLSL::header(const BuiltInFunctionEmulator *builtInFunctionEmulator) "\n"; } - if (mOutputType == SH_HLSL11_OUTPUT) + if (mOutputType == SH_HLSL_4_1_OUTPUT || mOutputType == SH_HLSL_4_0_FL9_3_OUTPUT) { out << "cbuffer DriverConstants : register(b1)\n" "{\n"; @@ -479,6 +538,18 @@ void OutputHLSL::header(const BuiltInFunctionEmulator *builtInFunctionEmulator) out << " float3 dx_DepthFront : packoffset(c2);\n"; } + if (mUsesFragCoord) + { + // dx_ViewScale is only used in the fragment shader to correct + // the value for glFragCoord if necessary + out << " float2 dx_ViewScale : packoffset(c3);\n"; + } + + if (mOutputType == SH_HLSL_4_1_OUTPUT) + { + mUniformHLSL->samplerMetadataUniforms(out, "c4"); + } + out << "};\n"; } else @@ -547,6 +618,11 @@ void OutputHLSL::header(const BuiltInFunctionEmulator *builtInFunctionEmulator) out << "static int gl_InstanceID;"; } + if (mUsesVertexID) + { + out << "static int gl_VertexID;"; + } + out << "\n" "// Varyings\n"; out << varyings; @@ -563,7 +639,7 @@ void OutputHLSL::header(const BuiltInFunctionEmulator *builtInFunctionEmulator) "\n"; } - if (mOutputType == SH_HLSL11_OUTPUT) + if (mOutputType == SH_HLSL_4_1_OUTPUT || mOutputType == SH_HLSL_4_0_FL9_3_OUTPUT) { out << "cbuffer DriverConstants : register(b1)\n" "{\n"; @@ -573,11 +649,18 @@ void OutputHLSL::header(const BuiltInFunctionEmulator *builtInFunctionEmulator) out << " float3 dx_DepthRange : packoffset(c0);\n"; } - // dx_ViewAdjust and dx_ViewCoords will only be used in Feature Level 9 shaders. - // However, we declare it for all shaders (including Feature Level 10+). - // The bytecode is the same whether we declare it or not, since D3DCompiler removes it if it's unused. + // dx_ViewAdjust and dx_ViewCoords will only be used in Feature Level 9 + // shaders. However, we declare it for all shaders (including Feature Level 10+). + // The bytecode is the same whether we declare it or not, since D3DCompiler removes it + // if it's unused. out << " float4 dx_ViewAdjust : packoffset(c1);\n"; out << " float2 dx_ViewCoords : packoffset(c2);\n"; + out << " float2 dx_ViewScale : packoffset(c3);\n"; + + if (mOutputType == SH_HLSL_4_1_OUTPUT) + { + mUniformHLSL->samplerMetadataUniforms(out, "c4"); + } out << "};\n" "\n"; @@ -663,7 +746,7 @@ void OutputHLSL::header(const BuiltInFunctionEmulator *builtInFunctionEmulator) // Argument list int hlslCoords = 4; - if (mOutputType == SH_HLSL9_OUTPUT) + if (mOutputType == SH_HLSL_3_0_OUTPUT) { switch(textureFunction->sampler) { @@ -682,29 +765,20 @@ void OutputHLSL::header(const BuiltInFunctionEmulator *builtInFunctionEmulator) default: UNREACHABLE(); } } - else if (mOutputType == SH_HLSL11_OUTPUT) + else { - switch(textureFunction->sampler) + hlslCoords = HLSLTextureCoordsCount(textureFunction->sampler); + if (mOutputType == SH_HLSL_4_0_FL9_3_OUTPUT) { - case EbtSampler2D: out << "Texture2D x, SamplerState s"; hlslCoords = 2; break; - case EbtSampler3D: out << "Texture3D x, SamplerState s"; hlslCoords = 3; break; - case EbtSamplerCube: out << "TextureCube x, SamplerState s"; hlslCoords = 3; break; - case EbtSampler2DArray: out << "Texture2DArray x, SamplerState s"; hlslCoords = 3; break; - case EbtISampler2D: out << "Texture2D x, SamplerState s"; hlslCoords = 2; break; - case EbtISampler3D: out << "Texture3D x, SamplerState s"; hlslCoords = 3; break; - case EbtISamplerCube: out << "Texture2DArray x, SamplerState s"; hlslCoords = 3; break; - case EbtISampler2DArray: out << "Texture2DArray x, SamplerState s"; hlslCoords = 3; break; - case EbtUSampler2D: out << "Texture2D x, SamplerState s"; hlslCoords = 2; break; - case EbtUSampler3D: out << "Texture3D x, SamplerState s"; hlslCoords = 3; break; - case EbtUSamplerCube: out << "Texture2DArray x, SamplerState s"; hlslCoords = 3; break; - case EbtUSampler2DArray: out << "Texture2DArray x, SamplerState s"; hlslCoords = 3; break; - case EbtSampler2DShadow: out << "Texture2D x, SamplerComparisonState s"; hlslCoords = 2; break; - case EbtSamplerCubeShadow: out << "TextureCube x, SamplerComparisonState s"; hlslCoords = 3; break; - case EbtSampler2DArrayShadow: out << "Texture2DArray x, SamplerComparisonState s"; hlslCoords = 3; break; - default: UNREACHABLE(); + out << TextureString(textureFunction->sampler) << " x, " + << SamplerString(textureFunction->sampler) << " s"; + } + else + { + ASSERT(mOutputType == SH_HLSL_4_1_OUTPUT); + out << "const uint samplerIndex"; } } - else UNREACHABLE(); if (textureFunction->method == TextureFunction::FETCH) // Integer coordinates { @@ -795,25 +869,56 @@ void OutputHLSL::header(const BuiltInFunctionEmulator *builtInFunctionEmulator) out << ")\n" "{\n"; + // In some cases we use a variable to store the texture/sampler objects, but to work around + // a D3D11 compiler bug related to discard inside a loop that is conditional on texture + // sampling we need to call the function directly on a reference to the array. The bug was + // found using dEQP-GLES3.functional.shaders.discard*loop_texture* tests. + TString textureReference("x"); + TString samplerReference("s"); + if (mOutputType == SH_HLSL_4_1_OUTPUT) + { + TString suffix = TextureGroupSuffix(textureFunction->sampler); + if (TextureGroup(textureFunction->sampler) == HLSL_TEXTURE_2D) + { + textureReference = TString("textures") + suffix + "[samplerIndex]"; + samplerReference = TString("samplers") + suffix + "[samplerIndex]"; + } + else + { + out << " const uint textureIndex = samplerIndex - textureIndexOffset" << suffix + << ";\n"; + textureReference = TString("textures") + suffix + "[textureIndex]"; + out << " const uint samplerArrayIndex = samplerIndex - samplerIndexOffset" + << suffix << ";\n"; + samplerReference = TString("samplers") + suffix + "[samplerArrayIndex]"; + } + } + if (textureFunction->method == TextureFunction::SIZE) { + out << "int baseLevel = samplerMetadata[samplerIndex].baseLevel;\n"; if (IsSampler2D(textureFunction->sampler) || IsSamplerCube(textureFunction->sampler)) { - if (IsSamplerArray(textureFunction->sampler)) + if (IsSamplerArray(textureFunction->sampler) || + (IsIntegerSampler(textureFunction->sampler) && + IsSamplerCube(textureFunction->sampler))) { out << " uint width; uint height; uint layers; uint numberOfLevels;\n" - " x.GetDimensions(lod, width, height, layers, numberOfLevels);\n"; + << " " << textureReference << ".GetDimensions(baseLevel + lod, width, " + "height, layers, numberOfLevels);\n"; } else { out << " uint width; uint height; uint numberOfLevels;\n" - " x.GetDimensions(lod, width, height, numberOfLevels);\n"; + << " " << textureReference + << ".GetDimensions(baseLevel + lod, width, height, numberOfLevels);\n"; } } else if (IsSampler3D(textureFunction->sampler)) { out << " uint width; uint height; uint depth; uint numberOfLevels;\n" - " x.GetDimensions(lod, width, height, depth, numberOfLevels);\n"; + << " " << textureReference + << ".GetDimensions(baseLevel + lod, width, height, depth, numberOfLevels);\n"; } else UNREACHABLE(); @@ -839,13 +944,40 @@ void OutputHLSL::header(const BuiltInFunctionEmulator *builtInFunctionEmulator) } else { + TString texCoordX("t.x"); + TString texCoordY("t.y"); + TString texCoordZ("t.z"); + TString proj = ""; + + if (textureFunction->proj) + { + switch (textureFunction->coords) + { + case 3: + proj = " / t.z"; + break; + case 4: + proj = " / t.w"; + break; + default: + UNREACHABLE(); + } + if (proj != "") + { + texCoordX = "(" + texCoordX + proj + ")"; + texCoordY = "(" + texCoordY + proj + ")"; + texCoordZ = "(" + texCoordZ + proj + ")"; + } + } + if (IsIntegerSampler(textureFunction->sampler) && IsSamplerCube(textureFunction->sampler)) { out << " float width; float height; float layers; float levels;\n"; out << " uint mip = 0;\n"; - out << " x.GetDimensions(mip, width, height, layers, levels);\n"; + out << " " << textureReference + << ".GetDimensions(mip, width, height, layers, levels);\n"; out << " bool xMajor = abs(t.x) > abs(t.y) && abs(t.x) > abs(t.z);\n"; out << " bool yMajor = abs(t.y) > abs(t.z) && abs(t.y) > abs(t.x);\n"; @@ -866,6 +998,63 @@ void OutputHLSL::header(const BuiltInFunctionEmulator *builtInFunctionEmulator) out << " t.x = (u * 0.5f / m) + 0.5f;\n"; out << " t.y = (v * 0.5f / m) + 0.5f;\n"; + + // Mip level computation. + if (textureFunction->method == TextureFunction::IMPLICIT || + textureFunction->method == TextureFunction::LOD || + textureFunction->method == TextureFunction::GRAD) + { + if (textureFunction->method == TextureFunction::IMPLICIT) + { + out << " float2 tSized = float2(t.x * width, t.y * height);\n" + " float2 dx = ddx(tSized);\n" + " float2 dy = ddy(tSized);\n" + " float lod = 0.5f * log2(max(dot(dx, dx), dot(dy, dy)));\n"; + } + else if (textureFunction->method == TextureFunction::GRAD) + { + // ESSL 3.00.6 spec section 8.8: "For the cube version, the partial + // derivatives of P are assumed to be in the coordinate system used before + // texture coordinates are projected onto the appropriate cube face." + // ddx[0] and ddy[0] are the derivatives of t.x passed into the function + // ddx[1] and ddy[1] are the derivatives of t.y passed into the function + // ddx[2] and ddy[2] are the derivatives of t.z passed into the function + // Determine the derivatives of u, v and m + out << " float dudx = xMajor ? ddx[2] : (yMajor && t.y < 0.0f ? -ddx[0] " + ": ddx[0]);\n" + " float dudy = xMajor ? ddy[2] : (yMajor && t.y < 0.0f ? -ddy[0] " + ": ddy[0]);\n" + " float dvdx = yMajor ? ddx[2] : (negative ? ddx[1] : -ddx[1]);\n" + " float dvdy = yMajor ? ddy[2] : (negative ? ddy[1] : -ddy[1]);\n" + " float dmdx = xMajor ? ddx[0] : (yMajor ? ddx[1] : ddx[2]);\n" + " float dmdy = xMajor ? ddy[0] : (yMajor ? ddy[1] : ddy[2]);\n"; + // Now determine the derivatives of the face coordinates, using the + // derivatives calculated above. + // d / dx (u(x) * 0.5 / m(x) + 0.5) + // = 0.5 * (m(x) * u'(x) - u(x) * m'(x)) / m(x)^2 + out << " float dfacexdx = 0.5f * (m * dudx - u * dmdx) / (m * m);\n" + " float dfaceydx = 0.5f * (m * dvdx - v * dmdx) / (m * m);\n" + " float dfacexdy = 0.5f * (m * dudy - u * dmdy) / (m * m);\n" + " float dfaceydy = 0.5f * (m * dvdy - v * dmdy) / (m * m);\n" + " float2 sizeVec = float2(width, height);\n" + " float2 faceddx = float2(dfacexdx, dfaceydx) * sizeVec;\n" + " float2 faceddy = float2(dfacexdy, dfaceydy) * sizeVec;\n"; + // Optimization: instead of: log2(max(length(faceddx), length(faceddy))) + // we compute: log2(max(length(faceddx)^2, length(faceddy)^2)) / 2 + out << " float lengthfaceddx2 = dot(faceddx, faceddx);\n" + " float lengthfaceddy2 = dot(faceddy, faceddy);\n" + " float lod = log2(max(lengthfaceddx2, lengthfaceddy2)) * " + "0.5f;\n"; + } + out << " mip = uint(min(max(round(lod), 0), levels - 1));\n" + << " " << textureReference + << ".GetDimensions(mip, width, height, layers, levels);\n"; + } + + // Convert from normalized floating-point to integer + texCoordX = "int(floor(width * frac(" + texCoordX + ")))"; + texCoordY = "int(floor(height * frac(" + texCoordY + ")))"; + texCoordZ = "face"; } else if (IsIntegerSampler(textureFunction->sampler) && textureFunction->method != TextureFunction::FETCH) @@ -886,11 +1075,13 @@ void OutputHLSL::header(const BuiltInFunctionEmulator *builtInFunctionEmulator) } else { + + out << " " << textureReference + << ".GetDimensions(0, width, height, layers, levels);\n"; if (textureFunction->method == TextureFunction::IMPLICIT || textureFunction->method == TextureFunction::BIAS) { - out << " x.GetDimensions(0, width, height, layers, levels);\n" - " float2 tSized = float2(t.x * width, t.y * height);\n" + out << " float2 tSized = float2(t.x * width, t.y * height);\n" " float dx = length(ddx(tSized));\n" " float dy = length(ddy(tSized));\n" " float lod = log2(max(dx, dy));\n"; @@ -902,14 +1093,18 @@ void OutputHLSL::header(const BuiltInFunctionEmulator *builtInFunctionEmulator) } else if (textureFunction->method == TextureFunction::GRAD) { - out << " x.GetDimensions(0, width, height, layers, levels);\n" - " float lod = log2(max(length(ddx), length(ddy)));\n"; + out << " float2 sizeVec = float2(width, height);\n" + " float2 sizeDdx = ddx * sizeVec;\n" + " float2 sizeDdy = ddy * sizeVec;\n" + " float lod = log2(max(dot(sizeDdx, sizeDdx), " + "dot(sizeDdy, sizeDdy))) * 0.5f;\n"; } out << " uint mip = uint(min(max(round(lod), 0), levels - 1));\n"; } - out << " x.GetDimensions(mip, width, height, layers, levels);\n"; + out << " " << textureReference + << ".GetDimensions(mip, width, height, layers, levels);\n"; } else { @@ -925,11 +1120,13 @@ void OutputHLSL::header(const BuiltInFunctionEmulator *builtInFunctionEmulator) } else { + out << " " << textureReference + << ".GetDimensions(0, width, height, levels);\n"; + if (textureFunction->method == TextureFunction::IMPLICIT || textureFunction->method == TextureFunction::BIAS) { - out << " x.GetDimensions(0, width, height, levels);\n" - " float2 tSized = float2(t.x * width, t.y * height);\n" + out << " float2 tSized = float2(t.x * width, t.y * height);\n" " float dx = length(ddx(tSized));\n" " float dy = length(ddy(tSized));\n" " float lod = log2(max(dx, dy));\n"; @@ -939,20 +1136,20 @@ void OutputHLSL::header(const BuiltInFunctionEmulator *builtInFunctionEmulator) out << " lod += bias;\n"; } } - else if (textureFunction->method == TextureFunction::LOD) - { - out << " x.GetDimensions(0, width, height, levels);\n"; - } else if (textureFunction->method == TextureFunction::GRAD) { - out << " x.GetDimensions(0, width, height, levels);\n" - " float lod = log2(max(length(ddx), length(ddy)));\n"; + out << " float2 sizeVec = float2(width, height);\n" + " float2 sizeDdx = ddx * sizeVec;\n" + " float2 sizeDdy = ddy * sizeVec;\n" + " float lod = log2(max(dot(sizeDdx, sizeDdx), " + "dot(sizeDdy, sizeDdy))) * 0.5f;\n"; } out << " uint mip = uint(min(max(round(lod), 0), levels - 1));\n"; } - out << " x.GetDimensions(mip, width, height, levels);\n"; + out << " " << textureReference + << ".GetDimensions(mip, width, height, levels);\n"; } } else if (IsSampler3D(textureFunction->sampler)) @@ -969,11 +1166,14 @@ void OutputHLSL::header(const BuiltInFunctionEmulator *builtInFunctionEmulator) } else { + out << " " << textureReference + << ".GetDimensions(0, width, height, depth, levels);\n"; + if (textureFunction->method == TextureFunction::IMPLICIT || textureFunction->method == TextureFunction::BIAS) { - out << " x.GetDimensions(0, width, height, depth, levels);\n" - " float3 tSized = float3(t.x * width, t.y * height, t.z * depth);\n" + out << " float3 tSized = float3(t.x * width, t.y * height, t.z * " + "depth);\n" " float dx = length(ddx(tSized));\n" " float dy = length(ddy(tSized));\n" " float lod = log2(max(dx, dy));\n"; @@ -985,22 +1185,67 @@ void OutputHLSL::header(const BuiltInFunctionEmulator *builtInFunctionEmulator) } else if (textureFunction->method == TextureFunction::GRAD) { - out << " x.GetDimensions(0, width, height, depth, levels);\n" - " float lod = log2(max(length(ddx), length(ddy)));\n"; + out << " float3 sizeVec = float3(width, height, depth);\n" + " float3 sizeDdx = ddx * sizeVec;\n" + " float3 sizeDdy = ddy * sizeVec;\n" + " float lod = log2(max(dot(sizeDdx, sizeDdx), dot(sizeDdy, " + "sizeDdy))) * 0.5f;\n"; } out << " uint mip = uint(min(max(round(lod), 0), levels - 1));\n"; } - out << " x.GetDimensions(mip, width, height, depth, levels);\n"; + out << " " << textureReference + << ".GetDimensions(mip, width, height, depth, levels);\n"; } else UNREACHABLE(); + + // Convert from normalized floating-point to integer + out << "int wrapS = samplerMetadata[samplerIndex].wrapModes & 0x3;\n"; + if (textureFunction->offset) + { + OutputIntTexCoordWrap(out, "wrapS", "width", texCoordX, "offset.x", "tix"); + } + else + { + OutputIntTexCoordWrap(out, "wrapS", "width", texCoordX, "0", "tix"); + } + texCoordX = "tix"; + out << "int wrapT = (samplerMetadata[samplerIndex].wrapModes >> 2) & 0x3;\n"; + if (textureFunction->offset) + { + OutputIntTexCoordWrap(out, "wrapT", "height", texCoordY, "offset.y", "tiy"); + } + else + { + OutputIntTexCoordWrap(out, "wrapT", "height", texCoordY, "0", "tiy"); + } + texCoordY = "tiy"; + + if (IsSamplerArray(textureFunction->sampler)) + { + texCoordZ = "int(max(0, min(layers - 1, floor(0.5 + t.z))))"; + } + else if (!IsSamplerCube(textureFunction->sampler) && + !IsSampler2D(textureFunction->sampler)) + { + out << "int wrapR = (samplerMetadata[samplerIndex].wrapModes >> 4) & 0x3;\n"; + if (textureFunction->offset) + { + OutputIntTexCoordWrap(out, "wrapR", "depth", texCoordZ, "offset.z", "tiz"); + } + else + { + OutputIntTexCoordWrap(out, "wrapR", "depth", texCoordZ, "0", "tiz"); + } + texCoordZ = "tiz"; + } } out << " return "; // HLSL intrinsic - if (mOutputType == SH_HLSL9_OUTPUT) + if (mOutputType == SH_HLSL_3_0_OUTPUT) { switch(textureFunction->sampler) { @@ -1011,45 +1256,71 @@ void OutputHLSL::header(const BuiltInFunctionEmulator *builtInFunctionEmulator) switch(textureFunction->method) { - case TextureFunction::IMPLICIT: out << "(s, "; break; - case TextureFunction::BIAS: out << "bias(s, "; break; - case TextureFunction::LOD: out << "lod(s, "; break; - case TextureFunction::LOD0: out << "lod(s, "; break; - case TextureFunction::LOD0BIAS: out << "lod(s, "; break; + case TextureFunction::IMPLICIT: + out << "(" << samplerReference << ", "; + break; + case TextureFunction::BIAS: + out << "bias(" << samplerReference << ", "; + break; + case TextureFunction::LOD: + out << "lod(" << samplerReference << ", "; + break; + case TextureFunction::LOD0: + out << "lod(" << samplerReference << ", "; + break; + case TextureFunction::LOD0BIAS: + out << "lod(" << samplerReference << ", "; + break; default: UNREACHABLE(); } } - else if (mOutputType == SH_HLSL11_OUTPUT) + else if (mOutputType == SH_HLSL_4_1_OUTPUT || mOutputType == SH_HLSL_4_0_FL9_3_OUTPUT) { if (textureFunction->method == TextureFunction::GRAD) { if (IsIntegerSampler(textureFunction->sampler)) { - out << "x.Load("; + out << "" << textureReference << ".Load("; } else if (IsShadowSampler(textureFunction->sampler)) { - out << "x.SampleCmpLevelZero(s, "; + out << "" << textureReference << ".SampleCmpLevelZero(" << samplerReference + << ", "; } else { - out << "x.SampleGrad(s, "; + out << "" << textureReference << ".SampleGrad(" << samplerReference << ", "; } } else if (IsIntegerSampler(textureFunction->sampler) || textureFunction->method == TextureFunction::FETCH) { - out << "x.Load("; + out << "" << textureReference << ".Load("; } else if (IsShadowSampler(textureFunction->sampler)) { switch(textureFunction->method) { - case TextureFunction::IMPLICIT: out << "x.SampleCmp(s, "; break; - case TextureFunction::BIAS: out << "x.SampleCmp(s, "; break; - case TextureFunction::LOD: out << "x.SampleCmp(s, "; break; - case TextureFunction::LOD0: out << "x.SampleCmpLevelZero(s, "; break; - case TextureFunction::LOD0BIAS: out << "x.SampleCmpLevelZero(s, "; break; + case TextureFunction::IMPLICIT: + out << "" << textureReference << ".SampleCmp(" << samplerReference + << ", "; + break; + case TextureFunction::BIAS: + out << "" << textureReference << ".SampleCmp(" << samplerReference + << ", "; + break; + case TextureFunction::LOD: + out << "" << textureReference << ".SampleCmp(" << samplerReference + << ", "; + break; + case TextureFunction::LOD0: + out << "" << textureReference << ".SampleCmpLevelZero(" + << samplerReference << ", "; + break; + case TextureFunction::LOD0BIAS: + out << "" << textureReference << ".SampleCmpLevelZero(" + << samplerReference << ", "; + break; default: UNREACHABLE(); } } @@ -1057,23 +1328,31 @@ void OutputHLSL::header(const BuiltInFunctionEmulator *builtInFunctionEmulator) { switch(textureFunction->method) { - case TextureFunction::IMPLICIT: out << "x.Sample(s, "; break; - case TextureFunction::BIAS: out << "x.SampleBias(s, "; break; - case TextureFunction::LOD: out << "x.SampleLevel(s, "; break; - case TextureFunction::LOD0: out << "x.SampleLevel(s, "; break; - case TextureFunction::LOD0BIAS: out << "x.SampleLevel(s, "; break; + case TextureFunction::IMPLICIT: + out << "" << textureReference << ".Sample(" << samplerReference << ", "; + break; + case TextureFunction::BIAS: + out << "" << textureReference << ".SampleBias(" << samplerReference + << ", "; + break; + case TextureFunction::LOD: + out << "" << textureReference << ".SampleLevel(" << samplerReference + << ", "; + break; + case TextureFunction::LOD0: + out << "" << textureReference << ".SampleLevel(" << samplerReference + << ", "; + break; + case TextureFunction::LOD0BIAS: + out << "" << textureReference << ".SampleLevel(" << samplerReference + << ", "; + break; default: UNREACHABLE(); } } } else UNREACHABLE(); - // Integer sampling requires integer addresses - TString addressx = ""; - TString addressy = ""; - TString addressz = ""; - TString close = ""; - if (IsIntegerSampler(textureFunction->sampler) || textureFunction->method == TextureFunction::FETCH) { @@ -1083,28 +1362,6 @@ void OutputHLSL::header(const BuiltInFunctionEmulator *builtInFunctionEmulator) case 3: out << "int4("; break; default: UNREACHABLE(); } - - // Convert from normalized floating-point to integer - if (textureFunction->method != TextureFunction::FETCH) - { - addressx = "int(floor(width * frac(("; - addressy = "int(floor(height * frac(("; - - if (IsSamplerArray(textureFunction->sampler)) - { - addressz = "int(max(0, min(layers - 1, floor(0.5 + "; - } - else if (IsSamplerCube(textureFunction->sampler)) - { - addressz = "(((("; - } - else - { - addressz = "int(floor(depth * frac(("; - } - - close = "))))"; - } } else { @@ -1117,21 +1374,9 @@ void OutputHLSL::header(const BuiltInFunctionEmulator *builtInFunctionEmulator) } } - TString proj = ""; // Only used for projected textures - - if (textureFunction->proj) - { - switch(textureFunction->coords) - { - case 3: proj = " / t.z"; break; - case 4: proj = " / t.w"; break; - default: UNREACHABLE(); - } - } - - out << addressx + ("t.x" + proj) + close + ", " + addressy + ("t.y" + proj) + close; + out << texCoordX << ", " << texCoordY; - if (mOutputType == SH_HLSL9_OUTPUT) + if (mOutputType == SH_HLSL_3_0_OUTPUT) { if (hlslCoords >= 3) { @@ -1141,7 +1386,7 @@ void OutputHLSL::header(const BuiltInFunctionEmulator *builtInFunctionEmulator) } else { - out << ", t.z" + proj; + out << ", t.z" << proj; } } @@ -1159,18 +1404,13 @@ void OutputHLSL::header(const BuiltInFunctionEmulator *builtInFunctionEmulator) out << "));\n"; } - else if (mOutputType == SH_HLSL11_OUTPUT) + else if (mOutputType == SH_HLSL_4_1_OUTPUT || mOutputType == SH_HLSL_4_0_FL9_3_OUTPUT) { if (hlslCoords >= 3) { - if (IsIntegerSampler(textureFunction->sampler) && IsSamplerCube(textureFunction->sampler)) - { - out << ", face"; - } - else - { - out << ", " + addressz + ("t.z" + proj) + close; - } + ASSERT(!IsIntegerSampler(textureFunction->sampler) || + !IsSamplerCube(textureFunction->sampler) || texCoordZ == "face"); + out << ", " << texCoordZ; } if (textureFunction->method == TextureFunction::GRAD) @@ -1240,7 +1480,8 @@ void OutputHLSL::header(const BuiltInFunctionEmulator *builtInFunctionEmulator) } } - if (textureFunction->offset) + if (textureFunction->offset && (!IsIntegerSampler(textureFunction->sampler) || + textureFunction->method == TextureFunction::FETCH)) { out << ", offset"; } @@ -1335,7 +1576,8 @@ void OutputHLSL::visitSymbol(TIntermSymbol *node) ensureStructDefined(nodeType); - out << DecorateUniform(name, nodeType); + const TName &nameWithMetadata = node->getName(); + out << DecorateUniform(nameWithMetadata, nodeType); } else if (qualifier == EvqAttribute || qualifier == EvqVertexIn) { @@ -1387,18 +1629,19 @@ void OutputHLSL::visitSymbol(TIntermSymbol *node) mUsesInstanceID = true; out << name; } - else if (name == "gl_FragDepthEXT") + else if (qualifier == EvqVertexID) { - mUsesFragDepth = true; - out << "gl_Depth"; + mUsesVertexID = true; + out << name; } - else if (node->isInternal()) + else if (name == "gl_FragDepthEXT" || name == "gl_FragDepth") { - out << name; + mUsesFragDepth = true; + out << "gl_Depth"; } else { - out << Decorate(name); + out << DecorateIfNeeded(node->getName()); } } } @@ -1414,11 +1657,11 @@ void OutputHLSL::outputEqual(Visit visit, const TType &type, TOperator op, TInfo { if (op == EOpEqual) { - outputTriplet(visit, "(", " == ", ")", out); + outputTriplet(out, visit, "(", " == ", ")"); } else { - outputTriplet(visit, "(", " != ", ")", out); + outputTriplet(out, visit, "(", " != ", ")"); } } else @@ -1431,22 +1674,58 @@ void OutputHLSL::outputEqual(Visit visit, const TType &type, TOperator op, TInfo if (type.isArray()) { const TString &functionName = addArrayEqualityFunction(type); - outputTriplet(visit, (functionName + "(").c_str(), ", ", ")", out); + outputTriplet(out, visit, (functionName + "(").c_str(), ", ", ")"); } else if (type.getBasicType() == EbtStruct) { const TStructure &structure = *type.getStruct(); const TString &functionName = addStructEqualityFunction(structure); - outputTriplet(visit, (functionName + "(").c_str(), ", ", ")", out); + outputTriplet(out, visit, (functionName + "(").c_str(), ", ", ")"); } else { ASSERT(type.isMatrix() || type.isVector()); - outputTriplet(visit, "all(", " == ", ")", out); + outputTriplet(out, visit, "all(", " == ", ")"); } } } +bool OutputHLSL::ancestorEvaluatesToSamplerInStruct(Visit visit) +{ + // Inside InVisit the current node is already in the path. + const unsigned int initialN = visit == InVisit ? 1u : 0u; + for (unsigned int n = initialN; getAncestorNode(n) != nullptr; ++n) + { + TIntermNode *ancestor = getAncestorNode(n); + const TIntermBinary *ancestorBinary = ancestor->getAsBinaryNode(); + if (ancestorBinary == nullptr) + { + return false; + } + switch (ancestorBinary->getOp()) + { + case EOpIndexDirectStruct: + { + const TStructure *structure = ancestorBinary->getLeft()->getType().getStruct(); + const TIntermConstantUnion *index = + ancestorBinary->getRight()->getAsConstantUnion(); + const TField *field = structure->fields()[index->getIConst(0)]; + if (IsSampler(field->type()->getBasicType())) + { + return true; + } + break; + } + case EOpIndexDirect: + break; + default: + // Returning a sampler from indirect indexing is not supported. + return false; + } + } + return false; +} + bool OutputHLSL::visitBinary(Visit visit, TIntermBinary *node) { TInfoSinkBase &out = getInfoSink(); @@ -1482,11 +1761,11 @@ bool OutputHLSL::visitBinary(Visit visit, TIntermBinary *node) ASSERT(rightAgg == nullptr || rightAgg->getOp() != EOpFunctionCall); const TString &functionName = addArrayAssignmentFunction(node->getType()); - outputTriplet(visit, (functionName + "(").c_str(), ", ", ")"); + outputTriplet(out, visit, (functionName + "(").c_str(), ", ", ")"); } else { - outputTriplet(visit, "(", " = ", ")"); + outputTriplet(out, visit, "(", " = ", ")"); } break; case EOpInitialize: @@ -1501,18 +1780,17 @@ bool OutputHLSL::visitBinary(Visit visit, TIntermBinary *node) ASSERT(symbolNode); TIntermTyped *expression = node->getRight(); - // TODO (jmadill): do a 'deep' scan to know if an expression is statically const - if (symbolNode->getQualifier() == EvqGlobal && expression->getQualifier() != EvqConst) + // Global initializers must be constant at this point. + ASSERT(symbolNode->getQualifier() != EvqGlobal || + (expression->getQualifier() == EvqConst && + expression->getAsConstantUnion() != nullptr)); + if (writeSameSymbolInitializer(out, symbolNode, expression)) { - // For variables which are not constant, defer their real initialization until - // after we initialize other globals: uniforms, attributes and varyings. - mDeferredGlobalInitializers.push_back(std::make_pair(symbolNode, expression)); - const TString &initString = initializer(node->getType()); - node->setRight(new TIntermRaw(node->getType(), initString)); + // Skip initializing the rest of the expression + return false; } - else if (writeSameSymbolInitializer(out, symbolNode, expression)) + else if (writeConstantInitialization(out, symbolNode, expression)) { - // Skip initializing the rest of the expression return false; } } @@ -1521,11 +1799,21 @@ bool OutputHLSL::visitBinary(Visit visit, TIntermBinary *node) out << " = "; } break; - case EOpAddAssign: outputTriplet(visit, "(", " += ", ")"); break; - case EOpSubAssign: outputTriplet(visit, "(", " -= ", ")"); break; - case EOpMulAssign: outputTriplet(visit, "(", " *= ", ")"); break; - case EOpVectorTimesScalarAssign: outputTriplet(visit, "(", " *= ", ")"); break; - case EOpMatrixTimesScalarAssign: outputTriplet(visit, "(", " *= ", ")"); break; + case EOpAddAssign: + outputTriplet(out, visit, "(", " += ", ")"); + break; + case EOpSubAssign: + outputTriplet(out, visit, "(", " -= ", ")"); + break; + case EOpMulAssign: + outputTriplet(out, visit, "(", " *= ", ")"); + break; + case EOpVectorTimesScalarAssign: + outputTriplet(out, visit, "(", " *= ", ")"); + break; + case EOpMatrixTimesScalarAssign: + outputTriplet(out, visit, "(", " *= ", ")"); + break; case EOpVectorTimesMatrixAssign: if (visit == PreVisit) { @@ -1558,13 +1846,27 @@ bool OutputHLSL::visitBinary(Visit visit, TIntermBinary *node) out << "))))"; } break; - case EOpDivAssign: outputTriplet(visit, "(", " /= ", ")"); break; - case EOpIModAssign: outputTriplet(visit, "(", " %= ", ")"); break; - case EOpBitShiftLeftAssign: outputTriplet(visit, "(", " <<= ", ")"); break; - case EOpBitShiftRightAssign: outputTriplet(visit, "(", " >>= ", ")"); break; - case EOpBitwiseAndAssign: outputTriplet(visit, "(", " &= ", ")"); break; - case EOpBitwiseXorAssign: outputTriplet(visit, "(", " ^= ", ")"); break; - case EOpBitwiseOrAssign: outputTriplet(visit, "(", " |= ", ")"); break; + case EOpDivAssign: + outputTriplet(out, visit, "(", " /= ", ")"); + break; + case EOpIModAssign: + outputTriplet(out, visit, "(", " %= ", ")"); + break; + case EOpBitShiftLeftAssign: + outputTriplet(out, visit, "(", " <<= ", ")"); + break; + case EOpBitShiftRightAssign: + outputTriplet(out, visit, "(", " >>= ", ")"); + break; + case EOpBitwiseAndAssign: + outputTriplet(out, visit, "(", " &= ", ")"); + break; + case EOpBitwiseXorAssign: + outputTriplet(out, visit, "(", " ^= ", ")"); + break; + case EOpBitwiseOrAssign: + outputTriplet(out, visit, "(", " |= ", ")"); + break; case EOpIndexDirect: { const TType& leftType = node->getLeft()->getType(); @@ -1579,26 +1881,58 @@ bool OutputHLSL::visitBinary(Visit visit, TIntermBinary *node) return false; } } + else if (ancestorEvaluatesToSamplerInStruct(visit)) + { + // All parts of an expression that access a sampler in a struct need to use _ as + // separator to access the sampler variable that has been moved out of the struct. + outputTriplet(out, visit, "", "_", ""); + } else { - outputTriplet(visit, "", "[", "]"); + outputTriplet(out, visit, "", "[", "]"); } } break; case EOpIndexIndirect: // We do not currently support indirect references to interface blocks ASSERT(node->getLeft()->getBasicType() != EbtInterfaceBlock); - outputTriplet(visit, "", "[", "]"); + outputTriplet(out, visit, "", "[", "]"); break; case EOpIndexDirectStruct: - if (visit == InVisit) { const TStructure* structure = node->getLeft()->getType().getStruct(); const TIntermConstantUnion* index = node->getRight()->getAsConstantUnion(); const TField* field = structure->fields()[index->getIConst(0)]; - out << "." + DecorateField(field->name(), *structure); - return false; + // In cases where indexing returns a sampler, we need to access the sampler variable + // that has been moved out of the struct. + bool indexingReturnsSampler = IsSampler(field->type()->getBasicType()); + if (visit == PreVisit && indexingReturnsSampler) + { + // Samplers extracted from structs have "angle" prefix to avoid name conflicts. + // This prefix is only output at the beginning of the indexing expression, which + // may have multiple parts. + out << "angle"; + } + if (!indexingReturnsSampler) + { + // All parts of an expression that access a sampler in a struct need to use _ as + // separator to access the sampler variable that has been moved out of the struct. + indexingReturnsSampler = ancestorEvaluatesToSamplerInStruct(visit); + } + if (visit == InVisit) + { + if (indexingReturnsSampler) + { + out << "_" + field->name(); + } + else + { + out << "." + DecorateField(field->name(), *structure); + } + + return false; + } } break; case EOpIndexDirectInterfaceBlock: @@ -1648,55 +1982,81 @@ bool OutputHLSL::visitBinary(Visit visit, TIntermBinary *node) return false; // Fully processed } break; - case EOpAdd: outputTriplet(visit, "(", " + ", ")"); break; - case EOpSub: outputTriplet(visit, "(", " - ", ")"); break; - case EOpMul: outputTriplet(visit, "(", " * ", ")"); break; - case EOpDiv: outputTriplet(visit, "(", " / ", ")"); break; - case EOpIMod: outputTriplet(visit, "(", " % ", ")"); break; - case EOpBitShiftLeft: outputTriplet(visit, "(", " << ", ")"); break; - case EOpBitShiftRight: outputTriplet(visit, "(", " >> ", ")"); break; - case EOpBitwiseAnd: outputTriplet(visit, "(", " & ", ")"); break; - case EOpBitwiseXor: outputTriplet(visit, "(", " ^ ", ")"); break; - case EOpBitwiseOr: outputTriplet(visit, "(", " | ", ")"); break; + case EOpAdd: + outputTriplet(out, visit, "(", " + ", ")"); + break; + case EOpSub: + outputTriplet(out, visit, "(", " - ", ")"); + break; + case EOpMul: + outputTriplet(out, visit, "(", " * ", ")"); + break; + case EOpDiv: + outputTriplet(out, visit, "(", " / ", ")"); + break; + case EOpIMod: + outputTriplet(out, visit, "(", " % ", ")"); + break; + case EOpBitShiftLeft: + outputTriplet(out, visit, "(", " << ", ")"); + break; + case EOpBitShiftRight: + outputTriplet(out, visit, "(", " >> ", ")"); + break; + case EOpBitwiseAnd: + outputTriplet(out, visit, "(", " & ", ")"); + break; + case EOpBitwiseXor: + outputTriplet(out, visit, "(", " ^ ", ")"); + break; + case EOpBitwiseOr: + outputTriplet(out, visit, "(", " | ", ")"); + break; case EOpEqual: case EOpNotEqual: outputEqual(visit, node->getLeft()->getType(), node->getOp(), out); break; - case EOpLessThan: outputTriplet(visit, "(", " < ", ")"); break; - case EOpGreaterThan: outputTriplet(visit, "(", " > ", ")"); break; - case EOpLessThanEqual: outputTriplet(visit, "(", " <= ", ")"); break; - case EOpGreaterThanEqual: outputTriplet(visit, "(", " >= ", ")"); break; - case EOpVectorTimesScalar: outputTriplet(visit, "(", " * ", ")"); break; - case EOpMatrixTimesScalar: outputTriplet(visit, "(", " * ", ")"); break; - case EOpVectorTimesMatrix: outputTriplet(visit, "mul(", ", transpose(", "))"); break; - case EOpMatrixTimesVector: outputTriplet(visit, "mul(transpose(", "), ", ")"); break; - case EOpMatrixTimesMatrix: outputTriplet(visit, "transpose(mul(transpose(", "), transpose(", ")))"); break; + case EOpLessThan: + outputTriplet(out, visit, "(", " < ", ")"); + break; + case EOpGreaterThan: + outputTriplet(out, visit, "(", " > ", ")"); + break; + case EOpLessThanEqual: + outputTriplet(out, visit, "(", " <= ", ")"); + break; + case EOpGreaterThanEqual: + outputTriplet(out, visit, "(", " >= ", ")"); + break; + case EOpVectorTimesScalar: + outputTriplet(out, visit, "(", " * ", ")"); + break; + case EOpMatrixTimesScalar: + outputTriplet(out, visit, "(", " * ", ")"); + break; + case EOpVectorTimesMatrix: + outputTriplet(out, visit, "mul(", ", transpose(", "))"); + break; + case EOpMatrixTimesVector: + outputTriplet(out, visit, "mul(transpose(", "), ", ")"); + break; + case EOpMatrixTimesMatrix: + outputTriplet(out, visit, "transpose(mul(transpose(", "), transpose(", ")))"); + break; case EOpLogicalOr: - if (node->getRight()->hasSideEffects()) - { - out << "s" << mUnfoldShortCircuit->getNextTemporaryIndex(); - return false; - } - else - { - outputTriplet(visit, "(", " || ", ")"); - return true; - } + // HLSL doesn't short-circuit ||, so we assume that || affected by short-circuiting have been unfolded. + ASSERT(!node->getRight()->hasSideEffects()); + outputTriplet(out, visit, "(", " || ", ")"); + return true; case EOpLogicalXor: mUsesXor = true; - outputTriplet(visit, "xor(", ", ", ")"); + outputTriplet(out, visit, "xor(", ", ", ")"); break; case EOpLogicalAnd: - if (node->getRight()->hasSideEffects()) - { - out << "s" << mUnfoldShortCircuit->getNextTemporaryIndex(); - return false; - } - else - { - outputTriplet(visit, "(", " && ", ")"); - return true; - } + // HLSL doesn't short-circuit &&, so we assume that && affected by short-circuiting have been unfolded. + ASSERT(!node->getRight()->hasSideEffects()); + outputTriplet(out, visit, "(", " && ", ")"); + return true; default: UNREACHABLE(); } @@ -1705,137 +2065,261 @@ bool OutputHLSL::visitBinary(Visit visit, TIntermBinary *node) bool OutputHLSL::visitUnary(Visit visit, TIntermUnary *node) { + TInfoSinkBase &out = getInfoSink(); + switch (node->getOp()) { - case EOpNegative: outputTriplet(visit, "(-", "", ")"); break; - case EOpPositive: outputTriplet(visit, "(+", "", ")"); break; - case EOpVectorLogicalNot: outputTriplet(visit, "(!", "", ")"); break; - case EOpLogicalNot: outputTriplet(visit, "(!", "", ")"); break; - case EOpBitwiseNot: outputTriplet(visit, "(~", "", ")"); break; - case EOpPostIncrement: outputTriplet(visit, "(", "", "++)"); break; - case EOpPostDecrement: outputTriplet(visit, "(", "", "--)"); break; - case EOpPreIncrement: outputTriplet(visit, "(++", "", ")"); break; - case EOpPreDecrement: outputTriplet(visit, "(--", "", ")"); break; - case EOpRadians: outputTriplet(visit, "radians(", "", ")"); break; - case EOpDegrees: outputTriplet(visit, "degrees(", "", ")"); break; - case EOpSin: outputTriplet(visit, "sin(", "", ")"); break; - case EOpCos: outputTriplet(visit, "cos(", "", ")"); break; - case EOpTan: outputTriplet(visit, "tan(", "", ")"); break; - case EOpAsin: outputTriplet(visit, "asin(", "", ")"); break; - case EOpAcos: outputTriplet(visit, "acos(", "", ")"); break; - case EOpAtan: outputTriplet(visit, "atan(", "", ")"); break; - case EOpSinh: outputTriplet(visit, "sinh(", "", ")"); break; - case EOpCosh: outputTriplet(visit, "cosh(", "", ")"); break; - case EOpTanh: outputTriplet(visit, "tanh(", "", ")"); break; + case EOpNegative: + outputTriplet(out, visit, "(-", "", ")"); + break; + case EOpPositive: + outputTriplet(out, visit, "(+", "", ")"); + break; + case EOpVectorLogicalNot: + outputTriplet(out, visit, "(!", "", ")"); + break; + case EOpLogicalNot: + outputTriplet(out, visit, "(!", "", ")"); + break; + case EOpBitwiseNot: + outputTriplet(out, visit, "(~", "", ")"); + break; + case EOpPostIncrement: + outputTriplet(out, visit, "(", "", "++)"); + break; + case EOpPostDecrement: + outputTriplet(out, visit, "(", "", "--)"); + break; + case EOpPreIncrement: + outputTriplet(out, visit, "(++", "", ")"); + break; + case EOpPreDecrement: + outputTriplet(out, visit, "(--", "", ")"); + break; + case EOpRadians: + outputTriplet(out, visit, "radians(", "", ")"); + break; + case EOpDegrees: + outputTriplet(out, visit, "degrees(", "", ")"); + break; + case EOpSin: + outputTriplet(out, visit, "sin(", "", ")"); + break; + case EOpCos: + outputTriplet(out, visit, "cos(", "", ")"); + break; + case EOpTan: + outputTriplet(out, visit, "tan(", "", ")"); + break; + case EOpAsin: + outputTriplet(out, visit, "asin(", "", ")"); + break; + case EOpAcos: + outputTriplet(out, visit, "acos(", "", ")"); + break; + case EOpAtan: + outputTriplet(out, visit, "atan(", "", ")"); + break; + case EOpSinh: + outputTriplet(out, visit, "sinh(", "", ")"); + break; + case EOpCosh: + outputTriplet(out, visit, "cosh(", "", ")"); + break; + case EOpTanh: + outputTriplet(out, visit, "tanh(", "", ")"); + break; case EOpAsinh: ASSERT(node->getUseEmulatedFunction()); - writeEmulatedFunctionTriplet(visit, "asinh("); + writeEmulatedFunctionTriplet(out, visit, "asinh("); break; case EOpAcosh: ASSERT(node->getUseEmulatedFunction()); - writeEmulatedFunctionTriplet(visit, "acosh("); + writeEmulatedFunctionTriplet(out, visit, "acosh("); break; case EOpAtanh: ASSERT(node->getUseEmulatedFunction()); - writeEmulatedFunctionTriplet(visit, "atanh("); + writeEmulatedFunctionTriplet(out, visit, "atanh("); break; - case EOpExp: outputTriplet(visit, "exp(", "", ")"); break; - case EOpLog: outputTriplet(visit, "log(", "", ")"); break; - case EOpExp2: outputTriplet(visit, "exp2(", "", ")"); break; - case EOpLog2: outputTriplet(visit, "log2(", "", ")"); break; - case EOpSqrt: outputTriplet(visit, "sqrt(", "", ")"); break; - case EOpInverseSqrt: outputTriplet(visit, "rsqrt(", "", ")"); break; - case EOpAbs: outputTriplet(visit, "abs(", "", ")"); break; - case EOpSign: outputTriplet(visit, "sign(", "", ")"); break; - case EOpFloor: outputTriplet(visit, "floor(", "", ")"); break; - case EOpTrunc: outputTriplet(visit, "trunc(", "", ")"); break; - case EOpRound: outputTriplet(visit, "round(", "", ")"); break; + case EOpExp: + outputTriplet(out, visit, "exp(", "", ")"); + break; + case EOpLog: + outputTriplet(out, visit, "log(", "", ")"); + break; + case EOpExp2: + outputTriplet(out, visit, "exp2(", "", ")"); + break; + case EOpLog2: + outputTriplet(out, visit, "log2(", "", ")"); + break; + case EOpSqrt: + outputTriplet(out, visit, "sqrt(", "", ")"); + break; + case EOpInverseSqrt: + outputTriplet(out, visit, "rsqrt(", "", ")"); + break; + case EOpAbs: + outputTriplet(out, visit, "abs(", "", ")"); + break; + case EOpSign: + outputTriplet(out, visit, "sign(", "", ")"); + break; + case EOpFloor: + outputTriplet(out, visit, "floor(", "", ")"); + break; + case EOpTrunc: + outputTriplet(out, visit, "trunc(", "", ")"); + break; + case EOpRound: + outputTriplet(out, visit, "round(", "", ")"); + break; case EOpRoundEven: ASSERT(node->getUseEmulatedFunction()); - writeEmulatedFunctionTriplet(visit, "roundEven("); + writeEmulatedFunctionTriplet(out, visit, "roundEven("); break; - case EOpCeil: outputTriplet(visit, "ceil(", "", ")"); break; - case EOpFract: outputTriplet(visit, "frac(", "", ")"); break; + case EOpCeil: + outputTriplet(out, visit, "ceil(", "", ")"); + break; + case EOpFract: + outputTriplet(out, visit, "frac(", "", ")"); + break; case EOpIsNan: - outputTriplet(visit, "isnan(", "", ")"); + outputTriplet(out, visit, "isnan(", "", ")"); mRequiresIEEEStrictCompiling = true; break; - case EOpIsInf: outputTriplet(visit, "isinf(", "", ")"); break; - case EOpFloatBitsToInt: outputTriplet(visit, "asint(", "", ")"); break; - case EOpFloatBitsToUint: outputTriplet(visit, "asuint(", "", ")"); break; - case EOpIntBitsToFloat: outputTriplet(visit, "asfloat(", "", ")"); break; - case EOpUintBitsToFloat: outputTriplet(visit, "asfloat(", "", ")"); break; + case EOpIsInf: + outputTriplet(out, visit, "isinf(", "", ")"); + break; + case EOpFloatBitsToInt: + outputTriplet(out, visit, "asint(", "", ")"); + break; + case EOpFloatBitsToUint: + outputTriplet(out, visit, "asuint(", "", ")"); + break; + case EOpIntBitsToFloat: + outputTriplet(out, visit, "asfloat(", "", ")"); + break; + case EOpUintBitsToFloat: + outputTriplet(out, visit, "asfloat(", "", ")"); + break; case EOpPackSnorm2x16: ASSERT(node->getUseEmulatedFunction()); - writeEmulatedFunctionTriplet(visit, "packSnorm2x16("); + writeEmulatedFunctionTriplet(out, visit, "packSnorm2x16("); break; case EOpPackUnorm2x16: ASSERT(node->getUseEmulatedFunction()); - writeEmulatedFunctionTriplet(visit, "packUnorm2x16("); + writeEmulatedFunctionTriplet(out, visit, "packUnorm2x16("); break; case EOpPackHalf2x16: ASSERT(node->getUseEmulatedFunction()); - writeEmulatedFunctionTriplet(visit, "packHalf2x16("); + writeEmulatedFunctionTriplet(out, visit, "packHalf2x16("); break; case EOpUnpackSnorm2x16: ASSERT(node->getUseEmulatedFunction()); - writeEmulatedFunctionTriplet(visit, "unpackSnorm2x16("); + writeEmulatedFunctionTriplet(out, visit, "unpackSnorm2x16("); break; case EOpUnpackUnorm2x16: ASSERT(node->getUseEmulatedFunction()); - writeEmulatedFunctionTriplet(visit, "unpackUnorm2x16("); + writeEmulatedFunctionTriplet(out, visit, "unpackUnorm2x16("); break; case EOpUnpackHalf2x16: ASSERT(node->getUseEmulatedFunction()); - writeEmulatedFunctionTriplet(visit, "unpackHalf2x16("); + writeEmulatedFunctionTriplet(out, visit, "unpackHalf2x16("); break; - case EOpLength: outputTriplet(visit, "length(", "", ")"); break; - case EOpNormalize: outputTriplet(visit, "normalize(", "", ")"); break; + case EOpLength: + outputTriplet(out, visit, "length(", "", ")"); + break; + case EOpNormalize: + outputTriplet(out, visit, "normalize(", "", ")"); + break; case EOpDFdx: if(mInsideDiscontinuousLoop || mOutputLod0Function) { - outputTriplet(visit, "(", "", ", 0.0)"); + outputTriplet(out, visit, "(", "", ", 0.0)"); } else { - outputTriplet(visit, "ddx(", "", ")"); + outputTriplet(out, visit, "ddx(", "", ")"); } break; case EOpDFdy: if(mInsideDiscontinuousLoop || mOutputLod0Function) { - outputTriplet(visit, "(", "", ", 0.0)"); + outputTriplet(out, visit, "(", "", ", 0.0)"); } else { - outputTriplet(visit, "ddy(", "", ")"); + outputTriplet(out, visit, "ddy(", "", ")"); } break; case EOpFwidth: if(mInsideDiscontinuousLoop || mOutputLod0Function) { - outputTriplet(visit, "(", "", ", 0.0)"); + outputTriplet(out, visit, "(", "", ", 0.0)"); } else { - outputTriplet(visit, "fwidth(", "", ")"); + outputTriplet(out, visit, "fwidth(", "", ")"); } break; - case EOpTranspose: outputTriplet(visit, "transpose(", "", ")"); break; - case EOpDeterminant: outputTriplet(visit, "determinant(transpose(", "", "))"); break; + case EOpTranspose: + outputTriplet(out, visit, "transpose(", "", ")"); + break; + case EOpDeterminant: + outputTriplet(out, visit, "determinant(transpose(", "", "))"); + break; case EOpInverse: ASSERT(node->getUseEmulatedFunction()); - writeEmulatedFunctionTriplet(visit, "inverse("); + writeEmulatedFunctionTriplet(out, visit, "inverse("); break; - case EOpAny: outputTriplet(visit, "any(", "", ")"); break; - case EOpAll: outputTriplet(visit, "all(", "", ")"); break; + case EOpAny: + outputTriplet(out, visit, "any(", "", ")"); + break; + case EOpAll: + outputTriplet(out, visit, "all(", "", ")"); + break; default: UNREACHABLE(); } return true; } +TString OutputHLSL::samplerNamePrefixFromStruct(TIntermTyped *node) +{ + if (node->getAsSymbolNode()) + { + return node->getAsSymbolNode()->getSymbol(); + } + TIntermBinary *nodeBinary = node->getAsBinaryNode(); + switch (nodeBinary->getOp()) + { + case EOpIndexDirect: + { + int index = nodeBinary->getRight()->getAsConstantUnion()->getIConst(0); + + TInfoSinkBase prefixSink; + prefixSink << samplerNamePrefixFromStruct(nodeBinary->getLeft()) << "_" << index; + return TString(prefixSink.c_str()); + } + case EOpIndexDirectStruct: + { + TStructure *s = nodeBinary->getLeft()->getAsTyped()->getType().getStruct(); + int index = nodeBinary->getRight()->getAsConstantUnion()->getIConst(0); + const TField *field = s->fields()[index]; + + TInfoSinkBase prefixSink; + prefixSink << samplerNamePrefixFromStruct(nodeBinary->getLeft()) << "_" + << field->name(); + return TString(prefixSink.c_str()); + } + default: + UNREACHABLE(); + return TString(""); + } +} + bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node) { TInfoSinkBase &out = getInfoSink(); @@ -1846,26 +2330,30 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node) { if (mInsideFunction) { - outputLineDirective(node->getLine().first_line); + outputLineDirective(out, node->getLine().first_line); out << "{\n"; } for (TIntermSequence::iterator sit = node->getSequence()->begin(); sit != node->getSequence()->end(); sit++) { - outputLineDirective((*sit)->getLine().first_line); + outputLineDirective(out, (*sit)->getLine().first_line); - traverseStatements(*sit); + (*sit)->traverse(this); // Don't output ; after case labels, they're terminated by : // This is needed especially since outputting a ; after a case statement would turn empty // case statements into non-empty case statements, disallowing fall-through from them. - if ((*sit)->getAsCaseNode() == nullptr) + // Also no need to output ; after selection (if) statements or sequences. This is done just + // for code clarity. + TIntermSelection *asSelection = (*sit)->getAsSelectionNode(); + ASSERT(asSelection == nullptr || !asSelection->usesTernaryOperator()); + if ((*sit)->getAsCaseNode() == nullptr && asSelection == nullptr && !IsSequence(*sit)) out << ";\n"; } if (mInsideFunction) { - outputLineDirective(node->getLine().last_line); + outputLineDirective(out, node->getLine().last_line); out << "}\n"; } @@ -1876,44 +2364,34 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node) { TIntermSequence *sequence = node->getSequence(); TIntermTyped *variable = (*sequence)[0]->getAsTyped(); + ASSERT(sequence->size() == 1); - if (variable && (variable->getQualifier() == EvqTemporary || variable->getQualifier() == EvqGlobal)) + if (variable && + (variable->getQualifier() == EvqTemporary || + variable->getQualifier() == EvqGlobal || variable->getQualifier() == EvqConst)) { ensureStructDefined(variable->getType()); if (!variable->getAsSymbolNode() || variable->getAsSymbolNode()->getSymbol() != "") // Variable declaration { - for (const auto &seqElement : *sequence) + if (!mInsideFunction) { - if (isSingleStatement(seqElement)) - { - mUnfoldShortCircuit->traverse(seqElement); - } - - if (!mInsideFunction) - { - out << "static "; - } - - out << TypeString(variable->getType()) + " "; + out << "static "; + } - TIntermSymbol *symbol = seqElement->getAsSymbolNode(); + out << TypeString(variable->getType()) + " "; - if (symbol) - { - symbol->traverse(this); - out << ArrayString(symbol->getType()); - out << " = " + initializer(symbol->getType()); - } - else - { - seqElement->traverse(this); - } + TIntermSymbol *symbol = variable->getAsSymbolNode(); - if (seqElement != sequence->back()) - { - out << ";\n"; - } + if (symbol) + { + symbol->traverse(this); + out << ArrayString(symbol->getType()); + out << " = " + initializer(symbol->getType()); + } + else + { + variable->traverse(this); } } else if (variable->getAsSymbolNode() && variable->getAsSymbolNode()->getSymbol() == "") // Type (struct) declaration @@ -1960,10 +2438,12 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node) return false; } - out << TypeString(node->getType()) << " " << Decorate(TFunction::unmangleName(node->getName())) << (mOutputLod0Function ? "Lod0(" : "("); - TIntermSequence *arguments = node->getSequence(); + TString name = DecorateFunctionIfNeeded(node->getNameObj()); + out << TypeString(node->getType()) << " " << name << DisambiguateFunctionName(arguments) + << (mOutputLod0Function ? "Lod0(" : "("); + for (unsigned int i = 0; i < arguments->size(); i++) { TIntermSymbol *symbol = (*arguments)[i]->getAsSymbolNode(); @@ -1994,11 +2474,13 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node) return false; } break; - case EOpComma: outputTriplet(visit, "(", ", ", ")"); break; + case EOpComma: + outputTriplet(out, visit, "(", ", ", ")"); + break; case EOpFunction: { ASSERT(mCurrentFunctionMetadata == nullptr); - TString name = TFunction::unmangleName(node->getName()); + TString name = TFunction::unmangleName(node->getNameObj().getString()); size_t index = mCallDag.findIndex(node); ASSERT(index != CallDAG::InvalidIndex); @@ -2006,18 +2488,19 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node) out << TypeString(node->getType()) << " "; + TIntermSequence *sequence = node->getSequence(); + TIntermSequence *arguments = (*sequence)[0]->getAsAggregate()->getSequence(); + if (name == "main") { out << "gl_main("; } else { - out << Decorate(name) << (mOutputLod0Function ? "Lod0(" : "("); + out << DecorateFunctionIfNeeded(node->getNameObj()) + << DisambiguateFunctionName(arguments) << (mOutputLod0Function ? "Lod0(" : "("); } - TIntermSequence *sequence = node->getSequence(); - TIntermSequence *arguments = (*sequence)[0]->getAsAggregate()->getSequence(); - for (unsigned int i = 0; i < arguments->size(); i++) { TIntermSymbol *symbol = (*arguments)[i]->getAsSymbolNode(); @@ -2036,17 +2519,21 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node) else UNREACHABLE(); } - out << ")\n" - "{\n"; + out << ")\n"; if (sequence->size() > 1) { mInsideFunction = true; - (*sequence)[1]->traverse(this); + TIntermNode *body = (*sequence)[1]; + // The function body node will output braces. + ASSERT(IsSequence(body)); + body->traverse(this); mInsideFunction = false; } - - out << "}\n"; + else + { + out << "{}\n"; + } mCurrentFunctionMetadata = nullptr; @@ -2064,7 +2551,6 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node) break; case EOpFunctionCall: { - TString name = TFunction::unmangleName(node->getName()); TIntermSequence *arguments = node->getSequence(); bool lod0 = mInsideDiscontinuousLoop || mOutputLod0Function; @@ -2078,10 +2564,13 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node) ASSERT(index != CallDAG::InvalidIndex); lod0 &= mASTMetadataList[index].mNeedsLod0; - out << Decorate(name) << (lod0 ? "Lod0(" : "("); + out << DecorateFunctionIfNeeded(node->getNameObj()); + out << DisambiguateFunctionName(node->getSequence()); + out << (lod0 ? "Lod0(" : "("); } else { + TString name = TFunction::unmangleName(node->getNameObj().getString()); TBasicType samplerType = (*arguments)[0]->getAsTyped()->getType().getBasicType(); TextureFunction textureFunction; @@ -2202,7 +2691,8 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node) for (TIntermSequence::iterator arg = arguments->begin(); arg != arguments->end(); arg++) { - if (mOutputType == SH_HLSL11_OUTPUT && IsSampler((*arg)->getAsTyped()->getBasicType())) + TIntermTyped *typedArg = (*arg)->getAsTyped(); + if (mOutputType == SH_HLSL_4_0_FL9_3_OUTPUT && IsSampler(typedArg->getBasicType())) { out << "texture_"; (*arg)->traverse(this); @@ -2211,6 +2701,30 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node) (*arg)->traverse(this); + if (typedArg->getType().isStructureContainingSamplers()) + { + const TType &argType = typedArg->getType(); + TVector samplerSymbols; + TString structName = samplerNamePrefixFromStruct(typedArg); + argType.createSamplerSymbols("angle_" + structName, "", + argType.isArray() ? argType.getArraySize() : 0, + &samplerSymbols, nullptr); + for (const TIntermSymbol *sampler : samplerSymbols) + { + if (mOutputType == SH_HLSL_4_0_FL9_3_OUTPUT) + { + out << ", texture_" << sampler->getSymbol(); + out << ", sampler_" << sampler->getSymbol(); + } + else + { + // In case of HLSL 4.1+, this symbol is the sampler index, and in case + // of D3D9, it's the sampler variable. + out << ", " + sampler->getSymbol(); + } + } + } + if (arg < arguments->end() - 1) { out << ", "; @@ -2222,26 +2736,84 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node) return false; } break; - case EOpParameters: outputTriplet(visit, "(", ", ", ")\n{\n"); break; - case EOpConstructFloat: outputConstructor(visit, node->getType(), "vec1", node->getSequence()); break; - case EOpConstructVec2: outputConstructor(visit, node->getType(), "vec2", node->getSequence()); break; - case EOpConstructVec3: outputConstructor(visit, node->getType(), "vec3", node->getSequence()); break; - case EOpConstructVec4: outputConstructor(visit, node->getType(), "vec4", node->getSequence()); break; - case EOpConstructBool: outputConstructor(visit, node->getType(), "bvec1", node->getSequence()); break; - case EOpConstructBVec2: outputConstructor(visit, node->getType(), "bvec2", node->getSequence()); break; - case EOpConstructBVec3: outputConstructor(visit, node->getType(), "bvec3", node->getSequence()); break; - case EOpConstructBVec4: outputConstructor(visit, node->getType(), "bvec4", node->getSequence()); break; - case EOpConstructInt: outputConstructor(visit, node->getType(), "ivec1", node->getSequence()); break; - case EOpConstructIVec2: outputConstructor(visit, node->getType(), "ivec2", node->getSequence()); break; - case EOpConstructIVec3: outputConstructor(visit, node->getType(), "ivec3", node->getSequence()); break; - case EOpConstructIVec4: outputConstructor(visit, node->getType(), "ivec4", node->getSequence()); break; - case EOpConstructUInt: outputConstructor(visit, node->getType(), "uvec1", node->getSequence()); break; - case EOpConstructUVec2: outputConstructor(visit, node->getType(), "uvec2", node->getSequence()); break; - case EOpConstructUVec3: outputConstructor(visit, node->getType(), "uvec3", node->getSequence()); break; - case EOpConstructUVec4: outputConstructor(visit, node->getType(), "uvec4", node->getSequence()); break; - case EOpConstructMat2: outputConstructor(visit, node->getType(), "mat2", node->getSequence()); break; - case EOpConstructMat3: outputConstructor(visit, node->getType(), "mat3", node->getSequence()); break; - case EOpConstructMat4: outputConstructor(visit, node->getType(), "mat4", node->getSequence()); break; + case EOpParameters: + outputTriplet(out, visit, "(", ", ", ")\n{\n"); + break; + case EOpConstructFloat: + outputConstructor(out, visit, node->getType(), "vec1", node->getSequence()); + break; + case EOpConstructVec2: + outputConstructor(out, visit, node->getType(), "vec2", node->getSequence()); + break; + case EOpConstructVec3: + outputConstructor(out, visit, node->getType(), "vec3", node->getSequence()); + break; + case EOpConstructVec4: + outputConstructor(out, visit, node->getType(), "vec4", node->getSequence()); + break; + case EOpConstructBool: + outputConstructor(out, visit, node->getType(), "bvec1", node->getSequence()); + break; + case EOpConstructBVec2: + outputConstructor(out, visit, node->getType(), "bvec2", node->getSequence()); + break; + case EOpConstructBVec3: + outputConstructor(out, visit, node->getType(), "bvec3", node->getSequence()); + break; + case EOpConstructBVec4: + outputConstructor(out, visit, node->getType(), "bvec4", node->getSequence()); + break; + case EOpConstructInt: + outputConstructor(out, visit, node->getType(), "ivec1", node->getSequence()); + break; + case EOpConstructIVec2: + outputConstructor(out, visit, node->getType(), "ivec2", node->getSequence()); + break; + case EOpConstructIVec3: + outputConstructor(out, visit, node->getType(), "ivec3", node->getSequence()); + break; + case EOpConstructIVec4: + outputConstructor(out, visit, node->getType(), "ivec4", node->getSequence()); + break; + case EOpConstructUInt: + outputConstructor(out, visit, node->getType(), "uvec1", node->getSequence()); + break; + case EOpConstructUVec2: + outputConstructor(out, visit, node->getType(), "uvec2", node->getSequence()); + break; + case EOpConstructUVec3: + outputConstructor(out, visit, node->getType(), "uvec3", node->getSequence()); + break; + case EOpConstructUVec4: + outputConstructor(out, visit, node->getType(), "uvec4", node->getSequence()); + break; + case EOpConstructMat2: + outputConstructor(out, visit, node->getType(), "mat2", node->getSequence()); + break; + case EOpConstructMat2x3: + outputConstructor(out, visit, node->getType(), "mat2x3", node->getSequence()); + break; + case EOpConstructMat2x4: + outputConstructor(out, visit, node->getType(), "mat2x4", node->getSequence()); + break; + case EOpConstructMat3x2: + outputConstructor(out, visit, node->getType(), "mat3x2", node->getSequence()); + break; + case EOpConstructMat3: + outputConstructor(out, visit, node->getType(), "mat3", node->getSequence()); + break; + case EOpConstructMat3x4: + outputConstructor(out, visit, node->getType(), "mat3x4", node->getSequence()); + break; + case EOpConstructMat4x2: + outputConstructor(out, visit, node->getType(), "mat4x2", node->getSequence()); + break; + case EOpConstructMat4x3: + outputConstructor(out, visit, node->getType(), "mat4x3", node->getSequence()); + break; + case EOpConstructMat4: + outputConstructor(out, visit, node->getType(), "mat4", node->getSequence()); + break; case EOpConstructStruct: { if (node->getType().isArray()) @@ -2250,147 +2822,207 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node) } const TString &structName = StructNameString(*node->getType().getStruct()); mStructureHLSL->addConstructor(node->getType(), structName, node->getSequence()); - outputTriplet(visit, (structName + "_ctor(").c_str(), ", ", ")"); + outputTriplet(out, visit, (structName + "_ctor(").c_str(), ", ", ")"); } break; - case EOpLessThan: outputTriplet(visit, "(", " < ", ")"); break; - case EOpGreaterThan: outputTriplet(visit, "(", " > ", ")"); break; - case EOpLessThanEqual: outputTriplet(visit, "(", " <= ", ")"); break; - case EOpGreaterThanEqual: outputTriplet(visit, "(", " >= ", ")"); break; - case EOpVectorEqual: outputTriplet(visit, "(", " == ", ")"); break; - case EOpVectorNotEqual: outputTriplet(visit, "(", " != ", ")"); break; + case EOpLessThan: + outputTriplet(out, visit, "(", " < ", ")"); + break; + case EOpGreaterThan: + outputTriplet(out, visit, "(", " > ", ")"); + break; + case EOpLessThanEqual: + outputTriplet(out, visit, "(", " <= ", ")"); + break; + case EOpGreaterThanEqual: + outputTriplet(out, visit, "(", " >= ", ")"); + break; + case EOpVectorEqual: + outputTriplet(out, visit, "(", " == ", ")"); + break; + case EOpVectorNotEqual: + outputTriplet(out, visit, "(", " != ", ")"); + break; case EOpMod: ASSERT(node->getUseEmulatedFunction()); - writeEmulatedFunctionTriplet(visit, "mod("); + writeEmulatedFunctionTriplet(out, visit, "mod("); break; - case EOpModf: outputTriplet(visit, "modf(", ", ", ")"); break; - case EOpPow: outputTriplet(visit, "pow(", ", ", ")"); break; + case EOpModf: + outputTriplet(out, visit, "modf(", ", ", ")"); + break; + case EOpPow: + outputTriplet(out, visit, "pow(", ", ", ")"); + break; case EOpAtan: ASSERT(node->getSequence()->size() == 2); // atan(x) is a unary operator ASSERT(node->getUseEmulatedFunction()); - writeEmulatedFunctionTriplet(visit, "atan("); + writeEmulatedFunctionTriplet(out, visit, "atan("); + break; + case EOpMin: + outputTriplet(out, visit, "min(", ", ", ")"); + break; + case EOpMax: + outputTriplet(out, visit, "max(", ", ", ")"); + break; + case EOpClamp: + outputTriplet(out, visit, "clamp(", ", ", ")"); + break; + case EOpMix: + { + TIntermTyped *lastParamNode = (*(node->getSequence()))[2]->getAsTyped(); + if (lastParamNode->getType().getBasicType() == EbtBool) + { + // There is no HLSL equivalent for ESSL3 built-in "genType mix (genType x, genType y, genBType a)", + // so use emulated version. + ASSERT(node->getUseEmulatedFunction()); + writeEmulatedFunctionTriplet(out, visit, "mix("); + } + else + { + outputTriplet(out, visit, "lerp(", ", ", ")"); + } + } break; - case EOpMin: outputTriplet(visit, "min(", ", ", ")"); break; - case EOpMax: outputTriplet(visit, "max(", ", ", ")"); break; - case EOpClamp: outputTriplet(visit, "clamp(", ", ", ")"); break; - case EOpMix: outputTriplet(visit, "lerp(", ", ", ")"); break; - case EOpStep: outputTriplet(visit, "step(", ", ", ")"); break; - case EOpSmoothStep: outputTriplet(visit, "smoothstep(", ", ", ")"); break; - case EOpDistance: outputTriplet(visit, "distance(", ", ", ")"); break; - case EOpDot: outputTriplet(visit, "dot(", ", ", ")"); break; - case EOpCross: outputTriplet(visit, "cross(", ", ", ")"); break; + case EOpStep: + outputTriplet(out, visit, "step(", ", ", ")"); + break; + case EOpSmoothStep: + outputTriplet(out, visit, "smoothstep(", ", ", ")"); + break; + case EOpDistance: + outputTriplet(out, visit, "distance(", ", ", ")"); + break; + case EOpDot: + outputTriplet(out, visit, "dot(", ", ", ")"); + break; + case EOpCross: + outputTriplet(out, visit, "cross(", ", ", ")"); + break; case EOpFaceForward: ASSERT(node->getUseEmulatedFunction()); - writeEmulatedFunctionTriplet(visit, "faceforward("); + writeEmulatedFunctionTriplet(out, visit, "faceforward("); break; - case EOpReflect: outputTriplet(visit, "reflect(", ", ", ")"); break; - case EOpRefract: outputTriplet(visit, "refract(", ", ", ")"); break; + case EOpReflect: + outputTriplet(out, visit, "reflect(", ", ", ")"); + break; + case EOpRefract: + outputTriplet(out, visit, "refract(", ", ", ")"); + break; case EOpOuterProduct: ASSERT(node->getUseEmulatedFunction()); - writeEmulatedFunctionTriplet(visit, "outerProduct("); + writeEmulatedFunctionTriplet(out, visit, "outerProduct("); break; - case EOpMul: outputTriplet(visit, "(", " * ", ")"); break; + case EOpMul: + outputTriplet(out, visit, "(", " * ", ")"); + break; default: UNREACHABLE(); } return true; } -bool OutputHLSL::visitSelection(Visit visit, TIntermSelection *node) +void OutputHLSL::writeSelection(TInfoSinkBase &out, TIntermSelection *node) { - TInfoSinkBase &out = getInfoSink(); + out << "if ("; - if (node->usesTernaryOperator()) - { - out << "s" << mUnfoldShortCircuit->getNextTemporaryIndex(); - } - else // if/else statement - { - mUnfoldShortCircuit->traverse(node->getCondition()); + node->getCondition()->traverse(this); - // D3D errors when there is a gradient operation in a loop in an unflattened if. - if (mShaderType == GL_FRAGMENT_SHADER - && mCurrentFunctionMetadata->hasDiscontinuousLoop(node) - && mCurrentFunctionMetadata->hasGradientInCallGraph(node)) - { - out << "FLATTEN "; - } + out << ")\n"; - out << "if ("; + outputLineDirective(out, node->getLine().first_line); - node->getCondition()->traverse(this); + bool discard = false; - out << ")\n"; + if (node->getTrueBlock()) + { + // The trueBlock child node will output braces. + ASSERT(IsSequence(node->getTrueBlock())); - outputLineDirective(node->getLine().first_line); - out << "{\n"; + node->getTrueBlock()->traverse(this); - bool discard = false; + // Detect true discard + discard = (discard || FindDiscard::search(node->getTrueBlock())); + } + else + { + // TODO(oetuaho): Check if the semicolon inside is necessary. + // It's there as a result of conservative refactoring of the output. + out << "{;}\n"; + } - if (node->getTrueBlock()) - { - traverseStatements(node->getTrueBlock()); + outputLineDirective(out, node->getLine().first_line); - // Detect true discard - discard = (discard || FindDiscard::search(node->getTrueBlock())); - } + if (node->getFalseBlock()) + { + out << "else\n"; - outputLineDirective(node->getLine().first_line); - out << ";\n}\n"; + outputLineDirective(out, node->getFalseBlock()->getLine().first_line); - if (node->getFalseBlock()) - { - out << "else\n"; + // Either this is "else if" or the falseBlock child node will output braces. + ASSERT(IsSequence(node->getFalseBlock()) || node->getFalseBlock()->getAsSelectionNode() != nullptr); - outputLineDirective(node->getFalseBlock()->getLine().first_line); - out << "{\n"; + node->getFalseBlock()->traverse(this); - outputLineDirective(node->getFalseBlock()->getLine().first_line); - traverseStatements(node->getFalseBlock()); + outputLineDirective(out, node->getFalseBlock()->getLine().first_line); - outputLineDirective(node->getFalseBlock()->getLine().first_line); - out << ";\n}\n"; + // Detect false discard + discard = (discard || FindDiscard::search(node->getFalseBlock())); + } - // Detect false discard - discard = (discard || FindDiscard::search(node->getFalseBlock())); - } + // ANGLE issue 486: Detect problematic conditional discard + if (discard) + { + mUsesDiscardRewriting = true; + } +} - // ANGLE issue 486: Detect problematic conditional discard - if (discard && FindSideEffectRewriting::search(node)) - { - mUsesDiscardRewriting = true; - } +bool OutputHLSL::visitSelection(Visit visit, TIntermSelection *node) +{ + TInfoSinkBase &out = getInfoSink(); + + ASSERT(!node->usesTernaryOperator()); + ASSERT(mInsideFunction); + + // D3D errors when there is a gradient operation in a loop in an unflattened if. + if (mShaderType == GL_FRAGMENT_SHADER && mCurrentFunctionMetadata->hasGradientLoop(node)) + { + out << "FLATTEN "; } + writeSelection(out, node); + return false; } bool OutputHLSL::visitSwitch(Visit visit, TIntermSwitch *node) { + TInfoSinkBase &out = getInfoSink(); + if (node->getStatementList()) { node->setStatementList(RemoveSwitchFallThrough::removeFallThrough(node->getStatementList())); - outputTriplet(visit, "switch (", ") ", ""); + outputTriplet(out, visit, "switch (", ") ", ""); // The curly braces get written when visiting the statementList aggregate } else { // No statementList, so it won't output curly braces - outputTriplet(visit, "switch (", ") {", "}\n"); + outputTriplet(out, visit, "switch (", ") {", "}\n"); } return true; } bool OutputHLSL::visitCase(Visit visit, TIntermCase *node) { + TInfoSinkBase &out = getInfoSink(); + if (node->hasCondition()) { - outputTriplet(visit, "case (", "", "):\n"); + outputTriplet(out, visit, "case (", "", "):\n"); return true; } else { - TInfoSinkBase &out = getInfoSink(); out << "default:\n"; return false; } @@ -2398,7 +3030,8 @@ bool OutputHLSL::visitCase(Visit visit, TIntermCase *node) void OutputHLSL::visitConstantUnion(TIntermConstantUnion *node) { - writeConstantUnion(node->getType(), node->getUnionArrayPointer()); + TInfoSinkBase &out = getInfoSink(); + writeConstantUnion(out, node->getType(), node->getUnionArrayPointer()); } bool OutputHLSL::visitLoop(Visit visit, TIntermLoop *node) @@ -2409,9 +3042,11 @@ bool OutputHLSL::visitLoop(Visit visit, TIntermLoop *node) mInsideDiscontinuousLoop = mInsideDiscontinuousLoop || mCurrentFunctionMetadata->mDiscontinuousLoops.count(node) > 0; - if (mOutputType == SH_HLSL9_OUTPUT) + TInfoSinkBase &out = getInfoSink(); + + if (mOutputType == SH_HLSL_3_0_OUTPUT) { - if (handleExcessiveLoop(node)) + if (handleExcessiveLoop(out, node)) { mInsideDiscontinuousLoop = wasDiscontinuous; mNestedLoopDepth--; @@ -2420,15 +3055,12 @@ bool OutputHLSL::visitLoop(Visit visit, TIntermLoop *node) } } - TInfoSinkBase &out = getInfoSink(); - const char *unroll = mCurrentFunctionMetadata->hasGradientInCallGraph(node) ? "LOOP" : ""; if (node->getType() == ELoopDoWhile) { out << "{" << unroll << " do\n"; - outputLineDirective(node->getLine().first_line); - out << "{\n"; + outputLineDirective(out, node->getLine().first_line); } else { @@ -2455,21 +3087,27 @@ bool OutputHLSL::visitLoop(Visit visit, TIntermLoop *node) out << ")\n"; - outputLineDirective(node->getLine().first_line); - out << "{\n"; + outputLineDirective(out, node->getLine().first_line); } if (node->getBody()) { - traverseStatements(node->getBody()); + // The loop body node will output braces. + ASSERT(IsSequence(node->getBody())); + node->getBody()->traverse(this); + } + else + { + // TODO(oetuaho): Check if the semicolon inside is necessary. + // It's there as a result of conservative refactoring of the output. + out << "{;}\n"; } - outputLineDirective(node->getLine().first_line); - out << ";}\n"; + outputLineDirective(out, node->getLine().first_line); if (node->getType() == ELoopDoWhile) { - outputLineDirective(node->getCondition()->getLine().first_line); + outputLineDirective(out, node->getCondition()->getLine().first_line); out << "while(\n"; node->getCondition()->traverse(this); @@ -2492,7 +3130,7 @@ bool OutputHLSL::visitBranch(Visit visit, TIntermBranch *node) switch (node->getFlowOp()) { case EOpKill: - outputTriplet(visit, "discard;\n", "", ""); + outputTriplet(out, visit, "discard;\n", "", ""); break; case EOpBreak: if (visit == PreVisit) @@ -2514,7 +3152,9 @@ bool OutputHLSL::visitBranch(Visit visit, TIntermBranch *node) } } break; - case EOpContinue: outputTriplet(visit, "continue;\n", "", ""); break; + case EOpContinue: + outputTriplet(out, visit, "continue;\n", "", ""); + break; case EOpReturn: if (visit == PreVisit) { @@ -2541,16 +3181,6 @@ bool OutputHLSL::visitBranch(Visit visit, TIntermBranch *node) return true; } -void OutputHLSL::traverseStatements(TIntermNode *node) -{ - if (isSingleStatement(node)) - { - mUnfoldShortCircuit->traverse(node); - } - - node->traverse(this); -} - bool OutputHLSL::isSingleStatement(TIntermNode *node) { TIntermAggregate *aggregate = node->getAsAggregate(); @@ -2586,10 +3216,9 @@ bool OutputHLSL::isSingleStatement(TIntermNode *node) // Handle loops with more than 254 iterations (unsupported by D3D9) by splitting them // (The D3D documentation says 255 iterations, but the compiler complains at anything more than 254). -bool OutputHLSL::handleExcessiveLoop(TIntermLoop *node) +bool OutputHLSL::handleExcessiveLoop(TInfoSinkBase &out, TIntermLoop *node) { const int MAX_LOOP_ITERATIONS = 254; - TInfoSinkBase &out = getInfoSink(); // Parse loops of the form: // for(int index = initial; index [comparator] limit; index += increment) @@ -2756,7 +3385,7 @@ bool OutputHLSL::handleExcessiveLoop(TIntermLoop *node) out << increment; out << ")\n"; - outputLineDirective(node->getLine().first_line); + outputLineDirective(out, node->getLine().first_line); out << "{\n"; if (node->getBody()) @@ -2764,7 +3393,7 @@ bool OutputHLSL::handleExcessiveLoop(TIntermLoop *node) node->getBody()->traverse(this); } - outputLineDirective(node->getLine().first_line); + outputLineDirective(out, node->getLine().first_line); out << ";}\n"; if (!firstLoopFragment) @@ -2790,7 +3419,11 @@ bool OutputHLSL::handleExcessiveLoop(TIntermLoop *node) return false; // Not handled as an excessive loop } -void OutputHLSL::outputTriplet(Visit visit, const char *preString, const char *inString, const char *postString, TInfoSinkBase &out) +void OutputHLSL::outputTriplet(TInfoSinkBase &out, + Visit visit, + const char *preString, + const char *inString, + const char *postString) { if (visit == PreVisit) { @@ -2806,17 +3439,10 @@ void OutputHLSL::outputTriplet(Visit visit, const char *preString, const char *i } } -void OutputHLSL::outputTriplet(Visit visit, const char *preString, const char *inString, const char *postString) -{ - outputTriplet(visit, preString, inString, postString, getInfoSink()); -} - -void OutputHLSL::outputLineDirective(int line) +void OutputHLSL::outputLineDirective(TInfoSinkBase &out, int line) { if ((mCompileOptions & SH_LINE_DIRECTIVES) && (line > 0)) { - TInfoSinkBase &out = getInfoSink(); - out << "\n"; out << "#line " << line; @@ -2832,25 +3458,79 @@ void OutputHLSL::outputLineDirective(int line) TString OutputHLSL::argumentString(const TIntermSymbol *symbol) { TQualifier qualifier = symbol->getQualifier(); - const TType &type = symbol->getType(); - TString name = symbol->getSymbol(); + const TType &type = symbol->getType(); + const TName &name = symbol->getName(); + TString nameStr; - if (name.empty()) // HLSL demands named arguments, also for prototypes + if (name.getString().empty()) // HLSL demands named arguments, also for prototypes { - name = "x" + str(mUniqueIndex++); + nameStr = "x" + str(mUniqueIndex++); } - else if (!symbol->isInternal()) + else { - name = Decorate(name); + nameStr = DecorateIfNeeded(name); } - if (mOutputType == SH_HLSL11_OUTPUT && IsSampler(type.getBasicType())) + if (IsSampler(type.getBasicType())) { - return QualifierString(qualifier) + " " + TextureString(type) + " texture_" + name + ArrayString(type) + ", " + - QualifierString(qualifier) + " " + SamplerString(type) + " sampler_" + name + ArrayString(type); + if (mOutputType == SH_HLSL_4_1_OUTPUT) + { + // Samplers are passed as indices to the sampler array. + ASSERT(qualifier != EvqOut && qualifier != EvqInOut); + return "const uint " + nameStr + ArrayString(type); + } + if (mOutputType == SH_HLSL_4_0_FL9_3_OUTPUT) + { + return QualifierString(qualifier) + " " + TextureString(type.getBasicType()) + + " texture_" + nameStr + ArrayString(type) + ", " + QualifierString(qualifier) + + " " + SamplerString(type.getBasicType()) + " sampler_" + nameStr + + ArrayString(type); + } } - return QualifierString(qualifier) + " " + TypeString(type) + " " + name + ArrayString(type); + TStringStream argString; + argString << QualifierString(qualifier) << " " << TypeString(type) << " " << nameStr + << ArrayString(type); + + // If the structure parameter contains samplers, they need to be passed into the function as + // separate parameters. HLSL doesn't natively support samplers in structs. + if (type.isStructureContainingSamplers()) + { + ASSERT(qualifier != EvqOut && qualifier != EvqInOut); + TVector samplerSymbols; + type.createSamplerSymbols("angle" + nameStr, "", 0, &samplerSymbols, nullptr); + for (const TIntermSymbol *sampler : samplerSymbols) + { + if (mOutputType == SH_HLSL_4_1_OUTPUT) + { + argString << ", const uint " << sampler->getSymbol() << ArrayString(type); + } + else if (mOutputType == SH_HLSL_4_0_FL9_3_OUTPUT) + { + const TType &samplerType = sampler->getType(); + ASSERT((!type.isArray() && !samplerType.isArray()) || + type.getArraySize() == samplerType.getArraySize()); + ASSERT(IsSampler(samplerType.getBasicType())); + argString << ", " << QualifierString(qualifier) << " " + << TextureString(samplerType.getBasicType()) << " texture_" + << sampler->getSymbol() << ArrayString(type) << ", " + << QualifierString(qualifier) << " " + << SamplerString(samplerType.getBasicType()) << " sampler_" + << sampler->getSymbol() << ArrayString(type); + } + else + { + const TType &samplerType = sampler->getType(); + ASSERT((!type.isArray() && !samplerType.isArray()) || + type.getArraySize() == samplerType.getArraySize()); + ASSERT(IsSampler(samplerType.getBasicType())); + argString << ", " << QualifierString(qualifier) << " " << TypeString(samplerType) + << " " << sampler->getSymbol() << ArrayString(type); + } + } + } + + return argString.str(); } TString OutputHLSL::initializer(const TType &type) @@ -2871,19 +3551,22 @@ TString OutputHLSL::initializer(const TType &type) return "{" + string + "}"; } -void OutputHLSL::outputConstructor(Visit visit, const TType &type, const char *name, const TIntermSequence *parameters) +void OutputHLSL::outputConstructor(TInfoSinkBase &out, + Visit visit, + const TType &type, + const char *name, + const TIntermSequence *parameters) { if (type.isArray()) { UNIMPLEMENTED(); } - TInfoSinkBase &out = getInfoSink(); if (visit == PreVisit) { - mStructureHLSL->addConstructor(type, name, parameters); + TString constructorName = mStructureHLSL->addConstructor(type, name, parameters); - out << name << "("; + out << constructorName << "("; } else if (visit == InVisit) { @@ -2895,9 +3578,11 @@ void OutputHLSL::outputConstructor(Visit visit, const TType &type, const char *n } } -const TConstantUnion *OutputHLSL::writeConstantUnion(const TType &type, const TConstantUnion *constUnion) +const TConstantUnion *OutputHLSL::writeConstantUnion(TInfoSinkBase &out, + const TType &type, + const TConstantUnion *const constUnion) { - TInfoSinkBase &out = getInfoSink(); + const TConstantUnion *constUnionIterated = constUnion; const TStructure* structure = type.getStruct(); if (structure) @@ -2909,7 +3594,7 @@ const TConstantUnion *OutputHLSL::writeConstantUnion(const TType &type, const TC for (size_t i = 0; i < fields.size(); i++) { const TType *fieldType = fields[i]->type(); - constUnion = writeConstantUnion(*fieldType, constUnion); + constUnionIterated = writeConstantUnion(out, *fieldType, constUnionIterated); if (i != fields.size() - 1) { @@ -2928,37 +3613,20 @@ const TConstantUnion *OutputHLSL::writeConstantUnion(const TType &type, const TC { out << TypeString(type) << "("; } - - for (size_t i = 0; i < size; i++, constUnion++) - { - switch (constUnion->getType()) - { - case EbtFloat: out << std::min(FLT_MAX, std::max(-FLT_MAX, constUnion->getFConst())); break; - case EbtInt: out << constUnion->getIConst(); break; - case EbtUInt: out << constUnion->getUConst(); break; - case EbtBool: out << constUnion->getBConst(); break; - default: UNREACHABLE(); - } - - if (i != size - 1) - { - out << ", "; - } - } - + constUnionIterated = WriteConstantUnionArray(out, constUnionIterated, size); if (writeType) { out << ")"; } } - return constUnion; + return constUnionIterated; } -void OutputHLSL::writeEmulatedFunctionTriplet(Visit visit, const char *preStr) +void OutputHLSL::writeEmulatedFunctionTriplet(TInfoSinkBase &out, Visit visit, const char *preStr) { TString preString = BuiltInFunctionEmulator::GetEmulatedFunctionName(preStr); - outputTriplet(visit, preString.c_str(), ", ", ")"); + outputTriplet(out, visit, preString.c_str(), ", ", ")"); } bool OutputHLSL::writeSameSymbolInitializer(TInfoSinkBase &out, TIntermSymbol *symbolNode, TIntermTyped *expression) @@ -2982,33 +3650,66 @@ bool OutputHLSL::writeSameSymbolInitializer(TInfoSinkBase &out, TIntermSymbol *s return false; } -void OutputHLSL::writeDeferredGlobalInitializers(TInfoSinkBase &out) +bool OutputHLSL::canWriteAsHLSLLiteral(TIntermTyped *expression) { - out << "#define ANGLE_USES_DEFERRED_INIT\n" - << "\n" - << "void initializeDeferredGlobals()\n" - << "{\n"; - - for (const auto &deferredGlobal : mDeferredGlobalInitializers) + // We support writing constant unions and constructors that only take constant unions as + // parameters as HLSL literals. + if (expression->getAsConstantUnion()) { - TIntermSymbol *symbol = deferredGlobal.first; - TIntermTyped *expression = deferredGlobal.second; - ASSERT(symbol); - ASSERT(symbol->getQualifier() == EvqGlobal && expression->getQualifier() != EvqConst); - - out << " " << Decorate(symbol->getSymbol()) << " = "; + return true; + } + if (expression->getQualifier() != EvqConst || !expression->getAsAggregate() || + !expression->getAsAggregate()->isConstructor()) + { + return false; + } + TIntermAggregate *constructor = expression->getAsAggregate(); + for (TIntermNode *&node : *constructor->getSequence()) + { + if (!node->getAsConstantUnion()) + return false; + } + return true; +} - if (!writeSameSymbolInitializer(out, symbol, expression)) +bool OutputHLSL::writeConstantInitialization(TInfoSinkBase &out, + TIntermSymbol *symbolNode, + TIntermTyped *expression) +{ + if (canWriteAsHLSLLiteral(expression)) + { + symbolNode->traverse(this); + if (expression->getType().isArray()) { - ASSERT(mInfoSinkStack.top() == &out); - expression->traverse(this); + out << "[" << expression->getType().getArraySize() << "]"; } - - out << ";\n"; + out << " = {"; + if (expression->getAsConstantUnion()) + { + TIntermConstantUnion *nodeConst = expression->getAsConstantUnion(); + const TConstantUnion *constUnion = nodeConst->getUnionArrayPointer(); + WriteConstantUnionArray(out, constUnion, nodeConst->getType().getObjectSize()); + } + else + { + TIntermAggregate *constructor = expression->getAsAggregate(); + ASSERT(constructor != nullptr); + for (TIntermNode *&node : *constructor->getSequence()) + { + TIntermConstantUnion *nodeConst = node->getAsConstantUnion(); + ASSERT(nodeConst); + const TConstantUnion *constUnion = nodeConst->getUnionArrayPointer(); + WriteConstantUnionArray(out, constUnion, nodeConst->getType().getObjectSize()); + if (node != constructor->getSequence()->back()) + { + out << ", "; + } + } + } + out << "}"; + return true; } - - out << "}\n" - << "\n"; + return false; } TString OutputHLSL::addStructEqualityFunction(const TStructure &structure) diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/OutputHLSL.h b/Source/ThirdParty/ANGLE/src/compiler/translator/OutputHLSL.h index 59f305c46a5a..c5003bad558f 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/OutputHLSL.h +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/OutputHLSL.h @@ -47,8 +47,10 @@ class OutputHLSL : public TIntermTraverser TInfoSinkBase &getInfoSink() { ASSERT(!mInfoSinkStack.empty()); return *mInfoSinkStack.top(); } + static bool canWriteAsHLSLLiteral(TIntermTyped *expression); + protected: - void header(const BuiltInFunctionEmulator *builtInFunctionEmulator); + void header(TInfoSinkBase &out, const BuiltInFunctionEmulator *builtInFunctionEmulator); // Visit AST nodes and output their code to the body stream void visitSymbol(TIntermSymbol*); @@ -63,29 +65,43 @@ class OutputHLSL : public TIntermTraverser bool visitLoop(Visit visit, TIntermLoop*); bool visitBranch(Visit visit, TIntermBranch*); - void traverseStatements(TIntermNode *node); bool isSingleStatement(TIntermNode *node); - bool handleExcessiveLoop(TIntermLoop *node); + bool handleExcessiveLoop(TInfoSinkBase &out, TIntermLoop *node); // Emit one of three strings depending on traverse phase. Called with literal strings so using const char* instead of TString. - void outputTriplet(Visit visit, const char *preString, const char *inString, const char *postString, TInfoSinkBase &out); - void outputTriplet(Visit visit, const char *preString, const char *inString, const char *postString); - void outputLineDirective(int line); + void outputTriplet(TInfoSinkBase &out, + Visit visit, + const char *preString, + const char *inString, + const char *postString); + void outputLineDirective(TInfoSinkBase &out, int line); TString argumentString(const TIntermSymbol *symbol); int vectorSize(const TType &type) const; // Emit constructor. Called with literal names so using const char* instead of TString. - void outputConstructor(Visit visit, const TType &type, const char *name, const TIntermSequence *parameters); - const TConstantUnion *writeConstantUnion(const TType &type, const TConstantUnion *constUnion); + void outputConstructor(TInfoSinkBase &out, + Visit visit, + const TType &type, + const char *name, + const TIntermSequence *parameters); + const TConstantUnion *writeConstantUnion(TInfoSinkBase &out, + const TType &type, + const TConstantUnion *constUnion); void outputEqual(Visit visit, const TType &type, TOperator op, TInfoSinkBase &out); - void writeEmulatedFunctionTriplet(Visit visit, const char *preStr); + void writeEmulatedFunctionTriplet(TInfoSinkBase &out, Visit visit, const char *preStr); void makeFlaggedStructMaps(const std::vector &flaggedStructs); // Returns true if it found a 'same symbol' initializer (initializer that references the variable it's initting) bool writeSameSymbolInitializer(TInfoSinkBase &out, TIntermSymbol *symbolNode, TIntermTyped *expression); + // Returns true if variable initializer could be written using literal {} notation. + bool writeConstantInitialization(TInfoSinkBase &out, + TIntermSymbol *symbolNode, + TIntermTyped *expression); + void writeDeferredGlobalInitializers(TInfoSinkBase &out); + void writeSelection(TInfoSinkBase &out, TIntermSelection *node); // Returns the function name TString addStructEqualityFunction(const TStructure &structure); @@ -103,7 +119,6 @@ class OutputHLSL : public TIntermTraverser const ShShaderOutput mOutputType; int mCompileOptions; - UnfoldShortCircuit *mUnfoldShortCircuit; bool mInsideFunction; // Output streams @@ -162,6 +177,7 @@ class OutputHLSL : public TIntermTraverser bool mUsesFrontFacing; bool mUsesPointSize; bool mUsesInstanceID; + bool mUsesVertexID; bool mUsesFragDepth; bool mUsesXor; bool mUsesDiscardRewriting; @@ -187,12 +203,6 @@ class OutputHLSL : public TIntermTraverser std::map mFlaggedStructMappedNames; std::map mFlaggedStructOriginalNames; - // Some initializers use varyings, uniforms or attributes, thus we can't evaluate some variables - // at global static scope in HLSL. These variables depend on values which we retrieve from the - // shader input structure, which we set in the D3D main function. Instead, we can initialize - // these static globals after we initialize our other globals. - std::vector> mDeferredGlobalInitializers; - struct HelperFunction { TString functionName; @@ -225,6 +235,10 @@ class OutputHLSL : public TIntermTraverser // with the other N parameters of the function. This is used to work around that arrays can't be // return values in HLSL. std::vector mArrayConstructIntoFunctions; + + private: + TString samplerNamePrefixFromStruct(TIntermTyped *node); + bool ancestorEvaluatesToSamplerInStruct(Visit visit); }; } diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/ParseContext.cpp b/Source/ThirdParty/ANGLE/src/compiler/translator/ParseContext.cpp index 1cd787c7b4f4..7f67daae197f 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/ParseContext.cpp +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/ParseContext.cpp @@ -10,8 +10,11 @@ #include #include "compiler/preprocessor/SourceLocation.h" +#include "compiler/translator/Cache.h" #include "compiler/translator/glslang.h" #include "compiler/translator/ValidateSwitch.h" +#include "compiler/translator/ValidateGlobalInitializer.h" +#include "compiler/translator/util.h" /////////////////////////////////////////////////////////////////////// // @@ -23,86 +26,98 @@ // Look at a '.' field selector string and change it into offsets // for a vector. // -bool TParseContext::parseVectorFields(const TString& compString, int vecSize, TVectorFields& fields, const TSourceLoc& line) +bool TParseContext::parseVectorFields(const TString &compString, + int vecSize, + TVectorFields &fields, + const TSourceLoc &line) { - fields.num = (int) compString.size(); - if (fields.num > 4) { + fields.num = (int)compString.size(); + if (fields.num > 4) + { error(line, "illegal vector field selection", compString.c_str()); return false; } - enum { + enum + { exyzw, ergba, estpq } fieldSet[4]; - for (int i = 0; i < fields.num; ++i) { - switch (compString[i]) { - case 'x': - fields.offsets[i] = 0; - fieldSet[i] = exyzw; - break; - case 'r': - fields.offsets[i] = 0; - fieldSet[i] = ergba; - break; - case 's': - fields.offsets[i] = 0; - fieldSet[i] = estpq; - break; - case 'y': - fields.offsets[i] = 1; - fieldSet[i] = exyzw; - break; - case 'g': - fields.offsets[i] = 1; - fieldSet[i] = ergba; - break; - case 't': - fields.offsets[i] = 1; - fieldSet[i] = estpq; - break; - case 'z': - fields.offsets[i] = 2; - fieldSet[i] = exyzw; - break; - case 'b': - fields.offsets[i] = 2; - fieldSet[i] = ergba; - break; - case 'p': - fields.offsets[i] = 2; - fieldSet[i] = estpq; - break; - - case 'w': - fields.offsets[i] = 3; - fieldSet[i] = exyzw; - break; - case 'a': - fields.offsets[i] = 3; - fieldSet[i] = ergba; - break; - case 'q': - fields.offsets[i] = 3; - fieldSet[i] = estpq; - break; - default: - error(line, "illegal vector field selection", compString.c_str()); - return false; + for (int i = 0; i < fields.num; ++i) + { + switch (compString[i]) + { + case 'x': + fields.offsets[i] = 0; + fieldSet[i] = exyzw; + break; + case 'r': + fields.offsets[i] = 0; + fieldSet[i] = ergba; + break; + case 's': + fields.offsets[i] = 0; + fieldSet[i] = estpq; + break; + case 'y': + fields.offsets[i] = 1; + fieldSet[i] = exyzw; + break; + case 'g': + fields.offsets[i] = 1; + fieldSet[i] = ergba; + break; + case 't': + fields.offsets[i] = 1; + fieldSet[i] = estpq; + break; + case 'z': + fields.offsets[i] = 2; + fieldSet[i] = exyzw; + break; + case 'b': + fields.offsets[i] = 2; + fieldSet[i] = ergba; + break; + case 'p': + fields.offsets[i] = 2; + fieldSet[i] = estpq; + break; + + case 'w': + fields.offsets[i] = 3; + fieldSet[i] = exyzw; + break; + case 'a': + fields.offsets[i] = 3; + fieldSet[i] = ergba; + break; + case 'q': + fields.offsets[i] = 3; + fieldSet[i] = estpq; + break; + default: + error(line, "illegal vector field selection", compString.c_str()); + return false; } } - for (int i = 0; i < fields.num; ++i) { - if (fields.offsets[i] >= vecSize) { - error(line, "vector field selection out of range", compString.c_str()); + for (int i = 0; i < fields.num; ++i) + { + if (fields.offsets[i] >= vecSize) + { + error(line, "vector field selection out of range", compString.c_str()); return false; } - if (i > 0) { - if (fieldSet[i] != fieldSet[i-1]) { - error(line, "illegal - vector component fields not from the same set", compString.c_str()); + if (i > 0) + { + if (fieldSet[i] != fieldSet[i - 1]) + { + error(line, "illegal - vector component fields not from the same set", + compString.c_str()); return false; } } @@ -111,55 +126,6 @@ bool TParseContext::parseVectorFields(const TString& compString, int vecSize, TV return true; } - -// -// Look at a '.' field selector string and change it into offsets -// for a matrix. -// -bool TParseContext::parseMatrixFields(const TString& compString, int matCols, int matRows, TMatrixFields& fields, const TSourceLoc& line) -{ - fields.wholeRow = false; - fields.wholeCol = false; - fields.row = -1; - fields.col = -1; - - if (compString.size() != 2) { - error(line, "illegal length of matrix field selection", compString.c_str()); - return false; - } - - if (compString[0] == '_') { - if (compString[1] < '0' || compString[1] > '3') { - error(line, "illegal matrix field selection", compString.c_str()); - return false; - } - fields.wholeCol = true; - fields.col = compString[1] - '0'; - } else if (compString[1] == '_') { - if (compString[0] < '0' || compString[0] > '3') { - error(line, "illegal matrix field selection", compString.c_str()); - return false; - } - fields.wholeRow = true; - fields.row = compString[0] - '0'; - } else { - if (compString[0] < '0' || compString[0] > '3' || - compString[1] < '0' || compString[1] > '3') { - error(line, "illegal matrix field selection", compString.c_str()); - return false; - } - fields.row = compString[0] - '0'; - fields.col = compString[1] - '0'; - } - - if (fields.row >= matRows || fields.col >= matCols) { - error(line, "matrix field selection out of range", compString.c_str()); - return false; - } - - return true; -} - /////////////////////////////////////////////////////////////////////// // // Errors @@ -176,32 +142,49 @@ void TParseContext::recover() // // Used by flex/bison to output all syntax and parsing errors. // -void TParseContext::error(const TSourceLoc& loc, - const char* reason, const char* token, - const char* extraInfo) +void TParseContext::error(const TSourceLoc &loc, + const char *reason, + const char *token, + const char *extraInfo) { pp::SourceLocation srcLoc; srcLoc.file = loc.first_file; srcLoc.line = loc.first_line; - diagnostics.writeInfo(pp::Diagnostics::PP_ERROR, - srcLoc, reason, token, extraInfo); - + mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, srcLoc, reason, token, extraInfo); } -void TParseContext::warning(const TSourceLoc& loc, - const char* reason, const char* token, - const char* extraInfo) { +void TParseContext::warning(const TSourceLoc &loc, + const char *reason, + const char *token, + const char *extraInfo) +{ pp::SourceLocation srcLoc; srcLoc.file = loc.first_file; srcLoc.line = loc.first_line; - diagnostics.writeInfo(pp::Diagnostics::PP_WARNING, - srcLoc, reason, token, extraInfo); + mDiagnostics.writeInfo(pp::Diagnostics::PP_WARNING, srcLoc, reason, token, extraInfo); +} + +void TParseContext::outOfRangeError(bool isError, + const TSourceLoc &loc, + const char *reason, + const char *token, + const char *extraInfo) +{ + if (isError) + { + error(loc, reason, token, extraInfo); + recover(); + } + else + { + warning(loc, reason, token, extraInfo); + } } // // Same error message for all places assignments don't work. // -void TParseContext::assignError(const TSourceLoc& line, const char* op, TString left, TString right) +void TParseContext::assignError(const TSourceLoc &line, const char *op, TString left, TString right) { std::stringstream extraInfoStream; extraInfoStream << "cannot convert from '" << right << "' to '" << left << "'"; @@ -212,11 +195,11 @@ void TParseContext::assignError(const TSourceLoc& line, const char* op, TString // // Same error message for all places unary operations don't work. // -void TParseContext::unaryOpError(const TSourceLoc& line, const char* op, TString operand) +void TParseContext::unaryOpError(const TSourceLoc &line, const char *op, TString operand) { std::stringstream extraInfoStream; - extraInfoStream << "no operation '" << op << "' exists that takes an operand of type " << operand - << " (or there is no acceptable conversion)"; + extraInfoStream << "no operation '" << op << "' exists that takes an operand of type " + << operand << " (or there is no acceptable conversion)"; std::string extraInfo = extraInfoStream.str(); error(line, " wrong operand type", op, extraInfo.c_str()); } @@ -224,33 +207,44 @@ void TParseContext::unaryOpError(const TSourceLoc& line, const char* op, TString // // Same error message for all binary operations don't work. // -void TParseContext::binaryOpError(const TSourceLoc& line, const char* op, TString left, TString right) +void TParseContext::binaryOpError(const TSourceLoc &line, + const char *op, + TString left, + TString right) { std::stringstream extraInfoStream; - extraInfoStream << "no operation '" << op << "' exists that takes a left-hand operand of type '" << left - << "' and a right operand of type '" << right << "' (or there is no acceptable conversion)"; + extraInfoStream << "no operation '" << op << "' exists that takes a left-hand operand of type '" + << left << "' and a right operand of type '" << right + << "' (or there is no acceptable conversion)"; std::string extraInfo = extraInfoStream.str(); - error(line, " wrong operand types ", op, extraInfo.c_str()); + error(line, " wrong operand types ", op, extraInfo.c_str()); } -bool TParseContext::precisionErrorCheck(const TSourceLoc& line, TPrecision precision, TBasicType type){ - if (!checksPrecisionErrors) +bool TParseContext::precisionErrorCheck(const TSourceLoc &line, + TPrecision precision, + TBasicType type) +{ + if (!mChecksPrecisionErrors) return false; - switch( type ){ - case EbtFloat: - if( precision == EbpUndefined ){ - error( line, "No precision specified for (float)", "" ); - return true; - } - break; - case EbtInt: - if( precision == EbpUndefined ){ - error( line, "No precision specified (int)", "" ); - return true; + if (precision == EbpUndefined) + { + switch (type) + { + case EbtFloat: + error(line, "No precision specified for (float)", ""); + return true; + case EbtInt: + case EbtUInt: + UNREACHABLE(); // there's always a predeclared qualifier + error(line, "No precision specified (int)", ""); + return true; + default: + if (IsSampler(type)) + { + error(line, "No precision specified (sampler)", ""); + return true; + } } - break; - default: - return false; } return false; } @@ -261,86 +255,112 @@ bool TParseContext::precisionErrorCheck(const TSourceLoc& line, TPrecision preci // // Returns true if the was an error. // -bool TParseContext::lValueErrorCheck(const TSourceLoc& line, const char* op, TIntermTyped* node) +bool TParseContext::lValueErrorCheck(const TSourceLoc &line, const char *op, TIntermTyped *node) { - TIntermSymbol* symNode = node->getAsSymbolNode(); - TIntermBinary* binaryNode = node->getAsBinaryNode(); + TIntermSymbol *symNode = node->getAsSymbolNode(); + TIntermBinary *binaryNode = node->getAsBinaryNode(); - if (binaryNode) { + if (binaryNode) + { bool errorReturn; - switch(binaryNode->getOp()) { - case EOpIndexDirect: - case EOpIndexIndirect: - case EOpIndexDirectStruct: - case EOpIndexDirectInterfaceBlock: - return lValueErrorCheck(line, op, binaryNode->getLeft()); - case EOpVectorSwizzle: - errorReturn = lValueErrorCheck(line, op, binaryNode->getLeft()); - if (!errorReturn) { - int offset[4] = {0,0,0,0}; - - TIntermTyped* rightNode = binaryNode->getRight(); - TIntermAggregate *aggrNode = rightNode->getAsAggregate(); - - for (TIntermSequence::iterator p = aggrNode->getSequence()->begin(); - p != aggrNode->getSequence()->end(); p++) { - int value = (*p)->getAsTyped()->getAsConstantUnion()->getIConst(0); - offset[value]++; - if (offset[value] > 1) { - error(line, " l-value of swizzle cannot have duplicate components", op); - - return true; + switch (binaryNode->getOp()) + { + case EOpIndexDirect: + case EOpIndexIndirect: + case EOpIndexDirectStruct: + case EOpIndexDirectInterfaceBlock: + return lValueErrorCheck(line, op, binaryNode->getLeft()); + case EOpVectorSwizzle: + errorReturn = lValueErrorCheck(line, op, binaryNode->getLeft()); + if (!errorReturn) + { + int offset[4] = {0, 0, 0, 0}; + + TIntermTyped *rightNode = binaryNode->getRight(); + TIntermAggregate *aggrNode = rightNode->getAsAggregate(); + + for (TIntermSequence::iterator p = aggrNode->getSequence()->begin(); + p != aggrNode->getSequence()->end(); p++) + { + int value = (*p)->getAsTyped()->getAsConstantUnion()->getIConst(0); + offset[value]++; + if (offset[value] > 1) + { + error(line, " l-value of swizzle cannot have duplicate components", op); + + return true; + } } } - } - return errorReturn; - default: - break; + return errorReturn; + default: + break; } error(line, " l-value required", op); return true; } - - const char* symbol = 0; + const char *symbol = 0; if (symNode != 0) symbol = symNode->getSymbol().c_str(); - const char* message = 0; - switch (node->getQualifier()) { - case EvqConst: message = "can't modify a const"; break; - case EvqConstReadOnly: message = "can't modify a const"; break; - case EvqAttribute: message = "can't modify an attribute"; break; - case EvqFragmentIn: message = "can't modify an input"; break; - case EvqVertexIn: message = "can't modify an input"; break; - case EvqUniform: message = "can't modify a uniform"; break; - case EvqVaryingIn: message = "can't modify a varying"; break; - case EvqFragCoord: message = "can't modify gl_FragCoord"; break; - case EvqFrontFacing: message = "can't modify gl_FrontFacing"; break; - case EvqPointCoord: message = "can't modify gl_PointCoord"; break; - default: - - // - // Type that can't be written to? - // - if (node->getBasicType() == EbtVoid) { - message = "can't modify void"; - } - if (IsSampler(node->getBasicType())) { - message = "can't modify a sampler"; - } + const char *message = 0; + switch (node->getQualifier()) + { + case EvqConst: + message = "can't modify a const"; + break; + case EvqConstReadOnly: + message = "can't modify a const"; + break; + case EvqAttribute: + message = "can't modify an attribute"; + break; + case EvqFragmentIn: + message = "can't modify an input"; + break; + case EvqVertexIn: + message = "can't modify an input"; + break; + case EvqUniform: + message = "can't modify a uniform"; + break; + case EvqVaryingIn: + message = "can't modify a varying"; + break; + case EvqFragCoord: + message = "can't modify gl_FragCoord"; + break; + case EvqFrontFacing: + message = "can't modify gl_FrontFacing"; + break; + case EvqPointCoord: + message = "can't modify gl_PointCoord"; + break; + default: + // + // Type that can't be written to? + // + if (node->getBasicType() == EbtVoid) + { + message = "can't modify void"; + } + if (IsSampler(node->getBasicType())) + { + message = "can't modify a sampler"; + } } - if (message == 0 && binaryNode == 0 && symNode == 0) { + if (message == 0 && binaryNode == 0 && symNode == 0) + { error(line, " l-value required", op); return true; } - // // Everything else is okay, no error. // @@ -350,13 +370,15 @@ bool TParseContext::lValueErrorCheck(const TSourceLoc& line, const char* op, TIn // // If we get here, we have an error and a message. // - if (symNode) { + if (symNode) + { std::stringstream extraInfoStream; extraInfoStream << "\"" << symbol << "\" (" << message << ")"; std::string extraInfo = extraInfoStream.str(); error(line, " l-value required", op, extraInfo.c_str()); } - else { + else + { std::stringstream extraInfoStream; extraInfoStream << "(" << message << ")"; std::string extraInfo = extraInfoStream.str(); @@ -372,7 +394,7 @@ bool TParseContext::lValueErrorCheck(const TSourceLoc& line, const char* op, TIn // // Returns true if the was an error. // -bool TParseContext::constErrorCheck(TIntermTyped* node) +bool TParseContext::constErrorCheck(TIntermTyped *node) { if (node->getQualifier() == EvqConst) return false; @@ -388,7 +410,7 @@ bool TParseContext::constErrorCheck(TIntermTyped* node) // // Returns true if the was an error. // -bool TParseContext::integerErrorCheck(TIntermTyped* node, const char* token) +bool TParseContext::integerErrorCheck(TIntermTyped *node, const char *token) { if (node->isScalarInt()) return false; @@ -404,7 +426,7 @@ bool TParseContext::integerErrorCheck(TIntermTyped* node, const char* token) // // Returns true if the was an error. // -bool TParseContext::globalErrorCheck(const TSourceLoc& line, bool global, const char* token) +bool TParseContext::globalErrorCheck(const TSourceLoc &line, bool global, const char *token) { if (global) return false; @@ -423,30 +445,40 @@ bool TParseContext::globalErrorCheck(const TSourceLoc& line, bool global, const // // Returns true if there was an error. // -bool TParseContext::reservedErrorCheck(const TSourceLoc& line, const TString& identifier) +bool TParseContext::reservedErrorCheck(const TSourceLoc &line, const TString &identifier) { - static const char* reservedErrMsg = "reserved built-in name"; - if (!symbolTable.atBuiltInLevel()) { - if (identifier.compare(0, 3, "gl_") == 0) { + static const char *reservedErrMsg = "reserved built-in name"; + if (!symbolTable.atBuiltInLevel()) + { + if (identifier.compare(0, 3, "gl_") == 0) + { error(line, reservedErrMsg, "gl_"); return true; } - if (IsWebGLBasedSpec(shaderSpec)) { - if (identifier.compare(0, 6, "webgl_") == 0) { + if (IsWebGLBasedSpec(mShaderSpec)) + { + if (identifier.compare(0, 6, "webgl_") == 0) + { error(line, reservedErrMsg, "webgl_"); return true; } - if (identifier.compare(0, 7, "_webgl_") == 0) { + if (identifier.compare(0, 7, "_webgl_") == 0) + { error(line, reservedErrMsg, "_webgl_"); return true; } - if (shaderSpec == SH_CSS_SHADERS_SPEC && identifier.compare(0, 4, "css_") == 0) { + if (mShaderSpec == SH_CSS_SHADERS_SPEC && identifier.compare(0, 4, "css_") == 0) + { error(line, reservedErrMsg, "css_"); return true; } } - if (identifier.find("__") != TString::npos) { - error(line, "identifiers containing two consecutive underscores (__) are reserved as possible future keywords", identifier.c_str()); + if (identifier.find("__") != TString::npos) + { + error(line, + "identifiers containing two consecutive underscores (__) are reserved as " + "possible future keywords", + identifier.c_str()); return true; } } @@ -461,19 +493,30 @@ bool TParseContext::reservedErrorCheck(const TSourceLoc& line, const TString& id // // Returns true if there was an error in construction. // -bool TParseContext::constructorErrorCheck(const TSourceLoc& line, TIntermNode* node, TFunction& function, TOperator op, TType* type) +bool TParseContext::constructorErrorCheck(const TSourceLoc &line, + TIntermNode *argumentsNode, + TFunction &function, + TOperator op, + TType *type) { *type = function.getReturnType(); bool constructingMatrix = false; - switch(op) { - case EOpConstructMat2: - case EOpConstructMat3: - case EOpConstructMat4: - constructingMatrix = true; - break; - default: - break; + switch (op) + { + case EOpConstructMat2: + case EOpConstructMat2x3: + case EOpConstructMat2x4: + case EOpConstructMat3x2: + case EOpConstructMat3: + case EOpConstructMat3x4: + case EOpConstructMat4x2: + case EOpConstructMat4x3: + case EOpConstructMat4: + constructingMatrix = true; + break; + default: + break; } // @@ -482,16 +525,17 @@ bool TParseContext::constructorErrorCheck(const TSourceLoc& line, TIntermNode* n // again, there is an extra argument, so 'overfull' will become true. // - size_t size = 0; - bool constType = true; - bool full = false; - bool overFull = false; + size_t size = 0; + bool constType = true; + bool full = false; + bool overFull = false; bool matrixInMatrix = false; bool arrayArg = false; - for (size_t i = 0; i < function.getParamCount(); ++i) { - const TParameter& param = function.getParam(i); + for (size_t i = 0; i < function.getParamCount(); ++i) + { + const TConstParameter ¶m = function.getParam(i); size += param.type->getObjectSize(); - + if (constructingMatrix && param.type->isMatrix()) matrixInMatrix = true; if (full) @@ -503,7 +547,7 @@ bool TParseContext::constructorErrorCheck(const TSourceLoc& line, TIntermNode* n if (param.type->isArray()) arrayArg = true; } - + if (constType) type->setQualifier(EvqConst); @@ -520,58 +564,81 @@ bool TParseContext::constructorErrorCheck(const TSourceLoc& line, TIntermNode* n } } - if (arrayArg && op != EOpConstructStruct) { + if (arrayArg && op != EOpConstructStruct) + { error(line, "constructing from a non-dereferenced array", "constructor"); return true; } - if (matrixInMatrix && !type->isArray()) { - if (function.getParamCount() != 1) { - error(line, "constructing matrix from matrix can only take one argument", "constructor"); - return true; + if (matrixInMatrix && !type->isArray()) + { + if (function.getParamCount() != 1) + { + error(line, "constructing matrix from matrix can only take one argument", + "constructor"); + return true; } } - if (overFull) { + if (overFull) + { error(line, "too many arguments", "constructor"); return true; } - - if (op == EOpConstructStruct && !type->isArray() && type->getStruct()->fields().size() != function.getParamCount()) { - error(line, "Number of constructor parameters does not match the number of structure fields", "constructor"); + + if (op == EOpConstructStruct && !type->isArray() && + type->getStruct()->fields().size() != function.getParamCount()) + { + error(line, + "Number of constructor parameters does not match the number of structure fields", + "constructor"); return true; } - if (!type->isMatrix() || !matrixInMatrix) { + if (!type->isMatrix() || !matrixInMatrix) + { if ((op != EOpConstructStruct && size != 1 && size < type->getObjectSize()) || - (op == EOpConstructStruct && size < type->getObjectSize())) { + (op == EOpConstructStruct && size < type->getObjectSize())) + { error(line, "not enough data provided for construction", "constructor"); return true; } } - TIntermTyped *typed = node ? node->getAsTyped() : 0; - if (typed == 0) { - error(line, "constructor argument does not have a type", "constructor"); - return true; - } - if (op != EOpConstructStruct && IsSampler(typed->getBasicType())) { - error(line, "cannot convert a sampler", "constructor"); + if (argumentsNode == nullptr) + { + error(line, "constructor does not have any arguments", "constructor"); return true; } - if (typed->getBasicType() == EbtVoid) { - error(line, "cannot convert a void", "constructor"); - return true; + + TIntermAggregate *argumentsAgg = argumentsNode->getAsAggregate(); + for (TIntermNode *&argNode : *argumentsAgg->getSequence()) + { + TIntermTyped *argTyped = argNode->getAsTyped(); + ASSERT(argTyped != nullptr); + if (op != EOpConstructStruct && IsSampler(argTyped->getBasicType())) + { + error(line, "cannot convert a sampler", "constructor"); + return true; + } + if (argTyped->getBasicType() == EbtVoid) + { + error(line, "cannot convert a void", "constructor"); + return true; + } } return false; } -// This function checks to see if a void variable has been declared and raise an error message for such a case +// This function checks to see if a void variable has been declared and raise an error message for +// such a case // // returns true in case of an error // -bool TParseContext::voidErrorCheck(const TSourceLoc &line, const TString &identifier, const TBasicType &type) +bool TParseContext::voidErrorCheck(const TSourceLoc &line, + const TString &identifier, + const TBasicType &type) { if (type == EbtVoid) { @@ -582,45 +649,55 @@ bool TParseContext::voidErrorCheck(const TSourceLoc &line, const TString &identi return false; } -// This function checks to see if the node (for the expression) contains a scalar boolean expression or not +// This function checks to see if the node (for the expression) contains a scalar boolean expression +// or not // // returns true in case of an error // -bool TParseContext::boolErrorCheck(const TSourceLoc& line, const TIntermTyped* type) +bool TParseContext::boolErrorCheck(const TSourceLoc &line, const TIntermTyped *type) { - if (type->getBasicType() != EbtBool || type->isArray() || type->isMatrix() || type->isVector()) { + if (type->getBasicType() != EbtBool || type->isArray() || type->isMatrix() || type->isVector()) + { error(line, "boolean expression expected", ""); return true; - } + } return false; } -// This function checks to see if the node (for the expression) contains a scalar boolean expression or not +// This function checks to see if the node (for the expression) contains a scalar boolean expression +// or not // // returns true in case of an error // -bool TParseContext::boolErrorCheck(const TSourceLoc& line, const TPublicType& pType) +bool TParseContext::boolErrorCheck(const TSourceLoc &line, const TPublicType &pType) { - if (pType.type != EbtBool || pType.isAggregate()) { + if (pType.type != EbtBool || pType.isAggregate()) + { error(line, "boolean expression expected", ""); return true; - } + } return false; } -bool TParseContext::samplerErrorCheck(const TSourceLoc& line, const TPublicType& pType, const char* reason) +bool TParseContext::samplerErrorCheck(const TSourceLoc &line, + const TPublicType &pType, + const char *reason) { - if (pType.type == EbtStruct) { - if (containsSampler(*pType.userDef)) { + if (pType.type == EbtStruct) + { + if (containsSampler(*pType.userDef)) + { error(line, reason, getBasicString(pType.type), "(structure contains a sampler)"); - + return true; } - + return false; - } else if (IsSampler(pType.type)) { + } + else if (IsSampler(pType.type)) + { error(line, reason, getBasicString(pType.type)); return true; @@ -629,21 +706,25 @@ bool TParseContext::samplerErrorCheck(const TSourceLoc& line, const TPublicType& return false; } -bool TParseContext::locationDeclaratorListCheck(const TSourceLoc& line, const TPublicType &pType) +bool TParseContext::locationDeclaratorListCheck(const TSourceLoc &line, const TPublicType &pType) { if (pType.layoutQualifier.location != -1) { - error(line, "location must only be specified for a single input or output variable", "location"); + error(line, "location must only be specified for a single input or output variable", + "location"); return true; } return false; } -bool TParseContext::parameterSamplerErrorCheck(const TSourceLoc& line, TQualifier qualifier, const TType& type) +bool TParseContext::parameterSamplerErrorCheck(const TSourceLoc &line, + TQualifier qualifier, + const TType &type) { - if ((qualifier == EvqOut || qualifier == EvqInOut) && - type.getBasicType() != EbtStruct && IsSampler(type.getBasicType())) { + if ((qualifier == EvqOut || qualifier == EvqInOut) && type.getBasicType() != EbtStruct && + IsSampler(type.getBasicType())) + { error(line, "samplers cannot be output parameters", type.getBasicString()); return true; } @@ -651,14 +732,16 @@ bool TParseContext::parameterSamplerErrorCheck(const TSourceLoc& line, TQualifie return false; } -bool TParseContext::containsSampler(TType& type) +bool TParseContext::containsSampler(const TType &type) { if (IsSampler(type.getBasicType())) return true; - if (type.getBasicType() == EbtStruct || type.isInterfaceBlock()) { - const TFieldList& fields = type.getStruct()->fields(); - for (unsigned int i = 0; i < fields.size(); ++i) { + if (type.getBasicType() == EbtStruct || type.isInterfaceBlock()) + { + const TFieldList &fields = type.getStruct()->fields(); + for (unsigned int i = 0; i < fields.size(); ++i) + { if (containsSampler(*fields[i]->type())) return true; } @@ -672,11 +755,14 @@ bool TParseContext::containsSampler(TType& type) // // Returns true if there was an error. // -bool TParseContext::arraySizeErrorCheck(const TSourceLoc& line, TIntermTyped* expr, int& size) +bool TParseContext::arraySizeErrorCheck(const TSourceLoc &line, TIntermTyped *expr, int &size) { - TIntermConstantUnion* constant = expr->getAsConstantUnion(); + TIntermConstantUnion *constant = expr->getAsConstantUnion(); - if (constant == nullptr || !constant->isScalarInt()) + // TODO(oetuaho@nvidia.com): Get rid of the constant == nullptr check here once all constant + // expressions can be folded. Right now we don't allow constant expressions that ANGLE can't + // fold as array size. + if (expr->getQualifier() != EvqConst || constant == nullptr || !constant->isScalarInt()) { error(line, "array size must be a constant integer expression", ""); size = 1; @@ -688,7 +774,7 @@ bool TParseContext::arraySizeErrorCheck(const TSourceLoc& line, TIntermTyped* ex if (constant->getBasicType() == EbtUInt) { unsignedSize = constant->getUConst(0); - size = static_cast(unsignedSize); + size = static_cast(unsignedSize); } else { @@ -734,9 +820,10 @@ bool TParseContext::arraySizeErrorCheck(const TSourceLoc& line, TIntermTyped* ex bool TParseContext::arrayQualifierErrorCheck(const TSourceLoc &line, const TPublicType &type) { if ((type.qualifier == EvqAttribute) || (type.qualifier == EvqVertexIn) || - (type.qualifier == EvqConst && shaderVersion < 300)) + (type.qualifier == EvqConst && mShaderVersion < 300)) { - error(line, "cannot declare arrays of this qualifier", TType(type).getCompleteString().c_str()); + error(line, "cannot declare arrays of this qualifier", + TType(type).getCompleteString().c_str()); return true; } @@ -748,15 +835,25 @@ bool TParseContext::arrayQualifierErrorCheck(const TSourceLoc &line, const TPubl // // Returns true if there is an error. // -bool TParseContext::arrayTypeErrorCheck(const TSourceLoc& line, TPublicType type) +bool TParseContext::arrayTypeErrorCheck(const TSourceLoc &line, const TPublicType &type) { // // Can the type be an array? // - if (type.array) { + if (type.array) + { error(line, "cannot declare arrays of arrays", TType(type).getCompleteString().c_str()); return true; } + // In ESSL1.00 shaders, structs cannot be varying (section 4.3.5). This is checked elsewhere. + // In ESSL3.00 shaders, struct inputs/outputs are allowed but not arrays of structs (section + // 4.3.4). + if (mShaderVersion >= 300 && type.type == EbtStruct && sh::IsVarying(type.qualifier)) + { + error(line, "cannot declare arrays of structs of this qualifier", + TType(type).getCompleteString().c_str()); + return true; + } return false; } @@ -766,7 +863,9 @@ bool TParseContext::arrayTypeErrorCheck(const TSourceLoc& line, TPublicType type // // Returns true if there was an error. // -bool TParseContext::nonInitErrorCheck(const TSourceLoc &line, const TString &identifier, TPublicType *type) +bool TParseContext::nonInitErrorCheck(const TSourceLoc &line, + const TString &identifier, + TPublicType *type) { ASSERT(type != nullptr); if (type->qualifier == EvqConst) @@ -776,9 +875,12 @@ bool TParseContext::nonInitErrorCheck(const TSourceLoc &line, const TString &ide // Generate informative error messages for ESSL1. // In ESSL3 arrays and structures containing arrays can be constant. - if (shaderVersion < 300 && type->isStructureContainingArrays()) + if (mShaderVersion < 300 && type->isStructureContainingArrays()) { - error(line, "structures containing arrays may not be declared constant since they cannot be initialized", identifier.c_str()); + error(line, + "structures containing arrays may not be declared constant since they cannot be " + "initialized", + identifier.c_str()); } else { @@ -800,7 +902,9 @@ bool TParseContext::nonInitErrorCheck(const TSourceLoc &line, const TString &ide // // Returns true if declaring the variable succeeded. // -bool TParseContext::declareVariable(const TSourceLoc &line, const TString &identifier, const TType &type, +bool TParseContext::declareVariable(const TSourceLoc &line, + const TString &identifier, + const TType &type, TVariable **variable) { ASSERT((*variable) == nullptr); @@ -810,18 +914,19 @@ bool TParseContext::declareVariable(const TSourceLoc &line, const TString &ident // gl_LastFragData may be redeclared with a new precision qualifier if (type.isArray() && identifier.compare(0, 15, "gl_LastFragData") == 0) { - const TVariable *maxDrawBuffers = - static_cast(symbolTable.findBuiltIn("gl_MaxDrawBuffers", shaderVersion)); + const TVariable *maxDrawBuffers = static_cast( + symbolTable.findBuiltIn("gl_MaxDrawBuffers", mShaderVersion)); if (type.getArraySize() == maxDrawBuffers->getConstPointer()->getIConst()) { - if (TSymbol *builtInSymbol = symbolTable.findBuiltIn(identifier, shaderVersion)) + if (TSymbol *builtInSymbol = symbolTable.findBuiltIn(identifier, mShaderVersion)) { needsReservedErrorCheck = extensionErrorCheck(line, builtInSymbol->getExtension()); } } else { - error(line, "redeclaration of gl_LastFragData with size != gl_MaxDrawBuffers", identifier.c_str()); + error(line, "redeclaration of gl_LastFragData with size != gl_MaxDrawBuffers", + identifier.c_str()); return false; } } @@ -833,8 +938,7 @@ bool TParseContext::declareVariable(const TSourceLoc &line, const TString &ident if (!symbolTable.declare(*variable)) { error(line, "redefinition", identifier.c_str()); - delete (*variable); - (*variable) = nullptr; + *variable = nullptr; return false; } @@ -844,14 +948,20 @@ bool TParseContext::declareVariable(const TSourceLoc &line, const TString &ident return true; } -bool TParseContext::paramErrorCheck(const TSourceLoc& line, TQualifier qualifier, TQualifier paramQualifier, TType* type) -{ - if (qualifier != EvqConst && qualifier != EvqTemporary) { +bool TParseContext::paramErrorCheck(const TSourceLoc &line, + TQualifier qualifier, + TQualifier paramQualifier, + TType *type) +{ + if (qualifier != EvqConst && qualifier != EvqTemporary) + { error(line, "qualifier not allowed on function parameter", getQualifierString(qualifier)); return true; } - if (qualifier == EvqConst && paramQualifier != EvqIn) { - error(line, "qualifier not allowed with ", getQualifierString(qualifier), getQualifierString(paramQualifier)); + if (qualifier == EvqConst && paramQualifier != EvqIn) + { + error(line, "qualifier not allowed with ", getQualifierString(qualifier), + getQualifierString(paramQualifier)); return true; } @@ -863,20 +973,23 @@ bool TParseContext::paramErrorCheck(const TSourceLoc& line, TQualifier qualifier return false; } -bool TParseContext::extensionErrorCheck(const TSourceLoc& line, const TString& extension) +bool TParseContext::extensionErrorCheck(const TSourceLoc &line, const TString &extension) { - const TExtensionBehavior& extBehavior = extensionBehavior(); + const TExtensionBehavior &extBehavior = extensionBehavior(); TExtensionBehavior::const_iterator iter = extBehavior.find(extension.c_str()); - if (iter == extBehavior.end()) { + if (iter == extBehavior.end()) + { error(line, "extension", extension.c_str(), "is not supported"); return true; } // In GLSL ES, an extension's default behavior is "disable". - if (iter->second == EBhDisable || iter->second == EBhUndefined) { + if (iter->second == EBhDisable || iter->second == EBhUndefined) + { error(line, "extension", extension.c_str(), "is disabled"); return true; } - if (iter->second == EBhWarn) { + if (iter->second == EBhWarn) + { warning(line, "extension", extension.c_str(), "is being used"); return false; } @@ -884,30 +997,32 @@ bool TParseContext::extensionErrorCheck(const TSourceLoc& line, const TString& e return false; } -// These checks are common for all declarations starting a declarator list, and declarators that follow an empty -// declaration. +// These checks are common for all declarations starting a declarator list, and declarators that +// follow an empty declaration. // -bool TParseContext::singleDeclarationErrorCheck(TPublicType &publicType, const TSourceLoc &identifierLocation) +bool TParseContext::singleDeclarationErrorCheck(const TPublicType &publicType, + const TSourceLoc &identifierLocation) { switch (publicType.qualifier) { - case EvqVaryingIn: - case EvqVaryingOut: - case EvqAttribute: - case EvqVertexIn: - case EvqFragmentOut: - if (publicType.type == EbtStruct) - { - error(identifierLocation, "cannot be used with a structure", - getQualifierString(publicType.qualifier)); - return true; - } + case EvqVaryingIn: + case EvqVaryingOut: + case EvqAttribute: + case EvqVertexIn: + case EvqFragmentOut: + if (publicType.type == EbtStruct) + { + error(identifierLocation, "cannot be used with a structure", + getQualifierString(publicType.qualifier)); + return true; + } - default: break; + default: + break; } - if (publicType.qualifier != EvqUniform && samplerErrorCheck(identifierLocation, publicType, - "samplers must be uniform")) + if (publicType.qualifier != EvqUniform && + samplerErrorCheck(identifierLocation, publicType, "samplers must be uniform")) { return true; } @@ -917,14 +1032,16 @@ bool TParseContext::singleDeclarationErrorCheck(TPublicType &publicType, const T if (layoutQualifier.matrixPacking != EmpUnspecified) { - error(identifierLocation, "layout qualifier", getMatrixPackingString(layoutQualifier.matrixPacking), + error(identifierLocation, "layout qualifier", + getMatrixPackingString(layoutQualifier.matrixPacking), "only valid for interface blocks"); return true; } if (layoutQualifier.blockStorage != EbsUnspecified) { - error(identifierLocation, "layout qualifier", getBlockStorageString(layoutQualifier.blockStorage), + error(identifierLocation, "layout qualifier", + getBlockStorageString(layoutQualifier.blockStorage), "only valid for interface blocks"); return true; } @@ -938,18 +1055,21 @@ bool TParseContext::singleDeclarationErrorCheck(TPublicType &publicType, const T return false; } -bool TParseContext::layoutLocationErrorCheck(const TSourceLoc& location, const TLayoutQualifier &layoutQualifier) +bool TParseContext::layoutLocationErrorCheck(const TSourceLoc &location, + const TLayoutQualifier &layoutQualifier) { if (layoutQualifier.location != -1) { - error(location, "invalid layout qualifier:", "location", "only valid on program inputs and outputs"); + error(location, "invalid layout qualifier:", "location", + "only valid on program inputs and outputs"); return true; } return false; } -bool TParseContext::functionCallLValueErrorCheck(const TFunction *fnCandidate, TIntermAggregate *aggregate) +bool TParseContext::functionCallLValueErrorCheck(const TFunction *fnCandidate, + TIntermAggregate *aggregate) { for (size_t i = 0; i < fnCandidate->getParamCount(); ++i) { @@ -960,7 +1080,7 @@ bool TParseContext::functionCallLValueErrorCheck(const TFunction *fnCandidate, T if (lValueErrorCheck(node->getLine(), "assign", node)) { error(node->getLine(), - "Constant value cannot be passed for 'out' or 'inout' parameters.", "Error"); + "Constant value cannot be passed for 'out' or 'inout' parameters.", "Error"); recover(); return true; } @@ -969,40 +1089,47 @@ bool TParseContext::functionCallLValueErrorCheck(const TFunction *fnCandidate, T return false; } -bool TParseContext::supportsExtension(const char* extension) +void TParseContext::es3InvariantErrorCheck(const TQualifier qualifier, + const TSourceLoc &invariantLocation) { - const TExtensionBehavior& extbehavior = extensionBehavior(); - TExtensionBehavior::const_iterator iter = extbehavior.find(extension); - return (iter != extbehavior.end()); + if (!sh::IsVaryingOut(qualifier) && qualifier != EvqFragmentOut) + { + error(invariantLocation, "Only out variables can be invariant.", "invariant"); + recover(); + } } -bool TParseContext::isExtensionEnabled(const char* extension) const +bool TParseContext::supportsExtension(const char *extension) { - const TExtensionBehavior& extbehavior = extensionBehavior(); + const TExtensionBehavior &extbehavior = extensionBehavior(); TExtensionBehavior::const_iterator iter = extbehavior.find(extension); + return (iter != extbehavior.end()); +} - if (iter == extbehavior.end()) - { - return false; - } - - return (iter->second == EBhEnable || iter->second == EBhRequire); +bool TParseContext::isExtensionEnabled(const char *extension) const +{ + return ::IsExtensionEnabled(extensionBehavior(), extension); } -void TParseContext::handleExtensionDirective(const TSourceLoc& loc, const char* extName, const char* behavior) +void TParseContext::handleExtensionDirective(const TSourceLoc &loc, + const char *extName, + const char *behavior) { pp::SourceLocation srcLoc; srcLoc.file = loc.first_file; srcLoc.line = loc.first_line; - directiveHandler.handleExtension(srcLoc, extName, behavior); + mDirectiveHandler.handleExtension(srcLoc, extName, behavior); } -void TParseContext::handlePragmaDirective(const TSourceLoc& loc, const char* name, const char* value, bool stdgl) +void TParseContext::handlePragmaDirective(const TSourceLoc &loc, + const char *name, + const char *value, + bool stdgl) { pp::SourceLocation srcLoc; srcLoc.file = loc.first_file; srcLoc.line = loc.first_line; - directiveHandler.handlePragma(srcLoc, name, value, stdgl); + mDirectiveHandler.handlePragma(srcLoc, name, value, stdgl); } ///////////////////////////////////////////////////////////////////////////////// @@ -1029,14 +1156,46 @@ const TVariable *TParseContext::getNamedVariable(const TSourceLoc &location, } else { - variable = static_cast(symbol); + variable = static_cast(symbol); - if (symbolTable.findBuiltIn(variable->getName(), shaderVersion) && + if (symbolTable.findBuiltIn(variable->getName(), mShaderVersion) && !variable->getExtension().empty() && extensionErrorCheck(location, variable->getExtension())) { recover(); } + + // Reject shaders using both gl_FragData and gl_FragColor + TQualifier qualifier = variable->getType().getQualifier(); + if (qualifier == EvqFragData || qualifier == EvqSecondaryFragDataEXT) + { + mUsesFragData = true; + } + else if (qualifier == EvqFragColor || qualifier == EvqSecondaryFragColorEXT) + { + mUsesFragColor = true; + } + if (qualifier == EvqSecondaryFragDataEXT || qualifier == EvqSecondaryFragColorEXT) + { + mUsesSecondaryOutputs = true; + } + + // This validation is not quite correct - it's only an error to write to + // both FragData and FragColor. For simplicity, and because users shouldn't + // be rewarded for reading from undefined varaibles, return an error + // if they are both referenced, rather than assigned. + if (mUsesFragData && mUsesFragColor) + { + const char *errorMessage = "cannot use both gl_FragData and gl_FragColor"; + if (mUsesSecondaryOutputs) + { + errorMessage = + "cannot use both output variable sets (gl_FragData, gl_SecondaryFragDataEXT)" + " and (gl_FragColor, gl_SecondaryFragColorEXT)"; + } + error(location, errorMessage, name->c_str()); + recover(); + } } if (!variable) @@ -1050,32 +1209,56 @@ const TVariable *TParseContext::getNamedVariable(const TSourceLoc &location, return variable; } +TIntermTyped *TParseContext::parseVariableIdentifier(const TSourceLoc &location, + const TString *name, + const TSymbol *symbol) +{ + const TVariable *variable = getNamedVariable(location, name, symbol); + + if (variable->getConstPointer()) + { + const TConstantUnion *constArray = variable->getConstPointer(); + return intermediate.addConstantUnion(constArray, variable->getType(), location); + } + else + { + return intermediate.addSymbol(variable->getUniqueId(), variable->getName(), + variable->getType(), location); + } +} + // // Look up a function name in the symbol table, and make sure it is a function. // // Return the function symbol if found, otherwise 0. // -const TFunction* TParseContext::findFunction(const TSourceLoc& line, TFunction* call, int inputShaderVersion, bool *builtIn) +const TFunction *TParseContext::findFunction(const TSourceLoc &line, + TFunction *call, + int inputShaderVersion, + bool *builtIn) { // First find by unmangled name to check whether the function name has been // hidden by a variable name or struct typename. // If a function is found, check for one with a matching argument list. - const TSymbol* symbol = symbolTable.find(call->getName(), inputShaderVersion, builtIn); - if (symbol == 0 || symbol->isFunction()) { + const TSymbol *symbol = symbolTable.find(call->getName(), inputShaderVersion, builtIn); + if (symbol == 0 || symbol->isFunction()) + { symbol = symbolTable.find(call->getMangledName(), inputShaderVersion, builtIn); } - if (symbol == 0) { + if (symbol == 0) + { error(line, "no matching overloaded function found", call->getName().c_str()); return 0; } - if (!symbol->isFunction()) { + if (!symbol->isFunction()) + { error(line, "function name expected", call->getName().c_str()); return 0; } - return static_cast(symbol); + return static_cast(symbol); } // @@ -1084,8 +1267,11 @@ const TFunction* TParseContext::findFunction(const TSourceLoc& line, TFunction* // // Returns true on error, false if no error // -bool TParseContext::executeInitializer(const TSourceLoc &line, const TString &identifier, TPublicType &pType, - TIntermTyped *initializer, TIntermNode **intermNode) +bool TParseContext::executeInitializer(const TSourceLoc &line, + const TString &identifier, + const TPublicType &pType, + TIntermTyped *initializer, + TIntermNode **intermNode) { ASSERT(intermNode != nullptr); TType type = TType(pType); @@ -1100,20 +1286,42 @@ bool TParseContext::executeInitializer(const TSourceLoc &line, const TString &id return true; } + bool globalInitWarning = false; + if (symbolTable.atGlobalLevel() && + !ValidateGlobalInitializer(initializer, this, &globalInitWarning)) + { + // Error message does not completely match behavior with ESSL 1.00, but + // we want to steer developers towards only using constant expressions. + error(line, "global variable initializers must be constant expressions", "="); + return true; + } + if (globalInitWarning) + { + warning( + line, + "global variable initializers should be constant expressions " + "(uniforms and globals are allowed in global initializers for legacy compatibility)", + "="); + } + // // identifier must be of type constant, a global, or a temporary // TQualifier qualifier = variable->getType().getQualifier(); - if ((qualifier != EvqTemporary) && (qualifier != EvqGlobal) && (qualifier != EvqConst)) { - error(line, " cannot initialize this type of qualifier ", variable->getType().getQualifierString()); + if ((qualifier != EvqTemporary) && (qualifier != EvqGlobal) && (qualifier != EvqConst)) + { + error(line, " cannot initialize this type of qualifier ", + variable->getType().getQualifierString()); return true; } // // test for and propagate constant // - if (qualifier == EvqConst) { - if (qualifier != initializer->getType().getQualifier()) { + if (qualifier == EvqConst) + { + if (qualifier != initializer->getType().getQualifier()) + { std::stringstream extraInfoStream; extraInfoStream << "'" << variable->getType().getCompleteString() << "'"; std::string extraInfo = extraInfoStream.str(); @@ -1121,86 +1329,76 @@ bool TParseContext::executeInitializer(const TSourceLoc &line, const TString &id variable->getType().setQualifier(EvqTemporary); return true; } - if (type != initializer->getType()) { - error(line, " non-matching types for const initializer ", - variable->getType().getQualifierString()); + if (type != initializer->getType()) + { + error(line, " non-matching types for const initializer ", + variable->getType().getQualifierString()); variable->getType().setQualifier(EvqTemporary); return true; } - if (initializer->getAsConstantUnion()) { - variable->shareConstPointer(initializer->getAsConstantUnion()->getUnionArrayPointer()); - } else if (initializer->getAsSymbolNode()) { - const TSymbol* symbol = symbolTable.find(initializer->getAsSymbolNode()->getSymbol(), 0); - const TVariable* tVar = static_cast(symbol); - TConstantUnion* constArray = tVar->getConstPointer(); - variable->shareConstPointer(constArray); - } else { - std::stringstream extraInfoStream; - extraInfoStream << "'" << variable->getType().getCompleteString() << "'"; - std::string extraInfo = extraInfoStream.str(); - error(line, " cannot assign to", "=", extraInfo.c_str()); - variable->getType().setQualifier(EvqTemporary); - return true; + // Save the constant folded value to the variable if possible. For example array + // initializers are not folded, since that way copying the array literal to multiple places + // in the shader is avoided. + // TODO(oetuaho@nvidia.com): Consider constant folding array initialization in cases where + // it would be beneficial. + if (initializer->getAsConstantUnion()) + { + variable->shareConstPointer(initializer->getAsConstantUnion()->getUnionArrayPointer()); + *intermNode = nullptr; + return false; } - } - - if (qualifier != EvqConst) - { - TIntermSymbol *intermSymbol = intermediate.addSymbol(variable->getUniqueId(), variable->getName(), - variable->getType(), line); - *intermNode = createAssign(EOpInitialize, intermSymbol, initializer, line); - if (*intermNode == nullptr) + else if (initializer->getAsSymbolNode()) { - assignError(line, "=", intermSymbol->getCompleteString(), initializer->getCompleteString()); - return true; + const TSymbol *symbol = + symbolTable.find(initializer->getAsSymbolNode()->getSymbol(), 0); + const TVariable *tVar = static_cast(symbol); + + const TConstantUnion *constArray = tVar->getConstPointer(); + if (constArray) + { + variable->shareConstPointer(constArray); + *intermNode = nullptr; + return false; + } } } - else + + TIntermSymbol *intermSymbol = intermediate.addSymbol( + variable->getUniqueId(), variable->getName(), variable->getType(), line); + *intermNode = createAssign(EOpInitialize, intermSymbol, initializer, line); + if (*intermNode == nullptr) { - *intermNode = nullptr; + assignError(line, "=", intermSymbol->getCompleteString(), initializer->getCompleteString()); + return true; } return false; } -bool TParseContext::areAllChildConst(TIntermAggregate* aggrNode) -{ - ASSERT(aggrNode != NULL); - if (!aggrNode->isConstructor()) - return false; - - bool allConstant = true; - - // check if all the child nodes are constants so that they can be inserted into - // the parent node - TIntermSequence *sequence = aggrNode->getSequence() ; - for (TIntermSequence::iterator p = sequence->begin(); p != sequence->end(); ++p) { - if (!(*p)->getAsTyped()->getAsConstantUnion()) - return false; - } - - return allConstant; -} - -TPublicType TParseContext::addFullySpecifiedType(TQualifier qualifier, TLayoutQualifier layoutQualifier, const TPublicType& typeSpecifier) +TPublicType TParseContext::addFullySpecifiedType(TQualifier qualifier, + bool invariant, + TLayoutQualifier layoutQualifier, + const TPublicType &typeSpecifier) { - TPublicType returnType = typeSpecifier; - returnType.qualifier = qualifier; + TPublicType returnType = typeSpecifier; + returnType.qualifier = qualifier; + returnType.invariant = invariant; returnType.layoutQualifier = layoutQualifier; - if (typeSpecifier.array) - { - error(typeSpecifier.line, "not supported", "first-class array"); - recover(); - returnType.clearArrayness(); - } - - if (shaderVersion < 300) + if (mShaderVersion < 300) { - if (qualifier == EvqAttribute && (typeSpecifier.type == EbtBool || typeSpecifier.type == EbtInt)) + if (typeSpecifier.array) { - error(typeSpecifier.line, "cannot be bool or int", getQualifierString(qualifier)); + error(typeSpecifier.line, "not supported", "first-class array"); + recover(); + returnType.clearArrayness(); + } + + if (qualifier == EvqAttribute && + (typeSpecifier.type == EbtBool || typeSpecifier.type == EbtInt)) + { + error(typeSpecifier.line, "cannot be bool or int", getQualifierString(qualifier)); recover(); } @@ -1213,53 +1411,124 @@ TPublicType TParseContext::addFullySpecifiedType(TQualifier qualifier, TLayoutQu } else { - switch (qualifier) + if (!layoutQualifier.isEmpty()) { - case EvqSmoothIn: - case EvqSmoothOut: - case EvqVertexOut: - case EvqFragmentIn: - case EvqCentroidOut: - case EvqCentroidIn: - if (typeSpecifier.type == EbtBool) + if (globalErrorCheck(typeSpecifier.line, symbolTable.atGlobalLevel(), "layout")) { - error(typeSpecifier.line, "cannot be bool", getQualifierString(qualifier)); recover(); } - if (typeSpecifier.type == EbtInt || typeSpecifier.type == EbtUInt) + } + if (sh::IsVarying(qualifier) || qualifier == EvqVertexIn || qualifier == EvqFragmentOut) + { + es3InputOutputTypeCheck(qualifier, typeSpecifier, typeSpecifier.line); + } + } + + return returnType; +} + +void TParseContext::es3InputOutputTypeCheck(const TQualifier qualifier, + const TPublicType &type, + const TSourceLoc &qualifierLocation) +{ + // An input/output variable can never be bool or a sampler. Samplers are checked elsewhere. + if (type.type == EbtBool) + { + error(qualifierLocation, "cannot be bool", getQualifierString(qualifier)); + recover(); + } + + // Specific restrictions apply for vertex shader inputs and fragment shader outputs. + switch (qualifier) + { + case EvqVertexIn: + // ESSL 3.00 section 4.3.4 + if (type.array) { - error(typeSpecifier.line, "must use 'flat' interpolation here", getQualifierString(qualifier)); + error(qualifierLocation, "cannot be array", getQualifierString(qualifier)); recover(); } - break; - - case EvqVertexIn: - case EvqFragmentOut: - case EvqFlatIn: - case EvqFlatOut: - if (typeSpecifier.type == EbtBool) + // Vertex inputs with a struct type are disallowed in singleDeclarationErrorCheck + return; + case EvqFragmentOut: + // ESSL 3.00 section 4.3.6 + if (type.isMatrix()) { - error(typeSpecifier.line, "cannot be bool", getQualifierString(qualifier)); + error(qualifierLocation, "cannot be matrix", getQualifierString(qualifier)); recover(); } + // Fragment outputs with a struct type are disallowed in singleDeclarationErrorCheck + return; + default: break; + } - default: break; - } + // Vertex shader outputs / fragment shader inputs have a different, slightly more lenient set of + // restrictions. + bool typeContainsIntegers = + (type.type == EbtInt || type.type == EbtUInt || type.isStructureContainingType(EbtInt) || + type.isStructureContainingType(EbtUInt)); + if (typeContainsIntegers && qualifier != EvqFlatIn && qualifier != EvqFlatOut) + { + error(qualifierLocation, "must use 'flat' interpolation here", + getQualifierString(qualifier)); + recover(); } - return returnType; + if (type.type == EbtStruct) + { + // ESSL 3.00 sections 4.3.4 and 4.3.6. + // These restrictions are only implied by the ESSL 3.00 spec, but + // the ESSL 3.10 spec lists these restrictions explicitly. + if (type.array) + { + error(qualifierLocation, "cannot be an array of structures", + getQualifierString(qualifier)); + recover(); + } + if (type.isStructureContainingArrays()) + { + error(qualifierLocation, "cannot be a structure containing an array", + getQualifierString(qualifier)); + recover(); + } + if (type.isStructureContainingType(EbtStruct)) + { + error(qualifierLocation, "cannot be a structure containing a structure", + getQualifierString(qualifier)); + recover(); + } + if (type.isStructureContainingType(EbtBool)) + { + error(qualifierLocation, "cannot be a structure containing a bool", + getQualifierString(qualifier)); + recover(); + } + } } TIntermAggregate *TParseContext::parseSingleDeclaration(TPublicType &publicType, const TSourceLoc &identifierOrTypeLocation, const TString &identifier) { - TIntermSymbol *symbol = intermediate.addSymbol(0, identifier, TType(publicType), identifierOrTypeLocation); + TIntermSymbol *symbol = + intermediate.addSymbol(0, identifier, TType(publicType), identifierOrTypeLocation); - mDeferredSingleDeclarationErrorCheck = (identifier == ""); + bool emptyDeclaration = (identifier == ""); - if (!mDeferredSingleDeclarationErrorCheck) + mDeferredSingleDeclarationErrorCheck = emptyDeclaration; + + if (emptyDeclaration) + { + if (publicType.isUnsizedArray()) + { + // ESSL3 spec section 4.1.9: Array declaration which leaves the size unspecified is an + // error. It is assumed that this applies to empty declarations as well. + error(identifierOrTypeLocation, "empty array declaration needs to specify a size", + identifier.c_str()); + } + } + else { if (singleDeclarationErrorCheck(publicType, identifierOrTypeLocation)) recover(); @@ -1292,7 +1561,8 @@ TIntermAggregate *TParseContext::parseSingleArrayDeclaration(TPublicType &public if (nonInitErrorCheck(identifierLocation, identifier, &publicType)) recover(); - if (arrayTypeErrorCheck(indexLocation, publicType) || arrayQualifierErrorCheck(indexLocation, publicType)) + if (arrayTypeErrorCheck(indexLocation, publicType) || + arrayQualifierErrorCheck(indexLocation, publicType)) { recover(); } @@ -1319,7 +1589,7 @@ TIntermAggregate *TParseContext::parseSingleArrayDeclaration(TPublicType &public return intermediate.makeAggregate(symbol, identifierLocation); } -TIntermAggregate *TParseContext::parseSingleInitDeclaration(TPublicType &publicType, +TIntermAggregate *TParseContext::parseSingleInitDeclaration(const TPublicType &publicType, const TSourceLoc &identifierLocation, const TString &identifier, const TSourceLoc &initLocation, @@ -1345,20 +1615,22 @@ TIntermAggregate *TParseContext::parseSingleInitDeclaration(TPublicType &publicT } } -TIntermAggregate *TParseContext::parseSingleArrayInitDeclaration(TPublicType &publicType, - const TSourceLoc &identifierLocation, - const TString &identifier, - const TSourceLoc &indexLocation, - TIntermTyped *indexExpression, - const TSourceLoc &initLocation, - TIntermTyped *initializer) +TIntermAggregate *TParseContext::parseSingleArrayInitDeclaration( + TPublicType &publicType, + const TSourceLoc &identifierLocation, + const TString &identifier, + const TSourceLoc &indexLocation, + TIntermTyped *indexExpression, + const TSourceLoc &initLocation, + TIntermTyped *initializer) { mDeferredSingleDeclarationErrorCheck = false; if (singleDeclarationErrorCheck(publicType, identifierLocation)) recover(); - if (arrayTypeErrorCheck(indexLocation, publicType) || arrayQualifierErrorCheck(indexLocation, publicType)) + if (arrayTypeErrorCheck(indexLocation, publicType) || + arrayQualifierErrorCheck(indexLocation, publicType)) { recover(); } @@ -1366,8 +1638,10 @@ TIntermAggregate *TParseContext::parseSingleArrayInitDeclaration(TPublicType &pu TPublicType arrayType(publicType); int size = 0; - // If indexExpression is nullptr, then the array will eventually get its size implicitly from the initializer. - if (indexExpression != nullptr && arraySizeErrorCheck(identifierLocation, indexExpression, size)) + // If indexExpression is nullptr, then the array will eventually get its size implicitly from + // the initializer. + if (indexExpression != nullptr && + arraySizeErrorCheck(identifierLocation, indexExpression, size)) { recover(); } @@ -1410,7 +1684,8 @@ TIntermAggregate *TParseContext::parseInvariantDeclaration(const TSourceLoc &inv const TString kGlFrontFacing("gl_FrontFacing"); if (*identifier == kGlFrontFacing) { - error(identifierLoc, "identifier should not be declared as invariant", identifier->c_str()); + error(identifierLoc, "identifier should not be declared as invariant", + identifier->c_str()); recover(); return nullptr; } @@ -1418,8 +1693,8 @@ TIntermAggregate *TParseContext::parseInvariantDeclaration(const TSourceLoc &inv const TVariable *variable = getNamedVariable(identifierLoc, identifier, symbol); ASSERT(variable); const TType &type = variable->getType(); - TIntermSymbol *intermSymbol = intermediate.addSymbol(variable->getUniqueId(), - *identifier, type, identifierLoc); + TIntermSymbol *intermSymbol = + intermediate.addSymbol(variable->getUniqueId(), *identifier, type, identifierLoc); TIntermAggregate *aggregate = intermediate.makeAggregate(intermSymbol, identifierLoc); aggregate->setOp(EOpInvariantDeclaration); @@ -1427,10 +1702,13 @@ TIntermAggregate *TParseContext::parseInvariantDeclaration(const TSourceLoc &inv } } -TIntermAggregate *TParseContext::parseDeclarator(TPublicType &publicType, TIntermAggregate *aggregateDeclaration, - const TSourceLoc &identifierLocation, const TString &identifier) +TIntermAggregate *TParseContext::parseDeclarator(TPublicType &publicType, + TIntermAggregate *aggregateDeclaration, + const TSourceLoc &identifierLocation, + const TString &identifier) { - // If the declaration starting this declarator list was empty (example: int,), some checks were not performed. + // If the declaration starting this declarator list was empty (example: int,), some checks were + // not performed. if (mDeferredSingleDeclarationErrorCheck) { if (singleDeclarationErrorCheck(publicType, identifierLocation)) @@ -1448,18 +1726,23 @@ TIntermAggregate *TParseContext::parseDeclarator(TPublicType &publicType, TInter if (!declareVariable(identifierLocation, identifier, TType(publicType), &variable)) recover(); - TIntermSymbol *symbol = intermediate.addSymbol(0, identifier, TType(publicType), identifierLocation); + TIntermSymbol *symbol = + intermediate.addSymbol(0, identifier, TType(publicType), identifierLocation); if (variable && symbol) symbol->setId(variable->getUniqueId()); return intermediate.growAggregate(aggregateDeclaration, symbol, identifierLocation); } -TIntermAggregate *TParseContext::parseArrayDeclarator(TPublicType &publicType, TIntermAggregate *aggregateDeclaration, - const TSourceLoc &identifierLocation, const TString &identifier, - const TSourceLoc &arrayLocation, TIntermTyped *indexExpression) +TIntermAggregate *TParseContext::parseArrayDeclarator(TPublicType &publicType, + TIntermAggregate *aggregateDeclaration, + const TSourceLoc &identifierLocation, + const TString &identifier, + const TSourceLoc &arrayLocation, + TIntermTyped *indexExpression) { - // If the declaration starting this declarator list was empty (example: int,), some checks were not performed. + // If the declaration starting this declarator list was empty (example: int,), some checks were + // not performed. if (mDeferredSingleDeclarationErrorCheck) { if (singleDeclarationErrorCheck(publicType, identifierLocation)) @@ -1473,7 +1756,8 @@ TIntermAggregate *TParseContext::parseArrayDeclarator(TPublicType &publicType, T if (nonInitErrorCheck(identifierLocation, identifier, &publicType)) recover(); - if (arrayTypeErrorCheck(arrayLocation, publicType) || arrayQualifierErrorCheck(arrayLocation, publicType)) + if (arrayTypeErrorCheck(arrayLocation, publicType) || + arrayQualifierErrorCheck(arrayLocation, publicType)) { recover(); } @@ -1491,7 +1775,8 @@ TIntermAggregate *TParseContext::parseArrayDeclarator(TPublicType &publicType, T if (!declareVariable(identifierLocation, identifier, arrayType, &variable)) recover(); - TIntermSymbol *symbol = intermediate.addSymbol(0, identifier, arrayType, identifierLocation); + TIntermSymbol *symbol = + intermediate.addSymbol(0, identifier, arrayType, identifierLocation); if (variable && symbol) symbol->setId(variable->getUniqueId()); @@ -1501,11 +1786,15 @@ TIntermAggregate *TParseContext::parseArrayDeclarator(TPublicType &publicType, T return nullptr; } -TIntermAggregate *TParseContext::parseInitDeclarator(TPublicType &publicType, TIntermAggregate *aggregateDeclaration, - const TSourceLoc &identifierLocation, const TString &identifier, - const TSourceLoc &initLocation, TIntermTyped *initializer) +TIntermAggregate *TParseContext::parseInitDeclarator(const TPublicType &publicType, + TIntermAggregate *aggregateDeclaration, + const TSourceLoc &identifierLocation, + const TString &identifier, + const TSourceLoc &initLocation, + TIntermTyped *initializer) { - // If the declaration starting this declarator list was empty (example: int,), some checks were not performed. + // If the declaration starting this declarator list was empty (example: int,), some checks were + // not performed. if (mDeferredSingleDeclarationErrorCheck) { if (singleDeclarationErrorCheck(publicType, identifierLocation)) @@ -1538,15 +1827,17 @@ TIntermAggregate *TParseContext::parseInitDeclarator(TPublicType &publicType, TI } } -TIntermAggregate *TParseContext::parseArrayInitDeclarator(TPublicType &publicType, +TIntermAggregate *TParseContext::parseArrayInitDeclarator(const TPublicType &publicType, TIntermAggregate *aggregateDeclaration, - const TSourceLoc& identifierLocation, + const TSourceLoc &identifierLocation, const TString &identifier, - const TSourceLoc& indexLocation, + const TSourceLoc &indexLocation, TIntermTyped *indexExpression, - const TSourceLoc &initLocation, TIntermTyped *initializer) + const TSourceLoc &initLocation, + TIntermTyped *initializer) { - // If the declaration starting this declarator list was empty (example: int,), some checks were not performed. + // If the declaration starting this declarator list was empty (example: int,), some checks were + // not performed. if (mDeferredSingleDeclarationErrorCheck) { if (singleDeclarationErrorCheck(publicType, identifierLocation)) @@ -1557,7 +1848,8 @@ TIntermAggregate *TParseContext::parseArrayInitDeclarator(TPublicType &publicTyp if (locationDeclaratorListCheck(identifierLocation, publicType)) recover(); - if (arrayTypeErrorCheck(indexLocation, publicType) || arrayQualifierErrorCheck(indexLocation, publicType)) + if (arrayTypeErrorCheck(indexLocation, publicType) || + arrayQualifierErrorCheck(indexLocation, publicType)) { recover(); } @@ -1565,8 +1857,10 @@ TIntermAggregate *TParseContext::parseArrayInitDeclarator(TPublicType &publicTyp TPublicType arrayType(publicType); int size = 0; - // If indexExpression is nullptr, then the array will eventually get its size implicitly from the initializer. - if (indexExpression != nullptr && arraySizeErrorCheck(identifierLocation, indexExpression, size)) + // If indexExpression is nullptr, then the array will eventually get its size implicitly from + // the initializer. + if (indexExpression != nullptr && + arraySizeErrorCheck(identifierLocation, indexExpression, size)) { recover(); } @@ -1598,7 +1892,8 @@ void TParseContext::parseGlobalLayoutQualifier(const TPublicType &typeQualifier) { if (typeQualifier.qualifier != EvqUniform) { - error(typeQualifier.line, "invalid qualifier:", getQualifierString(typeQualifier.qualifier), "global layout must be uniform"); + error(typeQualifier.line, "invalid qualifier:", getQualifierString(typeQualifier.qualifier), + "global layout must be uniform"); recover(); return; } @@ -1606,7 +1901,7 @@ void TParseContext::parseGlobalLayoutQualifier(const TPublicType &typeQualifier) const TLayoutQualifier layoutQualifier = typeQualifier.layoutQualifier; ASSERT(!layoutQualifier.isEmpty()); - if (shaderVersion < 300) + if (mShaderVersion < 300) { error(typeQualifier.line, "layout qualifiers supported in GLSL ES 3.00 only", "layout"); recover(); @@ -1621,17 +1916,278 @@ void TParseContext::parseGlobalLayoutQualifier(const TPublicType &typeQualifier) if (layoutQualifier.matrixPacking != EmpUnspecified) { - defaultMatrixPacking = layoutQualifier.matrixPacking; + mDefaultMatrixPacking = layoutQualifier.matrixPacking; } if (layoutQualifier.blockStorage != EbsUnspecified) { - defaultBlockStorage = layoutQualifier.blockStorage; + mDefaultBlockStorage = layoutQualifier.blockStorage; } } -TFunction *TParseContext::addConstructorFunc(TPublicType publicType) +TIntermAggregate *TParseContext::addFunctionPrototypeDeclaration(const TFunction &function, + const TSourceLoc &location) { + // Note: symbolTableFunction could be the same as function if this is the first declaration. + // Either way the instance in the symbol table is used to track whether the function is declared + // multiple times. + TFunction *symbolTableFunction = + static_cast(symbolTable.find(function.getMangledName(), getShaderVersion())); + if (symbolTableFunction->hasPrototypeDeclaration() && mShaderVersion == 100) + { + // ESSL 1.00.17 section 4.2.7. + // Doesn't apply to ESSL 3.00.4: see section 4.2.3. + error(location, "duplicate function prototype declarations are not allowed", "function"); + recover(); + } + symbolTableFunction->setHasPrototypeDeclaration(); + + TIntermAggregate *prototype = new TIntermAggregate; + prototype->setType(function.getReturnType()); + prototype->setName(function.getMangledName()); + prototype->setFunctionId(function.getUniqueId()); + + for (size_t i = 0; i < function.getParamCount(); i++) + { + const TConstParameter ¶m = function.getParam(i); + if (param.name != 0) + { + TVariable variable(param.name, *param.type); + + TIntermSymbol *paramSymbol = intermediate.addSymbol( + variable.getUniqueId(), variable.getName(), variable.getType(), location); + prototype = intermediate.growAggregate(prototype, paramSymbol, location); + } + else + { + TIntermSymbol *paramSymbol = intermediate.addSymbol(0, "", *param.type, location); + prototype = intermediate.growAggregate(prototype, paramSymbol, location); + } + } + + prototype->setOp(EOpPrototype); + + symbolTable.pop(); + + if (!symbolTable.atGlobalLevel()) + { + // ESSL 3.00.4 section 4.2.4. + error(location, "local function prototype declarations are not allowed", "function"); + recover(); + } + + return prototype; +} + +TIntermAggregate *TParseContext::addFunctionDefinition(const TFunction &function, + TIntermAggregate *functionPrototype, + TIntermAggregate *functionBody, + const TSourceLoc &location) +{ + //?? Check that all paths return a value if return type != void ? + // May be best done as post process phase on intermediate code + if (mCurrentFunctionType->getBasicType() != EbtVoid && !mFunctionReturnsValue) + { + error(location, "function does not return a value:", "", function.getName().c_str()); + recover(); + } + + TIntermAggregate *aggregate = + intermediate.growAggregate(functionPrototype, functionBody, location); + intermediate.setAggregateOperator(aggregate, EOpFunction, location); + aggregate->setName(function.getMangledName().c_str()); + aggregate->setType(function.getReturnType()); + aggregate->setFunctionId(function.getUniqueId()); + + symbolTable.pop(); + return aggregate; +} + +void TParseContext::parseFunctionPrototype(const TSourceLoc &location, + TFunction *function, + TIntermAggregate **aggregateOut) +{ + const TSymbol *builtIn = + symbolTable.findBuiltIn(function->getMangledName(), getShaderVersion()); + + if (builtIn) + { + error(location, "built-in functions cannot be redefined", function->getName().c_str()); + recover(); + } + + TFunction *prevDec = + static_cast(symbolTable.find(function->getMangledName(), getShaderVersion())); + // + // Note: 'prevDec' could be 'function' if this is the first time we've seen function + // as it would have just been put in the symbol table. Otherwise, we're looking up + // an earlier occurance. + // + if (prevDec->isDefined()) + { + // Then this function already has a body. + error(location, "function already has a body", function->getName().c_str()); + recover(); + } + prevDec->setDefined(); + // + // Overload the unique ID of the definition to be the same unique ID as the declaration. + // Eventually we will probably want to have only a single definition and just swap the + // arguments to be the definition's arguments. + // + function->setUniqueId(prevDec->getUniqueId()); + + // Raise error message if main function takes any parameters or return anything other than void + if (function->getName() == "main") + { + if (function->getParamCount() > 0) + { + error(location, "function cannot take any parameter(s)", function->getName().c_str()); + recover(); + } + if (function->getReturnType().getBasicType() != EbtVoid) + { + error(location, "", function->getReturnType().getBasicString(), + "main function cannot return a value"); + recover(); + } + } + + // + // Remember the return type for later checking for RETURN statements. + // + mCurrentFunctionType = &(prevDec->getReturnType()); + mFunctionReturnsValue = false; + + // + // Insert parameters into the symbol table. + // If the parameter has no name, it's not an error, just don't insert it + // (could be used for unused args). + // + // Also, accumulate the list of parameters into the HIL, so lower level code + // knows where to find parameters. + // + TIntermAggregate *paramNodes = new TIntermAggregate; + for (size_t i = 0; i < function->getParamCount(); i++) + { + const TConstParameter ¶m = function->getParam(i); + if (param.name != 0) + { + TVariable *variable = new TVariable(param.name, *param.type); + // + // Insert the parameters with name in the symbol table. + // + if (!symbolTable.declare(variable)) + { + error(location, "redefinition", variable->getName().c_str()); + recover(); + paramNodes = intermediate.growAggregate( + paramNodes, intermediate.addSymbol(0, "", *param.type, location), location); + continue; + } + + // + // Add the parameter to the HIL + // + TIntermSymbol *symbol = intermediate.addSymbol( + variable->getUniqueId(), variable->getName(), variable->getType(), location); + + paramNodes = intermediate.growAggregate(paramNodes, symbol, location); + } + else + { + paramNodes = intermediate.growAggregate( + paramNodes, intermediate.addSymbol(0, "", *param.type, location), location); + } + } + intermediate.setAggregateOperator(paramNodes, EOpParameters, location); + *aggregateOut = paramNodes; + setLoopNestingLevel(0); +} + +TFunction *TParseContext::parseFunctionDeclarator(const TSourceLoc &location, TFunction *function) +{ + // + // We don't know at this point whether this is a function definition or a prototype. + // The definition production code will check for redefinitions. + // In the case of ESSL 1.00 the prototype production code will also check for redeclarations. + // + // Return types and parameter qualifiers must match in all redeclarations, so those are checked + // here. + // + TFunction *prevDec = + static_cast(symbolTable.find(function->getMangledName(), getShaderVersion())); + + if (getShaderVersion() >= 300 && symbolTable.hasUnmangledBuiltIn(function->getName().c_str())) + { + // With ESSL 3.00, names of built-in functions cannot be redeclared as functions. + // Therefore overloading or redefining builtin functions is an error. + error(location, "Name of a built-in function cannot be redeclared as function", + function->getName().c_str()); + recover(); + } + else if (prevDec) + { + if (prevDec->getReturnType() != function->getReturnType()) + { + error(location, "overloaded functions must have the same return type", + function->getReturnType().getBasicString()); + recover(); + } + for (size_t i = 0; i < prevDec->getParamCount(); ++i) + { + if (prevDec->getParam(i).type->getQualifier() != + function->getParam(i).type->getQualifier()) + { + error(location, "overloaded functions must have the same parameter qualifiers", + function->getParam(i).type->getQualifierString()); + recover(); + } + } + } + + // + // Check for previously declared variables using the same name. + // + TSymbol *prevSym = symbolTable.find(function->getName(), getShaderVersion()); + if (prevSym) + { + if (!prevSym->isFunction()) + { + error(location, "redefinition", function->getName().c_str(), "function"); + recover(); + } + } + else + { + // Insert the unmangled name to detect potential future redefinition as a variable. + TFunction *newFunction = + new TFunction(NewPoolTString(function->getName().c_str()), &function->getReturnType()); + symbolTable.getOuterLevel()->insertUnmangled(newFunction); + } + + // We're at the inner scope level of the function's arguments and body statement. + // Add the function prototype to the surrounding scope instead. + symbolTable.getOuterLevel()->insert(function); + + // + // If this is a redeclaration, it could also be a definition, in which case, we want to use the + // variable names from this one, and not the one that's + // being redeclared. So, pass back up this declaration, not the one in the symbol table. + // + return function; +} + +TFunction *TParseContext::addConstructorFunc(const TPublicType &publicTypeIn) +{ + TPublicType publicType = publicTypeIn; + if (publicType.isStructSpecifier) + { + error(publicType.line, "constructor can't be a structure definition", + getBasicString(publicType.type)); + recover(); + } + TOperator op = EOpNull; if (publicType.userDef) { @@ -1641,60 +2197,131 @@ TFunction *TParseContext::addConstructorFunc(TPublicType publicType) { switch (publicType.type) { - case EbtFloat: - if (publicType.isMatrix()) - { - // TODO: non-square matrices - switch(publicType.getCols()) + case EbtFloat: + if (publicType.isMatrix()) { - case 2: op = EOpConstructMat2; break; - case 3: op = EOpConstructMat3; break; - case 4: op = EOpConstructMat4; break; + switch (publicType.getCols()) + { + case 2: + switch (publicType.getRows()) + { + case 2: + op = EOpConstructMat2; + break; + case 3: + op = EOpConstructMat2x3; + break; + case 4: + op = EOpConstructMat2x4; + break; + } + break; + case 3: + switch (publicType.getRows()) + { + case 2: + op = EOpConstructMat3x2; + break; + case 3: + op = EOpConstructMat3; + break; + case 4: + op = EOpConstructMat3x4; + break; + } + break; + case 4: + switch (publicType.getRows()) + { + case 2: + op = EOpConstructMat4x2; + break; + case 3: + op = EOpConstructMat4x3; + break; + case 4: + op = EOpConstructMat4; + break; + } + break; + } } - } - else - { - switch(publicType.getNominalSize()) + else { - case 1: op = EOpConstructFloat; break; - case 2: op = EOpConstructVec2; break; - case 3: op = EOpConstructVec3; break; - case 4: op = EOpConstructVec4; break; + switch (publicType.getNominalSize()) + { + case 1: + op = EOpConstructFloat; + break; + case 2: + op = EOpConstructVec2; + break; + case 3: + op = EOpConstructVec3; + break; + case 4: + op = EOpConstructVec4; + break; + } } - } - break; + break; - case EbtInt: - switch(publicType.getNominalSize()) - { - case 1: op = EOpConstructInt; break; - case 2: op = EOpConstructIVec2; break; - case 3: op = EOpConstructIVec3; break; - case 4: op = EOpConstructIVec4; break; - } - break; + case EbtInt: + switch (publicType.getNominalSize()) + { + case 1: + op = EOpConstructInt; + break; + case 2: + op = EOpConstructIVec2; + break; + case 3: + op = EOpConstructIVec3; + break; + case 4: + op = EOpConstructIVec4; + break; + } + break; - case EbtUInt: - switch(publicType.getNominalSize()) - { - case 1: op = EOpConstructUInt; break; - case 2: op = EOpConstructUVec2; break; - case 3: op = EOpConstructUVec3; break; - case 4: op = EOpConstructUVec4; break; - } - break; + case EbtUInt: + switch (publicType.getNominalSize()) + { + case 1: + op = EOpConstructUInt; + break; + case 2: + op = EOpConstructUVec2; + break; + case 3: + op = EOpConstructUVec3; + break; + case 4: + op = EOpConstructUVec4; + break; + } + break; - case EbtBool: - switch(publicType.getNominalSize()) - { - case 1: op = EOpConstructBool; break; - case 2: op = EOpConstructBVec2; break; - case 3: op = EOpConstructBVec3; break; - case 4: op = EOpConstructBVec4; break; - } - break; + case EbtBool: + switch (publicType.getNominalSize()) + { + case 1: + op = EOpConstructBool; + break; + case 2: + op = EOpConstructBVec2; + break; + case 3: + op = EOpConstructBVec3; + break; + case 4: + op = EOpConstructBVec4; + break; + } + break; - default: break; + default: + break; } if (op == EOpNull) @@ -1702,34 +2329,34 @@ TFunction *TParseContext::addConstructorFunc(TPublicType publicType) error(publicType.line, "cannot construct this type", getBasicString(publicType.type)); recover(); publicType.type = EbtFloat; - op = EOpConstructFloat; + op = EOpConstructFloat; } } TString tempString; - TType type(publicType); + const TType *type = new TType(publicType); return new TFunction(&tempString, type, op); } -// This function is used to test for the correctness of the parameters passed to various constructor functions -// and also convert them to the right datatype if it is allowed and required. +// This function is used to test for the correctness of the parameters passed to various constructor +// functions and also convert them to the right datatype if it is allowed and required. // // Returns 0 for an error or the constructed node (aggregate or typed) for no error. // -TIntermTyped *TParseContext::addConstructor(TIntermNode *arguments, TType *type, TOperator op, TFunction *fnCall, const TSourceLoc &line) +TIntermTyped *TParseContext::addConstructor(TIntermNode *arguments, + TType *type, + TOperator op, + TFunction *fnCall, + const TSourceLoc &line) { - TIntermAggregate *aggregateArguments = arguments->getAsAggregate(); - - if (!aggregateArguments) - { - aggregateArguments = new TIntermAggregate; - aggregateArguments->getSequence()->push_back(arguments); - } + TIntermAggregate *constructor = arguments->getAsAggregate(); + ASSERT(constructor != nullptr); if (type->isArray()) { - // GLSL ES 3.00 section 5.4.4: Each argument must be the same type as the element type of the array. - TIntermSequence *args = aggregateArguments->getSequence(); + // GLSL ES 3.00 section 5.4.4: Each argument must be the same type as the element type of + // the array. + TIntermSequence *args = constructor->getSequence(); for (size_t i = 0; i < args->size(); i++) { const TType &argType = (*args)[i]->getAsTyped()->getType(); @@ -1746,13 +2373,14 @@ TIntermTyped *TParseContext::addConstructor(TIntermNode *arguments, TType *type, else if (op == EOpConstructStruct) { const TFieldList &fields = type->getStruct()->fields(); - TIntermSequence *args = aggregateArguments->getSequence(); + TIntermSequence *args = constructor->getSequence(); for (size_t i = 0; i < fields.size(); i++) { if (i >= args->size() || (*args)[i]->getAsTyped()->getType() != *fields[i]->type()) { - error(line, "Structure constructor arguments do not match structure fields", "Error"); + error(line, "Structure constructor arguments do not match structure fields", + "Error"); recover(); return 0; @@ -1761,12 +2389,12 @@ TIntermTyped *TParseContext::addConstructor(TIntermNode *arguments, TType *type, } // Turn the argument list itself into a constructor - TIntermAggregate *constructor = intermediate.setAggregateOperator(aggregateArguments, op, line); - TIntermTyped *constConstructor = foldConstConstructor(constructor, *type); - if (constConstructor) - { - return constConstructor; - } + constructor->setOp(op); + constructor->setLine(line); + ASSERT(constructor->isConstructor()); + + // Need to set type before setPrecisionFromChildren() because bool doesn't have precision. + constructor->setType(*type); // Structs should not be precision qualified, the individual members may be. // Built-in types on the other hand should be precision qualified. @@ -1776,174 +2404,142 @@ TIntermTyped *TParseContext::addConstructor(TIntermNode *arguments, TType *type, type->setPrecision(constructor->getPrecision()); } - return constructor; -} - -TIntermTyped* TParseContext::foldConstConstructor(TIntermAggregate* aggrNode, const TType& type) -{ - // TODO: Add support for folding array constructors - bool canBeFolded = areAllChildConst(aggrNode) && !type.isArray(); - aggrNode->setType(type); - if (canBeFolded) { - bool returnVal = false; - TConstantUnion* unionArray = new TConstantUnion[type.getObjectSize()]; - if (aggrNode->getSequence()->size() == 1) { - returnVal = intermediate.parseConstTree(aggrNode->getLine(), aggrNode, unionArray, aggrNode->getOp(), type, true); - } - else { - returnVal = intermediate.parseConstTree(aggrNode->getLine(), aggrNode, unionArray, aggrNode->getOp(), type); - } - if (returnVal) - return 0; - - return intermediate.addConstantUnion(unionArray, type, aggrNode->getLine()); + TIntermTyped *constConstructor = intermediate.foldAggregateBuiltIn(constructor); + if (constConstructor) + { + return constConstructor; } - return 0; + return constructor; } // -// This function returns the tree representation for the vector field(s) being accessed from contant vector. -// If only one component of vector is accessed (v.x or v[0] where v is a contant vector), then a contant node is -// returned, else an aggregate node is returned (for v.xy). The input to this function could either be the symbol -// node or it could be the intermediate tree representation of accessing fields in a constant structure or column of -// a constant matrix. +// This function returns the tree representation for the vector field(s) being accessed from contant +// vector. +// If only one component of vector is accessed (v.x or v[0] where v is a contant vector), then a +// contant node is returned, else an aggregate node is returned (for v.xy). The input to this +// function could either be the symbol node or it could be the intermediate tree representation of +// accessing fields in a constant structure or column of a constant matrix. // -TIntermTyped* TParseContext::addConstVectorNode(TVectorFields& fields, TIntermTyped* node, const TSourceLoc& line) +TIntermTyped *TParseContext::addConstVectorNode(TVectorFields &fields, + TIntermConstantUnion *node, + const TSourceLoc &line, + bool outOfRangeIndexIsError) { - TIntermTyped* typedNode; - TIntermConstantUnion* tempConstantNode = node->getAsConstantUnion(); - - const TConstantUnion *unionArray; - if (tempConstantNode) { - unionArray = tempConstantNode->getUnionArrayPointer(); + const TConstantUnion *unionArray = node->getUnionArrayPointer(); + ASSERT(unionArray); - if (!unionArray) { - return node; - } - } else { // The node has to be either a symbol node or an aggregate node or a tempConstant node, else, its an error - error(line, "Cannot offset into the vector", "Error"); - recover(); + TConstantUnion *constArray = new TConstantUnion[fields.num]; - return 0; - } - - TConstantUnion* constArray = new TConstantUnion[fields.num]; - - for (int i = 0; i < fields.num; i++) { - if (fields.offsets[i] >= node->getType().getNominalSize()) { + for (int i = 0; i < fields.num; i++) + { + if (fields.offsets[i] >= node->getType().getNominalSize()) + { std::stringstream extraInfoStream; extraInfoStream << "vector field selection out of range '" << fields.offsets[i] << "'"; std::string extraInfo = extraInfoStream.str(); - error(line, "", "[", extraInfo.c_str()); - recover(); - fields.offsets[i] = 0; + outOfRangeError(outOfRangeIndexIsError, line, "", "[", extraInfo.c_str()); + fields.offsets[i] = node->getType().getNominalSize() - 1; } - - constArray[i] = unionArray[fields.offsets[i]]; - } - typedNode = intermediate.addConstantUnion(constArray, node->getType(), line); - return typedNode; + constArray[i] = unionArray[fields.offsets[i]]; + } + return intermediate.addConstantUnion(constArray, node->getType(), line); } // -// This function returns the column being accessed from a constant matrix. The values are retrieved from -// the symbol table and parse-tree is built for a vector (each column of a matrix is a vector). The input -// to the function could either be a symbol node (m[0] where m is a constant matrix)that represents a -// constant matrix or it could be the tree representation of the constant matrix (s.m1[0] where s is a constant structure) +// This function returns the column being accessed from a constant matrix. The values are retrieved +// from the symbol table and parse-tree is built for a vector (each column of a matrix is a vector). +// The input to the function could either be a symbol node (m[0] where m is a constant matrix)that +// represents a constant matrix or it could be the tree representation of the constant matrix +// (s.m1[0] where s is a constant structure) // -TIntermTyped* TParseContext::addConstMatrixNode(int index, TIntermTyped* node, const TSourceLoc& line) +TIntermTyped *TParseContext::addConstMatrixNode(int index, + TIntermConstantUnion *node, + const TSourceLoc &line, + bool outOfRangeIndexIsError) { - TIntermTyped* typedNode; - TIntermConstantUnion* tempConstantNode = node->getAsConstantUnion(); - - if (index >= node->getType().getCols()) { + if (index >= node->getType().getCols()) + { std::stringstream extraInfoStream; extraInfoStream << "matrix field selection out of range '" << index << "'"; std::string extraInfo = extraInfoStream.str(); - error(line, "", "[", extraInfo.c_str()); - recover(); - index = 0; - } - - if (tempConstantNode) { - TConstantUnion *unionArray = tempConstantNode->getUnionArrayPointer(); - int size = tempConstantNode->getType().getCols(); - typedNode = intermediate.addConstantUnion(&unionArray[size*index], tempConstantNode->getType(), line); - } else { - error(line, "Cannot offset into the matrix", "Error"); - recover(); - - return 0; + outOfRangeError(outOfRangeIndexIsError, line, "", "[", extraInfo.c_str()); + index = node->getType().getCols() - 1; } - return typedNode; + const TConstantUnion *unionArray = node->getUnionArrayPointer(); + int size = node->getType().getCols(); + return intermediate.addConstantUnion(&unionArray[size * index], node->getType(), line); } - // -// This function returns an element of an array accessed from a constant array. The values are retrieved from -// the symbol table and parse-tree is built for the type of the element. The input -// to the function could either be a symbol node (a[0] where a is a constant array)that represents a -// constant array or it could be the tree representation of the constant array (s.a1[0] where s is a constant structure) +// This function returns an element of an array accessed from a constant array. The values are +// retrieved from the symbol table and parse-tree is built for the type of the element. The input +// to the function could either be a symbol node (a[0] where a is a constant array)that represents a +// constant array or it could be the tree representation of the constant array (s.a1[0] where s is a +// constant structure) // -TIntermTyped* TParseContext::addConstArrayNode(int index, TIntermTyped* node, const TSourceLoc& line) +TIntermTyped *TParseContext::addConstArrayNode(int index, + TIntermConstantUnion *node, + const TSourceLoc &line, + bool outOfRangeIndexIsError) { - TIntermTyped* typedNode; - TIntermConstantUnion* tempConstantNode = node->getAsConstantUnion(); TType arrayElementType = node->getType(); arrayElementType.clearArrayness(); - if (index >= node->getType().getArraySize()) { + if (index >= node->getType().getArraySize()) + { std::stringstream extraInfoStream; extraInfoStream << "array field selection out of range '" << index << "'"; std::string extraInfo = extraInfoStream.str(); - error(line, "", "[", extraInfo.c_str()); - recover(); - index = 0; + outOfRangeError(outOfRangeIndexIsError, line, "", "[", extraInfo.c_str()); + index = node->getType().getArraySize() - 1; } - - if (tempConstantNode) { - size_t arrayElementSize = arrayElementType.getObjectSize(); - TConstantUnion* unionArray = tempConstantNode->getUnionArrayPointer(); - typedNode = intermediate.addConstantUnion(&unionArray[arrayElementSize * index], tempConstantNode->getType(), line); - } else { - error(line, "Cannot offset into the array", "Error"); - recover(); - - return 0; - } - - return typedNode; + size_t arrayElementSize = arrayElementType.getObjectSize(); + const TConstantUnion *unionArray = node->getUnionArrayPointer(); + return intermediate.addConstantUnion(&unionArray[arrayElementSize * index], node->getType(), + line); } - // -// This function returns the value of a particular field inside a constant structure from the symbol table. -// If there is an embedded/nested struct, it appropriately calls addConstStructNested or addConstStructFromAggr -// function and returns the parse-tree with the values of the embedded/nested struct. +// This function returns the value of a particular field inside a constant structure from the symbol +// table. +// If there is an embedded/nested struct, it appropriately calls addConstStructNested or +// addConstStructFromAggr function and returns the parse-tree with the values of the embedded/nested +// struct. // -TIntermTyped* TParseContext::addConstStruct(const TString &identifier, TIntermTyped *node, const TSourceLoc& line) +TIntermTyped *TParseContext::addConstStruct(const TString &identifier, + TIntermTyped *node, + const TSourceLoc &line) { - const TFieldList& fields = node->getType().getStruct()->fields(); - size_t instanceSize = 0; + const TFieldList &fields = node->getType().getStruct()->fields(); + size_t instanceSize = 0; - for (size_t index = 0; index < fields.size(); ++index) { - if (fields[index]->name() == identifier) { + for (size_t index = 0; index < fields.size(); ++index) + { + if (fields[index]->name() == identifier) + { break; - } else { + } + else + { instanceSize += fields[index]->type()->getObjectSize(); } } TIntermTyped *typedNode; TIntermConstantUnion *tempConstantNode = node->getAsConstantUnion(); - if (tempConstantNode) { - TConstantUnion* constArray = tempConstantNode->getUnionArrayPointer(); + if (tempConstantNode) + { + const TConstantUnion *constArray = tempConstantNode->getUnionArrayPointer(); - typedNode = intermediate.addConstantUnion(constArray+instanceSize, tempConstantNode->getType(), line); // type will be changed in the calling function - } else { + // type will be changed in the calling function + typedNode = intermediate.addConstantUnion(constArray + instanceSize, + tempConstantNode->getType(), line); + } + else + { error(line, "Cannot offset into the structure", "Error"); recover(); @@ -1956,15 +2552,22 @@ TIntermTyped* TParseContext::addConstStruct(const TString &identifier, TIntermTy // // Interface/uniform blocks // -TIntermAggregate* TParseContext::addInterfaceBlock(const TPublicType& typeQualifier, const TSourceLoc& nameLine, const TString& blockName, TFieldList* fieldList, - const TString* instanceName, const TSourceLoc& instanceLine, TIntermTyped* arrayIndex, const TSourceLoc& arrayIndexLine) +TIntermAggregate *TParseContext::addInterfaceBlock(const TPublicType &typeQualifier, + const TSourceLoc &nameLine, + const TString &blockName, + TFieldList *fieldList, + const TString *instanceName, + const TSourceLoc &instanceLine, + TIntermTyped *arrayIndex, + const TSourceLoc &arrayIndexLine) { if (reservedErrorCheck(nameLine, blockName)) recover(); if (typeQualifier.qualifier != EvqUniform) { - error(typeQualifier.line, "invalid qualifier:", getQualifierString(typeQualifier.qualifier), "interface blocks must be uniform"); + error(typeQualifier.line, "invalid qualifier:", getQualifierString(typeQualifier.qualifier), + "interface blocks must be uniform"); recover(); } @@ -1976,39 +2579,44 @@ TIntermAggregate* TParseContext::addInterfaceBlock(const TPublicType& typeQualif if (blockLayoutQualifier.matrixPacking == EmpUnspecified) { - blockLayoutQualifier.matrixPacking = defaultMatrixPacking; + blockLayoutQualifier.matrixPacking = mDefaultMatrixPacking; } if (blockLayoutQualifier.blockStorage == EbsUnspecified) { - blockLayoutQualifier.blockStorage = defaultBlockStorage; + blockLayoutQualifier.blockStorage = mDefaultBlockStorage; } - TSymbol* blockNameSymbol = new TInterfaceBlockName(&blockName); - if (!symbolTable.declare(blockNameSymbol)) { + TSymbol *blockNameSymbol = new TInterfaceBlockName(&blockName); + if (!symbolTable.declare(blockNameSymbol)) + { error(nameLine, "redefinition", blockName.c_str(), "interface block name"); recover(); } // check for sampler types and apply layout qualifiers - for (size_t memberIndex = 0; memberIndex < fieldList->size(); ++memberIndex) { - TField* field = (*fieldList)[memberIndex]; - TType* fieldType = field->type(); - if (IsSampler(fieldType->getBasicType())) { - error(field->line(), "unsupported type", fieldType->getBasicString(), "sampler types are not allowed in interface blocks"); + for (size_t memberIndex = 0; memberIndex < fieldList->size(); ++memberIndex) + { + TField *field = (*fieldList)[memberIndex]; + TType *fieldType = field->type(); + if (IsSampler(fieldType->getBasicType())) + { + error(field->line(), "unsupported type", fieldType->getBasicString(), + "sampler types are not allowed in interface blocks"); recover(); } const TQualifier qualifier = fieldType->getQualifier(); switch (qualifier) { - case EvqGlobal: - case EvqUniform: - break; - default: - error(field->line(), "invalid qualifier on interface block member", getQualifierString(qualifier)); - recover(); - break; + case EvqGlobal: + case EvqUniform: + break; + default: + error(field->line(), "invalid qualifier on interface block member", + getQualifierString(qualifier)); + recover(); + break; } // check layout qualifiers @@ -2020,7 +2628,8 @@ TIntermAggregate* TParseContext::addInterfaceBlock(const TPublicType& typeQualif if (fieldLayoutQualifier.blockStorage != EbsUnspecified) { - error(field->line(), "invalid layout qualifier:", getBlockStorageString(fieldLayoutQualifier.blockStorage), "cannot be used here"); + error(field->line(), "invalid layout qualifier:", + getBlockStorageString(fieldLayoutQualifier.blockStorage), "cannot be used here"); recover(); } @@ -2028,10 +2637,11 @@ TIntermAggregate* TParseContext::addInterfaceBlock(const TPublicType& typeQualif { fieldLayoutQualifier.matrixPacking = blockLayoutQualifier.matrixPacking; } - else if (!fieldType->isMatrix()) + else if (!fieldType->isMatrix() && fieldType->getBasicType() != EbtStruct) { - error(field->line(), "invalid layout qualifier:", getMatrixPackingString(fieldLayoutQualifier.matrixPacking), "can only be used on matrix types"); - recover(); + warning(field->line(), "extraneous layout qualifier:", + getMatrixPackingString(fieldLayoutQualifier.matrixPacking), + "only has an effect on matrix types"); } fieldType->setLayoutQualifier(fieldLayoutQualifier); @@ -2045,62 +2655,74 @@ TIntermAggregate* TParseContext::addInterfaceBlock(const TPublicType& typeQualif recover(); } - TInterfaceBlock* interfaceBlock = new TInterfaceBlock(&blockName, fieldList, instanceName, arraySize, blockLayoutQualifier); - TType interfaceBlockType(interfaceBlock, typeQualifier.qualifier, blockLayoutQualifier, arraySize); + TInterfaceBlock *interfaceBlock = + new TInterfaceBlock(&blockName, fieldList, instanceName, arraySize, blockLayoutQualifier); + TType interfaceBlockType(interfaceBlock, typeQualifier.qualifier, blockLayoutQualifier, + arraySize); TString symbolName = ""; - int symbolId = 0; + int symbolId = 0; if (!instanceName) { // define symbols for the members of the interface block for (size_t memberIndex = 0; memberIndex < fieldList->size(); ++memberIndex) { - TField* field = (*fieldList)[memberIndex]; - TType* fieldType = field->type(); + TField *field = (*fieldList)[memberIndex]; + TType *fieldType = field->type(); // set parent pointer of the field variable fieldType->setInterfaceBlock(interfaceBlock); - TVariable* fieldVariable = new TVariable(&field->name(), *fieldType); + TVariable *fieldVariable = new TVariable(&field->name(), *fieldType); fieldVariable->setQualifier(typeQualifier.qualifier); - if (!symbolTable.declare(fieldVariable)) { - error(field->line(), "redefinition", field->name().c_str(), "interface block member name"); + if (!symbolTable.declare(fieldVariable)) + { + error(field->line(), "redefinition", field->name().c_str(), + "interface block member name"); recover(); } } } else { + if (reservedErrorCheck(instanceLine, *instanceName)) + recover(); + // add a symbol for this interface block - TVariable* instanceTypeDef = new TVariable(instanceName, interfaceBlockType, false); + TVariable *instanceTypeDef = new TVariable(instanceName, interfaceBlockType, false); instanceTypeDef->setQualifier(typeQualifier.qualifier); - if (!symbolTable.declare(instanceTypeDef)) { - error(instanceLine, "redefinition", instanceName->c_str(), "interface block instance name"); + if (!symbolTable.declare(instanceTypeDef)) + { + error(instanceLine, "redefinition", instanceName->c_str(), + "interface block instance name"); recover(); } - symbolId = instanceTypeDef->getUniqueId(); + symbolId = instanceTypeDef->getUniqueId(); symbolName = instanceTypeDef->getName(); } - TIntermAggregate *aggregate = intermediate.makeAggregate(intermediate.addSymbol(symbolId, symbolName, interfaceBlockType, typeQualifier.line), nameLine); + TIntermAggregate *aggregate = intermediate.makeAggregate( + intermediate.addSymbol(symbolId, symbolName, interfaceBlockType, typeQualifier.line), + nameLine); aggregate->setOp(EOpDeclaration); exitStructDeclaration(); return aggregate; } -bool TParseContext::enterStructDeclaration(const TSourceLoc& line, const TString& identifier) +bool TParseContext::enterStructDeclaration(const TSourceLoc &line, const TString &identifier) { - ++structNestingLevel; + ++mStructNestingLevel; // Embedded structure definitions are not supported per GLSL ES spec. // They aren't allowed in GLSL either, but we need to detect this here // so we don't rely on the GLSL compiler to catch it. - if (structNestingLevel > 1) { + if (mStructNestingLevel > 1) + { error(line, "", "Embedded struct definitions are not allowed"); return true; } @@ -2110,33 +2732,34 @@ bool TParseContext::enterStructDeclaration(const TSourceLoc& line, const TString void TParseContext::exitStructDeclaration() { - --structNestingLevel; + --mStructNestingLevel; } -namespace { - +namespace +{ const int kWebGLMaxStructNesting = 4; } // namespace -bool TParseContext::structNestingErrorCheck(const TSourceLoc& line, const TField& field) +bool TParseContext::structNestingErrorCheck(const TSourceLoc &line, const TField &field) { - if (!IsWebGLBasedSpec(shaderSpec)) { + if (!IsWebGLBasedSpec(mShaderSpec)) + { return false; } - if (field.type()->getBasicType() != EbtStruct) { + if (field.type()->getBasicType() != EbtStruct) + { return false; } // We're already inside a structure definition at this point, so add // one to the field's struct nesting. - if (1 + field.type()->getDeepestStructNesting() > kWebGLMaxStructNesting) { + if (1 + field.type()->getDeepestStructNesting() > kWebGLMaxStructNesting) + { std::stringstream reasonStream; - reasonStream << "Reference of struct type " - << field.type()->getStruct()->name().c_str() - << " exceeds maximum allowed nesting level of " - << kWebGLMaxStructNesting; + reasonStream << "Reference of struct type " << field.type()->getStruct()->name().c_str() + << " exceeds maximum allowed nesting level of " << kWebGLMaxStructNesting; std::string reason = reasonStream.str(); error(line, reason.c_str(), field.name().c_str(), ""); return true; @@ -2148,7 +2771,9 @@ bool TParseContext::structNestingErrorCheck(const TSourceLoc& line, const TField // // Parse an array index expression // -TIntermTyped* TParseContext::addIndexExpression(TIntermTyped *baseExpression, const TSourceLoc& location, TIntermTyped *indexExpression) +TIntermTyped *TParseContext::addIndexExpression(TIntermTyped *baseExpression, + const TSourceLoc &location, + TIntermTyped *indexExpression) { TIntermTyped *indexedExpression = NULL; @@ -2156,7 +2781,8 @@ TIntermTyped* TParseContext::addIndexExpression(TIntermTyped *baseExpression, co { if (baseExpression->getAsSymbolNode()) { - error(location, " left of '[' is not of type array, matrix, or vector ", baseExpression->getAsSymbolNode()->getSymbol().c_str()); + error(location, " left of '[' is not of type array, matrix, or vector ", + baseExpression->getAsSymbolNode()->getSymbol().c_str()); } else { @@ -2167,37 +2793,73 @@ TIntermTyped* TParseContext::addIndexExpression(TIntermTyped *baseExpression, co TIntermConstantUnion *indexConstantUnion = indexExpression->getAsConstantUnion(); - if (indexExpression->getQualifier() == EvqConst && indexConstantUnion) + // TODO(oetuaho@nvidia.com): Get rid of indexConstantUnion == nullptr below once ANGLE is able + // to constant fold all constant expressions. Right now we don't allow indexing interface blocks + // or fragment outputs with expressions that ANGLE is not able to constant fold, even if the + // index is a constant expression. + if (indexExpression->getQualifier() != EvqConst || indexConstantUnion == nullptr) + { + if (baseExpression->isInterfaceBlock()) + { + error( + location, "", "[", + "array indexes for interface blocks arrays must be constant integral expressions"); + recover(); + } + else if (baseExpression->getQualifier() == EvqFragmentOut) + { + error(location, "", "[", + "array indexes for fragment outputs must be constant integral expressions"); + recover(); + } + else if (mShaderSpec == SH_WEBGL2_SPEC && baseExpression->getQualifier() == EvqFragData) + { + error(location, "", "[", "array index for gl_FragData must be constant zero"); + recover(); + } + } + + if (indexConstantUnion) { + // If the index is not qualified as constant, the behavior in the spec is undefined. This + // applies even if ANGLE has been able to constant fold it (ANGLE may constant fold + // expressions that are not constant expressions). The most compatible way to handle this + // case is to report a warning instead of an error and force the index to be in the + // correct range. + bool outOfRangeIndexIsError = indexExpression->getQualifier() == EvqConst; int index = indexConstantUnion->getIConst(0); if (index < 0) { std::stringstream infoStream; infoStream << index; std::string info = infoStream.str(); - error(location, "negative index", info.c_str()); - recover(); + outOfRangeError(outOfRangeIndexIsError, location, "negative index", info.c_str()); index = 0; } - if (baseExpression->getType().getQualifier() == EvqConst) + TIntermConstantUnion *baseConstantUnion = baseExpression->getAsConstantUnion(); + if (baseConstantUnion) { if (baseExpression->isArray()) { - // constant folding for arrays - indexedExpression = addConstArrayNode(index, baseExpression, location); + // constant folding for array indexing + indexedExpression = + addConstArrayNode(index, baseConstantUnion, location, outOfRangeIndexIsError); } else if (baseExpression->isVector()) { - // constant folding for vectors + // constant folding for vector indexing TVectorFields fields; fields.num = 1; - fields.offsets[0] = index; // need to do it this way because v.xy sends fields integer array - indexedExpression = addConstVectorNode(fields, baseExpression, location); + fields.offsets[0] = + index; // need to do it this way because v.xy sends fields integer array + indexedExpression = + addConstVectorNode(fields, baseConstantUnion, location, outOfRangeIndexIsError); } else if (baseExpression->isMatrix()) { - // constant folding for matrices - indexedExpression = addConstMatrixNode(index, baseExpression, location); + // constant folding for matrix indexing + indexedExpression = + addConstMatrixNode(index, baseConstantUnion, location, outOfRangeIndexIsError); } } else @@ -2206,34 +2868,50 @@ TIntermTyped* TParseContext::addIndexExpression(TIntermTyped *baseExpression, co if (baseExpression->isArray()) { - if (index >= baseExpression->getType().getArraySize()) + if (baseExpression->getQualifier() == EvqFragData && index > 0) + { + if (mShaderSpec == SH_WEBGL2_SPEC) + { + // Error has been already generated if index is not const. + if (indexExpression->getQualifier() == EvqConst) + { + error(location, "", "[", + "array index for gl_FragData must be constant zero"); + recover(); + } + safeIndex = 0; + } + else if (!isExtensionEnabled("GL_EXT_draw_buffers")) + { + outOfRangeError(outOfRangeIndexIsError, location, "", "[", + "array index for gl_FragData must be zero when " + "GL_EXT_draw_buffers is disabled"); + safeIndex = 0; + } + } + // Only do generic out-of-range check if similar error hasn't already been reported. + if (safeIndex < 0 && index >= baseExpression->getType().getArraySize()) { std::stringstream extraInfoStream; extraInfoStream << "array index out of range '" << index << "'"; std::string extraInfo = extraInfoStream.str(); - error(location, "", "[", extraInfo.c_str()); - recover(); + outOfRangeError(outOfRangeIndexIsError, location, "", "[", extraInfo.c_str()); safeIndex = baseExpression->getType().getArraySize() - 1; } - else if (baseExpression->getQualifier() == EvqFragData && index > 0 && !isExtensionEnabled("GL_EXT_draw_buffers")) - { - error(location, "", "[", "array indexes for gl_FragData must be zero when GL_EXT_draw_buffers is disabled"); - recover(); - safeIndex = 0; - } } - else if ((baseExpression->isVector() || baseExpression->isMatrix()) && baseExpression->getType().getNominalSize() <= index) + else if ((baseExpression->isVector() || baseExpression->isMatrix()) && + baseExpression->getType().getNominalSize() <= index) { std::stringstream extraInfoStream; extraInfoStream << "field selection out of range '" << index << "'"; std::string extraInfo = extraInfoStream.str(); - error(location, "", "[", extraInfo.c_str()); - recover(); + outOfRangeError(outOfRangeIndexIsError, location, "", "[", extraInfo.c_str()); safeIndex = baseExpression->getType().getNominalSize() - 1; } - // Don't modify the data of the previous constant union, because it can point - // to builtins, like gl_MaxDrawBuffers. Instead use a new sanitized object. + // Data of constant unions can't be changed, because it may be shared with other + // constant unions or even builtins, like gl_MaxDrawBuffers. Instead use a new + // sanitized object. if (safeIndex != -1) { TConstantUnion *safeConstantUnion = new TConstantUnion(); @@ -2241,74 +2919,62 @@ TIntermTyped* TParseContext::addIndexExpression(TIntermTyped *baseExpression, co indexConstantUnion->replaceConstantUnion(safeConstantUnion); } - indexedExpression = intermediate.addIndex(EOpIndexDirect, baseExpression, indexExpression, location); + indexedExpression = + intermediate.addIndex(EOpIndexDirect, baseExpression, indexExpression, location); } } else { - if (baseExpression->isInterfaceBlock()) - { - error(location, "", "[", "array indexes for interface blocks arrays must be constant integral expressions"); - recover(); - } - else if (baseExpression->getQualifier() == EvqFragmentOut) - { - error(location, "", "[", "array indexes for fragment outputs must be constant integral expressions"); - recover(); - } - - indexedExpression = intermediate.addIndex(EOpIndexIndirect, baseExpression, indexExpression, location); + indexedExpression = + intermediate.addIndex(EOpIndexIndirect, baseExpression, indexExpression, location); } if (indexedExpression == 0) { TConstantUnion *unionArray = new TConstantUnion[1]; unionArray->setFConst(0.0f); - indexedExpression = intermediate.addConstantUnion(unionArray, TType(EbtFloat, EbpHigh, EvqConst), location); + indexedExpression = + intermediate.addConstantUnion(unionArray, TType(EbtFloat, EbpHigh, EvqConst), location); } else if (baseExpression->isArray()) { - const TType &baseType = baseExpression->getType(); - if (baseType.getStruct()) - { - TType copyOfType(baseType.getStruct()); - indexedExpression->setType(copyOfType); - } - else if (baseType.isInterfaceBlock()) - { - TType copyOfType(baseType.getInterfaceBlock(), baseType.getQualifier(), baseType.getLayoutQualifier(), 0); - indexedExpression->setType(copyOfType); - } - else - { - indexedExpression->setType(TType(baseExpression->getBasicType(), baseExpression->getPrecision(), EvqTemporary, - static_cast(baseExpression->getNominalSize()), static_cast(baseExpression->getSecondarySize()))); - } - - if (baseExpression->getType().getQualifier() == EvqConst) - { - indexedExpression->getTypePointer()->setQualifier(EvqConst); - } + TType indexedType = baseExpression->getType(); + indexedType.clearArrayness(); + indexedExpression->setType(indexedType); } else if (baseExpression->isMatrix()) { - TQualifier qualifier = baseExpression->getType().getQualifier() == EvqConst ? EvqConst : EvqTemporary; - indexedExpression->setType(TType(baseExpression->getBasicType(), baseExpression->getPrecision(), qualifier, static_cast(baseExpression->getRows()))); + indexedExpression->setType(TType(baseExpression->getBasicType(), + baseExpression->getPrecision(), EvqTemporary, + static_cast(baseExpression->getRows()))); } else if (baseExpression->isVector()) { - TQualifier qualifier = baseExpression->getType().getQualifier() == EvqConst ? EvqConst : EvqTemporary; - indexedExpression->setType(TType(baseExpression->getBasicType(), baseExpression->getPrecision(), qualifier)); + indexedExpression->setType( + TType(baseExpression->getBasicType(), baseExpression->getPrecision(), EvqTemporary)); } else { indexedExpression->setType(baseExpression->getType()); } + if (baseExpression->getType().getQualifier() == EvqConst && + indexExpression->getType().getQualifier() == EvqConst) + { + indexedExpression->getTypePointer()->setQualifier(EvqConst); + } + else + { + indexedExpression->getTypePointer()->setQualifier(EvqTemporary); + } + return indexedExpression; } -TIntermTyped* TParseContext::addFieldSelectionExpression(TIntermTyped *baseExpression, const TSourceLoc& dotLocation, const TString &fieldString, const TSourceLoc& fieldLocation) +TIntermTyped *TParseContext::addFieldSelectionExpression(TIntermTyped *baseExpression, + const TSourceLoc &dotLocation, + const TString &fieldString, + const TSourceLoc &fieldLocation) { TIntermTyped *indexedExpression = NULL; @@ -2321,71 +2987,43 @@ TIntermTyped* TParseContext::addFieldSelectionExpression(TIntermTyped *baseExpre if (baseExpression->isVector()) { TVectorFields fields; - if (!parseVectorFields(fieldString, baseExpression->getNominalSize(), fields, fieldLocation)) + if (!parseVectorFields(fieldString, baseExpression->getNominalSize(), fields, + fieldLocation)) { - fields.num = 1; + fields.num = 1; fields.offsets[0] = 0; recover(); } - if (baseExpression->getType().getQualifier() == EvqConst) + if (baseExpression->getAsConstantUnion()) { // constant folding for vector fields - indexedExpression = addConstVectorNode(fields, baseExpression, fieldLocation); - if (indexedExpression == 0) - { - recover(); - indexedExpression = baseExpression; - } - else - { - indexedExpression->setType(TType(baseExpression->getBasicType(), baseExpression->getPrecision(), EvqConst, (unsigned char) (fieldString).size())); - } + indexedExpression = addConstVectorNode(fields, baseExpression->getAsConstantUnion(), + fieldLocation, true); } else { - TString vectorString = fieldString; - TIntermTyped* index = intermediate.addSwizzle(fields, fieldLocation); - indexedExpression = intermediate.addIndex(EOpVectorSwizzle, baseExpression, index, dotLocation); - indexedExpression->setType(TType(baseExpression->getBasicType(), baseExpression->getPrecision(), EvqTemporary, (unsigned char) vectorString.size())); - } - } - else if (baseExpression->isMatrix()) - { - TMatrixFields fields; - if (!parseMatrixFields(fieldString, baseExpression->getCols(), baseExpression->getRows(), fields, fieldLocation)) - { - fields.wholeRow = false; - fields.wholeCol = false; - fields.row = 0; - fields.col = 0; - recover(); + TIntermTyped *index = intermediate.addSwizzle(fields, fieldLocation); + indexedExpression = + intermediate.addIndex(EOpVectorSwizzle, baseExpression, index, dotLocation); } - - if (fields.wholeRow || fields.wholeCol) + if (indexedExpression == nullptr) { - error(dotLocation, " non-scalar fields not implemented yet", "."); recover(); - TConstantUnion *unionArray = new TConstantUnion[1]; - unionArray->setIConst(0); - TIntermTyped* index = intermediate.addConstantUnion(unionArray, TType(EbtInt, EbpUndefined, EvqConst), fieldLocation); - indexedExpression = intermediate.addIndex(EOpIndexDirect, baseExpression, index, dotLocation); - indexedExpression->setType(TType(baseExpression->getBasicType(), baseExpression->getPrecision(),EvqTemporary, - static_cast(baseExpression->getCols()), static_cast(baseExpression->getRows()))); + indexedExpression = baseExpression; } else { - TConstantUnion *unionArray = new TConstantUnion[1]; - unionArray->setIConst(fields.col * baseExpression->getRows() + fields.row); - TIntermTyped* index = intermediate.addConstantUnion(unionArray, TType(EbtInt, EbpUndefined, EvqConst), fieldLocation); - indexedExpression = intermediate.addIndex(EOpIndexDirect, baseExpression, index, dotLocation); - indexedExpression->setType(TType(baseExpression->getBasicType(), baseExpression->getPrecision())); + // Note that the qualifier set here will be corrected later. + indexedExpression->setType(TType(baseExpression->getBasicType(), + baseExpression->getPrecision(), EvqTemporary, + (unsigned char)(fieldString).size())); } } else if (baseExpression->getBasicType() == EbtStruct) { - bool fieldFound = false; - const TFieldList& fields = baseExpression->getType().getStruct()->fields(); + bool fieldFound = false; + const TFieldList &fields = baseExpression->getType().getStruct()->fields(); if (fields.empty()) { error(dotLocation, "structure has no fields", "Internal Error"); @@ -2405,7 +3043,7 @@ TIntermTyped* TParseContext::addFieldSelectionExpression(TIntermTyped *baseExpre } if (fieldFound) { - if (baseExpression->getType().getQualifier() == EvqConst) + if (baseExpression->getAsConstantUnion()) { indexedExpression = addConstStruct(fieldString, baseExpression, dotLocation); if (indexedExpression == 0) @@ -2416,17 +3054,16 @@ TIntermTyped* TParseContext::addFieldSelectionExpression(TIntermTyped *baseExpre else { indexedExpression->setType(*fields[i]->type()); - // change the qualifier of the return type, not of the structure field - // as the structure definition is shared between various structures. - indexedExpression->getTypePointer()->setQualifier(EvqConst); } } else { TConstantUnion *unionArray = new TConstantUnion[1]; unionArray->setIConst(i); - TIntermTyped* index = intermediate.addConstantUnion(unionArray, *fields[i]->type(), fieldLocation); - indexedExpression = intermediate.addIndex(EOpIndexDirectStruct, baseExpression, index, dotLocation); + TIntermTyped *index = intermediate.addConstantUnion( + unionArray, *fields[i]->type(), fieldLocation); + indexedExpression = intermediate.addIndex(EOpIndexDirectStruct, baseExpression, + index, dotLocation); indexedExpression->setType(*fields[i]->type()); } } @@ -2440,8 +3077,8 @@ TIntermTyped* TParseContext::addFieldSelectionExpression(TIntermTyped *baseExpre } else if (baseExpression->isInterfaceBlock()) { - bool fieldFound = false; - const TFieldList& fields = baseExpression->getType().getInterfaceBlock()->fields(); + bool fieldFound = false; + const TFieldList &fields = baseExpression->getType().getInterfaceBlock()->fields(); if (fields.empty()) { error(dotLocation, "interface block has no fields", "Internal Error"); @@ -2463,8 +3100,10 @@ TIntermTyped* TParseContext::addFieldSelectionExpression(TIntermTyped *baseExpre { TConstantUnion *unionArray = new TConstantUnion[1]; unionArray->setIConst(i); - TIntermTyped* index = intermediate.addConstantUnion(unionArray, *fields[i]->type(), fieldLocation); - indexedExpression = intermediate.addIndex(EOpIndexDirectInterfaceBlock, baseExpression, index, dotLocation); + TIntermTyped *index = + intermediate.addConstantUnion(unionArray, *fields[i]->type(), fieldLocation); + indexedExpression = intermediate.addIndex(EOpIndexDirectInterfaceBlock, + baseExpression, index, dotLocation); indexedExpression->setType(*fields[i]->type()); } else @@ -2477,28 +3116,42 @@ TIntermTyped* TParseContext::addFieldSelectionExpression(TIntermTyped *baseExpre } else { - if (shaderVersion < 300) + if (mShaderVersion < 300) { - error(dotLocation, " field selection requires structure, vector, or matrix on left hand side", fieldString.c_str()); + error(dotLocation, " field selection requires structure or vector on left hand side", + fieldString.c_str()); } else { - error(dotLocation, " field selection requires structure, vector, matrix, or interface block on left hand side", fieldString.c_str()); + error(dotLocation, + " field selection requires structure, vector, or interface block on left hand " + "side", + fieldString.c_str()); } recover(); indexedExpression = baseExpression; } + if (baseExpression->getQualifier() == EvqConst) + { + indexedExpression->getTypePointer()->setQualifier(EvqConst); + } + else + { + indexedExpression->getTypePointer()->setQualifier(EvqTemporary); + } + return indexedExpression; } -TLayoutQualifier TParseContext::parseLayoutQualifier(const TString &qualifierType, const TSourceLoc& qualifierTypeLine) +TLayoutQualifier TParseContext::parseLayoutQualifier(const TString &qualifierType, + const TSourceLoc &qualifierTypeLine) { TLayoutQualifier qualifier; - qualifier.location = -1; + qualifier.location = -1; qualifier.matrixPacking = EmpUnspecified; - qualifier.blockStorage = EbsUnspecified; + qualifier.blockStorage = EbsUnspecified; if (qualifierType == "shared") { @@ -2522,7 +3175,8 @@ TLayoutQualifier TParseContext::parseLayoutQualifier(const TString &qualifierTyp } else if (qualifierType == "location") { - error(qualifierTypeLine, "invalid layout qualifier", qualifierType.c_str(), "location requires an argument"); + error(qualifierTypeLine, "invalid layout qualifier", qualifierType.c_str(), + "location requires an argument"); recover(); } else @@ -2534,17 +3188,22 @@ TLayoutQualifier TParseContext::parseLayoutQualifier(const TString &qualifierTyp return qualifier; } -TLayoutQualifier TParseContext::parseLayoutQualifier(const TString &qualifierType, const TSourceLoc& qualifierTypeLine, const TString &intValueString, int intValue, const TSourceLoc& intValueLine) +TLayoutQualifier TParseContext::parseLayoutQualifier(const TString &qualifierType, + const TSourceLoc &qualifierTypeLine, + const TString &intValueString, + int intValue, + const TSourceLoc &intValueLine) { TLayoutQualifier qualifier; - qualifier.location = -1; + qualifier.location = -1; qualifier.matrixPacking = EmpUnspecified; - qualifier.blockStorage = EbsUnspecified; + qualifier.blockStorage = EbsUnspecified; if (qualifierType != "location") { - error(qualifierTypeLine, "invalid layout qualifier", qualifierType.c_str(), "only location may have arguments"); + error(qualifierTypeLine, "invalid layout qualifier", qualifierType.c_str(), + "only location may have arguments"); recover(); } else @@ -2552,7 +3211,8 @@ TLayoutQualifier TParseContext::parseLayoutQualifier(const TString &qualifierTyp // must check that location is non-negative if (intValue < 0) { - error(intValueLine, "out of range:", intValueString.c_str(), "location must be non-negative"); + error(intValueLine, "out of range:", intValueString.c_str(), + "location must be non-negative"); recover(); } else @@ -2564,7 +3224,8 @@ TLayoutQualifier TParseContext::parseLayoutQualifier(const TString &qualifierTyp return qualifier; } -TLayoutQualifier TParseContext::joinLayoutQualifiers(TLayoutQualifier leftQualifier, TLayoutQualifier rightQualifier) +TLayoutQualifier TParseContext::joinLayoutQualifiers(TLayoutQualifier leftQualifier, + TLayoutQualifier rightQualifier) { TLayoutQualifier joinedQualifier = leftQualifier; @@ -2584,41 +3245,54 @@ TLayoutQualifier TParseContext::joinLayoutQualifiers(TLayoutQualifier leftQualif return joinedQualifier; } -TPublicType TParseContext::joinInterpolationQualifiers(const TSourceLoc &interpolationLoc, TQualifier interpolationQualifier, - const TSourceLoc &storageLoc, TQualifier storageQualifier) +TPublicType TParseContext::joinInterpolationQualifiers(const TSourceLoc &interpolationLoc, + TQualifier interpolationQualifier, + const TSourceLoc &storageLoc, + TQualifier storageQualifier) { TQualifier mergedQualifier = EvqSmoothIn; - if (storageQualifier == EvqFragmentIn) { + if (storageQualifier == EvqFragmentIn) + { if (interpolationQualifier == EvqSmooth) mergedQualifier = EvqSmoothIn; else if (interpolationQualifier == EvqFlat) mergedQualifier = EvqFlatIn; - else UNREACHABLE(); + else + UNREACHABLE(); } - else if (storageQualifier == EvqCentroidIn) { + else if (storageQualifier == EvqCentroidIn) + { if (interpolationQualifier == EvqSmooth) mergedQualifier = EvqCentroidIn; else if (interpolationQualifier == EvqFlat) mergedQualifier = EvqFlatIn; - else UNREACHABLE(); + else + UNREACHABLE(); } - else if (storageQualifier == EvqVertexOut) { + else if (storageQualifier == EvqVertexOut) + { if (interpolationQualifier == EvqSmooth) mergedQualifier = EvqSmoothOut; else if (interpolationQualifier == EvqFlat) mergedQualifier = EvqFlatOut; - else UNREACHABLE(); + else + UNREACHABLE(); } - else if (storageQualifier == EvqCentroidOut) { + else if (storageQualifier == EvqCentroidOut) + { if (interpolationQualifier == EvqSmooth) mergedQualifier = EvqCentroidOut; else if (interpolationQualifier == EvqFlat) mergedQualifier = EvqFlatOut; - else UNREACHABLE(); + else + UNREACHABLE(); } - else { - error(interpolationLoc, "interpolation qualifier requires a fragment 'in' or vertex 'out' storage qualifier", getInterpolationString(interpolationQualifier)); + else + { + error(interpolationLoc, + "interpolation qualifier requires a fragment 'in' or vertex 'out' storage qualifier", + getInterpolationString(interpolationQualifier)); recover(); mergedQualifier = storageQualifier; @@ -2629,18 +3303,20 @@ TPublicType TParseContext::joinInterpolationQualifiers(const TSourceLoc &interpo return type; } -TFieldList *TParseContext::addStructDeclaratorList(const TPublicType& typeSpecifier, TFieldList *fieldList) +TFieldList *TParseContext::addStructDeclaratorList(const TPublicType &typeSpecifier, + TFieldList *fieldList) { if (voidErrorCheck(typeSpecifier.line, (*fieldList)[0]->name(), typeSpecifier.type)) { recover(); } - for (unsigned int i = 0; i < fieldList->size(); ++i) { + for (unsigned int i = 0; i < fieldList->size(); ++i) + { // // Careful not to replace already known aspects of type, like array-ness // - TType* type = (*fieldList)[i]->type(); + TType *type = (*fieldList)[i]->type(); type->setBasicType(typeSpecifier.type); type->setPrimarySize(typeSpecifier.primarySize); type->setSecondarySize(typeSpecifier.secondarySize); @@ -2649,17 +3325,20 @@ TFieldList *TParseContext::addStructDeclaratorList(const TPublicType& typeSpecif type->setLayoutQualifier(typeSpecifier.layoutQualifier); // don't allow arrays of arrays - if (type->isArray()) { + if (type->isArray()) + { if (arrayTypeErrorCheck(typeSpecifier.line, typeSpecifier)) recover(); } if (typeSpecifier.array) type->setArraySize(typeSpecifier.arraySize); - if (typeSpecifier.userDef) { + if (typeSpecifier.userDef) + { type->setStruct(typeSpecifier.userDef->getStruct()); } - if (structNestingErrorCheck(typeSpecifier.line, *(*fieldList)[i])) { + if (structNestingErrorCheck(typeSpecifier.line, *(*fieldList)[i])) + { recover(); } } @@ -2667,10 +3346,13 @@ TFieldList *TParseContext::addStructDeclaratorList(const TPublicType& typeSpecif return fieldList; } -TPublicType TParseContext::addStructure(const TSourceLoc& structLine, const TSourceLoc& nameLine, const TString *structName, TFieldList* fieldList) +TPublicType TParseContext::addStructure(const TSourceLoc &structLine, + const TSourceLoc &nameLine, + const TString *structName, + TFieldList *fieldList) { - TStructure* structure = new TStructure(structName, fieldList); - TType* structureType = new TType(structure); + TStructure *structure = new TStructure(structName, fieldList); + TType *structureType = new TType(structure); // Store a bool in the struct if we're at global scope, to allow us to // skip the local struct scoping workaround in HLSL. @@ -2683,8 +3365,9 @@ TPublicType TParseContext::addStructure(const TSourceLoc& structLine, const TSou { recover(); } - TVariable* userTypeDef = new TVariable(structName, *structureType, true); - if (!symbolTable.declare(userTypeDef)) { + TVariable *userTypeDef = new TVariable(structName, *structureType, true); + if (!symbolTable.declare(userTypeDef)) + { error(nameLine, "redefinition", structName->c_str(), "struct"); recover(); } @@ -2693,37 +3376,40 @@ TPublicType TParseContext::addStructure(const TSourceLoc& structLine, const TSou // ensure we do not specify any storage qualifiers on the struct members for (unsigned int typeListIndex = 0; typeListIndex < fieldList->size(); typeListIndex++) { - const TField &field = *(*fieldList)[typeListIndex]; + const TField &field = *(*fieldList)[typeListIndex]; const TQualifier qualifier = field.type()->getQualifier(); switch (qualifier) { - case EvqGlobal: - case EvqTemporary: - break; - default: - error(field.line(), "invalid qualifier on struct member", getQualifierString(qualifier)); - recover(); - break; + case EvqGlobal: + case EvqTemporary: + break; + default: + error(field.line(), "invalid qualifier on struct member", + getQualifierString(qualifier)); + recover(); + break; } } TPublicType publicType; publicType.setBasic(EbtStruct, EvqTemporary, structLine); publicType.userDef = structureType; + publicType.isStructSpecifier = true; exitStructDeclaration(); return publicType; } -TIntermSwitch *TParseContext::addSwitch(TIntermTyped *init, TIntermAggregate *statementList, const TSourceLoc &loc) +TIntermSwitch *TParseContext::addSwitch(TIntermTyped *init, + TIntermAggregate *statementList, + const TSourceLoc &loc) { TBasicType switchType = init->getBasicType(); - if ((switchType != EbtInt && switchType != EbtUInt) || - init->isMatrix() || - init->isArray() || + if ((switchType != EbtInt && switchType != EbtUInt) || init->isMatrix() || init->isArray() || init->isVector()) { - error(init->getLine(), "init-expression in a switch statement must be a scalar integer", "switch"); + error(init->getLine(), "init-expression in a switch statement must be a scalar integer", + "switch"); recover(); return nullptr; } @@ -2762,15 +3448,16 @@ TIntermCase *TParseContext::addCase(TIntermTyped *condition, const TSourceLoc &l return nullptr; } if ((condition->getBasicType() != EbtInt && condition->getBasicType() != EbtUInt) || - condition->isMatrix() || - condition->isArray() || - condition->isVector()) + condition->isMatrix() || condition->isArray() || condition->isVector()) { error(condition->getLine(), "case label must be a scalar integer", "case"); recover(); } TIntermConstantUnion *conditionConst = condition->getAsConstantUnion(); - if (conditionConst == nullptr) + // TODO(oetuaho@nvidia.com): Get rid of the conditionConst == nullptr check once all constant + // expressions can be folded. Right now we don't allow constant expressions that ANGLE can't + // fold in case labels. + if (condition->getQualifier() != EvqConst || conditionConst == nullptr) { error(condition->getLine(), "case label must be constant", "case"); recover(); @@ -2803,8 +3490,10 @@ TIntermCase *TParseContext::addDefault(const TSourceLoc &loc) return node; } -TIntermTyped *TParseContext::createUnaryMath(TOperator op, TIntermTyped *child, const TSourceLoc &loc, - const TType *funcReturnType) +TIntermTyped *TParseContext::createUnaryMath(TOperator op, + TIntermTyped *child, + const TSourceLoc &loc, + const TType *funcReturnType) { if (child == nullptr) { @@ -2813,38 +3502,34 @@ TIntermTyped *TParseContext::createUnaryMath(TOperator op, TIntermTyped *child, switch (op) { - case EOpLogicalNot: - if (child->getBasicType() != EbtBool || - child->isMatrix() || - child->isArray() || - child->isVector()) - { - return nullptr; - } - break; - case EOpBitwiseNot: - if ((child->getBasicType() != EbtInt && child->getBasicType() != EbtUInt) || - child->isMatrix() || - child->isArray()) - { - return nullptr; - } - break; - case EOpPostIncrement: - case EOpPreIncrement: - case EOpPostDecrement: - case EOpPreDecrement: - case EOpNegative: - case EOpPositive: - if (child->getBasicType() == EbtStruct || - child->getBasicType() == EbtBool || - child->isArray()) - { - return nullptr; - } - // Operators for built-ins are already type checked against their prototype. - default: - break; + case EOpLogicalNot: + if (child->getBasicType() != EbtBool || child->isMatrix() || child->isArray() || + child->isVector()) + { + return nullptr; + } + break; + case EOpBitwiseNot: + if ((child->getBasicType() != EbtInt && child->getBasicType() != EbtUInt) || + child->isMatrix() || child->isArray()) + { + return nullptr; + } + break; + case EOpPostIncrement: + case EOpPreIncrement: + case EOpPostDecrement: + case EOpPreDecrement: + case EOpNegative: + case EOpPositive: + if (child->getBasicType() == EbtStruct || child->getBasicType() == EbtBool || + child->isArray()) + { + return nullptr; + } + // Operators for built-ins are already type checked against their prototype. + default: + break; } return intermediate.addUnaryMath(op, child, loc, funcReturnType); @@ -2862,19 +3547,23 @@ TIntermTyped *TParseContext::addUnaryMath(TOperator op, TIntermTyped *child, con return node; } -TIntermTyped *TParseContext::addUnaryMathLValue(TOperator op, TIntermTyped *child, const TSourceLoc &loc) +TIntermTyped *TParseContext::addUnaryMathLValue(TOperator op, + TIntermTyped *child, + const TSourceLoc &loc) { if (lValueErrorCheck(loc, GetOperatorString(op), child)) recover(); return addUnaryMath(op, child, loc); } -bool TParseContext::binaryOpCommonCheck(TOperator op, TIntermTyped *left, TIntermTyped *right, - const TSourceLoc &loc) +bool TParseContext::binaryOpCommonCheck(TOperator op, + TIntermTyped *left, + TIntermTyped *right, + const TSourceLoc &loc) { if (left->isArray() || right->isArray()) { - if (shaderVersion < 300) + if (mShaderVersion < 300) { error(loc, "Invalid operation for arrays", GetOperatorString(op)); return false; @@ -2888,14 +3577,14 @@ bool TParseContext::binaryOpCommonCheck(TOperator op, TIntermTyped *left, TInter switch (op) { - case EOpEqual: - case EOpNotEqual: - case EOpAssign: - case EOpInitialize: - break; - default: - error(loc, "Invalid operation for arrays", GetOperatorString(op)); - return false; + case EOpEqual: + case EOpNotEqual: + case EOpAssign: + case EOpInitialize: + break; + default: + error(loc, "Invalid operation for arrays", GetOperatorString(op)); + return false; } // At this point, size of implicitly sized arrays should be resolved. if (left->getArraySize() != right->getArraySize()) @@ -2909,33 +3598,33 @@ bool TParseContext::binaryOpCommonCheck(TOperator op, TIntermTyped *left, TInter bool isBitShift = false; switch (op) { - case EOpBitShiftLeft: - case EOpBitShiftRight: - case EOpBitShiftLeftAssign: - case EOpBitShiftRightAssign: - // Unsigned can be bit-shifted by signed and vice versa, but we need to - // check that the basic type is an integer type. - isBitShift = true; - if (!IsInteger(left->getBasicType()) || !IsInteger(right->getBasicType())) - { - return false; - } - break; - case EOpBitwiseAnd: - case EOpBitwiseXor: - case EOpBitwiseOr: - case EOpBitwiseAndAssign: - case EOpBitwiseXorAssign: - case EOpBitwiseOrAssign: - // It is enough to check the type of only one operand, since later it - // is checked that the operand types match. - if (!IsInteger(left->getBasicType())) - { - return false; - } - break; - default: - break; + case EOpBitShiftLeft: + case EOpBitShiftRight: + case EOpBitShiftLeftAssign: + case EOpBitShiftRightAssign: + // Unsigned can be bit-shifted by signed and vice versa, but we need to + // check that the basic type is an integer type. + isBitShift = true; + if (!IsInteger(left->getBasicType()) || !IsInteger(right->getBasicType())) + { + return false; + } + break; + case EOpBitwiseAnd: + case EOpBitwiseXor: + case EOpBitwiseOr: + case EOpBitwiseAndAssign: + case EOpBitwiseXorAssign: + case EOpBitwiseOrAssign: + // It is enough to check the type of only one operand, since later it + // is checked that the operand types match. + if (!IsInteger(left->getBasicType())) + { + return false; + } + break; + default: + break; } // GLSL ES 1.00 and 3.00 do not support implicit type casting. @@ -2947,132 +3636,144 @@ bool TParseContext::binaryOpCommonCheck(TOperator op, TIntermTyped *left, TInter // Check that type sizes match exactly on ops that require that. // Also check restrictions for structs that contain arrays or samplers. - switch(op) + switch (op) { - case EOpAssign: - case EOpInitialize: - case EOpEqual: - case EOpNotEqual: - // ESSL 1.00 sections 5.7, 5.8, 5.9 - if (shaderVersion < 300 && left->getType().isStructureContainingArrays()) - { - error(loc, "undefined operation for structs containing arrays", GetOperatorString(op)); - return false; - } - // Samplers as l-values are disallowed also in ESSL 3.00, see section 4.1.7, - // we interpret the spec so that this extends to structs containing samplers, - // similarly to ESSL 1.00 spec. - if ((shaderVersion < 300 || op == EOpAssign || op == EOpInitialize) && - left->getType().isStructureContainingSamplers()) - { - error(loc, "undefined operation for structs containing samplers", GetOperatorString(op)); - return false; - } - case EOpLessThan: - case EOpGreaterThan: - case EOpLessThanEqual: - case EOpGreaterThanEqual: - if ((left->getNominalSize() != right->getNominalSize()) || - (left->getSecondarySize() != right->getSecondarySize())) - { - return false; - } - default: - break; + case EOpAssign: + case EOpInitialize: + case EOpEqual: + case EOpNotEqual: + // ESSL 1.00 sections 5.7, 5.8, 5.9 + if (mShaderVersion < 300 && left->getType().isStructureContainingArrays()) + { + error(loc, "undefined operation for structs containing arrays", + GetOperatorString(op)); + return false; + } + // Samplers as l-values are disallowed also in ESSL 3.00, see section 4.1.7, + // we interpret the spec so that this extends to structs containing samplers, + // similarly to ESSL 1.00 spec. + if ((mShaderVersion < 300 || op == EOpAssign || op == EOpInitialize) && + left->getType().isStructureContainingSamplers()) + { + error(loc, "undefined operation for structs containing samplers", + GetOperatorString(op)); + return false; + } + case EOpLessThan: + case EOpGreaterThan: + case EOpLessThanEqual: + case EOpGreaterThanEqual: + if ((left->getNominalSize() != right->getNominalSize()) || + (left->getSecondarySize() != right->getSecondarySize())) + { + return false; + } + default: + break; } return true; } -TIntermTyped *TParseContext::addBinaryMathInternal(TOperator op, TIntermTyped *left, TIntermTyped *right, - const TSourceLoc &loc) +TIntermTyped *TParseContext::addBinaryMathInternal(TOperator op, + TIntermTyped *left, + TIntermTyped *right, + const TSourceLoc &loc) { if (!binaryOpCommonCheck(op, left, right, loc)) return nullptr; switch (op) { - case EOpEqual: - case EOpNotEqual: - break; - case EOpLessThan: - case EOpGreaterThan: - case EOpLessThanEqual: - case EOpGreaterThanEqual: - ASSERT(!left->isArray() && !right->isArray()); - if (left->isMatrix() || left->isVector() || - left->getBasicType() == EbtStruct) - { - return nullptr; - } - break; - case EOpLogicalOr: - case EOpLogicalXor: - case EOpLogicalAnd: - ASSERT(!left->isArray() && !right->isArray()); - if (left->getBasicType() != EbtBool || - left->isMatrix() || left->isVector()) - { - return nullptr; - } - break; - case EOpAdd: - case EOpSub: - case EOpDiv: - case EOpMul: - ASSERT(!left->isArray() && !right->isArray()); - if (left->getBasicType() == EbtStruct || left->getBasicType() == EbtBool) - { - return nullptr; - } - break; - case EOpIMod: - ASSERT(!left->isArray() && !right->isArray()); - // Note that this is only for the % operator, not for mod() - if (left->getBasicType() == EbtStruct || left->getBasicType() == EbtBool || left->getBasicType() == EbtFloat) - { - return nullptr; - } - break; - // Note that for bitwise ops, type checking is done in promote() to - // share code between ops and compound assignment - default: - break; + case EOpEqual: + case EOpNotEqual: + break; + case EOpLessThan: + case EOpGreaterThan: + case EOpLessThanEqual: + case EOpGreaterThanEqual: + ASSERT(!left->isArray() && !right->isArray()); + if (left->isMatrix() || left->isVector() || left->getBasicType() == EbtStruct) + { + return nullptr; + } + break; + case EOpLogicalOr: + case EOpLogicalXor: + case EOpLogicalAnd: + ASSERT(!left->isArray() && !right->isArray()); + if (left->getBasicType() != EbtBool || left->isMatrix() || left->isVector()) + { + return nullptr; + } + break; + case EOpAdd: + case EOpSub: + case EOpDiv: + case EOpMul: + ASSERT(!left->isArray() && !right->isArray()); + if (left->getBasicType() == EbtStruct || left->getBasicType() == EbtBool) + { + return nullptr; + } + break; + case EOpIMod: + ASSERT(!left->isArray() && !right->isArray()); + // Note that this is only for the % operator, not for mod() + if (left->getBasicType() == EbtStruct || left->getBasicType() == EbtBool || + left->getBasicType() == EbtFloat) + { + return nullptr; + } + break; + // Note that for bitwise ops, type checking is done in promote() to + // share code between ops and compound assignment + default: + break; } return intermediate.addBinaryMath(op, left, right, loc); } -TIntermTyped *TParseContext::addBinaryMath(TOperator op, TIntermTyped *left, TIntermTyped *right, - const TSourceLoc &loc) +TIntermTyped *TParseContext::addBinaryMath(TOperator op, + TIntermTyped *left, + TIntermTyped *right, + const TSourceLoc &loc) { TIntermTyped *node = addBinaryMathInternal(op, left, right, loc); if (node == 0) { - binaryOpError(loc, GetOperatorString(op), left->getCompleteString(), right->getCompleteString()); + binaryOpError(loc, GetOperatorString(op), left->getCompleteString(), + right->getCompleteString()); recover(); return left; } return node; } -TIntermTyped *TParseContext::addBinaryMathBooleanResult(TOperator op, TIntermTyped *left, TIntermTyped *right, - const TSourceLoc &loc) +TIntermTyped *TParseContext::addBinaryMathBooleanResult(TOperator op, + TIntermTyped *left, + TIntermTyped *right, + const TSourceLoc &loc) { TIntermTyped *node = addBinaryMathInternal(op, left, right, loc); if (node == 0) { - binaryOpError(loc, GetOperatorString(op), left->getCompleteString(), right->getCompleteString()); + binaryOpError(loc, GetOperatorString(op), left->getCompleteString(), + right->getCompleteString()); recover(); TConstantUnion *unionArray = new TConstantUnion[1]; unionArray->setBConst(false); - return intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), loc); + return intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), + loc); } return node; } -TIntermTyped *TParseContext::createAssign(TOperator op, TIntermTyped *left, TIntermTyped *right, - const TSourceLoc &loc) +TIntermTyped *TParseContext::createAssign(TOperator op, + TIntermTyped *left, + TIntermTyped *right, + const TSourceLoc &loc) { if (binaryOpCommonCheck(op, left, right, loc)) { @@ -3081,8 +3782,10 @@ TIntermTyped *TParseContext::createAssign(TOperator op, TIntermTyped *left, TInt return nullptr; } -TIntermTyped *TParseContext::addAssign(TOperator op, TIntermTyped *left, TIntermTyped *right, - const TSourceLoc &loc) +TIntermTyped *TParseContext::addAssign(TOperator op, + TIntermTyped *left, + TIntermTyped *right, + const TSourceLoc &loc) { TIntermTyped *node = createAssign(op, left, right, loc); if (node == nullptr) @@ -3094,48 +3797,57 @@ TIntermTyped *TParseContext::addAssign(TOperator op, TIntermTyped *left, TInterm return node; } +TIntermTyped *TParseContext::addComma(TIntermTyped *left, + TIntermTyped *right, + const TSourceLoc &loc) +{ + return intermediate.addComma(left, right, loc, mShaderVersion); +} + TIntermBranch *TParseContext::addBranch(TOperator op, const TSourceLoc &loc) { switch (op) { - case EOpContinue: - if (mLoopNestingLevel <= 0) - { - error(loc, "continue statement only allowed in loops", ""); - recover(); - } - break; - case EOpBreak: - if (mLoopNestingLevel <= 0 && mSwitchNestingLevel <= 0) - { - error(loc, "break statement only allowed in loops and switch statements", ""); - recover(); - } - break; - case EOpReturn: - if (currentFunctionType->getBasicType() != EbtVoid) - { - error(loc, "non-void function must return a value", "return"); - recover(); - } - break; - default: - // No checks for discard - break; + case EOpContinue: + if (mLoopNestingLevel <= 0) + { + error(loc, "continue statement only allowed in loops", ""); + recover(); + } + break; + case EOpBreak: + if (mLoopNestingLevel <= 0 && mSwitchNestingLevel <= 0) + { + error(loc, "break statement only allowed in loops and switch statements", ""); + recover(); + } + break; + case EOpReturn: + if (mCurrentFunctionType->getBasicType() != EbtVoid) + { + error(loc, "non-void function must return a value", "return"); + recover(); + } + break; + default: + // No checks for discard + break; } return intermediate.addBranch(op, loc); } -TIntermBranch *TParseContext::addBranch(TOperator op, TIntermTyped *returnValue, const TSourceLoc &loc) +TIntermBranch *TParseContext::addBranch(TOperator op, + TIntermTyped *returnValue, + const TSourceLoc &loc) { ASSERT(op == EOpReturn); mFunctionReturnsValue = true; - if (currentFunctionType->getBasicType() == EbtVoid) + if (mCurrentFunctionType->getBasicType() == EbtVoid) { error(loc, "void function cannot return a value", "return"); recover(); } - else if (*currentFunctionType != returnValue->getType()) + else if (*mCurrentFunctionType != returnValue->getType()) { error(loc, "function return is not matching type:", "return"); recover(); @@ -3143,17 +3855,73 @@ TIntermBranch *TParseContext::addBranch(TOperator op, TIntermTyped *returnValue, return intermediate.addBranch(op, returnValue, loc); } -TIntermTyped *TParseContext::addFunctionCallOrMethod(TFunction *fnCall, TIntermNode *paramNode, TIntermNode *thisNode, - const TSourceLoc &loc, bool *fatalError) +void TParseContext::checkTextureOffsetConst(TIntermAggregate *functionCall) +{ + ASSERT(!functionCall->isUserDefined()); + const TString &name = functionCall->getName(); + TIntermNode *offset = nullptr; + TIntermSequence *arguments = functionCall->getSequence(); + if (name.compare(0, 16, "texelFetchOffset") == 0 || + name.compare(0, 16, "textureLodOffset") == 0 || + name.compare(0, 20, "textureProjLodOffset") == 0 || + name.compare(0, 17, "textureGradOffset") == 0 || + name.compare(0, 21, "textureProjGradOffset") == 0) + { + offset = arguments->back(); + } + else if (name.compare(0, 13, "textureOffset") == 0 || + name.compare(0, 17, "textureProjOffset") == 0) + { + // A bias parameter might follow the offset parameter. + ASSERT(arguments->size() >= 3); + offset = (*arguments)[2]; + } + if (offset != nullptr) + { + TIntermConstantUnion *offsetConstantUnion = offset->getAsConstantUnion(); + if (offset->getAsTyped()->getQualifier() != EvqConst || !offsetConstantUnion) + { + TString unmangledName = TFunction::unmangleName(name); + error(functionCall->getLine(), "Texture offset must be a constant expression", + unmangledName.c_str()); + recover(); + } + else + { + ASSERT(offsetConstantUnion->getBasicType() == EbtInt); + size_t size = offsetConstantUnion->getType().getObjectSize(); + const TConstantUnion *values = offsetConstantUnion->getUnionArrayPointer(); + for (size_t i = 0u; i < size; ++i) + { + int offsetValue = values[i].getIConst(); + if (offsetValue > mMaxProgramTexelOffset || offsetValue < mMinProgramTexelOffset) + { + std::stringstream tokenStream; + tokenStream << offsetValue; + std::string token = tokenStream.str(); + error(offset->getLine(), "Texture offset value out of valid range", + token.c_str()); + recover(); + } + } + } + } +} + +TIntermTyped *TParseContext::addFunctionCallOrMethod(TFunction *fnCall, + TIntermNode *paramNode, + TIntermNode *thisNode, + const TSourceLoc &loc, + bool *fatalError) { - *fatalError = false; - TOperator op = fnCall->getBuiltInOp(); + *fatalError = false; + TOperator op = fnCall->getBuiltInOp(); TIntermTyped *callNode = nullptr; if (thisNode != nullptr) { TConstantUnion *unionArray = new TConstantUnion[1]; - int arraySize = 0; + int arraySize = 0; TIntermTyped *typedThis = thisNode->getAsTyped(); if (fnCall->getName() != "length") { @@ -3179,15 +3947,19 @@ TIntermTyped *TParseContext::addFunctionCallOrMethod(TFunction *fnCall, TIntermN // (a = b).length() // (func()).length() // (int[3](0, 1, 2)).length() - // ESSL 3.00 section 5.9 defines expressions so that this is not actually a valid expression. - // It allows "An array name with the length method applied" in contrast to GLSL 4.4 spec section 5.9 - // which allows "An array, vector or matrix expression with the length method applied". - error(loc, "length can only be called on array names, not on array expressions", "length"); + // ESSL 3.00 section 5.9 defines expressions so that this is not actually a valid + // expression. + // It allows "An array name with the length method applied" in contrast to GLSL 4.4 + // spec section 5.9 which allows "An array, vector or matrix expression with the + // length method applied". + error(loc, "length can only be called on array names, not on array expressions", + "length"); recover(); } } unionArray->setIConst(arraySize); - callNode = intermediate.addConstantUnion(unionArray, TType(EbtInt, EbpUndefined, EvqConst), loc); + callNode = + intermediate.addConstantUnion(unionArray, TType(EbtInt, EbpUndefined, EvqConst), loc); } else if (op != EOpNull) { @@ -3217,9 +3989,9 @@ TIntermTyped *TParseContext::addFunctionCallOrMethod(TFunction *fnCall, TIntermN // // Not a constructor. Find it in the symbol table. // - const TFunction* fnCandidate; + const TFunction *fnCandidate; bool builtIn; - fnCandidate = findFunction(loc, fnCall, shaderVersion, &builtIn); + fnCandidate = findFunction(loc, fnCall, mShaderVersion, &builtIn); if (fnCandidate) { // @@ -3241,38 +4013,61 @@ TIntermTyped *TParseContext::addFunctionCallOrMethod(TFunction *fnCall, TIntermN // // Treat it like a built-in unary operator. // - callNode = createUnaryMath(op, paramNode->getAsTyped(), loc, &fnCandidate->getReturnType()); + TIntermAggregate *paramAgg = paramNode->getAsAggregate(); + paramNode = paramAgg->getSequence()->front(); + callNode = createUnaryMath(op, paramNode->getAsTyped(), loc, + &fnCandidate->getReturnType()); if (callNode == nullptr) { std::stringstream extraInfoStream; - extraInfoStream << "built in unary operator function. Type: " - << static_cast(paramNode)->getCompleteString(); + extraInfoStream + << "built in unary operator function. Type: " + << static_cast(paramNode)->getCompleteString(); std::string extraInfo = extraInfoStream.str(); - error(paramNode->getLine(), " wrong operand type", "Internal Error", extraInfo.c_str()); + error(paramNode->getLine(), " wrong operand type", "Internal Error", + extraInfo.c_str()); *fatalError = true; return nullptr; } } else { - TIntermAggregate *aggregate = intermediate.setAggregateOperator(paramNode, op, loc); + TIntermAggregate *aggregate = + intermediate.setAggregateOperator(paramNode, op, loc); aggregate->setType(fnCandidate->getReturnType()); aggregate->setPrecisionFromChildren(); - callNode = aggregate; + if (aggregate->areChildrenConstQualified()) + { + aggregate->getTypePointer()->setQualifier(EvqConst); + } // Some built-in functions have out parameters too. functionCallLValueErrorCheck(fnCandidate, aggregate); + + // See if we can constant fold a built-in. Note that this may be possible even + // if it is not const-qualified. + TIntermTyped *foldedNode = intermediate.foldAggregateBuiltIn(aggregate); + if (foldedNode) + { + callNode = foldedNode; + } + else + { + callNode = aggregate; + } } } else { // This is a real function call - - TIntermAggregate *aggregate = intermediate.setAggregateOperator(paramNode, EOpFunctionCall, loc); + TIntermAggregate *aggregate = + intermediate.setAggregateOperator(paramNode, EOpFunctionCall, loc); aggregate->setType(fnCandidate->getReturnType()); - // this is how we know whether the given function is a builtIn function or a user defined function - // if builtIn == false, it's a userDefined -> could be an overloaded builtIn function also + // this is how we know whether the given function is a builtIn function or a user + // defined function + // if builtIn == false, it's a userDefined -> could be an overloaded + // builtIn function also // if builtIn == true, it's definitely a builtIn function with EOpNull if (!builtIn) aggregate->setUserDefined(); @@ -3281,8 +4076,12 @@ TIntermTyped *TParseContext::addFunctionCallOrMethod(TFunction *fnCall, TIntermN // This needs to happen after the name is set if (builtIn) + { aggregate->setBuiltInFunctionPrecision(); + checkTextureOffsetConst(aggregate); + } + callNode = aggregate; functionCallLValueErrorCheck(fnCandidate, aggregate); @@ -3294,15 +4093,17 @@ TIntermTyped *TParseContext::addFunctionCallOrMethod(TFunction *fnCall, TIntermN // Put on a dummy node for error recovery TConstantUnion *unionArray = new TConstantUnion[1]; unionArray->setFConst(0.0f); - callNode = intermediate.addConstantUnion(unionArray, TType(EbtFloat, EbpUndefined, EvqConst), loc); + callNode = intermediate.addConstantUnion(unionArray, + TType(EbtFloat, EbpUndefined, EvqConst), loc); recover(); } } - delete fnCall; return callNode; } -TIntermTyped *TParseContext::addTernarySelection(TIntermTyped *cond, TIntermTyped *trueBlock, TIntermTyped *falseBlock, +TIntermTyped *TParseContext::addTernarySelection(TIntermTyped *cond, + TIntermTyped *trueBlock, + TIntermTyped *falseBlock, const TSourceLoc &loc) { if (boolErrorCheck(loc, cond)) @@ -3331,8 +4132,11 @@ TIntermTyped *TParseContext::addTernarySelection(TIntermTyped *cond, TIntermType // // Returns 0 for success. // -int PaParseStrings(size_t count, const char* const string[], const int length[], - TParseContext* context) { +int PaParseStrings(size_t count, + const char *const string[], + const int length[], + TParseContext *context) +{ if ((count == 0) || (string == NULL)) return 1; @@ -3347,6 +4151,3 @@ int PaParseStrings(size_t count, const char* const string[], const int length[], return (error == 0) && (context->numErrors() == 0) ? 0 : 1; } - - - diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/ParseContext.h b/Source/ThirdParty/ANGLE/src/compiler/translator/ParseContext.h index c837fdf0e555..1eaf1e5b422b 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/ParseContext.h +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/ParseContext.h @@ -9,11 +9,12 @@ #include "compiler/translator/Compiler.h" #include "compiler/translator/Diagnostics.h" #include "compiler/translator/DirectiveHandler.h" -#include "compiler/translator/intermediate.h" +#include "compiler/translator/Intermediate.h" #include "compiler/translator/SymbolTable.h" #include "compiler/preprocessor/Preprocessor.h" -struct TMatrixFields { +struct TMatrixFields +{ bool wholeRow; bool wholeCol; int row; @@ -24,162 +25,275 @@ struct TMatrixFields { // The following are extra variables needed during parsing, grouped together so // they can be passed to the parser without needing a global. // -struct TParseContext { - TParseContext(TSymbolTable& symt, TExtensionBehavior& ext, TIntermediate& interm, sh::GLenum type, ShShaderSpec spec, int options, bool checksPrecErrors, TInfoSink& is, bool debugShaderPrecisionSupported) : - intermediate(interm), - symbolTable(symt), - shaderType(type), - shaderSpec(spec), - compileOptions(options), - treeRoot(0), - mLoopNestingLevel(0), - structNestingLevel(0), - mSwitchNestingLevel(0), - currentFunctionType(NULL), - mFunctionReturnsValue(false), - checksPrecisionErrors(checksPrecErrors), - fragmentPrecisionHigh(false), - defaultMatrixPacking(EmpColumnMajor), - defaultBlockStorage(EbsShared), - diagnostics(is), - shaderVersion(100), - directiveHandler(ext, diagnostics, shaderVersion, debugShaderPrecisionSupported), - preprocessor(&diagnostics, &directiveHandler), - scanner(NULL), - mDeferredSingleDeclarationErrorCheck(false) +class TParseContext : angle::NonCopyable +{ + public: + TParseContext(TSymbolTable &symt, + TExtensionBehavior &ext, + TIntermediate &interm, + sh::GLenum type, + ShShaderSpec spec, + int options, + bool checksPrecErrors, + TInfoSink &is, + const ShBuiltInResources &resources) + : intermediate(interm), + symbolTable(symt), + mDeferredSingleDeclarationErrorCheck(false), + mShaderType(type), + mShaderSpec(spec), + mShaderVersion(100), + mTreeRoot(nullptr), + mLoopNestingLevel(0), + mStructNestingLevel(0), + mSwitchNestingLevel(0), + mCurrentFunctionType(nullptr), + mFunctionReturnsValue(false), + mChecksPrecisionErrors(checksPrecErrors), + mFragmentPrecisionHighOnESSL1(false), + mDefaultMatrixPacking(EmpColumnMajor), + mDefaultBlockStorage(EbsShared), + mDiagnostics(is), + mDirectiveHandler(ext, + mDiagnostics, + mShaderVersion, + mShaderType, + resources.WEBGL_debug_shader_precision == 1), + mPreprocessor(&mDiagnostics, &mDirectiveHandler), + mScanner(nullptr), + mUsesFragData(false), + mUsesFragColor(false), + mUsesSecondaryOutputs(false), + mMinProgramTexelOffset(resources.MinProgramTexelOffset), + mMaxProgramTexelOffset(resources.MaxProgramTexelOffset) { } - TIntermediate& intermediate; // to hold and build a parse tree - TSymbolTable& symbolTable; // symbol table that goes with the language currently being parsed - sh::GLenum shaderType; // vertex or fragment language (future: pack or unpack) - ShShaderSpec shaderSpec; // The language specification compiler conforms to - GLES2 or WebGL. - int shaderVersion; - int compileOptions; - TIntermNode* treeRoot; // root of parse tree being created - int mLoopNestingLevel; // 0 if outside all loops - int structNestingLevel; // incremented while parsing a struct declaration - int mSwitchNestingLevel; // 0 if outside all switch statements - const TType* currentFunctionType; // the return type of the function that's currently being parsed - bool mFunctionReturnsValue; // true if a non-void function has a return - bool checksPrecisionErrors; // true if an error will be generated when a variable is declared without precision, explicit or implicit. - bool fragmentPrecisionHigh; // true if highp precision is supported in the fragment language. - TLayoutMatrixPacking defaultMatrixPacking; - TLayoutBlockStorage defaultBlockStorage; - TString HashErrMsg; - TDiagnostics diagnostics; - TDirectiveHandler directiveHandler; - pp::Preprocessor preprocessor; - void* scanner; - - int getShaderVersion() const { return shaderVersion; } - int numErrors() const { return diagnostics.numErrors(); } - TInfoSink& infoSink() { return diagnostics.infoSink(); } - void error(const TSourceLoc& loc, const char *reason, const char* token, - const char* extraInfo=""); - void warning(const TSourceLoc& loc, const char* reason, const char* token, - const char* extraInfo=""); + + const pp::Preprocessor &getPreprocessor() const { return mPreprocessor; } + pp::Preprocessor &getPreprocessor() { return mPreprocessor; } + void *getScanner() const { return mScanner; } + void setScanner(void *scanner) { mScanner = scanner; } + int getShaderVersion() const { return mShaderVersion; } + sh::GLenum getShaderType() const { return mShaderType; } + ShShaderSpec getShaderSpec() const { return mShaderSpec; } + int numErrors() const { return mDiagnostics.numErrors(); } + TInfoSink &infoSink() { return mDiagnostics.infoSink(); } + void error(const TSourceLoc &loc, const char *reason, const char *token, + const char *extraInfo=""); + void warning(const TSourceLoc &loc, const char *reason, const char *token, + const char *extraInfo=""); + + // If isError is false, a warning will be reported instead. + void outOfRangeError(bool isError, + const TSourceLoc &loc, + const char *reason, + const char *token, + const char *extraInfo = ""); + void recover(); + TIntermNode *getTreeRoot() const { return mTreeRoot; } + void setTreeRoot(TIntermNode *treeRoot) { mTreeRoot = treeRoot; } + + bool getFragmentPrecisionHigh() const + { + return mFragmentPrecisionHighOnESSL1 || mShaderVersion >= 300; + } + void setFragmentPrecisionHighOnESSL1(bool fragmentPrecisionHigh) + { + mFragmentPrecisionHighOnESSL1 = fragmentPrecisionHigh; + } + + void setLoopNestingLevel(int loopNestintLevel) + { + mLoopNestingLevel = loopNestintLevel; + } + + void incrLoopNestingLevel() { ++mLoopNestingLevel; } + void decrLoopNestingLevel() { --mLoopNestingLevel; } + + void incrSwitchNestingLevel() { ++mSwitchNestingLevel; } + void decrSwitchNestingLevel() { --mSwitchNestingLevel; } // This method is guaranteed to succeed, even if no variable with 'name' exists. const TVariable *getNamedVariable(const TSourceLoc &location, const TString *name, const TSymbol *symbol); - - bool parseVectorFields(const TString&, int vecSize, TVectorFields&, const TSourceLoc& line); - bool parseMatrixFields(const TString&, int matCols, int matRows, TMatrixFields&, const TSourceLoc& line); - - bool reservedErrorCheck(const TSourceLoc& line, const TString& identifier); - void assignError(const TSourceLoc& line, const char* op, TString left, TString right); - void unaryOpError(const TSourceLoc& line, const char* op, TString operand); - void binaryOpError(const TSourceLoc& line, const char* op, TString left, TString right); - bool precisionErrorCheck(const TSourceLoc& line, TPrecision precision, TBasicType type); - bool lValueErrorCheck(const TSourceLoc& line, const char* op, TIntermTyped*); - bool constErrorCheck(TIntermTyped* node); - bool integerErrorCheck(TIntermTyped* node, const char* token); - bool globalErrorCheck(const TSourceLoc& line, bool global, const char* token); - bool constructorErrorCheck(const TSourceLoc& line, TIntermNode*, TFunction&, TOperator, TType*); - bool arraySizeErrorCheck(const TSourceLoc& line, TIntermTyped* expr, int& size); + TIntermTyped *parseVariableIdentifier(const TSourceLoc &location, + const TString *name, + const TSymbol *symbol); + + bool parseVectorFields(const TString&, int vecSize, TVectorFields&, const TSourceLoc &line); + + bool reservedErrorCheck(const TSourceLoc &line, const TString &identifier); + void assignError(const TSourceLoc &line, const char *op, TString left, TString right); + void unaryOpError(const TSourceLoc &line, const char *op, TString operand); + void binaryOpError(const TSourceLoc &line, const char *op, TString left, TString right); + bool precisionErrorCheck(const TSourceLoc &line, TPrecision precision, TBasicType type); + bool lValueErrorCheck(const TSourceLoc &line, const char *op, TIntermTyped*); + bool constErrorCheck(TIntermTyped *node); + bool integerErrorCheck(TIntermTyped *node, const char *token); + bool globalErrorCheck(const TSourceLoc &line, bool global, const char *token); + bool constructorErrorCheck(const TSourceLoc &line, + TIntermNode *argumentsNode, + TFunction &function, + TOperator op, + TType *type); + bool arraySizeErrorCheck(const TSourceLoc &line, TIntermTyped *expr, int &size); bool arrayQualifierErrorCheck(const TSourceLoc &line, const TPublicType &type); - bool arrayTypeErrorCheck(const TSourceLoc& line, TPublicType type); + bool arrayTypeErrorCheck(const TSourceLoc &line, const TPublicType &type); bool voidErrorCheck(const TSourceLoc &line, const TString &identifier, const TBasicType &type); bool boolErrorCheck(const TSourceLoc&, const TIntermTyped*); bool boolErrorCheck(const TSourceLoc&, const TPublicType&); - bool samplerErrorCheck(const TSourceLoc& line, const TPublicType& pType, const char* reason); - bool locationDeclaratorListCheck(const TSourceLoc& line, const TPublicType &pType); - bool parameterSamplerErrorCheck(const TSourceLoc& line, TQualifier qualifier, const TType& type); - bool paramErrorCheck(const TSourceLoc& line, TQualifier qualifier, TQualifier paramQualifier, TType* type); - bool extensionErrorCheck(const TSourceLoc& line, const TString&); - bool singleDeclarationErrorCheck(TPublicType &publicType, const TSourceLoc &identifierLocation); - bool layoutLocationErrorCheck(const TSourceLoc& location, const TLayoutQualifier &layoutQualifier); + bool samplerErrorCheck(const TSourceLoc &line, const TPublicType &pType, const char *reason); + bool locationDeclaratorListCheck(const TSourceLoc &line, const TPublicType &pType); + bool parameterSamplerErrorCheck(const TSourceLoc &line, TQualifier qualifier, const TType &type); + bool paramErrorCheck(const TSourceLoc &line, TQualifier qualifier, TQualifier paramQualifier, TType *type); + bool extensionErrorCheck(const TSourceLoc &line, const TString&); + bool singleDeclarationErrorCheck(const TPublicType &publicType, const TSourceLoc &identifierLocation); + bool layoutLocationErrorCheck(const TSourceLoc &location, const TLayoutQualifier &layoutQualifier); bool functionCallLValueErrorCheck(const TFunction *fnCandidate, TIntermAggregate *); - - const TPragma& pragma() const { return directiveHandler.pragma(); } - const TExtensionBehavior& extensionBehavior() const { return directiveHandler.extensionBehavior(); } - bool supportsExtension(const char* extension); - bool isExtensionEnabled(const char* extension) const; - void handleExtensionDirective(const TSourceLoc& loc, const char* extName, const char* behavior); - void handlePragmaDirective(const TSourceLoc& loc, const char* name, const char* value, bool stdgl); - - bool containsSampler(TType& type); - bool areAllChildConst(TIntermAggregate* aggrNode); - const TFunction* findFunction(const TSourceLoc& line, TFunction* pfnCall, int inputShaderVersion, bool *builtIn = 0); - bool executeInitializer(const TSourceLoc &line, const TString &identifier, TPublicType &pType, - TIntermTyped *initializer, TIntermNode **intermNode); - - TPublicType addFullySpecifiedType(TQualifier qualifier, const TPublicType& typeSpecifier); - TPublicType addFullySpecifiedType(TQualifier qualifier, TLayoutQualifier layoutQualifier, const TPublicType& typeSpecifier); + void es3InvariantErrorCheck(const TQualifier qualifier, const TSourceLoc &invariantLocation); + void es3InputOutputTypeCheck(const TQualifier qualifier, + const TPublicType &type, + const TSourceLoc &qualifierLocation); + + const TPragma &pragma() const { return mDirectiveHandler.pragma(); } + const TExtensionBehavior &extensionBehavior() const { return mDirectiveHandler.extensionBehavior(); } + bool supportsExtension(const char *extension); + bool isExtensionEnabled(const char *extension) const; + void handleExtensionDirective(const TSourceLoc &loc, const char *extName, const char *behavior); + void handlePragmaDirective(const TSourceLoc &loc, const char *name, const char *value, bool stdgl); + + bool containsSampler(const TType &type); + const TFunction* findFunction( + const TSourceLoc &line, TFunction *pfnCall, int inputShaderVersion, bool *builtIn = 0); + bool executeInitializer(const TSourceLoc &line, + const TString &identifier, + const TPublicType &pType, + TIntermTyped *initializer, + TIntermNode **intermNode); + + TPublicType addFullySpecifiedType(TQualifier qualifier, + bool invariant, + TLayoutQualifier layoutQualifier, + const TPublicType &typeSpecifier); TIntermAggregate *parseSingleDeclaration(TPublicType &publicType, - const TSourceLoc &identifierOrTypeLocation, const TString &identifier); + const TSourceLoc &identifierOrTypeLocation, + const TString &identifier); TIntermAggregate *parseSingleArrayDeclaration(TPublicType &publicType, - const TSourceLoc &identifierLocation, const TString &identifier, - const TSourceLoc &indexLocation, TIntermTyped *indexExpression); - TIntermAggregate *parseSingleInitDeclaration(TPublicType &publicType, - const TSourceLoc &identifierLocation, const TString &identifier, - const TSourceLoc &initLocation, TIntermTyped *initializer); + const TSourceLoc &identifierLocation, + const TString &identifier, + const TSourceLoc &indexLocation, + TIntermTyped *indexExpression); + TIntermAggregate *parseSingleInitDeclaration(const TPublicType &publicType, + const TSourceLoc &identifierLocation, + const TString &identifier, + const TSourceLoc &initLocation, + TIntermTyped *initializer); // Parse a declaration like "type a[n] = initializer" // Note that this does not apply to declarations like "type[n] a = initializer" TIntermAggregate *parseSingleArrayInitDeclaration(TPublicType &publicType, - const TSourceLoc &identifierLocation, const TString &identifier, - const TSourceLoc &indexLocation, TIntermTyped *indexExpression, - const TSourceLoc &initLocation, TIntermTyped *initializer); - - TIntermAggregate *parseInvariantDeclaration(const TSourceLoc &invariantLoc, const TSourceLoc &identifierLoc, - const TString *identifier, const TSymbol *symbol); - - TIntermAggregate *parseDeclarator(TPublicType &publicType, TIntermAggregate *aggregateDeclaration, - const TSourceLoc &identifierLocation, const TString &identifier); - TIntermAggregate *parseArrayDeclarator(TPublicType &publicType, TIntermAggregate *aggregateDeclaration, - const TSourceLoc &identifierLocation, const TString &identifier, - const TSourceLoc &arrayLocation, TIntermTyped *indexExpression); - TIntermAggregate *parseInitDeclarator(TPublicType &publicType, TIntermAggregate *aggregateDeclaration, - const TSourceLoc &identifierLocation, const TString &identifier, - const TSourceLoc &initLocation, TIntermTyped *initializer); + const TSourceLoc &identifierLocation, + const TString &identifier, + const TSourceLoc &indexLocation, + TIntermTyped *indexExpression, + const TSourceLoc &initLocation, + TIntermTyped *initializer); + + TIntermAggregate *parseInvariantDeclaration(const TSourceLoc &invariantLoc, + const TSourceLoc &identifierLoc, + const TString *identifier, + const TSymbol *symbol); + + TIntermAggregate *parseDeclarator(TPublicType &publicType, + TIntermAggregate *aggregateDeclaration, + const TSourceLoc &identifierLocation, + const TString &identifier); + TIntermAggregate *parseArrayDeclarator(TPublicType &publicType, + TIntermAggregate *aggregateDeclaration, + const TSourceLoc &identifierLocation, + const TString &identifier, + const TSourceLoc &arrayLocation, + TIntermTyped *indexExpression); + TIntermAggregate *parseInitDeclarator(const TPublicType &publicType, + TIntermAggregate *aggregateDeclaration, + const TSourceLoc &identifierLocation, + const TString &identifier, + const TSourceLoc &initLocation, + TIntermTyped *initializer); // Parse a declarator like "a[n] = initializer" - TIntermAggregate *parseArrayInitDeclarator(TPublicType &publicType, TIntermAggregate *aggregateDeclaration, - const TSourceLoc& identifierLocation, const TString &identifier, - const TSourceLoc& indexLocation, TIntermTyped *indexExpression, - const TSourceLoc &initLocation, TIntermTyped *initializer); + TIntermAggregate *parseArrayInitDeclarator(const TPublicType &publicType, + TIntermAggregate *aggregateDeclaration, + const TSourceLoc &identifierLocation, + const TString &identifier, + const TSourceLoc &indexLocation, + TIntermTyped *indexExpression, + const TSourceLoc &initLocation, + TIntermTyped *initializer); void parseGlobalLayoutQualifier(const TPublicType &typeQualifier); - TFunction *addConstructorFunc(TPublicType publicType); - TIntermTyped* addConstructor(TIntermNode*, TType*, TOperator, TFunction*, const TSourceLoc&); - TIntermTyped* foldConstConstructor(TIntermAggregate* aggrNode, const TType& type); - TIntermTyped* addConstVectorNode(TVectorFields&, TIntermTyped*, const TSourceLoc&); - TIntermTyped* addConstMatrixNode(int , TIntermTyped*, const TSourceLoc&); - TIntermTyped* addConstArrayNode(int index, TIntermTyped* node, const TSourceLoc& line); - TIntermTyped* addConstStruct(const TString &identifier, TIntermTyped *node, const TSourceLoc& line); - TIntermTyped* addIndexExpression(TIntermTyped *baseExpression, const TSourceLoc& location, TIntermTyped *indexExpression); - TIntermTyped* addFieldSelectionExpression(TIntermTyped *baseExpression, const TSourceLoc& dotLocation, const TString &fieldString, const TSourceLoc& fieldLocation); - - TFieldList *addStructDeclaratorList(const TPublicType& typeSpecifier, TFieldList *fieldList); - TPublicType addStructure(const TSourceLoc& structLine, const TSourceLoc& nameLine, const TString *structName, TFieldList* fieldList); - - TIntermAggregate* addInterfaceBlock(const TPublicType& typeQualifier, const TSourceLoc& nameLine, const TString& blockName, TFieldList* fieldList, - const TString* instanceName, const TSourceLoc& instanceLine, TIntermTyped* arrayIndex, const TSourceLoc& arrayIndexLine); - - TLayoutQualifier parseLayoutQualifier(const TString &qualifierType, const TSourceLoc& qualifierTypeLine); - TLayoutQualifier parseLayoutQualifier(const TString &qualifierType, const TSourceLoc& qualifierTypeLine, const TString &intValueString, int intValue, const TSourceLoc& intValueLine); + TIntermAggregate *addFunctionPrototypeDeclaration(const TFunction &function, + const TSourceLoc &location); + TIntermAggregate *addFunctionDefinition(const TFunction &function, + TIntermAggregate *functionPrototype, + TIntermAggregate *functionBody, + const TSourceLoc &location); + void parseFunctionPrototype(const TSourceLoc &location, + TFunction *function, + TIntermAggregate **aggregateOut); + TFunction *parseFunctionDeclarator(const TSourceLoc &location, + TFunction *function); + TFunction *addConstructorFunc(const TPublicType &publicType); + TIntermTyped *addConstructor(TIntermNode *arguments, + TType *type, + TOperator op, + TFunction *fnCall, + const TSourceLoc &line); + TIntermTyped *addConstVectorNode(TVectorFields &fields, + TIntermConstantUnion *node, + const TSourceLoc &line, + bool outOfRangeIndexIsError); + TIntermTyped *addConstMatrixNode(int index, + TIntermConstantUnion *node, + const TSourceLoc &line, + bool outOfRangeIndexIsError); + TIntermTyped *addConstArrayNode(int index, + TIntermConstantUnion *node, + const TSourceLoc &line, + bool outOfRangeIndexIsError); + TIntermTyped *addConstStruct( + const TString &identifier, TIntermTyped *node, const TSourceLoc& line); + TIntermTyped *addIndexExpression(TIntermTyped *baseExpression, + const TSourceLoc& location, + TIntermTyped *indexExpression); + TIntermTyped* addFieldSelectionExpression(TIntermTyped *baseExpression, + const TSourceLoc &dotLocation, + const TString &fieldString, + const TSourceLoc &fieldLocation); + + TFieldList *addStructDeclaratorList(const TPublicType &typeSpecifier, TFieldList *fieldList); + TPublicType addStructure(const TSourceLoc &structLine, + const TSourceLoc &nameLine, + const TString *structName, + TFieldList *fieldList); + + TIntermAggregate* addInterfaceBlock(const TPublicType &typeQualifier, + const TSourceLoc &nameLine, + const TString &blockName, + TFieldList *fieldList, + const TString *instanceName, + const TSourceLoc &instanceLine, + TIntermTyped *arrayIndex, + const TSourceLoc& arrayIndexLine); + + TLayoutQualifier parseLayoutQualifier( + const TString &qualifierType, const TSourceLoc &qualifierTypeLine); + TLayoutQualifier parseLayoutQualifier(const TString &qualifierType, + const TSourceLoc &qualifierTypeLine, + const TString &intValueString, + int intValue, + const TSourceLoc &intValueLine); TLayoutQualifier joinLayoutQualifiers(TLayoutQualifier leftQualifier, TLayoutQualifier rightQualifier); TPublicType joinInterpolationQualifiers(const TSourceLoc &interpolationLoc, TQualifier interpolationQualifier, const TSourceLoc &storageLoc, TQualifier storageQualifier); @@ -187,56 +301,92 @@ struct TParseContext { // Performs an error check for embedded struct declarations. // Returns true if an error was raised due to the declaration of // this struct. - bool enterStructDeclaration(const TSourceLoc& line, const TString& identifier); + bool enterStructDeclaration(const TSourceLoc &line, const TString &identifier); void exitStructDeclaration(); - bool structNestingErrorCheck(const TSourceLoc& line, const TField& field); + bool structNestingErrorCheck(const TSourceLoc &line, const TField &field); TIntermSwitch *addSwitch(TIntermTyped *init, TIntermAggregate *statementList, const TSourceLoc &loc); TIntermCase *addCase(TIntermTyped *condition, const TSourceLoc &loc); TIntermCase *addDefault(const TSourceLoc &loc); - TIntermTyped *addUnaryMath(TOperator op, TIntermTyped *child, const TSourceLoc &); - TIntermTyped *addUnaryMathLValue(TOperator op, TIntermTyped *child, const TSourceLoc &); - TIntermTyped *addBinaryMath(TOperator op, TIntermTyped *left, TIntermTyped *right, - const TSourceLoc &); - TIntermTyped *addBinaryMathBooleanResult(TOperator op, TIntermTyped *left, TIntermTyped *right, - const TSourceLoc &); - TIntermTyped *addAssign(TOperator op, TIntermTyped *left, TIntermTyped *right, - const TSourceLoc &loc); + TIntermTyped *addUnaryMath(TOperator op, TIntermTyped *child, const TSourceLoc &loc); + TIntermTyped *addUnaryMathLValue(TOperator op, TIntermTyped *child, const TSourceLoc &loc); + TIntermTyped *addBinaryMath( + TOperator op, TIntermTyped *left, TIntermTyped *right, const TSourceLoc &loc); + TIntermTyped *addBinaryMathBooleanResult( + TOperator op, TIntermTyped *left, TIntermTyped *right, const TSourceLoc &loc); + TIntermTyped *addAssign( + TOperator op, TIntermTyped *left, TIntermTyped *right, const TSourceLoc &loc); + + TIntermTyped *addComma(TIntermTyped *left, TIntermTyped *right, const TSourceLoc &loc); TIntermBranch *addBranch(TOperator op, const TSourceLoc &loc); TIntermBranch *addBranch(TOperator op, TIntermTyped *returnValue, const TSourceLoc &loc); - TIntermTyped *addFunctionCallOrMethod(TFunction *fnCall, TIntermNode *paramNode, TIntermNode *thisNode, - const TSourceLoc &loc, bool *fatalError); + void checkTextureOffsetConst(TIntermAggregate *functionCall); + TIntermTyped *addFunctionCallOrMethod(TFunction *fnCall, + TIntermNode *paramNode, + TIntermNode *thisNode, + const TSourceLoc &loc, + bool *fatalError); + + TIntermTyped *addTernarySelection( + TIntermTyped *cond, TIntermTyped *trueBlock, TIntermTyped *falseBlock, const TSourceLoc &line); - TIntermTyped *addTernarySelection(TIntermTyped *cond, TIntermTyped *trueBlock, TIntermTyped *falseBlock, - const TSourceLoc &line); + // TODO(jmadill): make these private + TIntermediate &intermediate; // to hold and build a parse tree + TSymbolTable &symbolTable; // symbol table that goes with the language currently being parsed private: bool declareVariable(const TSourceLoc &line, const TString &identifier, const TType &type, TVariable **variable); bool nonInitErrorCheck(const TSourceLoc &line, const TString &identifier, TPublicType *type); - TIntermTyped *addBinaryMathInternal(TOperator op, TIntermTyped *left, TIntermTyped *right, - const TSourceLoc &loc); - TIntermTyped *createAssign(TOperator op, TIntermTyped *left, TIntermTyped *right, - const TSourceLoc &loc); + TIntermTyped *addBinaryMathInternal( + TOperator op, TIntermTyped *left, TIntermTyped *right, const TSourceLoc &loc); + TIntermTyped *createAssign( + TOperator op, TIntermTyped *left, TIntermTyped *right, const TSourceLoc &loc); // The funcReturnType parameter is expected to be non-null when the operation is a built-in function. // It is expected to be null for other unary operators. - TIntermTyped *createUnaryMath(TOperator op, TIntermTyped *child, const TSourceLoc &loc, - const TType *funcReturnType); + TIntermTyped *createUnaryMath( + TOperator op, TIntermTyped *child, const TSourceLoc &loc, const TType *funcReturnType); // Return true if the checks pass - bool binaryOpCommonCheck(TOperator op, TIntermTyped *left, TIntermTyped *right, - const TSourceLoc &loc); + bool binaryOpCommonCheck( + TOperator op, TIntermTyped *left, TIntermTyped *right, const TSourceLoc &loc); // Set to true when the last/current declarator list was started with an empty declaration. bool mDeferredSingleDeclarationErrorCheck; + + sh::GLenum mShaderType; // vertex or fragment language (future: pack or unpack) + ShShaderSpec mShaderSpec; // The language specification compiler conforms to - GLES2 or WebGL. + int mShaderVersion; + TIntermNode *mTreeRoot; // root of parse tree being created + int mLoopNestingLevel; // 0 if outside all loops + int mStructNestingLevel; // incremented while parsing a struct declaration + int mSwitchNestingLevel; // 0 if outside all switch statements + const TType *mCurrentFunctionType; // the return type of the function that's currently being parsed + bool mFunctionReturnsValue; // true if a non-void function has a return + bool mChecksPrecisionErrors; // true if an error will be generated when a variable is declared without precision, explicit or implicit. + bool mFragmentPrecisionHighOnESSL1; // true if highp precision is supported when compiling + // ESSL1. + TLayoutMatrixPacking mDefaultMatrixPacking; + TLayoutBlockStorage mDefaultBlockStorage; + TString mHashErrMsg; + TDiagnostics mDiagnostics; + TDirectiveHandler mDirectiveHandler; + pp::Preprocessor mPreprocessor; + void *mScanner; + bool mUsesFragData; // track if we are using both gl_FragData and gl_FragColor + bool mUsesFragColor; + bool mUsesSecondaryOutputs; // Track if we are using either gl_SecondaryFragData or + // gl_Secondary FragColor or both. + int mMinProgramTexelOffset; + int mMaxProgramTexelOffset; }; -int PaParseStrings(size_t count, const char* const string[], const int length[], - TParseContext* context); +int PaParseStrings( + size_t count, const char *const string[], const int length[], TParseContext *context); #endif // COMPILER_TRANSLATOR_PARSECONTEXT_H_ diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/PoolAlloc.h b/Source/ThirdParty/ANGLE/src/compiler/translator/PoolAlloc.h index 6cd8d3011440..dab2926c9070 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/PoolAlloc.h +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/PoolAlloc.h @@ -247,18 +247,13 @@ class pool_allocator { pointer address(reference x) const { return &x; } const_pointer address(const_reference x) const { return &x; } - pool_allocator() : allocator(GetGlobalPoolAllocator()) { } - pool_allocator(TPoolAllocator& a) : allocator(&a) { } - pool_allocator(const pool_allocator& p) : allocator(p.allocator) { } - - template - pool_allocator& operator=(const pool_allocator& p) { - allocator = p.allocator; - return *this; - } + pool_allocator() { } template - pool_allocator(const pool_allocator& p) : allocator(&p.getAllocator()) { } + pool_allocator(const pool_allocator& p) { } + + template + pool_allocator& operator=(const pool_allocator& p) { return *this; } #if defined(__SUNPRO_CC) && !defined(_RWSTD_ALLOCATOR) // libCStd on some platforms have a different allocate/deallocate interface. @@ -284,17 +279,13 @@ class pool_allocator { void construct(pointer p, const T& val) { new ((void *)p) T(val); } void destroy(pointer p) { p->T::~T(); } - bool operator==(const pool_allocator& rhs) const { return &getAllocator() == &rhs.getAllocator(); } - bool operator!=(const pool_allocator& rhs) const { return &getAllocator() != &rhs.getAllocator(); } + bool operator==(const pool_allocator& rhs) const { return true; } + bool operator!=(const pool_allocator& rhs) const { return false; } size_type max_size() const { return static_cast(-1) / sizeof(T); } size_type max_size(int size) const { return static_cast(-1) / size; } - void setAllocator(TPoolAllocator* a) { allocator = a; } - TPoolAllocator& getAllocator() const { return *allocator; } - -protected: - TPoolAllocator* allocator; + TPoolAllocator& getAllocator() const { return *GetGlobalPoolAllocator(); } }; #endif // COMPILER_TRANSLATOR_POOLALLOC_H_ diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/QualifierAlive.cpp b/Source/ThirdParty/ANGLE/src/compiler/translator/QualifierAlive.cpp deleted file mode 100644 index 3d950aab5a16..000000000000 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/QualifierAlive.cpp +++ /dev/null @@ -1,58 +0,0 @@ -// -// Copyright (c) 2002-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 "compiler/translator/IntermNode.h" - -class TAliveTraverser : public TIntermTraverser { -public: - TAliveTraverser(TQualifier q) : TIntermTraverser(true, false, false, true), found(false), qualifier(q) - { - } - - bool wasFound() { return found; } - -protected: - bool found; - TQualifier qualifier; - - void visitSymbol(TIntermSymbol*); - bool visitSelection(Visit, TIntermSelection*); -}; - -// -// Report whether or not a variable of the given qualifier type -// is guaranteed written. Not always possible to determine if -// it is written conditionally. -// -// ?? It does not do this well yet, this is just a place holder -// that simply determines if it was reference at all, anywhere. -// -bool QualifierWritten(TIntermNode* node, TQualifier qualifier) -{ - TAliveTraverser it(qualifier); - - if (node) - node->traverse(&it); - - return it.wasFound(); -} - -void TAliveTraverser::visitSymbol(TIntermSymbol* node) -{ - // - // If it's what we're looking for, record it. - // - if (node->getQualifier() == qualifier) - found = true; -} - -bool TAliveTraverser::visitSelection(Visit, TIntermSelection*) -{ - if (wasFound()) - return false; - - return true; -} diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/RecordConstantPrecision.cpp b/Source/ThirdParty/ANGLE/src/compiler/translator/RecordConstantPrecision.cpp new file mode 100644 index 000000000000..14e88b749a71 --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/RecordConstantPrecision.cpp @@ -0,0 +1,157 @@ +// +// Copyright (c) 2002-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. +// +// During parsing, all constant expressions are folded to constant union nodes. The expressions that have been +// folded may have had precision qualifiers, which should affect the precision of the consuming operation. +// If the folded constant union nodes are written to output as such they won't have any precision qualifiers, +// and their effect on the precision of the consuming operation is lost. +// +// RecordConstantPrecision is an AST traverser that inspects the precision qualifiers of constants and hoists +// the constants outside the containing expression as precision qualified named variables in case that is +// required for correct precision propagation. +// + +#include "compiler/translator/RecordConstantPrecision.h" + +#include "compiler/translator/InfoSink.h" +#include "compiler/translator/IntermNode.h" + +namespace +{ + +class RecordConstantPrecisionTraverser : public TIntermTraverser +{ + public: + RecordConstantPrecisionTraverser(); + + void visitConstantUnion(TIntermConstantUnion *node) override; + + void nextIteration(); + + bool foundHigherPrecisionConstant() const { return mFoundHigherPrecisionConstant; } + protected: + bool operandAffectsParentOperationPrecision(TIntermTyped *operand); + + bool mFoundHigherPrecisionConstant; +}; + +RecordConstantPrecisionTraverser::RecordConstantPrecisionTraverser() + : TIntermTraverser(true, false, true), + mFoundHigherPrecisionConstant(false) +{ +} + +bool RecordConstantPrecisionTraverser::operandAffectsParentOperationPrecision(TIntermTyped *operand) +{ + const TIntermBinary *parentAsBinary = getParentNode()->getAsBinaryNode(); + if (parentAsBinary != nullptr) + { + // If the constant is assigned or is used to initialize a variable, or if it's an index, + // its precision has no effect. + switch (parentAsBinary->getOp()) + { + case EOpInitialize: + case EOpAssign: + case EOpIndexDirect: + case EOpIndexDirectStruct: + case EOpIndexDirectInterfaceBlock: + case EOpIndexIndirect: + return false; + default: + break; + } + + TIntermTyped *otherOperand = parentAsBinary->getRight(); + if (otherOperand == operand) + { + otherOperand = parentAsBinary->getLeft(); + } + // If the precision of the other child is at least as high as the precision of the constant, the precision of + // the constant has no effect. + if (otherOperand->getAsConstantUnion() == nullptr && otherOperand->getPrecision() >= operand->getPrecision()) + { + return false; + } + } + + TIntermAggregate *parentAsAggregate = getParentNode()->getAsAggregate(); + if (parentAsAggregate != nullptr) + { + if (!parentAsAggregate->gotPrecisionFromChildren()) + { + // This can be either: + // * a call to an user-defined function + // * a call to a texture function + // * some other kind of aggregate + // In any of these cases the constant precision has no effect. + return false; + } + if (parentAsAggregate->isConstructor() && parentAsAggregate->getBasicType() == EbtBool) + { + return false; + } + // If the precision of operands does affect the result, but the precision of any of the other children + // has a precision that's at least as high as the precision of the constant, the precision of the constant + // has no effect. + TIntermSequence *parameters = parentAsAggregate->getSequence(); + for (TIntermNode *parameter : *parameters) + { + const TIntermTyped *typedParameter = parameter->getAsTyped(); + if (parameter != operand && typedParameter != nullptr && parameter->getAsConstantUnion() == nullptr && + typedParameter->getPrecision() >= operand->getPrecision()) + { + return false; + } + } + } + return true; +} + +void RecordConstantPrecisionTraverser::visitConstantUnion(TIntermConstantUnion *node) +{ + if (mFoundHigherPrecisionConstant) + return; + + // If the constant has lowp or undefined precision, it can't increase the precision of consuming operations. + if (node->getPrecision() < EbpMedium) + return; + + // It's possible the node has no effect on the precision of the consuming expression, depending on the + // consuming expression, and the precision of the other parameters of the expression. + if (!operandAffectsParentOperationPrecision(node)) + return; + + // Make the constant a precision-qualified named variable to make sure it affects the precision of the consuming + // expression. + TIntermSequence insertions; + insertions.push_back(createTempInitDeclaration(node, EvqConst)); + insertStatementsInParentBlock(insertions); + mReplacements.push_back(NodeUpdateEntry(getParentNode(), node, createTempSymbol(node->getType()), false)); + mFoundHigherPrecisionConstant = true; +} + +void RecordConstantPrecisionTraverser::nextIteration() +{ + nextTemporaryIndex(); + mFoundHigherPrecisionConstant = false; +} + +} // namespace + +void RecordConstantPrecision(TIntermNode *root, unsigned int *temporaryIndex) +{ + RecordConstantPrecisionTraverser traverser; + ASSERT(temporaryIndex != nullptr); + traverser.useTemporaryIndex(temporaryIndex); + // Iterate as necessary, and reset the traverser between iterations. + do + { + traverser.nextIteration(); + root->traverse(&traverser); + if (traverser.foundHigherPrecisionConstant()) + traverser.updateTree(); + } + while (traverser.foundHigherPrecisionConstant()); +} diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/RecordConstantPrecision.h b/Source/ThirdParty/ANGLE/src/compiler/translator/RecordConstantPrecision.h new file mode 100644 index 000000000000..2cd401b41817 --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/RecordConstantPrecision.h @@ -0,0 +1,23 @@ +// +// Copyright (c) 2002-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. +// +// During parsing, all constant expressions are folded to constant union nodes. The expressions that have been +// folded may have had precision qualifiers, which should affect the precision of the consuming operation. +// If the folded constant union nodes are written to output as such they won't have any precision qualifiers, +// and their effect on the precision of the consuming operation is lost. +// +// RecordConstantPrecision is an AST traverser that inspects the precision qualifiers of constants and hoists +// the constants outside the containing expression as precision qualified named variables in case that is +// required for correct precision propagation. +// + +#ifndef COMPILER_TRANSLATOR_RECORDCONSTANTPRECISION_H_ +#define COMPILER_TRANSLATOR_RECORDCONSTANTPRECISION_H_ + +class TIntermNode; + +void RecordConstantPrecision(TIntermNode *root, unsigned int *temporaryIndex); + +#endif // COMPILER_TRANSLATOR_RECORDCONSTANTPRECISION_H_ diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/RegenerateStructNames.h b/Source/ThirdParty/ANGLE/src/compiler/translator/RegenerateStructNames.h index 8be2bf68cdac..3b98e5d70956 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/RegenerateStructNames.h +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/RegenerateStructNames.h @@ -7,7 +7,7 @@ #ifndef COMPILER_TRANSLATOR_REGENERATESTRUCTNAMES_H_ #define COMPILER_TRANSLATOR_REGENERATESTRUCTNAMES_H_ -#include "compiler/translator/intermediate.h" +#include "compiler/translator/Intermediate.h" #include "compiler/translator/SymbolTable.h" #include @@ -17,13 +17,14 @@ class RegenerateStructNames : public TIntermTraverser public: RegenerateStructNames(const TSymbolTable &symbolTable, int shaderVersion) - : mSymbolTable(symbolTable), + : TIntermTraverser(true, false, false), + mSymbolTable(symbolTable), mShaderVersion(shaderVersion), mScopeDepth(0) {} protected: - virtual void visitSymbol(TIntermSymbol *); - virtual bool visitAggregate(Visit, TIntermAggregate *); + void visitSymbol(TIntermSymbol *) override; + bool visitAggregate(Visit, TIntermAggregate *) override; private: const TSymbolTable &mSymbolTable; diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/RemoveDynamicIndexing.cpp b/Source/ThirdParty/ANGLE/src/compiler/translator/RemoveDynamicIndexing.cpp new file mode 100644 index 000000000000..74814f22a793 --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/RemoveDynamicIndexing.cpp @@ -0,0 +1,513 @@ +// +// Copyright (c) 2002-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. +// +// RemoveDynamicIndexing is an AST traverser to remove dynamic indexing of vectors and matrices, +// replacing them with calls to functions that choose which component to return or write. +// + +#include "compiler/translator/RemoveDynamicIndexing.h" + +#include "compiler/translator/InfoSink.h" +#include "compiler/translator/IntermNode.h" +#include "compiler/translator/SymbolTable.h" + +namespace +{ + +TName GetIndexFunctionName(const TType &type, bool write) +{ + TInfoSinkBase nameSink; + nameSink << "dyn_index_"; + if (write) + { + nameSink << "write_"; + } + if (type.isMatrix()) + { + nameSink << "mat" << type.getCols() << "x" << type.getRows(); + } + else + { + switch (type.getBasicType()) + { + case EbtInt: + nameSink << "ivec"; + break; + case EbtBool: + nameSink << "bvec"; + break; + case EbtUInt: + nameSink << "uvec"; + break; + case EbtFloat: + nameSink << "vec"; + break; + default: + UNREACHABLE(); + } + nameSink << type.getNominalSize(); + } + TString nameString = TFunction::mangleName(nameSink.c_str()); + TName name(nameString); + name.setInternal(true); + return name; +} + +TIntermSymbol *CreateBaseSymbol(const TType &type, TQualifier qualifier) +{ + TIntermSymbol *symbol = new TIntermSymbol(0, "base", type); + symbol->setInternal(true); + symbol->getTypePointer()->setQualifier(qualifier); + return symbol; +} + +TIntermSymbol *CreateIndexSymbol() +{ + TIntermSymbol *symbol = new TIntermSymbol(0, "index", TType(EbtInt, EbpHigh)); + symbol->setInternal(true); + symbol->getTypePointer()->setQualifier(EvqIn); + return symbol; +} + +TIntermSymbol *CreateValueSymbol(const TType &type) +{ + TIntermSymbol *symbol = new TIntermSymbol(0, "value", type); + symbol->setInternal(true); + symbol->getTypePointer()->setQualifier(EvqIn); + return symbol; +} + +TIntermConstantUnion *CreateIntConstantNode(int i) +{ + TConstantUnion *constant = new TConstantUnion(); + constant->setIConst(i); + return new TIntermConstantUnion(constant, TType(EbtInt, EbpHigh)); +} + +TIntermBinary *CreateIndexDirectBaseSymbolNode(const TType &indexedType, + const TType &fieldType, + const int index, + TQualifier baseQualifier) +{ + TIntermBinary *indexNode = new TIntermBinary(EOpIndexDirect); + indexNode->setType(fieldType); + TIntermSymbol *baseSymbol = CreateBaseSymbol(indexedType, baseQualifier); + indexNode->setLeft(baseSymbol); + indexNode->setRight(CreateIntConstantNode(index)); + return indexNode; +} + +TIntermBinary *CreateAssignValueSymbolNode(TIntermTyped *targetNode, const TType &assignedValueType) +{ + TIntermBinary *assignNode = new TIntermBinary(EOpAssign); + assignNode->setType(assignedValueType); + assignNode->setLeft(targetNode); + assignNode->setRight(CreateValueSymbol(assignedValueType)); + return assignNode; +} + +TIntermTyped *EnsureSignedInt(TIntermTyped *node) +{ + if (node->getBasicType() == EbtInt) + return node; + + TIntermAggregate *convertedNode = new TIntermAggregate(EOpConstructInt); + convertedNode->setType(TType(EbtInt)); + convertedNode->getSequence()->push_back(node); + convertedNode->setPrecisionFromChildren(); + return convertedNode; +} + +TType GetFieldType(const TType &indexedType) +{ + if (indexedType.isMatrix()) + { + TType fieldType = TType(indexedType.getBasicType(), indexedType.getPrecision()); + fieldType.setPrimarySize(static_cast(indexedType.getRows())); + return fieldType; + } + else + { + return TType(indexedType.getBasicType(), indexedType.getPrecision()); + } +} + +// Generate a read or write function for one field in a vector/matrix. +// Out-of-range indices are clamped. This is consistent with how ANGLE handles out-of-range +// indices in other places. +// Note that indices can be either int or uint. We create only int versions of the functions, +// and convert uint indices to int at the call site. +// read function example: +// float dyn_index_vec2(in vec2 base, in int index) +// { +// switch(index) +// { +// case (0): +// return base[0]; +// case (1): +// return base[1]; +// default: +// break; +// } +// if (index < 0) +// return base[0]; +// return base[1]; +// } +// write function example: +// void dyn_index_write_vec2(inout vec2 base, in int index, in float value) +// { +// switch(index) +// { +// case (0): +// base[0] = value; +// return; +// case (1): +// base[1] = value; +// return; +// default: +// break; +// } +// if (index < 0) +// { +// base[0] = value; +// return; +// } +// base[1] = value; +// } +// Note that else is not used in above functions to avoid the RewriteElseBlocks transformation. +TIntermAggregate *GetIndexFunctionDefinition(TType type, bool write) +{ + ASSERT(!type.isArray()); + // Conservatively use highp here, even if the indexed type is not highp. That way the code can't + // end up using mediump version of an indexing function for a highp value, if both mediump and + // highp values are being indexed in the shader. For HLSL precision doesn't matter, but in + // principle this code could be used with multiple backends. + type.setPrecision(EbpHigh); + TIntermAggregate *indexingFunction = new TIntermAggregate(EOpFunction); + indexingFunction->setNameObj(GetIndexFunctionName(type, write)); + + TType fieldType = GetFieldType(type); + int numCases = 0; + if (type.isMatrix()) + { + numCases = type.getCols(); + } + else + { + numCases = type.getNominalSize(); + } + if (write) + { + indexingFunction->setType(TType(EbtVoid)); + } + else + { + indexingFunction->setType(fieldType); + } + + TIntermAggregate *paramsNode = new TIntermAggregate(EOpParameters); + TQualifier baseQualifier = EvqInOut; + if (!write) + baseQualifier = EvqIn; + TIntermSymbol *baseParam = CreateBaseSymbol(type, baseQualifier); + paramsNode->getSequence()->push_back(baseParam); + TIntermSymbol *indexParam = CreateIndexSymbol(); + paramsNode->getSequence()->push_back(indexParam); + if (write) + { + TIntermSymbol *valueParam = CreateValueSymbol(fieldType); + paramsNode->getSequence()->push_back(valueParam); + } + indexingFunction->getSequence()->push_back(paramsNode); + + TIntermAggregate *statementList = new TIntermAggregate(EOpSequence); + for (int i = 0; i < numCases; ++i) + { + TIntermCase *caseNode = new TIntermCase(CreateIntConstantNode(i)); + statementList->getSequence()->push_back(caseNode); + + TIntermBinary *indexNode = + CreateIndexDirectBaseSymbolNode(type, fieldType, i, baseQualifier); + if (write) + { + TIntermBinary *assignNode = CreateAssignValueSymbolNode(indexNode, fieldType); + statementList->getSequence()->push_back(assignNode); + TIntermBranch *returnNode = new TIntermBranch(EOpReturn, nullptr); + statementList->getSequence()->push_back(returnNode); + } + else + { + TIntermBranch *returnNode = new TIntermBranch(EOpReturn, indexNode); + statementList->getSequence()->push_back(returnNode); + } + } + + // Default case + TIntermCase *defaultNode = new TIntermCase(nullptr); + statementList->getSequence()->push_back(defaultNode); + TIntermBranch *breakNode = new TIntermBranch(EOpBreak, nullptr); + statementList->getSequence()->push_back(breakNode); + + TIntermSwitch *switchNode = new TIntermSwitch(CreateIndexSymbol(), statementList); + + TIntermAggregate *bodyNode = new TIntermAggregate(EOpSequence); + bodyNode->getSequence()->push_back(switchNode); + + TIntermBinary *cond = new TIntermBinary(EOpLessThan); + cond->setType(TType(EbtBool, EbpUndefined)); + cond->setLeft(CreateIndexSymbol()); + cond->setRight(CreateIntConstantNode(0)); + + // Two blocks: one accesses (either reads or writes) the first element and returns, + // the other accesses the last element. + TIntermAggregate *useFirstBlock = new TIntermAggregate(EOpSequence); + TIntermAggregate *useLastBlock = new TIntermAggregate(EOpSequence); + TIntermBinary *indexFirstNode = + CreateIndexDirectBaseSymbolNode(type, fieldType, 0, baseQualifier); + TIntermBinary *indexLastNode = + CreateIndexDirectBaseSymbolNode(type, fieldType, numCases - 1, baseQualifier); + if (write) + { + TIntermBinary *assignFirstNode = CreateAssignValueSymbolNode(indexFirstNode, fieldType); + useFirstBlock->getSequence()->push_back(assignFirstNode); + TIntermBranch *returnNode = new TIntermBranch(EOpReturn, nullptr); + useFirstBlock->getSequence()->push_back(returnNode); + + TIntermBinary *assignLastNode = CreateAssignValueSymbolNode(indexLastNode, fieldType); + useLastBlock->getSequence()->push_back(assignLastNode); + } + else + { + TIntermBranch *returnFirstNode = new TIntermBranch(EOpReturn, indexFirstNode); + useFirstBlock->getSequence()->push_back(returnFirstNode); + + TIntermBranch *returnLastNode = new TIntermBranch(EOpReturn, indexLastNode); + useLastBlock->getSequence()->push_back(returnLastNode); + } + TIntermSelection *ifNode = new TIntermSelection(cond, useFirstBlock, nullptr); + bodyNode->getSequence()->push_back(ifNode); + bodyNode->getSequence()->push_back(useLastBlock); + + indexingFunction->getSequence()->push_back(bodyNode); + + return indexingFunction; +} + +class RemoveDynamicIndexingTraverser : public TLValueTrackingTraverser +{ + public: + RemoveDynamicIndexingTraverser(const TSymbolTable &symbolTable, int shaderVersion); + + bool visitBinary(Visit visit, TIntermBinary *node) override; + + void insertHelperDefinitions(TIntermNode *root); + + void nextIteration(); + + bool usedTreeInsertion() const { return mUsedTreeInsertion; } + + protected: + // Sets of types that are indexed. Note that these can not store multiple variants + // of the same type with different precisions - only one precision gets stored. + std::set mIndexedVecAndMatrixTypes; + std::set mWrittenVecAndMatrixTypes; + + bool mUsedTreeInsertion; + + // When true, the traverser will remove side effects from any indexing expression. + // This is done so that in code like + // V[j++][i]++. + // where V is an array of vectors, j++ will only be evaluated once. + bool mRemoveIndexSideEffectsInSubtree; +}; + +RemoveDynamicIndexingTraverser::RemoveDynamicIndexingTraverser(const TSymbolTable &symbolTable, + int shaderVersion) + : TLValueTrackingTraverser(true, false, false, symbolTable, shaderVersion), + mUsedTreeInsertion(false), + mRemoveIndexSideEffectsInSubtree(false) +{ +} + +void RemoveDynamicIndexingTraverser::insertHelperDefinitions(TIntermNode *root) +{ + TIntermAggregate *rootAgg = root->getAsAggregate(); + ASSERT(rootAgg != nullptr && rootAgg->getOp() == EOpSequence); + TIntermSequence insertions; + for (TType type : mIndexedVecAndMatrixTypes) + { + insertions.push_back(GetIndexFunctionDefinition(type, false)); + } + for (TType type : mWrittenVecAndMatrixTypes) + { + insertions.push_back(GetIndexFunctionDefinition(type, true)); + } + mInsertions.push_back(NodeInsertMultipleEntry(rootAgg, 0, insertions, TIntermSequence())); +} + +// Create a call to dyn_index_*() based on an indirect indexing op node +TIntermAggregate *CreateIndexFunctionCall(TIntermBinary *node, + TIntermTyped *indexedNode, + TIntermTyped *index) +{ + ASSERT(node->getOp() == EOpIndexIndirect); + TIntermAggregate *indexingCall = new TIntermAggregate(EOpFunctionCall); + indexingCall->setLine(node->getLine()); + indexingCall->setUserDefined(); + indexingCall->setNameObj(GetIndexFunctionName(indexedNode->getType(), false)); + indexingCall->getSequence()->push_back(indexedNode); + indexingCall->getSequence()->push_back(index); + + TType fieldType = GetFieldType(indexedNode->getType()); + indexingCall->setType(fieldType); + return indexingCall; +} + +TIntermAggregate *CreateIndexedWriteFunctionCall(TIntermBinary *node, + TIntermTyped *index, + TIntermTyped *writtenValue) +{ + // Deep copy the left node so that two pointers to the same node don't end up in the tree. + TIntermNode *leftCopy = node->getLeft()->deepCopy(); + ASSERT(leftCopy != nullptr && leftCopy->getAsTyped() != nullptr); + TIntermAggregate *indexedWriteCall = + CreateIndexFunctionCall(node, leftCopy->getAsTyped(), index); + indexedWriteCall->setNameObj(GetIndexFunctionName(node->getLeft()->getType(), true)); + indexedWriteCall->setType(TType(EbtVoid)); + indexedWriteCall->getSequence()->push_back(writtenValue); + return indexedWriteCall; +} + +bool RemoveDynamicIndexingTraverser::visitBinary(Visit visit, TIntermBinary *node) +{ + if (mUsedTreeInsertion) + return false; + + if (node->getOp() == EOpIndexIndirect) + { + if (mRemoveIndexSideEffectsInSubtree) + { + ASSERT(node->getRight()->hasSideEffects()); + // In case we're just removing index side effects, convert + // v_expr[index_expr] + // to this: + // int s0 = index_expr; v_expr[s0]; + // Now v_expr[s0] can be safely executed several times without unintended side effects. + + // Init the temp variable holding the index + TIntermAggregate *initIndex = createTempInitDeclaration(node->getRight()); + TIntermSequence insertions; + insertions.push_back(initIndex); + insertStatementsInParentBlock(insertions); + mUsedTreeInsertion = true; + + // Replace the index with the temp variable + TIntermSymbol *tempIndex = createTempSymbol(node->getRight()->getType()); + NodeUpdateEntry replaceIndex(node, node->getRight(), tempIndex, false); + mReplacements.push_back(replaceIndex); + } + else if (!node->getLeft()->isArray() && node->getLeft()->getBasicType() != EbtStruct) + { + bool write = isLValueRequiredHere(); + + TType type = node->getLeft()->getType(); + mIndexedVecAndMatrixTypes.insert(type); + + if (write) + { + // Convert: + // v_expr[index_expr]++; + // to this: + // int s0 = index_expr; float s1 = dyn_index(v_expr, s0); s1++; + // dyn_index_write(v_expr, s0, s1); + // This works even if index_expr has some side effects. + if (node->getLeft()->hasSideEffects()) + { + // If v_expr has side effects, those need to be removed before proceeding. + // Otherwise the side effects of v_expr would be evaluated twice. + // The only case where an l-value can have side effects is when it is + // indexing. For example, it can be V[j++] where V is an array of vectors. + mRemoveIndexSideEffectsInSubtree = true; + return true; + } + // TODO(oetuaho@nvidia.com): This is not optimal if the expression using the value + // only writes it and doesn't need the previous value. http://anglebug.com/1116 + + mWrittenVecAndMatrixTypes.insert(type); + TType fieldType = GetFieldType(type); + + TIntermSequence insertionsBefore; + TIntermSequence insertionsAfter; + + // Store the index in a temporary signed int variable. + TIntermTyped *indexInitializer = EnsureSignedInt(node->getRight()); + TIntermAggregate *initIndex = createTempInitDeclaration(indexInitializer); + initIndex->setLine(node->getLine()); + insertionsBefore.push_back(initIndex); + + TIntermAggregate *indexingCall = CreateIndexFunctionCall( + node, node->getLeft(), createTempSymbol(indexInitializer->getType())); + + // Create a node for referring to the index after the nextTemporaryIndex() call + // below. + TIntermSymbol *tempIndex = createTempSymbol(indexInitializer->getType()); + + nextTemporaryIndex(); // From now on, creating temporary symbols that refer to the + // field value. + insertionsBefore.push_back(createTempInitDeclaration(indexingCall)); + + TIntermAggregate *indexedWriteCall = + CreateIndexedWriteFunctionCall(node, tempIndex, createTempSymbol(fieldType)); + insertionsAfter.push_back(indexedWriteCall); + insertStatementsInParentBlock(insertionsBefore, insertionsAfter); + NodeUpdateEntry replaceIndex(getParentNode(), node, createTempSymbol(fieldType), + false); + mReplacements.push_back(replaceIndex); + mUsedTreeInsertion = true; + } + else + { + // The indexed value is not being written, so we can simply convert + // v_expr[index_expr] + // into + // dyn_index(v_expr, index_expr) + // If the index_expr is unsigned, we'll convert it to signed. + ASSERT(!mRemoveIndexSideEffectsInSubtree); + TIntermAggregate *indexingCall = CreateIndexFunctionCall( + node, node->getLeft(), EnsureSignedInt(node->getRight())); + NodeUpdateEntry replaceIndex(getParentNode(), node, indexingCall, false); + mReplacements.push_back(replaceIndex); + } + } + } + return !mUsedTreeInsertion; +} + +void RemoveDynamicIndexingTraverser::nextIteration() +{ + mUsedTreeInsertion = false; + mRemoveIndexSideEffectsInSubtree = false; + nextTemporaryIndex(); +} + +} // namespace + +void RemoveDynamicIndexing(TIntermNode *root, + unsigned int *temporaryIndex, + const TSymbolTable &symbolTable, + int shaderVersion) +{ + RemoveDynamicIndexingTraverser traverser(symbolTable, shaderVersion); + ASSERT(temporaryIndex != nullptr); + traverser.useTemporaryIndex(temporaryIndex); + do + { + traverser.nextIteration(); + root->traverse(&traverser); + traverser.updateTree(); + } while (traverser.usedTreeInsertion()); + traverser.insertHelperDefinitions(root); + traverser.updateTree(); +} diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/RemoveDynamicIndexing.h b/Source/ThirdParty/ANGLE/src/compiler/translator/RemoveDynamicIndexing.h new file mode 100644 index 000000000000..ae3a93c9b143 --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/RemoveDynamicIndexing.h @@ -0,0 +1,21 @@ +// +// Copyright (c) 2002-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. +// +// RemoveDynamicIndexing is an AST traverser to remove dynamic indexing of vectors and matrices, +// replacing them with calls to functions that choose which component to return or write. +// + +#ifndef COMPILER_TRANSLATOR_REMOVEDYNAMICINDEXING_H_ +#define COMPILER_TRANSLATOR_REMOVEDYNAMICINDEXING_H_ + +class TIntermNode; +class TSymbolTable; + +void RemoveDynamicIndexing(TIntermNode *root, + unsigned int *temporaryIndex, + const TSymbolTable &symbolTable, + int shaderVersion); + +#endif // COMPILER_TRANSLATOR_REMOVEDYNAMICINDEXING_H_ diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/RemovePow.cpp b/Source/ThirdParty/ANGLE/src/compiler/translator/RemovePow.cpp new file mode 100644 index 000000000000..6dbb48da9cde --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/RemovePow.cpp @@ -0,0 +1,105 @@ +// +// Copyright (c) 2002-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. +// +// RemovePow is an AST traverser to convert pow(x, y) built-in calls where y is a +// constant to exp2(y * log2(x)). This works around an issue in NVIDIA 311 series +// OpenGL drivers. +// + +#include "compiler/translator/RemovePow.h" + +#include "compiler/translator/InfoSink.h" +#include "compiler/translator/IntermNode.h" + +namespace +{ + +bool IsProblematicPow(TIntermTyped *node) +{ + TIntermAggregate *agg = node->getAsAggregate(); + if (agg != nullptr && agg->getOp() == EOpPow) + { + ASSERT(agg->getSequence()->size() == 2); + return agg->getSequence()->at(1)->getAsConstantUnion() != nullptr; + } + return false; +} + +// Traverser that converts all pow operations simultaneously. +class RemovePowTraverser : public TIntermTraverser +{ + public: + RemovePowTraverser(); + + bool visitAggregate(Visit visit, TIntermAggregate *node) override; + + void nextIteration() { mNeedAnotherIteration = false; } + bool needAnotherIteration() const { return mNeedAnotherIteration; } + + protected: + bool mNeedAnotherIteration; +}; + +RemovePowTraverser::RemovePowTraverser() + : TIntermTraverser(true, false, false), + mNeedAnotherIteration(false) +{ +} + +bool RemovePowTraverser::visitAggregate(Visit visit, TIntermAggregate *node) +{ + if (IsProblematicPow(node)) + { + TInfoSink nullSink; + + TIntermTyped *x = node->getSequence()->at(0)->getAsTyped(); + TIntermTyped *y = node->getSequence()->at(1)->getAsTyped(); + + TIntermUnary *log = new TIntermUnary(EOpLog2); + log->setOperand(x); + log->setLine(node->getLine()); + log->setType(x->getType()); + + TIntermBinary *mul = new TIntermBinary(EOpMul); + mul->setLeft(y); + mul->setRight(log); + mul->setLine(node->getLine()); + bool valid = mul->promote(nullSink); + UNUSED_ASSERTION_VARIABLE(valid); + ASSERT(valid); + + TIntermUnary *exp = new TIntermUnary(EOpExp2); + exp->setOperand(mul); + exp->setLine(node->getLine()); + exp->setType(node->getType()); + + NodeUpdateEntry replacePow(getParentNode(), node, exp, false); + mReplacements.push_back(replacePow); + + // If the x parameter also needs to be replaced, we need to do that in another traversal, + // since it's parent node will change in a way that's not handled correctly by updateTree(). + if (IsProblematicPow(x)) + { + mNeedAnotherIteration = true; + return false; + } + } + return true; +} + +} // namespace + +void RemovePow(TIntermNode *root) +{ + RemovePowTraverser traverser; + // Iterate as necessary, and reset the traverser between iterations. + do + { + traverser.nextIteration(); + root->traverse(&traverser); + traverser.updateTree(); + } + while (traverser.needAnotherIteration()); +} diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/RemovePow.h b/Source/ThirdParty/ANGLE/src/compiler/translator/RemovePow.h new file mode 100644 index 000000000000..40f9d672b24c --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/RemovePow.h @@ -0,0 +1,18 @@ +// +// Copyright (c) 2002-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. +// +// RemovePow is an AST traverser to convert pow(x, y) built-in calls where y is a +// constant to exp2(y * log2(x)). This works around an issue in NVIDIA 311 series +// OpenGL drivers. +// + +#ifndef COMPILER_TRANSLATOR_REMOVEPOW_H_ +#define COMPILER_TRANSLATOR_REMOVEPOW_H_ + +class TIntermNode; + +void RemovePow(TIntermNode *root); + +#endif // COMPILER_TRANSLATOR_REMOVEPOW_H_ diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/RenameFunction.h b/Source/ThirdParty/ANGLE/src/compiler/translator/RenameFunction.h index 868e5d566b9c..fd6a365fea86 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/RenameFunction.h +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/RenameFunction.h @@ -20,7 +20,7 @@ class RenameFunction : public TIntermTraverser , mOldFunctionName(oldFunctionName) , mNewFunctionName(newFunctionName) {} - virtual bool visitAggregate(Visit visit, TIntermAggregate* node) + bool visitAggregate(Visit visit, TIntermAggregate *node) override { TOperator op = node->getOp(); if ((op == EOpFunction || op == EOpFunctionCall) && node->getName() == mOldFunctionName) diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/RewriteDoWhile.cpp b/Source/ThirdParty/ANGLE/src/compiler/translator/RewriteDoWhile.cpp new file mode 100644 index 000000000000..834744754619 --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/RewriteDoWhile.cpp @@ -0,0 +1,163 @@ +// +// Copyright (c) 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. +// + +// RewriteDoWhile.cpp: rewrites do-while loops using another equivalent +// construct. + +#include "compiler/translator/RewriteDoWhile.h" + +#include "compiler/translator/IntermNode.h" + +namespace +{ + +// An AST traverser that rewrites loops of the form +// do { +// CODE; +// } while (CONDITION) +// +// to loops of the form +// bool temp = false; +// while (true) { +// if (temp) { +// if (!CONDITION) { +// break; +// } +// } +// temp = true; +// CODE; +// } +// +// The reason we don't use a simpler form, with for example just (temp && !CONDITION) in the +// while condition, is that short-circuit is often badly supported by driver shader compiler. +// The double if has the same effect, but forces shader compilers to behave. +// +// TODO(cwallez) when UnfoldShortCircuitIntoIf handles loops correctly, revisit this as we might +// be able to use while (temp || CONDITION) with temp initially set to true then run +// UnfoldShortCircuitIntoIf +class DoWhileRewriter : public TIntermTraverser +{ + public: + DoWhileRewriter() : TIntermTraverser(true, false, false) {} + + bool visitAggregate(Visit, TIntermAggregate *node) override + { + // A well-formed AST can only have do-while in EOpSequence which represent lists of + // statements. By doing a prefix traversal we are able to replace the do-while in the + // sequence directly as the content of the do-while will be traversed later. + if (node->getOp() != EOpSequence) + { + return true; + } + + TIntermSequence *statements = node->getSequence(); + + // The statements vector will have new statements inserted when we encounter a do-while, + // which prevents us from using a range-based for loop. Using the usual i++ works, as + // the (two) new statements inserted replace the statement at the current position. + for (size_t i = 0; i < statements->size(); i++) + { + TIntermNode *statement = (*statements)[i]; + TIntermLoop *loop = statement->getAsLoopNode(); + + if (loop == nullptr || loop->getType() != ELoopDoWhile) + { + continue; + } + + TType boolType = TType(EbtBool); + + // bool temp = false; + TIntermAggregate *tempDeclaration = nullptr; + { + TConstantUnion *falseConstant = new TConstantUnion(); + falseConstant->setBConst(false); + TIntermTyped *falseValue = new TIntermConstantUnion(falseConstant, boolType); + + tempDeclaration = createTempInitDeclaration(falseValue); + } + + // temp = true; + TIntermBinary *assignTrue = nullptr; + { + TConstantUnion *trueConstant = new TConstantUnion(); + trueConstant->setBConst(true); + TIntermTyped *trueValue = new TIntermConstantUnion(trueConstant, boolType); + + assignTrue = createTempAssignment(trueValue); + } + + // if (temp) { + // if (!CONDITION) { + // break; + // } + // } + TIntermSelection *breakIf = nullptr; + { + TIntermBranch *breakStatement = new TIntermBranch(EOpBreak, nullptr); + + TIntermAggregate *breakBlock = new TIntermAggregate(EOpSequence); + breakBlock->getSequence()->push_back(breakStatement); + + TIntermUnary *negatedCondition = new TIntermUnary(EOpLogicalNot); + negatedCondition->setOperand(loop->getCondition()); + + TIntermSelection *innerIf = + new TIntermSelection(negatedCondition, breakBlock, nullptr); + + TIntermAggregate *innerIfBlock = new TIntermAggregate(EOpSequence); + innerIfBlock->getSequence()->push_back(innerIf); + + breakIf = new TIntermSelection(createTempSymbol(boolType), innerIfBlock, nullptr); + } + + // Assemble the replacement loops, reusing the do-while loop's body and inserting our + // statements at the front. + TIntermLoop *newLoop = nullptr; + { + TConstantUnion *trueConstant = new TConstantUnion(); + trueConstant->setBConst(true); + TIntermTyped *trueValue = new TIntermConstantUnion(trueConstant, boolType); + + TIntermAggregate *body = nullptr; + if (loop->getBody() != nullptr) + { + body = loop->getBody()->getAsAggregate(); + } + else + { + body = new TIntermAggregate(EOpSequence); + } + auto sequence = body->getSequence(); + sequence->insert(sequence->begin(), assignTrue); + sequence->insert(sequence->begin(), breakIf); + + newLoop = new TIntermLoop(ELoopWhile, nullptr, trueValue, nullptr, body); + } + + TIntermSequence replacement; + replacement.push_back(tempDeclaration); + replacement.push_back(newLoop); + + node->replaceChildNodeWithMultiple(loop, replacement); + + nextTemporaryIndex(); + } + return true; + } +}; + +} // anonymous namespace + +void RewriteDoWhile(TIntermNode *root, unsigned int *temporaryIndex) +{ + ASSERT(temporaryIndex != 0); + + DoWhileRewriter rewriter; + rewriter.useTemporaryIndex(temporaryIndex); + + root->traverse(&rewriter); +} diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/RewriteDoWhile.h b/Source/ThirdParty/ANGLE/src/compiler/translator/RewriteDoWhile.h new file mode 100644 index 000000000000..f6ec1caf0671 --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/RewriteDoWhile.h @@ -0,0 +1,16 @@ +// +// Copyright (c) 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. +// + +// RewriteDoWhile.h: rewrite do-while loops as while loops to work around +// driver bugs + +#ifndef COMPILER_TRANSLATOR_REWRITEDOWHILE_H_ +#define COMPILER_TRANSLATOR_REWRITEDOWHILE_H_ + +class TIntermNode; +void RewriteDoWhile(TIntermNode *root, unsigned int *temporaryIndex); + +#endif // COMPILER_TRANSLATOR_REWRITEDOWHILE_H_ diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/RewriteElseBlocks.cpp b/Source/ThirdParty/ANGLE/src/compiler/translator/RewriteElseBlocks.cpp index 4631b5d58e17..52ede17434a5 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/RewriteElseBlocks.cpp +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/RewriteElseBlocks.cpp @@ -23,32 +23,14 @@ class ElseBlockRewriter : public TIntermTraverser ElseBlockRewriter(); protected: - bool visitAggregate(Visit visit, TIntermAggregate *aggregate); + bool visitAggregate(Visit visit, TIntermAggregate *aggregate) override; private: - int mTemporaryIndex; const TType *mFunctionType; TIntermNode *rewriteSelection(TIntermSelection *selection); }; -TIntermSymbol *MakeNewTemporary(const TString &name, TBasicType type) -{ - TType variableType(type, EbpHigh, EvqTemporary); - TIntermSymbol *node = new TIntermSymbol(-1, name, variableType); - node->setInternal(true); - return node; -} - -TIntermBinary *MakeNewBinary(TOperator op, TIntermTyped *left, TIntermTyped *right, const TType &resultType) -{ - TIntermBinary *binary = new TIntermBinary(op); - binary->setLeft(left); - binary->setRight(right); - binary->setType(resultType); - return binary; -} - TIntermUnary *MakeNewUnary(TOperator op, TIntermTyped *operand) { TIntermUnary *unary = new TIntermUnary(op, operand->getType()); @@ -57,8 +39,7 @@ TIntermUnary *MakeNewUnary(TOperator op, TIntermTyped *operand) } ElseBlockRewriter::ElseBlockRewriter() - : TIntermTraverser(true, false, true, false), - mTemporaryIndex(0), + : TIntermTraverser(true, false, true), mFunctionType(NULL) {} @@ -73,7 +54,7 @@ bool ElseBlockRewriter::visitAggregate(Visit visit, TIntermAggregate *node) { TIntermNode *statement = (*node->getSequence())[statementIndex]; TIntermSelection *selection = statement->getAsSelectionNode(); - if (selection && selection->getFalseBlock() != NULL) + if (selection && selection->getFalseBlock() != nullptr) { // Check for if / else if TIntermSelection *elseIfBranch = selection->getFalseBlock()->getAsSelectionNode(); @@ -103,20 +84,20 @@ bool ElseBlockRewriter::visitAggregate(Visit visit, TIntermAggregate *node) TIntermNode *ElseBlockRewriter::rewriteSelection(TIntermSelection *selection) { - ASSERT(selection != NULL); + ASSERT(selection != nullptr); + + nextTemporaryIndex(); - TString temporaryName = "cond_" + str(mTemporaryIndex++); TIntermTyped *typedCondition = selection->getCondition()->getAsTyped(); - TType resultType(EbtBool, EbpUndefined); - TIntermSymbol *conditionSymbolInit = MakeNewTemporary(temporaryName, EbtBool); - TIntermBinary *storeCondition = MakeNewBinary(EOpInitialize, conditionSymbolInit, - typedCondition, resultType); - TIntermNode *negatedElse = NULL; + TIntermAggregate *storeCondition = createTempInitDeclaration(typedCondition); - TIntermSelection *falseBlock = NULL; + TIntermSelection *falseBlock = nullptr; + + TType boolType(EbtBool, EbpUndefined, EvqTemporary); if (selection->getFalseBlock()) { + TIntermAggregate *negatedElse = nullptr; // crbug.com/346463 // D3D generates error messages claiming a function has no return value, when rewriting // an if-else clause that returns something non-void in a function. By appending dummy @@ -126,24 +107,22 @@ TIntermNode *ElseBlockRewriter::rewriteSelection(TIntermSelection *selection) TString typeString = mFunctionType->getStruct() ? mFunctionType->getStruct()->name() : mFunctionType->getBasicString(); TString rawText = "return (" + typeString + ")0"; - negatedElse = new TIntermRaw(*mFunctionType, rawText); + TIntermRaw *returnNode = new TIntermRaw(*mFunctionType, rawText); + negatedElse = new TIntermAggregate(EOpSequence); + negatedElse->getSequence()->push_back(returnNode); } - TIntermSymbol *conditionSymbolElse = MakeNewTemporary(temporaryName, EbtBool); + TIntermSymbol *conditionSymbolElse = createTempSymbol(boolType); TIntermUnary *negatedCondition = MakeNewUnary(EOpLogicalNot, conditionSymbolElse); falseBlock = new TIntermSelection(negatedCondition, selection->getFalseBlock(), negatedElse); } - TIntermSymbol *conditionSymbolSel = MakeNewTemporary(temporaryName, EbtBool); - TIntermSelection *newSelection = new TIntermSelection(conditionSymbolSel, - selection->getTrueBlock(), falseBlock); - - TIntermAggregate *declaration = new TIntermAggregate(EOpDeclaration); - declaration->getSequence()->push_back(storeCondition); + TIntermSymbol *conditionSymbolSel = createTempSymbol(boolType); + TIntermSelection *newSelection = new TIntermSelection(conditionSymbolSel, selection->getTrueBlock(), falseBlock); TIntermAggregate *block = new TIntermAggregate(EOpSequence); - block->getSequence()->push_back(declaration); + block->getSequence()->push_back(storeCondition); block->getSequence()->push_back(newSelection); return block; @@ -151,9 +130,10 @@ TIntermNode *ElseBlockRewriter::rewriteSelection(TIntermSelection *selection) } -void RewriteElseBlocks(TIntermNode *node) +void RewriteElseBlocks(TIntermNode *node, unsigned int *temporaryIndex) { ElseBlockRewriter rewriter; + rewriter.useTemporaryIndex(temporaryIndex); node->traverse(&rewriter); } diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/RewriteElseBlocks.h b/Source/ThirdParty/ANGLE/src/compiler/translator/RewriteElseBlocks.h index 5527d27f8359..24a425e66d52 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/RewriteElseBlocks.h +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/RewriteElseBlocks.h @@ -15,7 +15,7 @@ namespace sh { -void RewriteElseBlocks(TIntermNode *node); +void RewriteElseBlocks(TIntermNode *node, unsigned int *temporaryIndex); } diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/ScalarizeVecAndMatConstructorArgs.cpp b/Source/ThirdParty/ANGLE/src/compiler/translator/ScalarizeVecAndMatConstructorArgs.cpp index ff35e418a271..775c5d871010 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/ScalarizeVecAndMatConstructorArgs.cpp +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/ScalarizeVecAndMatConstructorArgs.cpp @@ -109,7 +109,13 @@ bool ScalarizeVecAndMatConstructorArgs::visitAggregate(Visit visit, TIntermAggre scalarizeArgs(node, false, true); break; case EOpConstructMat2: + case EOpConstructMat2x3: + case EOpConstructMat2x4: + case EOpConstructMat3x2: case EOpConstructMat3: + case EOpConstructMat3x4: + case EOpConstructMat4x2: + case EOpConstructMat4x3: case EOpConstructMat4: if (ContainsVectorNode(*(node->getSequence()))) scalarizeArgs(node, true, false); @@ -144,9 +150,21 @@ void ScalarizeVecAndMatConstructorArgs::scalarizeArgs( case EOpConstructMat2: size = 4; break; + case EOpConstructMat2x3: + case EOpConstructMat3x2: + size = 6; + break; + case EOpConstructMat2x4: + case EOpConstructMat4x2: + size = 8; + break; case EOpConstructMat3: size = 9; break; + case EOpConstructMat3x4: + case EOpConstructMat4x3: + size = 12; + break; case EOpConstructMat4: size = 16; break; diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/ScalarizeVecAndMatConstructorArgs.h b/Source/ThirdParty/ANGLE/src/compiler/translator/ScalarizeVecAndMatConstructorArgs.h index 0726ed4c64b5..d7553be23bd4 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/ScalarizeVecAndMatConstructorArgs.h +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/ScalarizeVecAndMatConstructorArgs.h @@ -14,12 +14,13 @@ class ScalarizeVecAndMatConstructorArgs : public TIntermTraverser public: ScalarizeVecAndMatConstructorArgs(sh::GLenum shaderType, bool fragmentPrecisionHigh) - : mTempVarCount(0), + : TIntermTraverser(true, false, false), + mTempVarCount(0), mShaderType(shaderType), mFragmentPrecisionHigh(fragmentPrecisionHigh) {} protected: - virtual bool visitAggregate(Visit visit, TIntermAggregate *node); + bool visitAggregate(Visit visit, TIntermAggregate *node) override; private: void scalarizeArgs(TIntermAggregate *aggregate, diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/SearchSymbol.cpp b/Source/ThirdParty/ANGLE/src/compiler/translator/SearchSymbol.cpp index fb7a6cdb9ba7..cccd4d3ff012 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/SearchSymbol.cpp +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/SearchSymbol.cpp @@ -12,7 +12,9 @@ namespace sh { -SearchSymbol::SearchSymbol(const TString &symbol) : mSymbol(symbol) +SearchSymbol::SearchSymbol(const TString &symbol) + : TIntermTraverser(true, false, false), + mSymbol(symbol) { match = false; } diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/SearchSymbol.h b/Source/ThirdParty/ANGLE/src/compiler/translator/SearchSymbol.h index 36d51910586f..1e5e1700d15f 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/SearchSymbol.h +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/SearchSymbol.h @@ -20,7 +20,7 @@ class SearchSymbol : public TIntermTraverser SearchSymbol(const TString &symbol); void traverse(TIntermNode *node); - void visitSymbol(TIntermSymbol *symbolNode); + void visitSymbol(TIntermSymbol *symbolNode) override; bool foundMatch() const; diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/SeparateArrayInitialization.cpp b/Source/ThirdParty/ANGLE/src/compiler/translator/SeparateArrayInitialization.cpp index f8d14660a43c..de9050cd80a0 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/SeparateArrayInitialization.cpp +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/SeparateArrayInitialization.cpp @@ -9,10 +9,16 @@ // will effectively become // type[n] a; // a = initializer; +// +// Note that if the array is declared as const, the initialization may still be split, making the +// AST technically invalid. Because of that this transformation should only be used when subsequent +// stages don't care about const qualifiers. However, the initialization will not be split if the +// initializer can be written as a HLSL literal. #include "compiler/translator/SeparateArrayInitialization.h" #include "compiler/translator/IntermNode.h" +#include "compiler/translator/OutputHLSL.h" namespace { @@ -47,7 +53,7 @@ bool SeparateArrayInitTraverser::visitAggregate(Visit, TIntermAggregate *node) if (initNode != nullptr && initNode->getOp() == EOpInitialize) { TIntermTyped *initializer = initNode->getRight(); - if (initializer->isArray()) + if (initializer->isArray() && !sh::OutputHLSL::canWriteAsHLSLLiteral(initializer)) { // We rely on that array declarations have been isolated to single declarations. ASSERT(sequence->size() == 1); diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/SeparateArrayInitialization.h b/Source/ThirdParty/ANGLE/src/compiler/translator/SeparateArrayInitialization.h index d7c3ae609bd3..d16357a3afd8 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/SeparateArrayInitialization.h +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/SeparateArrayInitialization.h @@ -9,6 +9,11 @@ // will effectively become // type[n] a; // a = initializer; +// +// Note that if the array is declared as const, the initialization may still be split, making the +// AST technically invalid. Because of that this transformation should only be used when subsequent +// stages don't care about const qualifiers. However, the initialization will not be split if the +// initializer can be written as a HLSL literal. #ifndef COMPILER_TRANSLATOR_SEPARATEARRAYINITIALIZATION_H_ #define COMPILER_TRANSLATOR_SEPARATEARRAYINITIALIZATION_H_ diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/SeparateDeclarations.cpp b/Source/ThirdParty/ANGLE/src/compiler/translator/SeparateDeclarations.cpp index 7ea1ce05522c..d33747f85bb6 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/SeparateDeclarations.cpp +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/SeparateDeclarations.cpp @@ -3,9 +3,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // -// The SeparateArrayDeclarations function processes declarations that contain array declarators. Each declarator in -// such declarations gets its own declaration. -// This is useful as an intermediate step when initialization needs to be separated from declaration. +// The SeparateDeclarations function processes declarations, so that in the end each declaration +// contains only one declarator. +// This is useful as an intermediate step when initialization needs to be separated from declaration, +// or when things need to be unfolded out of the initializer. // Example: // int a[1] = int[1](1), b[1] = int[1](2); // gets transformed when run through this class into the AST equivalent of: @@ -19,43 +20,33 @@ namespace { -class SeparateDeclarations : private TIntermTraverser +class SeparateDeclarationsTraverser : private TIntermTraverser { public: static void apply(TIntermNode *root); private: - SeparateDeclarations(); + SeparateDeclarationsTraverser(); bool visitAggregate(Visit, TIntermAggregate *node) override; }; -void SeparateDeclarations::apply(TIntermNode *root) +void SeparateDeclarationsTraverser::apply(TIntermNode *root) { - SeparateDeclarations separateDecl; + SeparateDeclarationsTraverser separateDecl; root->traverse(&separateDecl); separateDecl.updateTree(); } -SeparateDeclarations::SeparateDeclarations() +SeparateDeclarationsTraverser::SeparateDeclarationsTraverser() : TIntermTraverser(true, false, false) { } -bool SeparateDeclarations::visitAggregate(Visit, TIntermAggregate *node) +bool SeparateDeclarationsTraverser::visitAggregate(Visit, TIntermAggregate *node) { if (node->getOp() == EOpDeclaration) { TIntermSequence *sequence = node->getSequence(); - bool sequenceContainsArrays = false; - for (size_t ii = 0; ii < sequence->size(); ++ii) - { - TIntermTyped *typed = sequence->at(ii)->getAsTyped(); - if (typed != nullptr && typed->isArray()) - { - sequenceContainsArrays = true; - break; - } - } - if (sequence->size() > 1 && sequenceContainsArrays) + if (sequence->size() > 1) { TIntermAggregate *parentAgg = getParentNode()->getAsAggregate(); ASSERT(parentAgg != nullptr); @@ -80,7 +71,7 @@ bool SeparateDeclarations::visitAggregate(Visit, TIntermAggregate *node) } // namespace -void SeparateArrayDeclarations(TIntermNode *root) +void SeparateDeclarations(TIntermNode *root) { - SeparateDeclarations::apply(root); + SeparateDeclarationsTraverser::apply(root); } diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/SeparateDeclarations.h b/Source/ThirdParty/ANGLE/src/compiler/translator/SeparateDeclarations.h index 2aa5294f0831..77913ab8bbc1 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/SeparateDeclarations.h +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/SeparateDeclarations.h @@ -3,9 +3,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // -// The SeparateArrayDeclarations function processes declarations that contain array declarators. Each declarator in -// such declarations gets its own declaration. -// This is useful as an intermediate step when initialization needs to be separated from declaration. +// The SeparateDeclarations function processes declarations, so that in the end each declaration +// contains only one declarator. +// This is useful as an intermediate step when initialization needs to be separated from declaration, +// or when things need to be unfolded out of the initializer. // Example: // int a[1] = int[1](1), b[1] = int[1](2); // gets transformed when run through this class into the AST equivalent of: @@ -17,6 +18,6 @@ class TIntermNode; -void SeparateArrayDeclarations(TIntermNode *root); +void SeparateDeclarations(TIntermNode *root); #endif // COMPILER_TRANSLATOR_SEPARATEDECLARATIONS_H_ diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/SeparateExpressionsReturningArrays.cpp b/Source/ThirdParty/ANGLE/src/compiler/translator/SeparateExpressionsReturningArrays.cpp new file mode 100644 index 000000000000..e8e1a21d9c49 --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/SeparateExpressionsReturningArrays.cpp @@ -0,0 +1,169 @@ +// +// Copyright (c) 2002-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. +// +// SeparateExpressionsReturningArrays splits array-returning expressions that are not array names from more complex +// expressions, assigning them to a temporary variable a#. +// Examples where a, b and c are all arrays: +// (a = b) == (a = c) is split into a = b; type[n] a1 = a; a = c; type[n] a2 = a; a1 == a2; +// type d = type[n](...)[i]; is split into type[n] a1 = type[n](...); type d = a1[i]; + +#include "compiler/translator/SeparateExpressionsReturningArrays.h" + +#include "compiler/translator/IntermNode.h" + +namespace +{ + +// Traverser that separates one array expression into a statement at a time. +class SeparateExpressionsTraverser : public TIntermTraverser +{ + public: + SeparateExpressionsTraverser(); + + bool visitBinary(Visit visit, TIntermBinary *node) override; + bool visitAggregate(Visit visit, TIntermAggregate *node) override; + + void nextIteration(); + bool foundArrayExpression() const { return mFoundArrayExpression; } + + protected: + // Marked to true once an operation that needs to be hoisted out of the expression has been found. + // After that, no more AST updates are performed on that traversal. + bool mFoundArrayExpression; +}; + +SeparateExpressionsTraverser::SeparateExpressionsTraverser() + : TIntermTraverser(true, false, false), + mFoundArrayExpression(false) +{ +} + +// Performs a shallow copy of an assignment node. +// These shallow copies are useful when a node gets inserted into an aggregate node +// and also needs to be replaced in its original location by a different node. +TIntermBinary *CopyAssignmentNode(TIntermBinary *node) +{ + TIntermBinary *copyNode = new TIntermBinary(node->getOp()); + copyNode->setLeft(node->getLeft()); + copyNode->setRight(node->getRight()); + copyNode->setType(node->getType()); + return copyNode; +} + +// Performs a shallow copy of a constructor/function call node. +TIntermAggregate *CopyAggregateNode(TIntermAggregate *node) +{ + TIntermAggregate *copyNode = new TIntermAggregate(node->getOp()); + TIntermSequence *copySeq = copyNode->getSequence(); + copySeq->insert(copySeq->begin(), node->getSequence()->begin(), node->getSequence()->end()); + copyNode->setType(node->getType()); + copyNode->setFunctionId(node->getFunctionId()); + if (node->isUserDefined()) + { + copyNode->setUserDefined(); + } + copyNode->setNameObj(node->getNameObj()); + return copyNode; +} + +bool SeparateExpressionsTraverser::visitBinary(Visit visit, TIntermBinary *node) +{ + if (mFoundArrayExpression) + return false; + + // Early return if the expression is not an array or if we're not inside a complex expression. + if (!node->getType().isArray() || parentNodeIsBlock()) + return true; + + switch (node->getOp()) + { + case EOpAssign: + { + mFoundArrayExpression = true; + + TIntermSequence insertions; + insertions.push_back(CopyAssignmentNode(node)); + // TODO(oetuaho): In some cases it would be more optimal to not add the temporary node, but just use the + // original target of the assignment. Care must be taken so that this doesn't happen when the same array + // symbol is a target of assignment more than once in one expression. + insertions.push_back(createTempInitDeclaration(node->getLeft())); + insertStatementsInParentBlock(insertions); + + NodeUpdateEntry replaceVariable(getParentNode(), node, createTempSymbol(node->getType()), false); + mReplacements.push_back(replaceVariable); + } + return false; + default: + return true; + } +} + +bool SeparateExpressionsTraverser::visitAggregate(Visit visit, TIntermAggregate *node) +{ + if (mFoundArrayExpression) + return false; // No need to traverse further + + if (getParentNode() != nullptr) + { + TIntermBinary *parentBinary = getParentNode()->getAsBinaryNode(); + bool parentIsAssignment = (parentBinary != nullptr && + (parentBinary->getOp() == EOpAssign || parentBinary->getOp() == EOpInitialize)); + + if (!node->getType().isArray() || parentNodeIsBlock() || parentIsAssignment) + return true; + + if (node->isConstructor()) + { + mFoundArrayExpression = true; + + TIntermSequence insertions; + insertions.push_back(createTempInitDeclaration(CopyAggregateNode(node))); + insertStatementsInParentBlock(insertions); + + NodeUpdateEntry replaceVariable(getParentNode(), node, createTempSymbol(node->getType()), false); + mReplacements.push_back(replaceVariable); + + return false; + } + else if (node->getOp() == EOpFunctionCall) + { + mFoundArrayExpression = true; + + TIntermSequence insertions; + insertions.push_back(createTempInitDeclaration(CopyAggregateNode(node))); + insertStatementsInParentBlock(insertions); + + NodeUpdateEntry replaceVariable(getParentNode(), node, createTempSymbol(node->getType()), false); + mReplacements.push_back(replaceVariable); + + return false; + } + } + return true; +} + +void SeparateExpressionsTraverser::nextIteration() +{ + mFoundArrayExpression = false; + nextTemporaryIndex(); +} + +} // namespace + +void SeparateExpressionsReturningArrays(TIntermNode *root, unsigned int *temporaryIndex) +{ + SeparateExpressionsTraverser traverser; + ASSERT(temporaryIndex != nullptr); + traverser.useTemporaryIndex(temporaryIndex); + // Separate one expression at a time, and reset the traverser between iterations. + do + { + traverser.nextIteration(); + root->traverse(&traverser); + if (traverser.foundArrayExpression()) + traverser.updateTree(); + } + while (traverser.foundArrayExpression()); +} diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/SeparateExpressionsReturningArrays.h b/Source/ThirdParty/ANGLE/src/compiler/translator/SeparateExpressionsReturningArrays.h new file mode 100644 index 000000000000..b178ebb3ec44 --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/SeparateExpressionsReturningArrays.h @@ -0,0 +1,19 @@ +// +// Copyright (c) 2002-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. +// +// SeparateExpressionsReturningArrays splits array-returning expressions that are not array names from more complex +// expressions, assigning them to a temporary variable a#. +// Examples where a, b and c are all arrays: +// (a = b) == (a = c) is split into a = b; type[n] a1 = a; a = c; type[n] a2 = a; a1 == a2; +// type d = type[n](...)[i]; is split into type[n] a1 = type[n](...); type d = a1[i]; + +#ifndef COMPILER_TRANSLATOR_SEPARATEEXPRESSIONSRETURNINGARRAYS_H_ +#define COMPILER_TRANSLATOR_SEPARATEEXPRESSIONSRETURNINGARRAYS_H_ + +class TIntermNode; + +void SeparateExpressionsReturningArrays(TIntermNode *root, unsigned int *temporaryIndex); + +#endif // COMPILER_TRANSLATOR_SEPARATEEXPRESSIONSRETURNINGARRAYS_H_ diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/ShaderLang.cpp b/Source/ThirdParty/ANGLE/src/compiler/translator/ShaderLang.cpp index b8040da7f953..a58e91783209 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/ShaderLang.cpp +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/ShaderLang.cpp @@ -23,15 +23,6 @@ namespace { -enum ShaderVariableType -{ - SHADERVAR_UNIFORM, - SHADERVAR_VARYING, - SHADERVAR_ATTRIBUTE, - SHADERVAR_OUTPUTVARIABLE, - SHADERVAR_INTERFACEBLOCK -}; - bool isInitialized = false; // @@ -40,36 +31,40 @@ bool isInitialized = false; // template -const std::vector *GetVariableList(const TCompiler *compiler, ShaderVariableType variableType); +const std::vector *GetVariableList(const TCompiler *compiler); template <> -const std::vector *GetVariableList(const TCompiler *compiler, ShaderVariableType) +const std::vector *GetVariableList(const TCompiler *compiler) { return &compiler->getUniforms(); } template <> -const std::vector *GetVariableList(const TCompiler *compiler, ShaderVariableType) +const std::vector *GetVariableList(const TCompiler *compiler) { return &compiler->getVaryings(); } template <> -const std::vector *GetVariableList(const TCompiler *compiler, ShaderVariableType variableType) +const std::vector *GetVariableList(const TCompiler *compiler) { - return (variableType == SHADERVAR_ATTRIBUTE ? - &compiler->getAttributes() : - &compiler->getOutputVariables()); + return &compiler->getAttributes(); } template <> -const std::vector *GetVariableList(const TCompiler *compiler, ShaderVariableType) +const std::vector *GetVariableList(const TCompiler *compiler) +{ + return &compiler->getOutputVariables(); +} + +template <> +const std::vector *GetVariableList(const TCompiler *compiler) { return &compiler->getInterfaceBlocks(); } template -const std::vector *GetShaderVariables(const ShHandle handle, ShaderVariableType variableType) +const std::vector *GetShaderVariables(const ShHandle handle) { if (!handle) { @@ -83,7 +78,7 @@ const std::vector *GetShaderVariables(const ShHandle handle, ShaderVariabl return NULL; } - return GetVariableList(compiler, variableType); + return GetVariableList(compiler); } TCompiler *GetCompilerFromHandle(ShHandle handle) @@ -104,7 +99,7 @@ TranslatorHLSL *GetTranslatorHLSLFromHandle(ShHandle handle) } #endif // ANGLE_ENABLE_HLSL -} // namespace anonymous +} // anonymous namespace // // Driver must call this first, once, before doing any other compiler operations. @@ -154,6 +149,7 @@ void ShInitBuiltInResources(ShBuiltInResources* resources) resources->OES_standard_derivatives = 0; resources->OES_EGL_image_external = 0; resources->ARB_texture_rectangle = 0; + resources->EXT_blend_func_extended = 0; resources->EXT_draw_buffers = 0; resources->EXT_frag_depth = 0; resources->EXT_shader_texture_lod = 0; @@ -173,13 +169,17 @@ void ShInitBuiltInResources(ShBuiltInResources* resources) resources->MinProgramTexelOffset = -8; resources->MaxProgramTexelOffset = 7; + // Extensions constants. + resources->MaxDualSourceDrawBuffers = 0; + // Disable name hashing by default. resources->HashFunction = NULL; resources->ArrayIndexClampingStrategy = SH_CLAMP_WITH_CLAMP_INTRINSIC; resources->MaxExpressionComplexity = 256; - resources->MaxCallStackDepth = 256; + resources->MaxCallStackDepth = 256; + resources->MaxFunctionParameters = 1024; } // @@ -190,9 +190,16 @@ ShHandle ShConstructCompiler(sh::GLenum type, ShShaderSpec spec, const ShBuiltInResources* resources) { TShHandleBase* base = static_cast(ConstructCompiler(type, spec, output)); + if (base == nullptr) + { + return 0; + } + TCompiler* compiler = base->getAsCompiler(); - if (compiler == 0) + if (compiler == nullptr) + { return 0; + } // Generate built-in symbol table. if (!compiler->Init(*resources)) { @@ -240,6 +247,13 @@ bool ShCompile( return compiler->compile(shaderStrings, numStrings, compileOptions); } +void ShClearResults(const ShHandle handle) +{ + TCompiler *compiler = GetCompilerFromHandle(handle); + ASSERT(compiler); + compiler->clearResults(); +} + int ShGetShaderVersion(const ShHandle handle) { TCompiler* compiler = GetCompilerFromHandle(handle); @@ -288,27 +302,27 @@ const std::map *ShGetNameHashingMap( const std::vector *ShGetUniforms(const ShHandle handle) { - return GetShaderVariables(handle, SHADERVAR_UNIFORM); + return GetShaderVariables(handle); } const std::vector *ShGetVaryings(const ShHandle handle) { - return GetShaderVariables(handle, SHADERVAR_VARYING); + return GetShaderVariables(handle); } const std::vector *ShGetAttributes(const ShHandle handle) { - return GetShaderVariables(handle, SHADERVAR_ATTRIBUTE); + return GetShaderVariables(handle); } -const std::vector *ShGetOutputVariables(const ShHandle handle) +const std::vector *ShGetOutputVariables(const ShHandle handle) { - return GetShaderVariables(handle, SHADERVAR_OUTPUTVARIABLE); + return GetShaderVariables(handle); } const std::vector *ShGetInterfaceBlocks(const ShHandle handle) { - return GetShaderVariables(handle, SHADERVAR_INTERFACEBLOCK); + return GetShaderVariables(handle); } bool ShCheckVariablesWithinPackingLimits( @@ -349,23 +363,15 @@ bool ShGetInterfaceBlockRegister(const ShHandle handle, #endif // ANGLE_ENABLE_HLSL } -bool ShGetUniformRegister(const ShHandle handle, - const std::string &uniformName, - unsigned int *indexOut) +const std::map *ShGetUniformRegisterMap(const ShHandle handle) { #ifdef ANGLE_ENABLE_HLSL - ASSERT(indexOut); TranslatorHLSL *translator = GetTranslatorHLSLFromHandle(handle); ASSERT(translator); - if (!translator->hasUniform(uniformName)) - { - return false; - } - - *indexOut = translator->getUniformRegister(uniformName); - return true; + return translator->getUniformRegisterMap(); #else - return false; -#endif // ANGLE_ENABLE_HLSL + static std::map map; + return ↦ +#endif // ANGLE_ENABLE_HLSL } diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/ShaderVars.cpp b/Source/ThirdParty/ANGLE/src/compiler/translator/ShaderVars.cpp index 590655f59aac..8f931b9bdd34 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/ShaderVars.cpp +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/ShaderVars.cpp @@ -217,31 +217,75 @@ bool Uniform::isSameUniformAtLinkTime(const Uniform &other) const return ShaderVariable::isSameVariableAtLinkTime(other, true); } -Attribute::Attribute() - : location(-1) +InterfaceVariable::InterfaceVariable() : location(-1) {} -Attribute::~Attribute() +InterfaceVariable::~InterfaceVariable() {} -Attribute::Attribute(const Attribute &other) - : ShaderVariable(other), - location(other.location) +InterfaceVariable::InterfaceVariable(const InterfaceVariable &other) + : ShaderVariable(other), location(other.location) {} -Attribute &Attribute::operator=(const Attribute &other) +InterfaceVariable &InterfaceVariable::operator=(const InterfaceVariable &other) { ShaderVariable::operator=(other); location = other.location; return *this; } -bool Attribute::operator==(const Attribute &other) const +bool InterfaceVariable::operator==(const InterfaceVariable &other) const { return (ShaderVariable::operator==(other) && location == other.location); } +Attribute::Attribute() +{ +} + +Attribute::~Attribute() +{ +} + +Attribute::Attribute(const Attribute &other) : InterfaceVariable(other) +{ +} + +Attribute &Attribute::operator=(const Attribute &other) +{ + InterfaceVariable::operator=(other); + return *this; +} + +bool Attribute::operator==(const Attribute &other) const +{ + return InterfaceVariable::operator==(other); +} + +OutputVariable::OutputVariable() +{ +} + +OutputVariable::~OutputVariable() +{ +} + +OutputVariable::OutputVariable(const OutputVariable &other) : InterfaceVariable(other) +{ +} + +OutputVariable &OutputVariable::operator=(const OutputVariable &other) +{ + InterfaceVariable::operator=(other); + return *this; +} + +bool OutputVariable::operator==(const OutputVariable &other) const +{ + return InterfaceVariable::operator==(other); +} + InterfaceBlockField::InterfaceBlockField() : isRowMajorLayout(false) {} @@ -304,10 +348,15 @@ bool Varying::operator==(const Varying &other) const } bool Varying::isSameVaryingAtLinkTime(const Varying &other) const +{ + return isSameVaryingAtLinkTime(other, 100); +} + +bool Varying::isSameVaryingAtLinkTime(const Varying &other, int shaderVersion) const { return (ShaderVariable::isSameVariableAtLinkTime(other, false) && interpolation == other.interpolation && - isInvariant == other.isInvariant); + (shaderVersion >= 300 || isInvariant == other.isInvariant)); } InterfaceBlock::InterfaceBlock() @@ -344,4 +393,9 @@ InterfaceBlock &InterfaceBlock::operator=(const InterfaceBlock &other) return *this; } +std::string InterfaceBlock::fieldPrefix() const +{ + return instanceName.empty() ? "" : name; } + +} // namespace sh diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/SimplifyArrayAssignment.cpp b/Source/ThirdParty/ANGLE/src/compiler/translator/SimplifyArrayAssignment.cpp deleted file mode 100644 index ac5eb67070d2..000000000000 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/SimplifyArrayAssignment.cpp +++ /dev/null @@ -1,38 +0,0 @@ -// -// Copyright (c) 2002-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. -// - -#include "compiler/translator/SimplifyArrayAssignment.h" - -bool SimplifyArrayAssignment::visitBinary(Visit visit, TIntermBinary *node) -{ - switch (node->getOp()) - { - case EOpAssign: - { - TIntermNode *parent = getParentNode(); - if (node->getLeft()->isArray() && parent != nullptr) - { - TIntermAggregate *parentAgg = parent->getAsAggregate(); - if (parentAgg != nullptr && parentAgg->getOp() == EOpSequence) - { - // This case is fine, the result of the assignment is not used. - break; - } - - // The result of the assignment needs to be stored into a temporary variable, - // the assignment needs to be replaced with a reference to the temporary variable, - // and the temporary variable needs to finally be assigned to the target variable. - - // This also needs to interact correctly with unfolding short circuiting operators. - UNIMPLEMENTED(); - } - } - break; - default: - break; - } - return true; -} diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/SimplifyArrayAssignment.h b/Source/ThirdParty/ANGLE/src/compiler/translator/SimplifyArrayAssignment.h deleted file mode 100644 index 247eb88d72aa..000000000000 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/SimplifyArrayAssignment.h +++ /dev/null @@ -1,25 +0,0 @@ -// -// Copyright (c) 2002-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. -// -// SimplifyArrayAssignment is an AST traverser to replace statements where -// the return value of array assignment is used with statements where -// the return value of array assignment is not used. -// - -#ifndef COMPILER_TRANSLATOR_SIMPLIFYARRAYASSIGNMENT_H_ -#define COMPILER_TRANSLATOR_SIMPLIFYARRAYASSIGNMENT_H_ - -#include "common/angleutils.h" -#include "compiler/translator/IntermNode.h" - -class SimplifyArrayAssignment : public TIntermTraverser -{ - public: - SimplifyArrayAssignment() { } - - virtual bool visitBinary(Visit visit, TIntermBinary *node); -}; - -#endif // COMPILER_TRANSLATOR_SIMPLIFYARRAYASSIGNMENT_H_ diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/StructureHLSL.cpp b/Source/ThirdParty/ANGLE/src/compiler/translator/StructureHLSL.cpp index fd1a29c1cdf8..93e0ba573710 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/StructureHLSL.cpp +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/StructureHLSL.cpp @@ -182,26 +182,29 @@ TString StructureHLSL::define(const TStructure &structure, bool useHLSLRowMajorP string += declareString + "\n" "{\n"; - for (unsigned int i = 0; i < fields.size(); i++) + for (const TField *field : fields) { - const TField &field = *fields[i]; - const TType &fieldType = *field.type(); - const TStructure *fieldStruct = fieldType.getStruct(); - const TString &fieldTypeString = fieldStruct ? - QualifiedStructNameString(*fieldStruct, useHLSLRowMajorPacking, - useStd140Packing) : - TypeString(fieldType); - - if (padHelper) + const TType &fieldType = *field->type(); + if (!IsSampler(fieldType.getBasicType())) { - string += padHelper->prePaddingString(fieldType); - } + const TStructure *fieldStruct = fieldType.getStruct(); + const TString &fieldTypeString = + fieldStruct ? QualifiedStructNameString(*fieldStruct, useHLSLRowMajorPacking, + useStd140Packing) + : TypeString(fieldType); + + if (padHelper) + { + string += padHelper->prePaddingString(fieldType); + } - string += " " + fieldTypeString + " " + DecorateField(field.name(), structure) + ArrayString(fieldType) + ";\n"; + string += " " + fieldTypeString + " " + DecorateField(field->name(), structure) + + ArrayString(fieldType) + ";\n"; - if (padHelper) - { - string += padHelper->postPaddingString(fieldType, useHLSLRowMajorPacking); + if (padHelper) + { + string += padHelper->postPaddingString(fieldType, useHLSLRowMajorPacking); + } } } @@ -211,16 +214,18 @@ TString StructureHLSL::define(const TStructure &structure, bool useHLSLRowMajorP return string; } -void StructureHLSL::addConstructor(const TType &type, const TString &name, const TIntermSequence *parameters) +TString StructureHLSL::addConstructor(const TType &type, + const TString &name, + const TIntermSequence *parameters) { if (name == "") { - return; // Nameless structures don't have constructors + return TString(); // Nameless structures don't have constructors } if (type.getStruct() && mStructNames.find(name) != mStructNames.end()) { - return; // Already added + return TString(name); // Already added } TType ctorType = type; @@ -231,6 +236,8 @@ void StructureHLSL::addConstructor(const TType &type, const TString &name, const typedef std::vector ParameterArray; ParameterArray ctorParameters; + TString constructorFunctionName; + const TStructure* structure = type.getStruct(); if (structure) { @@ -261,17 +268,24 @@ void StructureHLSL::addConstructor(const TType &type, const TString &name, const } const TFieldList &fields = structure->fields(); - for (unsigned int i = 0; i < fields.size(); i++) + for (const TField *field : fields) { - ctorParameters.push_back(*fields[i]->type()); + const TType *fieldType = field->type(); + if (!IsSampler(fieldType->getBasicType())) + { + ctorParameters.push_back(*fieldType); + } } + constructorFunctionName = TString(name); } else if (parameters) { - for (TIntermSequence::const_iterator parameter = parameters->begin(); parameter != parameters->end(); parameter++) + for (auto parameter : *parameters) { - ctorParameters.push_back((*parameter)->getAsTyped()->getType()); + const TType ¶mType = parameter->getAsTyped()->getType(); + ctorParameters.push_back(paramType); } + constructorFunctionName = TString(name) + DisambiguateFunctionName(parameters); } else UNREACHABLE(); @@ -283,7 +297,7 @@ void StructureHLSL::addConstructor(const TType &type, const TString &name, const } else // Built-in type { - constructor += TypeString(ctorType) + " " + name + "("; + constructor += TypeString(ctorType) + " " + constructorFunctionName + "("; } for (unsigned int parameter = 0; parameter < ctorParameters.size(); parameter++) @@ -303,7 +317,15 @@ void StructureHLSL::addConstructor(const TType &type, const TString &name, const if (ctorType.getStruct()) { - constructor += " " + name + " structure = {"; + constructor += " " + name + " structure"; + if (ctorParameters.empty()) + { + constructor += ";\n"; + } + else + { + constructor += " = { "; + } } else { @@ -362,7 +384,15 @@ void StructureHLSL::addConstructor(const TType &type, const TString &name, const } else { - size_t remainingComponents = ctorType.getObjectSize(); + size_t remainingComponents = 0; + if (ctorType.getStruct()) + { + remainingComponents = ctorParameters.size(); + } + else + { + remainingComponents = ctorType.getObjectSize(); + } size_t parameterIndex = 0; while (remainingComponents > 0) @@ -375,10 +405,9 @@ void StructureHLSL::addConstructor(const TType &type, const TString &name, const if (ctorType.getStruct()) { - ASSERT(remainingComponents == parameterSize || moreParameters); - ASSERT(parameterSize <= remainingComponents); + ASSERT(remainingComponents == 1 || moreParameters); - remainingComponents -= parameterSize; + --remainingComponents; } else if (parameter.isScalar()) { @@ -454,9 +483,13 @@ void StructureHLSL::addConstructor(const TType &type, const TString &name, const if (ctorType.getStruct()) { - constructor += "};\n" - " return structure;\n" - "}\n"; + if (!ctorParameters.empty()) + { + constructor += "};\n"; + } + constructor += + " return structure;\n" + "}\n"; } else { @@ -465,6 +498,8 @@ void StructureHLSL::addConstructor(const TType &type, const TString &name, const } mConstructors.insert(constructor); + + return constructorFunctionName; } std::string StructureHLSL::structsHeader() const diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/StructureHLSL.h b/Source/ThirdParty/ANGLE/src/compiler/translator/StructureHLSL.h index cffe2a41ae05..96139ec9a7ce 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/StructureHLSL.h +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/StructureHLSL.h @@ -49,7 +49,11 @@ class StructureHLSL : angle::NonCopyable public: StructureHLSL(); - void addConstructor(const TType &type, const TString &name, const TIntermSequence *parameters); + // Returns the name of the constructor function. "name" parameter is the name of the type being + // constructed. + TString addConstructor(const TType &type, + const TString &name, + const TIntermSequence *parameters); std::string structsHeader() const; TString defineQualified(const TStructure &structure, bool useHLSLRowMajorPacking, bool useStd140Packing); diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/SymbolTable.cpp b/Source/ThirdParty/ANGLE/src/compiler/translator/SymbolTable.cpp index 9525040f5c42..f5789091425e 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/SymbolTable.cpp +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/SymbolTable.cpp @@ -14,6 +14,7 @@ #endif #include "compiler/translator/SymbolTable.h" +#include "compiler/translator/Cache.h" #include #include @@ -29,6 +30,18 @@ TFunction::~TFunction() delete (*i).type; } +const TString *TFunction::buildMangledName() const +{ + std::string newName = mangleName(getName()).c_str(); + + for (const auto &p : parameters) + { + newName += p.type->getMangledName().c_str(); + } + + return NewPoolTString(newName.c_str()); +} + // // Symbol table levels are a map of pointers to symbols that have to be deleted. // @@ -139,7 +152,7 @@ bool IsVecType(const TType *type) return false; } -TType *SpecificType(TType *type, int size) +const TType *SpecificType(const TType *type, int size) { ASSERT(size >= 1 && size <= 4); @@ -152,15 +165,15 @@ TType *SpecificType(TType *type, int size) switch(type->getBasicType()) { - case EbtGenType: return new TType(EbtFloat, static_cast(size)); - case EbtGenIType: return new TType(EbtInt, static_cast(size)); - case EbtGenUType: return new TType(EbtUInt, static_cast(size)); - case EbtGenBType: return new TType(EbtBool, static_cast(size)); + case EbtGenType: return TCache::getType(EbtFloat, static_cast(size)); + case EbtGenIType: return TCache::getType(EbtInt, static_cast(size)); + case EbtGenUType: return TCache::getType(EbtUInt, static_cast(size)); + case EbtGenBType: return TCache::getType(EbtBool, static_cast(size)); default: return type; } } -TType *VectorType(TType *type, int size) +const TType *VectorType(const TType *type, int size) { ASSERT(size >= 2 && size <= 4); @@ -173,48 +186,53 @@ TType *VectorType(TType *type, int size) switch(type->getBasicType()) { - case EbtVec: return new TType(EbtFloat, static_cast(size)); - case EbtIVec: return new TType(EbtInt, static_cast(size)); - case EbtUVec: return new TType(EbtUInt, static_cast(size)); - case EbtBVec: return new TType(EbtBool, static_cast(size)); + case EbtVec: return TCache::getType(EbtFloat, static_cast(size)); + case EbtIVec: return TCache::getType(EbtInt, static_cast(size)); + case EbtUVec: return TCache::getType(EbtUInt, static_cast(size)); + case EbtBVec: return TCache::getType(EbtBool, static_cast(size)); default: return type; } } -void TSymbolTable::insertBuiltIn(ESymbolLevel level, TOperator op, const char *ext, TType *rvalue, const char *name, - TType *ptype1, TType *ptype2, TType *ptype3, TType *ptype4, TType *ptype5) +void TSymbolTable::insertBuiltIn(ESymbolLevel level, TOperator op, const char *ext, const TType *rvalue, const char *name, + const TType *ptype1, const TType *ptype2, const TType *ptype3, const TType *ptype4, const TType *ptype5) { if (ptype1->getBasicType() == EbtGSampler2D) { + insertUnmangledBuiltIn(name); bool gvec4 = (rvalue->getBasicType() == EbtGVec4); - insertBuiltIn(level, gvec4 ? new TType(EbtFloat, 4) : rvalue, name, new TType(EbtSampler2D), ptype2, ptype3, ptype4, ptype5); - insertBuiltIn(level, gvec4 ? new TType(EbtInt, 4) : rvalue, name, new TType(EbtISampler2D), ptype2, ptype3, ptype4, ptype5); - insertBuiltIn(level, gvec4 ? new TType(EbtUInt, 4) : rvalue, name, new TType(EbtUSampler2D), ptype2, ptype3, ptype4, ptype5); + insertBuiltIn(level, gvec4 ? TCache::getType(EbtFloat, 4) : rvalue, name, TCache::getType(EbtSampler2D), ptype2, ptype3, ptype4, ptype5); + insertBuiltIn(level, gvec4 ? TCache::getType(EbtInt, 4) : rvalue, name, TCache::getType(EbtISampler2D), ptype2, ptype3, ptype4, ptype5); + insertBuiltIn(level, gvec4 ? TCache::getType(EbtUInt, 4) : rvalue, name, TCache::getType(EbtUSampler2D), ptype2, ptype3, ptype4, ptype5); } else if (ptype1->getBasicType() == EbtGSampler3D) { + insertUnmangledBuiltIn(name); bool gvec4 = (rvalue->getBasicType() == EbtGVec4); - insertBuiltIn(level, gvec4 ? new TType(EbtFloat, 4) : rvalue, name, new TType(EbtSampler3D), ptype2, ptype3, ptype4, ptype5); - insertBuiltIn(level, gvec4 ? new TType(EbtInt, 4) : rvalue, name, new TType(EbtISampler3D), ptype2, ptype3, ptype4, ptype5); - insertBuiltIn(level, gvec4 ? new TType(EbtUInt, 4) : rvalue, name, new TType(EbtUSampler3D), ptype2, ptype3, ptype4, ptype5); + insertBuiltIn(level, gvec4 ? TCache::getType(EbtFloat, 4) : rvalue, name, TCache::getType(EbtSampler3D), ptype2, ptype3, ptype4, ptype5); + insertBuiltIn(level, gvec4 ? TCache::getType(EbtInt, 4) : rvalue, name, TCache::getType(EbtISampler3D), ptype2, ptype3, ptype4, ptype5); + insertBuiltIn(level, gvec4 ? TCache::getType(EbtUInt, 4) : rvalue, name, TCache::getType(EbtUSampler3D), ptype2, ptype3, ptype4, ptype5); } else if (ptype1->getBasicType() == EbtGSamplerCube) { + insertUnmangledBuiltIn(name); bool gvec4 = (rvalue->getBasicType() == EbtGVec4); - insertBuiltIn(level, gvec4 ? new TType(EbtFloat, 4) : rvalue, name, new TType(EbtSamplerCube), ptype2, ptype3, ptype4, ptype5); - insertBuiltIn(level, gvec4 ? new TType(EbtInt, 4) : rvalue, name, new TType(EbtISamplerCube), ptype2, ptype3, ptype4, ptype5); - insertBuiltIn(level, gvec4 ? new TType(EbtUInt, 4) : rvalue, name, new TType(EbtUSamplerCube), ptype2, ptype3, ptype4, ptype5); + insertBuiltIn(level, gvec4 ? TCache::getType(EbtFloat, 4) : rvalue, name, TCache::getType(EbtSamplerCube), ptype2, ptype3, ptype4, ptype5); + insertBuiltIn(level, gvec4 ? TCache::getType(EbtInt, 4) : rvalue, name, TCache::getType(EbtISamplerCube), ptype2, ptype3, ptype4, ptype5); + insertBuiltIn(level, gvec4 ? TCache::getType(EbtUInt, 4) : rvalue, name, TCache::getType(EbtUSamplerCube), ptype2, ptype3, ptype4, ptype5); } else if (ptype1->getBasicType() == EbtGSampler2DArray) { + insertUnmangledBuiltIn(name); bool gvec4 = (rvalue->getBasicType() == EbtGVec4); - insertBuiltIn(level, gvec4 ? new TType(EbtFloat, 4) : rvalue, name, new TType(EbtSampler2DArray), ptype2, ptype3, ptype4, ptype5); - insertBuiltIn(level, gvec4 ? new TType(EbtInt, 4) : rvalue, name, new TType(EbtISampler2DArray), ptype2, ptype3, ptype4, ptype5); - insertBuiltIn(level, gvec4 ? new TType(EbtUInt, 4) : rvalue, name, new TType(EbtUSampler2DArray), ptype2, ptype3, ptype4, ptype5); + insertBuiltIn(level, gvec4 ? TCache::getType(EbtFloat, 4) : rvalue, name, TCache::getType(EbtSampler2DArray), ptype2, ptype3, ptype4, ptype5); + insertBuiltIn(level, gvec4 ? TCache::getType(EbtInt, 4) : rvalue, name, TCache::getType(EbtISampler2DArray), ptype2, ptype3, ptype4, ptype5); + insertBuiltIn(level, gvec4 ? TCache::getType(EbtUInt, 4) : rvalue, name, TCache::getType(EbtUSampler2DArray), ptype2, ptype3, ptype4, ptype5); } else if (IsGenType(rvalue) || IsGenType(ptype1) || IsGenType(ptype2) || IsGenType(ptype3)) { ASSERT(!ptype4 && !ptype5); + insertUnmangledBuiltIn(name); insertBuiltIn(level, op, ext, SpecificType(rvalue, 1), name, SpecificType(ptype1, 1), SpecificType(ptype2, 1), SpecificType(ptype3, 1)); insertBuiltIn(level, op, ext, SpecificType(rvalue, 2), name, SpecificType(ptype1, 2), SpecificType(ptype2, 2), SpecificType(ptype3, 2)); insertBuiltIn(level, op, ext, SpecificType(rvalue, 3), name, SpecificType(ptype1, 3), SpecificType(ptype2, 3), SpecificType(ptype3, 3)); @@ -223,41 +241,38 @@ void TSymbolTable::insertBuiltIn(ESymbolLevel level, TOperator op, const char *e else if (IsVecType(rvalue) || IsVecType(ptype1) || IsVecType(ptype2) || IsVecType(ptype3)) { ASSERT(!ptype4 && !ptype5); + insertUnmangledBuiltIn(name); insertBuiltIn(level, op, ext, VectorType(rvalue, 2), name, VectorType(ptype1, 2), VectorType(ptype2, 2), VectorType(ptype3, 2)); insertBuiltIn(level, op, ext, VectorType(rvalue, 3), name, VectorType(ptype1, 3), VectorType(ptype2, 3), VectorType(ptype3, 3)); insertBuiltIn(level, op, ext, VectorType(rvalue, 4), name, VectorType(ptype1, 4), VectorType(ptype2, 4), VectorType(ptype3, 4)); } else { - TFunction *function = new TFunction(NewPoolTString(name), *rvalue, op, ext); + TFunction *function = new TFunction(NewPoolTString(name), rvalue, op, ext); - TParameter param1 = {0, ptype1}; - function->addParameter(param1); + function->addParameter(TConstParameter(ptype1)); if (ptype2) { - TParameter param2 = {0, ptype2}; - function->addParameter(param2); + function->addParameter(TConstParameter(ptype2)); } if (ptype3) { - TParameter param3 = {0, ptype3}; - function->addParameter(param3); + function->addParameter(TConstParameter(ptype3)); } if (ptype4) { - TParameter param4 = {0, ptype4}; - function->addParameter(param4); + function->addParameter(TConstParameter(ptype4)); } if (ptype5) { - TParameter param5 = {0, ptype5}; - function->addParameter(param5); + function->addParameter(TConstParameter(ptype5)); } + ASSERT(hasUnmangledBuiltIn(name)); insert(level, function); } } @@ -272,7 +287,7 @@ TPrecision TSymbolTable::getDefaultPrecision(TBasicType type) const int level = static_cast(precisionStack.size()) - 1; assert(level >= 0); // Just to be safe. Should not happen. - // If we dont find anything we return this. Should we error check this? + // If we dont find anything we return this. Some types don't have predefined default precision. TPrecision prec = EbpUndefined; while (level >= 0) { diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/SymbolTable.h b/Source/ThirdParty/ANGLE/src/compiler/translator/SymbolTable.h index 8ccb443349df..6de7c988300b 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/SymbolTable.h +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/SymbolTable.h @@ -109,13 +109,8 @@ class TVariable : public TSymbol unionArray(0) { } - virtual ~TVariable() - { - } - virtual bool isVariable() const - { - return true; - } + ~TVariable() override {} + bool isVariable() const override { return true; } TType &getType() { return type; @@ -133,40 +128,67 @@ class TVariable : public TSymbol type.setQualifier(qualifier); } - TConstantUnion *getConstPointer() - { - if (!unionArray) - unionArray = new TConstantUnion[type.getObjectSize()]; - - return unionArray; - } - - TConstantUnion *getConstPointer() const - { - return unionArray; - } + const TConstantUnion *getConstPointer() const { return unionArray; } - void shareConstPointer(TConstantUnion *constArray) - { - if (unionArray == constArray) - return; - - delete[] unionArray; - unionArray = constArray; - } + void shareConstPointer(const TConstantUnion *constArray) { unionArray = constArray; } private: TType type; bool userType; // we are assuming that Pool Allocator will free the memory // allocated to unionArray when this object is destroyed. - TConstantUnion *unionArray; + const TConstantUnion *unionArray; +}; + +// Immutable version of TParameter. +struct TConstParameter +{ + TConstParameter() + : name(nullptr), + type(nullptr) + { + } + explicit TConstParameter(const TString *n) + : name(n), + type(nullptr) + { + } + explicit TConstParameter(const TType *t) + : name(nullptr), + type(t) + { + } + TConstParameter(const TString *n, const TType *t) + : name(n), + type(t) + { + } + + // Both constructor arguments must be const. + TConstParameter(TString *n, TType *t) = delete; + TConstParameter(const TString *n, TType *t) = delete; + TConstParameter(TString *n, const TType *t) = delete; + + const TString *name; + const TType *type; }; // The function sub-class of symbols and the parser will need to // share this definition of a function parameter. struct TParameter { + // Destructively converts to TConstParameter. + // This method resets name and type to nullptrs to make sure + // their content cannot be modified after the call. + TConstParameter turnToConst() + { + const TString *constName = name; + const TType *constType = type; + name = nullptr; + type = nullptr; + return TConstParameter(constName, constType); + } + TString *name; TType *type; }; @@ -175,27 +197,21 @@ struct TParameter class TFunction : public TSymbol { public: - TFunction(TOperator o) - : TSymbol(0), - returnType(TType(EbtVoid, EbpUndefined)), - op(o), - defined(false) - { - } - TFunction(const TString *name, const TType &retType, TOperator tOp = EOpNull, const char *ext = "") + TFunction(const TString *name, + const TType *retType, + TOperator tOp = EOpNull, + const char *ext = "") : TSymbol(name), returnType(retType), - mangledName(TFunction::mangleName(*name)), + mangledName(nullptr), op(tOp), - defined(false) + defined(false), + mHasPrototypeDeclaration(false) { relateToExtension(ext); } - virtual ~TFunction(); - virtual bool isFunction() const - { - return true; - } + ~TFunction() override; + bool isFunction() const override { return true; } static TString mangleName(const TString &name) { @@ -206,19 +222,23 @@ class TFunction : public TSymbol return TString(mangledName.c_str(), mangledName.find_first_of('(')); } - void addParameter(TParameter &p) - { + void addParameter(const TConstParameter &p) + { parameters.push_back(p); - mangledName = mangledName + p.type->getMangledName(); + mangledName = nullptr; } - const TString &getMangledName() const + const TString &getMangledName() const override { - return mangledName; + if (mangledName == nullptr) + { + mangledName = buildMangledName(); + } + return *mangledName; } const TType &getReturnType() const { - return returnType; + return *returnType; } TOperator getBuiltInOp() const @@ -226,31 +246,30 @@ class TFunction : public TSymbol return op; } - void setDefined() - { - defined = true; - } - bool isDefined() - { - return defined; - } + void setDefined() { defined = true; } + bool isDefined() { return defined; } + void setHasPrototypeDeclaration() { mHasPrototypeDeclaration = true; } + bool hasPrototypeDeclaration() const { return mHasPrototypeDeclaration; } size_t getParamCount() const { return parameters.size(); } - const TParameter &getParam(size_t i) const + const TConstParameter &getParam(size_t i) const { return parameters[i]; } private: - typedef TVector TParamList; + const TString *buildMangledName() const; + + typedef TVector TParamList; TParamList parameters; - TType returnType; - TString mangledName; + const TType *returnType; + mutable const TString *mangledName; TOperator op; bool defined; + bool mHasPrototypeDeclaration; }; // Interface block name sub-symbol @@ -364,28 +383,43 @@ class TSymbolTable : angle::NonCopyable { TVariable *constant = new TVariable( NewPoolTString(name), TType(EbtInt, EbpUndefined, EvqConst, 1)); - constant->getConstPointer()->setIConst(value); + TConstantUnion *unionArray = new TConstantUnion[1]; + unionArray[0].setIConst(value); + constant->shareConstPointer(unionArray); return insert(level, constant); } - void insertBuiltIn(ESymbolLevel level, TOperator op, const char *ext, TType *rvalue, const char *name, - TType *ptype1, TType *ptype2 = 0, TType *ptype3 = 0, TType *ptype4 = 0, TType *ptype5 = 0); + bool insertConstIntExt(ESymbolLevel level, const char *ext, const char *name, int value) + { + TVariable *constant = + new TVariable(NewPoolTString(name), TType(EbtInt, EbpUndefined, EvqConst, 1)); + TConstantUnion *unionArray = new TConstantUnion[1]; + unionArray[0].setIConst(value); + constant->shareConstPointer(unionArray); + return insert(level, ext, constant); + } + + void insertBuiltIn(ESymbolLevel level, TOperator op, const char *ext, const TType *rvalue, const char *name, + const TType *ptype1, const TType *ptype2 = 0, const TType *ptype3 = 0, const TType *ptype4 = 0, const TType *ptype5 = 0); - void insertBuiltIn(ESymbolLevel level, TType *rvalue, const char *name, - TType *ptype1, TType *ptype2 = 0, TType *ptype3 = 0, TType *ptype4 = 0, TType *ptype5 = 0) + void insertBuiltIn(ESymbolLevel level, const TType *rvalue, const char *name, + const TType *ptype1, const TType *ptype2 = 0, const TType *ptype3 = 0, const TType *ptype4 = 0, const TType *ptype5 = 0) { + insertUnmangledBuiltIn(name); insertBuiltIn(level, EOpNull, "", rvalue, name, ptype1, ptype2, ptype3, ptype4, ptype5); } - void insertBuiltIn(ESymbolLevel level, const char *ext, TType *rvalue, const char *name, - TType *ptype1, TType *ptype2 = 0, TType *ptype3 = 0, TType *ptype4 = 0, TType *ptype5 = 0) + void insertBuiltIn(ESymbolLevel level, const char *ext, const TType *rvalue, const char *name, + const TType *ptype1, const TType *ptype2 = 0, const TType *ptype3 = 0, const TType *ptype4 = 0, const TType *ptype5 = 0) { + insertUnmangledBuiltIn(name); insertBuiltIn(level, EOpNull, ext, rvalue, name, ptype1, ptype2, ptype3, ptype4, ptype5); } - void insertBuiltIn(ESymbolLevel level, TOperator op, TType *rvalue, const char *name, - TType *ptype1, TType *ptype2 = 0, TType *ptype3 = 0, TType *ptype4 = 0, TType *ptype5 = 0) + void insertBuiltIn(ESymbolLevel level, TOperator op, const TType *rvalue, const char *name, + const TType *ptype1, const TType *ptype2 = 0, const TType *ptype3 = 0, const TType *ptype4 = 0, const TType *ptype5 = 0) { + insertUnmangledBuiltIn(name); insertBuiltIn(level, op, "", rvalue, name, ptype1, ptype2, ptype3, ptype4, ptype5); } @@ -405,6 +439,8 @@ class TSymbolTable : angle::NonCopyable { if (!SupportsPrecision(type.type)) return false; + if (type.type == EbtUInt) + return false; // ESSL 3.00.4 section 4.5.4 if (type.isAggregate()) return false; // Not allowed to set for aggregate types int indexOfLastElement = static_cast(precisionStack.size()) - 1; @@ -441,16 +477,29 @@ class TSymbolTable : angle::NonCopyable return ++uniqueIdCounter; } + bool hasUnmangledBuiltIn(const char *name) + { + return mUnmangledBuiltinNames.count(std::string(name)) > 0; + } + private: ESymbolLevel currentLevel() const { return static_cast(table.size() - 1); } + // Used to insert unmangled functions to check redeclaration of built-ins in ESSL 3.00. + void insertUnmangledBuiltIn(const char *name) + { + mUnmangledBuiltinNames.insert(std::string(name)); + } + std::vector table; typedef TMap PrecisionStackLevel; std::vector< PrecisionStackLevel *> precisionStack; + std::set mUnmangledBuiltinNames; + std::set mInvariantVaryings; bool mGlobalInvariant; diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/TranslatorESSL.cpp b/Source/ThirdParty/ANGLE/src/compiler/translator/TranslatorESSL.cpp index 238bc97576ad..76d006fd11dd 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/TranslatorESSL.cpp +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/TranslatorESSL.cpp @@ -8,6 +8,7 @@ #include "compiler/translator/BuiltInFunctionEmulatorGLSL.h" #include "compiler/translator/EmulatePrecision.h" +#include "compiler/translator/RecordConstantPrecision.h" #include "compiler/translator/OutputESSL.h" #include "angle_gl.h" @@ -19,16 +20,18 @@ TranslatorESSL::TranslatorESSL(sh::GLenum type, ShShaderSpec spec) void TranslatorESSL::initBuiltInFunctionEmulator(BuiltInFunctionEmulator *emu, int compileOptions) { if (compileOptions & SH_EMULATE_BUILT_IN_FUNCTIONS) - InitBuiltInFunctionEmulatorForGLSL(emu, getShaderType()); + { + InitBuiltInFunctionEmulatorForGLSLWorkarounds(emu, getShaderType()); + } } void TranslatorESSL::translate(TIntermNode *root, int) { TInfoSinkBase& sink = getInfoSink().obj; - int shaderVersion = getShaderVersion(); - if (shaderVersion > 100) + int shaderVer = getShaderVersion(); + if (shaderVer > 100) { - sink << "#version " << shaderVersion << " es\n"; + sink << "#version " << shaderVer << " es\n"; } writePragma(); @@ -40,12 +43,14 @@ void TranslatorESSL::translate(TIntermNode *root, int) { if (precisionEmulation) { - EmulatePrecision emulatePrecision; + EmulatePrecision emulatePrecision(getSymbolTable(), shaderVer); root->traverse(&emulatePrecision); emulatePrecision.updateTree(); emulatePrecision.writeEmulationHelpers(sink, SH_ESSL_OUTPUT); } + RecordConstantPrecision(root, getTemporaryIndex()); + // Write emulated built-in functions if needed. if (!getBuiltInFunctionEmulator().IsOutputEmpty()) { @@ -71,13 +76,8 @@ void TranslatorESSL::translate(TIntermNode *root, int) { getArrayBoundsClamper().OutputClampingFunctionDefinition(sink); // Write translated shader. - TOutputESSL outputESSL(sink, - getArrayIndexClampingStrategy(), - getHashFunction(), - getNameMap(), - getSymbolTable(), - shaderVersion, - precisionEmulation); + TOutputESSL outputESSL(sink, getArrayIndexClampingStrategy(), getHashFunction(), getNameMap(), + getSymbolTable(), shaderVer, precisionEmulation); root->traverse(&outputESSL); } diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/TranslatorESSL.h b/Source/ThirdParty/ANGLE/src/compiler/translator/TranslatorESSL.h index c2c1b01b42bf..2cc61074d489 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/TranslatorESSL.h +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/TranslatorESSL.h @@ -17,7 +17,7 @@ class TranslatorESSL : public TCompiler protected: void initBuiltInFunctionEmulator(BuiltInFunctionEmulator *emu, int compileOptions) override; - virtual void translate(TIntermNode *root, int compileOptions) override; + void translate(TIntermNode *root, int compileOptions) override; private: void writeExtensionBehavior(); diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/TranslatorGLSL.cpp b/Source/ThirdParty/ANGLE/src/compiler/translator/TranslatorGLSL.cpp index c76a7ab6ff78..05e9eb310bad 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/TranslatorGLSL.cpp +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/TranslatorGLSL.cpp @@ -9,53 +9,10 @@ #include "angle_gl.h" #include "compiler/translator/BuiltInFunctionEmulatorGLSL.h" #include "compiler/translator/EmulatePrecision.h" +#include "compiler/translator/ExtensionGLSL.h" #include "compiler/translator/OutputGLSL.h" #include "compiler/translator/VersionGLSL.h" -namespace -{ - -// To search for what output variables are used in a fragment shader. -// We handle gl_FragColor and gl_FragData at the moment. -class TFragmentOutSearcher : public TIntermTraverser -{ - public: - TFragmentOutSearcher() - : mUsesGlFragColor(false), - mUsesGlFragData(false) - { - } - - bool usesGlFragColor() const - { - return mUsesGlFragColor; - } - - bool usesGlFragData() const - { - return mUsesGlFragData; - } - - protected: - virtual void visitSymbol(TIntermSymbol *node) override - { - if (node->getSymbol() == "gl_FragColor") - { - mUsesGlFragColor = true; - } - else if (node->getSymbol() == "gl_FragData") - { - mUsesGlFragData = true; - } - } - - private: - bool mUsesGlFragColor; - bool mUsesGlFragData; -}; - -} // namespace anonymous - TranslatorGLSL::TranslatorGLSL(sh::GLenum type, ShShaderSpec spec, ShShaderOutput output) @@ -65,10 +22,16 @@ TranslatorGLSL::TranslatorGLSL(sh::GLenum type, void TranslatorGLSL::initBuiltInFunctionEmulator(BuiltInFunctionEmulator *emu, int compileOptions) { if (compileOptions & SH_EMULATE_BUILT_IN_FUNCTIONS) - InitBuiltInFunctionEmulatorForGLSL(emu, getShaderType()); + { + InitBuiltInFunctionEmulatorForGLSLWorkarounds(emu, getShaderType()); + } + + int targetGLSLVersion = ShaderOutputTypeToGLSLVersion(getOutputType()); + InitBuiltInFunctionEmulatorForGLSLMissingFunctions(emu, getShaderType(), targetGLSLVersion); } -void TranslatorGLSL::translate(TIntermNode *root, int) { +void TranslatorGLSL::translate(TIntermNode *root, int compileOptions) +{ TInfoSinkBase& sink = getInfoSink().obj; // Write GLSL version. @@ -77,13 +40,13 @@ void TranslatorGLSL::translate(TIntermNode *root, int) { writePragma(); // Write extension behaviour as needed - writeExtensionBehavior(); + writeExtensionBehavior(root); bool precisionEmulation = getResources().WEBGL_debug_shader_precision && getPragma().debugShaderPrecision; if (precisionEmulation) { - EmulatePrecision emulatePrecision; + EmulatePrecision emulatePrecision(getSymbolTable(), getShaderVersion()); root->traverse(&emulatePrecision); emulatePrecision.updateTree(); emulatePrecision.writeEmulationHelpers(sink, getOutputType()); @@ -103,19 +66,70 @@ void TranslatorGLSL::translate(TIntermNode *root, int) { // Declare gl_FragColor and glFragData as webgl_FragColor and webgl_FragData // if it's core profile shaders and they are used. - if (getShaderType() == GL_FRAGMENT_SHADER && IsGLSL130OrNewer(getOutputType())) + if (getShaderType() == GL_FRAGMENT_SHADER) { - TFragmentOutSearcher searcher; - root->traverse(&searcher); - ASSERT(!(searcher.usesGlFragData() && searcher.usesGlFragColor())); - if (searcher.usesGlFragColor()) + const bool mayHaveESSL1SecondaryOutputs = + IsExtensionEnabled(getExtensionBehavior(), "GL_EXT_blend_func_extended") && + getShaderVersion() == 100; + const bool declareGLFragmentOutputs = IsGLSL130OrNewer(getOutputType()); + + bool hasGLFragColor = false; + bool hasGLFragData = false; + bool hasGLSecondaryFragColor = false; + bool hasGLSecondaryFragData = false; + + for (const auto &outputVar : outputVariables) + { + if (declareGLFragmentOutputs) + { + if (outputVar.name == "gl_FragColor") + { + ASSERT(!hasGLFragColor); + hasGLFragColor = true; + continue; + } + else if (outputVar.name == "gl_FragData") + { + ASSERT(!hasGLFragData); + hasGLFragData = true; + continue; + } + } + if (mayHaveESSL1SecondaryOutputs) + { + if (outputVar.name == "gl_SecondaryFragColorEXT") + { + ASSERT(!hasGLSecondaryFragColor); + hasGLSecondaryFragColor = true; + continue; + } + else if (outputVar.name == "gl_SecondaryFragDataEXT") + { + ASSERT(!hasGLSecondaryFragData); + hasGLSecondaryFragData = true; + continue; + } + } + } + ASSERT(!((hasGLFragColor || hasGLSecondaryFragColor) && + (hasGLFragData || hasGLSecondaryFragData))); + if (hasGLFragColor) { sink << "out vec4 webgl_FragColor;\n"; } - if (searcher.usesGlFragData()) + if (hasGLFragData) { sink << "out vec4 webgl_FragData[gl_MaxDrawBuffers];\n"; } + if (hasGLSecondaryFragColor) + { + sink << "out vec4 angle_SecondaryFragColor;\n"; + } + if (hasGLSecondaryFragData) + { + sink << "out vec4 angle_SecondaryFragData[" << getResources().MaxDualSourceDrawBuffers + << "];\n"; + } } // Write translated shader. @@ -143,19 +157,41 @@ void TranslatorGLSL::writeVersion(TIntermNode *root) } } -void TranslatorGLSL::writeExtensionBehavior() { +void TranslatorGLSL::writeExtensionBehavior(TIntermNode *root) +{ TInfoSinkBase& sink = getInfoSink().obj; const TExtensionBehavior& extBehavior = getExtensionBehavior(); - for (TExtensionBehavior::const_iterator iter = extBehavior.begin(); - iter != extBehavior.end(); ++iter) { - if (iter->second == EBhUndefined) + for (const auto &iter : extBehavior) + { + if (iter.second == EBhUndefined) + { continue; + } // For GLSL output, we don't need to emit most extensions explicitly, // but some we need to translate. - if (iter->first == "GL_EXT_shader_texture_lod") { - sink << "#extension GL_ARB_shader_texture_lod : " - << getBehaviorString(iter->second) << "\n"; + if (iter.first == "GL_EXT_shader_texture_lod") + { + sink << "#extension GL_ARB_shader_texture_lod : " << getBehaviorString(iter.second) + << "\n"; } } + + // GLSL ES 3 explicit location qualifiers need to use an extension before GLSL 330 + if (getShaderVersion() >= 300 && getOutputType() < SH_GLSL_330_CORE_OUTPUT) + { + sink << "#extension GL_ARB_explicit_attrib_location : require\n"; + } + + TExtensionGLSL extensionGLSL(getOutputType()); + root->traverse(&extensionGLSL); + + for (const auto &ext : extensionGLSL.getEnabledExtensions()) + { + sink << "#extension " << ext << " : enable\n"; + } + for (const auto &ext : extensionGLSL.getRequiredExtensions()) + { + sink << "#extension " << ext << " : require\n"; + } } diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/TranslatorGLSL.h b/Source/ThirdParty/ANGLE/src/compiler/translator/TranslatorGLSL.h index 2b9dc30568c1..4f07b2198006 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/TranslatorGLSL.h +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/TranslatorGLSL.h @@ -17,11 +17,11 @@ class TranslatorGLSL : public TCompiler protected: void initBuiltInFunctionEmulator(BuiltInFunctionEmulator *emu, int compileOptions) override; - virtual void translate(TIntermNode *root, int compileOptions) override; + void translate(TIntermNode *root, int compileOptions) override; private: void writeVersion(TIntermNode *root); - void writeExtensionBehavior(); + void writeExtensionBehavior(TIntermNode *root); }; #endif // COMPILER_TRANSLATOR_TRANSLATORGLSL_H_ diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/TranslatorHLSL.cpp b/Source/ThirdParty/ANGLE/src/compiler/translator/TranslatorHLSL.cpp index a59b65ece4aa..2940260e71a8 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/TranslatorHLSL.cpp +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/TranslatorHLSL.cpp @@ -8,9 +8,12 @@ #include "compiler/translator/ArrayReturnValueToOutParameter.h" #include "compiler/translator/OutputHLSL.h" +#include "compiler/translator/RemoveDynamicIndexing.h" +#include "compiler/translator/RewriteElseBlocks.h" #include "compiler/translator/SeparateArrayInitialization.h" #include "compiler/translator/SeparateDeclarations.h" -#include "compiler/translator/SimplifyArrayAssignment.h" +#include "compiler/translator/SeparateExpressionsReturningArrays.h" +#include "compiler/translator/UnfoldShortCircuitToIf.h" TranslatorHLSL::TranslatorHLSL(sh::GLenum type, ShShaderSpec spec, ShShaderOutput output) : TCompiler(type, spec, output) @@ -22,17 +25,32 @@ void TranslatorHLSL::translate(TIntermNode *root, int compileOptions) const ShBuiltInResources &resources = getResources(); int numRenderTargets = resources.EXT_draw_buffers ? resources.MaxDrawBuffers : 1; - SeparateArrayDeclarations(root); + SeparateDeclarations(root); + + // Note that SeparateDeclarations needs to be run before UnfoldShortCircuitToIf. + UnfoldShortCircuitToIf(root, getTemporaryIndex()); + + SeparateExpressionsReturningArrays(root, getTemporaryIndex()); // Note that SeparateDeclarations needs to be run before SeparateArrayInitialization. SeparateArrayInitialization(root); - SimplifyArrayAssignment simplify; - root->traverse(&simplify); - // HLSL doesn't support arrays as return values, we'll need to make functions that have an array // as a return value to use an out parameter to transfer the array data instead. - ArrayReturnValueToOutParameter(root); + ArrayReturnValueToOutParameter(root, getTemporaryIndex()); + + if (!shouldRunLoopAndIndexingValidation(compileOptions)) + { + // HLSL doesn't support dynamic indexing of vectors and matrices. + RemoveDynamicIndexing(root, getTemporaryIndex(), getSymbolTable(), getShaderVersion()); + } + + // Work around D3D9 bug that would manifest in vertex shaders with selection blocks which + // use a vertex attribute as a condition, and some related computation in the else block. + if (getOutputType() == SH_HLSL_3_0_OUTPUT && getShaderType() == GL_VERTEX_SHADER) + { + sh::RewriteElseBlocks(root, getTemporaryIndex()); + } sh::OutputHLSL outputHLSL(getShaderType(), getShaderVersion(), getExtensionBehavior(), getSourcePath(), getOutputType(), numRenderTargets, getUniforms(), compileOptions); @@ -54,13 +72,7 @@ unsigned int TranslatorHLSL::getInterfaceBlockRegister(const std::string &interf return mInterfaceBlockRegisterMap.find(interfaceBlockName)->second; } -bool TranslatorHLSL::hasUniform(const std::string &uniformName) const -{ - return (mUniformRegisterMap.count(uniformName) > 0); -} - -unsigned int TranslatorHLSL::getUniformRegister(const std::string &uniformName) const +const std::map *TranslatorHLSL::getUniformRegisterMap() const { - ASSERT(hasUniform(uniformName)); - return mUniformRegisterMap.find(uniformName)->second; + return &mUniformRegisterMap; } diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/TranslatorHLSL.h b/Source/ThirdParty/ANGLE/src/compiler/translator/TranslatorHLSL.h index 09032235f6a2..4e84612f2cd4 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/TranslatorHLSL.h +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/TranslatorHLSL.h @@ -13,16 +13,20 @@ class TranslatorHLSL : public TCompiler { public: TranslatorHLSL(sh::GLenum type, ShShaderSpec spec, ShShaderOutput output); - virtual TranslatorHLSL *getAsTranslatorHLSL() { return this; } +#ifdef ANGLE_ENABLE_HLSL + TranslatorHLSL *getAsTranslatorHLSL() override { return this; } +#endif bool hasInterfaceBlock(const std::string &interfaceBlockName) const; unsigned int getInterfaceBlockRegister(const std::string &interfaceBlockName) const; - bool hasUniform(const std::string &uniformName) const; - unsigned int getUniformRegister(const std::string &uniformName) const; + const std::map *getUniformRegisterMap() const; protected: - virtual void translate(TIntermNode *root, int compileOptions) override; + void translate(TIntermNode *root, int compileOptions) override; + + // collectVariables needs to be run always so registers can be assigned. + bool shouldCollectVariables(int compileOptions) override { return true; } std::map mInterfaceBlockRegisterMap; std::map mUniformRegisterMap; diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/Types.cpp b/Source/ThirdParty/ANGLE/src/compiler/translator/Types.cpp index 24b5e0c476c2..dffdd370aee5 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/Types.cpp +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/Types.cpp @@ -9,6 +9,8 @@ #endif #include "compiler/translator/Types.h" +#include "compiler/translator/InfoSink.h" +#include "compiler/translator/IntermNode.h" #include #include @@ -46,9 +48,9 @@ const char* getBasicString(TBasicType t) } TType::TType(const TPublicType &p) - : type(p.type), precision(p.precision), qualifier(p.qualifier), layoutQualifier(p.layoutQualifier), - primarySize(p.primarySize), secondarySize(p.secondarySize), array(p.array), arraySize(p.arraySize), - interfaceBlock(0), structure(0) + : type(p.type), precision(p.precision), qualifier(p.qualifier), invariant(p.invariant), + layoutQualifier(p.layoutQualifier), primarySize(p.primarySize), secondarySize(p.secondarySize), + array(p.array), arraySize(p.arraySize), interfaceBlock(0), structure(0) { if (p.userDef) structure = p.userDef->getStruct(); @@ -59,6 +61,27 @@ bool TStructure::equals(const TStructure &other) const return (uniqueId() == other.uniqueId()); } +TString TType::getCompleteString() const +{ + TStringStream stream; + + if (invariant) + stream << "invariant "; + if (qualifier != EvqTemporary && qualifier != EvqGlobal) + stream << getQualifierString() << " "; + if (precision != EbpUndefined) + stream << getPrecisionString() << " "; + if (array) + stream << "array[" << getArraySize() << "] of "; + if (isMatrix()) + stream << getCols() << "X" << getRows() << " matrix of "; + else if (isVector()) + stream << getNominalSize() << "-component vector of "; + + stream << getBasicString(); + return stream.str(); +} + // // Recursively generate mangled names. // @@ -201,6 +224,17 @@ bool TStructure::containsArrays() const return false; } +bool TStructure::containsType(TBasicType type) const +{ + for (size_t i = 0; i < mFields->size(); ++i) + { + const TType *fieldType = (*mFields)[i]->type(); + if (fieldType->getBasicType() == type || fieldType->isStructureContainingType(type)) + return true; + } + return false; +} + bool TStructure::containsSamplers() const { for (size_t i = 0; i < mFields->size(); ++i) @@ -212,9 +246,79 @@ bool TStructure::containsSamplers() const return false; } -TString TFieldListCollection::buildMangledName() const +void TStructure::createSamplerSymbols(const TString &structName, + const TString &structAPIName, + const int arrayOfStructsSize, + TVector *outputSymbols, + TMap *outputSymbolsToAPINames) const +{ + for (auto &field : *mFields) + { + const TType *fieldType = field->type(); + if (IsSampler(fieldType->getBasicType())) + { + if (arrayOfStructsSize > 0) + { + for (int arrayIndex = 0; arrayIndex < arrayOfStructsSize; ++arrayIndex) + { + TStringStream name; + name << structName << "_" << arrayIndex << "_" << field->name(); + TIntermSymbol *symbol = new TIntermSymbol(0, name.str(), *fieldType); + outputSymbols->push_back(symbol); + + if (outputSymbolsToAPINames) + { + TStringStream apiName; + apiName << structAPIName << "[" << arrayIndex << "]." << field->name(); + (*outputSymbolsToAPINames)[symbol] = apiName.str(); + } + } + } + else + { + TString symbolName = structName + "_" + field->name(); + TIntermSymbol *symbol = new TIntermSymbol(0, symbolName, *fieldType); + outputSymbols->push_back(symbol); + + if (outputSymbolsToAPINames) + { + TString apiName = structAPIName + "." + field->name(); + (*outputSymbolsToAPINames)[symbol] = apiName; + } + } + } + else if (fieldType->isStructureContainingSamplers()) + { + int nestedArrayOfStructsSize = fieldType->isArray() ? fieldType->getArraySize() : 0; + if (arrayOfStructsSize > 0) + { + for (int arrayIndex = 0; arrayIndex < arrayOfStructsSize; ++arrayIndex) + { + TStringStream fieldName; + fieldName << structName << "_" << arrayIndex << "_" << field->name(); + TStringStream fieldAPIName; + if (outputSymbolsToAPINames) + { + fieldAPIName << structAPIName << "[" << arrayIndex << "]." << field->name(); + } + fieldType->createSamplerSymbols(fieldName.str(), fieldAPIName.str(), + nestedArrayOfStructsSize, outputSymbols, + outputSymbolsToAPINames); + } + } + else + { + fieldType->createSamplerSymbols( + structName + "_" + field->name(), structAPIName + "." + field->name(), + nestedArrayOfStructsSize, outputSymbols, outputSymbolsToAPINames); + } + } + } +} + +TString TFieldListCollection::buildMangledName(const TString &mangledNamePrefix) const { - TString mangledName(mangledNamePrefix()); + TString mangledName(mangledNamePrefix); mangledName += *mName; for (size_t i = 0; i < mFields->size(); ++i) { diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/Types.h b/Source/ThirdParty/ANGLE/src/compiler/translator/Types.h index f81f93daa3a0..1a29e5068a3d 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/Types.h +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/Types.h @@ -16,6 +16,7 @@ struct TPublicType; class TType; class TSymbol; +class TIntermSymbol; class TField : angle::NonCopyable { @@ -73,12 +74,6 @@ class TFieldListCollection : angle::NonCopyable return *mFields; } - const TString &mangledName() const - { - if (mMangledName.empty()) - mMangledName = buildMangledName(); - return mMangledName; - } size_t objectSize() const { if (mObjectSize == 0) @@ -93,9 +88,8 @@ class TFieldListCollection : angle::NonCopyable mObjectSize(0) { } - TString buildMangledName() const; + TString buildMangledName(const TString &mangledNamePrefix) const; size_t calculateObjectSize() const; - virtual TString mangledNamePrefix() const = 0; const TString *mName; TFieldList *mFields; @@ -124,8 +118,15 @@ class TStructure : public TFieldListCollection return mDeepestNesting; } bool containsArrays() const; + bool containsType(TBasicType t) const; bool containsSamplers() const; + void createSamplerSymbols(const TString &structName, + const TString &structAPIName, + const int arrayOfStructsSize, + TVector *outputSymbols, + TMap *outputSymbolsToAPINames) const; + bool equals(const TStructure &other) const; void setUniqueId(int uniqueId) @@ -149,6 +150,13 @@ class TStructure : public TFieldListCollection return mAtGlobalScope; } + const TString &mangledName() const + { + if (mMangledName.empty()) + mMangledName = buildMangledName("struct-"); + return mMangledName; + } + private: // TODO(zmo): Find a way to get rid of the const_cast in function // setName(). At the moment keep this function private so only @@ -160,10 +168,6 @@ class TStructure : public TFieldListCollection *mutableName = name; } - virtual TString mangledNamePrefix() const - { - return "struct-"; - } int calculateDeepestNesting() const; mutable int mDeepestNesting; @@ -209,13 +213,14 @@ class TInterfaceBlock : public TFieldListCollection { return mMatrixPacking; } - - private: - virtual TString mangledNamePrefix() const + const TString &mangledName() const { - return "iblock-"; + if (mMangledName.empty()) + mMangledName = buildMangledName("iblock-"); + return mMangledName; } + private: const TString *mInstanceName; // for interface block instance names int mArraySize; // 0 if not an array TLayoutBlockStorage mBlockStorage; @@ -230,10 +235,14 @@ class TType public: POOL_ALLOCATOR_NEW_DELETE(); TType() + : type(EbtVoid), precision(EbpUndefined), qualifier(EvqGlobal), invariant(false), + layoutQualifier(TLayoutQualifier::create()), + primarySize(0), secondarySize(0), array(false), arraySize(0), + interfaceBlock(nullptr), structure(nullptr) { } TType(TBasicType t, unsigned char ps = 1, unsigned char ss = 1) - : type(t), precision(EbpUndefined), qualifier(EvqGlobal), + : type(t), precision(EbpUndefined), qualifier(EvqGlobal), invariant(false), layoutQualifier(TLayoutQualifier::create()), primarySize(ps), secondarySize(ss), array(false), arraySize(0), interfaceBlock(0), structure(0) @@ -241,7 +250,7 @@ class TType } TType(TBasicType t, TPrecision p, TQualifier q = EvqTemporary, unsigned char ps = 1, unsigned char ss = 1, bool a = false) - : type(t), precision(p), qualifier(q), + : type(t), precision(p), qualifier(q), invariant(false), layoutQualifier(TLayoutQualifier::create()), primarySize(ps), secondarySize(ss), array(a), arraySize(0), interfaceBlock(0), structure(0) @@ -249,7 +258,7 @@ class TType } explicit TType(const TPublicType &p); TType(TStructure *userDef, TPrecision p = EbpUndefined) - : type(EbtStruct), precision(p), qualifier(EvqTemporary), + : type(EbtStruct), precision(p), qualifier(EvqTemporary), invariant(false), layoutQualifier(TLayoutQualifier::create()), primarySize(1), secondarySize(1), array(false), arraySize(0), interfaceBlock(0), structure(userDef) @@ -258,19 +267,26 @@ class TType TType(TInterfaceBlock *interfaceBlockIn, TQualifier qualifierIn, TLayoutQualifier layoutQualifierIn, int arraySizeIn) : type(EbtInterfaceBlock), precision(EbpUndefined), qualifier(qualifierIn), - layoutQualifier(layoutQualifierIn), + invariant(false), layoutQualifier(layoutQualifierIn), primarySize(1), secondarySize(1), array(arraySizeIn > 0), arraySize(arraySizeIn), interfaceBlock(interfaceBlockIn), structure(0) { } + TType(const TType &) = default; + TType &operator=(const TType &) = default; + TBasicType getBasicType() const { return type; } void setBasicType(TBasicType t) { - type = t; + if (type != t) + { + type = t; + invalidateMangledName(); + } } TPrecision getPrecision() const @@ -291,6 +307,11 @@ class TType qualifier = q; } + bool isInvariant() const + { + return invariant; + } + TLayoutQualifier getLayoutQualifier() const { return layoutQualifier; @@ -320,11 +341,19 @@ class TType } void setPrimarySize(unsigned char ps) { - primarySize = ps; + if (primarySize != ps) + { + primarySize = ps; + invalidateMangledName(); + } } void setSecondarySize(unsigned char ss) { - secondarySize = ss; + if (secondarySize != ss) + { + secondarySize = ss; + invalidateMangledName(); + } } // Full size of single instance of type @@ -352,13 +381,21 @@ class TType } void setArraySize(int s) { - array = true; - arraySize = s; + if (!array || arraySize != s) + { + array = true; + arraySize = s; + invalidateMangledName(); + } } void clearArrayness() { - array = false; - arraySize = 0; + if (array) + { + array = false; + arraySize = 0; + invalidateMangledName(); + } } TInterfaceBlock *getInterfaceBlock() const @@ -367,7 +404,11 @@ class TType } void setInterfaceBlock(TInterfaceBlock *interfaceBlockIn) { - interfaceBlock = interfaceBlockIn; + if (interfaceBlock != interfaceBlockIn) + { + interfaceBlock = interfaceBlockIn; + invalidateMangledName(); + } } bool isInterfaceBlock() const { @@ -393,10 +434,14 @@ class TType } void setStruct(TStructure *s) { - structure = s; + if (structure != s) + { + structure = s; + invalidateMangledName(); + } } - const TString &getMangledName() + const TString &getMangledName() const { if (mangled.empty()) { @@ -481,19 +526,42 @@ class TType return structure ? structure->containsArrays() : false; } + bool isStructureContainingType(TBasicType t) const + { + return structure ? structure->containsType(t) : false; + } + bool isStructureContainingSamplers() const { return structure ? structure->containsSamplers() : false; } - protected: + void createSamplerSymbols(const TString &structName, + const TString &structAPIName, + const int arrayOfStructsSize, + TVector *outputSymbols, + TMap *outputSymbolsToAPINames) const + { + ASSERT(structure != nullptr && structure->containsSamplers()); + structure->createSamplerSymbols(structName, structAPIName, arrayOfStructsSize, + outputSymbols, outputSymbolsToAPINames); + } + + // Initializes all lazily-initialized members. + void realize() + { + getMangledName(); + } + + private: + void invalidateMangledName() { mangled = ""; } TString buildMangledName() const; size_t getStructSize() const; - void computeDeepestStructNesting(); TBasicType type; TPrecision precision; TQualifier qualifier; + bool invariant; TLayoutQualifier layoutQualifier; unsigned char primarySize; // size of vector or cols matrix unsigned char secondarySize; // rows of a matrix @@ -523,6 +591,7 @@ struct TPublicType TBasicType type; TLayoutQualifier layoutQualifier; TQualifier qualifier; + bool invariant; TPrecision precision; unsigned char primarySize; // size of vector or cols of matrix unsigned char secondarySize; // rows of matrix @@ -531,11 +600,15 @@ struct TPublicType TType *userDef; TSourceLoc line; + // true if the type was defined by a struct specifier rather than a reference to a type name. + bool isStructSpecifier; + void setBasic(TBasicType bt, TQualifier q, const TSourceLoc &ln) { type = bt; layoutQualifier = TLayoutQualifier::create(); qualifier = q; + invariant = false; precision = EbpUndefined; primarySize = 1; secondarySize = 1; @@ -543,6 +616,7 @@ struct TPublicType arraySize = 0; userDef = 0; line = ln; + isStructSpecifier = false; } void setAggregate(unsigned char size) @@ -582,6 +656,16 @@ struct TPublicType return userDef->isStructureContainingArrays(); } + bool isStructureContainingType(TBasicType t) const + { + if (!userDef) + { + return false; + } + + return userDef->isStructureContainingType(t); + } + bool isMatrix() const { return primarySize > 1 && secondarySize > 1; diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/UnfoldShortCircuit.cpp b/Source/ThirdParty/ANGLE/src/compiler/translator/UnfoldShortCircuit.cpp deleted file mode 100644 index f79f9dd7fb89..000000000000 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/UnfoldShortCircuit.cpp +++ /dev/null @@ -1,185 +0,0 @@ -// -// Copyright (c) 2002-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. -// -// UnfoldShortCircuit is an AST traverser to output short-circuiting operators as if-else statements. -// The results are assigned to s# temporaries, which are used by the main translator instead of -// the original expression. -// - -#include "compiler/translator/UnfoldShortCircuit.h" - -#include "compiler/translator/InfoSink.h" -#include "compiler/translator/OutputHLSL.h" -#include "compiler/translator/UtilsHLSL.h" - -namespace sh -{ -UnfoldShortCircuit::UnfoldShortCircuit(OutputHLSL *outputHLSL) : mOutputHLSL(outputHLSL) -{ - mTemporaryIndex = 0; -} - -void UnfoldShortCircuit::traverse(TIntermNode *node) -{ - int rewindIndex = mTemporaryIndex; - node->traverse(this); - mTemporaryIndex = rewindIndex; -} - -bool UnfoldShortCircuit::visitBinary(Visit visit, TIntermBinary *node) -{ - TInfoSinkBase &out = mOutputHLSL->getInfoSink(); - - // If our right node doesn't have side effects, we know we don't need to unfold this - // expression: there will be no short-circuiting side effects to avoid - // (note: unfolding doesn't depend on the left node -- it will always be evaluated) - if (!node->getRight()->hasSideEffects()) - { - return true; - } - - switch (node->getOp()) - { - case EOpLogicalOr: - // "x || y" is equivalent to "x ? true : y", which unfolds to "bool s; if(x) s = true; else s = y;", - // and then further simplifies down to "bool s = x; if(!s) s = y;". - { - int i = mTemporaryIndex; - - out << "bool s" << i << ";\n"; - - out << "{\n"; - - mTemporaryIndex = i + 1; - node->getLeft()->traverse(this); - out << "s" << i << " = "; - mTemporaryIndex = i + 1; - node->getLeft()->traverse(mOutputHLSL); - out << ";\n"; - out << "if (!s" << i << ")\n" - "{\n"; - mTemporaryIndex = i + 1; - node->getRight()->traverse(this); - out << " s" << i << " = "; - mTemporaryIndex = i + 1; - node->getRight()->traverse(mOutputHLSL); - out << ";\n" - "}\n"; - - out << "}\n"; - - mTemporaryIndex = i + 1; - } - return false; - case EOpLogicalAnd: - // "x && y" is equivalent to "x ? y : false", which unfolds to "bool s; if(x) s = y; else s = false;", - // and then further simplifies down to "bool s = x; if(s) s = y;". - { - int i = mTemporaryIndex; - - out << "bool s" << i << ";\n"; - - out << "{\n"; - - mTemporaryIndex = i + 1; - node->getLeft()->traverse(this); - out << "s" << i << " = "; - mTemporaryIndex = i + 1; - node->getLeft()->traverse(mOutputHLSL); - out << ";\n"; - out << "if (s" << i << ")\n" - "{\n"; - mTemporaryIndex = i + 1; - node->getRight()->traverse(this); - out << " s" << i << " = "; - mTemporaryIndex = i + 1; - node->getRight()->traverse(mOutputHLSL); - out << ";\n" - "}\n"; - - out << "}\n"; - - mTemporaryIndex = i + 1; - } - return false; - default: - return true; - } -} - -bool UnfoldShortCircuit::visitSelection(Visit visit, TIntermSelection *node) -{ - TInfoSinkBase &out = mOutputHLSL->getInfoSink(); - - // Unfold "b ? x : y" into "type s; if(b) s = x; else s = y;" - if (node->usesTernaryOperator()) - { - int i = mTemporaryIndex; - - out << TypeString(node->getType()) << " s" << i << ";\n"; - - out << "{\n"; - - mTemporaryIndex = i + 1; - node->getCondition()->traverse(this); - out << "if ("; - mTemporaryIndex = i + 1; - node->getCondition()->traverse(mOutputHLSL); - out << ")\n" - "{\n"; - mTemporaryIndex = i + 1; - node->getTrueBlock()->traverse(this); - out << " s" << i << " = "; - mTemporaryIndex = i + 1; - node->getTrueBlock()->traverse(mOutputHLSL); - out << ";\n" - "}\n" - "else\n" - "{\n"; - mTemporaryIndex = i + 1; - node->getFalseBlock()->traverse(this); - out << " s" << i << " = "; - mTemporaryIndex = i + 1; - node->getFalseBlock()->traverse(mOutputHLSL); - out << ";\n" - "}\n"; - - out << "}\n"; - - mTemporaryIndex = i + 1; - } - - return false; -} - -bool UnfoldShortCircuit::visitLoop(Visit visit, TIntermLoop *node) -{ - int rewindIndex = mTemporaryIndex; - - if (node->getInit()) - { - node->getInit()->traverse(this); - } - - if (node->getCondition()) - { - node->getCondition()->traverse(this); - } - - if (node->getExpression()) - { - node->getExpression()->traverse(this); - } - - mTemporaryIndex = rewindIndex; - - return false; -} - -int UnfoldShortCircuit::getNextTemporaryIndex() -{ - return mTemporaryIndex++; -} -} diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/UnfoldShortCircuit.h b/Source/ThirdParty/ANGLE/src/compiler/translator/UnfoldShortCircuit.h deleted file mode 100644 index eaceb0a0b3de..000000000000 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/UnfoldShortCircuit.h +++ /dev/null @@ -1,38 +0,0 @@ -// -// Copyright (c) 2002-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. -// -// UnfoldShortCircuit is an AST traverser to output short-circuiting operators as if-else statements -// - -#ifndef COMPILER_TRANSLATOR_UNFOLDSHORTCIRCUIT_H_ -#define COMPILER_TRANSLATOR_UNFOLDSHORTCIRCUIT_H_ - -#include "compiler/translator/IntermNode.h" -#include "compiler/translator/ParseContext.h" - -namespace sh -{ -class OutputHLSL; - -class UnfoldShortCircuit : public TIntermTraverser -{ - public: - UnfoldShortCircuit(OutputHLSL *outputHLSL); - - void traverse(TIntermNode *node); - bool visitBinary(Visit visit, TIntermBinary*); - bool visitSelection(Visit visit, TIntermSelection *node); - bool visitLoop(Visit visit, TIntermLoop *node); - - int getNextTemporaryIndex(); - - protected: - OutputHLSL *const mOutputHLSL; - - int mTemporaryIndex; -}; -} - -#endif // COMPILER_TRANSLATOR_UNFOLDSHORTCIRCUIT_H_ diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/UnfoldShortCircuitAST.h b/Source/ThirdParty/ANGLE/src/compiler/translator/UnfoldShortCircuitAST.h index 7b698ccb6320..b92a4e91526b 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/UnfoldShortCircuitAST.h +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/UnfoldShortCircuitAST.h @@ -20,9 +20,12 @@ class UnfoldShortCircuitAST : public TIntermTraverser { public: - UnfoldShortCircuitAST() { } + UnfoldShortCircuitAST() + : TIntermTraverser(true, false, false) + { + } - virtual bool visitBinary(Visit visit, TIntermBinary *); + bool visitBinary(Visit visit, TIntermBinary *) override; }; #endif // COMPILER_TRANSLATOR_UNFOLDSHORTCIRCUITAST_H_ diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/UnfoldShortCircuitToIf.cpp b/Source/ThirdParty/ANGLE/src/compiler/translator/UnfoldShortCircuitToIf.cpp new file mode 100644 index 000000000000..be23b524d757 --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/UnfoldShortCircuitToIf.cpp @@ -0,0 +1,368 @@ +// +// Copyright (c) 2002-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. +// +// UnfoldShortCircuitToIf is an AST traverser to convert short-circuiting operators to if-else statements. +// The results are assigned to s# temporaries, which are used by the main translator instead of +// the original expression. +// + +#include "compiler/translator/UnfoldShortCircuitToIf.h" + +#include "compiler/translator/IntermNode.h" + +namespace +{ + +// Traverser that unfolds one short-circuiting operation at a time. +class UnfoldShortCircuitTraverser : public TIntermTraverser +{ + public: + UnfoldShortCircuitTraverser(); + + bool visitBinary(Visit visit, TIntermBinary *node) override; + bool visitAggregate(Visit visit, TIntermAggregate *node) override; + bool visitSelection(Visit visit, TIntermSelection *node) override; + bool visitLoop(Visit visit, TIntermLoop *node) override; + + void nextIteration(); + bool foundShortCircuit() const { return mFoundShortCircuit; } + + protected: + // Check if the traversal is inside a loop condition or expression, in which case the unfolded + // expression needs to be copied inside the loop. Returns true if the copying is done, in which + // case no further unfolding should be done on the same traversal. + // The parameters are the node that will be unfolded to multiple statements and so can't remain + // inside a loop condition, and its parent. + bool copyLoopConditionOrExpression(TIntermNode *parent, TIntermTyped *node); + + // Marked to true once an operation that needs to be unfolded has been found. + // After that, no more unfolding is performed on that traversal. + bool mFoundShortCircuit; + + // Set to the loop node while a loop condition or expression is being traversed. + TIntermLoop *mParentLoop; + // Parent of the loop node while a loop condition or expression is being traversed. + TIntermNode *mLoopParent; + + bool mInLoopCondition; + bool mInLoopExpression; +}; + +UnfoldShortCircuitTraverser::UnfoldShortCircuitTraverser() + : TIntermTraverser(true, false, true), + mFoundShortCircuit(false), + mParentLoop(nullptr), + mLoopParent(nullptr), + mInLoopCondition(false), + mInLoopExpression(false) +{ +} + +bool UnfoldShortCircuitTraverser::visitBinary(Visit visit, TIntermBinary *node) +{ + if (mFoundShortCircuit) + return false; + // If our right node doesn't have side effects, we know we don't need to unfold this + // expression: there will be no short-circuiting side effects to avoid + // (note: unfolding doesn't depend on the left node -- it will always be evaluated) + if (!node->getRight()->hasSideEffects()) + { + return true; + } + + switch (node->getOp()) + { + case EOpLogicalOr: + mFoundShortCircuit = true; + if (!copyLoopConditionOrExpression(getParentNode(), node)) + { + // "x || y" is equivalent to "x ? true : y", which unfolds to "bool s; if(x) s = true; + // else s = y;", + // and then further simplifies down to "bool s = x; if(!s) s = y;". + + TIntermSequence insertions; + TType boolType(EbtBool, EbpUndefined, EvqTemporary); + + ASSERT(node->getLeft()->getType() == boolType); + insertions.push_back(createTempInitDeclaration(node->getLeft())); + + TIntermAggregate *assignRightBlock = new TIntermAggregate(EOpSequence); + ASSERT(node->getRight()->getType() == boolType); + assignRightBlock->getSequence()->push_back(createTempAssignment(node->getRight())); + + TIntermUnary *notTempSymbol = new TIntermUnary(EOpLogicalNot, boolType); + notTempSymbol->setOperand(createTempSymbol(boolType)); + TIntermSelection *ifNode = new TIntermSelection(notTempSymbol, assignRightBlock, nullptr); + insertions.push_back(ifNode); + + insertStatementsInParentBlock(insertions); + + NodeUpdateEntry replaceVariable(getParentNode(), node, createTempSymbol(boolType), false); + mReplacements.push_back(replaceVariable); + } + return false; + case EOpLogicalAnd: + mFoundShortCircuit = true; + if (!copyLoopConditionOrExpression(getParentNode(), node)) + { + // "x && y" is equivalent to "x ? y : false", which unfolds to "bool s; if(x) s = y; + // else s = false;", + // and then further simplifies down to "bool s = x; if(s) s = y;". + TIntermSequence insertions; + TType boolType(EbtBool, EbpUndefined, EvqTemporary); + + ASSERT(node->getLeft()->getType() == boolType); + insertions.push_back(createTempInitDeclaration(node->getLeft())); + + TIntermAggregate *assignRightBlock = new TIntermAggregate(EOpSequence); + ASSERT(node->getRight()->getType() == boolType); + assignRightBlock->getSequence()->push_back(createTempAssignment(node->getRight())); + + TIntermSelection *ifNode = new TIntermSelection(createTempSymbol(boolType), assignRightBlock, nullptr); + insertions.push_back(ifNode); + + insertStatementsInParentBlock(insertions); + + NodeUpdateEntry replaceVariable(getParentNode(), node, createTempSymbol(boolType), false); + mReplacements.push_back(replaceVariable); + } + return false; + default: + return true; + } +} + +bool UnfoldShortCircuitTraverser::visitSelection(Visit visit, TIntermSelection *node) +{ + if (mFoundShortCircuit) + return false; + + // Unfold "b ? x : y" into "type s; if(b) s = x; else s = y;" + if (visit == PreVisit && node->usesTernaryOperator()) + { + mFoundShortCircuit = true; + if (!copyLoopConditionOrExpression(getParentNode(), node)) + { + TIntermSequence insertions; + + TIntermSymbol *tempSymbol = createTempSymbol(node->getType()); + TIntermAggregate *tempDeclaration = new TIntermAggregate(EOpDeclaration); + tempDeclaration->getSequence()->push_back(tempSymbol); + insertions.push_back(tempDeclaration); + + TIntermAggregate *trueBlock = new TIntermAggregate(EOpSequence); + TIntermBinary *trueAssignment = + createTempAssignment(node->getTrueBlock()->getAsTyped()); + trueBlock->getSequence()->push_back(trueAssignment); + + TIntermAggregate *falseBlock = new TIntermAggregate(EOpSequence); + TIntermBinary *falseAssignment = + createTempAssignment(node->getFalseBlock()->getAsTyped()); + falseBlock->getSequence()->push_back(falseAssignment); + + TIntermSelection *ifNode = + new TIntermSelection(node->getCondition()->getAsTyped(), trueBlock, falseBlock); + insertions.push_back(ifNode); + + insertStatementsInParentBlock(insertions); + + TIntermSymbol *ternaryResult = createTempSymbol(node->getType()); + NodeUpdateEntry replaceVariable(getParentNode(), node, ternaryResult, false); + mReplacements.push_back(replaceVariable); + } + return false; + } + + return true; +} + +bool UnfoldShortCircuitTraverser::visitAggregate(Visit visit, TIntermAggregate *node) +{ + if (visit == PreVisit && mFoundShortCircuit) + return false; // No need to traverse further + + if (node->getOp() == EOpComma) + { + ASSERT(visit != PreVisit || !mFoundShortCircuit); + + if (visit == PostVisit && mFoundShortCircuit) + { + // We can be sure that we arrived here because there was a short-circuiting operator + // inside the sequence operator since we only start traversing the sequence operator in + // case a short-circuiting operator has not been found so far. + // We need to unfold the sequence (comma) operator, otherwise the evaluation order of + // statements would be messed up by unfolded operations inside. + // Don't do any other unfolding on this round of traversal. + mReplacements.clear(); + mMultiReplacements.clear(); + mInsertions.clear(); + + if (!copyLoopConditionOrExpression(getParentNode(), node)) + { + TIntermSequence insertions; + TIntermSequence *seq = node->getSequence(); + + TIntermSequence::size_type i = 0; + ASSERT(!seq->empty()); + while (i < seq->size() - 1) + { + TIntermTyped *child = (*seq)[i]->getAsTyped(); + insertions.push_back(child); + ++i; + } + + insertStatementsInParentBlock(insertions); + + NodeUpdateEntry replaceVariable(getParentNode(), node, (*seq)[i], false); + mReplacements.push_back(replaceVariable); + } + } + } + return true; +} + +bool UnfoldShortCircuitTraverser::visitLoop(Visit visit, TIntermLoop *node) +{ + if (visit == PreVisit) + { + if (mFoundShortCircuit) + return false; // No need to traverse further + + mLoopParent = getParentNode(); + mParentLoop = node; + incrementDepth(node); + + if (node->getInit()) + { + node->getInit()->traverse(this); + if (mFoundShortCircuit) + { + decrementDepth(); + return false; + } + } + + if (node->getCondition()) + { + mInLoopCondition = true; + node->getCondition()->traverse(this); + mInLoopCondition = false; + + if (mFoundShortCircuit) + { + decrementDepth(); + return false; + } + } + + if (node->getExpression()) + { + mInLoopExpression = true; + node->getExpression()->traverse(this); + mInLoopExpression = false; + + if (mFoundShortCircuit) + { + decrementDepth(); + return false; + } + } + + if (node->getBody()) + node->getBody()->traverse(this); + + decrementDepth(); + } + return false; +} + +bool UnfoldShortCircuitTraverser::copyLoopConditionOrExpression(TIntermNode *parent, + TIntermTyped *node) +{ + if (mInLoopCondition) + { + mReplacements.push_back( + NodeUpdateEntry(parent, node, createTempSymbol(node->getType()), false)); + TIntermAggregate *body = mParentLoop->getBody(); + TIntermSequence empty; + if (mParentLoop->getType() == ELoopDoWhile) + { + // Declare the temporary variable before the loop. + TIntermSequence insertionsBeforeLoop; + insertionsBeforeLoop.push_back(createTempDeclaration(node->getType())); + insertStatementsInParentBlock(insertionsBeforeLoop); + + // Move a part of do-while loop condition to inside the loop. + TIntermSequence insertionsInLoop; + insertionsInLoop.push_back(createTempAssignment(node)); + mInsertions.push_back(NodeInsertMultipleEntry(body, body->getSequence()->size() - 1, + empty, insertionsInLoop)); + } + else + { + // The loop initializer expression and one copy of the part of the loop condition are + // executed before the loop. They need to be in a new scope. + TIntermAggregate *loopScope = new TIntermAggregate(EOpSequence); + + TIntermNode *initializer = mParentLoop->getInit(); + if (initializer != nullptr) + { + // Move the initializer to the newly created outer scope, so that condition can + // depend on it. + mReplacements.push_back(NodeUpdateEntry(mParentLoop, initializer, nullptr, false)); + loopScope->getSequence()->push_back(initializer); + } + + loopScope->getSequence()->push_back(createTempInitDeclaration(node)); + loopScope->getSequence()->push_back(mParentLoop); + mReplacements.push_back(NodeUpdateEntry(mLoopParent, mParentLoop, loopScope, true)); + + // The second copy of the part of the loop condition is executed inside the loop. + TIntermSequence insertionsInLoop; + insertionsInLoop.push_back(createTempAssignment(node->deepCopy())); + mInsertions.push_back(NodeInsertMultipleEntry(body, body->getSequence()->size() - 1, + empty, insertionsInLoop)); + } + return true; + } + + if (mInLoopExpression) + { + TIntermTyped *movedExpression = mParentLoop->getExpression(); + mReplacements.push_back(NodeUpdateEntry(mParentLoop, movedExpression, nullptr, false)); + TIntermAggregate *body = mParentLoop->getBody(); + TIntermSequence empty; + TIntermSequence insertions; + insertions.push_back(movedExpression); + mInsertions.push_back( + NodeInsertMultipleEntry(body, body->getSequence()->size() - 1, empty, insertions)); + return true; + } + return false; +} + +void UnfoldShortCircuitTraverser::nextIteration() +{ + mFoundShortCircuit = false; + nextTemporaryIndex(); +} + +} // namespace + +void UnfoldShortCircuitToIf(TIntermNode *root, unsigned int *temporaryIndex) +{ + UnfoldShortCircuitTraverser traverser; + ASSERT(temporaryIndex != nullptr); + traverser.useTemporaryIndex(temporaryIndex); + // Unfold one operator at a time, and reset the traverser between iterations. + do + { + traverser.nextIteration(); + root->traverse(&traverser); + if (traverser.foundShortCircuit()) + traverser.updateTree(); + } + while (traverser.foundShortCircuit()); +} diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/UnfoldShortCircuitToIf.h b/Source/ThirdParty/ANGLE/src/compiler/translator/UnfoldShortCircuitToIf.h new file mode 100644 index 000000000000..0fe37b714009 --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/UnfoldShortCircuitToIf.h @@ -0,0 +1,18 @@ +// +// Copyright (c) 2002-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. +// +// UnfoldShortCircuitToIf is an AST traverser to convert short-circuiting operators to if-else statements. +// The results are assigned to s# temporaries, which are used by the main translator instead of +// the original expression. +// + +#ifndef COMPILER_TRANSLATOR_UNFOLDSHORTCIRCUIT_H_ +#define COMPILER_TRANSLATOR_UNFOLDSHORTCIRCUIT_H_ + +class TIntermNode; + +void UnfoldShortCircuitToIf(TIntermNode *root, unsigned int *temporaryIndex); + +#endif // COMPILER_TRANSLATOR_UNFOLDSHORTCIRCUIT_H_ diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/UniformHLSL.cpp b/Source/ThirdParty/ANGLE/src/compiler/translator/UniformHLSL.cpp index 71659fe35404..24d7760cb3a0 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/UniformHLSL.cpp +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/UniformHLSL.cpp @@ -89,11 +89,12 @@ const Uniform *UniformHLSL::findUniformByName(const TString &name) const } } - UNREACHABLE(); - return NULL; + return nullptr; } -unsigned int UniformHLSL::declareUniformAndAssignRegister(const TType &type, const TString &name) +unsigned int UniformHLSL::assignUniformRegister(const TType &type, + const TString &name, + unsigned int *outRegisterCount) { unsigned int registerIndex = (IsSampler(type.getBasicType()) ? mSamplerRegister : mUniformRegister); @@ -112,48 +113,240 @@ unsigned int UniformHLSL::declareUniformAndAssignRegister(const TType &type, con { mUniformRegister += registerCount; } + if (outRegisterCount) + { + *outRegisterCount = registerCount; + } + return registerIndex; +} +unsigned int UniformHLSL::assignSamplerInStructUniformRegister(const TType &type, + const TString &name, + unsigned int *outRegisterCount) +{ + // Sampler that is a field of a uniform structure. + ASSERT(IsSampler(type.getBasicType())); + unsigned int registerIndex = mSamplerRegister; + mUniformRegisterMap[std::string(name.c_str())] = registerIndex; + unsigned int registerCount = type.isArray() ? type.getArraySize() : 1; + mSamplerRegister += registerCount; + if (outRegisterCount) + { + *outRegisterCount = registerCount; + } return registerIndex; } -TString UniformHLSL::uniformsHeader(ShShaderOutput outputType, const ReferencedSymbols &referencedUniforms) +void UniformHLSL::outputHLSLSamplerUniformGroup( + TInfoSinkBase &out, + const HLSLTextureSamplerGroup textureGroup, + const TVector &group, + const TMap &samplerInStructSymbolsToAPINames, + unsigned int *groupTextureRegisterIndex) { - TString uniforms; + if (group.empty()) + { + return; + } + unsigned int groupRegisterCount = 0; + for (const TIntermSymbol *uniform : group) + { + const TType &type = uniform->getType(); + const TString &name = uniform->getSymbol(); + unsigned int registerCount; + + // The uniform might be just a regular sampler or one extracted from a struct. + unsigned int samplerArrayIndex = 0u; + const Uniform *uniformByName = findUniformByName(name); + if (uniformByName) + { + samplerArrayIndex = assignUniformRegister(type, name, ®isterCount); + } + else + { + ASSERT(samplerInStructSymbolsToAPINames.find(uniform) != + samplerInStructSymbolsToAPINames.end()); + samplerArrayIndex = assignSamplerInStructUniformRegister( + type, samplerInStructSymbolsToAPINames.at(uniform), ®isterCount); + } + groupRegisterCount += registerCount; - for (ReferencedSymbols::const_iterator uniformIt = referencedUniforms.begin(); - uniformIt != referencedUniforms.end(); uniformIt++) + if (type.isArray()) + { + out << "static const uint " << DecorateIfNeeded(uniform->getName()) << ArrayString(type) + << " = {"; + for (int i = 0; i < type.getArraySize(); ++i) + { + if (i > 0) + out << ", "; + out << (samplerArrayIndex + i); + } + out << "};\n"; + } + else + { + out << "static const uint " << DecorateIfNeeded(uniform->getName()) << " = " + << samplerArrayIndex << ";\n"; + } + } + TString suffix = TextureGroupSuffix(textureGroup); + // Since HLSL_TEXTURE_2D is the first group, it has a fixed offset of zero. + if (textureGroup != HLSL_TEXTURE_2D) { - const TIntermSymbol &uniform = *uniformIt->second; - const TType &type = uniform.getType(); - const TString &name = uniform.getSymbol(); + out << "static const uint textureIndexOffset" << suffix << " = " + << (*groupTextureRegisterIndex) << ";\n"; + out << "static const uint samplerIndexOffset" << suffix << " = " + << (*groupTextureRegisterIndex) << ";\n"; + } + out << "uniform " << TextureString(textureGroup) << " textures" << suffix << "[" + << groupRegisterCount << "]" + << " : register(t" << (*groupTextureRegisterIndex) << ");\n"; + out << "uniform " << SamplerString(textureGroup) << " samplers" << suffix << "[" + << groupRegisterCount << "]" + << " : register(s" << (*groupTextureRegisterIndex) << ");\n"; + *groupTextureRegisterIndex += groupRegisterCount; +} - unsigned int registerIndex = declareUniformAndAssignRegister(type, name); +void UniformHLSL::outputHLSL4_0_FL9_3Sampler(TInfoSinkBase &out, + const TType &type, + const TName &name, + const unsigned int registerIndex) +{ + out << "uniform " << SamplerString(type.getBasicType()) << " sampler_" + << DecorateUniform(name, type) << ArrayString(type) << " : register(s" << str(registerIndex) + << ");\n"; + out << "uniform " << TextureString(type.getBasicType()) << " texture_" + << DecorateUniform(name, type) << ArrayString(type) << " : register(t" << str(registerIndex) + << ");\n"; +} - if (outputType == SH_HLSL11_OUTPUT && IsSampler(type.getBasicType())) // Also declare the texture - { - uniforms += "uniform " + SamplerString(type) + " sampler_" + DecorateUniform(name, type) + ArrayString(type) + - " : register(s" + str(registerIndex) + ");\n"; +void UniformHLSL::outputUniform(TInfoSinkBase &out, + const TType &type, + const TName &name, + const unsigned int registerIndex) +{ + const TStructure *structure = type.getStruct(); + // If this is a nameless struct, we need to use its full definition, rather than its (empty) + // name. + // TypeString() will invoke defineNameless in this case; qualifier prefixes are unnecessary for + // nameless structs in ES, as nameless structs cannot be used anywhere that layout qualifiers + // are permitted. + const TString &typeName = ((structure && !structure->name().empty()) + ? QualifiedStructNameString(*structure, false, false) + : TypeString(type)); + + const TString ®isterString = + TString("register(") + UniformRegisterPrefix(type) + str(registerIndex) + ")"; + + out << "uniform " << typeName << " "; + + out << DecorateUniform(name, type); + + out << ArrayString(type) << " : " << registerString << ";\n"; +} - uniforms += "uniform " + TextureString(type) + " texture_" + DecorateUniform(name, type) + ArrayString(type) + - " : register(t" + str(registerIndex) + ");\n"; +void UniformHLSL::uniformsHeader(TInfoSinkBase &out, + ShShaderOutput outputType, + const ReferencedSymbols &referencedUniforms) +{ + if (!referencedUniforms.empty()) + { + out << "// Uniforms\n\n"; + } + // In the case of HLSL 4, sampler uniforms need to be grouped by type before the code is + // written. They are grouped based on the combination of the HLSL texture type and + // HLSL sampler type, enumerated in HLSLTextureSamplerGroup. + TVector> groupedSamplerUniforms(HLSL_TEXTURE_MAX + 1); + TMap samplerInStructSymbolsToAPINames; + for (auto &uniformIt : referencedUniforms) + { + // Output regular uniforms. Group sampler uniforms by type. + const TIntermSymbol &uniform = *uniformIt.second; + const TType &type = uniform.getType(); + const TName &name = uniform.getName(); + + if (outputType == SH_HLSL_4_1_OUTPUT && IsSampler(type.getBasicType())) + { + HLSLTextureSamplerGroup group = TextureGroup(type.getBasicType()); + groupedSamplerUniforms[group].push_back(&uniform); + } + else if (outputType == SH_HLSL_4_0_FL9_3_OUTPUT && IsSampler(type.getBasicType())) + { + unsigned int registerIndex = assignUniformRegister(type, name.getString(), nullptr); + outputHLSL4_0_FL9_3Sampler(out, type, name, registerIndex); } else { - const TStructure *structure = type.getStruct(); - // If this is a nameless struct, we need to use its full definition, rather than its (empty) name. - // TypeString() will invoke defineNameless in this case; qualifier prefixes are unnecessary for - // nameless structs in ES, as nameless structs cannot be used anywhere that layout qualifiers are - // permitted. - const TString &typeName = ((structure && !structure->name().empty()) ? - QualifiedStructNameString(*structure, false, false) : TypeString(type)); - - const TString ®isterString = TString("register(") + UniformRegisterPrefix(type) + str(registerIndex) + ")"; + if (type.isStructureContainingSamplers()) + { + TVector samplerSymbols; + TMap symbolsToAPINames; + int arrayOfStructsSize = type.isArray() ? type.getArraySize() : 0; + type.createSamplerSymbols("angle_" + name.getString(), name.getString(), + arrayOfStructsSize, &samplerSymbols, &symbolsToAPINames); + for (TIntermSymbol *sampler : samplerSymbols) + { + const TType &samplerType = sampler->getType(); + + // Will use angle_ prefix instead of regular prefix. + sampler->setInternal(true); + const TName &samplerName = sampler->getName(); + + if (outputType == SH_HLSL_4_1_OUTPUT) + { + HLSLTextureSamplerGroup group = TextureGroup(samplerType.getBasicType()); + groupedSamplerUniforms[group].push_back(sampler); + samplerInStructSymbolsToAPINames[sampler] = symbolsToAPINames[sampler]; + } + else if (outputType == SH_HLSL_4_0_FL9_3_OUTPUT) + { + unsigned int registerIndex = assignSamplerInStructUniformRegister( + samplerType, symbolsToAPINames[sampler], nullptr); + outputHLSL4_0_FL9_3Sampler(out, samplerType, samplerName, registerIndex); + } + else + { + ASSERT(outputType == SH_HLSL_3_0_OUTPUT); + unsigned int registerIndex = assignSamplerInStructUniformRegister( + samplerType, symbolsToAPINames[sampler], nullptr); + outputUniform(out, samplerType, samplerName, registerIndex); + } + } + } + unsigned int registerIndex = assignUniformRegister(type, name.getString(), nullptr); + outputUniform(out, type, name, registerIndex); + } + } - uniforms += "uniform " + typeName + " " + DecorateUniform(name, type) + ArrayString(type) + " : " + registerString + ";\n"; + if (outputType == SH_HLSL_4_1_OUTPUT) + { + unsigned int groupTextureRegisterIndex = 0; + // TEXTURE_2D is special, index offset is assumed to be 0 and omitted in that case. + ASSERT(HLSL_TEXTURE_MIN == HLSL_TEXTURE_2D); + for (int groupId = HLSL_TEXTURE_MIN; groupId < HLSL_TEXTURE_MAX; ++groupId) + { + outputHLSLSamplerUniformGroup( + out, HLSLTextureSamplerGroup(groupId), groupedSamplerUniforms[groupId], + samplerInStructSymbolsToAPINames, &groupTextureRegisterIndex); } } +} - return (uniforms.empty() ? "" : ("// Uniforms\n\n" + uniforms)); +void UniformHLSL::samplerMetadataUniforms(TInfoSinkBase &out, const char *reg) +{ + // If mSamplerRegister is 0 the shader doesn't use any textures. + if (mSamplerRegister > 0) + { + out << " struct SamplerMetadata\n" + " {\n" + " int baseLevel;\n" + " int internalFormatBits;\n" + " int wrapModes;\n" + " int padding;\n" + " };\n" + " SamplerMetadata samplerMetadata[" + << mSamplerRegister << "] : packoffset(" << reg << ");\n"; + } } TString UniformHLSL::interfaceBlocksHeader(const ReferencedSymbols &referencedInterfaceBlocks) diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/UniformHLSL.h b/Source/ThirdParty/ANGLE/src/compiler/translator/UniformHLSL.h index 4ab9ccdf5366..c01b90fe00d4 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/UniformHLSL.h +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/UniformHLSL.h @@ -11,6 +11,7 @@ #define COMPILER_TRANSLATOR_UNIFORMHLSL_H_ #include "compiler/translator/OutputHLSL.h" +#include "compiler/translator/UtilsHLSL.h" namespace sh { @@ -23,7 +24,13 @@ class UniformHLSL : angle::NonCopyable void reserveUniformRegisters(unsigned int registerCount); void reserveInterfaceBlockRegisters(unsigned int registerCount); - TString uniformsHeader(ShShaderOutput outputType, const ReferencedSymbols &referencedUniforms); + void uniformsHeader(TInfoSinkBase &out, + ShShaderOutput outputType, + const ReferencedSymbols &referencedUniforms); + + // Must be called after uniformsHeader + void samplerMetadataUniforms(TInfoSinkBase &out, const char *reg); + TString interfaceBlocksHeader(const ReferencedSymbols &referencedInterfaceBlocks); // Used for direct index references @@ -44,8 +51,30 @@ class UniformHLSL : angle::NonCopyable TString interfaceBlockStructString(const TInterfaceBlock &interfaceBlock); const Uniform *findUniformByName(const TString &name) const; + void outputHLSL4_0_FL9_3Sampler(TInfoSinkBase &out, + const TType &type, + const TName &name, + const unsigned int registerIndex); + + void outputUniform(TInfoSinkBase &out, + const TType &type, + const TName &name, + const unsigned int registerIndex); + // Returns the uniform's register index - unsigned int declareUniformAndAssignRegister(const TType &type, const TString &name); + unsigned int assignUniformRegister(const TType &type, + const TString &name, + unsigned int *outRegisterCount); + unsigned int assignSamplerInStructUniformRegister(const TType &type, + const TString &name, + unsigned int *outRegisterCount); + + void outputHLSLSamplerUniformGroup( + TInfoSinkBase &out, + const HLSLTextureSamplerGroup textureGroup, + const TVector &group, + const TMap &samplerInStructSymbolsToAPINames, + unsigned int *groupTextureRegisterIndex); unsigned int mUniformRegister; unsigned int mInterfaceBlockRegister; diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/UtilsHLSL.cpp b/Source/ThirdParty/ANGLE/src/compiler/translator/UtilsHLSL.cpp index 94e19ac40d59..9c07631ef869 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/UtilsHLSL.cpp +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/UtilsHLSL.cpp @@ -8,15 +8,16 @@ // #include "compiler/translator/UtilsHLSL.h" +#include "compiler/translator/IntermNode.h" #include "compiler/translator/StructureHLSL.h" #include "compiler/translator/SymbolTable.h" namespace sh { -TString SamplerString(const TType &type) +TString SamplerString(const TBasicType type) { - if (IsShadowSampler(type.getBasicType())) + if (IsShadowSampler(type)) { return "SamplerComparisonState"; } @@ -26,40 +27,166 @@ TString SamplerString(const TType &type) } } -TString TextureString(const TType &type) +TString SamplerString(HLSLTextureSamplerGroup type) { - switch (type.getBasicType()) + if (type >= HLSL_COMPARISON_SAMPLER_GROUP_BEGIN && type <= HLSL_COMPARISON_SAMPLER_GROUP_END) { - case EbtSampler2D: return "Texture2D"; - case EbtSamplerCube: return "TextureCube"; - case EbtSamplerExternalOES: return "Texture2D"; - case EbtSampler2DArray: return "Texture2DArray"; - case EbtSampler3D: return "Texture3D"; - case EbtISampler2D: return "Texture2D"; - case EbtISampler3D: return "Texture3D"; - case EbtISamplerCube: return "Texture2DArray"; - case EbtISampler2DArray: return "Texture2DArray"; - case EbtUSampler2D: return "Texture2D"; - case EbtUSampler3D: return "Texture3D"; - case EbtUSamplerCube: return "Texture2DArray"; - case EbtUSampler2DArray: return "Texture2DArray"; - case EbtSampler2DShadow: return "Texture2D"; - case EbtSamplerCubeShadow: return "TextureCube"; - case EbtSampler2DArrayShadow: return "Texture2DArray"; - default: UNREACHABLE(); + return "SamplerComparisonState"; + } + else + { + return "SamplerState"; + } +} + +HLSLTextureSamplerGroup TextureGroup(const TBasicType type) +{ + switch (type) + { + case EbtSampler2D: + return HLSL_TEXTURE_2D; + case EbtSamplerCube: + return HLSL_TEXTURE_CUBE; + case EbtSamplerExternalOES: + return HLSL_TEXTURE_2D; + case EbtSampler2DArray: + return HLSL_TEXTURE_2D_ARRAY; + case EbtSampler3D: + return HLSL_TEXTURE_3D; + case EbtISampler2D: + return HLSL_TEXTURE_2D_INT4; + case EbtISampler3D: + return HLSL_TEXTURE_3D_INT4; + case EbtISamplerCube: + return HLSL_TEXTURE_2D_ARRAY_INT4; + case EbtISampler2DArray: + return HLSL_TEXTURE_2D_ARRAY_INT4; + case EbtUSampler2D: + return HLSL_TEXTURE_2D_UINT4; + case EbtUSampler3D: + return HLSL_TEXTURE_3D_UINT4; + case EbtUSamplerCube: + return HLSL_TEXTURE_2D_ARRAY_UINT4; + case EbtUSampler2DArray: + return HLSL_TEXTURE_2D_ARRAY_UINT4; + case EbtSampler2DShadow: + return HLSL_TEXTURE_2D_COMPARISON; + case EbtSamplerCubeShadow: + return HLSL_TEXTURE_CUBE_COMPARISON; + case EbtSampler2DArrayShadow: + return HLSL_TEXTURE_2D_ARRAY_COMPARISON; + default: + UNREACHABLE(); + } + return HLSL_TEXTURE_UNKNOWN; +} + +TString TextureString(const HLSLTextureSamplerGroup type) +{ + switch (type) + { + case HLSL_TEXTURE_2D: + return "Texture2D"; + case HLSL_TEXTURE_CUBE: + return "TextureCube"; + case HLSL_TEXTURE_2D_ARRAY: + return "Texture2DArray"; + case HLSL_TEXTURE_3D: + return "Texture3D"; + case HLSL_TEXTURE_2D_INT4: + return "Texture2D"; + case HLSL_TEXTURE_3D_INT4: + return "Texture3D"; + case HLSL_TEXTURE_2D_ARRAY_INT4: + return "Texture2DArray"; + case HLSL_TEXTURE_2D_UINT4: + return "Texture2D"; + case HLSL_TEXTURE_3D_UINT4: + return "Texture3D"; + case HLSL_TEXTURE_2D_ARRAY_UINT4: + return "Texture2DArray"; + case HLSL_TEXTURE_2D_COMPARISON: + return "Texture2D"; + case HLSL_TEXTURE_CUBE_COMPARISON: + return "TextureCube"; + case HLSL_TEXTURE_2D_ARRAY_COMPARISON: + return "Texture2DArray"; + default: + UNREACHABLE(); } return ""; } -TString DecorateUniform(const TString &string, const TType &type) +TString TextureString(const TBasicType type) +{ + return TextureString(TextureGroup(type)); +} + +TString TextureGroupSuffix(const HLSLTextureSamplerGroup type) +{ + switch (type) + { + case HLSL_TEXTURE_2D: + return "2D"; + case HLSL_TEXTURE_CUBE: + return "Cube"; + case HLSL_TEXTURE_2D_ARRAY: + return "2DArray"; + case HLSL_TEXTURE_3D: + return "3D"; + case HLSL_TEXTURE_2D_INT4: + return "2D_int4_"; + case HLSL_TEXTURE_3D_INT4: + return "3D_int4_"; + case HLSL_TEXTURE_2D_ARRAY_INT4: + return "2DArray_int4_"; + case HLSL_TEXTURE_2D_UINT4: + return "2D_uint4_"; + case HLSL_TEXTURE_3D_UINT4: + return "3D_uint4_"; + case HLSL_TEXTURE_2D_ARRAY_UINT4: + return "2DArray_uint4_"; + case HLSL_TEXTURE_2D_COMPARISON: + return "2D_comparison"; + case HLSL_TEXTURE_CUBE_COMPARISON: + return "Cube_comparison"; + case HLSL_TEXTURE_2D_ARRAY_COMPARISON: + return "2DArray_comparison"; + default: + UNREACHABLE(); + } + + return ""; +} + +TString TextureGroupSuffix(const TBasicType type) +{ + return TextureGroupSuffix(TextureGroup(type)); +} + +TString TextureTypeSuffix(const TBasicType type) +{ + switch (type) + { + case EbtISamplerCube: + return "Cube_int4_"; + case EbtUSamplerCube: + return "Cube_uint4_"; + default: + // All other types are identified by their group suffix + return TextureGroupSuffix(type); + } +} + +TString DecorateUniform(const TName &name, const TType &type) { if (type.getBasicType() == EbtSamplerExternalOES) { - return "ex_" + string; + return "ex_" + name.getString(); } - return Decorate(string); + return DecorateIfNeeded(name); } TString DecorateField(const TString &string, const TStructure &structure) @@ -87,6 +214,30 @@ TString Decorate(const TString &string) return string; } +TString DecorateIfNeeded(const TName &name) +{ + if (name.isInternal()) + { + return name.getString(); + } + else + { + return Decorate(name.getString()); + } +} + +TString DecorateFunctionIfNeeded(const TName &name) +{ + if (name.isInternal()) + { + return TFunction::unmangleName(name.getString()); + } + else + { + return Decorate(TFunction::unmangleName(name.getString())); + } +} + TString TypeString(const TType &type) { const TStructure* structure = type.getStruct(); @@ -217,13 +368,11 @@ TString InterpolationString(TQualifier qualifier) { case EvqVaryingIn: return ""; case EvqFragmentIn: return ""; - case EvqInvariantVaryingIn: return ""; case EvqSmoothIn: return "linear"; case EvqFlatIn: return "nointerpolation"; case EvqCentroidIn: return "centroid"; case EvqVaryingOut: return ""; case EvqVertexOut: return ""; - case EvqInvariantVaryingOut: return ""; case EvqSmoothOut: return "linear"; case EvqFlatOut: return "nointerpolation"; case EvqCentroidOut: return "centroid"; @@ -247,4 +396,62 @@ TString QualifierString(TQualifier qualifier) return ""; } +int HLSLTextureCoordsCount(const TBasicType samplerType) +{ + switch (samplerType) + { + case EbtSampler2D: + return 2; + case EbtSampler3D: + return 3; + case EbtSamplerCube: + return 3; + case EbtSampler2DArray: + return 3; + case EbtISampler2D: + return 2; + case EbtISampler3D: + return 3; + case EbtISamplerCube: + return 3; + case EbtISampler2DArray: + return 3; + case EbtUSampler2D: + return 2; + case EbtUSampler3D: + return 3; + case EbtUSamplerCube: + return 3; + case EbtUSampler2DArray: + return 3; + case EbtSampler2DShadow: + return 2; + case EbtSamplerCubeShadow: + return 3; + case EbtSampler2DArrayShadow: + return 3; + default: + UNREACHABLE(); + } + return 0; } + +TString DisambiguateFunctionName(const TIntermSequence *parameters) +{ + TString disambiguatingString; + for (auto parameter : *parameters) + { + const TType ¶mType = parameter->getAsTyped()->getType(); + // Disambiguation is needed for float2x2 and float4 parameters. These are the only parameter + // types that HLSL thinks are identical. float2x3 and float3x2 are different types, for + // example. Other parameter types are not added to function names to avoid making function + // names longer. + if (paramType.getObjectSize() == 4 && paramType.getBasicType() == EbtFloat) + { + disambiguatingString += "_" + TypeString(paramType); + } + } + return disambiguatingString; +} + +} // namespace sh diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/UtilsHLSL.h b/Source/ThirdParty/ANGLE/src/compiler/translator/UtilsHLSL.h index 9800a3bbf3f7..387ab8232a60 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/UtilsHLSL.h +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/UtilsHLSL.h @@ -11,18 +11,60 @@ #define COMPILER_TRANSLATOR_UTILSHLSL_H_ #include +#include "compiler/translator/IntermNode.h" #include "compiler/translator/Types.h" #include "angle_gl.h" +class TName; + namespace sh { -TString TextureString(const TType &type); -TString SamplerString(const TType &type); +// Unique combinations of HLSL Texture type and HLSL Sampler type. +enum HLSLTextureSamplerGroup +{ + // Regular samplers + HLSL_TEXTURE_2D, + HLSL_TEXTURE_MIN = HLSL_TEXTURE_2D, + + HLSL_TEXTURE_CUBE, + HLSL_TEXTURE_2D_ARRAY, + HLSL_TEXTURE_3D, + HLSL_TEXTURE_2D_INT4, + HLSL_TEXTURE_3D_INT4, + HLSL_TEXTURE_2D_ARRAY_INT4, + HLSL_TEXTURE_2D_UINT4, + HLSL_TEXTURE_3D_UINT4, + HLSL_TEXTURE_2D_ARRAY_UINT4, + + // Comparison samplers + + HLSL_TEXTURE_2D_COMPARISON, + HLSL_TEXTURE_CUBE_COMPARISON, + HLSL_TEXTURE_2D_ARRAY_COMPARISON, + + HLSL_COMPARISON_SAMPLER_GROUP_BEGIN = HLSL_TEXTURE_2D_COMPARISON, + HLSL_COMPARISON_SAMPLER_GROUP_END = HLSL_TEXTURE_2D_ARRAY_COMPARISON, + + HLSL_TEXTURE_UNKNOWN, + HLSL_TEXTURE_MAX = HLSL_TEXTURE_UNKNOWN +}; + +HLSLTextureSamplerGroup TextureGroup(const TBasicType type); +TString TextureString(const HLSLTextureSamplerGroup type); +TString TextureString(const TBasicType type); +TString TextureGroupSuffix(const HLSLTextureSamplerGroup type); +TString TextureGroupSuffix(const TBasicType type); +TString TextureTypeSuffix(const TBasicType type); +TString SamplerString(const TBasicType type); +TString SamplerString(HLSLTextureSamplerGroup type); // Prepends an underscore to avoid naming clashes TString Decorate(const TString &string); -TString DecorateUniform(const TString &string, const TType &type); +TString DecorateIfNeeded(const TName &name); +// Decorates and also unmangles the function name +TString DecorateFunctionIfNeeded(const TName &name); +TString DecorateUniform(const TName &name, const TType &type); TString DecorateField(const TString &string, const TStructure &structure); TString DecoratePrivate(const TString &privateText); TString TypeString(const TType &type); @@ -31,7 +73,10 @@ TString QualifiedStructNameString(const TStructure &structure, bool useHLSLRowMa bool useStd140Packing); TString InterpolationString(TQualifier qualifier); TString QualifierString(TQualifier qualifier); - +int HLSLTextureCoordsCount(const TBasicType samplerType); +// Parameters may need to be included in function names to disambiguate between overloaded +// functions. +TString DisambiguateFunctionName(const TIntermSequence *parameters); } #endif // COMPILER_TRANSLATOR_UTILSHLSL_H_ diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/ValidateGlobalInitializer.cpp b/Source/ThirdParty/ANGLE/src/compiler/translator/ValidateGlobalInitializer.cpp new file mode 100644 index 000000000000..2461b6a4383b --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/ValidateGlobalInitializer.cpp @@ -0,0 +1,112 @@ +// +// Copyright (c) 2002-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. +// + +#include "compiler/translator/ValidateGlobalInitializer.h" + +#include "compiler/translator/ParseContext.h" + +namespace +{ + +class ValidateGlobalInitializerTraverser : public TIntermTraverser +{ + public: + ValidateGlobalInitializerTraverser(const TParseContext *context); + + void visitSymbol(TIntermSymbol *node) override; + bool visitAggregate(Visit visit, TIntermAggregate *node) override; + bool visitBinary(Visit visit, TIntermBinary *node) override; + bool visitUnary(Visit visit, TIntermUnary *node) override; + + bool isValid() const { return mIsValid; } + bool issueWarning() const { return mIssueWarning; } + + private: + const TParseContext *mContext; + bool mIsValid; + bool mIssueWarning; +}; + +void ValidateGlobalInitializerTraverser::visitSymbol(TIntermSymbol *node) +{ + const TSymbol *sym = mContext->symbolTable.find(node->getSymbol(), mContext->getShaderVersion()); + if (sym->isVariable()) + { + // ESSL 1.00 section 4.3 (or ESSL 3.00 section 4.3): + // Global initializers must be constant expressions. + const TVariable *var = static_cast(sym); + switch (var->getType().getQualifier()) + { + case EvqConst: + break; + case EvqGlobal: + case EvqTemporary: + case EvqUniform: + // We allow these cases to be compatible with legacy ESSL 1.00 content. + // Implement stricter rules for ESSL 3.00 since there's no legacy content to deal with. + if (mContext->getShaderVersion() >= 300) + { + mIsValid = false; + } + else + { + mIssueWarning = true; + } + break; + default: + mIsValid = false; + } + } +} + +bool ValidateGlobalInitializerTraverser::visitAggregate(Visit visit, TIntermAggregate *node) +{ + // Disallow calls to user-defined functions and texture lookup functions in global variable initializers. + // This is done simply by disabling all function calls - built-in math functions don't use EOpFunctionCall. + if (node->getOp() == EOpFunctionCall) + { + mIsValid = false; + } + return true; +} + +bool ValidateGlobalInitializerTraverser::visitBinary(Visit visit, TIntermBinary *node) +{ + if (node->isAssignment()) + { + mIsValid = false; + } + return true; +} + +bool ValidateGlobalInitializerTraverser::visitUnary(Visit visit, TIntermUnary *node) +{ + if (node->isAssignment()) + { + mIsValid = false; + } + return true; +} + +ValidateGlobalInitializerTraverser::ValidateGlobalInitializerTraverser(const TParseContext *context) + : TIntermTraverser(true, false, false), + mContext(context), + mIsValid(true), + mIssueWarning(false) +{ +} + +} // namespace + +bool ValidateGlobalInitializer(TIntermTyped *initializer, const TParseContext *context, bool *warning) +{ + ValidateGlobalInitializerTraverser validate(context); + initializer->traverse(&validate); + ASSERT(warning != nullptr); + *warning = validate.issueWarning(); + return validate.isValid(); +} + diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/ValidateGlobalInitializer.h b/Source/ThirdParty/ANGLE/src/compiler/translator/ValidateGlobalInitializer.h new file mode 100644 index 000000000000..c3d2a47eba22 --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/ValidateGlobalInitializer.h @@ -0,0 +1,16 @@ +// +// Copyright (c) 2002-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. +// + +#ifndef COMPILER_TRANSLATOR_VALIDATEGLOBALINITIALIZER_H_ +#define COMPILER_TRANSLATOR_VALIDATEGLOBALINITIALIZER_H_ + +class TIntermTyped; +class TParseContext; + +// Returns true if the initializer is valid. +bool ValidateGlobalInitializer(TIntermTyped *initializer, const TParseContext *context, bool *warning); + +#endif // COMPILER_TRANSLATOR_VALIDATEGLOBALINITIALIZER_H_ diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/ValidateLimitations.cpp b/Source/ThirdParty/ANGLE/src/compiler/translator/ValidateLimitations.cpp index 12367066e8ef..ba8cdd0aa818 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/ValidateLimitations.cpp +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/ValidateLimitations.cpp @@ -26,12 +26,16 @@ class ValidateConstIndexExpr : public TIntermTraverser { public: ValidateConstIndexExpr(TLoopStack& stack) - : mValid(true), mLoopStack(stack) {} + : TIntermTraverser(true, false, false), + mValid(true), + mLoopStack(stack) + { + } // Returns true if the parsed node represents a constant index expression. bool isValid() const { return mValid; } - virtual void visitSymbol(TIntermSymbol *symbol) + void visitSymbol(TIntermSymbol *symbol) override { // Only constants and loop indices are allowed in a // constant index expression. @@ -49,12 +53,35 @@ class ValidateConstIndexExpr : public TIntermTraverser } // namespace anonymous -ValidateLimitations::ValidateLimitations(sh::GLenum shaderType, - TInfoSinkBase &sink) - : mShaderType(shaderType), +ValidateLimitations::ValidateLimitations(sh::GLenum shaderType, TInfoSinkBase *sink) + : TIntermTraverser(true, false, false), + mShaderType(shaderType), mSink(sink), - mNumErrors(0) + mNumErrors(0), + mValidateIndexing(true), + mValidateInnerLoops(true) +{ +} + +// static +bool ValidateLimitations::IsLimitedForLoop(TIntermLoop *loop) { + // The shader type doesn't matter in this case. + ValidateLimitations validate(GL_FRAGMENT_SHADER, nullptr); + validate.mValidateIndexing = false; + validate.mValidateInnerLoops = false; + if (!validate.validateLoopType(loop)) + return false; + if (!validate.validateForLoopHeader(loop)) + return false; + TIntermNode *body = loop->getBody(); + if (body != nullptr) + { + validate.mLoopStack.push(loop); + body->traverse(&validate); + validate.mLoopStack.pop(); + } + return (validate.mNumErrors == 0); } bool ValidateLimitations::visitBinary(Visit, TIntermBinary *node) @@ -67,10 +94,11 @@ bool ValidateLimitations::visitBinary(Visit, TIntermBinary *node) { case EOpIndexDirect: case EOpIndexIndirect: - validateIndexing(node); - break; + if (mValidateIndexing) + validateIndexing(node); + break; default: - break; + break; } return true; } @@ -97,6 +125,9 @@ bool ValidateLimitations::visitAggregate(Visit, TIntermAggregate *node) bool ValidateLimitations::visitLoop(Visit, TIntermLoop *node) { + if (!mValidateInnerLoops) + return true; + if (!validateLoopType(node)) return false; @@ -118,9 +149,12 @@ bool ValidateLimitations::visitLoop(Visit, TIntermLoop *node) void ValidateLimitations::error(TSourceLoc loc, const char *reason, const char *token) { - mSink.prefix(EPrefixError); - mSink.location(loc); - mSink << "'" << token << "' : " << reason << "\n"; + if (mSink) + { + mSink->prefix(EPrefixError); + mSink->location(loc); + (*mSink) << "'" << token << "' : " << reason << "\n"; + } ++mNumErrors; } @@ -389,13 +423,13 @@ bool ValidateLimitations::validateFunctionCall(TIntermAggregate *node) bool valid = true; TSymbolTable& symbolTable = GetGlobalParseContext()->symbolTable; - TSymbol* symbol = symbolTable.find(node->getName(), GetGlobalParseContext()->shaderVersion); + TSymbol* symbol = symbolTable.find(node->getName(), GetGlobalParseContext()->getShaderVersion()); ASSERT(symbol && symbol->isFunction()); TFunction *function = static_cast(symbol); for (ParamIndex::const_iterator i = pIndex.begin(); i != pIndex.end(); ++i) { - const TParameter ¶m = function->getParam(*i); + const TConstParameter ¶m = function->getParam(*i); TQualifier qual = param.type->getQualifier(); if ((qual == EvqOut) || (qual == EvqInOut)) { @@ -428,8 +462,8 @@ bool ValidateLimitations::validateOperation(TIntermOperator *node, bool ValidateLimitations::isConstExpr(TIntermNode *node) { - ASSERT(node != NULL); - return node->getAsConstantUnion() != NULL; + ASSERT(node != nullptr); + return node->getAsConstantUnion() != nullptr && node->getAsTyped()->getQualifier() == EvqConst; } bool ValidateLimitations::isConstIndexExpr(TIntermNode *node) @@ -448,13 +482,6 @@ bool ValidateLimitations::validateIndexing(TIntermBinary *node) bool valid = true; TIntermTyped *index = node->getRight(); - // The index expression must have integral type. - if (!index->isScalarInt()) { - error(index->getLine(), - "Index expression must have integral type", - index->getCompleteString().c_str()); - valid = false; - } // The index expession must be a constant-index-expression unless // the operand is a uniform in a vertex shader. TIntermTyped *operand = node->getLeft(); diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/ValidateLimitations.h b/Source/ThirdParty/ANGLE/src/compiler/translator/ValidateLimitations.h index 59cccb565ffb..666e38ff5c88 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/ValidateLimitations.h +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/ValidateLimitations.h @@ -17,14 +17,16 @@ class TInfoSinkBase; class ValidateLimitations : public TIntermTraverser { public: - ValidateLimitations(sh::GLenum shaderType, TInfoSinkBase &sink); + ValidateLimitations(sh::GLenum shaderType, TInfoSinkBase *sink); int numErrors() const { return mNumErrors; } - virtual bool visitBinary(Visit, TIntermBinary *); - virtual bool visitUnary(Visit, TIntermUnary *); - virtual bool visitAggregate(Visit, TIntermAggregate *); - virtual bool visitLoop(Visit, TIntermLoop *); + bool visitBinary(Visit, TIntermBinary *) override; + bool visitUnary(Visit, TIntermUnary *) override; + bool visitAggregate(Visit, TIntermAggregate *) override; + bool visitLoop(Visit, TIntermLoop *) override; + + static bool IsLimitedForLoop(TIntermLoop *node); private: void error(TSourceLoc loc, const char *reason, const char *token); @@ -51,9 +53,11 @@ class ValidateLimitations : public TIntermTraverser bool validateIndexing(TIntermBinary *node); sh::GLenum mShaderType; - TInfoSinkBase &mSink; + TInfoSinkBase *mSink; int mNumErrors; TLoopStack mLoopStack; + bool mValidateIndexing; + bool mValidateInnerLoops; }; #endif // COMPILER_TRANSLATOR_VALIDATELIMITATIONS_H_ diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/ValidateMaxParameters.cpp b/Source/ThirdParty/ANGLE/src/compiler/translator/ValidateMaxParameters.cpp new file mode 100644 index 000000000000..00b3c9b451ba --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/ValidateMaxParameters.cpp @@ -0,0 +1,35 @@ +// +// Copyright (c) 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. +// +// ValidateMaxParameters checks if function definitions have more than a set number of parameters. + +#include "compiler/translator/ValidateMaxParameters.h" + +ValidateMaxParameters::ValidateMaxParameters(unsigned int maxParameters) + : TIntermTraverser(true, false, false), mMaxParameters(maxParameters), mValid(true) +{ +} + +bool ValidateMaxParameters::visitAggregate(Visit visit, TIntermAggregate *node) +{ + if (!mValid) + { + return false; + } + + if (node->getOp() == EOpParameters && node->getSequence()->size() > mMaxParameters) + { + mValid = false; + } + + return mValid; +} + +bool ValidateMaxParameters::validate(TIntermNode *root, unsigned int maxParameters) +{ + ValidateMaxParameters argsTraverser(maxParameters); + root->traverse(&argsTraverser); + return argsTraverser.mValid; +} diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/ValidateMaxParameters.h b/Source/ThirdParty/ANGLE/src/compiler/translator/ValidateMaxParameters.h new file mode 100644 index 000000000000..87916afef8fd --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/ValidateMaxParameters.h @@ -0,0 +1,29 @@ +// +// Copyright (c) 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. +// +// ValidateMaxParameters checks if function definitions have more than a set number of parameters. + +#ifndef COMPILER_TRANSLATOR_VALIDATEMAXPARAMETERS_H_ +#define COMPILER_TRANSLATOR_VALIDATEMAXPARAMETERS_H_ + +#include "compiler/translator/IntermNode.h" + +class ValidateMaxParameters : public TIntermTraverser +{ + public: + // Returns false if maxParameters is exceeded. + static bool validate(TIntermNode *root, unsigned int maxParameters); + + protected: + bool visitAggregate(Visit visit, TIntermAggregate *node) override; + + private: + ValidateMaxParameters(unsigned int maxParameters); + + unsigned int mMaxParameters; + bool mValid; +}; + +#endif // COMPILER_TRANSLATOR_VALIDATEMAXPARAMETERS_H_ diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/ValidateOutputs.cpp b/Source/ThirdParty/ANGLE/src/compiler/translator/ValidateOutputs.cpp index ac1c10d6b035..cd37aeacd117 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/ValidateOutputs.cpp +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/ValidateOutputs.cpp @@ -9,11 +9,23 @@ #include "compiler/translator/InitializeParseContext.h" #include "compiler/translator/ParseContext.h" -ValidateOutputs::ValidateOutputs(TInfoSinkBase& sink, int maxDrawBuffers) - : mSink(sink), +namespace +{ +void error(int *errorCount, TInfoSinkBase &sink, const TIntermSymbol &symbol, const char *reason) +{ + sink.prefix(EPrefixError); + sink.location(symbol.getLine()); + sink << "'" << symbol.getSymbol() << "' : " << reason << "\n"; + (*errorCount)++; +} + +} // namespace + +ValidateOutputs::ValidateOutputs(const TExtensionBehavior &extBehavior, int maxDrawBuffers) + : TIntermTraverser(true, false, false), mMaxDrawBuffers(maxDrawBuffers), - mNumErrors(0), - mHasUnspecifiedOutputLocation(false) + mAllowUnspecifiedOutputLocationResolution( + IsExtensionEnabled(extBehavior, "GL_EXT_blend_func_extended")) { } @@ -29,50 +41,68 @@ void ValidateOutputs::visitSymbol(TIntermSymbol *symbol) if (qualifier == EvqFragmentOut) { - const TType &type = symbol->getType(); - const int location = type.getLayoutQualifier().location; - - if (mHasUnspecifiedOutputLocation) + if (symbol->getType().getLayoutQualifier().location == -1) { - error(symbol->getLine(), "must explicitly specify all locations when using multiple fragment outputs", name.c_str()); + mUnspecifiedLocationOutputs.push_back(symbol); } - else if (location == -1) + else { - mHasUnspecifiedOutputLocation = true; + mOutputs.push_back(symbol); } - else + } +} + +int ValidateOutputs::validateAndCountErrors(TInfoSinkBase &sink) const +{ + OutputVector validOutputs(mMaxDrawBuffers); + int errorCount = 0; + + for (const auto &symbol : mOutputs) + { + const TType &type = symbol->getType(); + const size_t elementCount = static_cast(type.isArray() ? type.getArraySize() : 1); + const size_t location = static_cast(type.getLayoutQualifier().location); + + ASSERT(type.getLayoutQualifier().location != -1); + + if (location + elementCount <= validOutputs.size()) { - OutputMap::iterator mapEntry = mOutputMap.find(location); - if (mapEntry == mOutputMap.end()) + for (size_t elementIndex = 0; elementIndex < elementCount; elementIndex++) { - const int elementCount = type.isArray() ? type.getArraySize() : 1; - if (location + elementCount > mMaxDrawBuffers) + const size_t offsetLocation = location + elementIndex; + if (validOutputs[offsetLocation]) { - error(symbol->getLine(), "output location must be < MAX_DRAW_BUFFERS", name.c_str()); + std::stringstream strstr; + strstr << "conflicting output locations with previously defined output '" + << validOutputs[offsetLocation]->getSymbol() << "'"; + error(&errorCount, sink, *symbol, strstr.str().c_str()); } - - for (int elementIndex = 0; elementIndex < elementCount; elementIndex++) + else { - const int offsetLocation = location + elementIndex; - mOutputMap[offsetLocation] = symbol; + validOutputs[offsetLocation] = symbol; } } - else + } + else + { + if (elementCount > 0) { - std::stringstream strstr; - strstr << "conflicting output locations with previously defined output '" - << mapEntry->second->getSymbol() << "'"; - - error(symbol->getLine(), strstr.str().c_str(), name.c_str()); + error(&errorCount, sink, *symbol, + elementCount > 1 ? "output array locations would exceed MAX_DRAW_BUFFERS" + : "output location must be < MAX_DRAW_BUFFERS"); } } } -} -void ValidateOutputs::error(TSourceLoc loc, const char *reason, const char* token) -{ - mSink.prefix(EPrefixError); - mSink.location(loc); - mSink << "'" << token << "' : " << reason << "\n"; - mNumErrors++; + if (!mAllowUnspecifiedOutputLocationResolution && + ((!mOutputs.empty() && !mUnspecifiedLocationOutputs.empty()) || + mUnspecifiedLocationOutputs.size() > 1)) + { + for (const auto &symbol : mUnspecifiedLocationOutputs) + { + error(&errorCount, sink, *symbol, + "must explicitly specify all locations when using multiple fragment outputs"); + } + } + return errorCount; } diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/ValidateOutputs.h b/Source/ThirdParty/ANGLE/src/compiler/translator/ValidateOutputs.h index 1538e0f1571f..06f63994cdf7 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/ValidateOutputs.h +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/ValidateOutputs.h @@ -7,6 +7,7 @@ #ifndef COMPILER_TRANSLATOR_VALIDATEOUTPUTS_H_ #define COMPILER_TRANSLATOR_VALIDATEOUTPUTS_H_ +#include "compiler/translator/ExtensionBehavior.h" #include "compiler/translator/IntermNode.h" #include @@ -16,23 +17,20 @@ class TInfoSinkBase; class ValidateOutputs : public TIntermTraverser { public: - ValidateOutputs(TInfoSinkBase& sink, int maxDrawBuffers); + ValidateOutputs(const TExtensionBehavior &extBehavior, int maxDrawBuffers); - int numErrors() const { return mNumErrors; } + int validateAndCountErrors(TInfoSinkBase &sink) const; - virtual void visitSymbol(TIntermSymbol*); + void visitSymbol(TIntermSymbol *) override; private: - TInfoSinkBase& mSink; int mMaxDrawBuffers; - int mNumErrors; - bool mHasUnspecifiedOutputLocation; + bool mAllowUnspecifiedOutputLocationResolution; - typedef std::map OutputMap; - OutputMap mOutputMap; + typedef std::vector OutputVector; + OutputVector mOutputs; + OutputVector mUnspecifiedLocationOutputs; std::set mVisitedSymbols; - - void error(TSourceLoc loc, const char *reason, const char* token); }; #endif // COMPILER_TRANSLATOR_VALIDATEOUTPUTS_H_ diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/ValidateSwitch.h b/Source/ThirdParty/ANGLE/src/compiler/translator/ValidateSwitch.h index 88b68a500e9c..ddbefc561974 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/ValidateSwitch.h +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/ValidateSwitch.h @@ -9,7 +9,7 @@ #include "compiler/translator/IntermNode.h" -struct TParseContext; +class TParseContext; class ValidateSwitch : public TIntermTraverser { diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/VariableInfo.cpp b/Source/ThirdParty/ANGLE/src/compiler/translator/VariableInfo.cpp index 1aa9e591eb76..611c1512d1f2 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/VariableInfo.cpp +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/VariableInfo.cpp @@ -16,18 +16,6 @@ namespace sh namespace { -TString InterfaceBlockFieldName(const TInterfaceBlock &interfaceBlock, const TField &field) -{ - if (interfaceBlock.hasInstanceName()) - { - return interfaceBlock.name() + "." + field.name(); - } - else - { - return field.name(); - } -} - BlockLayoutType GetBlockLayoutType(TLayoutBlockStorage blockStorage) { switch (blockStorage) @@ -55,7 +43,8 @@ void ExpandVariable(const ShaderVariable &variable, { if (variable.isArray()) { - for (unsigned int elementIndex = 0; elementIndex < variable.elementCount(); elementIndex++) + for (unsigned int elementIndex = 0; elementIndex < variable.elementCount(); + elementIndex++) { std::string lname = name + ::ArrayString(elementIndex); std::string lmappedName = mappedName + ::ArrayString(elementIndex); @@ -128,13 +117,14 @@ VarT *FindVariable(const TString &name, } CollectVariables::CollectVariables(std::vector *attribs, - std::vector *outputVariables, + std::vector *outputVariables, std::vector *uniforms, std::vector *varyings, std::vector *interfaceBlocks, ShHashFunction64 hashFunction, const TSymbolTable &symbolTable) - : mAttribs(attribs), + : TIntermTraverser(true, false, false), + mAttribs(attribs), mOutputVariables(outputVariables), mUniforms(uniforms), mVaryings(varyings), @@ -144,9 +134,16 @@ CollectVariables::CollectVariables(std::vector *attribs, mFrontFacingAdded(false), mFragCoordAdded(false), mInstanceIDAdded(false), + mVertexIDAdded(false), mPositionAdded(false), mPointSizeAdded(false), mLastFragDataAdded(false), + mFragColorAdded(false), + mFragDataAdded(false), + mFragDepthEXTAdded(false), + mFragDepthAdded(false), + mSecondaryFragColorEXTAdded(false), + mSecondaryFragDataEXTAdded(false), mHashFunction(hashFunction), mSymbolTable(symbolTable) { @@ -317,6 +314,22 @@ void CollectVariables::visitSymbol(TIntermSymbol *symbol) mInstanceIDAdded = true; } return; + case EvqVertexID: + if (!mVertexIDAdded) + { + Attribute info; + const char kName[] = "gl_VertexID"; + info.name = kName; + info.mappedName = kName; + info.type = GL_INT; + info.arraySize = 0; + info.precision = GL_HIGH_INT; // Defined by spec. + info.staticUse = true; + info.location = -1; + mAttribs->push_back(info); + mVertexIDAdded = true; + } + return; case EvqPosition: if (!mPositionAdded) { @@ -365,6 +378,105 @@ void CollectVariables::visitSymbol(TIntermSymbol *symbol) mLastFragDataAdded = true; } return; + case EvqFragColor: + if (!mFragColorAdded) + { + OutputVariable info; + const char kName[] = "gl_FragColor"; + info.name = kName; + info.mappedName = kName; + info.type = GL_FLOAT_VEC4; + info.arraySize = 0; + info.precision = GL_MEDIUM_FLOAT; // Defined by spec. + info.staticUse = true; + mOutputVariables->push_back(info); + mFragColorAdded = true; + } + return; + case EvqFragData: + if (!mFragDataAdded) + { + OutputVariable info; + const char kName[] = "gl_FragData"; + info.name = kName; + info.mappedName = kName; + info.type = GL_FLOAT_VEC4; + info.arraySize = static_cast( + mSymbolTable.findBuiltIn("gl_MaxDrawBuffers", 100)) + ->getConstPointer() + ->getIConst(); + info.precision = GL_MEDIUM_FLOAT; // Defined by spec. + info.staticUse = true; + mOutputVariables->push_back(info); + mFragDataAdded = true; + } + return; + case EvqFragDepthEXT: + if (!mFragDepthEXTAdded) + { + OutputVariable info; + const char kName[] = "gl_FragDepthEXT"; + info.name = kName; + info.mappedName = kName; + info.type = GL_FLOAT; + info.arraySize = 0; + info.precision = + GLVariablePrecision(static_cast( + mSymbolTable.findBuiltIn("gl_FragDepthEXT", 100)) + ->getType()); + info.staticUse = true; + mOutputVariables->push_back(info); + mFragDepthEXTAdded = true; + } + return; + case EvqFragDepth: + if (!mFragDepthAdded) + { + OutputVariable info; + const char kName[] = "gl_FragDepth"; + info.name = kName; + info.mappedName = kName; + info.type = GL_FLOAT; + info.arraySize = 0; + info.precision = GL_HIGH_FLOAT; + info.staticUse = true; + mOutputVariables->push_back(info); + mFragDepthAdded = true; + } + return; + case EvqSecondaryFragColorEXT: + if (!mSecondaryFragColorEXTAdded) + { + OutputVariable info; + const char kName[] = "gl_SecondaryFragColorEXT"; + info.name = kName; + info.mappedName = kName; + info.type = GL_FLOAT_VEC4; + info.arraySize = 0; + info.precision = GL_MEDIUM_FLOAT; // Defined by spec. + info.staticUse = true; + mOutputVariables->push_back(info); + mSecondaryFragColorEXTAdded = true; + } + return; + case EvqSecondaryFragDataEXT: + if (!mSecondaryFragDataEXTAdded) + { + OutputVariable info; + const char kName[] = "gl_SecondaryFragDataEXT"; + info.name = kName; + info.mappedName = kName; + info.type = GL_FLOAT_VEC4; + + const TVariable *maxDualSourceDrawBuffersVar = static_cast( + mSymbolTable.findBuiltIn("gl_MaxDualSourceDrawBuffersEXT", 100)); + info.arraySize = maxDualSourceDrawBuffersVar->getConstPointer()->getIConst(); + info.precision = GL_MEDIUM_FLOAT; // Defined by spec. + info.staticUse = true; + mOutputVariables->push_back(info); + mSecondaryFragDataEXTAdded = true; + } + return; default: break; } @@ -385,7 +497,7 @@ class NameHashingTraverser : public GetVariableTraverser {} private: - virtual void visitVariable(ShaderVariable *variable) + void visitVariable(ShaderVariable *variable) override { TString stringName = TString(variable->name.c_str()); variable->mappedName = TIntermTraverser::hash(stringName, mHashFunction).c_str(); @@ -415,6 +527,26 @@ void CollectVariables::visitVariable(const TIntermSymbol *variable, infoList->push_back(attribute); } +template <> +void CollectVariables::visitVariable(const TIntermSymbol *variable, + std::vector *infoList) const +{ + ASSERT(variable); + const TType &type = variable->getType(); + ASSERT(!type.getStruct()); + + OutputVariable attribute; + + attribute.type = GLVariableType(type); + attribute.precision = GLVariablePrecision(type); + attribute.name = variable->getSymbol().c_str(); + attribute.arraySize = static_cast(type.getArraySize()); + attribute.mappedName = TIntermTraverser::hash(variable->getSymbol(), mHashFunction).c_str(); + attribute.location = variable->getType().getLayoutQualifier().location; + + infoList->push_back(attribute); +} + template <> void CollectVariables::visitVariable(const TIntermSymbol *variable, std::vector *infoList) const @@ -424,23 +556,20 @@ void CollectVariables::visitVariable(const TIntermSymbol *variable, ASSERT(blockType); interfaceBlock.name = blockType->name().c_str(); - interfaceBlock.mappedName = TIntermTraverser::hash(variable->getSymbol(), mHashFunction).c_str(); + interfaceBlock.mappedName = + TIntermTraverser::hash(blockType->name().c_str(), mHashFunction).c_str(); interfaceBlock.instanceName = (blockType->hasInstanceName() ? blockType->instanceName().c_str() : ""); interfaceBlock.arraySize = variable->getArraySize(); interfaceBlock.isRowMajorLayout = (blockType->matrixPacking() == EmpRowMajor); interfaceBlock.layout = GetBlockLayoutType(blockType->blockStorage()); // Gather field information - const TFieldList &fieldList = blockType->fields(); - - for (size_t fieldIndex = 0; fieldIndex < fieldList.size(); ++fieldIndex) + for (const TField *field : blockType->fields()) { - const TField &field = *fieldList[fieldIndex]; - const TString &fullFieldName = InterfaceBlockFieldName(*blockType, field); - const TType &fieldType = *field.type(); + const TType &fieldType = *field->type(); - GetVariableTraverser traverser(mSymbolTable); - traverser.traverse(fieldType, fullFieldName, &interfaceBlock.fields); + NameHashingTraverser traverser(mHashFunction, mSymbolTable); + traverser.traverse(fieldType, field->name(), &interfaceBlock.fields); interfaceBlock.fields.back().isRowMajorLayout = (fieldType.getLayoutQualifier().matrixPacking == EmpRowMajor); } diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/VariableInfo.h b/Source/ThirdParty/ANGLE/src/compiler/translator/VariableInfo.h index 0b7e033c6a4b..e6d01758ec6d 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/VariableInfo.h +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/VariableInfo.h @@ -21,16 +21,16 @@ class CollectVariables : public TIntermTraverser { public: CollectVariables(std::vector *attribs, - std::vector *outputVariables, + std::vector *outputVariables, std::vector *uniforms, std::vector *varyings, std::vector *interfaceBlocks, ShHashFunction64 hashFunction, const TSymbolTable &symbolTable); - virtual void visitSymbol(TIntermSymbol *symbol); - virtual bool visitAggregate(Visit, TIntermAggregate *node); - virtual bool visitBinary(Visit visit, TIntermBinary *binaryNode); + void visitSymbol(TIntermSymbol *symbol) override; + bool visitAggregate(Visit, TIntermAggregate *node) override; + bool visitBinary(Visit visit, TIntermBinary *binaryNode) override; private: template @@ -40,7 +40,7 @@ class CollectVariables : public TIntermTraverser void visitInfoList(const TIntermSequence &sequence, std::vector *infoList) const; std::vector *mAttribs; - std::vector *mOutputVariables; + std::vector *mOutputVariables; std::vector *mUniforms; std::vector *mVaryings; std::vector *mInterfaceBlocks; @@ -53,9 +53,16 @@ class CollectVariables : public TIntermTraverser bool mFragCoordAdded; bool mInstanceIDAdded; + bool mVertexIDAdded; bool mPositionAdded; bool mPointSizeAdded; bool mLastFragDataAdded; + bool mFragColorAdded; + bool mFragDataAdded; + bool mFragDepthEXTAdded; + bool mFragDepthAdded; + bool mSecondaryFragColorEXTAdded; + bool mSecondaryFragDataEXTAdded; ShHashFunction64 mHashFunction; diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/VersionGLSL.cpp b/Source/ThirdParty/ANGLE/src/compiler/translator/VersionGLSL.cpp index 99bcf07a36f6..c8718daa1028 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/VersionGLSL.cpp +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/VersionGLSL.cpp @@ -6,11 +6,24 @@ #include "compiler/translator/VersionGLSL.h" -static const int GLSL_VERSION_110 = 110; -static const int GLSL_VERSION_120 = 120; -static const int GLSL_VERSION_130 = 130; -static const int GLSL_VERSION_410 = 410; -static const int GLSL_VERSION_420 = 420; +int ShaderOutputTypeToGLSLVersion(ShShaderOutput output) +{ + switch (output) + { + case SH_GLSL_130_OUTPUT: return GLSL_VERSION_130; + case SH_GLSL_140_OUTPUT: return GLSL_VERSION_140; + case SH_GLSL_150_CORE_OUTPUT: return GLSL_VERSION_150; + case SH_GLSL_330_CORE_OUTPUT: return GLSL_VERSION_330; + case SH_GLSL_400_CORE_OUTPUT: return GLSL_VERSION_400; + case SH_GLSL_410_CORE_OUTPUT: return GLSL_VERSION_410; + case SH_GLSL_420_CORE_OUTPUT: return GLSL_VERSION_420; + case SH_GLSL_430_CORE_OUTPUT: return GLSL_VERSION_430; + case SH_GLSL_440_CORE_OUTPUT: return GLSL_VERSION_440; + case SH_GLSL_450_CORE_OUTPUT: return GLSL_VERSION_450; + case SH_GLSL_COMPATIBILITY_OUTPUT: return GLSL_VERSION_110; + default: UNREACHABLE(); return 0; + } +} // We need to scan for the following: // 1. "invariant" keyword: This can occur in both - vertex and fragment shaders @@ -32,33 +45,21 @@ static const int GLSL_VERSION_420 = 420; TVersionGLSL::TVersionGLSL(sh::GLenum type, const TPragma &pragma, ShShaderOutput output) + : TIntermTraverser(true, false, false) { - if (output == SH_GLSL_130_OUTPUT) - { - mVersion = GLSL_VERSION_130; - } - else if (output == SH_GLSL_410_CORE_OUTPUT) + mVersion = ShaderOutputTypeToGLSLVersion(output); + if (pragma.stdgl.invariantAll) { - mVersion = GLSL_VERSION_410; - } - else if (output == SH_GLSL_420_CORE_OUTPUT) - { - mVersion = GLSL_VERSION_420; - } - else - { - ASSERT(output == SH_GLSL_COMPATIBILITY_OUTPUT); - if (pragma.stdgl.invariantAll) - mVersion = GLSL_VERSION_120; - else - mVersion = GLSL_VERSION_110; + ensureVersionIsAtLeast(GLSL_VERSION_120); } } void TVersionGLSL::visitSymbol(TIntermSymbol *node) { if (node->getSymbol() == "gl_PointCoord") - updateVersion(GLSL_VERSION_120); + { + ensureVersionIsAtLeast(GLSL_VERSION_120); + } } bool TVersionGLSL::visitAggregate(Visit, TIntermAggregate *node) @@ -74,16 +75,14 @@ bool TVersionGLSL::visitAggregate(Visit, TIntermAggregate *node) case EOpDeclaration: { const TIntermSequence &sequence = *(node->getSequence()); - TQualifier qualifier = sequence.front()->getAsTyped()->getQualifier(); - if ((qualifier == EvqInvariantVaryingIn) || - (qualifier == EvqInvariantVaryingOut)) + if (sequence.front()->getAsTyped()->getType().isInvariant()) { - updateVersion(GLSL_VERSION_120); + ensureVersionIsAtLeast(GLSL_VERSION_120); } break; } case EOpInvariantDeclaration: - updateVersion(GLSL_VERSION_120); + ensureVersionIsAtLeast(GLSL_VERSION_120); break; case EOpParameters: { @@ -97,7 +96,7 @@ bool TVersionGLSL::visitAggregate(Visit, TIntermAggregate *node) TQualifier qualifier = param->getQualifier(); if ((qualifier == EvqOut) || (qualifier == EvqInOut)) { - updateVersion(GLSL_VERSION_120); + ensureVersionIsAtLeast(GLSL_VERSION_120); break; } } @@ -107,7 +106,13 @@ bool TVersionGLSL::visitAggregate(Visit, TIntermAggregate *node) break; } case EOpConstructMat2: + case EOpConstructMat2x3: + case EOpConstructMat2x4: + case EOpConstructMat3x2: case EOpConstructMat3: + case EOpConstructMat3x4: + case EOpConstructMat4x2: + case EOpConstructMat4x3: case EOpConstructMat4: { const TIntermSequence &sequence = *(node->getSequence()); @@ -116,7 +121,7 @@ bool TVersionGLSL::visitAggregate(Visit, TIntermAggregate *node) TIntermTyped *typed = sequence.front()->getAsTyped(); if (typed && typed->isMatrix()) { - updateVersion(GLSL_VERSION_120); + ensureVersionIsAtLeast(GLSL_VERSION_120); } } break; @@ -128,7 +133,7 @@ bool TVersionGLSL::visitAggregate(Visit, TIntermAggregate *node) return visitChildren; } -void TVersionGLSL::updateVersion(int version) +void TVersionGLSL::ensureVersionIsAtLeast(int version) { mVersion = std::max(version, mVersion); } diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/VersionGLSL.h b/Source/ThirdParty/ANGLE/src/compiler/translator/VersionGLSL.h index 2b63d5f25db9..c41069d42dfb 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/VersionGLSL.h +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/VersionGLSL.h @@ -11,6 +11,21 @@ #include "compiler/translator/Pragma.h" +static const int GLSL_VERSION_110 = 110; +static const int GLSL_VERSION_120 = 120; +static const int GLSL_VERSION_130 = 130; +static const int GLSL_VERSION_140 = 140; +static const int GLSL_VERSION_150 = 150; +static const int GLSL_VERSION_330 = 330; +static const int GLSL_VERSION_400 = 400; +static const int GLSL_VERSION_410 = 410; +static const int GLSL_VERSION_420 = 420; +static const int GLSL_VERSION_430 = 430; +static const int GLSL_VERSION_440 = 440; +static const int GLSL_VERSION_450 = 450; + +int ShaderOutputTypeToGLSLVersion(ShShaderOutput output); + // Traverses the intermediate tree to return the minimum GLSL version // required to legally access all built-in features used in the shader. // GLSL 1.1 which is mandated by OpenGL 2.0 provides: @@ -39,15 +54,14 @@ class TVersionGLSL : public TIntermTraverser // - matrix/matrix constructors // - array "out" parameters // Else 110 is returned. - int getVersion() { return mVersion; } + int getVersion() const { return mVersion; } - virtual void visitSymbol(TIntermSymbol *); - virtual bool visitAggregate(Visit, TIntermAggregate *); - - protected: - void updateVersion(int version); + void visitSymbol(TIntermSymbol *) override; + bool visitAggregate(Visit, TIntermAggregate *) override; private: + void ensureVersionIsAtLeast(int version); + int mVersion; }; diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/blocklayout.cpp b/Source/ThirdParty/ANGLE/src/compiler/translator/blocklayout.cpp index 7cc631572461..ba6322848e7d 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/blocklayout.cpp +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/blocklayout.cpp @@ -27,7 +27,10 @@ BlockMemberInfo BlockLayoutEncoder::encodeType(GLenum type, unsigned int arraySi getBlockLayoutInfo(type, arraySize, isRowMajorMatrix, &arrayStride, &matrixStride); - const BlockMemberInfo memberInfo(static_cast(mCurrentOffset * BytesPerComponent), arrayStride * BytesPerComponent, matrixStride * BytesPerComponent, isRowMajorMatrix); + const BlockMemberInfo memberInfo(static_cast(mCurrentOffset * BytesPerComponent), + static_cast(arrayStride * BytesPerComponent), + static_cast(matrixStride * BytesPerComponent), + isRowMajorMatrix); advanceOffset(type, arraySize, isRowMajorMatrix, arrayStride, matrixStride); diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/blocklayout.h b/Source/ThirdParty/ANGLE/src/compiler/translator/blocklayout.h index c11357fe66f3..dd5fe07376c8 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/blocklayout.h +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/blocklayout.h @@ -26,6 +26,8 @@ struct InterfaceBlock; struct COMPILER_EXPORT BlockMemberInfo { + BlockMemberInfo() : offset(-1), arrayStride(-1), matrixStride(-1), isRowMajorMatrix(false) {} + BlockMemberInfo(int offset, int arrayStride, int matrixStride, bool isRowMajorMatrix) : offset(offset), arrayStride(arrayStride), @@ -48,12 +50,11 @@ class COMPILER_EXPORT BlockLayoutEncoder { public: BlockLayoutEncoder(); + virtual ~BlockLayoutEncoder() {} BlockMemberInfo encodeType(GLenum type, unsigned int arraySize, bool isRowMajorMatrix); size_t getBlockSize() const { return mCurrentOffset * BytesPerComponent; } - size_t getCurrentRegister() const { return mCurrentOffset / ComponentsPerRegister; } - size_t getCurrentElement() const { return mCurrentOffset % ComponentsPerRegister; } virtual void enterAggregateType() = 0; virtual void exitAggregateType() = 0; @@ -81,12 +82,20 @@ class COMPILER_EXPORT Std140BlockEncoder : public BlockLayoutEncoder public: Std140BlockEncoder(); - virtual void enterAggregateType(); - virtual void exitAggregateType(); + void enterAggregateType() override; + void exitAggregateType() override; protected: - virtual void getBlockLayoutInfo(GLenum type, unsigned int arraySize, bool isRowMajorMatrix, int *arrayStrideOut, int *matrixStrideOut); - virtual void advanceOffset(GLenum type, unsigned int arraySize, bool isRowMajorMatrix, int arrayStride, int matrixStride); + void getBlockLayoutInfo(GLenum type, + unsigned int arraySize, + bool isRowMajorMatrix, + int *arrayStrideOut, + int *matrixStrideOut) override; + void advanceOffset(GLenum type, + unsigned int arraySize, + bool isRowMajorMatrix, + int arrayStride, + int matrixStride) override; }; } diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/blocklayoutHLSL.cpp b/Source/ThirdParty/ANGLE/src/compiler/translator/blocklayoutHLSL.cpp index f32cf2cf8904..43119248eb91 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/blocklayoutHLSL.cpp +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/blocklayoutHLSL.cpp @@ -113,9 +113,14 @@ HLSLBlockEncoder::HLSLBlockEncoderStrategy HLSLBlockEncoder::GetStrategyFor(ShSh { switch (outputType) { - case SH_HLSL9_OUTPUT: return ENCODE_LOOSE; - case SH_HLSL11_OUTPUT: return ENCODE_PACKED; - default: UNREACHABLE(); return ENCODE_PACKED; + case SH_HLSL_3_0_OUTPUT: + return ENCODE_LOOSE; + case SH_HLSL_4_1_OUTPUT: + case SH_HLSL_4_0_FL9_3_OUTPUT: + return ENCODE_PACKED; + default: + UNREACHABLE(); + return ENCODE_PACKED; } } @@ -156,6 +161,7 @@ unsigned int HLSLVariableRegisterCount(const Varying &variable, bool transposeMa unsigned int HLSLVariableRegisterCount(const Uniform &variable, ShShaderOutput outputType) { HLSLBlockEncoder encoder(HLSLBlockEncoder::GetStrategyFor(outputType)); + encoder.setTransposeMatrices(true); HLSLVariableRegisterCount(variable, &encoder); const size_t registerBytes = (encoder.BytesPerComponent * encoder.ComponentsPerRegister); diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/depgraph/DependencyGraph.cpp b/Source/ThirdParty/ANGLE/src/compiler/translator/depgraph/DependencyGraph.cpp index 19ddf5c43925..4dee0dbd2e9b 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/depgraph/DependencyGraph.cpp +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/depgraph/DependencyGraph.cpp @@ -4,8 +4,6 @@ // found in the LICENSE file. // -#pragma warning(disable: 4718) - #include "compiler/translator/depgraph/DependencyGraph.h" #include "compiler/translator/depgraph/DependencyGraphBuilder.h" diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/depgraph/DependencyGraph.h b/Source/ThirdParty/ANGLE/src/compiler/translator/depgraph/DependencyGraph.h index 22db633678ff..2f7f7b9ab85a 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/depgraph/DependencyGraph.h +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/depgraph/DependencyGraph.h @@ -46,9 +46,10 @@ class TGraphNode { class TGraphParentNode : public TGraphNode { public: TGraphParentNode(TIntermNode* node) : TGraphNode(node) {} - virtual ~TGraphParentNode() {} + ~TGraphParentNode() override {} void addDependentNode(TGraphNode* node) { if (node != this) mDependentNodes.insert(node); } - virtual void traverse(TDependencyGraphTraverser* graphTraverser); + void traverse(TDependencyGraphTraverser *graphTraverser) override; + private: TGraphNodeSet mDependentNodes; }; @@ -61,10 +62,11 @@ class TGraphArgument : public TGraphParentNode { TGraphArgument(TIntermAggregate* intermFunctionCall, int argumentNumber) : TGraphParentNode(intermFunctionCall) , mArgumentNumber(argumentNumber) {} - virtual ~TGraphArgument() {} + ~TGraphArgument() override {} const TIntermAggregate* getIntermFunctionCall() const { return intermNode->getAsAggregate(); } int getArgumentNumber() const { return mArgumentNumber; } - virtual void traverse(TDependencyGraphTraverser* graphTraverser); + void traverse(TDependencyGraphTraverser *graphTraverser) override; + private: int mArgumentNumber; }; @@ -76,9 +78,9 @@ class TGraphFunctionCall : public TGraphParentNode { public: TGraphFunctionCall(TIntermAggregate* intermFunctionCall) : TGraphParentNode(intermFunctionCall) {} - virtual ~TGraphFunctionCall() {} + ~TGraphFunctionCall() override {} const TIntermAggregate* getIntermFunctionCall() const { return intermNode->getAsAggregate(); } - virtual void traverse(TDependencyGraphTraverser* graphTraverser); + void traverse(TDependencyGraphTraverser *graphTraverser) override; }; // @@ -87,9 +89,9 @@ class TGraphFunctionCall : public TGraphParentNode { class TGraphSymbol : public TGraphParentNode { public: TGraphSymbol(TIntermSymbol* intermSymbol) : TGraphParentNode(intermSymbol) {} - virtual ~TGraphSymbol() {} + ~TGraphSymbol() override {} const TIntermSymbol* getIntermSymbol() const { return intermNode->getAsSymbolNode(); } - virtual void traverse(TDependencyGraphTraverser* graphTraverser); + void traverse(TDependencyGraphTraverser *graphTraverser) override; }; // @@ -98,9 +100,9 @@ class TGraphSymbol : public TGraphParentNode { class TGraphSelection : public TGraphNode { public: TGraphSelection(TIntermSelection* intermSelection) : TGraphNode(intermSelection) {} - virtual ~TGraphSelection() {} + ~TGraphSelection() override {} const TIntermSelection* getIntermSelection() const { return intermNode->getAsSelectionNode(); } - virtual void traverse(TDependencyGraphTraverser* graphTraverser); + void traverse(TDependencyGraphTraverser *graphTraverser) override; }; // @@ -109,9 +111,9 @@ class TGraphSelection : public TGraphNode { class TGraphLoop : public TGraphNode { public: TGraphLoop(TIntermLoop* intermLoop) : TGraphNode(intermLoop) {} - virtual ~TGraphLoop() {} + ~TGraphLoop() override {} const TIntermLoop* getIntermLoop() const { return intermNode->getAsLoopNode(); } - virtual void traverse(TDependencyGraphTraverser* graphTraverser); + void traverse(TDependencyGraphTraverser *graphTraverser) override; }; // @@ -120,10 +122,10 @@ class TGraphLoop : public TGraphNode { class TGraphLogicalOp : public TGraphNode { public: TGraphLogicalOp(TIntermBinary* intermLogicalOp) : TGraphNode(intermLogicalOp) {} - virtual ~TGraphLogicalOp() {} + ~TGraphLogicalOp() override {} const TIntermBinary* getIntermLogicalOp() const { return intermNode->getAsBinaryNode(); } const char* getOpString() const; - virtual void traverse(TDependencyGraphTraverser* graphTraverser); + void traverse(TDependencyGraphTraverser *graphTraverser) override; }; // @@ -140,27 +142,11 @@ class TDependencyGraph { public: TDependencyGraph(TIntermNode* intermNode); ~TDependencyGraph(); - TGraphNodeVector::const_iterator begin() const { return mAllNodes.begin(); } - TGraphNodeVector::const_iterator end() const { return mAllNodes.end(); } - - TGraphSymbolVector::const_iterator beginSamplerSymbols() const - { - return mSamplerSymbols.begin(); - } - - TGraphSymbolVector::const_iterator endSamplerSymbols() const - { - return mSamplerSymbols.end(); - } - - TFunctionCallVector::const_iterator beginUserDefinedFunctionCalls() const - { - return mUserDefinedFunctionCalls.begin(); - } - - TFunctionCallVector::const_iterator endUserDefinedFunctionCalls() const + const TGraphNodeVector &allNodes() const { return mAllNodes; } + const TGraphSymbolVector &samplerSymbols() const { return mSamplerSymbols; } + const TFunctionCallVector &userDefinedFunctionCalls() const { - return mUserDefinedFunctionCalls.end(); + return mUserDefinedFunctionCalls; } TGraphArgument* createArgument(TIntermAggregate* intermFunctionCall, int argumentNumber); @@ -189,6 +175,7 @@ class TDependencyGraph { class TDependencyGraphTraverser : angle::NonCopyable { public: TDependencyGraphTraverser() : mDepth(0) {} + virtual ~TDependencyGraphTraverser() {} virtual void visitSymbol(TGraphSymbol* symbol) {}; virtual void visitArgument(TGraphArgument* selection) {}; diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/depgraph/DependencyGraphBuilder.h b/Source/ThirdParty/ANGLE/src/compiler/translator/depgraph/DependencyGraphBuilder.h index f7b3bd4b4370..c7b54f66b748 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/depgraph/DependencyGraphBuilder.h +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/depgraph/DependencyGraphBuilder.h @@ -18,11 +18,11 @@ class TDependencyGraphBuilder : public TIntermTraverser public: static void build(TIntermNode *node, TDependencyGraph *graph); - virtual void visitSymbol(TIntermSymbol *); - virtual bool visitBinary(Visit visit, TIntermBinary *); - virtual bool visitSelection(Visit visit, TIntermSelection *); - virtual bool visitAggregate(Visit visit, TIntermAggregate *); - virtual bool visitLoop(Visit visit, TIntermLoop *); + void visitSymbol(TIntermSymbol *) override; + bool visitBinary(Visit visit, TIntermBinary *) override; + bool visitSelection(Visit visit, TIntermSelection *) override; + bool visitAggregate(Visit visit, TIntermAggregate *) override; + bool visitLoop(Visit visit, TIntermLoop *) override; private: typedef std::stack TSymbolStack; diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/depgraph/DependencyGraphOutput.cpp b/Source/ThirdParty/ANGLE/src/compiler/translator/depgraph/DependencyGraphOutput.cpp index e226333545f7..32a2f30141d1 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/depgraph/DependencyGraphOutput.cpp +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/depgraph/DependencyGraphOutput.cpp @@ -54,9 +54,8 @@ void TDependencyGraphOutput::outputAllSpanningTrees(TDependencyGraph& graph) { mSink << "\n"; - for (TGraphNodeVector::const_iterator iter = graph.begin(); iter != graph.end(); ++iter) + for (auto symbol : graph.allNodes()) { - TGraphNode* symbol = *iter; mSink << "--- Dependency graph spanning tree ---\n"; clearVisited(); symbol->traverse(this); diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/generate_parser.sh b/Source/ThirdParty/ANGLE/src/compiler/translator/generate_parser.sh index e4d88b2e84cd..61eecce735f9 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/generate_parser.sh +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/generate_parser.sh @@ -7,22 +7,23 @@ run_flex() { -input_file=$script_dir/$1.l -output_source=$script_dir/$1_lex.cpp +input_file=./$1.l +output_source=./$1_lex.cpp flex --noline --nounistd --outfile=$output_source $input_file } run_bison() { -input_file=$script_dir/$1.y -output_header=$script_dir/$1_tab.h -output_source=$script_dir/$1_tab.cpp +input_file=./$1.y +output_header=./$1_tab.h +output_source=./$1_tab.cpp bison --no-lines --skeleton=yacc.c --defines=$output_header --output=$output_source $input_file } script_dir=$(dirname $0) # Generate Parser +cd $script_dir run_flex glslang run_bison glslang patch --silent --forward < 64bit-lexer-safety.patch diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/glslang.h b/Source/ThirdParty/ANGLE/src/compiler/translator/glslang.h index db31e6946c57..0555e96d4500 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/glslang.h +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/glslang.h @@ -7,7 +7,7 @@ #ifndef COMPILER_TRANSLATOR_GLSLANG_H_ #define COMPILER_TRANSLATOR_GLSLANG_H_ -struct TParseContext; +class TParseContext; extern int glslang_initialize(TParseContext* context); extern int glslang_finalize(TParseContext* context); diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/glslang.l b/Source/ThirdParty/ANGLE/src/compiler/translator/glslang.l index c8f21a79ff3c..a4a296121ddd 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/glslang.l +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/glslang.l @@ -72,7 +72,7 @@ static int ES2_reserved_ES3_keyword(TParseContext *context, int token); static int ES2_keyword_ES3_reserved(TParseContext *context, int token); static int ES2_ident_ES3_keyword(TParseContext *context, int token); static int uint_constant(TParseContext *context); -static int int_constant(yyscan_t yyscanner); +static int int_constant(TParseContext *context); static int float_constant(yyscan_t yyscanner); static int floatsuffix_check(TParseContext* context); %} @@ -246,7 +246,7 @@ O [0-7] "sampler2DMSArray" | "isampler2DMSArray" | "usampler2DMSArray" { - if (context->shaderVersion < 300) { + if (context->getShaderVersion() < 300) { yylval->lex.string = NewPoolTString(yytext); return check_type(yyscanner); } @@ -255,7 +255,7 @@ O [0-7] /* Reserved keywords in GLSL ES 1.00 that are not reserved in GLSL ES 3.00 */ "packed" { - if (context->shaderVersion >= 300) + if (context->getShaderVersion() >= 300) { yylval->lex.string = NewPoolTString(yytext); return check_type(yyscanner); @@ -321,9 +321,9 @@ O [0-7] return check_type(yyscanner); } -0[xX]{H}+ { return int_constant(yyscanner); } -0{O}+ { return int_constant(yyscanner); } -{D}+ { return int_constant(yyscanner); } +0[xX]{H}+ { return int_constant(context); } +0{O}+ { return int_constant(context); } +{D}+ { return int_constant(context); } 0[xX]{H}+[uU] { return uint_constant(context); } 0{O}+[uU] { return uint_constant(context); } @@ -390,16 +390,21 @@ O [0-7] return FIELD_SELECTION; } [ \t\v\f\r] {} +. { + yyextra->error(*yylloc, "Illegal character at fieldname start", yytext, ""); + yyextra->recover(); + return 0; +} [ \t\v\n\f\r] { } <*><> { yyterminate(); } -<*>. { return 0; } +<*>. { assert(false); return 0; } %% yy_size_t string_input(char* buf, yy_size_t max_size, yyscan_t yyscanner) { pp::Token token; - yyget_extra(yyscanner)->preprocessor.lex(&token); + yyget_extra(yyscanner)->getPreprocessor().lex(&token); yy_size_t len = token.type == pp::Token::LAST ? 0 : token.text.size(); if (len < max_size) memcpy(buf, token.text.c_str(), len); @@ -417,7 +422,7 @@ int check_type(yyscan_t yyscanner) { struct yyguts_t* yyg = (struct yyguts_t*) yyscanner; int token = IDENTIFIER; - TSymbol* symbol = yyextra->symbolTable.find(yytext, yyextra->shaderVersion); + TSymbol* symbol = yyextra->symbolTable.find(yytext, yyextra->getShaderVersion()); if (symbol && symbol->isVariable()) { TVariable* variable = static_cast(symbol); if (variable->isUserType()) { @@ -438,9 +443,9 @@ int reserved_word(yyscan_t yyscanner) { int ES2_reserved_ES3_keyword(TParseContext *context, int token) { - yyscan_t yyscanner = (yyscan_t) context->scanner; + yyscan_t yyscanner = (yyscan_t) context->getScanner(); - if (context->shaderVersion < 300) + if (context->getShaderVersion() < 300) { return reserved_word(yyscanner); } @@ -450,9 +455,9 @@ int ES2_reserved_ES3_keyword(TParseContext *context, int token) int ES2_keyword_ES3_reserved(TParseContext *context, int token) { - yyscan_t yyscanner = (yyscan_t) context->scanner; + yyscan_t yyscanner = (yyscan_t) context->getScanner(); - if (context->shaderVersion >= 300) + if (context->getShaderVersion() >= 300) { return reserved_word(yyscanner); } @@ -462,11 +467,11 @@ int ES2_keyword_ES3_reserved(TParseContext *context, int token) int ES2_ident_ES3_keyword(TParseContext *context, int token) { - struct yyguts_t* yyg = (struct yyguts_t*) context->scanner; - yyscan_t yyscanner = (yyscan_t) context->scanner; + struct yyguts_t* yyg = (struct yyguts_t*) context->getScanner(); + yyscan_t yyscanner = (yyscan_t) context->getScanner(); // not a reserved word in GLSL ES 1.00, so could be used as an identifier/type name - if (context->shaderVersion < 300) + if (context->getShaderVersion() < 300) { yylval->lex.string = NewPoolTString(yytext); return check_type(yyscanner); @@ -477,34 +482,35 @@ int ES2_ident_ES3_keyword(TParseContext *context, int token) int uint_constant(TParseContext *context) { - struct yyguts_t* yyg = (struct yyguts_t*) context->scanner; - yyscan_t yyscanner = (yyscan_t) context->scanner; + struct yyguts_t* yyg = (struct yyguts_t*) context->getScanner(); - if (context->shaderVersion < 300) + if (context->getShaderVersion() < 300) { context->error(*yylloc, "Unsigned integers are unsupported prior to GLSL ES 3.00", yytext, ""); context->recover(); return 0; } - if (!atoi_clamp(yytext, &(yylval->lex.i))) - yyextra->warning(*yylloc, "Integer overflow", yytext, ""); + if (!atoi_clamp(yytext, &(yylval->lex.u))) + yyextra->error(*yylloc, "Integer overflow", yytext, ""); return UINTCONSTANT; } int floatsuffix_check(TParseContext* context) { - struct yyguts_t* yyg = (struct yyguts_t*) context->scanner; + struct yyguts_t* yyg = (struct yyguts_t*) context->getScanner(); - if (context->shaderVersion < 300) + if (context->getShaderVersion() < 300) { context->error(*yylloc, "Floating-point suffix unsupported prior to GLSL ES 3.00", yytext); context->recover(); return 0; } - if (!atof_clamp(yytext, &(yylval->lex.f))) + std::string text = yytext; + text.resize(text.size() - 1); + if (!strtof_clamp(text, &(yylval->lex.f))) yyextra->warning(*yylloc, "Float overflow", yytext, ""); return(FLOATCONSTANT); @@ -515,18 +521,25 @@ void yyerror(YYLTYPE* lloc, TParseContext* context, void *scanner, const char* r context->recover(); } -int int_constant(yyscan_t yyscanner) { - struct yyguts_t* yyg = (struct yyguts_t*) yyscanner; +int int_constant(TParseContext *context) { + struct yyguts_t* yyg = (struct yyguts_t*) context->getScanner(); - if (!atoi_clamp(yytext, &(yylval->lex.i))) - yyextra->warning(*yylloc, "Integer overflow", yytext, ""); + unsigned int u; + if (!atoi_clamp(yytext, &u)) + { + if (context->getShaderVersion() >= 300) + yyextra->error(*yylloc, "Integer overflow", yytext, ""); + else + yyextra->warning(*yylloc, "Integer overflow", yytext, ""); + } + yylval->lex.i = static_cast(u); return INTCONSTANT; } int float_constant(yyscan_t yyscanner) { struct yyguts_t* yyg = (struct yyguts_t*) yyscanner; - if (!atof_clamp(yytext, &(yylval->lex.f))) + if (!strtof_clamp(yytext, &(yylval->lex.f))) yyextra->warning(*yylloc, "Float overflow", yytext, ""); return FLOATCONSTANT; } @@ -536,15 +549,15 @@ int glslang_initialize(TParseContext* context) { if (yylex_init_extra(context, &scanner)) return 1; - context->scanner = scanner; + context->setScanner(scanner); return 0; } int glslang_finalize(TParseContext* context) { - yyscan_t scanner = context->scanner; + yyscan_t scanner = context->getScanner(); if (scanner == NULL) return 0; - context->scanner = NULL; + context->setScanner(NULL); yylex_destroy(scanner); return 0; @@ -552,24 +565,26 @@ int glslang_finalize(TParseContext* context) { int glslang_scan(size_t count, const char* const string[], const int length[], TParseContext* context) { - yyrestart(NULL, context->scanner); - yyset_column(0, context->scanner); - yyset_lineno(1, context->scanner); + yyrestart(NULL, context->getScanner()); + yyset_column(0, context->getScanner()); + yyset_lineno(1, context->getScanner()); // Initialize preprocessor. - if (!context->preprocessor.init(count, string, length)) + pp::Preprocessor *preprocessor = &context->getPreprocessor(); + + if (!preprocessor->init(count, string, length)) return 1; // Define extension macros. const TExtensionBehavior& extBehavior = context->extensionBehavior(); for (TExtensionBehavior::const_iterator iter = extBehavior.begin(); iter != extBehavior.end(); ++iter) { - context->preprocessor.predefineMacro(iter->first.c_str(), 1); + preprocessor->predefineMacro(iter->first.c_str(), 1); } - if (context->fragmentPrecisionHigh) - context->preprocessor.predefineMacro("GL_FRAGMENT_PRECISION_HIGH", 1); + if (context->getFragmentPrecisionHigh()) + preprocessor->predefineMacro("GL_FRAGMENT_PRECISION_HIGH", 1); - context->preprocessor.setMaxTokenSize(GetGlobalMaxTokenSize(context->shaderSpec)); + preprocessor->setMaxTokenSize(GetGlobalMaxTokenSize(context->getShaderSpec())); return 0; } diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/glslang.y b/Source/ThirdParty/ANGLE/src/compiler/translator/glslang.y index a9cc4bc7fc19..aba270631150 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/glslang.y +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/glslang.y @@ -37,6 +37,7 @@ WHICH GENERATES THE GLSL ES PARSER (glslang_tab.cpp AND glslang_tab.h). #endif #include "angle_gl.h" +#include "compiler/translator/Cache.h" #include "compiler/translator/SymbolTable.h" #include "compiler/translator/ParseContext.h" #include "GLSLANG/ShaderLang.h" @@ -110,28 +111,28 @@ extern void yyerror(YYLTYPE* yylloc, TParseContext* context, void *scanner, cons } while (0) #define VERTEX_ONLY(S, L) { \ - if (context->shaderType != GL_VERTEX_SHADER) { \ + if (context->getShaderType() != GL_VERTEX_SHADER) { \ context->error(L, " supported in vertex shaders only ", S); \ context->recover(); \ } \ } #define FRAG_ONLY(S, L) { \ - if (context->shaderType != GL_FRAGMENT_SHADER) { \ + if (context->getShaderType() != GL_FRAGMENT_SHADER) { \ context->error(L, " supported in fragment shaders only ", S); \ context->recover(); \ } \ } #define ES2_ONLY(S, L) { \ - if (context->shaderVersion != 100) { \ + if (context->getShaderVersion() != 100) { \ context->error(L, " supported in GLSL ES 1.00 only ", S); \ context->recover(); \ } \ } #define ES3_ONLY(TOKEN, LINE, REASON) { \ - if (context->shaderVersion != 300) { \ + if (context->getShaderVersion() != 300) { \ context->error(LINE, REASON " supported in GLSL ES 3.00 only ", TOKEN); \ context->recover(); \ } \ @@ -177,10 +178,10 @@ extern void yyerror(YYLTYPE* yylloc, TParseContext* context, void *scanner, cons %type translation_unit function_definition %type statement simple_statement -%type statement_list compound_statement +%type statement_list compound_statement compound_statement_no_new_scope %type declaration_statement selection_statement expression_statement %type declaration external_declaration -%type for_init_statement compound_statement_no_new_scope +%type for_init_statement %type selection_rest_statement for_rest_statement %type switch_statement %type case_label @@ -214,21 +215,7 @@ identifier variable_identifier : IDENTIFIER { // The symbol table search was done in the lexical phase - const TVariable *variable = context->getNamedVariable(@1, $1.string, $1.symbol); - - if (variable->getType().getQualifier() == EvqConst) - { - TConstantUnion* constArray = variable->getConstPointer(); - TType t(variable->getType()); - $$ = context->intermediate.addConstantUnion(constArray, t, @1); - } - else - { - $$ = context->intermediate.addSymbol(variable->getUniqueId(), - variable->getName(), - variable->getType(), - @1); - } + $$ = context->parseVariableIdentifier(@1, $1.string, $1.symbol); // don't delete $1.string, it's used by error recovery, and the pool // pop will reclaim the memory @@ -338,14 +325,14 @@ function_call_header_no_parameters function_call_header_with_parameters : function_call_header assignment_expression { - TParameter param = { 0, new TType($2->getType()) }; - $1->addParameter(param); + const TType *type = new TType($2->getType()); + $1->addParameter(TConstParameter(type)); $$.function = $1; - $$.nodePair.node1 = $2; + $$.nodePair.node1 = context->intermediate.makeAggregate($2, @2); } | function_call_header_with_parameters COMMA assignment_expression { - TParameter param = { 0, new TType($3->getType()) }; - $1.function->addParameter(param); + const TType *type = new TType($3->getType()); + $1.function->addParameter(TConstParameter(type)); $$.function = $1.function; $$.nodePair.node1 = context->intermediate.growAggregate($1.intermNode, $3, @2); } @@ -369,14 +356,14 @@ function_identifier | IDENTIFIER { if (context->reservedErrorCheck(@1, *$1.string)) context->recover(); - TType type(EbtVoid, EbpUndefined); + const TType *type = TCache::getType(EbtVoid, EbpUndefined); TFunction *function = new TFunction($1.string, type); $$ = function; } | FIELD_SELECTION { if (context->reservedErrorCheck(@1, *$1.string)) context->recover(); - TType type(EbtVoid, EbpUndefined); + const TType *type = TCache::getType(EbtVoid, EbpUndefined); TFunction *function = new TFunction($1.string, type); $$ = function; } @@ -572,12 +559,7 @@ expression $$ = $1; } | expression COMMA assignment_expression { - $$ = context->intermediate.addComma($1, $3, @2); - if ($$ == 0) { - context->binaryOpError(@2, ",", $1->getCompleteString(), $3->getCompleteString()); - context->recover(); - $$ = $3; - } + $$ = context->addComma($1, $3, @2); } ; @@ -598,33 +580,8 @@ enter_struct ; declaration - : function_prototype SEMICOLON { - TFunction &function = *($1.function); - - TIntermAggregate *prototype = new TIntermAggregate; - prototype->setType(function.getReturnType()); - prototype->setName(function.getMangledName()); - prototype->setFunctionId(function.getUniqueId()); - - for (size_t i = 0; i < function.getParamCount(); i++) - { - const TParameter ¶m = function.getParam(i); - if (param.name != 0) - { - TVariable variable(param.name, *param.type); - - prototype = context->intermediate.growAggregate(prototype, context->intermediate.addSymbol(variable.getUniqueId(), variable.getName(), variable.getType(), @1), @1); - } - else - { - prototype = context->intermediate.growAggregate(prototype, context->intermediate.addSymbol(0, "", *param.type, @1), @1); - } - } - - prototype->setOp(EOpPrototype); - $$ = prototype; - - context->symbolTable.pop(); + : function_prototype SEMICOLON { + $$ = context->addFunctionPrototypeDeclaration(*($1.function), @1); } | init_declarator_list SEMICOLON { TIntermAggregate *aggNode = $1.intermAggregate; @@ -633,7 +590,7 @@ declaration $$ = aggNode; } | PRECISION precision_qualifier type_specifier_no_prec SEMICOLON { - if (($2 == EbpHigh) && (context->shaderType == GL_FRAGMENT_SHADER) && !context->fragmentPrecisionHigh) { + if (($2 == EbpHigh) && (context->getShaderType() == GL_FRAGMENT_SHADER) && !context->getFragmentPrecisionHigh()) { context->error(@1, "precision is not supported in fragment shader", "highp"); context->recover(); } @@ -663,57 +620,7 @@ declaration function_prototype : function_declarator RIGHT_PAREN { - // - // Multiple declarations of the same function are allowed. - // - // If this is a definition, the definition production code will check for redefinitions - // (we don't know at this point if it's a definition or not). - // - // Redeclarations are allowed. But, return types and parameter qualifiers must match. - // - TFunction* prevDec = static_cast(context->symbolTable.find($1->getMangledName(), context->shaderVersion)); - if (prevDec) { - if (prevDec->getReturnType() != $1->getReturnType()) { - context->error(@2, "overloaded functions must have the same return type", $1->getReturnType().getBasicString()); - context->recover(); - } - for (size_t i = 0; i < prevDec->getParamCount(); ++i) { - if (prevDec->getParam(i).type->getQualifier() != $1->getParam(i).type->getQualifier()) { - context->error(@2, "overloaded functions must have the same parameter qualifiers", $1->getParam(i).type->getQualifierString()); - context->recover(); - } - } - } - - // - // Check for previously declared variables using the same name. - // - TSymbol *prevSym = context->symbolTable.find($1->getName(), context->shaderVersion); - if (prevSym) - { - if (!prevSym->isFunction()) - { - context->error(@2, "redefinition", $1->getName().c_str(), "function"); - context->recover(); - } - } - else - { - // Insert the unmangled name to detect potential future redefinition as a variable. - TFunction *function = new TFunction(NewPoolTString($1->getName().c_str()), $1->getReturnType()); - context->symbolTable.getOuterLevel()->insertUnmangled(function); - } - - // - // If this is a redeclaration, it could also be a definition, - // in which case, we want to use the variable names from this one, and not the one that's - // being redeclared. So, pass back up this declaration, not the one in the symbol table. - // - $$.function = $1; - - // We're at the inner scope level of the function's arguments and body statement. - // Add the function prototype to the surrounding scope instead. - context->symbolTable.getOuterLevel()->insert($$.function); + $$.function = context->parseFunctionDeclarator(@2, $1); } ; @@ -732,7 +639,7 @@ function_header_with_parameters // Add the parameter $$ = $1; if ($2.param.type->getBasicType() != EbtVoid) - $1->addParameter($2.param); + $1->addParameter($2.param.turnToConst()); else delete $2.param.type; } @@ -751,24 +658,30 @@ function_header_with_parameters } else { // Add the parameter $$ = $1; - $1->addParameter($3.param); + $1->addParameter($3.param.turnToConst()); } } ; function_header : fully_specified_type IDENTIFIER LEFT_PAREN { - if ($1.qualifier != EvqGlobal && $1.qualifier != EvqTemporary) { + if ($1.qualifier != EvqGlobal && $1.qualifier != EvqTemporary) + { context->error(@2, "no qualifiers allowed for function return", getQualifierString($1.qualifier)); context->recover(); } + if (!$1.layoutQualifier.isEmpty()) + { + context->error(@2, "no qualifiers allowed for function return", "layout"); + context->recover(); + } // make sure a sampler is not involved as well... if (context->samplerErrorCheck(@2, $1, "samplers can't be function return values")) context->recover(); // Add the function as a prototype after parsing it (we do not support recursion) TFunction *function; - TType type($1); + const TType *type = new TType($1); function = new TFunction($2.string, type); $$ = function; @@ -934,13 +847,13 @@ fully_specified_type if ($1.array) { ES3_ONLY("[]", @1, "first-class-array"); - if (context->shaderVersion != 300) { + if (context->getShaderVersion() != 300) { $1.clearArrayness(); } } } | type_qualifier type_specifier { - $$ = context->addFullySpecifiedType($1.qualifier, $1.layoutQualifier, $2); + $$ = context->addFullySpecifiedType($1.qualifier, $1.invariant, $1.layoutQualifier, $2); } ; @@ -971,7 +884,7 @@ type_qualifier ES2_ONLY("varying", @1); if (context->globalErrorCheck(@1, context->symbolTable.atGlobalLevel(), "varying")) context->recover(); - if (context->shaderType == GL_VERTEX_SHADER) + if (context->getShaderType() == GL_VERTEX_SHADER) $$.setBasic(EbtVoid, EvqVaryingOut, @1); else $$.setBasic(EbtVoid, EvqVaryingIn, @1); @@ -980,18 +893,19 @@ type_qualifier ES2_ONLY("varying", @1); if (context->globalErrorCheck(@1, context->symbolTable.atGlobalLevel(), "invariant varying")) context->recover(); - if (context->shaderType == GL_VERTEX_SHADER) - $$.setBasic(EbtVoid, EvqInvariantVaryingOut, @1); + if (context->getShaderType() == GL_VERTEX_SHADER) + $$.setBasic(EbtVoid, EvqVaryingOut, @1); else - $$.setBasic(EbtVoid, EvqInvariantVaryingIn, @1); + $$.setBasic(EbtVoid, EvqVaryingIn, @1); + $$.invariant = true; } | storage_qualifier { - if ($1.qualifier != EvqConst && !context->symbolTable.atGlobalLevel()) { + if ($1.qualifier != EvqConst && !context->symbolTable.atGlobalLevel()) + { context->error(@1, "Local variables can only use the const storage qualifier.", getQualifierString($1.qualifier)); context->recover(); - } else { - $$.setBasic(EbtVoid, $1.qualifier, @1); } + $$.setBasic(EbtVoid, $1.qualifier, @1); } | interpolation_qualifier storage_qualifier { $$ = context->joinInterpolationQualifiers(@1, $1.qualifier, @2, $2.qualifier); @@ -1011,6 +925,16 @@ type_qualifier $$.setBasic(EbtVoid, $2.qualifier, @2); $$.layoutQualifier = $1; } + | INVARIANT storage_qualifier { + context->es3InvariantErrorCheck($2.qualifier, @1); + $$.setBasic(EbtVoid, $2.qualifier, @2); + $$.invariant = true; + } + | INVARIANT interpolation_qualifier storage_qualifier { + context->es3InvariantErrorCheck($3.qualifier, @1); + $$ = context->joinInterpolationQualifiers(@2, $2.qualifier, @3, $3.qualifier); + $$.invariant = true; + } ; storage_qualifier @@ -1019,29 +943,29 @@ storage_qualifier } | IN_QUAL { ES3_ONLY("in", @1, "storage qualifier"); - $$.qualifier = (context->shaderType == GL_FRAGMENT_SHADER) ? EvqFragmentIn : EvqVertexIn; + $$.qualifier = (context->getShaderType() == GL_FRAGMENT_SHADER) ? EvqFragmentIn : EvqVertexIn; } | OUT_QUAL { ES3_ONLY("out", @1, "storage qualifier"); - $$.qualifier = (context->shaderType == GL_FRAGMENT_SHADER) ? EvqFragmentOut : EvqVertexOut; + $$.qualifier = (context->getShaderType() == GL_FRAGMENT_SHADER) ? EvqFragmentOut : EvqVertexOut; } | CENTROID IN_QUAL { ES3_ONLY("centroid in", @1, "storage qualifier"); - if (context->shaderType == GL_VERTEX_SHADER) + if (context->getShaderType() == GL_VERTEX_SHADER) { context->error(@1, "invalid storage qualifier", "it is an error to use 'centroid in' in the vertex shader"); context->recover(); } - $$.qualifier = (context->shaderType == GL_FRAGMENT_SHADER) ? EvqCentroidIn : EvqVertexIn; + $$.qualifier = (context->getShaderType() == GL_FRAGMENT_SHADER) ? EvqCentroidIn : EvqVertexIn; } | CENTROID OUT_QUAL { ES3_ONLY("centroid out", @1, "storage qualifier"); - if (context->shaderType == GL_FRAGMENT_SHADER) + if (context->getShaderType() == GL_FRAGMENT_SHADER) { context->error(@1, "invalid storage qualifier", "it is an error to use 'centroid out' in the fragment shader"); context->recover(); } - $$.qualifier = (context->shaderType == GL_FRAGMENT_SHADER) ? EvqFragmentOut : EvqCentroidOut; + $$.qualifier = (context->getShaderType() == GL_FRAGMENT_SHADER) ? EvqFragmentOut : EvqCentroidOut; } | UNIFORM { if (context->globalErrorCheck(@1, context->symbolTable.atGlobalLevel(), "uniform")) @@ -1519,9 +1443,9 @@ selection_rest_statement ; switch_statement - : SWITCH LEFT_PAREN expression RIGHT_PAREN { ++context->mSwitchNestingLevel; } compound_statement { + : SWITCH LEFT_PAREN expression RIGHT_PAREN { context->incrSwitchNestingLevel(); } compound_statement { $$ = context->addSwitch($3, $6, @1); - --context->mSwitchNestingLevel; + context->decrSwitchNestingLevel(); } ; @@ -1556,22 +1480,22 @@ condition ; iteration_statement - : WHILE LEFT_PAREN { context->symbolTable.push(); ++context->mLoopNestingLevel; } condition RIGHT_PAREN statement_no_new_scope { + : WHILE LEFT_PAREN { context->symbolTable.push(); context->incrLoopNestingLevel(); } condition RIGHT_PAREN statement_no_new_scope { context->symbolTable.pop(); $$ = context->intermediate.addLoop(ELoopWhile, 0, $4, 0, $6, @1); - --context->mLoopNestingLevel; + context->decrLoopNestingLevel(); } - | DO { ++context->mLoopNestingLevel; } statement_with_scope WHILE LEFT_PAREN expression RIGHT_PAREN SEMICOLON { + | DO { context->incrLoopNestingLevel(); } statement_with_scope WHILE LEFT_PAREN expression RIGHT_PAREN SEMICOLON { if (context->boolErrorCheck(@8, $6)) context->recover(); $$ = context->intermediate.addLoop(ELoopDoWhile, 0, $6, 0, $3, @4); - --context->mLoopNestingLevel; + context->decrLoopNestingLevel(); } - | FOR LEFT_PAREN { context->symbolTable.push(); ++context->mLoopNestingLevel; } for_init_statement for_rest_statement RIGHT_PAREN statement_no_new_scope { + | FOR LEFT_PAREN { context->symbolTable.push(); context->incrLoopNestingLevel(); } for_init_statement for_rest_statement RIGHT_PAREN statement_no_new_scope { context->symbolTable.pop(); $$ = context->intermediate.addLoop(ELoopFor, $4, reinterpret_cast($5.node1), reinterpret_cast($5.node2), $7, @1); - --context->mLoopNestingLevel; + context->decrLoopNestingLevel(); } ; @@ -1628,11 +1552,11 @@ jump_statement translation_unit : external_declaration { $$ = $1; - context->treeRoot = $$; + context->setTreeRoot($$); } | translation_unit external_declaration { $$ = context->intermediate.growAggregate($1, $2, @$); - context->treeRoot = $$; + context->setTreeRoot($$); } ; @@ -1647,121 +1571,15 @@ external_declaration function_definition : function_prototype { - TFunction* function = $1.function; - - const TSymbol *builtIn = context->symbolTable.findBuiltIn(function->getMangledName(), context->shaderVersion); - - if (builtIn) - { - context->error(@1, "built-in functions cannot be redefined", function->getName().c_str()); - context->recover(); - } - - TFunction* prevDec = static_cast(context->symbolTable.find(function->getMangledName(), context->shaderVersion)); - // - // Note: 'prevDec' could be 'function' if this is the first time we've seen function - // as it would have just been put in the symbol table. Otherwise, we're looking up - // an earlier occurance. - // - if (prevDec->isDefined()) { - // - // Then this function already has a body. - // - context->error(@1, "function already has a body", function->getName().c_str()); - context->recover(); - } - prevDec->setDefined(); - // - // Overload the unique ID of the definition to be the same unique ID as the declaration. - // Eventually we will probably want to have only a single definition and just swap the - // arguments to be the definition's arguments. - // - function->setUniqueId(prevDec->getUniqueId()); - - // - // Raise error message if main function takes any parameters or return anything other than void - // - if (function->getName() == "main") { - if (function->getParamCount() > 0) { - context->error(@1, "function cannot take any parameter(s)", function->getName().c_str()); - context->recover(); - } - if (function->getReturnType().getBasicType() != EbtVoid) { - context->error(@1, "", function->getReturnType().getBasicString(), "main function cannot return a value"); - context->recover(); - } - } - - // - // Remember the return type for later checking for RETURN statements. - // - context->currentFunctionType = &(prevDec->getReturnType()); - context->mFunctionReturnsValue = false; - - // - // Insert parameters into the symbol table. - // If the parameter has no name, it's not an error, just don't insert it - // (could be used for unused args). - // - // Also, accumulate the list of parameters into the HIL, so lower level code - // knows where to find parameters. - // - TIntermAggregate* paramNodes = new TIntermAggregate; - for (size_t i = 0; i < function->getParamCount(); i++) { - const TParameter& param = function->getParam(i); - if (param.name != 0) { - TVariable *variable = new TVariable(param.name, *param.type); - // - // Insert the parameters with name in the symbol table. - // - if (! context->symbolTable.declare(variable)) { - context->error(@1, "redefinition", variable->getName().c_str()); - context->recover(); - delete variable; - } - - // - // Add the parameter to the HIL - // - paramNodes = context->intermediate.growAggregate( - paramNodes, - context->intermediate.addSymbol(variable->getUniqueId(), - variable->getName(), - variable->getType(), @1), - @1); - } else { - paramNodes = context->intermediate.growAggregate(paramNodes, context->intermediate.addSymbol(0, "", *param.type, @1), @1); - } - } - context->intermediate.setAggregateOperator(paramNodes, EOpParameters, @1); - $1.intermAggregate = paramNodes; - context->mLoopNestingLevel = 0; + context->parseFunctionPrototype(@1, $1.function, &$1.intermAggregate); } compound_statement_no_new_scope { - //?? Check that all paths return a value if return type != void ? - // May be best done as post process phase on intermediate code - if (context->currentFunctionType->getBasicType() != EbtVoid && ! context->mFunctionReturnsValue) { - context->error(@1, "function does not return a value:", "", $1.function->getName().c_str()); - context->recover(); - } - - $$ = context->intermediate.growAggregate($1.intermAggregate, $3, @$); - context->intermediate.setAggregateOperator($$, EOpFunction, @1); - $$->getAsAggregate()->setName($1.function->getMangledName().c_str()); - $$->getAsAggregate()->setType($1.function->getReturnType()); - $$->getAsAggregate()->setFunctionId($1.function->getUniqueId()); - - // store the pragma information for debug and optimize and other vendor specific - // information. This information can be queried from the parse tree - $$->getAsAggregate()->setOptimize(context->pragma().optimize); - $$->getAsAggregate()->setDebug(context->pragma().debug); - - context->symbolTable.pop(); + $$ = context->addFunctionDefinition(*($1.function), $1.intermAggregate, $3, @1); } ; %% int glslang_parse(TParseContext* context) { - return yyparse(context, context->scanner); + return yyparse(context, context->getScanner()); } diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/glslang_lex.cpp b/Source/ThirdParty/ANGLE/src/compiler/translator/glslang_lex.cpp index 6f362ab03679..1af876b95e29 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/glslang_lex.cpp +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/glslang_lex.cpp @@ -400,8 +400,8 @@ static void yy_fatal_error (yyconst char msg[] ,yyscan_t yyscanner ); *yy_cp = '\0'; \ yyg->yy_c_buf_p = yy_cp; -#define YY_NUM_RULES 239 -#define YY_END_OF_BUFFER 240 +#define YY_NUM_RULES 240 +#define YY_END_OF_BUFFER 241 /* This struct is not used in this scanner, but its presence is necessary. */ struct yy_trans_info @@ -409,98 +409,98 @@ struct yy_trans_info flex_int32_t yy_verify; flex_int32_t yy_nxt; }; -static yyconst flex_int16_t yy_accept[819] = +static yyconst flex_int16_t yy_accept[820] = { 0, - 0, 0, 0, 0, 240, 238, 237, 237, 222, 228, + 0, 0, 0, 0, 241, 239, 238, 238, 222, 228, 233, 217, 218, 226, 225, 214, 223, 221, 227, 180, 180, 215, 211, 229, 216, 230, 234, 177, 219, 220, 232, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, - 177, 212, 231, 213, 224, 236, 239, 235, 208, 194, - 213, 202, 197, 192, 200, 190, 201, 191, 186, 193, - 185, 179, 180, 0, 183, 0, 220, 212, 219, 209, - 205, 207, 206, 210, 177, 198, 204, 177, 177, 177, - 177, 177, 177, 177, 177, 177, 177, 177, 177, 12, - + 177, 212, 231, 213, 224, 237, 236, 240, 235, 208, + 194, 213, 202, 197, 192, 200, 190, 201, 191, 186, + 193, 185, 179, 180, 0, 183, 0, 220, 212, 219, + 209, 205, 207, 206, 210, 177, 198, 204, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, - 177, 177, 177, 15, 177, 177, 23, 177, 177, 177, + + 12, 177, 177, 177, 177, 177, 177, 177, 177, 177, + 177, 177, 177, 177, 15, 177, 177, 23, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, - 199, 203, 235, 0, 189, 185, 0, 188, 182, 0, - 184, 178, 195, 196, 177, 136, 177, 177, 177, 177, + 177, 199, 203, 235, 0, 189, 185, 0, 188, 182, + 0, 184, 178, 195, 196, 177, 136, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, - 177, 177, 177, 177, 177, 177, 177, 177, 177, 13, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, + 13, 177, 177, 177, 177, 177, 177, 177, 177, 177, - 27, 177, 177, 177, 177, 177, 177, 177, 177, 177, - 177, 177, 24, 177, 177, 177, 177, 177, 177, 177, + 177, 27, 177, 177, 177, 177, 177, 177, 177, 177, + 177, 177, 177, 24, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, - 177, 177, 177, 177, 177, 177, 177, 0, 186, 0, - 185, 187, 181, 177, 177, 177, 30, 177, 177, 18, - 174, 177, 177, 177, 177, 177, 177, 177, 177, 177, - 177, 16, 139, 177, 177, 177, 177, 21, 177, 177, - 143, 155, 177, 177, 177, 177, 177, 177, 177, 177, - 177, 177, 177, 177, 152, 4, 35, 36, 37, 177, + 177, 177, 177, 177, 177, 177, 177, 177, 0, 186, + 0, 185, 187, 181, 177, 177, 177, 30, 177, 177, + 18, 174, 177, 177, 177, 177, 177, 177, 177, 177, + 177, 177, 16, 139, 177, 177, 177, 177, 21, 177, + 177, 143, 155, 177, 177, 177, 177, 177, 177, 177, + 177, 177, 177, 177, 177, 152, 4, 35, 36, 37, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, - 177, 177, 177, 142, 31, 177, 177, 28, 177, 177, - 177, 177, 177, 177, 177, 47, 48, 49, 29, 177, - 177, 177, 177, 177, 177, 10, 53, 54, 55, 177, - 137, 177, 177, 7, 177, 177, 177, 177, 164, 165, - 166, 177, 32, 177, 156, 26, 167, 168, 169, 2, - 161, 162, 163, 177, 177, 177, 25, 159, 177, 177, - 177, 50, 51, 52, 177, 177, 177, 177, 177, 177, - 177, 177, 177, 177, 177, 86, 177, 177, 177, 177, - - 177, 177, 177, 153, 177, 177, 177, 177, 177, 177, - 177, 177, 177, 177, 177, 138, 177, 177, 176, 56, - 57, 58, 177, 177, 14, 177, 91, 177, 177, 177, - 177, 89, 177, 177, 177, 154, 149, 92, 177, 177, - 177, 177, 177, 177, 144, 177, 177, 177, 78, 38, - 41, 43, 42, 39, 45, 44, 46, 40, 177, 177, - 177, 177, 160, 135, 177, 177, 147, 177, 177, 177, - 34, 87, 173, 22, 148, 77, 177, 158, 17, 177, - 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, - 177, 177, 177, 19, 33, 177, 177, 177, 177, 177, - - 177, 93, 94, 95, 177, 177, 177, 177, 177, 3, + 177, 177, 177, 177, 142, 31, 177, 177, 28, 177, + 177, 177, 177, 177, 177, 177, 47, 48, 49, 29, + 177, 177, 177, 177, 177, 177, 10, 53, 54, 55, + 177, 137, 177, 177, 7, 177, 177, 177, 177, 164, + 165, 166, 177, 32, 177, 156, 26, 167, 168, 169, + 2, 161, 162, 163, 177, 177, 177, 25, 159, 177, + 177, 177, 50, 51, 52, 177, 177, 177, 177, 177, + 177, 177, 177, 177, 177, 177, 86, 177, 177, 177, + + 177, 177, 177, 177, 153, 177, 177, 177, 177, 177, + 177, 177, 177, 177, 177, 177, 138, 177, 177, 176, + 56, 57, 58, 177, 177, 14, 177, 91, 177, 177, + 177, 177, 89, 177, 177, 177, 154, 149, 92, 177, + 177, 177, 177, 177, 177, 144, 177, 177, 177, 78, + 38, 41, 43, 42, 39, 45, 44, 46, 40, 177, + 177, 177, 177, 160, 135, 177, 177, 147, 177, 177, + 177, 34, 87, 173, 22, 148, 77, 177, 158, 17, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, - 177, 140, 177, 177, 177, 177, 177, 8, 177, 177, - 9, 177, 177, 177, 177, 20, 79, 11, 150, 97, - 98, 99, 177, 177, 177, 177, 177, 177, 177, 177, - 177, 177, 177, 177, 145, 177, 177, 177, 81, 83, - 80, 177, 177, 177, 177, 177, 177, 177, 141, 101, - 102, 103, 177, 177, 157, 177, 146, 177, 177, 6, - 177, 177, 177, 177, 177, 177, 177, 177, 177, 96, - 151, 1, 177, 177, 177, 177, 177, 175, 177, 90, - - 5, 170, 59, 62, 177, 177, 177, 177, 177, 177, - 177, 177, 177, 177, 177, 177, 177, 82, 177, 177, - 177, 177, 100, 177, 177, 177, 177, 177, 120, 66, - 67, 177, 177, 177, 177, 177, 177, 177, 177, 177, - 177, 177, 177, 177, 88, 177, 177, 177, 104, 122, - 70, 71, 177, 177, 84, 177, 177, 177, 177, 177, - 177, 177, 115, 177, 177, 177, 177, 177, 177, 177, - 177, 177, 177, 129, 177, 177, 177, 177, 60, 177, + 177, 177, 177, 177, 19, 33, 177, 177, 177, 177, + + 177, 177, 93, 94, 95, 177, 177, 177, 177, 177, + 3, 177, 177, 177, 177, 177, 177, 177, 177, 177, + 177, 177, 140, 177, 177, 177, 177, 177, 8, 177, + 177, 9, 177, 177, 177, 177, 20, 79, 11, 150, + 97, 98, 99, 177, 177, 177, 177, 177, 177, 177, + 177, 177, 177, 177, 177, 145, 177, 177, 177, 81, + 83, 80, 177, 177, 177, 177, 177, 177, 177, 141, + 101, 102, 103, 177, 177, 157, 177, 146, 177, 177, + 6, 177, 177, 177, 177, 177, 177, 177, 177, 177, + 96, 151, 1, 177, 177, 177, 177, 177, 175, 177, + + 90, 5, 170, 59, 62, 177, 177, 177, 177, 177, + 177, 177, 177, 177, 177, 177, 177, 177, 82, 177, + 177, 177, 177, 100, 177, 177, 177, 177, 177, 120, + 66, 67, 177, 177, 177, 177, 177, 177, 177, 177, + 177, 177, 177, 177, 177, 88, 177, 177, 177, 104, + 122, 70, 71, 177, 177, 84, 177, 177, 177, 177, + 177, 177, 177, 115, 177, 177, 177, 177, 177, 177, + 177, 177, 177, 177, 129, 177, 177, 177, 177, 60, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, - 177, 116, 105, 177, 106, 177, 177, 177, 130, 177, - - 177, 68, 177, 177, 177, 177, 177, 177, 177, 177, - 177, 177, 177, 177, 177, 117, 177, 177, 131, 177, - 177, 72, 107, 108, 177, 111, 177, 112, 177, 177, - 177, 177, 177, 85, 177, 177, 177, 177, 64, 177, - 63, 126, 177, 177, 109, 110, 177, 177, 177, 177, - 177, 177, 177, 177, 177, 177, 124, 127, 118, 177, - 65, 177, 177, 177, 177, 177, 177, 177, 177, 125, - 128, 177, 177, 121, 69, 177, 177, 171, 177, 177, - 177, 74, 177, 177, 123, 73, 177, 177, 177, 177, - 177, 177, 132, 177, 177, 177, 177, 177, 177, 133, - - 177, 177, 177, 75, 177, 134, 113, 114, 177, 177, - 177, 61, 177, 177, 172, 119, 76, 0 + 177, 177, 116, 105, 177, 106, 177, 177, 177, 130, + + 177, 177, 68, 177, 177, 177, 177, 177, 177, 177, + 177, 177, 177, 177, 177, 177, 117, 177, 177, 131, + 177, 177, 72, 107, 108, 177, 111, 177, 112, 177, + 177, 177, 177, 177, 85, 177, 177, 177, 177, 64, + 177, 63, 126, 177, 177, 109, 110, 177, 177, 177, + 177, 177, 177, 177, 177, 177, 177, 124, 127, 118, + 177, 65, 177, 177, 177, 177, 177, 177, 177, 177, + 125, 128, 177, 177, 121, 69, 177, 177, 171, 177, + 177, 177, 74, 177, 177, 123, 73, 177, 177, 177, + 177, 177, 177, 132, 177, 177, 177, 177, 177, 177, + + 133, 177, 177, 177, 75, 177, 134, 113, 114, 177, + 177, 177, 61, 177, 177, 172, 119, 76, 0 } ; static yyconst flex_int32_t yy_ec[256] = @@ -547,194 +547,194 @@ static yyconst flex_int32_t yy_meta[73] = 1, 1 } ; -static yyconst flex_int16_t yy_base[824] = +static yyconst flex_int16_t yy_base[825] = { 0, 0, 0, 72, 0, 1016, 1017, 1017, 1017, 990, 120, 141, 1017, 1017, 989, 138, 1017, 137, 135, 988, 154, 208, 986, 1017, 154, 986, 132, 1017, 0, 1017, 1017, 139, 130, 123, 140, 147, 133, 177, 952, 186, 151, 139, 116, 161, 946, 173, 959, 193, 199, 208, 215, - 108, 1017, 184, 1017, 1017, 1017, 1017, 0, 1017, 1017, - 1017, 1017, 1017, 1017, 1017, 1017, 1017, 1017, 230, 1017, - 235, 235, 0, 271, 1017, 0, 1017, 1017, 1017, 982, - 1017, 1017, 1017, 981, 0, 1017, 1017, 943, 948, 152, - 945, 953, 952, 939, 942, 953, 243, 947, 935, 932, - - 945, 932, 929, 929, 935, 147, 248, 929, 939, 925, - 931, 934, 935, 0, 927, 937, 249, 936, 931, 912, - 177, 916, 929, 920, 184, 913, 250, 925, 927, 257, - 916, 913, 902, 911, 249, 257, 915, 911, 913, 902, - 905, 196, 217, 269, 914, 902, 914, 262, 907, 906, - 1017, 1017, 0, 311, 1017, 292, 328, 1017, 1017, 335, - 342, 257, 1017, 1017, 905, 0, 901, 896, 900, 909, - 906, 315, 890, 890, 901, 893, 215, 903, 900, 900, - 898, 895, 887, 893, 880, 878, 890, 876, 892, 0, - 889, 877, 884, 881, 885, 886, 879, 876, 865, 864, - - 877, 880, 868, 876, 864, 870, 861, 316, 866, 869, - 860, 867, 856, 860, 851, 865, 864, 855, 861, 307, - 845, 848, 846, 856, 846, 841, 839, 841, 851, 837, - 839, 836, 847, 846, 849, 831, 316, 839, 835, 833, - 842, 821, 353, 839, 841, 830, 822, 363, 370, 378, - 389, 1017, 1017, 819, 829, 828, 0, 826, 383, 0, - 0, 819, 817, 817, 818, 813, 821, 810, 827, 816, - 394, 0, 0, 810, 820, 819, 819, 0, 804, 397, - 0, 0, 806, 400, 813, 814, 805, 799, 798, 799, - 798, 798, 406, 793, 0, 0, 789, 788, 787, 789, - - 790, 795, 789, 785, 798, 793, 793, 791, 790, 784, - 778, 780, 779, 783, 775, 778, 773, 781, 786, 774, - 771, 783, 774, 0, 0, 780, 776, 0, 768, 768, - 773, 764, 771, 409, 768, 0, 0, 0, 0, 758, - 770, 769, 768, 769, 769, 0, 0, 0, 0, 756, - 0, 764, 755, 0, 754, 755, 749, 759, 0, 0, - 0, 750, 0, 746, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 756, 413, 755, 0, 0, 753, 749, - 746, 0, 0, 0, 738, 415, 418, 427, 743, 739, - 744, 735, 733, 746, 731, 0, 731, 744, 733, 729, - - 735, 730, 737, 0, 735, 732, 736, 720, 718, 721, - 727, 733, 728, 727, 715, 0, 717, 718, 0, 0, - 0, 0, 715, 718, 0, 712, 0, 725, 705, 714, - 709, 0, 702, 702, 715, 0, 717, 0, 431, 730, - 729, 728, 695, 694, 0, 711, 710, 705, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 694, 707, - 694, 691, 0, 0, 696, 695, 0, 692, 699, 698, - 0, 684, 0, 0, 0, 0, 681, 0, 0, 680, - 691, 434, 684, 690, 689, 686, 681, 678, 671, 671, - 684, 669, 681, 0, 0, 674, 697, 696, 695, 662, - - 661, 427, 428, 0, 673, 676, 674, 663, 659, 0, - 671, 668, 667, 657, 656, 646, 663, 649, 441, 657, - 660, 0, 677, 676, 675, 642, 641, 0, 655, 642, - 0, 652, 645, 646, 649, 0, 0, 0, 0, 669, - 668, 0, 645, 648, 633, 640, 631, 638, 639, 639, - 638, 624, 451, 636, 0, 637, 626, 625, 0, 0, - 0, 650, 649, 648, 615, 614, 610, 618, 0, 646, - 645, 0, 622, 625, 0, 458, 0, 603, 612, 0, - 608, 607, 616, 616, 604, 618, 602, 616, 611, 0, - 0, 0, 628, 627, 626, 593, 592, 0, 592, 0, - - 0, 434, 454, 616, 602, 605, 588, 600, 588, 587, - 596, 596, 613, 612, 611, 578, 577, 0, 577, 578, - 577, 587, 0, 590, 586, 588, 584, 571, 602, 449, - 0, 579, 582, 574, 566, 573, 564, 585, 573, 569, - 571, 569, 569, 568, 0, 556, 555, 565, 0, 585, - 462, 0, 562, 565, 0, 565, 564, 548, 540, 548, - 538, 546, 0, 543, 542, 563, 551, 549, 549, 533, - 536, 550, 534, 565, 545, 546, 543, 540, 550, 527, - 541, 540, 524, 523, 522, 543, 531, 529, 529, 510, - 509, 0, 537, 509, 535, 507, 511, 510, 541, 521, - - 518, 0, 517, 520, 516, 518, 502, 499, 512, 497, - 498, 505, 499, 488, 487, 0, 493, 492, 523, 503, - 500, 0, 0, 0, 496, 0, 495, 0, 501, 500, - 484, 481, 482, 0, 474, 482, 472, 478, 499, 478, - 0, 0, 490, 489, 0, 0, 488, 487, 471, 468, - 469, 483, 482, 459, 458, 464, 0, 0, 485, 457, - 483, 475, 467, 453, 132, 161, 177, 215, 245, 0, - 0, 288, 289, 0, 0, 294, 315, 0, 316, 306, - 331, 0, 363, 402, 0, 0, 395, 383, 395, 387, - 433, 434, 0, 435, 420, 461, 427, 430, 431, 0, - - 450, 452, 443, 0, 464, 0, 0, 0, 445, 446, - 440, 0, 441, 442, 0, 0, 0, 1017, 506, 509, - 512, 513, 514 + 108, 1017, 184, 1017, 1017, 1017, 1017, 1017, 0, 1017, + 1017, 1017, 1017, 1017, 1017, 1017, 1017, 1017, 1017, 230, + 1017, 235, 235, 0, 271, 1017, 0, 1017, 1017, 1017, + 982, 1017, 1017, 1017, 981, 0, 1017, 1017, 943, 948, + 152, 945, 953, 952, 939, 942, 953, 243, 947, 935, + + 932, 945, 932, 929, 929, 935, 147, 248, 929, 939, + 925, 931, 934, 935, 0, 927, 937, 249, 936, 931, + 912, 177, 916, 929, 920, 184, 913, 250, 925, 927, + 257, 916, 913, 902, 911, 249, 257, 915, 911, 913, + 902, 905, 196, 217, 269, 914, 902, 914, 262, 907, + 906, 1017, 1017, 0, 311, 1017, 292, 328, 1017, 1017, + 335, 342, 257, 1017, 1017, 905, 0, 901, 896, 900, + 909, 906, 315, 890, 890, 901, 893, 215, 903, 900, + 900, 898, 895, 887, 893, 880, 878, 890, 876, 892, + 0, 889, 877, 884, 881, 885, 886, 879, 876, 865, + + 864, 877, 880, 868, 876, 864, 870, 861, 316, 866, + 869, 860, 867, 856, 860, 851, 865, 864, 855, 861, + 307, 845, 848, 846, 856, 846, 841, 839, 841, 851, + 837, 839, 836, 847, 846, 849, 831, 316, 839, 835, + 833, 842, 821, 353, 839, 841, 830, 822, 363, 370, + 378, 389, 1017, 1017, 819, 829, 828, 0, 826, 383, + 0, 0, 819, 817, 817, 818, 813, 821, 810, 827, + 816, 394, 0, 0, 810, 820, 819, 819, 0, 804, + 397, 0, 0, 806, 400, 813, 814, 805, 799, 798, + 799, 798, 798, 406, 793, 0, 0, 789, 788, 787, + + 789, 790, 795, 789, 785, 798, 793, 793, 791, 790, + 784, 778, 780, 779, 783, 775, 778, 773, 781, 786, + 774, 771, 783, 774, 0, 0, 780, 776, 0, 768, + 768, 773, 764, 771, 409, 768, 0, 0, 0, 0, + 758, 770, 769, 768, 769, 769, 0, 0, 0, 0, + 756, 0, 764, 755, 0, 754, 755, 749, 759, 0, + 0, 0, 750, 0, 746, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 756, 413, 755, 0, 0, 753, + 749, 746, 0, 0, 0, 738, 415, 418, 427, 743, + 739, 744, 735, 733, 746, 731, 0, 731, 744, 733, + + 729, 735, 730, 737, 0, 735, 732, 736, 720, 718, + 721, 727, 733, 728, 727, 715, 0, 717, 718, 0, + 0, 0, 0, 715, 718, 0, 712, 0, 725, 705, + 714, 709, 0, 702, 702, 715, 0, 717, 0, 431, + 730, 729, 728, 695, 694, 0, 711, 710, 705, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 694, + 707, 694, 691, 0, 0, 696, 695, 0, 692, 699, + 698, 0, 684, 0, 0, 0, 0, 681, 0, 0, + 680, 691, 434, 684, 690, 689, 686, 681, 678, 671, + 671, 684, 669, 681, 0, 0, 674, 697, 696, 695, + + 662, 661, 427, 428, 0, 673, 676, 674, 663, 659, + 0, 671, 668, 667, 657, 656, 646, 663, 649, 441, + 657, 660, 0, 677, 676, 675, 642, 641, 0, 655, + 642, 0, 652, 645, 646, 649, 0, 0, 0, 0, + 669, 668, 0, 645, 648, 633, 640, 631, 638, 639, + 639, 638, 624, 451, 636, 0, 637, 626, 625, 0, + 0, 0, 650, 649, 648, 615, 614, 610, 618, 0, + 646, 645, 0, 622, 625, 0, 458, 0, 603, 612, + 0, 608, 607, 616, 616, 604, 618, 602, 616, 611, + 0, 0, 0, 628, 627, 626, 593, 592, 0, 592, + + 0, 0, 434, 454, 616, 602, 605, 588, 600, 588, + 587, 596, 596, 613, 612, 611, 578, 577, 0, 577, + 578, 577, 587, 0, 590, 586, 588, 584, 571, 602, + 449, 0, 579, 582, 574, 566, 573, 564, 585, 573, + 569, 571, 569, 569, 568, 0, 556, 555, 565, 0, + 585, 462, 0, 562, 565, 0, 565, 564, 548, 540, + 548, 538, 546, 0, 543, 542, 563, 551, 549, 549, + 533, 536, 550, 534, 565, 545, 546, 543, 540, 550, + 527, 541, 540, 524, 523, 522, 543, 531, 529, 529, + 510, 509, 0, 537, 509, 535, 507, 511, 510, 541, + + 521, 518, 0, 517, 520, 516, 518, 502, 499, 512, + 497, 498, 505, 499, 488, 487, 0, 493, 492, 523, + 503, 500, 0, 0, 0, 496, 0, 495, 0, 501, + 500, 484, 481, 482, 0, 474, 482, 472, 478, 499, + 478, 0, 0, 490, 489, 0, 0, 488, 487, 471, + 468, 469, 483, 482, 459, 458, 464, 0, 0, 485, + 457, 483, 475, 467, 453, 132, 161, 177, 215, 245, + 0, 0, 288, 289, 0, 0, 294, 315, 0, 316, + 306, 331, 0, 363, 402, 0, 0, 395, 383, 395, + 387, 433, 434, 0, 435, 420, 461, 427, 430, 431, + + 0, 450, 452, 443, 0, 464, 0, 0, 0, 445, + 446, 440, 0, 441, 442, 0, 0, 0, 1017, 506, + 509, 512, 513, 514 } ; -static yyconst flex_int16_t yy_def[824] = +static yyconst flex_int16_t yy_def[825] = { 0, - 818, 1, 818, 3, 818, 818, 818, 818, 818, 818, - 818, 818, 818, 818, 818, 818, 818, 818, 818, 818, - 818, 818, 818, 818, 818, 818, 818, 819, 818, 818, - 818, 819, 819, 819, 819, 819, 819, 819, 819, 819, - 819, 819, 819, 819, 819, 819, 819, 819, 819, 819, - 819, 818, 818, 818, 818, 818, 818, 820, 818, 818, - 818, 818, 818, 818, 818, 818, 818, 818, 821, 818, - 822, 20, 21, 818, 818, 823, 818, 818, 818, 818, - 818, 818, 818, 818, 819, 818, 818, 819, 819, 819, - 819, 819, 819, 819, 819, 819, 819, 819, 819, 819, - - 819, 819, 819, 819, 819, 819, 819, 819, 819, 819, - 819, 819, 819, 819, 819, 819, 819, 819, 819, 819, - 819, 819, 819, 819, 819, 819, 819, 819, 819, 819, - 819, 819, 819, 819, 819, 819, 819, 819, 819, 819, - 819, 819, 819, 819, 819, 819, 819, 819, 819, 819, - 818, 818, 820, 818, 818, 822, 818, 818, 818, 818, - 818, 823, 818, 818, 819, 819, 819, 819, 819, 819, - 819, 819, 819, 819, 819, 819, 819, 819, 819, 819, - 819, 819, 819, 819, 819, 819, 819, 819, 819, 819, - 819, 819, 819, 819, 819, 819, 819, 819, 819, 819, - - 819, 819, 819, 819, 819, 819, 819, 819, 819, 819, - 819, 819, 819, 819, 819, 819, 819, 819, 819, 819, - 819, 819, 819, 819, 819, 819, 819, 819, 819, 819, - 819, 819, 819, 819, 819, 819, 819, 819, 819, 819, - 819, 819, 819, 819, 819, 819, 819, 818, 818, 818, - 818, 818, 818, 819, 819, 819, 819, 819, 819, 819, - 819, 819, 819, 819, 819, 819, 819, 819, 819, 819, - 819, 819, 819, 819, 819, 819, 819, 819, 819, 819, - 819, 819, 819, 819, 819, 819, 819, 819, 819, 819, - 819, 819, 819, 819, 819, 819, 819, 819, 819, 819, - - 819, 819, 819, 819, 819, 819, 819, 819, 819, 819, - 819, 819, 819, 819, 819, 819, 819, 819, 819, 819, - 819, 819, 819, 819, 819, 819, 819, 819, 819, 819, - 819, 819, 819, 819, 819, 819, 819, 819, 819, 819, - 819, 819, 819, 819, 819, 819, 819, 819, 819, 819, - 819, 819, 819, 819, 819, 819, 819, 819, 819, 819, - 819, 819, 819, 819, 819, 819, 819, 819, 819, 819, - 819, 819, 819, 819, 819, 819, 819, 819, 819, 819, - 819, 819, 819, 819, 819, 819, 819, 819, 819, 819, - 819, 819, 819, 819, 819, 819, 819, 819, 819, 819, - - 819, 819, 819, 819, 819, 819, 819, 819, 819, 819, - 819, 819, 819, 819, 819, 819, 819, 819, 819, 819, - 819, 819, 819, 819, 819, 819, 819, 819, 819, 819, - 819, 819, 819, 819, 819, 819, 819, 819, 819, 819, - 819, 819, 819, 819, 819, 819, 819, 819, 819, 819, - 819, 819, 819, 819, 819, 819, 819, 819, 819, 819, - 819, 819, 819, 819, 819, 819, 819, 819, 819, 819, - 819, 819, 819, 819, 819, 819, 819, 819, 819, 819, - 819, 819, 819, 819, 819, 819, 819, 819, 819, 819, - 819, 819, 819, 819, 819, 819, 819, 819, 819, 819, - - 819, 819, 819, 819, 819, 819, 819, 819, 819, 819, - 819, 819, 819, 819, 819, 819, 819, 819, 819, 819, - 819, 819, 819, 819, 819, 819, 819, 819, 819, 819, - 819, 819, 819, 819, 819, 819, 819, 819, 819, 819, - 819, 819, 819, 819, 819, 819, 819, 819, 819, 819, - 819, 819, 819, 819, 819, 819, 819, 819, 819, 819, - 819, 819, 819, 819, 819, 819, 819, 819, 819, 819, - 819, 819, 819, 819, 819, 819, 819, 819, 819, 819, - 819, 819, 819, 819, 819, 819, 819, 819, 819, 819, - 819, 819, 819, 819, 819, 819, 819, 819, 819, 819, - - 819, 819, 819, 819, 819, 819, 819, 819, 819, 819, - 819, 819, 819, 819, 819, 819, 819, 819, 819, 819, - 819, 819, 819, 819, 819, 819, 819, 819, 819, 819, - 819, 819, 819, 819, 819, 819, 819, 819, 819, 819, - 819, 819, 819, 819, 819, 819, 819, 819, 819, 819, - 819, 819, 819, 819, 819, 819, 819, 819, 819, 819, - 819, 819, 819, 819, 819, 819, 819, 819, 819, 819, - 819, 819, 819, 819, 819, 819, 819, 819, 819, 819, - 819, 819, 819, 819, 819, 819, 819, 819, 819, 819, - 819, 819, 819, 819, 819, 819, 819, 819, 819, 819, - - 819, 819, 819, 819, 819, 819, 819, 819, 819, 819, - 819, 819, 819, 819, 819, 819, 819, 819, 819, 819, - 819, 819, 819, 819, 819, 819, 819, 819, 819, 819, - 819, 819, 819, 819, 819, 819, 819, 819, 819, 819, - 819, 819, 819, 819, 819, 819, 819, 819, 819, 819, - 819, 819, 819, 819, 819, 819, 819, 819, 819, 819, - 819, 819, 819, 819, 819, 819, 819, 819, 819, 819, - 819, 819, 819, 819, 819, 819, 819, 819, 819, 819, - 819, 819, 819, 819, 819, 819, 819, 819, 819, 819, - 819, 819, 819, 819, 819, 819, 819, 819, 819, 819, - - 819, 819, 819, 819, 819, 819, 819, 819, 819, 819, - 819, 819, 819, 819, 819, 819, 819, 0, 818, 818, - 818, 818, 818 + 819, 1, 819, 3, 819, 819, 819, 819, 819, 819, + 819, 819, 819, 819, 819, 819, 819, 819, 819, 819, + 819, 819, 819, 819, 819, 819, 819, 820, 819, 819, + 819, 820, 820, 820, 820, 820, 820, 820, 820, 820, + 820, 820, 820, 820, 820, 820, 820, 820, 820, 820, + 820, 819, 819, 819, 819, 819, 819, 819, 821, 819, + 819, 819, 819, 819, 819, 819, 819, 819, 819, 822, + 819, 823, 20, 21, 819, 819, 824, 819, 819, 819, + 819, 819, 819, 819, 819, 820, 819, 819, 820, 820, + 820, 820, 820, 820, 820, 820, 820, 820, 820, 820, + + 820, 820, 820, 820, 820, 820, 820, 820, 820, 820, + 820, 820, 820, 820, 820, 820, 820, 820, 820, 820, + 820, 820, 820, 820, 820, 820, 820, 820, 820, 820, + 820, 820, 820, 820, 820, 820, 820, 820, 820, 820, + 820, 820, 820, 820, 820, 820, 820, 820, 820, 820, + 820, 819, 819, 821, 819, 819, 823, 819, 819, 819, + 819, 819, 824, 819, 819, 820, 820, 820, 820, 820, + 820, 820, 820, 820, 820, 820, 820, 820, 820, 820, + 820, 820, 820, 820, 820, 820, 820, 820, 820, 820, + 820, 820, 820, 820, 820, 820, 820, 820, 820, 820, + + 820, 820, 820, 820, 820, 820, 820, 820, 820, 820, + 820, 820, 820, 820, 820, 820, 820, 820, 820, 820, + 820, 820, 820, 820, 820, 820, 820, 820, 820, 820, + 820, 820, 820, 820, 820, 820, 820, 820, 820, 820, + 820, 820, 820, 820, 820, 820, 820, 820, 819, 819, + 819, 819, 819, 819, 820, 820, 820, 820, 820, 820, + 820, 820, 820, 820, 820, 820, 820, 820, 820, 820, + 820, 820, 820, 820, 820, 820, 820, 820, 820, 820, + 820, 820, 820, 820, 820, 820, 820, 820, 820, 820, + 820, 820, 820, 820, 820, 820, 820, 820, 820, 820, + + 820, 820, 820, 820, 820, 820, 820, 820, 820, 820, + 820, 820, 820, 820, 820, 820, 820, 820, 820, 820, + 820, 820, 820, 820, 820, 820, 820, 820, 820, 820, + 820, 820, 820, 820, 820, 820, 820, 820, 820, 820, + 820, 820, 820, 820, 820, 820, 820, 820, 820, 820, + 820, 820, 820, 820, 820, 820, 820, 820, 820, 820, + 820, 820, 820, 820, 820, 820, 820, 820, 820, 820, + 820, 820, 820, 820, 820, 820, 820, 820, 820, 820, + 820, 820, 820, 820, 820, 820, 820, 820, 820, 820, + 820, 820, 820, 820, 820, 820, 820, 820, 820, 820, + + 820, 820, 820, 820, 820, 820, 820, 820, 820, 820, + 820, 820, 820, 820, 820, 820, 820, 820, 820, 820, + 820, 820, 820, 820, 820, 820, 820, 820, 820, 820, + 820, 820, 820, 820, 820, 820, 820, 820, 820, 820, + 820, 820, 820, 820, 820, 820, 820, 820, 820, 820, + 820, 820, 820, 820, 820, 820, 820, 820, 820, 820, + 820, 820, 820, 820, 820, 820, 820, 820, 820, 820, + 820, 820, 820, 820, 820, 820, 820, 820, 820, 820, + 820, 820, 820, 820, 820, 820, 820, 820, 820, 820, + 820, 820, 820, 820, 820, 820, 820, 820, 820, 820, + + 820, 820, 820, 820, 820, 820, 820, 820, 820, 820, + 820, 820, 820, 820, 820, 820, 820, 820, 820, 820, + 820, 820, 820, 820, 820, 820, 820, 820, 820, 820, + 820, 820, 820, 820, 820, 820, 820, 820, 820, 820, + 820, 820, 820, 820, 820, 820, 820, 820, 820, 820, + 820, 820, 820, 820, 820, 820, 820, 820, 820, 820, + 820, 820, 820, 820, 820, 820, 820, 820, 820, 820, + 820, 820, 820, 820, 820, 820, 820, 820, 820, 820, + 820, 820, 820, 820, 820, 820, 820, 820, 820, 820, + 820, 820, 820, 820, 820, 820, 820, 820, 820, 820, + + 820, 820, 820, 820, 820, 820, 820, 820, 820, 820, + 820, 820, 820, 820, 820, 820, 820, 820, 820, 820, + 820, 820, 820, 820, 820, 820, 820, 820, 820, 820, + 820, 820, 820, 820, 820, 820, 820, 820, 820, 820, + 820, 820, 820, 820, 820, 820, 820, 820, 820, 820, + 820, 820, 820, 820, 820, 820, 820, 820, 820, 820, + 820, 820, 820, 820, 820, 820, 820, 820, 820, 820, + 820, 820, 820, 820, 820, 820, 820, 820, 820, 820, + 820, 820, 820, 820, 820, 820, 820, 820, 820, 820, + 820, 820, 820, 820, 820, 820, 820, 820, 820, 820, + + 820, 820, 820, 820, 820, 820, 820, 820, 820, 820, + 820, 820, 820, 820, 820, 820, 820, 820, 820, 820, + 820, 820, 820, 820, 820, 820, 820, 820, 820, 820, + 820, 820, 820, 820, 820, 820, 820, 820, 820, 820, + 820, 820, 820, 820, 820, 820, 820, 820, 820, 820, + 820, 820, 820, 820, 820, 820, 820, 820, 820, 820, + 820, 820, 820, 820, 820, 820, 820, 820, 820, 820, + 820, 820, 820, 820, 820, 820, 820, 820, 820, 820, + 820, 820, 820, 820, 820, 820, 820, 820, 820, 820, + 820, 820, 820, 820, 820, 820, 820, 820, 820, 820, + + 820, 820, 820, 820, 820, 820, 820, 820, 820, 820, + 820, 820, 820, 820, 820, 820, 820, 820, 0, 819, + 819, 819, 819, 819 } ; static yyconst flex_int16_t yy_nxt[1090] = @@ -746,118 +746,118 @@ static yyconst flex_int16_t yy_nxt[1090] = 29, 30, 31, 28, 32, 33, 34, 35, 36, 37, 38, 39, 40, 28, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 28, 28, 28, 52, 53, - 54, 55, 6, 56, 57, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 58, - - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 6, 6, 6, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 6, 6, 6, 6, 60, 61, 62, 65, 67, 69, - 69, 69, 69, 69, 69, 69, 83, 84, 78, 149, - 122, 68, 66, 86, 123, 63, 71, 150, 72, 72, - 72, 72, 72, 72, 73, 79, 88, 80, 81, 783, - 91, 87, 92, 120, 94, 74, 93, 102, 95, 103, - 89, 90, 75, 76, 96, 98, 121, 97, 104, 99, - - 114, 186, 74, 115, 100, 124, 116, 117, 151, 167, - 101, 118, 187, 168, 119, 784, 75, 127, 125, 76, - 71, 105, 73, 73, 73, 73, 73, 73, 73, 106, - 111, 107, 128, 206, 108, 129, 211, 131, 112, 74, - 109, 207, 212, 785, 132, 133, 75, 138, 134, 113, - 139, 235, 236, 152, 135, 136, 74, 137, 140, 146, - 142, 154, 155, 147, 143, 141, 157, 158, 144, 237, - 75, 145, 148, 159, 818, 266, 267, 238, 154, 155, - 160, 786, 160, 157, 158, 161, 161, 161, 161, 161, - 161, 161, 188, 226, 175, 253, 214, 159, 176, 177, - - 818, 219, 228, 198, 787, 189, 199, 200, 227, 215, - 201, 216, 202, 239, 244, 229, 245, 220, 221, 253, - 248, 240, 248, 157, 158, 249, 249, 249, 249, 249, - 249, 249, 297, 298, 299, 788, 789, 250, 790, 250, - 157, 158, 251, 251, 251, 251, 251, 251, 251, 161, - 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, - 161, 161, 161, 260, 311, 329, 791, 792, 312, 336, - 337, 338, 793, 330, 252, 794, 261, 249, 249, 249, - 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, - 249, 252, 251, 251, 251, 251, 251, 251, 251, 347, - - 348, 349, 155, 251, 251, 251, 251, 251, 251, 251, - 359, 360, 361, 367, 368, 369, 371, 372, 373, 155, - 795, 158, 382, 383, 384, 420, 421, 422, 440, 441, - 442, 450, 451, 452, 453, 454, 455, 796, 158, 797, - 798, 443, 444, 456, 457, 458, 497, 498, 499, 523, - 524, 525, 799, 800, 545, 547, 562, 563, 564, 500, - 501, 635, 526, 527, 546, 548, 593, 594, 595, 565, - 566, 636, 567, 613, 614, 615, 665, 801, 802, 596, - 597, 637, 803, 666, 804, 667, 616, 617, 638, 685, - 639, 640, 805, 806, 807, 808, 686, 809, 687, 810, - - 811, 812, 813, 814, 815, 816, 817, 85, 85, 85, - 153, 153, 153, 69, 156, 162, 162, 782, 781, 780, - 779, 778, 777, 776, 775, 774, 773, 772, 771, 770, - 769, 768, 767, 766, 765, 764, 763, 762, 761, 760, - 759, 758, 757, 756, 755, 754, 753, 752, 751, 750, - 749, 748, 747, 746, 745, 744, 743, 742, 741, 740, - 739, 738, 737, 736, 735, 734, 733, 732, 731, 730, - 729, 728, 727, 726, 725, 724, 723, 722, 721, 720, - 719, 718, 717, 716, 715, 714, 713, 712, 711, 710, - 709, 708, 707, 706, 705, 704, 703, 702, 701, 700, - - 699, 698, 697, 696, 695, 694, 693, 692, 691, 690, - 689, 688, 684, 683, 682, 681, 680, 679, 678, 677, - 676, 675, 674, 673, 672, 671, 670, 669, 668, 664, - 663, 662, 661, 660, 659, 658, 657, 656, 655, 654, - 653, 652, 651, 650, 649, 648, 647, 646, 645, 644, - 643, 642, 641, 634, 633, 632, 631, 630, 629, 628, - 627, 626, 625, 624, 623, 622, 621, 620, 619, 618, - 612, 611, 610, 609, 608, 607, 606, 605, 604, 603, - 602, 601, 600, 599, 598, 592, 591, 590, 589, 588, - 587, 586, 585, 584, 583, 582, 581, 580, 579, 578, - - 577, 576, 575, 574, 573, 572, 571, 570, 569, 568, - 561, 560, 559, 558, 557, 556, 555, 554, 553, 552, - 551, 550, 549, 544, 543, 542, 541, 540, 539, 538, - 537, 536, 535, 534, 533, 532, 531, 530, 529, 528, - 522, 521, 520, 519, 518, 517, 516, 515, 514, 513, - 512, 511, 510, 509, 508, 507, 506, 505, 504, 503, - 502, 496, 495, 494, 493, 492, 491, 490, 489, 488, - 487, 486, 485, 484, 483, 482, 481, 480, 479, 478, - 477, 476, 475, 474, 473, 472, 471, 470, 469, 468, - 467, 466, 465, 464, 463, 462, 461, 460, 459, 449, - - 448, 447, 446, 445, 439, 438, 437, 436, 435, 434, - 433, 432, 431, 430, 429, 428, 427, 426, 425, 424, - 423, 419, 418, 417, 416, 415, 414, 413, 412, 411, - 410, 409, 408, 407, 406, 405, 404, 403, 402, 401, - 400, 399, 398, 397, 396, 395, 394, 393, 392, 391, - 390, 389, 388, 387, 386, 385, 381, 380, 379, 378, - 377, 376, 375, 374, 370, 366, 365, 364, 363, 362, - 358, 357, 356, 355, 354, 353, 352, 351, 350, 346, - 345, 344, 343, 342, 341, 340, 339, 335, 334, 333, - 332, 331, 328, 327, 326, 325, 324, 323, 322, 321, - - 320, 319, 318, 317, 316, 315, 314, 313, 310, 309, - 308, 307, 306, 305, 304, 303, 302, 301, 300, 296, - 295, 294, 293, 292, 291, 290, 289, 288, 287, 286, - 285, 284, 283, 282, 281, 280, 279, 278, 277, 276, - 275, 274, 273, 272, 271, 270, 269, 268, 265, 264, - 263, 262, 259, 258, 257, 256, 255, 254, 247, 246, - 243, 242, 241, 234, 233, 232, 231, 230, 225, 224, - 223, 222, 218, 217, 213, 210, 209, 208, 205, 204, - 203, 197, 196, 195, 194, 193, 192, 191, 190, 185, - 184, 183, 182, 181, 180, 179, 178, 174, 173, 172, - - 171, 170, 169, 166, 165, 164, 163, 130, 126, 110, - 82, 77, 70, 64, 59, 818, 5, 818, 818, 818, - 818, 818, 818, 818, 818, 818, 818, 818, 818, 818, - 818, 818, 818, 818, 818, 818, 818, 818, 818, 818, - 818, 818, 818, 818, 818, 818, 818, 818, 818, 818, - 818, 818, 818, 818, 818, 818, 818, 818, 818, 818, - 818, 818, 818, 818, 818, 818, 818, 818, 818, 818, - 818, 818, 818, 818, 818, 818, 818, 818, 818, 818, - 818, 818, 818, 818, 818, 818, 818, 818, 818 + 54, 55, 56, 57, 58, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 59, + + 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, + 59, 59, 56, 56, 56, 59, 59, 59, 59, 59, + 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, + 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, + 56, 56, 56, 56, 61, 62, 63, 66, 68, 70, + 70, 70, 70, 70, 70, 70, 84, 85, 79, 150, + 123, 69, 67, 87, 124, 64, 72, 151, 73, 73, + 73, 73, 73, 73, 74, 80, 89, 81, 82, 784, + 92, 88, 93, 121, 95, 75, 94, 103, 96, 104, + 90, 91, 76, 77, 97, 99, 122, 98, 105, 100, + + 115, 187, 75, 116, 101, 125, 117, 118, 152, 168, + 102, 119, 188, 169, 120, 785, 76, 128, 126, 77, + 72, 106, 74, 74, 74, 74, 74, 74, 74, 107, + 112, 108, 129, 207, 109, 130, 212, 132, 113, 75, + 110, 208, 213, 786, 133, 134, 76, 139, 135, 114, + 140, 236, 237, 153, 136, 137, 75, 138, 141, 147, + 143, 155, 156, 148, 144, 142, 158, 159, 145, 238, + 76, 146, 149, 160, 819, 267, 268, 239, 155, 156, + 161, 787, 161, 158, 159, 162, 162, 162, 162, 162, + 162, 162, 189, 227, 176, 254, 215, 160, 177, 178, + + 819, 220, 229, 199, 788, 190, 200, 201, 228, 216, + 202, 217, 203, 240, 245, 230, 246, 221, 222, 254, + 249, 241, 249, 158, 159, 250, 250, 250, 250, 250, + 250, 250, 298, 299, 300, 789, 790, 251, 791, 251, + 158, 159, 252, 252, 252, 252, 252, 252, 252, 162, + 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, + 162, 162, 162, 261, 312, 330, 792, 793, 313, 337, + 338, 339, 794, 331, 253, 795, 262, 250, 250, 250, + 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, + 250, 253, 252, 252, 252, 252, 252, 252, 252, 348, + + 349, 350, 156, 252, 252, 252, 252, 252, 252, 252, + 360, 361, 362, 368, 369, 370, 372, 373, 374, 156, + 796, 159, 383, 384, 385, 421, 422, 423, 441, 442, + 443, 451, 452, 453, 454, 455, 456, 797, 159, 798, + 799, 444, 445, 457, 458, 459, 498, 499, 500, 524, + 525, 526, 800, 801, 546, 548, 563, 564, 565, 501, + 502, 636, 527, 528, 547, 549, 594, 595, 596, 566, + 567, 637, 568, 614, 615, 616, 666, 802, 803, 597, + 598, 638, 804, 667, 805, 668, 617, 618, 639, 686, + 640, 641, 806, 807, 808, 809, 687, 810, 688, 811, + + 812, 813, 814, 815, 816, 817, 818, 86, 86, 86, + 154, 154, 154, 70, 157, 163, 163, 783, 782, 781, + 780, 779, 778, 777, 776, 775, 774, 773, 772, 771, + 770, 769, 768, 767, 766, 765, 764, 763, 762, 761, + 760, 759, 758, 757, 756, 755, 754, 753, 752, 751, + 750, 749, 748, 747, 746, 745, 744, 743, 742, 741, + 740, 739, 738, 737, 736, 735, 734, 733, 732, 731, + 730, 729, 728, 727, 726, 725, 724, 723, 722, 721, + 720, 719, 718, 717, 716, 715, 714, 713, 712, 711, + 710, 709, 708, 707, 706, 705, 704, 703, 702, 701, + + 700, 699, 698, 697, 696, 695, 694, 693, 692, 691, + 690, 689, 685, 684, 683, 682, 681, 680, 679, 678, + 677, 676, 675, 674, 673, 672, 671, 670, 669, 665, + 664, 663, 662, 661, 660, 659, 658, 657, 656, 655, + 654, 653, 652, 651, 650, 649, 648, 647, 646, 645, + 644, 643, 642, 635, 634, 633, 632, 631, 630, 629, + 628, 627, 626, 625, 624, 623, 622, 621, 620, 619, + 613, 612, 611, 610, 609, 608, 607, 606, 605, 604, + 603, 602, 601, 600, 599, 593, 592, 591, 590, 589, + 588, 587, 586, 585, 584, 583, 582, 581, 580, 579, + + 578, 577, 576, 575, 574, 573, 572, 571, 570, 569, + 562, 561, 560, 559, 558, 557, 556, 555, 554, 553, + 552, 551, 550, 545, 544, 543, 542, 541, 540, 539, + 538, 537, 536, 535, 534, 533, 532, 531, 530, 529, + 523, 522, 521, 520, 519, 518, 517, 516, 515, 514, + 513, 512, 511, 510, 509, 508, 507, 506, 505, 504, + 503, 497, 496, 495, 494, 493, 492, 491, 490, 489, + 488, 487, 486, 485, 484, 483, 482, 481, 480, 479, + 478, 477, 476, 475, 474, 473, 472, 471, 470, 469, + 468, 467, 466, 465, 464, 463, 462, 461, 460, 450, + + 449, 448, 447, 446, 440, 439, 438, 437, 436, 435, + 434, 433, 432, 431, 430, 429, 428, 427, 426, 425, + 424, 420, 419, 418, 417, 416, 415, 414, 413, 412, + 411, 410, 409, 408, 407, 406, 405, 404, 403, 402, + 401, 400, 399, 398, 397, 396, 395, 394, 393, 392, + 391, 390, 389, 388, 387, 386, 382, 381, 380, 379, + 378, 377, 376, 375, 371, 367, 366, 365, 364, 363, + 359, 358, 357, 356, 355, 354, 353, 352, 351, 347, + 346, 345, 344, 343, 342, 341, 340, 336, 335, 334, + 333, 332, 329, 328, 327, 326, 325, 324, 323, 322, + + 321, 320, 319, 318, 317, 316, 315, 314, 311, 310, + 309, 308, 307, 306, 305, 304, 303, 302, 301, 297, + 296, 295, 294, 293, 292, 291, 290, 289, 288, 287, + 286, 285, 284, 283, 282, 281, 280, 279, 278, 277, + 276, 275, 274, 273, 272, 271, 270, 269, 266, 265, + 264, 263, 260, 259, 258, 257, 256, 255, 248, 247, + 244, 243, 242, 235, 234, 233, 232, 231, 226, 225, + 224, 223, 219, 218, 214, 211, 210, 209, 206, 205, + 204, 198, 197, 196, 195, 194, 193, 192, 191, 186, + 185, 184, 183, 182, 181, 180, 179, 175, 174, 173, + + 172, 171, 170, 167, 166, 165, 164, 131, 127, 111, + 83, 78, 71, 65, 60, 819, 5, 819, 819, 819, + 819, 819, 819, 819, 819, 819, 819, 819, 819, 819, + 819, 819, 819, 819, 819, 819, 819, 819, 819, 819, + 819, 819, 819, 819, 819, 819, 819, 819, 819, 819, + 819, 819, 819, 819, 819, 819, 819, 819, 819, 819, + 819, 819, 819, 819, 819, 819, 819, 819, 819, 819, + 819, 819, 819, 819, 819, 819, 819, 819, 819, 819, + 819, 819, 819, 819, 819, 819, 819, 819, 819 } ; static yyconst flex_int16_t yy_chk[1090] = @@ -880,111 +880,111 @@ static yyconst flex_int16_t yy_chk[1090] = 3, 3, 3, 3, 10, 10, 11, 15, 17, 18, 18, 18, 18, 18, 18, 18, 26, 26, 24, 51, 42, 17, 15, 31, 42, 11, 20, 51, 20, 20, - 20, 20, 20, 20, 20, 24, 32, 24, 24, 765, + 20, 20, 20, 20, 20, 24, 32, 24, 24, 766, 33, 31, 33, 41, 34, 20, 33, 36, 34, 36, 32, 32, 20, 20, 34, 35, 41, 34, 36, 35, - 40, 106, 20, 40, 35, 43, 40, 40, 53, 90, - 35, 40, 106, 90, 40, 766, 20, 45, 43, 20, + 40, 107, 20, 40, 35, 43, 40, 40, 53, 91, + 35, 40, 107, 91, 40, 767, 20, 45, 43, 20, 21, 37, 21, 21, 21, 21, 21, 21, 21, 37, - 39, 37, 45, 121, 37, 45, 125, 47, 39, 21, - 37, 121, 125, 767, 47, 47, 21, 48, 47, 39, - 48, 142, 142, 53, 47, 47, 21, 47, 48, 50, - 49, 69, 69, 50, 49, 48, 71, 71, 49, 143, - 21, 49, 50, 72, 72, 177, 177, 143, 69, 69, - 74, 768, 74, 71, 71, 74, 74, 74, 74, 74, - 74, 74, 107, 135, 97, 162, 127, 72, 97, 97, - - 72, 130, 136, 117, 769, 107, 117, 117, 135, 127, - 117, 127, 117, 144, 148, 136, 148, 130, 130, 162, - 154, 144, 154, 156, 156, 154, 154, 154, 154, 154, - 154, 154, 208, 208, 208, 772, 773, 157, 776, 157, - 156, 156, 157, 157, 157, 157, 157, 157, 157, 160, - 160, 160, 160, 160, 160, 160, 161, 161, 161, 161, - 161, 161, 161, 172, 220, 237, 777, 779, 220, 243, - 243, 243, 780, 237, 161, 781, 172, 248, 248, 248, - 248, 248, 248, 248, 249, 249, 249, 249, 249, 249, - 249, 161, 250, 250, 250, 250, 250, 250, 250, 259, - - 259, 259, 249, 251, 251, 251, 251, 251, 251, 251, - 271, 271, 271, 280, 280, 280, 284, 284, 284, 249, - 783, 251, 293, 293, 293, 334, 334, 334, 375, 375, - 375, 386, 386, 386, 387, 387, 387, 784, 251, 787, - 788, 375, 375, 388, 388, 388, 439, 439, 439, 482, - 482, 482, 789, 790, 502, 503, 519, 519, 519, 439, - 439, 602, 482, 482, 502, 503, 553, 553, 553, 519, - 519, 602, 519, 576, 576, 576, 630, 791, 792, 553, - 553, 603, 794, 630, 795, 630, 576, 576, 603, 651, - 603, 603, 796, 797, 798, 799, 651, 801, 651, 802, - - 803, 805, 809, 810, 811, 813, 814, 819, 819, 819, - 820, 820, 820, 821, 822, 823, 823, 764, 763, 762, - 761, 760, 759, 756, 755, 754, 753, 752, 751, 750, - 749, 748, 747, 744, 743, 740, 739, 738, 737, 736, - 735, 733, 732, 731, 730, 729, 727, 725, 721, 720, - 719, 718, 717, 715, 714, 713, 712, 711, 710, 709, - 708, 707, 706, 705, 704, 703, 701, 700, 699, 698, - 697, 696, 695, 694, 693, 691, 690, 689, 688, 687, - 686, 685, 684, 683, 682, 681, 680, 679, 678, 677, - 676, 675, 674, 673, 672, 671, 670, 669, 668, 667, - - 666, 665, 664, 662, 661, 660, 659, 658, 657, 656, - 654, 653, 650, 648, 647, 646, 644, 643, 642, 641, - 640, 639, 638, 637, 636, 635, 634, 633, 632, 629, - 628, 627, 626, 625, 624, 622, 621, 620, 619, 617, - 616, 615, 614, 613, 612, 611, 610, 609, 608, 607, - 606, 605, 604, 599, 597, 596, 595, 594, 593, 589, - 588, 587, 586, 585, 584, 583, 582, 581, 579, 578, - 574, 573, 571, 570, 568, 567, 566, 565, 564, 563, - 562, 558, 557, 556, 554, 552, 551, 550, 549, 548, - 547, 546, 545, 544, 543, 541, 540, 535, 534, 533, - - 532, 530, 529, 527, 526, 525, 524, 523, 521, 520, - 518, 517, 516, 515, 514, 513, 512, 511, 509, 508, - 507, 506, 505, 501, 500, 499, 498, 497, 496, 493, - 492, 491, 490, 489, 488, 487, 486, 485, 484, 483, - 481, 480, 477, 472, 470, 469, 468, 466, 465, 462, - 461, 460, 459, 448, 447, 446, 444, 443, 442, 441, - 440, 437, 435, 434, 433, 431, 430, 429, 428, 426, - 424, 423, 418, 417, 415, 414, 413, 412, 411, 410, - 409, 408, 407, 406, 405, 403, 402, 401, 400, 399, - 398, 397, 395, 394, 393, 392, 391, 390, 389, 385, - - 381, 380, 379, 376, 374, 364, 362, 358, 357, 356, - 355, 353, 352, 350, 345, 344, 343, 342, 341, 340, - 335, 333, 332, 331, 330, 329, 327, 326, 323, 322, - 321, 320, 319, 318, 317, 316, 315, 314, 313, 312, - 311, 310, 309, 308, 307, 306, 305, 304, 303, 302, - 301, 300, 299, 298, 297, 294, 292, 291, 290, 289, - 288, 287, 286, 285, 283, 279, 277, 276, 275, 274, - 270, 269, 268, 267, 266, 265, 264, 263, 262, 258, - 256, 255, 254, 247, 246, 245, 244, 242, 241, 240, - 239, 238, 236, 235, 234, 233, 232, 231, 230, 229, - - 228, 227, 226, 225, 224, 223, 222, 221, 219, 218, - 217, 216, 215, 214, 213, 212, 211, 210, 209, 207, - 206, 205, 204, 203, 202, 201, 200, 199, 198, 197, - 196, 195, 194, 193, 192, 191, 189, 188, 187, 186, - 185, 184, 183, 182, 181, 180, 179, 178, 176, 175, - 174, 173, 171, 170, 169, 168, 167, 165, 150, 149, - 147, 146, 145, 141, 140, 139, 138, 137, 134, 133, - 132, 131, 129, 128, 126, 124, 123, 122, 120, 119, - 118, 116, 115, 113, 112, 111, 110, 109, 108, 105, - 104, 103, 102, 101, 100, 99, 98, 96, 95, 94, - - 93, 92, 91, 89, 88, 84, 80, 46, 44, 38, - 25, 22, 19, 14, 9, 5, 818, 818, 818, 818, - 818, 818, 818, 818, 818, 818, 818, 818, 818, 818, - 818, 818, 818, 818, 818, 818, 818, 818, 818, 818, - 818, 818, 818, 818, 818, 818, 818, 818, 818, 818, - 818, 818, 818, 818, 818, 818, 818, 818, 818, 818, - 818, 818, 818, 818, 818, 818, 818, 818, 818, 818, - 818, 818, 818, 818, 818, 818, 818, 818, 818, 818, - 818, 818, 818, 818, 818, 818, 818, 818, 818 + 39, 37, 45, 122, 37, 45, 126, 47, 39, 21, + 37, 122, 126, 768, 47, 47, 21, 48, 47, 39, + 48, 143, 143, 53, 47, 47, 21, 47, 48, 50, + 49, 70, 70, 50, 49, 48, 72, 72, 49, 144, + 21, 49, 50, 73, 73, 178, 178, 144, 70, 70, + 75, 769, 75, 72, 72, 75, 75, 75, 75, 75, + 75, 75, 108, 136, 98, 163, 128, 73, 98, 98, + + 73, 131, 137, 118, 770, 108, 118, 118, 136, 128, + 118, 128, 118, 145, 149, 137, 149, 131, 131, 163, + 155, 145, 155, 157, 157, 155, 155, 155, 155, 155, + 155, 155, 209, 209, 209, 773, 774, 158, 777, 158, + 157, 157, 158, 158, 158, 158, 158, 158, 158, 161, + 161, 161, 161, 161, 161, 161, 162, 162, 162, 162, + 162, 162, 162, 173, 221, 238, 778, 780, 221, 244, + 244, 244, 781, 238, 162, 782, 173, 249, 249, 249, + 249, 249, 249, 249, 250, 250, 250, 250, 250, 250, + 250, 162, 251, 251, 251, 251, 251, 251, 251, 260, + + 260, 260, 250, 252, 252, 252, 252, 252, 252, 252, + 272, 272, 272, 281, 281, 281, 285, 285, 285, 250, + 784, 252, 294, 294, 294, 335, 335, 335, 376, 376, + 376, 387, 387, 387, 388, 388, 388, 785, 252, 788, + 789, 376, 376, 389, 389, 389, 440, 440, 440, 483, + 483, 483, 790, 791, 503, 504, 520, 520, 520, 440, + 440, 603, 483, 483, 503, 504, 554, 554, 554, 520, + 520, 603, 520, 577, 577, 577, 631, 792, 793, 554, + 554, 604, 795, 631, 796, 631, 577, 577, 604, 652, + 604, 604, 797, 798, 799, 800, 652, 802, 652, 803, + + 804, 806, 810, 811, 812, 814, 815, 820, 820, 820, + 821, 821, 821, 822, 823, 824, 824, 765, 764, 763, + 762, 761, 760, 757, 756, 755, 754, 753, 752, 751, + 750, 749, 748, 745, 744, 741, 740, 739, 738, 737, + 736, 734, 733, 732, 731, 730, 728, 726, 722, 721, + 720, 719, 718, 716, 715, 714, 713, 712, 711, 710, + 709, 708, 707, 706, 705, 704, 702, 701, 700, 699, + 698, 697, 696, 695, 694, 692, 691, 690, 689, 688, + 687, 686, 685, 684, 683, 682, 681, 680, 679, 678, + 677, 676, 675, 674, 673, 672, 671, 670, 669, 668, + + 667, 666, 665, 663, 662, 661, 660, 659, 658, 657, + 655, 654, 651, 649, 648, 647, 645, 644, 643, 642, + 641, 640, 639, 638, 637, 636, 635, 634, 633, 630, + 629, 628, 627, 626, 625, 623, 622, 621, 620, 618, + 617, 616, 615, 614, 613, 612, 611, 610, 609, 608, + 607, 606, 605, 600, 598, 597, 596, 595, 594, 590, + 589, 588, 587, 586, 585, 584, 583, 582, 580, 579, + 575, 574, 572, 571, 569, 568, 567, 566, 565, 564, + 563, 559, 558, 557, 555, 553, 552, 551, 550, 549, + 548, 547, 546, 545, 544, 542, 541, 536, 535, 534, + + 533, 531, 530, 528, 527, 526, 525, 524, 522, 521, + 519, 518, 517, 516, 515, 514, 513, 512, 510, 509, + 508, 507, 506, 502, 501, 500, 499, 498, 497, 494, + 493, 492, 491, 490, 489, 488, 487, 486, 485, 484, + 482, 481, 478, 473, 471, 470, 469, 467, 466, 463, + 462, 461, 460, 449, 448, 447, 445, 444, 443, 442, + 441, 438, 436, 435, 434, 432, 431, 430, 429, 427, + 425, 424, 419, 418, 416, 415, 414, 413, 412, 411, + 410, 409, 408, 407, 406, 404, 403, 402, 401, 400, + 399, 398, 396, 395, 394, 393, 392, 391, 390, 386, + + 382, 381, 380, 377, 375, 365, 363, 359, 358, 357, + 356, 354, 353, 351, 346, 345, 344, 343, 342, 341, + 336, 334, 333, 332, 331, 330, 328, 327, 324, 323, + 322, 321, 320, 319, 318, 317, 316, 315, 314, 313, + 312, 311, 310, 309, 308, 307, 306, 305, 304, 303, + 302, 301, 300, 299, 298, 295, 293, 292, 291, 290, + 289, 288, 287, 286, 284, 280, 278, 277, 276, 275, + 271, 270, 269, 268, 267, 266, 265, 264, 263, 259, + 257, 256, 255, 248, 247, 246, 245, 243, 242, 241, + 240, 239, 237, 236, 235, 234, 233, 232, 231, 230, + + 229, 228, 227, 226, 225, 224, 223, 222, 220, 219, + 218, 217, 216, 215, 214, 213, 212, 211, 210, 208, + 207, 206, 205, 204, 203, 202, 201, 200, 199, 198, + 197, 196, 195, 194, 193, 192, 190, 189, 188, 187, + 186, 185, 184, 183, 182, 181, 180, 179, 177, 176, + 175, 174, 172, 171, 170, 169, 168, 166, 151, 150, + 148, 147, 146, 142, 141, 140, 139, 138, 135, 134, + 133, 132, 130, 129, 127, 125, 124, 123, 121, 120, + 119, 117, 116, 114, 113, 112, 111, 110, 109, 106, + 105, 104, 103, 102, 101, 100, 99, 97, 96, 95, + + 94, 93, 92, 90, 89, 85, 81, 46, 44, 38, + 25, 22, 19, 14, 9, 5, 819, 819, 819, 819, + 819, 819, 819, 819, 819, 819, 819, 819, 819, 819, + 819, 819, 819, 819, 819, 819, 819, 819, 819, 819, + 819, 819, 819, 819, 819, 819, 819, 819, 819, 819, + 819, 819, 819, 819, 819, 819, 819, 819, 819, 819, + 819, 819, 819, 819, 819, 819, 819, 819, 819, 819, + 819, 819, 819, 819, 819, 819, 819, 819, 819, 819, + 819, 819, 819, 819, 819, 819, 819, 819, 819 } ; /* Table of booleans, true if rule could match eol. */ -static yyconst flex_int32_t yy_rule_can_match_eol[240] = +static yyconst flex_int32_t yy_rule_can_match_eol[241] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -997,8 +997,8 @@ static yyconst flex_int32_t yy_rule_can_match_eol[240] = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 1, 0, + 0, }; /* The intent behind this definition is that it'll catch * any uses of REJECT which flex missed. @@ -1055,7 +1055,7 @@ static int ES2_reserved_ES3_keyword(TParseContext *context, int token); static int ES2_keyword_ES3_reserved(TParseContext *context, int token); static int ES2_ident_ES3_keyword(TParseContext *context, int token); static int uint_constant(TParseContext *context); -static int int_constant(yyscan_t yyscanner); +static int int_constant(TParseContext *context); static int float_constant(yyscan_t yyscanner); static int floatsuffix_check(TParseContext* context); @@ -1350,13 +1350,13 @@ YY_DECL while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 819 ) + if ( yy_current_state >= 820 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; ++yy_cp; } - while ( yy_current_state != 818 ); + while ( yy_current_state != 819 ); yy_cp = yyg->yy_last_accepting_cpos; yy_current_state = yyg->yy_last_accepting_state; @@ -1759,7 +1759,7 @@ case 133: case 134: YY_RULE_SETUP { - if (context->shaderVersion < 300) { + if (context->getShaderVersion() < 300) { yylval->lex.string = NewPoolTString(yytext); return check_type(yyscanner); } @@ -1770,7 +1770,7 @@ YY_RULE_SETUP case 135: YY_RULE_SETUP { - if (context->shaderVersion >= 300) + if (context->getShaderVersion() >= 300) { yylval->lex.string = NewPoolTString(yytext); return check_type(yyscanner); @@ -1833,15 +1833,15 @@ YY_RULE_SETUP YY_BREAK case 178: YY_RULE_SETUP -{ return int_constant(yyscanner); } +{ return int_constant(context); } YY_BREAK case 179: YY_RULE_SETUP -{ return int_constant(yyscanner); } +{ return int_constant(context); } YY_BREAK case 180: YY_RULE_SETUP -{ return int_constant(yyscanner); } +{ return int_constant(context); } YY_BREAK case 181: YY_RULE_SETUP @@ -2072,7 +2072,15 @@ YY_RULE_SETUP {} YY_BREAK case 237: -/* rule 237 can match eol */ +YY_RULE_SETUP +{ + yyextra->error(*yylloc, "Illegal character at fieldname start", yytext, ""); + yyextra->recover(); + return 0; +} + YY_BREAK +case 238: +/* rule 238 can match eol */ YY_RULE_SETUP { } YY_BREAK @@ -2080,11 +2088,11 @@ case YY_STATE_EOF(INITIAL): case YY_STATE_EOF(FIELDS): { yyterminate(); } YY_BREAK -case 238: +case 239: YY_RULE_SETUP { return 0; } YY_BREAK -case 239: +case 240: YY_RULE_SETUP ECHO; YY_BREAK @@ -2381,7 +2389,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner) while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 819 ) + if ( yy_current_state >= 820 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; @@ -2410,11 +2418,11 @@ static int yy_get_next_buffer (yyscan_t yyscanner) while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 819 ) + if ( yy_current_state >= 820 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - yy_is_jam = (yy_current_state == 818); + yy_is_jam = (yy_current_state == 819); (void)yyg; return yy_is_jam ? 0 : yy_current_state; @@ -3234,7 +3242,7 @@ void yyfree (void * ptr , yyscan_t yyscanner) yy_size_t string_input(char* buf, yy_size_t max_size, yyscan_t yyscanner) { pp::Token token; - yyget_extra(yyscanner)->preprocessor.lex(&token); + yyget_extra(yyscanner)->getPreprocessor().lex(&token); yy_size_t len = token.type == pp::Token::LAST ? 0 : token.text.size(); if (len < max_size) memcpy(buf, token.text.c_str(), len); @@ -3252,7 +3260,7 @@ int check_type(yyscan_t yyscanner) { struct yyguts_t* yyg = (struct yyguts_t*) yyscanner; int token = IDENTIFIER; - TSymbol* symbol = yyextra->symbolTable.find(yytext, yyextra->shaderVersion); + TSymbol* symbol = yyextra->symbolTable.find(yytext, yyextra->getShaderVersion()); if (symbol && symbol->isVariable()) { TVariable* variable = static_cast(symbol); if (variable->isUserType()) { @@ -3273,9 +3281,9 @@ int reserved_word(yyscan_t yyscanner) { int ES2_reserved_ES3_keyword(TParseContext *context, int token) { - yyscan_t yyscanner = (yyscan_t) context->scanner; + yyscan_t yyscanner = (yyscan_t) context->getScanner(); - if (context->shaderVersion < 300) + if (context->getShaderVersion() < 300) { return reserved_word(yyscanner); } @@ -3285,9 +3293,9 @@ int ES2_reserved_ES3_keyword(TParseContext *context, int token) int ES2_keyword_ES3_reserved(TParseContext *context, int token) { - yyscan_t yyscanner = (yyscan_t) context->scanner; + yyscan_t yyscanner = (yyscan_t) context->getScanner(); - if (context->shaderVersion >= 300) + if (context->getShaderVersion() >= 300) { return reserved_word(yyscanner); } @@ -3297,11 +3305,11 @@ int ES2_keyword_ES3_reserved(TParseContext *context, int token) int ES2_ident_ES3_keyword(TParseContext *context, int token) { - struct yyguts_t* yyg = (struct yyguts_t*) context->scanner; - yyscan_t yyscanner = (yyscan_t) context->scanner; + struct yyguts_t* yyg = (struct yyguts_t*) context->getScanner(); + yyscan_t yyscanner = (yyscan_t) context->getScanner(); // not a reserved word in GLSL ES 1.00, so could be used as an identifier/type name - if (context->shaderVersion < 300) + if (context->getShaderVersion() < 300) { yylval->lex.string = NewPoolTString(yytext); return check_type(yyscanner); @@ -3312,34 +3320,35 @@ int ES2_ident_ES3_keyword(TParseContext *context, int token) int uint_constant(TParseContext *context) { - struct yyguts_t* yyg = (struct yyguts_t*) context->scanner; - yyscan_t yyscanner = (yyscan_t) context->scanner; + struct yyguts_t* yyg = (struct yyguts_t*) context->getScanner(); - if (context->shaderVersion < 300) + if (context->getShaderVersion() < 300) { context->error(*yylloc, "Unsigned integers are unsupported prior to GLSL ES 3.00", yytext, ""); context->recover(); return 0; } - if (!atoi_clamp(yytext, &(yylval->lex.i))) - yyextra->warning(*yylloc, "Integer overflow", yytext, ""); + if (!atoi_clamp(yytext, &(yylval->lex.u))) + yyextra->error(*yylloc, "Integer overflow", yytext, ""); return UINTCONSTANT; } int floatsuffix_check(TParseContext* context) { - struct yyguts_t* yyg = (struct yyguts_t*) context->scanner; + struct yyguts_t* yyg = (struct yyguts_t*) context->getScanner(); - if (context->shaderVersion < 300) + if (context->getShaderVersion() < 300) { context->error(*yylloc, "Floating-point suffix unsupported prior to GLSL ES 3.00", yytext); context->recover(); return 0; } - if (!atof_clamp(yytext, &(yylval->lex.f))) + std::string text = yytext; + text.resize(text.size() - 1); + if (!strtof_clamp(text, &(yylval->lex.f))) yyextra->warning(*yylloc, "Float overflow", yytext, ""); return(FLOATCONSTANT); @@ -3350,18 +3359,25 @@ void yyerror(YYLTYPE* lloc, TParseContext* context, void *scanner, const char* r context->recover(); } -int int_constant(yyscan_t yyscanner) { - struct yyguts_t* yyg = (struct yyguts_t*) yyscanner; +int int_constant(TParseContext *context) { + struct yyguts_t* yyg = (struct yyguts_t*) context->getScanner(); - if (!atoi_clamp(yytext, &(yylval->lex.i))) - yyextra->warning(*yylloc, "Integer overflow", yytext, ""); + unsigned int u; + if (!atoi_clamp(yytext, &u)) + { + if (context->getShaderVersion() >= 300) + yyextra->error(*yylloc, "Integer overflow", yytext, ""); + else + yyextra->warning(*yylloc, "Integer overflow", yytext, ""); + } + yylval->lex.i = static_cast(u); return INTCONSTANT; } int float_constant(yyscan_t yyscanner) { struct yyguts_t* yyg = (struct yyguts_t*) yyscanner; - if (!atof_clamp(yytext, &(yylval->lex.f))) + if (!strtof_clamp(yytext, &(yylval->lex.f))) yyextra->warning(*yylloc, "Float overflow", yytext, ""); return FLOATCONSTANT; } @@ -3371,15 +3387,15 @@ int glslang_initialize(TParseContext* context) { if (yylex_init_extra(context,&scanner)) return 1; - context->scanner = scanner; + context->setScanner(scanner); return 0; } int glslang_finalize(TParseContext* context) { - yyscan_t scanner = context->scanner; + yyscan_t scanner = context->getScanner(); if (scanner == NULL) return 0; - context->scanner = NULL; + context->setScanner(NULL); yylex_destroy(scanner); return 0; @@ -3387,24 +3403,26 @@ int glslang_finalize(TParseContext* context) { int glslang_scan(size_t count, const char* const string[], const int length[], TParseContext* context) { - yyrestart(NULL,context->scanner); - yyset_column(0,context->scanner); - yyset_lineno(1,context->scanner); + yyrestart(NULL,context->getScanner()); + yyset_column(0,context->getScanner()); + yyset_lineno(1,context->getScanner()); // Initialize preprocessor. - if (!context->preprocessor.init(count, string, length)) + pp::Preprocessor *preprocessor = &context->getPreprocessor(); + + if (!preprocessor->init(count, string, length)) return 1; // Define extension macros. const TExtensionBehavior& extBehavior = context->extensionBehavior(); for (TExtensionBehavior::const_iterator iter = extBehavior.begin(); iter != extBehavior.end(); ++iter) { - context->preprocessor.predefineMacro(iter->first.c_str(), 1); + preprocessor->predefineMacro(iter->first.c_str(), 1); } - if (context->fragmentPrecisionHigh) - context->preprocessor.predefineMacro("GL_FRAGMENT_PRECISION_HIGH", 1); + if (context->getFragmentPrecisionHigh()) + preprocessor->predefineMacro("GL_FRAGMENT_PRECISION_HIGH", 1); - context->preprocessor.setMaxTokenSize(GetGlobalMaxTokenSize(context->shaderSpec)); + preprocessor->setMaxTokenSize(GetGlobalMaxTokenSize(context->getShaderSpec())); return 0; } diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/glslang_tab.cpp b/Source/ThirdParty/ANGLE/src/compiler/translator/glslang_tab.cpp index 6fb0d46071f6..a799d29e2599 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/glslang_tab.cpp +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/glslang_tab.cpp @@ -1,6 +1,6 @@ /* A Bison parser, made by GNU Bison 3.0.4. */ -/* Apple Note: For the avoidance of doubt, Apple elects to distribute this file under the terms of the BSD license. */ +/* Apple Note: For the avoidance of doubt, Apple elects to distribute this file under the terms of the BSD license. */ /* Bison implementation for Yacc-like parsers in C @@ -89,6 +89,7 @@ #endif #include "angle_gl.h" +#include "compiler/translator/Cache.h" #include "compiler/translator/SymbolTable.h" #include "compiler/translator/ParseContext.h" #include "GLSLANG/ShaderLang.h" @@ -356,28 +357,28 @@ extern void yyerror(YYLTYPE* yylloc, TParseContext* context, void *scanner, cons } while (0) #define VERTEX_ONLY(S, L) { \ - if (context->shaderType != GL_VERTEX_SHADER) { \ + if (context->getShaderType() != GL_VERTEX_SHADER) { \ context->error(L, " supported in vertex shaders only ", S); \ context->recover(); \ } \ } #define FRAG_ONLY(S, L) { \ - if (context->shaderType != GL_FRAGMENT_SHADER) { \ + if (context->getShaderType() != GL_FRAGMENT_SHADER) { \ context->error(L, " supported in fragment shaders only ", S); \ context->recover(); \ } \ } #define ES2_ONLY(S, L) { \ - if (context->shaderVersion != 100) { \ + if (context->getShaderVersion() != 100) { \ context->error(L, " supported in GLSL ES 1.00 only ", S); \ context->recover(); \ } \ } #define ES3_ONLY(TOKEN, LINE, REASON) { \ - if (context->shaderVersion != 300) { \ + if (context->getShaderVersion() != 300) { \ context->error(LINE, REASON " supported in GLSL ES 3.00 only ", TOKEN); \ context->recover(); \ } \ @@ -625,18 +626,18 @@ union yyalloc #endif /* !YYCOPY_NEEDED */ /* YYFINAL -- State number of the termination state. */ -#define YYFINAL 114 +#define YYFINAL 116 /* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 2523 +#define YYLAST 2516 /* YYNTOKENS -- Number of terminals. */ #define YYNTOKENS 128 /* YYNNTS -- Number of nonterminals. */ #define YYNNTS 94 /* YYNRULES -- Number of rules. */ -#define YYNRULES 273 +#define YYNRULES 275 /* YYNSTATES -- Number of states. */ -#define YYNSTATES 414 +#define YYNSTATES 417 /* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned by yylex, with out-of-bounds checking. */ @@ -695,34 +696,34 @@ static const yytype_uint8 yytranslate[] = /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ static const yytype_uint16 yyrline[] = { - 0, 211, 211, 212, 215, 239, 242, 247, 252, 257, - 262, 268, 271, 274, 277, 280, 283, 289, 297, 308, - 312, 320, 323, 329, 333, 340, 346, 355, 363, 369, - 376, 386, 389, 392, 395, 405, 406, 407, 408, 416, - 417, 420, 423, 430, 431, 434, 440, 441, 445, 452, - 453, 456, 459, 462, 468, 469, 472, 478, 479, 486, - 487, 494, 495, 502, 503, 509, 510, 516, 517, 523, - 524, 530, 531, 539, 540, 541, 542, 546, 547, 548, - 552, 556, 560, 564, 571, 574, 585, 593, 601, 629, - 635, 646, 650, 654, 658, 665, 721, 724, 731, 739, - 760, 781, 791, 819, 824, 834, 839, 849, 852, 855, - 858, 864, 871, 874, 878, 882, 887, 892, 899, 903, - 907, 911, 916, 921, 925, 932, 942, 948, 951, 957, - 963, 970, 979, 988, 996, 999, 1006, 1010, 1017, 1020, - 1024, 1028, 1037, 1046, 1054, 1064, 1076, 1079, 1082, 1088, - 1095, 1098, 1104, 1107, 1110, 1116, 1119, 1124, 1139, 1143, - 1147, 1151, 1155, 1159, 1164, 1169, 1174, 1179, 1184, 1189, - 1194, 1199, 1204, 1209, 1214, 1219, 1224, 1229, 1234, 1239, - 1244, 1249, 1254, 1259, 1264, 1268, 1272, 1276, 1280, 1284, - 1288, 1292, 1296, 1300, 1304, 1308, 1312, 1316, 1320, 1324, - 1332, 1340, 1344, 1357, 1357, 1360, 1360, 1366, 1369, 1385, - 1388, 1397, 1401, 1407, 1414, 1429, 1433, 1437, 1438, 1444, - 1445, 1446, 1447, 1448, 1449, 1450, 1454, 1455, 1455, 1455, - 1465, 1466, 1470, 1470, 1471, 1471, 1476, 1479, 1489, 1492, - 1498, 1499, 1503, 1511, 1515, 1522, 1522, 1529, 1532, 1539, - 1544, 1559, 1559, 1564, 1564, 1571, 1571, 1579, 1582, 1588, - 1591, 1597, 1601, 1608, 1611, 1614, 1617, 1620, 1629, 1633, - 1640, 1643, 1649, 1649 + 0, 212, 212, 213, 216, 226, 229, 234, 239, 244, + 249, 255, 258, 261, 264, 267, 270, 276, 284, 295, + 299, 307, 310, 316, 320, 327, 333, 342, 350, 356, + 363, 373, 376, 379, 382, 392, 393, 394, 395, 403, + 404, 407, 410, 417, 418, 421, 427, 428, 432, 439, + 440, 443, 446, 449, 455, 456, 459, 465, 466, 473, + 474, 481, 482, 489, 490, 496, 497, 503, 504, 510, + 511, 517, 518, 526, 527, 528, 529, 533, 534, 535, + 539, 543, 547, 551, 558, 561, 567, 575, 583, 586, + 592, 603, 607, 611, 615, 622, 628, 631, 638, 646, + 667, 694, 704, 732, 737, 747, 752, 762, 765, 768, + 771, 777, 784, 787, 791, 795, 800, 805, 812, 816, + 820, 824, 829, 834, 838, 845, 855, 861, 864, 870, + 876, 883, 892, 902, 910, 913, 920, 924, 928, 933, + 941, 944, 948, 952, 961, 970, 978, 988, 1000, 1003, + 1006, 1012, 1019, 1022, 1028, 1031, 1034, 1040, 1043, 1048, + 1063, 1067, 1071, 1075, 1079, 1083, 1088, 1093, 1098, 1103, + 1108, 1113, 1118, 1123, 1128, 1133, 1138, 1143, 1148, 1153, + 1158, 1163, 1168, 1173, 1178, 1183, 1188, 1192, 1196, 1200, + 1204, 1208, 1212, 1216, 1220, 1224, 1228, 1232, 1236, 1240, + 1244, 1248, 1256, 1264, 1268, 1281, 1281, 1284, 1284, 1290, + 1293, 1309, 1312, 1321, 1325, 1331, 1338, 1353, 1357, 1361, + 1362, 1368, 1369, 1370, 1371, 1372, 1373, 1374, 1378, 1379, + 1379, 1379, 1389, 1390, 1394, 1394, 1395, 1395, 1400, 1403, + 1413, 1416, 1422, 1423, 1427, 1435, 1439, 1446, 1446, 1453, + 1456, 1463, 1468, 1483, 1483, 1488, 1488, 1495, 1495, 1503, + 1506, 1512, 1515, 1521, 1525, 1532, 1535, 1538, 1541, 1544, + 1553, 1557, 1564, 1567, 1573, 1573 }; #endif @@ -811,12 +812,12 @@ static const yytype_uint16 yytoknum[] = }; # endif -#define YYPACT_NINF -347 +#define YYPACT_NINF -361 #define yypact_value_is_default(Yystate) \ - (!!((Yystate) == (-347))) + (!!((Yystate) == (-361))) -#define YYTABLE_NINF -233 +#define YYTABLE_NINF -235 #define yytable_value_is_error(Yytable_value) \ 0 @@ -825,48 +826,48 @@ static const yytype_uint16 yytoknum[] = STATE-NUM. */ static const yytype_int16 yypact[] = { - 2161, -4, -347, -347, -347, 142, -347, -347, -347, -347, - -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, - -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, - -347, -347, -347, -347, -347, -347, -347, -3, -347, -347, - -58, -347, -347, -347, -347, -347, -347, -347, -347, -347, - -347, -347, -347, -347, -347, -347, -347, -347, -347, -57, - -347, -347, -38, -63, -55, 3, -50, -347, 84, 11, - 1180, -347, -347, 2446, 11, -347, -40, -347, 2086, -347, - -347, -347, -347, 2446, -347, -347, -347, -347, -347, -23, - 31, -347, 35, -347, 78, -347, -347, -347, -347, -347, - 2310, 132, 106, -347, 7, -27, -347, 60, -347, 2236, - -347, -347, -347, 1250, -347, -347, -33, 2236, -347, 17, - -72, -347, 408, -347, -347, -347, -347, 106, 2310, -24, - -347, 1348, 1639, -347, 79, 2310, 106, 1831, -347, 71, - -347, -347, -347, -347, -347, 1639, 1639, 1639, -347, -347, - -347, -347, -347, -347, -347, 19, -347, -347, -347, 73, - -21, 1734, 89, -347, 1639, 66, 72, 108, -64, 50, - 81, 74, 87, 114, 123, -62, -347, 110, -347, -347, - 1916, 2236, 116, -347, 31, 104, 105, -347, 117, 118, - 109, 1446, 120, 1639, 113, 122, 111, -347, -347, 56, - -347, -347, -13, -347, -38, 125, -347, -347, -347, -347, - 524, -347, -347, -347, -347, -347, -347, 124, -347, -347, - 1541, 1639, 119, 127, -347, -347, 106, 129, -8, -347, - -66, -347, -347, -347, -9, -347, -347, 1639, 2378, -347, - -347, 1639, 131, -347, -347, -347, 1639, 1639, 1639, 1639, - 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, - 1639, 1639, 1639, 1639, 1639, 1639, -347, -347, 2001, -347, - -347, -347, -347, -347, 133, -347, 1639, -347, -347, 20, - 1639, 128, -347, -347, -347, 640, -347, -347, -347, -347, - -347, -347, -347, -347, -347, -347, -347, 1639, 1639, -347, - -347, -347, 1639, 126, 135, -347, 1639, 130, 22, 1639, - 106, -347, -78, -347, -347, 138, 136, -347, 145, -347, - -347, -347, -347, -347, 66, 66, 72, 72, 108, 108, - 108, 108, -64, -64, 50, 81, 74, 87, 114, 123, - 86, -347, 190, 35, 872, 988, 5, -347, 10, -347, - 1085, 640, -347, -347, 143, 1639, 139, -347, 1639, -347, - 144, -347, 1639, -347, -347, 1639, 149, -347, -347, -347, - -347, 1085, 133, -347, 136, 106, 2310, 152, 150, -347, - -347, 1639, -347, -347, 151, -347, 1639, -347, 146, 157, - 246, -347, 156, 154, 756, -347, -347, 155, 21, 1639, - 756, 133, -347, 1639, -347, -347, -347, -347, 158, 136, - -347, -347, -347, -347 + 2154, 224, -361, -361, -361, 130, -361, -361, -361, -361, + -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, + -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, + -361, -361, -361, -361, -361, -361, -361, 145, -361, -361, + -46, -361, -361, -361, -361, -361, -361, -361, -361, -361, + -361, -361, -361, -361, -361, -361, -361, -361, -361, -82, + -361, -361, -68, -41, -45, 9, 7, -361, 117, 16, + 1173, -361, -361, 2439, 16, -361, -9, -361, 2079, -361, + -361, -361, -361, 16, -361, 2439, -361, -361, -361, -361, + -361, -31, 23, -361, 11, -361, 63, -361, -361, -361, + -361, -361, 2303, 168, 120, -361, 13, -66, -361, 31, + -361, 2229, -361, -361, -361, 1243, -361, -361, -361, 56, + 2229, -361, 17, -50, -361, 401, -361, -361, -361, -361, + 120, 2303, -18, -361, 1341, 1632, -361, 179, 2303, 120, + 1824, -361, 70, -361, -361, -361, -361, -361, 1632, 1632, + 1632, -361, -361, -361, -361, -361, -361, -361, 22, -361, + -361, -361, 101, -29, 1727, 114, -361, 1632, 96, -97, + 128, -54, 111, 118, 102, 115, 154, 153, -69, -361, + 140, -361, -361, 1909, 2229, 124, -361, 23, 134, 136, + -361, 147, 149, 143, 1439, 155, 1632, 148, 157, 160, + -361, -361, 184, -361, -361, 52, -361, -68, 158, -361, + -361, -361, -361, 517, -361, -361, -361, -361, -361, -361, + 166, -361, -361, 1534, 1632, 150, 159, -361, -361, 120, + 167, 61, -361, -62, -361, -361, -361, -5, -361, -361, + 1632, 2371, -361, -361, 1632, 185, -361, -361, -361, 1632, + 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, + 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, -361, + -361, 1994, -361, -361, -361, -361, -361, 181, -361, 1632, + -361, -361, 67, 1632, 180, -361, -361, -361, 633, -361, + -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, + 1632, 1632, -361, -361, -361, 1632, 178, 186, -361, 1632, + 182, 68, 1632, 120, -361, -71, -361, -361, 187, 188, + -361, 192, -361, -361, -361, -361, -361, 96, 96, -97, + -97, 128, 128, 128, 128, -54, -54, 111, 118, 102, + 115, 154, 153, 113, -361, 242, 11, 865, 981, 4, + -361, 18, -361, 1078, 633, -361, -361, 194, 1632, 189, + -361, 1632, -361, 196, -361, 1632, -361, -361, 1632, 200, + -361, -361, -361, -361, 1078, 181, -361, 188, 120, 2303, + 201, 198, -361, -361, 1632, -361, -361, 202, -361, 1632, + -361, 191, 203, 293, -361, 204, 205, 749, -361, -361, + 197, 60, 1632, 749, 181, -361, 1632, -361, -361, -361, + -361, 199, 188, -361, -361, -361, -361 }; /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM. @@ -874,78 +875,78 @@ static const yytype_int16 yypact[] = means the default is an error. */ static const yytype_uint16 yydefact[] = { - 0, 0, 146, 147, 148, 0, 130, 138, 162, 159, - 160, 161, 166, 167, 168, 169, 170, 171, 163, 164, - 165, 172, 173, 174, 175, 176, 177, 139, 140, 143, - 131, 178, 179, 180, 181, 182, 183, 0, 128, 127, - 0, 158, 184, 186, 199, 200, 187, 188, 189, 190, - 191, 192, 193, 194, 195, 185, 196, 197, 198, 0, - 202, 271, 272, 0, 97, 107, 0, 112, 118, 135, - 0, 133, 125, 0, 136, 144, 155, 201, 0, 268, - 270, 132, 124, 0, 141, 142, 2, 3, 205, 0, - 0, 88, 0, 95, 107, 129, 108, 109, 110, 98, - 0, 107, 0, 89, 2, 119, 134, 0, 94, 0, - 126, 145, 137, 0, 1, 269, 0, 0, 203, 152, - 0, 150, 0, 273, 99, 104, 106, 111, 0, 113, - 100, 0, 0, 87, 0, 0, 0, 0, 207, 4, - 8, 6, 7, 9, 30, 0, 0, 0, 156, 37, - 36, 38, 35, 5, 11, 31, 13, 18, 19, 0, - 0, 24, 0, 39, 0, 43, 46, 49, 54, 57, - 59, 61, 63, 65, 67, 69, 86, 0, 28, 90, - 0, 0, 0, 149, 0, 0, 0, 253, 0, 0, - 0, 0, 0, 0, 0, 0, 227, 236, 240, 39, - 71, 84, 0, 216, 0, 144, 219, 238, 218, 217, - 0, 220, 221, 222, 223, 224, 225, 101, 103, 105, - 0, 0, 0, 0, 215, 123, 0, 213, 0, 211, - 0, 208, 32, 33, 0, 15, 16, 0, 0, 22, - 21, 0, 158, 25, 27, 34, 0, 0, 0, 0, + 0, 0, 148, 149, 150, 0, 130, 140, 164, 161, + 162, 163, 168, 169, 170, 171, 172, 173, 165, 166, + 167, 174, 175, 176, 177, 178, 179, 141, 142, 145, + 131, 180, 181, 182, 183, 184, 185, 0, 128, 127, + 0, 160, 186, 188, 201, 202, 189, 190, 191, 192, + 193, 194, 195, 196, 197, 187, 198, 199, 200, 0, + 204, 273, 274, 0, 97, 107, 0, 112, 118, 135, + 0, 133, 125, 0, 136, 146, 157, 203, 0, 270, + 272, 132, 124, 0, 138, 0, 143, 144, 2, 3, + 207, 0, 0, 88, 0, 95, 107, 129, 108, 109, + 110, 98, 0, 107, 0, 89, 2, 119, 134, 0, + 94, 0, 126, 147, 137, 0, 1, 271, 139, 0, + 0, 205, 154, 0, 152, 0, 275, 99, 104, 106, + 111, 0, 113, 100, 0, 0, 87, 0, 0, 0, + 0, 209, 4, 8, 6, 7, 9, 30, 0, 0, + 0, 158, 37, 36, 38, 35, 5, 11, 31, 13, + 18, 19, 0, 0, 24, 0, 39, 0, 43, 46, + 49, 54, 57, 59, 61, 63, 65, 67, 69, 86, + 0, 28, 90, 0, 0, 0, 151, 0, 0, 0, + 255, 0, 0, 0, 0, 0, 0, 0, 0, 229, + 238, 242, 39, 71, 84, 0, 218, 0, 146, 221, + 240, 220, 219, 0, 222, 223, 224, 225, 226, 227, + 101, 103, 105, 0, 0, 0, 0, 217, 123, 0, + 215, 0, 213, 0, 210, 32, 33, 0, 15, 16, + 0, 0, 22, 21, 0, 160, 25, 27, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 157, 206, 0, 153, - 154, 151, 264, 263, 234, 255, 0, 267, 265, 0, - 0, 0, 248, 251, 226, 0, 74, 75, 77, 76, - 79, 80, 81, 82, 83, 78, 73, 0, 0, 241, - 237, 239, 0, 0, 0, 117, 0, 120, 0, 0, - 0, 209, 0, 91, 10, 0, 17, 29, 14, 20, - 26, 40, 41, 42, 45, 44, 47, 48, 52, 53, - 50, 51, 55, 56, 58, 60, 62, 64, 66, 68, - 0, 204, 0, 0, 0, 0, 0, 266, 0, 247, - 0, 228, 72, 85, 0, 0, 114, 121, 0, 210, - 0, 212, 0, 92, 12, 0, 0, 233, 235, 258, - 257, 260, 234, 245, 249, 0, 0, 0, 0, 102, - 115, 0, 122, 214, 0, 70, 0, 259, 0, 0, - 244, 242, 0, 0, 0, 229, 116, 0, 0, 261, - 0, 234, 246, 0, 231, 252, 230, 93, 0, 262, - 256, 243, 250, 254 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 159, + 208, 0, 155, 156, 153, 266, 265, 236, 257, 0, + 269, 267, 0, 0, 0, 250, 253, 228, 0, 74, + 75, 77, 76, 79, 80, 81, 82, 83, 78, 73, + 0, 0, 243, 239, 241, 0, 0, 0, 117, 0, + 120, 0, 0, 0, 211, 0, 91, 10, 0, 17, + 29, 14, 20, 26, 40, 41, 42, 45, 44, 47, + 48, 52, 53, 50, 51, 55, 56, 58, 60, 62, + 64, 66, 68, 0, 206, 0, 0, 0, 0, 0, + 268, 0, 249, 0, 230, 72, 85, 0, 0, 114, + 121, 0, 212, 0, 214, 0, 92, 12, 0, 0, + 235, 237, 260, 259, 262, 236, 247, 251, 0, 0, + 0, 0, 102, 115, 0, 122, 216, 0, 70, 0, + 261, 0, 0, 246, 244, 0, 0, 0, 231, 116, + 0, 0, 263, 0, 236, 248, 0, 233, 254, 232, + 93, 0, 264, 258, 245, 252, 256 }; /* YYPGOTO[NTERM-NUM]. */ static const yytype_int16 yypgoto[] = { - -347, -39, -347, -347, -347, -347, -347, -347, 32, -347, - -347, -347, -347, 63, -347, -48, -37, -90, -54, 12, - 14, 16, 18, 23, 9, -347, -96, -127, -347, -138, - -125, -347, 13, 15, -347, -347, -347, 147, 184, 178, - 153, -347, -347, -325, -347, -347, -106, -47, -68, 277, - -347, -347, 100, 0, -347, -347, -347, -347, -101, -123, - 61, -22, -214, -56, -202, -323, -102, -347, -347, -109, - -346, -347, -347, -88, 8, -53, -347, -347, -347, -347, - -347, -77, -347, -347, -347, -347, -347, -347, -347, -347, - -347, 217, -347, -347 + -361, -39, -361, -361, -361, -361, -361, -361, 73, -361, + -361, -361, -361, -107, -361, -15, -20, -67, -19, 53, + 54, 55, 51, 57, 58, -361, -110, -132, -361, -146, + -125, -361, 6, 12, -361, -361, -361, 190, 228, 217, + 195, -361, -361, -336, 25, -361, -104, 27, -57, 322, + -361, -361, 141, 0, -361, -361, -361, -361, -109, -130, + 100, 19, -185, -17, -193, -310, -65, -361, -361, -70, + -360, -361, -361, -92, 46, -13, -361, -361, -361, -361, + -361, -38, -361, -361, -361, -361, -361, -361, -361, -361, + -361, 259, -361, -361 }; /* YYDEFGOTO[NTERM-NUM]. */ static const yytype_int16 yydefgoto[] = { - -1, 227, 153, 154, 155, 315, 156, 157, 158, 159, - 160, 161, 162, 199, 164, 165, 166, 167, 168, 169, - 170, 171, 172, 173, 174, 175, 200, 201, 297, 202, - 177, 109, 203, 204, 63, 64, 65, 125, 99, 100, - 126, 66, 67, 68, 69, 101, 70, 71, 72, 73, - 74, 120, 121, 178, 76, 77, 181, 117, 137, 138, - 228, 229, 225, 206, 207, 208, 209, 285, 378, 405, - 342, 343, 344, 406, 210, 211, 212, 391, 213, 392, - 214, 377, 215, 350, 274, 345, 371, 388, 389, 216, - 78, 79, 80, 92 + -1, 230, 156, 157, 158, 318, 159, 160, 161, 162, + 163, 164, 165, 202, 167, 168, 169, 170, 171, 172, + 173, 174, 175, 176, 177, 178, 203, 204, 300, 205, + 180, 111, 206, 207, 63, 64, 65, 128, 101, 102, + 129, 66, 67, 68, 69, 103, 70, 71, 72, 73, + 74, 123, 124, 181, 76, 77, 184, 120, 140, 141, + 231, 232, 228, 209, 210, 211, 212, 288, 381, 408, + 345, 346, 347, 409, 213, 214, 215, 394, 216, 395, + 217, 380, 218, 353, 277, 348, 374, 391, 392, 219, + 78, 79, 80, 94 }; /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If @@ -953,420 +954,399 @@ static const yytype_int16 yydefgoto[] = number is the opposite. If YYTABLE_NINF, syntax error. */ static const yytype_int16 yytable[] = { - 75, 89, 110, 135, 123, 224, 223, 305, 301, 234, - 312, 135, 95, 61, 231, 62, 180, 176, 86, 87, - 7, 368, 106, 253, 254, 375, 390, 112, 362, 105, - 264, 135, 127, 183, 243, 176, 363, 84, 85, 184, - 81, 136, 93, 96, 97, 98, 375, 90, 313, 136, - 88, 27, 28, 279, 29, 411, 94, 231, 255, 256, - 127, 102, 37, 129, 103, 265, 113, 226, 281, 136, - 75, 404, 82, 111, 135, 135, 91, 404, 75, 131, - 268, 179, 220, 116, 240, 118, 132, 95, 217, 221, - 241, 61, 357, 62, 224, 304, 314, 176, 298, 316, - 75, 299, 298, 310, 235, 236, 311, 119, -96, 75, - 372, 130, 136, 136, 320, 373, 298, 75, 96, 97, - 98, 298, 205, 81, 176, 237, 408, 340, 75, 238, - 182, 298, 298, 310, 347, 75, 359, 75, 346, 257, - 258, 380, 348, 122, 382, 231, 2, 3, 4, 301, - 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, - 104, 87, 135, 328, 329, 330, 331, 396, 133, 296, - 352, 353, 96, 97, 98, -29, 163, 354, 239, 224, - 75, 75, 86, 87, 360, 246, 247, 248, 249, 412, - 250, 251, 252, 244, 163, 269, 270, 298, 365, 260, - 136, 324, 325, 332, 333, 262, 176, 259, 232, 233, - 205, 261, 374, 176, 326, 327, 263, 266, 272, 273, - 284, 275, 276, 277, 280, 282, 283, 245, 224, -28, - 302, 224, 306, 374, 307, 309, -23, 384, 385, 355, - 349, -232, 356, 358, 376, 364, 366, 298, 398, -30, - 379, 383, 381, 386, 224, 367, 163, 394, 397, 395, - 399, 409, 400, 401, 196, 376, 176, 403, 75, 407, - 319, 334, 413, 339, 335, 218, 224, 336, 124, 128, - 337, 219, 83, 163, 271, 205, 338, 308, 361, 369, - 402, 410, 370, 351, 387, 115, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 110, 321, - 322, 323, 163, 163, 163, 163, 163, 163, 163, 163, - 163, 163, 163, 163, 163, 163, 163, 163, 0, 0, - 0, 0, 0, 0, 0, 0, 393, 0, 0, 0, - 0, 0, 0, 0, 205, 205, 0, 0, 0, 0, - 205, 205, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 163, 0, 0, 0, 0, - 0, 205, 163, 0, 0, 0, 75, 0, 0, 0, + 75, 91, 126, 227, 237, 179, 61, 138, 166, 226, + 234, 183, 62, 112, 315, 393, 138, 378, 97, 252, + 304, 253, 92, 267, 179, 7, 83, 166, 84, 107, + 88, 89, 246, 256, 257, 365, 138, 371, 378, 308, + 134, 235, 236, 366, 414, 130, 93, 135, 282, 98, + 99, 100, 316, 234, 139, 186, 27, 28, 268, 29, + 248, 187, 90, 139, 95, 132, 96, 37, 258, 259, + 75, 284, 97, 113, 130, 271, 243, 121, 75, 138, + 138, 229, 244, 139, 61, 119, 179, 407, 223, 166, + 62, 220, 227, 407, 319, 224, 108, 115, 307, 122, + 317, 114, 75, 98, 99, 100, 301, 238, 239, 375, + 118, 75, 323, 179, -96, 301, 166, 133, 104, 125, + 75, 105, 343, 376, 360, 208, 139, 139, 240, 301, + 185, 75, 241, 349, 2, 3, 4, 351, 75, 136, + 75, 234, 324, 325, 326, 166, 166, 166, 166, 166, + 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, + 166, 304, 83, 301, 84, 411, 302, 138, 355, 356, + 182, 301, 313, 383, -29, 314, 385, 227, 301, 313, + 357, 350, 362, 75, 75, 86, 87, 363, 7, 331, + 332, 333, 334, 106, 89, 179, 88, 89, 166, 399, + 260, 261, 179, 272, 273, 166, 242, 377, 98, 99, + 100, 254, 255, 208, 139, 249, 250, 251, 247, 27, + 28, 415, 29, 81, 301, 368, 227, 263, 377, 227, + 37, 38, 39, 7, 329, 330, 388, 327, 328, 264, + 387, 335, 336, 401, 262, 265, 266, 269, 275, 379, + 276, 278, 227, 279, 370, 179, 412, 280, 166, 283, + 285, 286, -28, 309, 27, 28, 310, 29, 81, 287, + 379, 75, 305, 312, 227, 37, 38, 39, 289, 290, + 291, 292, 293, 294, 295, 296, 297, 298, 208, -234, + -23, 358, 352, 359, 367, 361, -30, 299, 369, 301, + 82, 382, 384, 386, 389, 402, 397, 398, 403, 400, + 404, 410, 199, 416, 322, 337, 340, 338, 406, 339, + 131, 221, 112, 341, 127, 342, 222, 85, 274, 311, + 405, 372, 364, 413, 354, 373, 390, 117, 0, 396, + 0, 0, 0, 0, 0, 0, 0, 208, 208, 0, + 0, 0, 0, 208, 208, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 205, 0, 0, 0, 0, 0, - 205, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, - 10, 11, 185, 186, 187, 163, 188, 189, 190, 191, - 192, 193, 194, 12, 13, 14, 15, 16, 17, 18, - 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, - 0, 29, 30, 31, 32, 33, 34, 35, 36, 37, - 38, 39, 40, 41, 195, 42, 43, 44, 45, 46, - 47, 48, 49, 50, 51, 52, 53, 54, 55, 0, - 56, 57, 58, 59, 139, 60, 140, 141, 142, 143, - 144, 0, 0, 145, 146, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 208, 0, 0, 0, 0, 75, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 147, 0, 0, 0, 196, 197, 0, 0, - 0, 0, 198, 149, 150, 151, 152, 1, 2, 3, - 4, 5, 6, 7, 8, 9, 10, 11, 185, 186, - 187, 0, 188, 189, 190, 191, 192, 193, 194, 12, - 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, - 23, 24, 25, 26, 27, 28, 0, 29, 30, 31, - 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, - 195, 42, 43, 44, 45, 46, 47, 48, 49, 50, - 51, 52, 53, 54, 55, 0, 56, 57, 58, 59, - 139, 60, 140, 141, 142, 143, 144, 0, 0, 145, - 146, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 147, 0, - 0, 0, 196, 300, 0, 0, 0, 0, 198, 149, - 150, 151, 152, 1, 2, 3, 4, 5, 6, 7, - 8, 9, 10, 11, 185, 186, 187, 0, 188, 189, - 190, 191, 192, 193, 194, 12, 13, 14, 15, 16, - 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, - 27, 28, 0, 29, 30, 31, 32, 33, 34, 35, - 36, 37, 38, 39, 40, 41, 195, 42, 43, 44, - 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, - 55, 0, 56, 57, 58, 59, 139, 60, 140, 141, - 142, 143, 144, 0, 0, 145, 146, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 208, 0, 0, + 0, 0, 0, 208, 1, 2, 3, 4, 5, 6, + 7, 8, 9, 10, 11, 188, 189, 190, 0, 191, + 192, 193, 194, 195, 196, 197, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, + 26, 27, 28, 0, 29, 30, 31, 32, 33, 34, + 35, 36, 37, 38, 39, 40, 41, 198, 42, 43, + 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, + 54, 55, 0, 56, 57, 58, 59, 142, 60, 143, + 144, 145, 146, 147, 0, 0, 148, 149, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 147, 0, 0, 0, 196, 0, - 0, 0, 0, 0, 198, 149, 150, 151, 152, 1, - 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, - 185, 186, 187, 0, 188, 189, 190, 191, 192, 193, - 194, 12, 13, 14, 15, 16, 17, 18, 19, 20, - 21, 22, 23, 24, 25, 26, 27, 28, 0, 29, - 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, - 40, 41, 195, 42, 43, 44, 45, 46, 47, 48, - 49, 50, 51, 52, 53, 54, 55, 0, 56, 57, - 58, 59, 139, 60, 140, 141, 142, 143, 144, 0, - 0, 145, 146, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 150, 0, 0, 0, 199, + 200, 0, 0, 0, 0, 201, 152, 153, 154, 155, + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, + 11, 188, 189, 190, 0, 191, 192, 193, 194, 195, + 196, 197, 12, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 23, 24, 25, 26, 27, 28, 0, + 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, + 39, 40, 41, 198, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, 0, 56, + 57, 58, 59, 142, 60, 143, 144, 145, 146, 147, + 0, 0, 148, 149, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 147, 0, 0, 0, 122, 0, 0, 0, 0, 0, - 198, 149, 150, 151, 152, 1, 2, 3, 4, 5, - 6, 7, 8, 9, 10, 11, 185, 186, 187, 0, - 188, 189, 190, 191, 192, 193, 194, 12, 13, 14, - 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, - 25, 26, 27, 28, 0, 29, 30, 31, 32, 33, - 34, 35, 36, 37, 38, 39, 40, 41, 195, 42, - 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, - 53, 54, 55, 0, 56, 57, 58, 59, 139, 60, - 140, 141, 142, 143, 144, 0, 0, 145, 146, 0, + 0, 150, 0, 0, 0, 199, 303, 0, 0, 0, + 0, 201, 152, 153, 154, 155, 1, 2, 3, 4, + 5, 6, 7, 8, 9, 10, 11, 188, 189, 190, + 0, 191, 192, 193, 194, 195, 196, 197, 12, 13, + 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, + 24, 25, 26, 27, 28, 0, 29, 30, 31, 32, + 33, 34, 35, 36, 37, 38, 39, 40, 41, 198, + 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, + 52, 53, 54, 55, 0, 56, 57, 58, 59, 142, + 60, 143, 144, 145, 146, 147, 0, 0, 148, 149, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 147, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 198, 149, 150, 151, - 152, 1, 2, 3, 4, 5, 6, 7, 8, 9, - 10, 11, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 12, 13, 14, 15, 16, 17, 18, - 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, - 0, 29, 30, 31, 32, 33, 34, 35, 36, 37, - 38, 39, 40, 41, 0, 42, 43, 44, 45, 46, - 47, 48, 49, 50, 51, 52, 53, 54, 55, 0, - 56, 57, 58, 59, 139, 60, 140, 141, 142, 143, - 144, 0, 0, 145, 146, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 134, 2, - 3, 4, 147, 6, 7, 8, 9, 10, 11, 0, - 0, 0, 198, 149, 150, 151, 152, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 150, 0, 0, + 0, 199, 0, 0, 0, 0, 0, 201, 152, 153, + 154, 155, 1, 2, 3, 4, 5, 6, 7, 8, + 9, 10, 11, 188, 189, 190, 0, 191, 192, 193, + 194, 195, 196, 197, 12, 13, 14, 15, 16, 17, + 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, + 28, 0, 29, 30, 31, 32, 33, 34, 35, 36, + 37, 38, 39, 40, 41, 198, 42, 43, 44, 45, + 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, + 0, 56, 57, 58, 59, 142, 60, 143, 144, 145, + 146, 147, 0, 0, 148, 149, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 150, 0, 0, 0, 125, 0, 0, + 0, 0, 0, 201, 152, 153, 154, 155, 1, 2, + 3, 4, 5, 6, 7, 8, 9, 10, 11, 188, + 189, 190, 0, 191, 192, 193, 194, 195, 196, 197, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 0, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, - 41, 0, 42, 43, 44, 45, 46, 47, 48, 49, + 41, 198, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 0, 56, 57, 58, - 59, 139, 60, 140, 141, 142, 143, 144, 0, 0, - 145, 146, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 2, 3, 4, 0, 0, 147, - 8, 9, 10, 11, 0, 0, 0, 0, 0, 0, - 149, 150, 151, 152, 0, 12, 13, 14, 15, 16, - 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, - 0, 0, 0, 0, 0, 31, 32, 33, 34, 35, - 36, 0, 0, 0, 40, 41, 0, 42, 43, 44, - 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, - 55, 0, 56, 57, 58, 0, 107, 60, 0, 0, - 8, 9, 10, 11, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 12, 13, 14, 15, 16, - 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, - 0, 0, 0, 0, 108, 31, 32, 33, 34, 35, - 36, 0, 0, 0, 40, 41, 0, 42, 43, 44, - 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, - 55, 0, 56, 57, 58, 0, 139, 60, 140, 141, - 142, 143, 144, 0, 0, 145, 146, 0, 0, 0, + 59, 142, 60, 143, 144, 145, 146, 147, 0, 0, + 148, 149, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 150, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 201, + 152, 153, 154, 155, 1, 2, 3, 4, 5, 6, + 7, 8, 9, 10, 11, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, + 26, 27, 28, 0, 29, 30, 31, 32, 33, 34, + 35, 36, 37, 38, 39, 40, 41, 0, 42, 43, + 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, + 54, 55, 0, 56, 57, 58, 59, 142, 60, 143, + 144, 145, 146, 147, 0, 0, 148, 149, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 147, 0, 0, 148, 8, 9, - 10, 11, 0, 0, 0, 149, 150, 151, 152, 0, + 0, 137, 2, 3, 4, 150, 6, 7, 8, 9, + 10, 11, 0, 0, 0, 201, 152, 153, 154, 155, 0, 0, 0, 12, 13, 14, 15, 16, 17, 18, - 19, 20, 21, 22, 23, 24, 25, 26, 0, 0, - 0, 0, 0, 31, 32, 33, 34, 35, 36, 0, - 0, 0, 40, 41, 0, 42, 43, 44, 45, 46, + 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, + 0, 29, 30, 31, 32, 33, 34, 35, 36, 37, + 38, 39, 40, 41, 0, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 0, - 56, 57, 58, 0, 139, 60, 140, 141, 142, 143, - 144, 0, 0, 145, 146, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 147, 0, 0, 222, 8, 9, 10, 11, - 0, 0, 0, 149, 150, 151, 152, 0, 0, 0, - 0, 12, 13, 14, 15, 16, 17, 18, 19, 20, - 21, 22, 23, 24, 25, 26, 0, 0, 0, 0, - 0, 31, 32, 33, 34, 35, 36, 0, 0, 0, - 40, 41, 0, 42, 43, 44, 45, 46, 47, 48, - 49, 50, 51, 52, 53, 54, 55, 0, 56, 57, - 58, 0, 139, 60, 140, 141, 142, 143, 144, 0, - 0, 145, 146, 0, 0, 0, 0, 0, 0, 0, + 56, 57, 58, 59, 142, 60, 143, 144, 145, 146, + 147, 0, 0, 148, 149, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 2, 3, 4, + 0, 0, 150, 8, 9, 10, 11, 0, 0, 0, + 0, 0, 0, 152, 153, 154, 155, 0, 12, 13, + 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, + 24, 25, 26, 0, 0, 0, 0, 0, 31, 32, + 33, 34, 35, 36, 0, 0, 0, 40, 41, 0, + 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, + 52, 53, 54, 55, 0, 56, 57, 58, 0, 109, + 60, 0, 0, 8, 9, 10, 11, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 12, 13, + 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, + 24, 25, 26, 0, 0, 0, 0, 110, 31, 32, + 33, 34, 35, 36, 0, 0, 0, 40, 41, 0, + 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, + 52, 53, 54, 55, 0, 56, 57, 58, 0, 142, + 60, 143, 144, 145, 146, 147, 0, 0, 148, 149, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 147, 8, 9, 10, 11, 0, 0, 0, 0, 0, - 278, 149, 150, 151, 152, 0, 12, 13, 14, 15, + 0, 0, 0, 0, 0, 0, 0, 150, 0, 0, + 151, 8, 9, 10, 11, 0, 0, 0, 152, 153, + 154, 155, 0, 0, 0, 0, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 0, 0, 0, 0, 0, 31, 32, 33, 34, 35, 36, 0, 0, 0, 40, 41, 0, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, - 54, 55, 0, 56, 57, 58, 0, 139, 60, 140, - 141, 142, 143, 144, 0, 0, 145, 146, 0, 0, + 54, 55, 0, 56, 57, 58, 0, 142, 60, 143, + 144, 145, 146, 147, 0, 0, 148, 149, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 147, 0, 0, 303, 8, - 9, 10, 11, 0, 0, 0, 149, 150, 151, 152, + 0, 0, 0, 0, 0, 150, 0, 0, 225, 8, + 9, 10, 11, 0, 0, 0, 152, 153, 154, 155, 0, 0, 0, 0, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 0, 0, 0, 0, 0, 31, 32, 33, 34, 35, 36, 0, 0, 0, 40, 41, 0, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, - 0, 56, 57, 58, 0, 139, 60, 140, 141, 142, - 143, 144, 0, 0, 145, 146, 0, 0, 0, 0, + 0, 56, 57, 58, 0, 142, 60, 143, 144, 145, + 146, 147, 0, 0, 148, 149, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 147, 8, 9, 10, 11, 0, 0, - 0, 0, 0, 0, 149, 150, 151, 152, 0, 12, + 0, 0, 0, 150, 8, 9, 10, 11, 0, 0, + 0, 0, 0, 281, 152, 153, 154, 155, 0, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 0, 0, 0, 0, 0, 31, - 32, 33, 34, 35, 36, 0, 0, 0, 40, 242, + 32, 33, 34, 35, 36, 0, 0, 0, 40, 41, 0, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 0, 56, 57, 58, 0, - 139, 60, 140, 141, 142, 143, 144, 0, 0, 145, - 146, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 134, 2, 3, 4, 147, 6, - 7, 8, 9, 10, 11, 0, 0, 0, 0, 149, - 150, 151, 152, 0, 0, 0, 12, 13, 14, 15, - 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, - 26, 27, 28, 0, 29, 30, 31, 32, 33, 34, - 35, 36, 37, 38, 39, 40, 41, 0, 42, 43, - 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, - 54, 55, 0, 56, 57, 58, 59, 0, 60, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 134, - 2, 3, 4, 0, 6, 7, 8, 9, 10, 11, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 230, 12, 13, 14, 15, 16, 17, 18, 19, 20, - 21, 22, 23, 24, 25, 26, 27, 28, 0, 29, - 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, - 40, 41, 0, 42, 43, 44, 45, 46, 47, 48, - 49, 50, 51, 52, 53, 54, 55, 0, 56, 57, - 58, 59, 0, 60, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 134, 2, 3, 4, 0, 6, - 7, 8, 9, 10, 11, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 267, 12, 13, 14, 15, - 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, - 26, 27, 28, 0, 29, 30, 31, 32, 33, 34, - 35, 36, 37, 38, 39, 40, 41, 0, 42, 43, - 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, - 54, 55, 0, 56, 57, 58, 59, 0, 60, 0, - 0, 0, 0, 0, 0, 0, 114, 0, 0, 1, - 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, + 142, 60, 143, 144, 145, 146, 147, 0, 0, 148, + 149, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 150, 0, + 0, 306, 8, 9, 10, 11, 0, 0, 0, 152, + 153, 154, 155, 0, 0, 0, 0, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 0, 0, 0, 0, 0, 31, 32, 33, + 34, 35, 36, 0, 0, 0, 40, 41, 0, 42, + 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, + 53, 54, 55, 0, 56, 57, 58, 0, 142, 60, + 143, 144, 145, 146, 147, 0, 0, 148, 149, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 341, 12, 13, 14, 15, 16, 17, 18, 19, 20, - 21, 22, 23, 24, 25, 26, 27, 28, 0, 29, - 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, - 40, 41, 0, 42, 43, 44, 45, 46, 47, 48, - 49, 50, 51, 52, 53, 54, 55, 0, 56, 57, - 58, 59, 0, 60, 1, 2, 3, 4, 5, 6, - 7, 8, 9, 10, 11, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 150, 8, 9, 10, + 11, 0, 0, 0, 0, 0, 0, 152, 153, 154, + 155, 0, 12, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 23, 24, 25, 26, 0, 0, 0, + 0, 0, 31, 32, 33, 34, 35, 36, 0, 0, + 0, 40, 245, 0, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, 0, 56, + 57, 58, 0, 142, 60, 143, 144, 145, 146, 147, + 0, 0, 148, 149, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 137, 2, 3, + 4, 150, 6, 7, 8, 9, 10, 11, 0, 0, + 0, 0, 152, 153, 154, 155, 0, 0, 0, 12, + 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, + 23, 24, 25, 26, 27, 28, 0, 29, 30, 31, + 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, + 0, 42, 43, 44, 45, 46, 47, 48, 49, 50, + 51, 52, 53, 54, 55, 0, 56, 57, 58, 59, + 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 137, 2, 3, 4, 0, 6, 7, 8, + 9, 10, 11, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 233, 12, 13, 14, 15, 16, 17, + 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, + 28, 0, 29, 30, 31, 32, 33, 34, 35, 36, + 37, 38, 39, 40, 41, 0, 42, 43, 44, 45, + 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, + 0, 56, 57, 58, 59, 0, 60, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 137, 2, 3, + 4, 0, 6, 7, 8, 9, 10, 11, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 270, 12, + 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, + 23, 24, 25, 26, 27, 28, 0, 29, 30, 31, + 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, + 0, 42, 43, 44, 45, 46, 47, 48, 49, 50, + 51, 52, 53, 54, 55, 0, 56, 57, 58, 59, + 0, 60, 0, 0, 0, 0, 0, 0, 0, 116, + 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, + 9, 10, 11, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 344, 12, 13, 14, 15, 16, 17, + 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, + 28, 0, 29, 30, 31, 32, 33, 34, 35, 36, + 37, 38, 39, 40, 41, 0, 42, 43, 44, 45, + 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, + 0, 56, 57, 58, 59, 0, 60, 1, 2, 3, + 4, 5, 6, 7, 8, 9, 10, 11, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, + 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, + 23, 24, 25, 26, 27, 28, 0, 29, 30, 31, + 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, + 0, 42, 43, 44, 45, 46, 47, 48, 49, 50, + 51, 52, 53, 54, 55, 0, 56, 57, 58, 59, + 0, 60, 137, 2, 3, 4, 0, 6, 7, 8, + 9, 10, 11, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 12, 13, 14, 15, 16, 17, + 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, + 28, 0, 29, 30, 31, 32, 33, 34, 35, 36, + 37, 38, 39, 40, 41, 0, 42, 43, 44, 45, + 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, + 0, 56, 57, 58, 59, 0, 60, 2, 3, 4, + 0, 0, 0, 8, 9, 10, 11, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 12, 13, + 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, + 24, 25, 26, 0, 0, 0, 0, 0, 31, 32, + 33, 34, 35, 36, 0, 0, 0, 40, 41, 0, + 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, + 52, 53, 54, 55, 0, 56, 57, 58, 0, 0, + 60, 8, 9, 10, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, - 26, 27, 28, 0, 29, 30, 31, 32, 33, 34, - 35, 36, 37, 38, 39, 40, 41, 0, 42, 43, + 26, 0, 0, 0, 0, 0, 31, 32, 33, 34, + 35, 36, 0, 0, 0, 40, 41, 0, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, - 54, 55, 0, 56, 57, 58, 59, 0, 60, 134, - 2, 3, 4, 0, 6, 7, 8, 9, 10, 11, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 12, 13, 14, 15, 16, 17, 18, 19, 20, - 21, 22, 23, 24, 25, 26, 27, 28, 0, 29, - 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, - 40, 41, 0, 42, 43, 44, 45, 46, 47, 48, - 49, 50, 51, 52, 53, 54, 55, 0, 56, 57, - 58, 59, 0, 60, 2, 3, 4, 0, 0, 0, - 8, 9, 10, 11, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 12, 13, 14, 15, 16, - 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, - 0, 0, 0, 0, 0, 31, 32, 33, 34, 35, - 36, 0, 0, 0, 40, 41, 0, 42, 43, 44, - 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, - 55, 0, 56, 57, 58, 0, 0, 60, 8, 9, - 10, 11, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 12, 13, 14, 15, 16, 17, 18, - 19, 20, 21, 22, 23, 24, 25, 26, 0, 0, - 0, 0, 0, 31, 32, 33, 34, 35, 36, 0, - 0, 0, 40, 41, 0, 42, 43, 44, 45, 46, - 47, 48, 49, 50, 51, 52, 53, 54, 55, 0, - 56, 57, 58, 0, 317, 60, 8, 9, 10, 11, - 318, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 12, 13, 14, 15, 16, 17, 18, 19, 20, - 21, 22, 23, 24, 25, 26, 0, 0, 0, 0, - 0, 31, 32, 33, 34, 35, 36, 0, 0, 0, - 40, 41, 0, 42, 43, 44, 45, 46, 47, 48, - 49, 50, 51, 52, 53, 54, 55, 0, 56, 57, - 58, 0, 0, 60 + 54, 55, 0, 56, 57, 58, 0, 320, 60, 8, + 9, 10, 11, 321, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 12, 13, 14, 15, 16, 17, + 18, 19, 20, 21, 22, 23, 24, 25, 26, 0, + 0, 0, 0, 0, 31, 32, 33, 34, 35, 36, + 0, 0, 0, 40, 41, 0, 42, 43, 44, 45, + 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, + 0, 56, 57, 58, 0, 0, 60 }; static const yytype_int16 yycheck[] = { - 0, 40, 70, 109, 92, 132, 131, 221, 210, 147, - 76, 117, 9, 0, 137, 0, 117, 113, 76, 77, - 9, 344, 69, 87, 88, 350, 372, 74, 106, 68, - 92, 137, 100, 105, 161, 131, 114, 40, 41, 111, - 44, 109, 105, 40, 41, 42, 371, 104, 114, 117, - 108, 40, 41, 191, 43, 401, 111, 180, 122, 123, - 128, 111, 51, 102, 114, 127, 106, 135, 193, 137, - 70, 394, 76, 73, 180, 181, 114, 400, 78, 106, - 181, 114, 106, 83, 105, 108, 113, 9, 127, 113, - 111, 78, 306, 78, 221, 220, 105, 193, 111, 237, - 100, 114, 111, 111, 85, 86, 114, 76, 105, 109, - 105, 104, 180, 181, 241, 105, 111, 117, 40, 41, - 42, 111, 122, 44, 220, 106, 105, 265, 128, 110, - 113, 111, 111, 111, 114, 135, 114, 137, 276, 89, - 90, 355, 280, 108, 358, 268, 4, 5, 6, 351, - 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, - 76, 77, 268, 253, 254, 255, 256, 381, 108, 113, - 297, 298, 40, 41, 42, 104, 113, 302, 105, 306, - 180, 181, 76, 77, 309, 119, 120, 121, 116, 403, - 118, 83, 84, 104, 131, 79, 80, 111, 112, 125, - 268, 249, 250, 257, 258, 91, 302, 126, 145, 146, - 210, 124, 350, 309, 251, 252, 93, 107, 114, 114, - 109, 104, 104, 114, 104, 112, 104, 164, 355, 104, - 106, 358, 113, 371, 107, 106, 105, 362, 365, 113, - 112, 108, 107, 113, 350, 107, 56, 111, 386, 104, - 107, 107, 113, 104, 381, 343, 193, 105, 107, 109, - 114, 399, 105, 17, 108, 371, 362, 113, 268, 114, - 238, 259, 114, 264, 260, 128, 403, 261, 94, 101, - 262, 128, 5, 220, 184, 285, 263, 226, 310, 345, - 392, 400, 345, 285, 371, 78, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 376, 246, - 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, - 257, 258, 259, 260, 261, 262, 263, 264, -1, -1, - -1, -1, -1, -1, -1, -1, 375, -1, -1, -1, - -1, -1, -1, -1, 344, 345, -1, -1, -1, -1, - 350, 351, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 302, -1, -1, -1, -1, - -1, 371, 309, -1, -1, -1, 376, -1, -1, -1, + 0, 40, 94, 135, 150, 115, 0, 111, 115, 134, + 140, 120, 0, 70, 76, 375, 120, 353, 9, 116, + 213, 118, 104, 92, 134, 9, 1, 134, 1, 68, + 76, 77, 164, 87, 88, 106, 140, 347, 374, 224, + 106, 148, 149, 114, 404, 102, 114, 113, 194, 40, + 41, 42, 114, 183, 111, 105, 40, 41, 127, 43, + 167, 111, 108, 120, 105, 104, 111, 51, 122, 123, + 70, 196, 9, 73, 131, 184, 105, 108, 78, 183, + 184, 138, 111, 140, 78, 85, 196, 397, 106, 196, + 78, 130, 224, 403, 240, 113, 69, 106, 223, 76, + 105, 74, 102, 40, 41, 42, 111, 85, 86, 105, + 83, 111, 244, 223, 105, 111, 223, 104, 111, 108, + 120, 114, 268, 105, 309, 125, 183, 184, 106, 111, + 113, 131, 110, 279, 4, 5, 6, 283, 138, 108, + 140, 271, 249, 250, 251, 252, 253, 254, 255, 256, + 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, + 267, 354, 137, 111, 137, 105, 114, 271, 300, 301, + 114, 111, 111, 358, 104, 114, 361, 309, 111, 111, + 305, 114, 114, 183, 184, 40, 41, 312, 9, 256, + 257, 258, 259, 76, 77, 305, 76, 77, 305, 384, + 89, 90, 312, 79, 80, 312, 105, 353, 40, 41, + 42, 83, 84, 213, 271, 119, 120, 121, 104, 40, + 41, 406, 43, 44, 111, 112, 358, 125, 374, 361, + 51, 52, 53, 9, 254, 255, 368, 252, 253, 124, + 365, 260, 261, 389, 126, 91, 93, 107, 114, 353, + 114, 104, 384, 104, 346, 365, 402, 114, 365, 104, + 112, 104, 104, 113, 40, 41, 107, 43, 44, 109, + 374, 271, 106, 106, 406, 51, 52, 53, 94, 95, + 96, 97, 98, 99, 100, 101, 102, 103, 288, 108, + 105, 113, 112, 107, 107, 113, 104, 113, 56, 111, + 76, 107, 113, 107, 104, 114, 105, 109, 105, 107, + 17, 114, 108, 114, 241, 262, 265, 263, 113, 264, + 103, 131, 379, 266, 96, 267, 131, 5, 187, 229, + 395, 348, 313, 403, 288, 348, 374, 78, -1, 378, + -1, -1, -1, -1, -1, -1, -1, 347, 348, -1, + -1, -1, -1, 353, 354, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 394, -1, -1, -1, -1, -1, - 400, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 3, 4, 5, 6, 7, 8, 9, 10, 11, - 12, 13, 14, 15, 16, 362, 18, 19, 20, 21, - 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, - 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, - -1, 43, 44, 45, 46, 47, 48, 49, 50, 51, - 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, - 62, 63, 64, 65, 66, 67, 68, 69, 70, -1, - 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, - 82, -1, -1, 85, 86, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 374, -1, -1, -1, -1, 379, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 104, -1, -1, -1, 108, 109, -1, -1, - -1, -1, 114, 115, 116, 117, 118, 3, 4, 5, - 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, - 16, -1, 18, 19, 20, 21, 22, 23, 24, 25, - 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, - 36, 37, 38, 39, 40, 41, -1, 43, 44, 45, - 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, - 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, - 66, 67, 68, 69, 70, -1, 72, 73, 74, 75, - 76, 77, 78, 79, 80, 81, 82, -1, -1, 85, - 86, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 104, -1, - -1, -1, 108, 109, -1, -1, -1, -1, 114, 115, - 116, 117, 118, 3, 4, 5, 6, 7, 8, 9, - 10, 11, 12, 13, 14, 15, 16, -1, 18, 19, - 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, - 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, - 40, 41, -1, 43, 44, 45, 46, 47, 48, 49, - 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, - 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, - 70, -1, 72, 73, 74, 75, 76, 77, 78, 79, - 80, 81, 82, -1, -1, 85, 86, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 397, -1, -1, + -1, -1, -1, 403, 3, 4, 5, 6, 7, 8, + 9, 10, 11, 12, 13, 14, 15, 16, -1, 18, + 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, + 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, + 39, 40, 41, -1, 43, 44, 45, 46, 47, 48, + 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, + 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, + 69, 70, -1, 72, 73, 74, 75, 76, 77, 78, + 79, 80, 81, 82, -1, -1, 85, 86, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 104, -1, -1, -1, 108, -1, - -1, -1, -1, -1, 114, 115, 116, 117, 118, 3, - 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, - 14, 15, 16, -1, 18, 19, 20, 21, 22, 23, - 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, - 34, 35, 36, 37, 38, 39, 40, 41, -1, 43, - 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, - 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, - 64, 65, 66, 67, 68, 69, 70, -1, 72, 73, - 74, 75, 76, 77, 78, 79, 80, 81, 82, -1, - -1, 85, 86, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 104, -1, -1, -1, 108, + 109, -1, -1, -1, -1, 114, 115, 116, 117, 118, + 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, + 13, 14, 15, 16, -1, 18, 19, 20, 21, 22, + 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, + 33, 34, 35, 36, 37, 38, 39, 40, 41, -1, + 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, + 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, + 63, 64, 65, 66, 67, 68, 69, 70, -1, 72, + 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, + -1, -1, 85, 86, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 104, -1, -1, -1, 108, -1, -1, -1, -1, -1, - 114, 115, 116, 117, 118, 3, 4, 5, 6, 7, - 8, 9, 10, 11, 12, 13, 14, 15, 16, -1, - 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, - 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, - 38, 39, 40, 41, -1, 43, 44, 45, 46, 47, - 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, - 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, - 68, 69, 70, -1, 72, 73, 74, 75, 76, 77, - 78, 79, 80, 81, 82, -1, -1, 85, 86, -1, + -1, 104, -1, -1, -1, 108, 109, -1, -1, -1, + -1, 114, 115, 116, 117, 118, 3, 4, 5, 6, + 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, + -1, 18, 19, 20, 21, 22, 23, 24, 25, 26, + 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, + 37, 38, 39, 40, 41, -1, 43, 44, 45, 46, + 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, + 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, + 67, 68, 69, 70, -1, 72, 73, 74, 75, 76, + 77, 78, 79, 80, 81, 82, -1, -1, 85, 86, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 104, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 114, 115, 116, 117, - 118, 3, 4, 5, 6, 7, 8, 9, 10, 11, - 12, 13, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 25, 26, 27, 28, 29, 30, 31, - 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, - -1, 43, 44, 45, 46, 47, 48, 49, 50, 51, - 52, 53, 54, 55, -1, 57, 58, 59, 60, 61, - 62, 63, 64, 65, 66, 67, 68, 69, 70, -1, - 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, - 82, -1, -1, 85, 86, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 3, 4, - 5, 6, 104, 8, 9, 10, 11, 12, 13, -1, - -1, -1, 114, 115, 116, 117, 118, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 104, -1, -1, + -1, 108, -1, -1, -1, -1, -1, 114, 115, 116, + 117, 118, 3, 4, 5, 6, 7, 8, 9, 10, + 11, 12, 13, 14, 15, 16, -1, 18, 19, 20, + 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, + 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, + 41, -1, 43, 44, 45, 46, 47, 48, 49, 50, + 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, + 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, + -1, 72, 73, 74, 75, 76, 77, 78, 79, 80, + 81, 82, -1, -1, 85, 86, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 104, -1, -1, -1, 108, -1, -1, + -1, -1, -1, 114, 115, 116, 117, 118, 3, 4, + 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, -1, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, -1, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, - 55, -1, 57, 58, 59, 60, 61, 62, 63, 64, + 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, -1, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, -1, -1, 85, 86, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 4, 5, 6, -1, -1, 104, - 10, 11, 12, 13, -1, -1, -1, -1, -1, -1, - 115, 116, 117, 118, -1, 25, 26, 27, 28, 29, - 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, - -1, -1, -1, -1, -1, 45, 46, 47, 48, 49, - 50, -1, -1, -1, 54, 55, -1, 57, 58, 59, - 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, - 70, -1, 72, 73, 74, -1, 76, 77, -1, -1, - 10, 11, 12, 13, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 25, 26, 27, 28, 29, - 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, - -1, -1, -1, -1, 114, 45, 46, 47, 48, 49, - 50, -1, -1, -1, 54, 55, -1, 57, 58, 59, - 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, - 70, -1, 72, 73, 74, -1, 76, 77, 78, 79, - 80, 81, 82, -1, -1, 85, 86, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 104, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 114, + 115, 116, 117, 118, 3, 4, 5, 6, 7, 8, + 9, 10, 11, 12, 13, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 25, 26, 27, 28, + 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, + 39, 40, 41, -1, 43, 44, 45, 46, 47, 48, + 49, 50, 51, 52, 53, 54, 55, -1, 57, 58, + 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, + 69, 70, -1, 72, 73, 74, 75, 76, 77, 78, + 79, 80, 81, 82, -1, -1, 85, 86, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 104, -1, -1, 107, 10, 11, - 12, 13, -1, -1, -1, 115, 116, 117, 118, -1, + -1, 3, 4, 5, 6, 104, 8, 9, 10, 11, + 12, 13, -1, -1, -1, 114, 115, 116, 117, 118, -1, -1, -1, 25, 26, 27, 28, 29, 30, 31, - 32, 33, 34, 35, 36, 37, 38, 39, -1, -1, - -1, -1, -1, 45, 46, 47, 48, 49, 50, -1, - -1, -1, 54, 55, -1, 57, 58, 59, 60, 61, + 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, + -1, 43, 44, 45, 46, 47, 48, 49, 50, 51, + 52, 53, 54, 55, -1, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, -1, - 72, 73, 74, -1, 76, 77, 78, 79, 80, 81, + 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, -1, -1, 85, 86, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 4, 5, 6, + -1, -1, 104, 10, 11, 12, 13, -1, -1, -1, + -1, -1, -1, 115, 116, 117, 118, -1, 25, 26, + 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, + 37, 38, 39, -1, -1, -1, -1, -1, 45, 46, + 47, 48, 49, 50, -1, -1, -1, 54, 55, -1, + 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, + 67, 68, 69, 70, -1, 72, 73, 74, -1, 76, + 77, -1, -1, 10, 11, 12, 13, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 25, 26, + 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, + 37, 38, 39, -1, -1, -1, -1, 114, 45, 46, + 47, 48, 49, 50, -1, -1, -1, 54, 55, -1, + 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, + 67, 68, 69, 70, -1, 72, 73, 74, -1, 76, + 77, 78, 79, 80, 81, 82, -1, -1, 85, 86, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 104, -1, -1, 107, 10, 11, 12, 13, - -1, -1, -1, 115, 116, 117, 118, -1, -1, -1, - -1, 25, 26, 27, 28, 29, 30, 31, 32, 33, - 34, 35, 36, 37, 38, 39, -1, -1, -1, -1, - -1, 45, 46, 47, 48, 49, 50, -1, -1, -1, - 54, 55, -1, 57, 58, 59, 60, 61, 62, 63, - 64, 65, 66, 67, 68, 69, 70, -1, 72, 73, - 74, -1, 76, 77, 78, 79, 80, 81, 82, -1, - -1, 85, 86, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 104, 10, 11, 12, 13, -1, -1, -1, -1, -1, - 114, 115, 116, 117, 118, -1, 25, 26, 27, 28, + -1, -1, -1, -1, -1, -1, -1, 104, -1, -1, + 107, 10, 11, 12, 13, -1, -1, -1, 115, 116, + 117, 118, -1, -1, -1, -1, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, -1, -1, -1, -1, -1, 45, 46, 47, 48, 49, 50, -1, -1, -1, 54, 55, -1, 57, 58, @@ -1385,7 +1365,7 @@ static const yytype_int16 yycheck[] = 81, 82, -1, -1, 85, 86, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 104, 10, 11, 12, 13, -1, -1, - -1, -1, -1, -1, 115, 116, 117, 118, -1, 25, + -1, -1, -1, 114, 115, 116, 117, 118, -1, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, -1, -1, -1, -1, -1, 45, 46, 47, 48, 49, 50, -1, -1, -1, 54, 55, @@ -1393,76 +1373,95 @@ static const yytype_int16 yycheck[] = 66, 67, 68, 69, 70, -1, 72, 73, 74, -1, 76, 77, 78, 79, 80, 81, 82, -1, -1, 85, 86, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 3, 4, 5, 6, 104, 8, - 9, 10, 11, 12, 13, -1, -1, -1, -1, 115, - 116, 117, 118, -1, -1, -1, 25, 26, 27, 28, - 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, - 39, 40, 41, -1, 43, 44, 45, 46, 47, 48, - 49, 50, 51, 52, 53, 54, 55, -1, 57, 58, - 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, - 69, 70, -1, 72, 73, 74, 75, -1, 77, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 3, - 4, 5, 6, -1, 8, 9, 10, 11, 12, 13, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 109, 25, 26, 27, 28, 29, 30, 31, 32, 33, - 34, 35, 36, 37, 38, 39, 40, 41, -1, 43, - 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, - 54, 55, -1, 57, 58, 59, 60, 61, 62, 63, - 64, 65, 66, 67, 68, 69, 70, -1, 72, 73, - 74, 75, -1, 77, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 3, 4, 5, 6, -1, 8, - 9, 10, 11, 12, 13, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 109, 25, 26, 27, 28, - 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, - 39, 40, 41, -1, 43, 44, 45, 46, 47, 48, - 49, 50, 51, 52, 53, 54, 55, -1, 57, 58, - 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, - 69, 70, -1, 72, 73, 74, 75, -1, 77, -1, - -1, -1, -1, -1, -1, -1, 0, -1, -1, 3, - 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, + -1, -1, -1, -1, -1, -1, -1, -1, 104, -1, + -1, 107, 10, 11, 12, 13, -1, -1, -1, 115, + 116, 117, 118, -1, -1, -1, -1, 25, 26, 27, + 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, + 38, 39, -1, -1, -1, -1, -1, 45, 46, 47, + 48, 49, 50, -1, -1, -1, 54, 55, -1, 57, + 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, + 68, 69, 70, -1, 72, 73, 74, -1, 76, 77, + 78, 79, 80, 81, 82, -1, -1, 85, 86, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 109, 25, 26, 27, 28, 29, 30, 31, 32, 33, - 34, 35, 36, 37, 38, 39, 40, 41, -1, 43, - 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, - 54, 55, -1, 57, 58, 59, 60, 61, 62, 63, - 64, 65, 66, 67, 68, 69, 70, -1, 72, 73, - 74, 75, -1, 77, 3, 4, 5, 6, 7, 8, - 9, 10, 11, 12, 13, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 104, 10, 11, 12, + 13, -1, -1, -1, -1, -1, -1, 115, 116, 117, + 118, -1, 25, 26, 27, 28, 29, 30, 31, 32, + 33, 34, 35, 36, 37, 38, 39, -1, -1, -1, + -1, -1, 45, 46, 47, 48, 49, 50, -1, -1, + -1, 54, 55, -1, 57, 58, 59, 60, 61, 62, + 63, 64, 65, 66, 67, 68, 69, 70, -1, 72, + 73, 74, -1, 76, 77, 78, 79, 80, 81, 82, + -1, -1, 85, 86, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 3, 4, 5, + 6, 104, 8, 9, 10, 11, 12, 13, -1, -1, + -1, -1, 115, 116, 117, 118, -1, -1, -1, 25, + 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, + 36, 37, 38, 39, 40, 41, -1, 43, 44, 45, + 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, + -1, 57, 58, 59, 60, 61, 62, 63, 64, 65, + 66, 67, 68, 69, 70, -1, 72, 73, 74, 75, + -1, 77, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 3, 4, 5, 6, -1, 8, 9, 10, + 11, 12, 13, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 109, 25, 26, 27, 28, 29, 30, + 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, + 41, -1, 43, 44, 45, 46, 47, 48, 49, 50, + 51, 52, 53, 54, 55, -1, 57, 58, 59, 60, + 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, + -1, 72, 73, 74, 75, -1, 77, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 3, 4, 5, + 6, -1, 8, 9, 10, 11, 12, 13, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 109, 25, + 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, + 36, 37, 38, 39, 40, 41, -1, 43, 44, 45, + 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, + -1, 57, 58, 59, 60, 61, 62, 63, 64, 65, + 66, 67, 68, 69, 70, -1, 72, 73, 74, 75, + -1, 77, -1, -1, -1, -1, -1, -1, -1, 0, + -1, -1, 3, 4, 5, 6, 7, 8, 9, 10, + 11, 12, 13, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 109, 25, 26, 27, 28, 29, 30, + 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, + 41, -1, 43, 44, 45, 46, 47, 48, 49, 50, + 51, 52, 53, 54, 55, -1, 57, 58, 59, 60, + 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, + -1, 72, 73, 74, 75, -1, 77, 3, 4, 5, + 6, 7, 8, 9, 10, 11, 12, 13, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 25, + 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, + 36, 37, 38, 39, 40, 41, -1, 43, 44, 45, + 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, + -1, 57, 58, 59, 60, 61, 62, 63, 64, 65, + 66, 67, 68, 69, 70, -1, 72, 73, 74, 75, + -1, 77, 3, 4, 5, 6, -1, 8, 9, 10, + 11, 12, 13, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 25, 26, 27, 28, 29, 30, + 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, + 41, -1, 43, 44, 45, 46, 47, 48, 49, 50, + 51, 52, 53, 54, 55, -1, 57, 58, 59, 60, + 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, + -1, 72, 73, 74, 75, -1, 77, 4, 5, 6, + -1, -1, -1, 10, 11, 12, 13, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 25, 26, + 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, + 37, 38, 39, -1, -1, -1, -1, -1, 45, 46, + 47, 48, 49, 50, -1, -1, -1, 54, 55, -1, + 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, + 67, 68, 69, 70, -1, 72, 73, 74, -1, -1, + 77, 10, 11, 12, 13, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, - 39, 40, 41, -1, 43, 44, 45, 46, 47, 48, - 49, 50, 51, 52, 53, 54, 55, -1, 57, 58, + 39, -1, -1, -1, -1, -1, 45, 46, 47, 48, + 49, 50, -1, -1, -1, 54, 55, -1, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, - 69, 70, -1, 72, 73, 74, 75, -1, 77, 3, - 4, 5, 6, -1, 8, 9, 10, 11, 12, 13, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 25, 26, 27, 28, 29, 30, 31, 32, 33, - 34, 35, 36, 37, 38, 39, 40, 41, -1, 43, - 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, - 54, 55, -1, 57, 58, 59, 60, 61, 62, 63, - 64, 65, 66, 67, 68, 69, 70, -1, 72, 73, - 74, 75, -1, 77, 4, 5, 6, -1, -1, -1, - 10, 11, 12, 13, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 25, 26, 27, 28, 29, - 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, - -1, -1, -1, -1, -1, 45, 46, 47, 48, 49, - 50, -1, -1, -1, 54, 55, -1, 57, 58, 59, - 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, - 70, -1, 72, 73, 74, -1, -1, 77, 10, 11, - 12, 13, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 25, 26, 27, 28, 29, 30, 31, - 32, 33, 34, 35, 36, 37, 38, 39, -1, -1, - -1, -1, -1, 45, 46, 47, 48, 49, 50, -1, - -1, -1, 54, 55, -1, 57, 58, 59, 60, 61, - 62, 63, 64, 65, 66, 67, 68, 69, 70, -1, - 72, 73, 74, -1, 76, 77, 10, 11, 12, 13, - 82, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 25, 26, 27, 28, 29, 30, 31, 32, 33, - 34, 35, 36, 37, 38, 39, -1, -1, -1, -1, - -1, 45, 46, 47, 48, 49, 50, -1, -1, -1, - 54, 55, -1, 57, 58, 59, 60, 61, 62, 63, - 64, 65, 66, 67, 68, 69, 70, -1, 72, 73, - 74, -1, -1, 77 + 69, 70, -1, 72, 73, 74, -1, 76, 77, 10, + 11, 12, 13, 82, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 25, 26, 27, 28, 29, 30, + 31, 32, 33, 34, 35, 36, 37, 38, 39, -1, + -1, -1, -1, -1, 45, 46, 47, 48, 49, 50, + -1, -1, -1, 54, 55, -1, 57, 58, 59, 60, + 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, + -1, 72, 73, 74, -1, -1, 77 }; /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing @@ -1477,40 +1476,40 @@ static const yytype_uint8 yystos[] = 65, 66, 67, 68, 69, 70, 72, 73, 74, 75, 77, 160, 161, 162, 163, 164, 169, 170, 171, 172, 174, 175, 176, 177, 178, 181, 182, 183, 218, 219, - 220, 44, 76, 177, 40, 41, 76, 77, 108, 129, - 104, 114, 221, 105, 111, 9, 40, 41, 42, 166, - 167, 173, 111, 114, 76, 129, 175, 76, 114, 159, - 176, 181, 175, 106, 0, 219, 181, 185, 108, 76, - 179, 180, 108, 201, 166, 165, 168, 176, 167, 129, - 104, 106, 113, 108, 3, 174, 176, 186, 187, 76, - 78, 79, 80, 81, 82, 85, 86, 104, 107, 115, - 116, 117, 118, 130, 131, 132, 134, 135, 136, 137, - 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, - 148, 149, 150, 151, 152, 153, 154, 158, 181, 114, - 186, 184, 113, 105, 111, 14, 15, 16, 18, 19, - 20, 21, 22, 23, 24, 56, 108, 109, 114, 141, - 154, 155, 157, 160, 161, 181, 191, 192, 193, 194, - 202, 203, 204, 206, 208, 210, 217, 129, 165, 168, - 106, 113, 107, 158, 155, 190, 176, 129, 188, 189, - 109, 187, 141, 141, 157, 85, 86, 106, 110, 105, - 105, 111, 55, 155, 104, 141, 119, 120, 121, 116, - 118, 83, 84, 87, 88, 122, 123, 89, 90, 126, - 125, 124, 91, 93, 92, 127, 107, 109, 186, 79, - 80, 180, 114, 114, 212, 104, 104, 114, 114, 157, - 104, 158, 112, 104, 109, 195, 94, 95, 96, 97, - 98, 99, 100, 101, 102, 103, 113, 156, 111, 114, - 109, 192, 106, 107, 158, 190, 113, 107, 188, 106, - 111, 114, 76, 114, 105, 133, 157, 76, 82, 136, - 155, 141, 141, 141, 143, 143, 144, 144, 145, 145, - 145, 145, 146, 146, 147, 148, 149, 150, 151, 152, - 157, 109, 198, 199, 200, 213, 157, 114, 157, 112, - 211, 202, 155, 155, 158, 113, 107, 190, 113, 114, - 158, 189, 106, 114, 107, 112, 56, 201, 193, 191, - 203, 214, 105, 105, 157, 171, 174, 209, 196, 107, - 190, 113, 190, 107, 158, 155, 104, 209, 215, 216, - 198, 205, 207, 129, 105, 109, 190, 107, 157, 114, - 105, 17, 194, 113, 193, 197, 201, 114, 105, 157, - 197, 198, 190, 114 + 220, 44, 76, 172, 175, 177, 40, 41, 76, 77, + 108, 129, 104, 114, 221, 105, 111, 9, 40, 41, + 42, 166, 167, 173, 111, 114, 76, 129, 175, 76, + 114, 159, 176, 181, 175, 106, 0, 219, 175, 181, + 185, 108, 76, 179, 180, 108, 201, 166, 165, 168, + 176, 167, 129, 104, 106, 113, 108, 3, 174, 176, + 186, 187, 76, 78, 79, 80, 81, 82, 85, 86, + 104, 107, 115, 116, 117, 118, 130, 131, 132, 134, + 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, + 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, + 158, 181, 114, 186, 184, 113, 105, 111, 14, 15, + 16, 18, 19, 20, 21, 22, 23, 24, 56, 108, + 109, 114, 141, 154, 155, 157, 160, 161, 181, 191, + 192, 193, 194, 202, 203, 204, 206, 208, 210, 217, + 129, 165, 168, 106, 113, 107, 158, 155, 190, 176, + 129, 188, 189, 109, 187, 141, 141, 157, 85, 86, + 106, 110, 105, 105, 111, 55, 155, 104, 141, 119, + 120, 121, 116, 118, 83, 84, 87, 88, 122, 123, + 89, 90, 126, 125, 124, 91, 93, 92, 127, 107, + 109, 186, 79, 80, 180, 114, 114, 212, 104, 104, + 114, 114, 157, 104, 158, 112, 104, 109, 195, 94, + 95, 96, 97, 98, 99, 100, 101, 102, 103, 113, + 156, 111, 114, 109, 192, 106, 107, 158, 190, 113, + 107, 188, 106, 111, 114, 76, 114, 105, 133, 157, + 76, 82, 136, 155, 141, 141, 141, 143, 143, 144, + 144, 145, 145, 145, 145, 146, 146, 147, 148, 149, + 150, 151, 152, 157, 109, 198, 199, 200, 213, 157, + 114, 157, 112, 211, 202, 155, 155, 158, 113, 107, + 190, 113, 114, 158, 189, 106, 114, 107, 112, 56, + 201, 193, 191, 203, 214, 105, 105, 157, 171, 174, + 209, 196, 107, 190, 113, 190, 107, 158, 155, 104, + 209, 215, 216, 198, 205, 207, 129, 105, 109, 190, + 107, 157, 114, 105, 17, 194, 113, 193, 197, 201, + 114, 105, 157, 197, 198, 190, 114 }; /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ @@ -1529,21 +1528,21 @@ static const yytype_uint8 yyr1[] = 164, 165, 165, 166, 166, 166, 166, 167, 167, 167, 167, 168, 169, 169, 169, 169, 169, 169, 170, 170, 170, 170, 170, 170, 170, 171, 171, 172, 172, 173, - 174, 174, 174, 174, 174, 174, 174, 174, 175, 175, - 175, 175, 175, 175, 176, 176, 177, 177, 177, 178, - 179, 179, 180, 180, 180, 181, 181, 181, 182, 182, + 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, + 175, 175, 175, 175, 175, 175, 176, 176, 177, 177, + 177, 178, 179, 179, 180, 180, 180, 181, 181, 181, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, - 182, 182, 182, 184, 183, 185, 183, 186, 186, 187, - 187, 188, 188, 189, 189, 190, 191, 192, 192, 193, - 193, 193, 193, 193, 193, 193, 194, 195, 196, 194, - 197, 197, 199, 198, 200, 198, 201, 201, 202, 202, - 203, 203, 204, 205, 205, 207, 206, 208, 208, 209, - 209, 211, 210, 212, 210, 213, 210, 214, 214, 215, - 215, 216, 216, 217, 217, 217, 217, 217, 218, 218, - 219, 219, 221, 220 + 182, 182, 182, 182, 182, 184, 183, 185, 183, 186, + 186, 187, 187, 188, 188, 189, 189, 190, 191, 192, + 192, 193, 193, 193, 193, 193, 193, 193, 194, 195, + 196, 194, 197, 197, 199, 198, 200, 198, 201, 201, + 202, 202, 203, 203, 204, 205, 205, 207, 206, 208, + 208, 209, 209, 211, 210, 212, 210, 213, 210, 214, + 214, 215, 215, 216, 216, 217, 217, 217, 217, 217, + 218, 218, 219, 219, 221, 220 }; /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */ @@ -1562,21 +1561,21 @@ static const yytype_uint8 yyr2[] = 3, 2, 5, 3, 2, 3, 2, 0, 1, 1, 1, 1, 1, 3, 6, 7, 8, 5, 1, 2, 5, 6, 7, 4, 2, 1, 2, 1, 1, 1, - 1, 1, 2, 1, 2, 1, 1, 2, 1, 1, - 1, 2, 2, 1, 1, 2, 1, 1, 1, 4, - 1, 3, 1, 3, 3, 1, 3, 4, 1, 1, + 1, 1, 2, 1, 2, 1, 1, 2, 2, 3, + 1, 1, 1, 2, 2, 1, 1, 2, 1, 1, + 1, 4, 1, 3, 1, 3, 3, 1, 3, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 0, 6, 0, 5, 1, 2, 3, - 4, 1, 3, 1, 4, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 2, 0, 0, 5, - 1, 1, 0, 2, 0, 2, 2, 3, 1, 2, - 1, 2, 5, 3, 1, 0, 6, 3, 2, 1, - 4, 0, 6, 0, 8, 0, 7, 1, 1, 1, - 0, 2, 3, 2, 2, 2, 3, 2, 1, 2, - 1, 1, 0, 3 + 1, 1, 1, 1, 1, 0, 6, 0, 5, 1, + 2, 3, 4, 1, 3, 1, 4, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 2, 0, + 0, 5, 1, 1, 0, 2, 0, 2, 2, 3, + 1, 2, 1, 2, 5, 3, 1, 0, 6, 3, + 2, 1, 4, 0, 6, 0, 8, 0, 7, 1, + 1, 1, 0, 2, 3, 2, 2, 2, 3, 2, + 1, 2, 1, 1, 0, 3 }; @@ -2359,21 +2358,7 @@ YYLTYPE yylloc = yyloc_default; { // The symbol table search was done in the lexical phase - const TVariable *variable = context->getNamedVariable((yylsp[0]), (yyvsp[0].lex).string, (yyvsp[0].lex).symbol); - - if (variable->getType().getQualifier() == EvqConst) - { - TConstantUnion* constArray = variable->getConstPointer(); - TType t(variable->getType()); - (yyval.interm.intermTypedNode) = context->intermediate.addConstantUnion(constArray, t, (yylsp[0])); - } - else - { - (yyval.interm.intermTypedNode) = context->intermediate.addSymbol(variable->getUniqueId(), - variable->getName(), - variable->getType(), - (yylsp[0])); - } + (yyval.interm.intermTypedNode) = context->parseVariableIdentifier((yylsp[0]), (yyvsp[0].lex).string, (yyvsp[0].lex).symbol); // don't delete $1.string, it's used by error recovery, and the pool // pop will reclaim the memory @@ -2564,10 +2549,10 @@ YYLTYPE yylloc = yyloc_default; case 25: { - TParameter param = { 0, new TType((yyvsp[0].interm.intermTypedNode)->getType()) }; - (yyvsp[-1].interm.function)->addParameter(param); + const TType *type = new TType((yyvsp[0].interm.intermTypedNode)->getType()); + (yyvsp[-1].interm.function)->addParameter(TConstParameter(type)); (yyval.interm).function = (yyvsp[-1].interm.function); - (yyval.interm).nodePair.node1 = (yyvsp[0].interm.intermTypedNode); + (yyval.interm).nodePair.node1 = context->intermediate.makeAggregate((yyvsp[0].interm.intermTypedNode), (yylsp[0])); } break; @@ -2575,8 +2560,8 @@ YYLTYPE yylloc = yyloc_default; case 26: { - TParameter param = { 0, new TType((yyvsp[0].interm.intermTypedNode)->getType()) }; - (yyvsp[-2].interm).function->addParameter(param); + const TType *type = new TType((yyvsp[0].interm.intermTypedNode)->getType()); + (yyvsp[-2].interm).function->addParameter(TConstParameter(type)); (yyval.interm).function = (yyvsp[-2].interm).function; (yyval.interm).nodePair.node1 = context->intermediate.growAggregate((yyvsp[-2].interm).intermNode, (yyvsp[0].interm.intermTypedNode), (yylsp[-1])); } @@ -2607,7 +2592,7 @@ YYLTYPE yylloc = yyloc_default; { if (context->reservedErrorCheck((yylsp[0]), *(yyvsp[0].lex).string)) context->recover(); - TType type(EbtVoid, EbpUndefined); + const TType *type = TCache::getType(EbtVoid, EbpUndefined); TFunction *function = new TFunction((yyvsp[0].lex).string, type); (yyval.interm.function) = function; } @@ -2619,7 +2604,7 @@ YYLTYPE yylloc = yyloc_default; { if (context->reservedErrorCheck((yylsp[0]), *(yyvsp[0].lex).string)) context->recover(); - TType type(EbtVoid, EbpUndefined); + const TType *type = TCache::getType(EbtVoid, EbpUndefined); TFunction *function = new TFunction((yyvsp[0].lex).string, type); (yyval.interm.function) = function; } @@ -3037,12 +3022,7 @@ YYLTYPE yylloc = yyloc_default; case 85: { - (yyval.interm.intermTypedNode) = context->intermediate.addComma((yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode), (yylsp[-1])); - if ((yyval.interm.intermTypedNode) == 0) { - context->binaryOpError((yylsp[-1]), ",", (yyvsp[-2].interm.intermTypedNode)->getCompleteString(), (yyvsp[0].interm.intermTypedNode)->getCompleteString()); - context->recover(); - (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); - } + (yyval.interm.intermTypedNode) = context->addComma((yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode), (yylsp[-1])); } break; @@ -3070,32 +3050,7 @@ YYLTYPE yylloc = yyloc_default; case 88: { - TFunction &function = *((yyvsp[-1].interm).function); - - TIntermAggregate *prototype = new TIntermAggregate; - prototype->setType(function.getReturnType()); - prototype->setName(function.getMangledName()); - prototype->setFunctionId(function.getUniqueId()); - - for (size_t i = 0; i < function.getParamCount(); i++) - { - const TParameter ¶m = function.getParam(i); - if (param.name != 0) - { - TVariable variable(param.name, *param.type); - - prototype = context->intermediate.growAggregate(prototype, context->intermediate.addSymbol(variable.getUniqueId(), variable.getName(), variable.getType(), (yylsp[-1])), (yylsp[-1])); - } - else - { - prototype = context->intermediate.growAggregate(prototype, context->intermediate.addSymbol(0, "", *param.type, (yylsp[-1])), (yylsp[-1])); - } - } - - prototype->setOp(EOpPrototype); - (yyval.interm.intermNode) = prototype; - - context->symbolTable.pop(); + (yyval.interm.intermNode) = context->addFunctionPrototypeDeclaration(*((yyvsp[-1].interm).function), (yylsp[-1])); } break; @@ -3114,7 +3069,7 @@ YYLTYPE yylloc = yyloc_default; case 90: { - if (((yyvsp[-2].interm.precision) == EbpHigh) && (context->shaderType == GL_FRAGMENT_SHADER) && !context->fragmentPrecisionHigh) { + if (((yyvsp[-2].interm.precision) == EbpHigh) && (context->getShaderType() == GL_FRAGMENT_SHADER) && !context->getFragmentPrecisionHigh()) { context->error((yylsp[-3]), "precision is not supported in fragment shader", "highp"); context->recover(); } @@ -3166,57 +3121,7 @@ YYLTYPE yylloc = yyloc_default; case 95: { - // - // Multiple declarations of the same function are allowed. - // - // If this is a definition, the definition production code will check for redefinitions - // (we don't know at this point if it's a definition or not). - // - // Redeclarations are allowed. But, return types and parameter qualifiers must match. - // - TFunction* prevDec = static_cast(context->symbolTable.find((yyvsp[-1].interm.function)->getMangledName(), context->shaderVersion)); - if (prevDec) { - if (prevDec->getReturnType() != (yyvsp[-1].interm.function)->getReturnType()) { - context->error((yylsp[0]), "overloaded functions must have the same return type", (yyvsp[-1].interm.function)->getReturnType().getBasicString()); - context->recover(); - } - for (size_t i = 0; i < prevDec->getParamCount(); ++i) { - if (prevDec->getParam(i).type->getQualifier() != (yyvsp[-1].interm.function)->getParam(i).type->getQualifier()) { - context->error((yylsp[0]), "overloaded functions must have the same parameter qualifiers", (yyvsp[-1].interm.function)->getParam(i).type->getQualifierString()); - context->recover(); - } - } - } - - // - // Check for previously declared variables using the same name. - // - TSymbol *prevSym = context->symbolTable.find((yyvsp[-1].interm.function)->getName(), context->shaderVersion); - if (prevSym) - { - if (!prevSym->isFunction()) - { - context->error((yylsp[0]), "redefinition", (yyvsp[-1].interm.function)->getName().c_str(), "function"); - context->recover(); - } - } - else - { - // Insert the unmangled name to detect potential future redefinition as a variable. - TFunction *function = new TFunction(NewPoolTString((yyvsp[-1].interm.function)->getName().c_str()), (yyvsp[-1].interm.function)->getReturnType()); - context->symbolTable.getOuterLevel()->insertUnmangled(function); - } - - // - // If this is a redeclaration, it could also be a definition, - // in which case, we want to use the variable names from this one, and not the one that's - // being redeclared. So, pass back up this declaration, not the one in the symbol table. - // - (yyval.interm).function = (yyvsp[-1].interm.function); - - // We're at the inner scope level of the function's arguments and body statement. - // Add the function prototype to the surrounding scope instead. - context->symbolTable.getOuterLevel()->insert((yyval.interm).function); + (yyval.interm).function = context->parseFunctionDeclarator((yylsp[0]), (yyvsp[-1].interm.function)); } break; @@ -3243,7 +3148,7 @@ YYLTYPE yylloc = yyloc_default; // Add the parameter (yyval.interm.function) = (yyvsp[-1].interm.function); if ((yyvsp[0].interm).param.type->getBasicType() != EbtVoid) - (yyvsp[-1].interm.function)->addParameter((yyvsp[0].interm).param); + (yyvsp[-1].interm.function)->addParameter((yyvsp[0].interm).param.turnToConst()); else delete (yyvsp[0].interm).param.type; } @@ -3267,7 +3172,7 @@ YYLTYPE yylloc = yyloc_default; } else { // Add the parameter (yyval.interm.function) = (yyvsp[-2].interm.function); - (yyvsp[-2].interm.function)->addParameter((yyvsp[0].interm).param); + (yyvsp[-2].interm.function)->addParameter((yyvsp[0].interm).param.turnToConst()); } } @@ -3276,17 +3181,23 @@ YYLTYPE yylloc = yyloc_default; case 100: { - if ((yyvsp[-2].interm.type).qualifier != EvqGlobal && (yyvsp[-2].interm.type).qualifier != EvqTemporary) { + if ((yyvsp[-2].interm.type).qualifier != EvqGlobal && (yyvsp[-2].interm.type).qualifier != EvqTemporary) + { context->error((yylsp[-1]), "no qualifiers allowed for function return", getQualifierString((yyvsp[-2].interm.type).qualifier)); context->recover(); } + if (!(yyvsp[-2].interm.type).layoutQualifier.isEmpty()) + { + context->error((yylsp[-1]), "no qualifiers allowed for function return", "layout"); + context->recover(); + } // make sure a sampler is not involved as well... if (context->samplerErrorCheck((yylsp[-1]), (yyvsp[-2].interm.type), "samplers can't be function return values")) context->recover(); // Add the function as a prototype after parsing it (we do not support recursion) TFunction *function; - TType type((yyvsp[-2].interm.type)); + const TType *type = new TType((yyvsp[-2].interm.type)); function = new TFunction((yyvsp[-1].lex).string, type); (yyval.interm.function) = function; @@ -3544,7 +3455,7 @@ YYLTYPE yylloc = yyloc_default; if ((yyvsp[0].interm.type).array) { ES3_ONLY("[]", (yylsp[0]), "first-class-array"); - if (context->shaderVersion != 300) { + if (context->getShaderVersion() != 300) { (yyvsp[0].interm.type).clearArrayness(); } } @@ -3555,7 +3466,7 @@ YYLTYPE yylloc = yyloc_default; case 126: { - (yyval.interm.type) = context->addFullySpecifiedType((yyvsp[-1].interm.type).qualifier, (yyvsp[-1].interm.type).layoutQualifier, (yyvsp[0].interm.type)); + (yyval.interm.type) = context->addFullySpecifiedType((yyvsp[-1].interm.type).qualifier, (yyvsp[-1].interm.type).invariant, (yyvsp[-1].interm.type).layoutQualifier, (yyvsp[0].interm.type)); } break; @@ -3602,7 +3513,7 @@ YYLTYPE yylloc = yyloc_default; ES2_ONLY("varying", (yylsp[0])); if (context->globalErrorCheck((yylsp[0]), context->symbolTable.atGlobalLevel(), "varying")) context->recover(); - if (context->shaderType == GL_VERTEX_SHADER) + if (context->getShaderType() == GL_VERTEX_SHADER) (yyval.interm.type).setBasic(EbtVoid, EvqVaryingOut, (yylsp[0])); else (yyval.interm.type).setBasic(EbtVoid, EvqVaryingIn, (yylsp[0])); @@ -3616,10 +3527,11 @@ YYLTYPE yylloc = yyloc_default; ES2_ONLY("varying", (yylsp[-1])); if (context->globalErrorCheck((yylsp[-1]), context->symbolTable.atGlobalLevel(), "invariant varying")) context->recover(); - if (context->shaderType == GL_VERTEX_SHADER) - (yyval.interm.type).setBasic(EbtVoid, EvqInvariantVaryingOut, (yylsp[-1])); + if (context->getShaderType() == GL_VERTEX_SHADER) + (yyval.interm.type).setBasic(EbtVoid, EvqVaryingOut, (yylsp[-1])); else - (yyval.interm.type).setBasic(EbtVoid, EvqInvariantVaryingIn, (yylsp[-1])); + (yyval.interm.type).setBasic(EbtVoid, EvqVaryingIn, (yylsp[-1])); + (yyval.interm.type).invariant = true; } break; @@ -3627,12 +3539,12 @@ YYLTYPE yylloc = yyloc_default; case 133: { - if ((yyvsp[0].interm.type).qualifier != EvqConst && !context->symbolTable.atGlobalLevel()) { + if ((yyvsp[0].interm.type).qualifier != EvqConst && !context->symbolTable.atGlobalLevel()) + { context->error((yylsp[0]), "Local variables can only use the const storage qualifier.", getQualifierString((yyvsp[0].interm.type).qualifier)); context->recover(); - } else { - (yyval.interm.type).setBasic(EbtVoid, (yyvsp[0].interm.type).qualifier, (yylsp[0])); } + (yyval.interm.type).setBasic(EbtVoid, (yyvsp[0].interm.type).qualifier, (yylsp[0])); } break; @@ -3678,7 +3590,9 @@ YYLTYPE yylloc = yyloc_default; case 138: { - (yyval.interm.type).qualifier = EvqConst; + context->es3InvariantErrorCheck((yyvsp[0].interm.type).qualifier, (yylsp[-1])); + (yyval.interm.type).setBasic(EbtVoid, (yyvsp[0].interm.type).qualifier, (yylsp[0])); + (yyval.interm.type).invariant = true; } break; @@ -3686,8 +3600,9 @@ YYLTYPE yylloc = yyloc_default; case 139: { - ES3_ONLY("in", (yylsp[0]), "storage qualifier"); - (yyval.interm.type).qualifier = (context->shaderType == GL_FRAGMENT_SHADER) ? EvqFragmentIn : EvqVertexIn; + context->es3InvariantErrorCheck((yyvsp[0].interm.type).qualifier, (yylsp[-2])); + (yyval.interm.type) = context->joinInterpolationQualifiers((yylsp[-1]), (yyvsp[-1].interm.type).qualifier, (yylsp[0]), (yyvsp[0].interm.type).qualifier); + (yyval.interm.type).invariant = true; } break; @@ -3695,8 +3610,7 @@ YYLTYPE yylloc = yyloc_default; case 140: { - ES3_ONLY("out", (yylsp[0]), "storage qualifier"); - (yyval.interm.type).qualifier = (context->shaderType == GL_FRAGMENT_SHADER) ? EvqFragmentOut : EvqVertexOut; + (yyval.interm.type).qualifier = EvqConst; } break; @@ -3704,13 +3618,8 @@ YYLTYPE yylloc = yyloc_default; case 141: { - ES3_ONLY("centroid in", (yylsp[-1]), "storage qualifier"); - if (context->shaderType == GL_VERTEX_SHADER) - { - context->error((yylsp[-1]), "invalid storage qualifier", "it is an error to use 'centroid in' in the vertex shader"); - context->recover(); - } - (yyval.interm.type).qualifier = (context->shaderType == GL_FRAGMENT_SHADER) ? EvqCentroidIn : EvqVertexIn; + ES3_ONLY("in", (yylsp[0]), "storage qualifier"); + (yyval.interm.type).qualifier = (context->getShaderType() == GL_FRAGMENT_SHADER) ? EvqFragmentIn : EvqVertexIn; } break; @@ -3718,13 +3627,8 @@ YYLTYPE yylloc = yyloc_default; case 142: { - ES3_ONLY("centroid out", (yylsp[-1]), "storage qualifier"); - if (context->shaderType == GL_FRAGMENT_SHADER) - { - context->error((yylsp[-1]), "invalid storage qualifier", "it is an error to use 'centroid out' in the fragment shader"); - context->recover(); - } - (yyval.interm.type).qualifier = (context->shaderType == GL_FRAGMENT_SHADER) ? EvqFragmentOut : EvqCentroidOut; + ES3_ONLY("out", (yylsp[0]), "storage qualifier"); + (yyval.interm.type).qualifier = (context->getShaderType() == GL_FRAGMENT_SHADER) ? EvqFragmentOut : EvqVertexOut; } break; @@ -3732,15 +3636,43 @@ YYLTYPE yylloc = yyloc_default; case 143: { - if (context->globalErrorCheck((yylsp[0]), context->symbolTable.atGlobalLevel(), "uniform")) - context->recover(); - (yyval.interm.type).qualifier = EvqUniform; + ES3_ONLY("centroid in", (yylsp[-1]), "storage qualifier"); + if (context->getShaderType() == GL_VERTEX_SHADER) + { + context->error((yylsp[-1]), "invalid storage qualifier", "it is an error to use 'centroid in' in the vertex shader"); + context->recover(); + } + (yyval.interm.type).qualifier = (context->getShaderType() == GL_FRAGMENT_SHADER) ? EvqCentroidIn : EvqVertexIn; } break; case 144: + { + ES3_ONLY("centroid out", (yylsp[-1]), "storage qualifier"); + if (context->getShaderType() == GL_FRAGMENT_SHADER) + { + context->error((yylsp[-1]), "invalid storage qualifier", "it is an error to use 'centroid out' in the fragment shader"); + context->recover(); + } + (yyval.interm.type).qualifier = (context->getShaderType() == GL_FRAGMENT_SHADER) ? EvqFragmentOut : EvqCentroidOut; + } + + break; + + case 145: + + { + if (context->globalErrorCheck((yylsp[0]), context->symbolTable.atGlobalLevel(), "uniform")) + context->recover(); + (yyval.interm.type).qualifier = EvqUniform; + } + + break; + + case 146: + { (yyval.interm.type) = (yyvsp[0].interm.type); @@ -3754,7 +3686,7 @@ YYLTYPE yylloc = yyloc_default; break; - case 145: + case 147: { (yyval.interm.type) = (yyvsp[0].interm.type); @@ -3768,7 +3700,7 @@ YYLTYPE yylloc = yyloc_default; break; - case 146: + case 148: { (yyval.interm.precision) = EbpHigh; @@ -3776,7 +3708,7 @@ YYLTYPE yylloc = yyloc_default; break; - case 147: + case 149: { (yyval.interm.precision) = EbpMedium; @@ -3784,7 +3716,7 @@ YYLTYPE yylloc = yyloc_default; break; - case 148: + case 150: { (yyval.interm.precision) = EbpLow; @@ -3792,7 +3724,7 @@ YYLTYPE yylloc = yyloc_default; break; - case 149: + case 151: { ES3_ONLY("layout", (yylsp[-3]), "qualifier"); @@ -3801,7 +3733,7 @@ YYLTYPE yylloc = yyloc_default; break; - case 150: + case 152: { (yyval.interm.layoutQualifier) = (yyvsp[0].interm.layoutQualifier); @@ -3809,7 +3741,7 @@ YYLTYPE yylloc = yyloc_default; break; - case 151: + case 153: { (yyval.interm.layoutQualifier) = context->joinLayoutQualifiers((yyvsp[-2].interm.layoutQualifier), (yyvsp[0].interm.layoutQualifier)); @@ -3817,7 +3749,7 @@ YYLTYPE yylloc = yyloc_default; break; - case 152: + case 154: { (yyval.interm.layoutQualifier) = context->parseLayoutQualifier(*(yyvsp[0].lex).string, (yylsp[0])); @@ -3825,7 +3757,7 @@ YYLTYPE yylloc = yyloc_default; break; - case 153: + case 155: { (yyval.interm.layoutQualifier) = context->parseLayoutQualifier(*(yyvsp[-2].lex).string, (yylsp[-2]), *(yyvsp[0].lex).string, (yyvsp[0].lex).i, (yylsp[0])); @@ -3833,7 +3765,7 @@ YYLTYPE yylloc = yyloc_default; break; - case 154: + case 156: { (yyval.interm.layoutQualifier) = context->parseLayoutQualifier(*(yyvsp[-2].lex).string, (yylsp[-2]), *(yyvsp[0].lex).string, (yyvsp[0].lex).i, (yylsp[0])); @@ -3841,7 +3773,7 @@ YYLTYPE yylloc = yyloc_default; break; - case 155: + case 157: { (yyval.interm.type) = (yyvsp[0].interm.type); @@ -3849,7 +3781,7 @@ YYLTYPE yylloc = yyloc_default; break; - case 156: + case 158: { ES3_ONLY("[]", (yylsp[-1]), "implicitly sized array"); @@ -3859,7 +3791,7 @@ YYLTYPE yylloc = yyloc_default; break; - case 157: + case 159: { (yyval.interm.type) = (yyvsp[-3].interm.type); @@ -3876,7 +3808,7 @@ YYLTYPE yylloc = yyloc_default; break; - case 158: + case 160: { TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; @@ -3885,7 +3817,7 @@ YYLTYPE yylloc = yyloc_default; break; - case 159: + case 161: { TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; @@ -3894,7 +3826,7 @@ YYLTYPE yylloc = yyloc_default; break; - case 160: + case 162: { TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; @@ -3903,7 +3835,7 @@ YYLTYPE yylloc = yyloc_default; break; - case 161: + case 163: { TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; @@ -3912,7 +3844,7 @@ YYLTYPE yylloc = yyloc_default; break; - case 162: + case 164: { TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; @@ -3921,7 +3853,7 @@ YYLTYPE yylloc = yyloc_default; break; - case 163: + case 165: { TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; @@ -3931,7 +3863,7 @@ YYLTYPE yylloc = yyloc_default; break; - case 164: + case 166: { TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; @@ -3941,7 +3873,7 @@ YYLTYPE yylloc = yyloc_default; break; - case 165: + case 167: { TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; @@ -3951,7 +3883,7 @@ YYLTYPE yylloc = yyloc_default; break; - case 166: + case 168: { TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; @@ -3961,7 +3893,7 @@ YYLTYPE yylloc = yyloc_default; break; - case 167: + case 169: { TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; @@ -3971,7 +3903,7 @@ YYLTYPE yylloc = yyloc_default; break; - case 168: + case 170: { TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; @@ -3981,7 +3913,7 @@ YYLTYPE yylloc = yyloc_default; break; - case 169: + case 171: { TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; @@ -3991,7 +3923,7 @@ YYLTYPE yylloc = yyloc_default; break; - case 170: + case 172: { TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; @@ -4001,7 +3933,7 @@ YYLTYPE yylloc = yyloc_default; break; - case 171: + case 173: { TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; @@ -4011,7 +3943,7 @@ YYLTYPE yylloc = yyloc_default; break; - case 172: + case 174: { TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; @@ -4021,7 +3953,7 @@ YYLTYPE yylloc = yyloc_default; break; - case 173: + case 175: { TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; @@ -4031,7 +3963,7 @@ YYLTYPE yylloc = yyloc_default; break; - case 174: + case 176: { TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; @@ -4041,7 +3973,7 @@ YYLTYPE yylloc = yyloc_default; break; - case 175: + case 177: { TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; @@ -4051,7 +3983,7 @@ YYLTYPE yylloc = yyloc_default; break; - case 176: + case 178: { TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; @@ -4061,7 +3993,7 @@ YYLTYPE yylloc = yyloc_default; break; - case 177: + case 179: { TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; @@ -4071,7 +4003,7 @@ YYLTYPE yylloc = yyloc_default; break; - case 178: + case 180: { TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; @@ -4081,7 +4013,7 @@ YYLTYPE yylloc = yyloc_default; break; - case 179: + case 181: { TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; @@ -4091,7 +4023,7 @@ YYLTYPE yylloc = yyloc_default; break; - case 180: + case 182: { TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; @@ -4101,7 +4033,7 @@ YYLTYPE yylloc = yyloc_default; break; - case 181: + case 183: { TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; @@ -4111,7 +4043,7 @@ YYLTYPE yylloc = yyloc_default; break; - case 182: + case 184: { TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; @@ -4121,7 +4053,7 @@ YYLTYPE yylloc = yyloc_default; break; - case 183: + case 185: { TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; @@ -4131,7 +4063,7 @@ YYLTYPE yylloc = yyloc_default; break; - case 184: + case 186: { TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; @@ -4140,7 +4072,7 @@ YYLTYPE yylloc = yyloc_default; break; - case 185: + case 187: { TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; @@ -4149,7 +4081,7 @@ YYLTYPE yylloc = yyloc_default; break; - case 186: + case 188: { TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; @@ -4158,7 +4090,7 @@ YYLTYPE yylloc = yyloc_default; break; - case 187: + case 189: { TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; @@ -4167,7 +4099,7 @@ YYLTYPE yylloc = yyloc_default; break; - case 188: + case 190: { TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; @@ -4176,7 +4108,7 @@ YYLTYPE yylloc = yyloc_default; break; - case 189: + case 191: { TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; @@ -4185,7 +4117,7 @@ YYLTYPE yylloc = yyloc_default; break; - case 190: + case 192: { TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; @@ -4194,7 +4126,7 @@ YYLTYPE yylloc = yyloc_default; break; - case 191: + case 193: { TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; @@ -4203,7 +4135,7 @@ YYLTYPE yylloc = yyloc_default; break; - case 192: + case 194: { TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; @@ -4212,7 +4144,7 @@ YYLTYPE yylloc = yyloc_default; break; - case 193: + case 195: { TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; @@ -4221,7 +4153,7 @@ YYLTYPE yylloc = yyloc_default; break; - case 194: + case 196: { TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; @@ -4230,7 +4162,7 @@ YYLTYPE yylloc = yyloc_default; break; - case 195: + case 197: { TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; @@ -4239,7 +4171,7 @@ YYLTYPE yylloc = yyloc_default; break; - case 196: + case 198: { TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; @@ -4248,7 +4180,7 @@ YYLTYPE yylloc = yyloc_default; break; - case 197: + case 199: { TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; @@ -4257,7 +4189,7 @@ YYLTYPE yylloc = yyloc_default; break; - case 198: + case 200: { TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; @@ -4266,7 +4198,7 @@ YYLTYPE yylloc = yyloc_default; break; - case 199: + case 201: { if (!context->supportsExtension("GL_OES_EGL_image_external")) { @@ -4279,7 +4211,7 @@ YYLTYPE yylloc = yyloc_default; break; - case 200: + case 202: { if (!context->supportsExtension("GL_ARB_texture_rectangle")) { @@ -4292,7 +4224,7 @@ YYLTYPE yylloc = yyloc_default; break; - case 201: + case 203: { (yyval.interm.type) = (yyvsp[0].interm.type); @@ -4301,7 +4233,7 @@ YYLTYPE yylloc = yyloc_default; break; - case 202: + case 204: { // @@ -4316,13 +4248,13 @@ YYLTYPE yylloc = yyloc_default; break; - case 203: + case 205: { if (context->enterStructDeclaration((yylsp[-1]), *(yyvsp[-1].lex).string)) context->recover(); } break; - case 204: + case 206: { (yyval.interm.type) = context->addStructure((yylsp[-5]), (yylsp[-4]), (yyvsp[-4].lex).string, (yyvsp[-1].interm.fieldList)); @@ -4330,13 +4262,13 @@ YYLTYPE yylloc = yyloc_default; break; - case 205: + case 207: { if (context->enterStructDeclaration((yylsp[0]), *(yyvsp[0].lex).string)) context->recover(); } break; - case 206: + case 208: { (yyval.interm.type) = context->addStructure((yylsp[-4]), (yyloc), NewPoolTString(""), (yyvsp[-1].interm.fieldList)); @@ -4344,7 +4276,7 @@ YYLTYPE yylloc = yyloc_default; break; - case 207: + case 209: { (yyval.interm.fieldList) = (yyvsp[0].interm.fieldList); @@ -4352,7 +4284,7 @@ YYLTYPE yylloc = yyloc_default; break; - case 208: + case 210: { (yyval.interm.fieldList) = (yyvsp[-1].interm.fieldList); @@ -4370,7 +4302,7 @@ YYLTYPE yylloc = yyloc_default; break; - case 209: + case 211: { (yyval.interm.fieldList) = context->addStructDeclaratorList((yyvsp[-2].interm.type), (yyvsp[-1].interm.fieldList)); @@ -4378,7 +4310,7 @@ YYLTYPE yylloc = yyloc_default; break; - case 210: + case 212: { // ES3 Only, but errors should be handled elsewhere @@ -4389,7 +4321,7 @@ YYLTYPE yylloc = yyloc_default; break; - case 211: + case 213: { (yyval.interm.fieldList) = NewPoolTFieldList(); @@ -4398,7 +4330,7 @@ YYLTYPE yylloc = yyloc_default; break; - case 212: + case 214: { (yyval.interm.fieldList)->push_back((yyvsp[0].interm.field)); @@ -4406,7 +4338,7 @@ YYLTYPE yylloc = yyloc_default; break; - case 213: + case 215: { if (context->reservedErrorCheck((yylsp[0]), *(yyvsp[0].lex).string)) @@ -4418,7 +4350,7 @@ YYLTYPE yylloc = yyloc_default; break; - case 214: + case 216: { if (context->reservedErrorCheck((yylsp[-3]), *(yyvsp[-3].lex).string)) @@ -4435,91 +4367,91 @@ YYLTYPE yylloc = yyloc_default; break; - case 215: + case 217: { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } break; - case 216: + case 218: { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } break; - case 217: + case 219: { (yyval.interm.intermNode) = (yyvsp[0].interm.intermAggregate); } break; - case 218: + case 220: { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } break; - case 219: + case 221: { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } break; - case 220: + case 222: { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } break; - case 221: + case 223: { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } break; - case 222: + case 224: { (yyval.interm.intermNode) = (yyvsp[0].interm.intermSwitch); } break; - case 223: + case 225: { (yyval.interm.intermNode) = (yyvsp[0].interm.intermCase); } break; - case 224: + case 226: { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } break; - case 225: + case 227: { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } break; - case 226: + case 228: { (yyval.interm.intermAggregate) = 0; } break; - case 227: + case 229: { context->symbolTable.push(); } break; - case 228: + case 230: { context->symbolTable.pop(); } break; - case 229: + case 231: { if ((yyvsp[-2].interm.intermAggregate) != 0) { @@ -4531,63 +4463,63 @@ YYLTYPE yylloc = yyloc_default; break; - case 230: + case 232: - { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } + { (yyval.interm.intermNode) = (yyvsp[0].interm.intermAggregate); } break; - case 231: + case 233: { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } break; - case 232: + case 234: { context->symbolTable.push(); } break; - case 233: + case 235: - { context->symbolTable.pop(); (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } + { context->symbolTable.pop(); (yyval.interm.intermNode) = (yyvsp[0].interm.intermAggregate); } break; - case 234: + case 236: { context->symbolTable.push(); } break; - case 235: + case 237: { context->symbolTable.pop(); (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } break; - case 236: + case 238: { - (yyval.interm.intermNode) = 0; + (yyval.interm.intermAggregate) = 0; } break; - case 237: + case 239: { if ((yyvsp[-1].interm.intermAggregate)) { (yyvsp[-1].interm.intermAggregate)->setOp(EOpSequence); (yyvsp[-1].interm.intermAggregate)->setLine((yyloc)); } - (yyval.interm.intermNode) = (yyvsp[-1].interm.intermAggregate); + (yyval.interm.intermAggregate) = (yyvsp[-1].interm.intermAggregate); } break; - case 238: + case 240: { (yyval.interm.intermAggregate) = context->intermediate.makeAggregate((yyvsp[0].interm.intermNode), (yyloc)); @@ -4595,7 +4527,7 @@ YYLTYPE yylloc = yyloc_default; break; - case 239: + case 241: { (yyval.interm.intermAggregate) = context->intermediate.growAggregate((yyvsp[-1].interm.intermAggregate), (yyvsp[0].interm.intermNode), (yyloc)); @@ -4603,19 +4535,19 @@ YYLTYPE yylloc = yyloc_default; break; - case 240: + case 242: { (yyval.interm.intermNode) = 0; } break; - case 241: + case 243: { (yyval.interm.intermNode) = static_cast((yyvsp[-1].interm.intermTypedNode)); } break; - case 242: + case 244: { if (context->boolErrorCheck((yylsp[-4]), (yyvsp[-2].interm.intermTypedNode))) @@ -4625,7 +4557,7 @@ YYLTYPE yylloc = yyloc_default; break; - case 243: + case 245: { (yyval.interm.nodePair).node1 = (yyvsp[-2].interm.intermNode); @@ -4634,7 +4566,7 @@ YYLTYPE yylloc = yyloc_default; break; - case 244: + case 246: { (yyval.interm.nodePair).node1 = (yyvsp[0].interm.intermNode); @@ -4643,22 +4575,22 @@ YYLTYPE yylloc = yyloc_default; break; - case 245: + case 247: - { ++context->mSwitchNestingLevel; } + { context->incrSwitchNestingLevel(); } break; - case 246: + case 248: { (yyval.interm.intermSwitch) = context->addSwitch((yyvsp[-3].interm.intermTypedNode), (yyvsp[0].interm.intermAggregate), (yylsp[-5])); - --context->mSwitchNestingLevel; + context->decrSwitchNestingLevel(); } break; - case 247: + case 249: { (yyval.interm.intermCase) = context->addCase((yyvsp[-1].interm.intermTypedNode), (yylsp[-2])); @@ -4666,7 +4598,7 @@ YYLTYPE yylloc = yyloc_default; break; - case 248: + case 250: { (yyval.interm.intermCase) = context->addDefault((yylsp[-1])); @@ -4674,7 +4606,7 @@ YYLTYPE yylloc = yyloc_default; break; - case 249: + case 251: { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); @@ -4684,7 +4616,7 @@ YYLTYPE yylloc = yyloc_default; break; - case 250: + case 252: { TIntermNode *intermNode; @@ -4701,57 +4633,57 @@ YYLTYPE yylloc = yyloc_default; break; - case 251: + case 253: - { context->symbolTable.push(); ++context->mLoopNestingLevel; } + { context->symbolTable.push(); context->incrLoopNestingLevel(); } break; - case 252: + case 254: { context->symbolTable.pop(); (yyval.interm.intermNode) = context->intermediate.addLoop(ELoopWhile, 0, (yyvsp[-2].interm.intermTypedNode), 0, (yyvsp[0].interm.intermNode), (yylsp[-5])); - --context->mLoopNestingLevel; + context->decrLoopNestingLevel(); } break; - case 253: + case 255: - { ++context->mLoopNestingLevel; } + { context->incrLoopNestingLevel(); } break; - case 254: + case 256: { if (context->boolErrorCheck((yylsp[0]), (yyvsp[-2].interm.intermTypedNode))) context->recover(); (yyval.interm.intermNode) = context->intermediate.addLoop(ELoopDoWhile, 0, (yyvsp[-2].interm.intermTypedNode), 0, (yyvsp[-5].interm.intermNode), (yylsp[-4])); - --context->mLoopNestingLevel; + context->decrLoopNestingLevel(); } break; - case 255: + case 257: - { context->symbolTable.push(); ++context->mLoopNestingLevel; } + { context->symbolTable.push(); context->incrLoopNestingLevel(); } break; - case 256: + case 258: { context->symbolTable.pop(); (yyval.interm.intermNode) = context->intermediate.addLoop(ELoopFor, (yyvsp[-3].interm.intermNode), reinterpret_cast((yyvsp[-2].interm.nodePair).node1), reinterpret_cast((yyvsp[-2].interm.nodePair).node2), (yyvsp[0].interm.intermNode), (yylsp[-6])); - --context->mLoopNestingLevel; + context->decrLoopNestingLevel(); } break; - case 257: + case 259: { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); @@ -4759,7 +4691,7 @@ YYLTYPE yylloc = yyloc_default; break; - case 258: + case 260: { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); @@ -4767,7 +4699,7 @@ YYLTYPE yylloc = yyloc_default; break; - case 259: + case 261: { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); @@ -4775,7 +4707,7 @@ YYLTYPE yylloc = yyloc_default; break; - case 260: + case 262: { (yyval.interm.intermTypedNode) = 0; @@ -4783,7 +4715,7 @@ YYLTYPE yylloc = yyloc_default; break; - case 261: + case 263: { (yyval.interm.nodePair).node1 = (yyvsp[-1].interm.intermTypedNode); @@ -4792,7 +4724,7 @@ YYLTYPE yylloc = yyloc_default; break; - case 262: + case 264: { (yyval.interm.nodePair).node1 = (yyvsp[-2].interm.intermTypedNode); @@ -4801,7 +4733,7 @@ YYLTYPE yylloc = yyloc_default; break; - case 263: + case 265: { (yyval.interm.intermNode) = context->addBranch(EOpContinue, (yylsp[-1])); @@ -4809,7 +4741,7 @@ YYLTYPE yylloc = yyloc_default; break; - case 264: + case 266: { (yyval.interm.intermNode) = context->addBranch(EOpBreak, (yylsp[-1])); @@ -4817,7 +4749,7 @@ YYLTYPE yylloc = yyloc_default; break; - case 265: + case 267: { (yyval.interm.intermNode) = context->addBranch(EOpReturn, (yylsp[-1])); @@ -4825,7 +4757,7 @@ YYLTYPE yylloc = yyloc_default; break; - case 266: + case 268: { (yyval.interm.intermNode) = context->addBranch(EOpReturn, (yyvsp[-1].interm.intermTypedNode), (yylsp[-2])); @@ -4833,7 +4765,7 @@ YYLTYPE yylloc = yyloc_default; break; - case 267: + case 269: { FRAG_ONLY("discard", (yylsp[-1])); @@ -4842,25 +4774,25 @@ YYLTYPE yylloc = yyloc_default; break; - case 268: + case 270: { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); - context->treeRoot = (yyval.interm.intermNode); + context->setTreeRoot((yyval.interm.intermNode)); } break; - case 269: + case 271: { (yyval.interm.intermNode) = context->intermediate.growAggregate((yyvsp[-1].interm.intermNode), (yyvsp[0].interm.intermNode), (yyloc)); - context->treeRoot = (yyval.interm.intermNode); + context->setTreeRoot((yyval.interm.intermNode)); } break; - case 270: + case 272: { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); @@ -4868,7 +4800,7 @@ YYLTYPE yylloc = yyloc_default; break; - case 271: + case 273: { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); @@ -4876,124 +4808,18 @@ YYLTYPE yylloc = yyloc_default; break; - case 272: + case 274: { - TFunction* function = (yyvsp[0].interm).function; - - const TSymbol *builtIn = context->symbolTable.findBuiltIn(function->getMangledName(), context->shaderVersion); - - if (builtIn) - { - context->error((yylsp[0]), "built-in functions cannot be redefined", function->getName().c_str()); - context->recover(); - } - - TFunction* prevDec = static_cast(context->symbolTable.find(function->getMangledName(), context->shaderVersion)); - // - // Note: 'prevDec' could be 'function' if this is the first time we've seen function - // as it would have just been put in the symbol table. Otherwise, we're looking up - // an earlier occurance. - // - if (prevDec->isDefined()) { - // - // Then this function already has a body. - // - context->error((yylsp[0]), "function already has a body", function->getName().c_str()); - context->recover(); - } - prevDec->setDefined(); - // - // Overload the unique ID of the definition to be the same unique ID as the declaration. - // Eventually we will probably want to have only a single definition and just swap the - // arguments to be the definition's arguments. - // - function->setUniqueId(prevDec->getUniqueId()); - - // - // Raise error message if main function takes any parameters or return anything other than void - // - if (function->getName() == "main") { - if (function->getParamCount() > 0) { - context->error((yylsp[0]), "function cannot take any parameter(s)", function->getName().c_str()); - context->recover(); - } - if (function->getReturnType().getBasicType() != EbtVoid) { - context->error((yylsp[0]), "", function->getReturnType().getBasicString(), "main function cannot return a value"); - context->recover(); - } - } - - // - // Remember the return type for later checking for RETURN statements. - // - context->currentFunctionType = &(prevDec->getReturnType()); - context->mFunctionReturnsValue = false; - - // - // Insert parameters into the symbol table. - // If the parameter has no name, it's not an error, just don't insert it - // (could be used for unused args). - // - // Also, accumulate the list of parameters into the HIL, so lower level code - // knows where to find parameters. - // - TIntermAggregate* paramNodes = new TIntermAggregate; - for (size_t i = 0; i < function->getParamCount(); i++) { - const TParameter& param = function->getParam(i); - if (param.name != 0) { - TVariable *variable = new TVariable(param.name, *param.type); - // - // Insert the parameters with name in the symbol table. - // - if (! context->symbolTable.declare(variable)) { - context->error((yylsp[0]), "redefinition", variable->getName().c_str()); - context->recover(); - delete variable; - } - - // - // Add the parameter to the HIL - // - paramNodes = context->intermediate.growAggregate( - paramNodes, - context->intermediate.addSymbol(variable->getUniqueId(), - variable->getName(), - variable->getType(), (yylsp[0])), - (yylsp[0])); - } else { - paramNodes = context->intermediate.growAggregate(paramNodes, context->intermediate.addSymbol(0, "", *param.type, (yylsp[0])), (yylsp[0])); - } - } - context->intermediate.setAggregateOperator(paramNodes, EOpParameters, (yylsp[0])); - (yyvsp[0].interm).intermAggregate = paramNodes; - context->mLoopNestingLevel = 0; + context->parseFunctionPrototype((yylsp[0]), (yyvsp[0].interm).function, &(yyvsp[0].interm).intermAggregate); } break; - case 273: + case 275: { - //?? Check that all paths return a value if return type != void ? - // May be best done as post process phase on intermediate code - if (context->currentFunctionType->getBasicType() != EbtVoid && ! context->mFunctionReturnsValue) { - context->error((yylsp[-2]), "function does not return a value:", "", (yyvsp[-2].interm).function->getName().c_str()); - context->recover(); - } - - (yyval.interm.intermNode) = context->intermediate.growAggregate((yyvsp[-2].interm).intermAggregate, (yyvsp[0].interm.intermNode), (yyloc)); - context->intermediate.setAggregateOperator((yyval.interm.intermNode), EOpFunction, (yylsp[-2])); - (yyval.interm.intermNode)->getAsAggregate()->setName((yyvsp[-2].interm).function->getMangledName().c_str()); - (yyval.interm.intermNode)->getAsAggregate()->setType((yyvsp[-2].interm).function->getReturnType()); - (yyval.interm.intermNode)->getAsAggregate()->setFunctionId((yyvsp[-2].interm).function->getUniqueId()); - - // store the pragma information for debug and optimize and other vendor specific - // information. This information can be queried from the parse tree - (yyval.interm.intermNode)->getAsAggregate()->setOptimize(context->pragma().optimize); - (yyval.interm.intermNode)->getAsAggregate()->setDebug(context->pragma().debug); - - context->symbolTable.pop(); + (yyval.interm.intermNode) = context->addFunctionDefinition(*((yyvsp[-2].interm).function), (yyvsp[-2].interm).intermAggregate, (yyvsp[0].interm.intermAggregate), (yylsp[-2])); } break; @@ -5238,5 +5064,5 @@ YYLTYPE yylloc = yyloc_default; int glslang_parse(TParseContext* context) { - return yyparse(context, context->scanner); + return yyparse(context, context->getScanner()); } diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/glslang_tab.h b/Source/ThirdParty/ANGLE/src/compiler/translator/glslang_tab.h index 7331594a4484..eb7ef392535b 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/glslang_tab.h +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/glslang_tab.h @@ -1,5 +1,7 @@ /* A Bison parser, made by GNU Bison 3.0.4. */ +/* Apple Note: For the avoidance of doubt, Apple elects to distribute this file under the terms of the BSD license. */ + /* Bison interface for Yacc-like parsers in C Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc. diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/intermOut.cpp b/Source/ThirdParty/ANGLE/src/compiler/translator/intermOut.cpp index 1e0c803dee7d..6dca547f0868 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/intermOut.cpp +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/intermOut.cpp @@ -4,12 +4,18 @@ // found in the LICENSE file. // -#include "compiler/translator/intermediate.h" +#include "compiler/translator/Intermediate.h" #include "compiler/translator/SymbolTable.h" namespace { +void OutputFunction(TInfoSinkBase &out, const char *str, TIntermAggregate *node) +{ + const char *internal = node->getNameObj().isInternal() ? " (internal function)" : ""; + out << str << internal << ": " << node->getNameObj().getString(); +} + // // Two purposes: // 1. Show an example of how to iterate tree. Functions can @@ -27,18 +33,21 @@ class TOutputTraverser : public TIntermTraverser { public: TOutputTraverser(TInfoSinkBase &i) - : sink(i) { } + : TIntermTraverser(true, false, false), + sink(i) + { + } TInfoSinkBase& sink; protected: - void visitSymbol(TIntermSymbol *); - void visitConstantUnion(TIntermConstantUnion *); - bool visitBinary(Visit visit, TIntermBinary *); - bool visitUnary(Visit visit, TIntermUnary *); - bool visitSelection(Visit visit, TIntermSelection *); - bool visitAggregate(Visit visit, TIntermAggregate *); - bool visitLoop(Visit visit, TIntermLoop *); - bool visitBranch(Visit visit, TIntermBranch *); + void visitSymbol(TIntermSymbol *) override; + void visitConstantUnion(TIntermConstantUnion *) override; + bool visitBinary(Visit visit, TIntermBinary *) override; + bool visitUnary(Visit visit, TIntermUnary *) override; + bool visitSelection(Visit visit, TIntermSelection *) override; + bool visitAggregate(Visit visit, TIntermAggregate *) override; + bool visitLoop(Visit visit, TIntermLoop *) override; + bool visitBranch(Visit visit, TIntermBranch *) override; }; // @@ -56,26 +65,6 @@ void OutputTreeText(TInfoSinkBase &sink, TIntermNode *node, const int depth) } // namespace anonymous - -TString TType::getCompleteString() const -{ - TStringStream stream; - - if (qualifier != EvqTemporary && qualifier != EvqGlobal) - stream << getQualifierString() << " "; - if (precision != EbpUndefined) - stream << getPrecisionString() << " "; - if (array) - stream << "array[" << getArraySize() << "] of "; - if (isMatrix()) - stream << getCols() << "X" << getRows() << " matrix of "; - else if (isVector()) - stream << getNominalSize() << "-component vector of "; - - stream << getBasicString(); - return stream.str(); -} - // // The rest of the file are the traversal functions. The last one // is the one that starts the traversal. @@ -390,10 +379,10 @@ bool TOutputTraverser::visitAggregate(Visit visit, TIntermAggregate *node) { case EOpSequence: out << "Sequence\n"; return true; case EOpComma: out << "Comma\n"; return true; - case EOpFunction: out << "Function Definition: " << node->getName(); break; - case EOpFunctionCall: out << "Function Call: " << node->getName(); break; + case EOpFunction: OutputFunction(out, "Function Definition", node); break; + case EOpFunctionCall: OutputFunction(out, "Function Call", node); break; case EOpParameters: out << "Function Parameters: "; break; - case EOpPrototype: out << "Function Prototype: " << node->getName(); break; + case EOpPrototype: OutputFunction(out, "Function Prototype", node); break; case EOpConstructFloat: out << "Construct float"; break; case EOpConstructVec2: out << "Construct vec2"; break; @@ -412,7 +401,13 @@ bool TOutputTraverser::visitAggregate(Visit visit, TIntermAggregate *node) case EOpConstructUVec3: out << "Construct uvec3"; break; case EOpConstructUVec4: out << "Construct uvec4"; break; case EOpConstructMat2: out << "Construct mat2"; break; + case EOpConstructMat2x3: out << "Construct mat2x3"; break; + case EOpConstructMat2x4: out << "Construct mat2x4"; break; + case EOpConstructMat3x2: out << "Construct mat3x2"; break; case EOpConstructMat3: out << "Construct mat3"; break; + case EOpConstructMat3x4: out << "Construct mat3x4"; break; + case EOpConstructMat4x2: out << "Construct mat4x2"; break; + case EOpConstructMat4x3: out << "Construct mat4x3"; break; case EOpConstructMat4: out << "Construct mat4"; break; case EOpConstructStruct: out << "Construct structure"; break; diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/intermediate.h b/Source/ThirdParty/ANGLE/src/compiler/translator/intermediate.h index 4806b28d1231..f723fc76481e 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/intermediate.h +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/intermediate.h @@ -39,6 +39,7 @@ class TIntermediate TIntermAggregate *growAggregate( TIntermNode *left, TIntermNode *right, const TSourceLoc &); TIntermAggregate *makeAggregate(TIntermNode *node, const TSourceLoc &); + TIntermAggregate *ensureSequence(TIntermNode *node); TIntermAggregate *setAggregateOperator(TIntermNode *, TOperator, const TSourceLoc &); TIntermNode *addSelection(TIntermTyped *cond, TIntermNodePair code, const TSourceLoc &); TIntermTyped *addSelection(TIntermTyped *cond, TIntermTyped *trueBlock, TIntermTyped *falseBlock, @@ -47,22 +48,24 @@ class TIntermediate TIntermTyped *init, TIntermAggregate *statementList, const TSourceLoc &line); TIntermCase *addCase( TIntermTyped *condition, const TSourceLoc &line); - TIntermTyped *addComma( - TIntermTyped *left, TIntermTyped *right, const TSourceLoc &); - TIntermConstantUnion *addConstantUnion( - TConstantUnion *constantUnion, const TType &type, const TSourceLoc &line); - // TODO(zmo): Get rid of default value. - bool parseConstTree(const TSourceLoc &, TIntermNode *, TConstantUnion *, - TOperator, TType, bool singleConstantParam = false); + TIntermTyped *addComma(TIntermTyped *left, + TIntermTyped *right, + const TSourceLoc &line, + int shaderVersion); + TIntermConstantUnion *addConstantUnion(const TConstantUnion *constantUnion, + const TType &type, + const TSourceLoc &line); TIntermNode *addLoop(TLoopType, TIntermNode *, TIntermTyped *, TIntermTyped *, TIntermNode *, const TSourceLoc &); TIntermBranch *addBranch(TOperator, const TSourceLoc &); TIntermBranch *addBranch(TOperator, TIntermTyped *, const TSourceLoc &); TIntermTyped *addSwizzle(TVectorFields &, const TSourceLoc &); - bool postProcess(TIntermNode *); + TIntermAggregate *postProcess(TIntermNode *root); static void outputTree(TIntermNode *, TInfoSinkBase &); + TIntermTyped *foldAggregateBuiltIn(TIntermAggregate *aggregate); + private: void operator=(TIntermediate &); // prevent assignments diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/parseConst.cpp b/Source/ThirdParty/ANGLE/src/compiler/translator/parseConst.cpp deleted file mode 100644 index 2ace87708f48..000000000000 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/parseConst.cpp +++ /dev/null @@ -1,264 +0,0 @@ -// -// Copyright (c) 2002-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 "compiler/translator/ParseContext.h" - -// -// Use this class to carry along data from node to node in -// the traversal -// -class TConstTraverser : public TIntermTraverser -{ - public: - TConstTraverser(TConstantUnion *cUnion, bool singleConstParam, - TOperator constructType, TInfoSink &sink, TType &t) - : error(false), - mIndex(0), - mUnionArray(cUnion), - mType(t), - mConstructorType(constructType), - mSingleConstantParam(singleConstParam), - mInfoSink(sink), - mSize(0), - mIsDiagonalMatrixInit(false), - mMatrixCols(0), - mMatrixRows(0) - { - } - - bool error; - - protected: - void visitSymbol(TIntermSymbol *); - void visitConstantUnion(TIntermConstantUnion *); - bool visitBinary(Visit visit, TIntermBinary *); - bool visitUnary(Visit visit, TIntermUnary *); - bool visitSelection(Visit visit, TIntermSelection *); - bool visitAggregate(Visit visit, TIntermAggregate *); - bool visitLoop(Visit visit, TIntermLoop *); - bool visitBranch(Visit visit, TIntermBranch *); - - size_t mIndex; - TConstantUnion *mUnionArray; - TType mType; - TOperator mConstructorType; - bool mSingleConstantParam; - TInfoSink &mInfoSink; - size_t mSize; // size of the constructor ( 4 for vec4) - bool mIsDiagonalMatrixInit; - int mMatrixCols; // columns of the matrix - int mMatrixRows; // rows of the matrix -}; - -// -// The rest of the file are the traversal functions. The last one -// is the one that starts the traversal. -// -// Return true from interior nodes to have the external traversal -// continue on to children. If you process children yourself, -// return false. -// -void TConstTraverser::visitSymbol(TIntermSymbol *node) -{ - mInfoSink.info.message(EPrefixInternalError, node->getLine(), - "Symbol Node found in constant constructor"); - return; -} - -bool TConstTraverser::visitBinary(Visit visit, TIntermBinary *node) -{ - TQualifier qualifier = node->getType().getQualifier(); - - if (qualifier != EvqConst) - { - TString buf; - buf.append("'constructor' : assigning non-constant to "); - buf.append(mType.getCompleteString()); - mInfoSink.info.message(EPrefixError, node->getLine(), buf.c_str()); - error = true; - return false; - } - - mInfoSink.info.message(EPrefixInternalError, node->getLine(), - "Binary Node found in constant constructor"); - return false; -} - -bool TConstTraverser::visitUnary(Visit visit, TIntermUnary *node) -{ - TString buf; - buf.append("'constructor' : assigning non-constant to "); - buf.append(mType.getCompleteString()); - mInfoSink.info.message(EPrefixError, node->getLine(), buf.c_str()); - error = true; - return false; -} - -bool TConstTraverser::visitAggregate(Visit visit, TIntermAggregate *node) -{ - if (!node->isConstructor() && node->getOp() != EOpComma) - { - TString buf; - buf.append("'constructor' : assigning non-constant to "); - buf.append(mType.getCompleteString()); - mInfoSink.info.message(EPrefixError, node->getLine(), buf.c_str()); - error = true; - return false; - } - - if (node->getSequence()->size() == 0) - { - error = true; - return false; - } - - bool flag = node->getSequence()->size() == 1 && - (*node->getSequence())[0]->getAsTyped()->getAsConstantUnion(); - if (flag) - { - mSingleConstantParam = true; - mConstructorType = node->getOp(); - mSize = node->getType().getObjectSize(); - - if (node->getType().isMatrix()) - { - mIsDiagonalMatrixInit = true; - mMatrixCols = node->getType().getCols(); - mMatrixRows = node->getType().getRows(); - } - } - - for (TIntermSequence::iterator p = node->getSequence()->begin(); - p != node->getSequence()->end(); p++) - { - if (node->getOp() == EOpComma) - mIndex = 0; - (*p)->traverse(this); - } - if (flag) - { - mSingleConstantParam = false; - mConstructorType = EOpNull; - mSize = 0; - mIsDiagonalMatrixInit = false; - mMatrixCols = 0; - mMatrixRows = 0; - } - return false; -} - -bool TConstTraverser::visitSelection(Visit visit, TIntermSelection *node) -{ - mInfoSink.info.message(EPrefixInternalError, node->getLine(), - "Selection Node found in constant constructor"); - error = true; - return false; -} - -void TConstTraverser::visitConstantUnion(TIntermConstantUnion *node) -{ - if (!node->getUnionArrayPointer()) - { - // The constant was not initialized, this should already have been logged - ASSERT(mInfoSink.info.size() != 0); - return; - } - - TConstantUnion *leftUnionArray = mUnionArray; - size_t instanceSize = mType.getObjectSize(); - TBasicType basicType = mType.getBasicType(); - - if (mIndex >= instanceSize) - return; - - if (!mSingleConstantParam) - { - size_t objectSize = node->getType().getObjectSize(); - const TConstantUnion *rightUnionArray = node->getUnionArrayPointer(); - for (size_t i=0; i < objectSize; i++) - { - if (mIndex >= instanceSize) - return; - leftUnionArray[mIndex].cast(basicType, rightUnionArray[i]); - mIndex++; - } - } - else - { - size_t totalSize = mIndex + mSize; - const TConstantUnion *rightUnionArray = node->getUnionArrayPointer(); - if (!mIsDiagonalMatrixInit) - { - int count = 0; - for (size_t i = mIndex; i < totalSize; i++) - { - if (i >= instanceSize) - return; - leftUnionArray[i].cast(basicType, rightUnionArray[count]); - mIndex++; - if (node->getType().getObjectSize() > 1) - count++; - } - } - else - { - // for matrix diagonal constructors from a single scalar - for (int i = 0, col = 0; col < mMatrixCols; col++) - { - for (int row = 0; row < mMatrixRows; row++, i++) - { - if (col == row) - { - leftUnionArray[i].cast(basicType, rightUnionArray[0]); - } - else - { - leftUnionArray[i].setFConst(0.0f); - } - mIndex++; - } - } - } - } -} - -bool TConstTraverser::visitLoop(Visit visit, TIntermLoop *node) -{ - mInfoSink.info.message(EPrefixInternalError, node->getLine(), - "Loop Node found in constant constructor"); - error = true; - return false; -} - -bool TConstTraverser::visitBranch(Visit visit, TIntermBranch *node) -{ - mInfoSink.info.message(EPrefixInternalError, node->getLine(), - "Branch Node found in constant constructor"); - error = true; - return false; -} - -// -// This function is the one to call externally to start the traversal. -// Individual functions can be initialized to 0 to skip processing of that -// type of node. It's children will still be processed. -// -bool TIntermediate::parseConstTree( - const TSourceLoc &line, TIntermNode *root, TConstantUnion *unionArray, - TOperator constructorType, TType t, bool singleConstantParam) -{ - if (root == 0) - return false; - - TConstTraverser it(unionArray, singleConstantParam, constructorType, - mInfoSink, t); - - root->traverse(&it); - if (it.error) - return true; - else - return false; -} diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/timing/RestrictFragmentShaderTiming.cpp b/Source/ThirdParty/ANGLE/src/compiler/translator/timing/RestrictFragmentShaderTiming.cpp index 48d44c72d171..790974a2bf58 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/timing/RestrictFragmentShaderTiming.cpp +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/timing/RestrictFragmentShaderTiming.cpp @@ -54,11 +54,8 @@ void RestrictFragmentShaderTiming::enforceRestrictions(const TDependencyGraph& g // Starting from each sampler, traverse the dependency graph and generate an error each time we // hit a node where sampler dependent values are not allowed. - for (TGraphSymbolVector::const_iterator iter = graph.beginSamplerSymbols(); - iter != graph.endSamplerSymbols(); - ++iter) + for (auto samplerSymbol : graph.samplerSymbols()) { - TGraphSymbol* samplerSymbol = *iter; clearVisited(); samplerSymbol->traverse(this); } @@ -66,11 +63,8 @@ void RestrictFragmentShaderTiming::enforceRestrictions(const TDependencyGraph& g void RestrictFragmentShaderTiming::validateUserDefinedFunctionCallUsage(const TDependencyGraph& graph) { - for (TFunctionCallVector::const_iterator iter = graph.beginUserDefinedFunctionCalls(); - iter != graph.endUserDefinedFunctionCalls(); - ++iter) + for (const auto* functionCall : graph.userDefinedFunctionCalls()) { - TGraphFunctionCall* functionCall = *iter; beginError(functionCall->getIntermFunctionCall()); mSink << "A call to a user defined function is not permitted.\n"; } diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/timing/RestrictVertexShaderTiming.h b/Source/ThirdParty/ANGLE/src/compiler/translator/timing/RestrictVertexShaderTiming.h index 74bfd0b5c2b0..23a8217722e5 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/timing/RestrictVertexShaderTiming.h +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/timing/RestrictVertexShaderTiming.h @@ -22,7 +22,8 @@ class RestrictVertexShaderTiming : public TIntermTraverser { void enforceRestrictions(TIntermNode* root) { root->traverse(this); } int numErrors() { return mNumErrors; } - virtual void visitSymbol(TIntermSymbol*); + void visitSymbol(TIntermSymbol *) override; + private: TInfoSinkBase& mSink; int mNumErrors; diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/util.cpp b/Source/ThirdParty/ANGLE/src/compiler/translator/util.cpp index 42a995ee6f44..013113720665 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/util.cpp +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/util.cpp @@ -12,7 +12,7 @@ #include "compiler/translator/SymbolTable.h" #include "common/utilities.h" -bool atof_clamp(const char *str, float *value) +bool strtof_clamp(const std::string &str, float *value) { bool success = pp::numeric_lex_float(str, value); if (!success) @@ -20,11 +20,11 @@ bool atof_clamp(const char *str, float *value) return success; } -bool atoi_clamp(const char *str, int *value) +bool atoi_clamp(const char *str, unsigned int *value) { bool success = pp::numeric_lex_int(str, value); if (!success) - *value = std::numeric_limits::max(); + *value = std::numeric_limits::max(); return success; } @@ -219,7 +219,6 @@ bool IsVaryingOut(TQualifier qualifier) switch (qualifier) { case EvqVaryingOut: - case EvqInvariantVaryingOut: case EvqSmoothOut: case EvqFlatOut: case EvqCentroidOut: @@ -237,7 +236,6 @@ bool IsVaryingIn(TQualifier qualifier) switch (qualifier) { case EvqVaryingIn: - case EvqInvariantVaryingIn: case EvqSmoothIn: case EvqFlatIn: case EvqCentroidIn: @@ -269,8 +267,6 @@ InterpolationType GetInterpolationType(TQualifier qualifier) case EvqFragmentIn: case EvqVaryingIn: case EvqVaryingOut: - case EvqInvariantVaryingIn: - case EvqInvariantVaryingOut: return INTERPOLATION_SMOOTH; case EvqCentroidIn: @@ -301,13 +297,13 @@ void GetVariableTraverser::setTypeSpecificInfo( ASSERT(variable); switch (type.getQualifier()) { - case EvqInvariantVaryingIn: - case EvqInvariantVaryingOut: - variable->isInvariant = true; - break; case EvqVaryingIn: case EvqVaryingOut: - if (mSymbolTable.isVaryingInvariant(std::string(name.c_str()))) + case EvqVertexOut: + case EvqSmoothOut: + case EvqFlatOut: + case EvqCentroidOut: + if (mSymbolTable.isVaryingInvariant(std::string(name.c_str())) || type.isInvariant()) { variable->isInvariant = true; } diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/util.h b/Source/ThirdParty/ANGLE/src/compiler/translator/util.h index 68bae6616895..ea7a35a352a0 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/translator/util.h +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/util.h @@ -14,15 +14,15 @@ #include "compiler/translator/Types.h" -// atof_clamp is like atof but +// strtof_clamp is like strtof but // 1. it forces C locale, i.e. forcing '.' as decimal point. // 2. it clamps the value to -FLT_MAX or FLT_MAX if overflow happens. // Return false if overflow happens. -extern bool atof_clamp(const char *str, float *value); +bool strtof_clamp(const std::string &str, float *value); -// If overflow happens, clamp the value to INT_MIN or INT_MAX. +// If overflow happens, clamp the value to UINT_MIN or UINT_MAX. // Return false if overflow happens. -extern bool atoi_clamp(const char *str, int *value); +bool atoi_clamp(const char *str, unsigned int *value); class TSymbolTable; @@ -41,6 +41,7 @@ class GetVariableTraverser : angle::NonCopyable { public: GetVariableTraverser(const TSymbolTable &symbolTable); + virtual ~GetVariableTraverser() {} template void traverse(const TType &type, const TString &name, std::vector *output); diff --git a/Source/ThirdParty/ANGLE/src/copy_compiler_dll.bat b/Source/ThirdParty/ANGLE/src/copy_compiler_dll.bat index 8106415c2db1..1aac1ab117c7 100644 --- a/Source/ThirdParty/ANGLE/src/copy_compiler_dll.bat +++ b/Source/ThirdParty/ANGLE/src/copy_compiler_dll.bat @@ -1,9 +1,9 @@ -@echo off -set _arch=%1 -set _arch=%_arch:Win32=x86% -copy %2"\Redist\D3D\"%_arch%"\d3dcompiler_47.dll" %3 > NUL -:: This is equivalent to `touch', see: -:: https://technet.microsoft.com/en-us/library/bb490886.aspx -:: This avoids rerunning because this batch file is also copied to the gen dir, -:: so it's timestamp would otherwise be newer than the dll. -copy /b %3\d3dcompiler_47.dll+,, %3\d3dcompiler_47.dll > NUL +@echo off +set _arch=%1 +set _arch=%_arch:Win32=x86% +copy %2"\Redist\D3D\"%_arch%"\d3dcompiler_47.dll" %3 > NUL +:: This is equivalent to `touch', see: +:: https://technet.microsoft.com/en-us/library/bb490886.aspx +:: This avoids rerunning because this batch file is also copied to the gen dir, +:: so it's timestamp would otherwise be newer than the dll. +copy /b %3\d3dcompiler_47.dll+,, %3\d3dcompiler_47.dll > NUL diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/AttributeMap.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/AttributeMap.cpp index 651a0120372d..710f5d5f5474 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/AttributeMap.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/AttributeMap.cpp @@ -13,33 +13,27 @@ AttributeMap::AttributeMap() { } -AttributeMap::AttributeMap(const EGLint *attributes) -{ - if (attributes) - { - for (const EGLint *curAttrib = attributes; curAttrib[0] != EGL_NONE; curAttrib += 2) - { - insert(curAttrib[0], curAttrib[1]); - } - } -} - -void AttributeMap::insert(EGLint key, EGLint value) +void AttributeMap::insert(EGLAttrib key, EGLAttrib value) { mAttributes[key] = value; } -bool AttributeMap::contains(EGLint key) const +bool AttributeMap::contains(EGLAttrib key) const { return (mAttributes.find(key) != mAttributes.end()); } -EGLint AttributeMap::get(EGLint key, EGLint defaultValue) const +EGLAttrib AttributeMap::get(EGLAttrib key, EGLAttrib defaultValue) const { - std::map::const_iterator iter = mAttributes.find(key); + std::map::const_iterator iter = mAttributes.find(key); return (mAttributes.find(key) != mAttributes.end()) ? iter->second : defaultValue; } +bool AttributeMap::isEmpty() const +{ + return mAttributes.empty(); +} + AttributeMap::const_iterator AttributeMap::begin() const { return mAttributes.begin(); @@ -50,4 +44,31 @@ AttributeMap::const_iterator AttributeMap::end() const return mAttributes.end(); } +// static +AttributeMap AttributeMap::CreateFromIntArray(const EGLint *attributes) +{ + AttributeMap map; + if (attributes) + { + for (const EGLint *curAttrib = attributes; curAttrib[0] != EGL_NONE; curAttrib += 2) + { + map.insert(static_cast(curAttrib[0]), static_cast(curAttrib[1])); + } + } + return map; +} + +// static +AttributeMap AttributeMap::CreateFromAttribArray(const EGLAttrib *attributes) +{ + AttributeMap map; + if (attributes) + { + for (const EGLAttrib *curAttrib = attributes; curAttrib[0] != EGL_NONE; curAttrib += 2) + { + map.insert(curAttrib[0], curAttrib[1]); + } + } + return map; +} } diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/AttributeMap.h b/Source/ThirdParty/ANGLE/src/libANGLE/AttributeMap.h index 72b6edc3c72d..831e62c48e70 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/AttributeMap.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/AttributeMap.h @@ -15,23 +15,26 @@ namespace egl { -class AttributeMap +class AttributeMap final { public: AttributeMap(); - explicit AttributeMap(const EGLint *attributes); - virtual void insert(EGLint key, EGLint value); - virtual bool contains(EGLint key) const; - virtual EGLint get(EGLint key, EGLint defaultValue) const; + void insert(EGLAttrib key, EGLAttrib value); + bool contains(EGLAttrib key) const; + EGLAttrib get(EGLAttrib key, EGLAttrib defaultValue) const; + bool isEmpty() const; - typedef std::map::const_iterator const_iterator; + typedef std::map::const_iterator const_iterator; const_iterator begin() const; const_iterator end() const; + static AttributeMap CreateFromIntArray(const EGLint *attributes); + static AttributeMap CreateFromAttribArray(const EGLAttrib *attributes); + private: - std::map mAttributes; + std::map mAttributes; }; } diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/BinaryStream.h b/Source/ThirdParty/ANGLE/src/libANGLE/BinaryStream.h index 50392e1d3f81..3e6ccc7446e4 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/BinaryStream.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/BinaryStream.h @@ -47,7 +47,7 @@ class BinaryInputStream : angle::NonCopyable template IntT readInt() { - int value; + int value = 0; read(&value); return static_cast(value); } @@ -60,7 +60,7 @@ class BinaryInputStream : angle::NonCopyable bool readBool() { - int value; + int value = 0; read(&value); return (value > 0); } @@ -92,7 +92,7 @@ class BinaryInputStream : angle::NonCopyable return; } - if (mOffset + length > mLength) + if (!rx::IsUnsignedAdditionSafe(mOffset, length) || mOffset + length > mLength) { mError = true; return; @@ -104,7 +104,7 @@ class BinaryInputStream : angle::NonCopyable void skip(size_t length) { - if (mOffset + length > mLength) + if (!rx::IsUnsignedAdditionSafe(mOffset, length) || mOffset + length > mLength) { mError = true; return; @@ -144,9 +144,15 @@ class BinaryInputStream : angle::NonCopyable { StaticAssertIsFundamental(); + if (!rx::IsUnsignedMultiplicationSafe(num, sizeof(T))) + { + mError = true; + return; + } + size_t length = num * sizeof(T); - if (mOffset + length > mLength) + if (!rx::IsUnsignedAdditionSafe(mOffset, length) || mOffset + length > mLength) { mError = true; return; diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/BinaryStream_unittest.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/BinaryStream_unittest.cpp new file mode 100644 index 000000000000..963f4891177c --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/libANGLE/BinaryStream_unittest.cpp @@ -0,0 +1,71 @@ +// +// Copyright (c) 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. +// + +// BinaryStream_unittest.cpp: Unit tests of the binary stream classes. + +#include + +#include "libANGLE/BinaryStream.h" + +namespace angle +{ + +// Test that errors are properly generated for overflows. +TEST(BinaryInputStream, Overflow) +{ + const uint8_t goodValue = 2; + const uint8_t badValue = 255; + + const size_t dataSize = 1024; + const size_t slopSize = 1024; + + std::vector data(dataSize + slopSize); + std::fill(data.begin(), data.begin() + dataSize, goodValue); + std::fill(data.begin() + dataSize, data.end(), badValue); + + std::vector outputData(dataSize); + + auto checkDataIsSafe = [=](uint8_t item) + { + return item == goodValue; + }; + + { + // One large read + gl::BinaryInputStream stream(data.data(), dataSize); + stream.readBytes(outputData.data(), dataSize); + ASSERT_FALSE(stream.error()); + ASSERT_TRUE(std::all_of(outputData.begin(), outputData.end(), checkDataIsSafe)); + ASSERT_TRUE(stream.endOfStream()); + } + + { + // Two half-sized reads + gl::BinaryInputStream stream(data.data(), dataSize); + stream.readBytes(outputData.data(), dataSize / 2); + ASSERT_FALSE(stream.error()); + stream.readBytes(outputData.data() + dataSize / 2, dataSize / 2); + ASSERT_FALSE(stream.error()); + ASSERT_TRUE(std::all_of(outputData.begin(), outputData.end(), checkDataIsSafe)); + ASSERT_TRUE(stream.endOfStream()); + } + + { + // One large read that is too big + gl::BinaryInputStream stream(data.data(), dataSize); + stream.readBytes(outputData.data(), dataSize + 1); + ASSERT_TRUE(stream.error()); + } + + { + // Two reads, one that overflows the offset + gl::BinaryInputStream stream(data.data(), dataSize); + stream.readBytes(outputData.data(), dataSize - 1); + ASSERT_FALSE(stream.error()); + stream.readBytes(outputData.data(), std::numeric_limits::max() - dataSize - 2); + } +} +} diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/Buffer.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/Buffer.cpp index 30dcbdc50321..589735c5a831 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/Buffer.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/Buffer.cpp @@ -18,6 +18,7 @@ namespace gl Buffer::Buffer(rx::BufferImpl *impl, GLuint id) : RefCountObject(id), mBuffer(impl), + mLabel(), mUsage(GL_STATIC_DRAW), mSize(0), mAccessFlags(0), @@ -34,6 +35,16 @@ Buffer::~Buffer() SafeDelete(mBuffer); } +void Buffer::setLabel(const std::string &label) +{ + mLabel = label; +} + +const std::string &Buffer::getLabel() const +{ + return mLabel; +} + Error Buffer::bufferData(const void *data, GLsizeiptr size, GLenum usage) { gl::Error error = mBuffer->setData(data, size, usage); @@ -93,8 +104,7 @@ Error Buffer::map(GLenum access) mMapLength = mSize; mAccess = access; mAccessFlags = GL_MAP_WRITE_BIT; - - mIndexRangeCache.invalidateRange(0, static_cast(mMapLength)); + mIndexRangeCache.clear(); return error; } @@ -151,4 +161,36 @@ Error Buffer::unmap(GLboolean *result) return error; } +void Buffer::onTransformFeedback() +{ + mIndexRangeCache.clear(); +} + +void Buffer::onPixelUnpack() +{ + mIndexRangeCache.clear(); +} + +Error Buffer::getIndexRange(GLenum type, + size_t offset, + size_t count, + bool primitiveRestartEnabled, + IndexRange *outRange) const +{ + if (mIndexRangeCache.findRange(type, offset, count, primitiveRestartEnabled, outRange)) + { + return gl::Error(GL_NO_ERROR); + } + + Error error = mBuffer->getIndexRange(type, offset, count, primitiveRestartEnabled, outRange); + if (error.isError()) + { + return error; + } + + mIndexRangeCache.addRange(type, offset, count, primitiveRestartEnabled, *outRange); + + return Error(GL_NO_ERROR); +} + } diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/Buffer.h b/Source/ThirdParty/ANGLE/src/libANGLE/Buffer.h index 029aff8c41c6..6c951ef5865c 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/Buffer.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/Buffer.h @@ -11,11 +11,11 @@ #ifndef LIBANGLE_BUFFER_H_ #define LIBANGLE_BUFFER_H_ +#include "common/angleutils.h" +#include "libANGLE/Debug.h" #include "libANGLE/Error.h" +#include "libANGLE/IndexRangeCache.h" #include "libANGLE/RefCountObject.h" -#include "libANGLE/renderer/IndexRangeCache.h" - -#include "common/angleutils.h" namespace rx { @@ -25,13 +25,15 @@ class BufferImpl; namespace gl { -class Buffer : public RefCountObject +class Buffer final : public RefCountObject, public LabeledObject { public: Buffer(rx::BufferImpl *impl, GLuint id); - virtual ~Buffer(); + void setLabel(const std::string &label) override; + const std::string &getLabel() const override; + Error bufferData(const void *data, GLsizeiptr size, GLenum usage); Error bufferSubData(const void *data, GLsizeiptr size, GLintptr offset); Error copyBufferSubData(Buffer* source, GLintptr sourceOffset, GLintptr destOffset, GLsizeiptr size); @@ -39,6 +41,15 @@ class Buffer : public RefCountObject Error mapRange(GLintptr offset, GLsizeiptr length, GLbitfield access); Error unmap(GLboolean *result); + void onTransformFeedback(); + void onPixelUnpack(); + + Error getIndexRange(GLenum type, + size_t offset, + size_t count, + bool primitiveRestartEnabled, + IndexRange *outRange) const; + GLenum getUsage() const { return mUsage; } GLbitfield getAccessFlags() const { return mAccessFlags; } GLenum getAccess() const { return mAccess; } @@ -50,12 +61,11 @@ class Buffer : public RefCountObject rx::BufferImpl *getImplementation() const { return mBuffer; } - rx::IndexRangeCache *getIndexRangeCache() { return &mIndexRangeCache; } - const rx::IndexRangeCache *getIndexRangeCache() const { return &mIndexRangeCache; } - private: rx::BufferImpl *mBuffer; + std::string mLabel; + GLenum mUsage; GLint64 mSize; GLbitfield mAccessFlags; @@ -65,7 +75,7 @@ class Buffer : public RefCountObject GLint64 mMapOffset; GLint64 mMapLength; - rx::IndexRangeCache mIndexRangeCache; + mutable IndexRangeCache mIndexRangeCache; }; } diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/Caps.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/Caps.cpp index 797d8dd14168..8f4ab045701a 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/Caps.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/Caps.cpp @@ -58,7 +58,7 @@ GLuint TextureCaps::getNearestSamples(GLuint requestedSamples) const void TextureCapsMap::insert(GLenum internalFormat, const TextureCaps &caps) { - mCapsMap.insert(std::make_pair(internalFormat, caps)); + mCapsMap[internalFormat] = caps; } void TextureCapsMap::remove(GLenum internalFormat) @@ -102,6 +102,7 @@ Extensions::Extensions() pixelBufferObject(false), mapBuffer(false), mapBufferRange(false), + colorBufferHalfFloat(false), textureHalfFloat(false), textureHalfFloatLinear(false), textureFloat(false), @@ -110,15 +111,22 @@ Extensions::Extensions() textureCompressionDXT1(false), textureCompressionDXT3(false), textureCompressionDXT5(false), + textureCompressionASTCHDR(false), + textureCompressionASTCLDR(false), + compressedETC1RGB8Texture(false), depthTextures(false), + depth32(false), + textureStorage(false), textureNPOT(false), drawBuffers(false), - textureStorage(false), textureFilterAnisotropic(false), maxTextureAnisotropy(false), occlusionQueryBoolean(false), fence(false), timerQuery(false), + disjointTimerQuery(false), + queryCounterBitsTimeElapsed(0), + queryCounterBitsTimestamp(0), robustness(false), blendMinMax(false), framebufferBlit(false), @@ -134,6 +142,22 @@ Extensions::Extensions() textureUsage(false), translatedShaderSource(false), fboRenderMipmap(false), + discardFramebuffer(false), + debugMarker(false), + eglImage(false), + eglImageExternal(false), + eglImageExternalEssl3(false), + eglStreamConsumerExternal(false), + unpackSubimage(false), + packSubimage(false), + vertexArrayObject(false), + debug(false), + maxDebugMessageLength(0), + maxDebugLoggedMessages(0), + maxDebugGroupStackDepth(0), + maxLabelLength(0), + noError(false), + lossyETCDecode(false), colorBufferFloat(false) { } @@ -142,53 +166,85 @@ std::vector Extensions::getStrings() const { std::vector extensionStrings; - // | Extension name | Supported flag | Output vector | - InsertExtensionString("GL_OES_element_index_uint", elementIndexUint, &extensionStrings); - InsertExtensionString("GL_OES_packed_depth_stencil", packedDepthStencil, &extensionStrings); - InsertExtensionString("GL_OES_get_program_binary", getProgramBinary, &extensionStrings); - InsertExtensionString("GL_OES_rgb8_rgba8", rgb8rgba8, &extensionStrings); - InsertExtensionString("GL_EXT_texture_format_BGRA8888", textureFormatBGRA8888, &extensionStrings); - InsertExtensionString("GL_EXT_read_format_bgra", readFormatBGRA, &extensionStrings); - InsertExtensionString("GL_NV_pixel_buffer_object", pixelBufferObject, &extensionStrings); - InsertExtensionString("GL_OES_mapbuffer", mapBuffer, &extensionStrings); - InsertExtensionString("GL_EXT_map_buffer_range", mapBufferRange, &extensionStrings); - InsertExtensionString("GL_OES_texture_half_float", textureHalfFloat, &extensionStrings); - InsertExtensionString("GL_OES_texture_half_float_linear", textureHalfFloatLinear, &extensionStrings); - InsertExtensionString("GL_OES_texture_float", textureFloat, &extensionStrings); - InsertExtensionString("GL_OES_texture_float_linear", textureFloatLinear, &extensionStrings); - InsertExtensionString("GL_EXT_texture_rg", textureRG, &extensionStrings); - InsertExtensionString("GL_EXT_texture_compression_dxt1", textureCompressionDXT1, &extensionStrings); - InsertExtensionString("GL_ANGLE_texture_compression_dxt3", textureCompressionDXT3, &extensionStrings); - InsertExtensionString("GL_ANGLE_texture_compression_dxt5", textureCompressionDXT5, &extensionStrings); - InsertExtensionString("GL_EXT_sRGB", sRGB, &extensionStrings); - InsertExtensionString("GL_ANGLE_depth_texture", depthTextures, &extensionStrings); - InsertExtensionString("GL_EXT_texture_storage", textureStorage, &extensionStrings); - InsertExtensionString("GL_OES_texture_npot", textureNPOT, &extensionStrings); - InsertExtensionString("GL_EXT_draw_buffers", drawBuffers, &extensionStrings); - InsertExtensionString("GL_EXT_texture_filter_anisotropic", textureFilterAnisotropic, &extensionStrings); - InsertExtensionString("GL_EXT_occlusion_query_boolean", occlusionQueryBoolean, &extensionStrings); - InsertExtensionString("GL_NV_fence", fence, &extensionStrings); - InsertExtensionString("GL_ANGLE_timer_query", timerQuery, &extensionStrings); - InsertExtensionString("GL_EXT_robustness", robustness, &extensionStrings); - InsertExtensionString("GL_EXT_blend_minmax", blendMinMax, &extensionStrings); - InsertExtensionString("GL_ANGLE_framebuffer_blit", framebufferBlit, &extensionStrings); - InsertExtensionString("GL_ANGLE_framebuffer_multisample", framebufferMultisample, &extensionStrings); - InsertExtensionString("GL_ANGLE_instanced_arrays", instancedArrays, &extensionStrings); - InsertExtensionString("GL_ANGLE_pack_reverse_row_order", packReverseRowOrder, &extensionStrings); - InsertExtensionString("GL_OES_standard_derivatives", standardDerivatives, &extensionStrings); - InsertExtensionString("GL_EXT_shader_texture_lod", shaderTextureLOD, &extensionStrings); - InsertExtensionString("GL_NV_shader_framebuffer_fetch", NVshaderFramebufferFetch, &extensionStrings); - InsertExtensionString("GL_ARM_shader_framebuffer_fetch", ARMshaderFramebufferFetch,&extensionStrings); - InsertExtensionString("GL_EXT_shader_framebuffer_fetch", shaderFramebufferFetch, &extensionStrings); - InsertExtensionString("GL_EXT_frag_depth", fragDepth, &extensionStrings); - InsertExtensionString("GL_ANGLE_texture_usage", textureUsage, &extensionStrings); - InsertExtensionString("GL_ANGLE_translated_shader_source", translatedShaderSource, &extensionStrings); - InsertExtensionString("GL_OES_fbo_render_mipmap", fboRenderMipmap, &extensionStrings); - InsertExtensionString("GL_EXT_color_buffer_float", colorBufferFloat, &extensionStrings); + // clang-format off + // | Extension name | Supported flag | Output vector | + InsertExtensionString("GL_OES_element_index_uint", elementIndexUint, &extensionStrings); + InsertExtensionString("GL_OES_packed_depth_stencil", packedDepthStencil, &extensionStrings); + InsertExtensionString("GL_OES_get_program_binary", getProgramBinary, &extensionStrings); + InsertExtensionString("GL_OES_rgb8_rgba8", rgb8rgba8, &extensionStrings); + InsertExtensionString("GL_EXT_texture_format_BGRA8888", textureFormatBGRA8888, &extensionStrings); + InsertExtensionString("GL_EXT_read_format_bgra", readFormatBGRA, &extensionStrings); + InsertExtensionString("GL_NV_pixel_buffer_object", pixelBufferObject, &extensionStrings); + InsertExtensionString("GL_OES_mapbuffer", mapBuffer, &extensionStrings); + InsertExtensionString("GL_EXT_map_buffer_range", mapBufferRange, &extensionStrings); + InsertExtensionString("GL_EXT_color_buffer_half_float", colorBufferHalfFloat, &extensionStrings); + InsertExtensionString("GL_OES_texture_half_float", textureHalfFloat, &extensionStrings); + InsertExtensionString("GL_OES_texture_half_float_linear", textureHalfFloatLinear, &extensionStrings); + InsertExtensionString("GL_OES_texture_float", textureFloat, &extensionStrings); + InsertExtensionString("GL_OES_texture_float_linear", textureFloatLinear, &extensionStrings); + InsertExtensionString("GL_EXT_texture_rg", textureRG, &extensionStrings); + InsertExtensionString("GL_EXT_texture_compression_dxt1", textureCompressionDXT1, &extensionStrings); + InsertExtensionString("GL_ANGLE_texture_compression_dxt3", textureCompressionDXT3, &extensionStrings); + InsertExtensionString("GL_ANGLE_texture_compression_dxt5", textureCompressionDXT5, &extensionStrings); + InsertExtensionString("GL_KHR_texture_compression_astc_hdr", textureCompressionASTCHDR, &extensionStrings); + InsertExtensionString("GL_KHR_texture_compression_astc_ldr", textureCompressionASTCLDR, &extensionStrings); + InsertExtensionString("GL_OES_compressed_ETC1_RGB8_texture", compressedETC1RGB8Texture, &extensionStrings); + InsertExtensionString("GL_EXT_sRGB", sRGB, &extensionStrings); + InsertExtensionString("GL_ANGLE_depth_texture", depthTextures, &extensionStrings); + InsertExtensionString("GL_OES_depth32", depth32, &extensionStrings); + InsertExtensionString("GL_EXT_texture_storage", textureStorage, &extensionStrings); + InsertExtensionString("GL_OES_texture_npot", textureNPOT, &extensionStrings); + InsertExtensionString("GL_EXT_draw_buffers", drawBuffers, &extensionStrings); + InsertExtensionString("GL_EXT_texture_filter_anisotropic", textureFilterAnisotropic, &extensionStrings); + InsertExtensionString("GL_EXT_occlusion_query_boolean", occlusionQueryBoolean, &extensionStrings); + InsertExtensionString("GL_NV_fence", fence, &extensionStrings); + InsertExtensionString("GL_ANGLE_timer_query", timerQuery, &extensionStrings); + InsertExtensionString("GL_EXT_disjoint_timer_query", disjointTimerQuery, &extensionStrings); + InsertExtensionString("GL_EXT_robustness", robustness, &extensionStrings); + InsertExtensionString("GL_EXT_blend_minmax", blendMinMax, &extensionStrings); + InsertExtensionString("GL_ANGLE_framebuffer_blit", framebufferBlit, &extensionStrings); + InsertExtensionString("GL_ANGLE_framebuffer_multisample", framebufferMultisample, &extensionStrings); + InsertExtensionString("GL_ANGLE_instanced_arrays", instancedArrays, &extensionStrings); + InsertExtensionString("GL_ANGLE_pack_reverse_row_order", packReverseRowOrder, &extensionStrings); + InsertExtensionString("GL_OES_standard_derivatives", standardDerivatives, &extensionStrings); + InsertExtensionString("GL_EXT_shader_texture_lod", shaderTextureLOD, &extensionStrings); + InsertExtensionString("GL_NV_shader_framebuffer_fetch", NVshaderFramebufferFetch, &extensionStrings); + InsertExtensionString("GL_ARM_shader_framebuffer_fetch", ARMshaderFramebufferFetch, &extensionStrings); + InsertExtensionString("GL_EXT_shader_framebuffer_fetch", shaderFramebufferFetch, &extensionStrings); + InsertExtensionString("GL_EXT_frag_depth", fragDepth, &extensionStrings); + InsertExtensionString("GL_ANGLE_texture_usage", textureUsage, &extensionStrings); + InsertExtensionString("GL_ANGLE_translated_shader_source", translatedShaderSource, &extensionStrings); + InsertExtensionString("GL_OES_fbo_render_mipmap", fboRenderMipmap, &extensionStrings); + InsertExtensionString("GL_EXT_discard_framebuffer", discardFramebuffer, &extensionStrings); + InsertExtensionString("GL_EXT_debug_marker", debugMarker, &extensionStrings); + InsertExtensionString("GL_OES_EGL_image", eglImage, &extensionStrings); + InsertExtensionString("GL_OES_EGL_image_external", eglImageExternal, &extensionStrings); + InsertExtensionString("GL_OES_EGL_image_external_essl3", eglImageExternalEssl3, &extensionStrings); + InsertExtensionString("GL_NV_EGL_stream_consumer_external", eglStreamConsumerExternal, &extensionStrings); + InsertExtensionString("GL_EXT_unpack_subimage", unpackSubimage, &extensionStrings); + InsertExtensionString("GL_NV_pack_subimage", packSubimage, &extensionStrings); + InsertExtensionString("GL_EXT_color_buffer_float", colorBufferFloat, &extensionStrings); + InsertExtensionString("GL_OES_vertex_array_object", vertexArrayObject, &extensionStrings); + InsertExtensionString("GL_KHR_debug", debug, &extensionStrings); + // TODO(jmadill): Enable this when complete. + //InsertExtensionString("GL_KHR_no_error", noError, &extensionStrings); + + InsertExtensionString("GL_ANGLE_lossy_etc_decode", lossyETCDecode, &extensionStrings); + // clang-format on return extensionStrings; } +Limitations::Limitations() + : noFrontFacingSupport(false), + noSampleAlphaToCoverageSupport(false), + attributeZeroRequiresZeroDivisorInEXT(false), + noSeparateStencilRefsAndMasks(false), + shadersRequireIndexedLoopValidation(false), + noSimultaneousConstantColorAndAlphaBlendFunc(false) +{ +} + static bool GetFormatSupport(const TextureCapsMap &textureCaps, const std::vector &requiredFormats, bool requiresTexturing, bool requiresFiltering, bool requiresRendering) { @@ -215,6 +271,15 @@ static bool GetFormatSupport(const TextureCapsMap &textureCaps, const std::vecto return true; } +// Check for GL_OES_packed_depth_stencil +static bool DeterminePackedDepthStencilSupport(const TextureCapsMap &textureCaps) +{ + std::vector requiredFormats; + requiredFormats.push_back(GL_DEPTH24_STENCIL8); + + return GetFormatSupport(textureCaps, requiredFormats, false, false, true); +} + // Checks for GL_OES_rgb8_rgba8 support static bool DetermineRGB8AndRGBA8TextureSupport(const TextureCapsMap &textureCaps) { @@ -234,6 +299,18 @@ static bool DetermineBGRA8TextureSupport(const TextureCapsMap &textureCaps) return GetFormatSupport(textureCaps, requiredFormats, true, true, true); } +// Checks for GL_OES_color_buffer_half_float support +static bool DetermineColorBufferHalfFloatSupport(const TextureCapsMap &textureCaps) +{ + std::vector requiredFormats; + requiredFormats.push_back(GL_RGBA16F); + requiredFormats.push_back(GL_RGB16F); + requiredFormats.push_back(GL_RG16F); + requiredFormats.push_back(GL_R16F); + + return GetFormatSupport(textureCaps, requiredFormats, true, false, true); +} + // Checks for GL_OES_texture_half_float support static bool DetermineHalfFloatTextureSupport(const TextureCapsMap &textureCaps) { @@ -251,7 +328,8 @@ static bool DetermineHalfFloatTextureFilteringSupport(const TextureCapsMap &text requiredFormats.push_back(GL_RGB16F); requiredFormats.push_back(GL_RGBA16F); - return GetFormatSupport(textureCaps, requiredFormats, true, true, false); + return DetermineHalfFloatTextureSupport(textureCaps) && + GetFormatSupport(textureCaps, requiredFormats, true, true, false); } // Checks for GL_OES_texture_float support @@ -271,7 +349,8 @@ static bool DetermineFloatTextureFilteringSupport(const TextureCapsMap &textureC requiredFormats.push_back(GL_RGB32F); requiredFormats.push_back(GL_RGBA32F); - return GetFormatSupport(textureCaps, requiredFormats, true, true, false); + return DetermineFloatTextureSupport(textureCaps) && + GetFormatSupport(textureCaps, requiredFormats, true, true, false); } // Checks for GL_EXT_texture_rg support @@ -322,6 +401,51 @@ static bool DetermineDXT5TextureSupport(const TextureCapsMap &textureCaps) return GetFormatSupport(textureCaps, requiredFormats, true, true, false); } +// Check for GL_KHR_texture_compression_astc_hdr and GL_KHR_texture_compression_astc_ldr +static bool DetermineASTCTextureSupport(const TextureCapsMap &textureCaps) +{ + std::vector requiredFormats; + requiredFormats.push_back(GL_COMPRESSED_RGBA_ASTC_4x4_KHR); + requiredFormats.push_back(GL_COMPRESSED_RGBA_ASTC_5x4_KHR); + requiredFormats.push_back(GL_COMPRESSED_RGBA_ASTC_5x5_KHR); + requiredFormats.push_back(GL_COMPRESSED_RGBA_ASTC_6x5_KHR); + requiredFormats.push_back(GL_COMPRESSED_RGBA_ASTC_6x6_KHR); + requiredFormats.push_back(GL_COMPRESSED_RGBA_ASTC_8x5_KHR); + requiredFormats.push_back(GL_COMPRESSED_RGBA_ASTC_8x6_KHR); + requiredFormats.push_back(GL_COMPRESSED_RGBA_ASTC_8x8_KHR); + requiredFormats.push_back(GL_COMPRESSED_RGBA_ASTC_10x5_KHR); + requiredFormats.push_back(GL_COMPRESSED_RGBA_ASTC_10x6_KHR); + requiredFormats.push_back(GL_COMPRESSED_RGBA_ASTC_10x8_KHR); + requiredFormats.push_back(GL_COMPRESSED_RGBA_ASTC_10x10_KHR); + requiredFormats.push_back(GL_COMPRESSED_RGBA_ASTC_12x10_KHR); + requiredFormats.push_back(GL_COMPRESSED_RGBA_ASTC_12x12_KHR); + requiredFormats.push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR); + requiredFormats.push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR); + requiredFormats.push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR); + requiredFormats.push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR); + requiredFormats.push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR); + requiredFormats.push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR); + requiredFormats.push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR); + requiredFormats.push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR); + requiredFormats.push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR); + requiredFormats.push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR); + requiredFormats.push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR); + requiredFormats.push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR); + requiredFormats.push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR); + requiredFormats.push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR); + + return GetFormatSupport(textureCaps, requiredFormats, true, true, false); +} + +// Check for GL_ETC1_RGB8_OES +static bool DetermineETC1RGB8TextureSupport(const TextureCapsMap &textureCaps) +{ + std::vector requiredFormats; + requiredFormats.push_back(GL_ETC1_RGB8_OES); + + return GetFormatSupport(textureCaps, requiredFormats, true, true, false); +} + // Check for GL_ANGLE_texture_compression_dxt5 static bool DetermineSRGBTextureSupport(const TextureCapsMap &textureCaps) { @@ -347,6 +471,15 @@ static bool DetermineDepthTextureSupport(const TextureCapsMap &textureCaps) return GetFormatSupport(textureCaps, requiredFormats, true, true, true); } +// Check for GL_OES_depth32 +static bool DetermineDepth32Support(const TextureCapsMap &textureCaps) +{ + std::vector requiredFormats; + requiredFormats.push_back(GL_DEPTH_COMPONENT32_OES); + + return GetFormatSupport(textureCaps, requiredFormats, false, false, true); +} + // Check for GL_EXT_color_buffer_float static bool DetermineColorBufferFloatSupport(const TextureCapsMap &textureCaps) { @@ -364,8 +497,10 @@ static bool DetermineColorBufferFloatSupport(const TextureCapsMap &textureCaps) void Extensions::setTextureExtensionSupport(const TextureCapsMap &textureCaps) { + packedDepthStencil = DeterminePackedDepthStencilSupport(textureCaps); rgb8rgba8 = DetermineRGB8AndRGBA8TextureSupport(textureCaps); textureFormatBGRA8888 = DetermineBGRA8TextureSupport(textureCaps); + colorBufferHalfFloat = DetermineColorBufferHalfFloatSupport(textureCaps); textureHalfFloat = DetermineHalfFloatTextureSupport(textureCaps); textureHalfFloatLinear = DetermineHalfFloatTextureFilteringSupport(textureCaps); textureFloat = DetermineFloatTextureSupport(textureCaps); @@ -374,8 +509,12 @@ void Extensions::setTextureExtensionSupport(const TextureCapsMap &textureCaps) textureCompressionDXT1 = DetermineDXT1TextureSupport(textureCaps); textureCompressionDXT3 = DetermineDXT3TextureSupport(textureCaps); textureCompressionDXT5 = DetermineDXT5TextureSupport(textureCaps); + textureCompressionASTCHDR = DetermineASTCTextureSupport(textureCaps); + textureCompressionASTCLDR = textureCompressionASTCHDR; + compressedETC1RGB8Texture = DetermineETC1RGB8TextureSupport(textureCaps); sRGB = DetermineSRGBTextureSupport(textureCaps); depthTextures = DetermineDepthTextureSupport(textureCaps); + depth32 = DetermineDepth32Support(textureCaps); colorBufferFloat = DetermineColorBufferFloatSupport(textureCaps); } @@ -483,9 +622,26 @@ DisplayExtensions::DisplayExtensions() surfaceD3DTexture2DShareHandle(false), querySurfacePointer(false), windowFixedSize(false), + keyedMutex(false), + surfaceOrientation(false), postSubBuffer(false), createContext(false), - deviceQuery(false) + deviceQuery(false), + image(false), + imageBase(false), + imagePixmap(false), + glTexture2DImage(false), + glTextureCubemapImage(false), + glTexture3DImage(false), + glRenderbufferImage(false), + getAllProcAddresses(false), + flexibleSurfaceCompatibility(false), + directComposition(false), + createContextNoError(false), + stream(false), + streamConsumerGLTexture(false), + streamConsumerGLTextureYUV(false), + streamProducerD3DTextureNV12(false) { } @@ -493,15 +649,34 @@ 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_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_NV_post_sub_buffer", postSubBuffer, &extensionStrings); InsertExtensionString("EGL_KHR_create_context", createContext, &extensionStrings); InsertExtensionString("EGL_EXT_device_query", deviceQuery, &extensionStrings); + InsertExtensionString("EGL_KHR_image", image, &extensionStrings); + InsertExtensionString("EGL_KHR_image_base", imageBase, &extensionStrings); + InsertExtensionString("EGL_KHR_image_pixmap", imagePixmap, &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_ANGLE_flexible_surface_compatibility", flexibleSurfaceCompatibility, &extensionStrings); + // TODO(jmadill): Enable this when complete. + //InsertExtensionString("KHR_create_context_no_error", createContextNoError, &extensionStrings); + // clang-format on return extensionStrings; } @@ -524,9 +699,15 @@ std::vector DeviceExtensions::getStrings() const ClientExtensions::ClientExtensions() : clientExtensions(false), platformBase(false), + platformDevice(false), platformANGLE(false), platformANGLED3D(false), - platformANGLEOpenGL(false) + platformANGLEOpenGL(false), + deviceCreation(false), + deviceCreationD3D11(false), + x11Visual(false), + experimentalPresentPath(false), + clientGetAllProcAddresses(false) { } @@ -534,12 +715,20 @@ std::vector ClientExtensions::getStrings() const { std::vector extensionStrings; - // | Extension name | Supported flag | Output vector | - InsertExtensionString("EGL_EXT_client_extensions", clientExtensions, &extensionStrings); - InsertExtensionString("EGL_EXT_platform_base", platformBase, &extensionStrings); - InsertExtensionString("EGL_ANGLE_platform_angle", platformANGLE, &extensionStrings); - InsertExtensionString("EGL_ANGLE_platform_angle_d3d", platformANGLED3D, &extensionStrings); - InsertExtensionString("EGL_ANGLE_platform_angle_opengl", platformANGLEOpenGL, &extensionStrings); + // clang-format off + // | Extension name | Supported flag | Output vector | + InsertExtensionString("EGL_EXT_client_extensions", clientExtensions, &extensionStrings); + InsertExtensionString("EGL_EXT_platform_base", platformBase, &extensionStrings); + InsertExtensionString("EGL_EXT_platform_device", platformDevice, &extensionStrings); + InsertExtensionString("EGL_ANGLE_platform_angle", platformANGLE, &extensionStrings); + InsertExtensionString("EGL_ANGLE_platform_angle_d3d", platformANGLED3D, &extensionStrings); + InsertExtensionString("EGL_ANGLE_platform_angle_opengl", platformANGLEOpenGL, &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); + // clang-format on return extensionStrings; } diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/Caps.h b/Source/ThirdParty/ANGLE/src/libANGLE/Caps.h index 3daf5b520bcc..f2e05c7f63c0 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/Caps.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/Caps.h @@ -73,14 +73,19 @@ struct Extensions // 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_compression_dxt1, GL_ANGLE_texture_compression_dxt3, GL_ANGLE_texture_compression_dxt5 + // GL_EXT_texture_compression_dxt1, GL_ANGLE_texture_compression_dxt3, + // GL_ANGLE_texture_compression_dxt5 + // GL_KHR_texture_compression_astc_hdr, GL_KHR_texture_compression_astc_ldr + // GL_OES_compressed_ETC1_RGB8_texture // GL_EXT_sRGB - // GL_ANGLE_depth_texture + // GL_ANGLE_depth_texture, GL_OES_depth32 // GL_EXT_color_buffer_float void setTextureExtensionSupport(const TextureCapsMap &textureCaps); @@ -113,6 +118,11 @@ struct Extensions bool mapBuffer; bool mapBufferRange; + // GL_EXT_color_buffer_half_float + // Together with GL_OES_texture_half_float in a GLES 2.0 context, implies that half-float + // textures are renderable. + bool colorBufferHalfFloat; + // GL_OES_texture_half_float and GL_OES_texture_half_float_linear // Implies that TextureCaps for GL_RGB16F, GL_RGBA16F, GL_ALPHA32F_EXT, GL_LUMINANCE32F_EXT and // GL_LUMINANCE_ALPHA32F_EXT exist @@ -137,6 +147,16 @@ struct Extensions bool textureCompressionDXT3; bool textureCompressionDXT5; + // GL_KHR_texture_compression_astc_hdr + bool textureCompressionASTCHDR; + + // GL_KHR_texture_compression_astc_ldr + bool textureCompressionASTCLDR; + + // GL_OES_compressed_ETC1_RGB8_texture + // Implies that TextureCaps for GL_ETC1_RGB8_OES exist + bool compressedETC1RGB8Texture; + // GL_EXT_sRGB // Implies that TextureCaps for GL_SRGB8_ALPHA8 and GL_SRGB8 exist // TODO: Don't advertise this extension in ES3 @@ -145,6 +165,10 @@ struct Extensions // GL_ANGLE_depth_texture bool depthTextures; + // GL_OES_depth32 + // Allows DEPTH_COMPONENT32_OES as a valid Renderbuffer format. + bool depth32; + // GL_EXT_texture_storage bool textureStorage; @@ -167,6 +191,11 @@ struct Extensions // GL_ANGLE_timer_query bool timerQuery; + // GL_EXT_disjoint_timer_query + bool disjointTimerQuery; + GLuint queryCounterBitsTimeElapsed; + GLuint queryCounterBitsTimestamp; + // GL_EXT_robustness bool robustness; @@ -212,12 +241,76 @@ struct Extensions // GL_OES_fbo_render_mipmap bool fboRenderMipmap; + // GL_EXT_discard_framebuffer + bool discardFramebuffer; + + // EXT_debug_marker + bool debugMarker; + + // GL_OES_EGL_image + bool eglImage; + + // GL_OES_EGL_image_external + bool eglImageExternal; + + // GL_OES_EGL_image_external_essl3 + bool eglImageExternalEssl3; + + // NV_EGL_stream_consumer_external + bool eglStreamConsumerExternal; + + // EXT_unpack_subimage + bool unpackSubimage; + + // NV_pack_subimage + bool packSubimage; + + // GL_OES_vertex_array_object + bool vertexArrayObject; + + // GL_KHR_debug + bool debug; + GLuint maxDebugMessageLength; + GLuint maxDebugLoggedMessages; + GLuint maxDebugGroupStackDepth; + GLuint maxLabelLength; + + // KHR_no_error + bool noError; + + // GL_ANGLE_lossy_etc_decode + bool lossyETCDecode; + // ES3 Extension support // GL_EXT_color_buffer_float bool colorBufferFloat; }; +struct Limitations +{ + Limitations(); + + // Renderer doesn't support gl_FrontFacing in fragment shaders + bool noFrontFacingSupport; + + // Renderer doesn't support GL_SAMPLE_ALPHA_TO_COVERAGE + bool noSampleAlphaToCoverageSupport; + + // In glVertexAttribDivisorANGLE, attribute zero must have a zero divisor + bool attributeZeroRequiresZeroDivisorInEXT; + + // Unable to support different values for front and back faces for stencil refs and masks + bool noSeparateStencilRefsAndMasks; + + // Renderer doesn't support non-constant indexing loops in fragment shader + bool shadersRequireIndexedLoopValidation; + + // 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; +}; + struct TypePrecision { TypePrecision(); @@ -345,6 +438,12 @@ struct DisplayExtensions // EGL_ANGLE_window_fixed_size bool windowFixedSize; + // EGL_ANGLE_keyed_mutex + bool keyedMutex; + + // EGL_ANGLE_surface_orientation + bool surfaceOrientation; + // EGL_NV_post_sub_buffer bool postSubBuffer; @@ -353,6 +452,51 @@ struct DisplayExtensions // EGL_EXT_device_query bool deviceQuery; + + // EGL_KHR_image + bool image; + + // EGL_KHR_image_base + bool imageBase; + + // EGL_KHR_image_pixmap + bool imagePixmap; + + // EGL_KHR_gl_texture_2D_image + bool glTexture2DImage; + + // EGL_KHR_gl_texture_cubemap_image + bool glTextureCubemapImage; + + // EGL_KHR_gl_texture_3D_image + bool glTexture3DImage; + + // EGL_KHR_gl_renderbuffer_image + bool glRenderbufferImage; + + // EGL_KHR_get_all_proc_addresses + bool getAllProcAddresses; + + // EGL_ANGLE_flexible_surface_compatibility + bool flexibleSurfaceCompatibility; + + // EGL_ANGLE_direct_composition + bool directComposition; + + // KHR_create_context_no_error + bool createContextNoError; + + // EGL_KHR_stream + bool stream; + + // EGL_KHR_stream_consumer_gltexture + bool streamConsumerGLTexture; + + // EGL_NV_stream_consumer_gltexture_yuv + bool streamConsumerGLTextureYUV; + + // EGL_ANGLE_stream_producer_d3d_texture_nv12 + bool streamProducerD3DTextureNV12; }; struct DeviceExtensions @@ -379,6 +523,9 @@ struct ClientExtensions // EGL_EXT_platform_base bool platformBase; + // EGL_EXT_platform_device + bool platformDevice; + // EGL_ANGLE_platform_angle bool platformANGLE; @@ -387,6 +534,21 @@ struct ClientExtensions // EGL_ANGLE_platform_angle_opengl bool platformANGLEOpenGL; + + // EGL_ANGLE_device_creation + bool deviceCreation; + + // EGL_ANGLE_device_creation_d3d11 + bool deviceCreationD3D11; + + // EGL_ANGLE_x11_visual + bool x11Visual; + + // EGL_ANGLE_experimental_present_path + bool experimentalPresentPath; + + // EGL_KHR_client_get_all_proc_addresses + bool clientGetAllProcAddresses; }; } diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/Compiler.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/Compiler.cpp index 7d0efea220e2..348c41bef33d 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/Compiler.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/Compiler.cpp @@ -7,32 +7,128 @@ // Compiler.cpp: implements the gl::Compiler class. #include "libANGLE/Compiler.h" -#include "libANGLE/renderer/CompilerImpl.h" #include "common/debug.h" +#include "libANGLE/Data.h" +#include "libANGLE/renderer/CompilerImpl.h" +#include "libANGLE/renderer/ImplFactory.h" namespace gl { -Compiler::Compiler(rx::CompilerImpl *impl) - : mCompiler(impl) +namespace +{ + +// Global count of active shader compiler handles. Needed to know when to call ShInitialize and +// ShFinalize. +size_t activeCompilerHandles = 0; + +} // anonymous namespace + +Compiler::Compiler(rx::ImplFactory *implFactory, const gl::Data &data) + : mImplementation(implFactory->createCompiler()), + mSpec(data.clientVersion > 2 ? SH_GLES3_SPEC : SH_GLES2_SPEC), + mOutputType(mImplementation->getTranslatorOutputType()), + mResources(), + mFragmentCompiler(nullptr), + mVertexCompiler(nullptr) { - ASSERT(mCompiler); + ASSERT(data.clientVersion == 2 || data.clientVersion == 3); + + const gl::Caps &caps = *data.caps; + const gl::Extensions &extensions = *data.extensions; + + ShInitBuiltInResources(&mResources); + mResources.MaxVertexAttribs = caps.maxVertexAttributes; + mResources.MaxVertexUniformVectors = caps.maxVertexUniformVectors; + mResources.MaxVaryingVectors = caps.maxVaryingVectors; + mResources.MaxVertexTextureImageUnits = caps.maxVertexTextureImageUnits; + mResources.MaxCombinedTextureImageUnits = caps.maxCombinedTextureImageUnits; + mResources.MaxTextureImageUnits = caps.maxTextureImageUnits; + mResources.MaxFragmentUniformVectors = caps.maxFragmentUniformVectors; + mResources.MaxDrawBuffers = caps.maxDrawBuffers; + mResources.OES_standard_derivatives = extensions.standardDerivatives; + mResources.EXT_draw_buffers = extensions.drawBuffers; + mResources.EXT_shader_texture_lod = extensions.shaderTextureLOD; + // TODO: disabled until the extension is actually supported. + mResources.OES_EGL_image_external = 0; + // TODO: use shader precision caps to determine if high precision is supported? + mResources.FragmentPrecisionHigh = 1; + mResources.EXT_frag_depth = extensions.fragDepth; + + // GLSL ES 3.0 constants + mResources.MaxVertexOutputVectors = caps.maxVertexOutputComponents / 4; + mResources.MaxFragmentInputVectors = caps.maxFragmentInputComponents / 4; + mResources.MinProgramTexelOffset = caps.minProgramTexelOffset; + mResources.MaxProgramTexelOffset = caps.maxProgramTexelOffset; } Compiler::~Compiler() { - SafeDelete(mCompiler); + release(); + SafeDelete(mImplementation); } Error Compiler::release() { - return mCompiler->release(); + if (mFragmentCompiler) + { + ShDestruct(mFragmentCompiler); + mFragmentCompiler = nullptr; + + ASSERT(activeCompilerHandles > 0); + activeCompilerHandles--; + } + + if (mVertexCompiler) + { + ShDestruct(mVertexCompiler); + mVertexCompiler = nullptr; + + ASSERT(activeCompilerHandles > 0); + activeCompilerHandles--; + } + + if (activeCompilerHandles == 0) + { + ShFinalize(); + } + + mImplementation->release(); + + return gl::Error(GL_NO_ERROR); } -rx::CompilerImpl *Compiler::getImplementation() +ShHandle Compiler::getCompilerHandle(GLenum type) { - return mCompiler; -} + ShHandle *compiler = nullptr; + switch (type) + { + case GL_VERTEX_SHADER: + compiler = &mVertexCompiler; + break; + case GL_FRAGMENT_SHADER: + compiler = &mFragmentCompiler; + break; + + default: + UNREACHABLE(); + return nullptr; + } + + if (!(*compiler)) + { + if (activeCompilerHandles == 0) + { + ShInitialize(); + } + + *compiler = ShConstructCompiler(type, mSpec, mOutputType, &mResources); + activeCompilerHandles++; + } + + return *compiler; } + +} // namespace gl diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/Compiler.h b/Source/ThirdParty/ANGLE/src/libANGLE/Compiler.h index 05de15ec977e..8634e39a4533 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/Compiler.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/Compiler.h @@ -11,29 +11,39 @@ #define LIBANGLE_COMPILER_H_ #include "libANGLE/Error.h" +#include "GLSLANG/ShaderLang.h" namespace rx { class CompilerImpl; +class ImplFactory; } namespace gl { +struct Data; -class Compiler final +class Compiler final : angle::NonCopyable { public: - explicit Compiler(rx::CompilerImpl *impl); + Compiler(rx::ImplFactory *implFactory, const Data &data); ~Compiler(); Error release(); - rx::CompilerImpl *getImplementation(); + ShHandle getCompilerHandle(GLenum type); + ShShaderOutput getShaderOutputType() const { return mOutputType; } private: - rx::CompilerImpl *mCompiler; + rx::CompilerImpl *mImplementation; + ShShaderSpec mSpec; + ShShaderOutput mOutputType; + ShBuiltInResources mResources; + + ShHandle mFragmentCompiler; + ShHandle mVertexCompiler; }; -} +} // namespace gl #endif // LIBANGLE_COMPILER_H_ diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/Config.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/Config.cpp index 2a68d5bd9acb..822518ef6156 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/Config.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/Config.cpp @@ -57,14 +57,15 @@ Config::Config() transparentType(EGL_NONE), transparentRedValue(0), transparentGreenValue(0), - transparentBlueValue(0) + transparentBlueValue(0), + optimalOrientation(0) { } 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); + EGLint id = static_cast(mConfigs.size()) + 1; Config copyConfig(config); copyConfig.configID = id; @@ -166,8 +167,8 @@ class ConfigSorter // components that are 0 or don't-care. for (auto attribIter = attributeMap.begin(); attribIter != attributeMap.end(); attribIter++) { - EGLint attributeKey = attribIter->first; - EGLint attributeValue = attribIter->second; + EGLAttrib attributeKey = attribIter->first; + EGLAttrib attributeValue = attribIter->second; if (attributeKey != 0 && attributeValue != EGL_DONT_CARE) { switch (attributeKey) @@ -214,8 +215,8 @@ std::vector ConfigSet::filter(const AttributeMap &attributeMap) c for (auto attribIter = attributeMap.begin(); attribIter != attributeMap.end(); attribIter++) { - EGLint attributeKey = attribIter->first; - EGLint attributeValue = attribIter->second; + EGLAttrib attributeKey = attribIter->first; + EGLAttrib attributeValue = attribIter->second; switch (attributeKey) { @@ -251,6 +252,9 @@ std::vector ConfigSet::filter(const AttributeMap &attributeMap) c 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; default: UNREACHABLE(); } diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/Config.h b/Source/ThirdParty/ANGLE/src/libANGLE/Config.h index aed8aedb1d90..00f5673b5968 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/Config.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/Config.h @@ -64,6 +64,7 @@ struct Config EGLint transparentRedValue; // Transparent red value EGLint transparentGreenValue; // Transparent green value EGLint transparentBlueValue; // Transparent blue value + EGLint optimalOrientation; // Optimal window surface orientation }; class ConfigSet diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/Config_unittest.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/Config_unittest.cpp index 0ebfdbfd9f82..4c49df6006ba 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/Config_unittest.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/Config_unittest.cpp @@ -59,7 +59,7 @@ static std::vector GenerateUniqueConfigs(size_t count) for (size_t i = 0; i < count; i++) { egl::Config config = GenerateGenericConfig(); - config.samples = i; + config.samples = static_cast(i); configs.push_back(config); } @@ -147,7 +147,7 @@ TEST(ConfigSetTest, Filtering_BitSizes) // Set the tested member of this config to i so it ranges from // [1, configsPerType] - config.*(testMembers[i].ConfigMember) = j + 1; + config.*(testMembers[i].ConfigMember) = static_cast(j) + 1; set.add(config); } @@ -158,7 +158,7 @@ TEST(ConfigSetTest, Filtering_BitSizes) for (size_t i = 0; i < ArraySize(testMembers); i++) { // Start with a filter of 1 to not grab the other members - for (size_t j = 0; j < configsPerType; j++) + for (EGLint j = 0; j < static_cast(configsPerType); j++) { egl::AttributeMap filter; filter.insert(testMembers[i].Name, j + 1); diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/Context.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/Context.cpp index c8ea993921b8..dcb6b21bb1bf 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/Context.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/Context.cpp @@ -33,22 +33,124 @@ #include "libANGLE/validationES.h" #include "libANGLE/renderer/Renderer.h" -namespace gl +namespace +{ + +template +gl::Error GetQueryObjectParameter(gl::Context *context, GLuint id, GLenum pname, T *params) +{ + gl::Query *queryObject = context->getQuery(id, false, GL_NONE); + ASSERT(queryObject != nullptr); + + switch (pname) + { + case GL_QUERY_RESULT_EXT: + return queryObject->getResult(params); + case GL_QUERY_RESULT_AVAILABLE_EXT: + { + bool available; + gl::Error error = queryObject->isResultAvailable(&available); + if (!error.isError()) + { + *params = static_cast(available ? GL_TRUE : GL_FALSE); + } + return error; + } + default: + UNREACHABLE(); + return gl::Error(GL_INVALID_OPERATION, "Unreachable Error"); + } +} + +void MarkTransformFeedbackBufferUsage(gl::TransformFeedback *transformFeedback) +{ + if (transformFeedback && transformFeedback->isActive() && !transformFeedback->isPaused()) + { + for (size_t tfBufferIndex = 0; tfBufferIndex < transformFeedback->getIndexedBufferCount(); + tfBufferIndex++) + { + const OffsetBindingPointer &buffer = + transformFeedback->getIndexedBuffer(tfBufferIndex); + if (buffer.get() != nullptr) + { + buffer->onTransformFeedback(); + } + } + } +} + +// Attribute map queries. +EGLint GetClientVersion(const egl::AttributeMap &attribs) +{ + return static_cast(attribs.get(EGL_CONTEXT_CLIENT_VERSION, 1)); +} + +GLenum GetResetStrategy(const egl::AttributeMap &attribs) +{ + EGLAttrib attrib = attribs.get(EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT, + EGL_NO_RESET_NOTIFICATION_EXT); + switch (attrib) + { + 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) +{ + return (attribs.get(EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT, EGL_FALSE) == EGL_TRUE); +} + +bool GetDebug(const egl::AttributeMap &attribs) { + return (attribs.get(EGL_CONTEXT_OPENGL_DEBUG, EGL_FALSE) == EGL_TRUE); +} -Context::Context(const egl::Config *config, int clientVersion, const Context *shareContext, rx::Renderer *renderer, bool notifyResets, bool robustAccess) - : mRenderer(renderer), - mData(clientVersion, mState, mCaps, mTextureCaps, mExtensions, nullptr) +bool GetNoError(const egl::AttributeMap &attribs) { - ASSERT(robustAccess == false); // Unimplemented + return (attribs.get(EGL_CONTEXT_OPENGL_NO_ERROR_KHR, EGL_FALSE) == EGL_TRUE); +} - initCaps(clientVersion); - mState.initialize(mCaps, clientVersion); +} // anonymous namespace - mClientVersion = clientVersion; +namespace gl +{ - mConfigID = config->configID; - mClientType = EGL_OPENGL_ES_API; +Context::Context(const egl::Config *config, + const Context *shareContext, + rx::Renderer *renderer, + const egl::AttributeMap &attribs) + : ValidationContext(GetClientVersion(attribs), + mState, + mCaps, + mTextureCaps, + mExtensions, + nullptr, + mLimitations, + GetNoError(attribs)), + mCompiler(nullptr), + mRenderer(renderer), + mClientVersion(GetClientVersion(attribs)), + mConfig(config), + mClientType(EGL_OPENGL_ES_API), + mHasBeenCurrent(false), + mContextLost(false), + mResetStatus(GL_NO_ERROR), + mResetStrategy(GetResetStrategy(attribs)), + mRobustAccess(GetRobustAccess(attribs)), + mCurrentSurface(nullptr), + mResourceManager(nullptr) +{ + ASSERT(!mRobustAccess); // Unimplemented + + initCaps(mClientVersion); + + mState.initialize(mCaps, mExtensions, mClientVersion, GetDebug(attribs)); mFenceNVHandleAllocator.setBaseHandle(0); @@ -88,15 +190,10 @@ Context::Context(const egl::Config *config, int clientVersion, const Context *sh mState.initializeZeroTextures(mZeroTextures); - // Allocate default FBO - mFramebufferMap[0] = new Framebuffer(mCaps, mRenderer, 0); - bindVertexArray(0); bindArrayBuffer(0); bindElementArrayBuffer(0); - bindReadFramebuffer(0); - bindDrawFramebuffer(0); bindRenderbuffer(0); bindGenericUniformBuffer(0); @@ -110,51 +207,91 @@ Context::Context(const egl::Config *config, int clientVersion, const Context *sh bindPixelPackBuffer(0); bindPixelUnpackBuffer(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 - mTransformFeedbackZero.set(new TransformFeedback(mRenderer->createTransformFeedback(), 0, mCaps)); - bindTransformFeedback(0); - - mHasBeenCurrent = false; - mContextLost = false; - mResetStatus = GL_NO_ERROR; - mResetStrategy = (notifyResets ? GL_LOSE_CONTEXT_ON_RESET_EXT : GL_NO_RESET_NOTIFICATION_EXT); - mRobustAccess = robustAccess; - - mCompiler = new Compiler(mRenderer->createCompiler(getData())); + if (mClientVersion >= 3) + { + // [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(0); + } + + mCompiler = new Compiler(mRenderer, getData()); + + // Initialize dirty bit masks + // TODO(jmadill): additional ES3 state + mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_ALIGNMENT); + mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_ROW_LENGTH); + mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_IMAGE_HEIGHT); + mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_IMAGES); + mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_ROWS); + mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_PIXELS); + // No dirty objects. + + // Readpixels uses the pack state and read FBO + mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_ALIGNMENT); + mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_REVERSE_ROW_ORDER); + mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_ROW_LENGTH); + mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_SKIP_ROWS); + mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_SKIP_PIXELS); + 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); + mClearDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER); + + mBlitDirtyBits.set(State::DIRTY_BIT_SCISSOR_TEST_ENABLED); + mBlitDirtyBits.set(State::DIRTY_BIT_SCISSOR); + mBlitDirtyObjects.set(State::DIRTY_OBJECT_READ_FRAMEBUFFER); + mBlitDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER); } Context::~Context() { mState.reset(); - while (!mFramebufferMap.empty()) + for (auto framebuffer : mFramebufferMap) { - // Delete the framebuffer in reverse order to destroy the framebuffer zero last. - deleteFramebuffer(mFramebufferMap.rbegin()->first); + // Default framebuffer are owned by their respective Surface + if (framebuffer.second != nullptr && framebuffer.second->id() != 0) + { + SafeDelete(framebuffer.second); + } } - while (!mFenceNVMap.empty()) + for (auto fence : mFenceNVMap) { - deleteFenceNV(mFenceNVMap.begin()->first); + SafeDelete(fence.second); } - while (!mQueryMap.empty()) + for (auto query : mQueryMap) { - deleteQuery(mQueryMap.begin()->first); + if (query.second != nullptr) + { + query.second->release(); + } } - while (!mVertexArrayMap.empty()) + for (auto vertexArray : mVertexArrayMap) { - deleteVertexArray(mVertexArrayMap.begin()->first); + SafeDelete(vertexArray.second); } - mTransformFeedbackZero.set(NULL); - while (!mTransformFeedbackMap.empty()) + for (auto transformFeedback : mTransformFeedbackMap) { - deleteTransformFeedback(mTransformFeedbackMap.begin()->first); + if (transformFeedback.second != nullptr) + { + transformFeedback.second->release(); + } } for (auto &zeroTexture : mZeroTextures) @@ -163,6 +300,11 @@ Context::~Context() } mZeroTextures.clear(); + if (mCurrentSurface != nullptr) + { + releaseSurface(); + } + if (mResourceManager) { mResourceManager->release(); @@ -186,50 +328,55 @@ void Context::makeCurrent(egl::Surface *surface) mHasBeenCurrent = true; } - // Update default framebuffer - Framebuffer *defaultFBO = mFramebufferMap[0]; + // TODO(jmadill): Rework this when we support ContextImpl + mState.setAllDirtyBits(); - GLenum drawBufferState = GL_BACK; - defaultFBO->setDrawBuffers(1, &drawBufferState); - defaultFBO->setReadBuffer(GL_BACK); - - const FramebufferAttachment *backAttachment = defaultFBO->getAttachment(GL_BACK); - - if (backAttachment && backAttachment->getSurface() == surface) + if (mCurrentSurface) { - // FBO already initialized to the surface. - return; + releaseSurface(); } + surface->setIsCurrent(true); + mCurrentSurface = surface; - const egl::Config *config = surface->getConfig(); - - defaultFBO->setAttachment(GL_FRAMEBUFFER_DEFAULT, GL_BACK, ImageIndex::MakeInvalid(), surface); - - if (config->depthSize > 0) - { - defaultFBO->setAttachment(GL_FRAMEBUFFER_DEFAULT, GL_DEPTH, ImageIndex::MakeInvalid(), surface); - } - else + // Update default framebuffer, the binding of the previous default + // framebuffer (or lack of) will have a nullptr. { - defaultFBO->resetAttachment(GL_DEPTH); + Framebuffer *newDefault = surface->getDefaultFramebuffer(); + if (mState.getReadFramebuffer() == nullptr) + { + mState.setReadFramebufferBinding(newDefault); + } + if (mState.getDrawFramebuffer() == nullptr) + { + mState.setDrawFramebufferBinding(newDefault); + } + mFramebufferMap[0] = newDefault; } - if (config->stencilSize > 0) - { - defaultFBO->setAttachment(GL_FRAMEBUFFER_DEFAULT, GL_STENCIL, ImageIndex::MakeInvalid(), surface); - } - else - { - defaultFBO->resetAttachment(GL_STENCIL); - } + // Notify the renderer of a context switch + mRenderer->onMakeCurrent(getData()); } void Context::releaseSurface() { - Framebuffer *defaultFBO = mFramebufferMap[0]; - defaultFBO->resetAttachment(GL_BACK); - defaultFBO->resetAttachment(GL_DEPTH); - defaultFBO->resetAttachment(GL_STENCIL); + ASSERT(mCurrentSurface != nullptr); + + // Remove the default framebuffer + { + Framebuffer *currentDefault = mCurrentSurface->getDefaultFramebuffer(); + if (mState.getReadFramebuffer() == currentDefault) + { + mState.setReadFramebufferBinding(nullptr); + } + if (mState.getDrawFramebuffer() == currentDefault) + { + mState.setDrawFramebufferBinding(nullptr); + } + mFramebufferMap.erase(0); + } + + mCurrentSurface->setIsCurrent(false); + mCurrentSurface = nullptr; } // NOTE: this function should not assume that this context is current! @@ -257,7 +404,7 @@ GLuint Context::createProgram() GLuint Context::createShader(GLenum type) { - return mResourceManager->createShader(getData(), type); + return mResourceManager->createShader(mRenderer->getRendererLimitations(), type); } GLuint Context::createTexture() @@ -279,14 +426,9 @@ GLsync Context::createFenceSync() GLuint Context::createVertexArray() { - GLuint handle = mVertexArrayHandleAllocator.allocate(); - - // Although the spec states VAO state is not initialized until the object is bound, - // we create it immediately. The resulting behaviour is transparent to the application, - // since it's not currently possible to access the state until the object is bound. - VertexArray *vertexArray = new VertexArray(mRenderer->createVertexArray(), handle, MAX_VERTEX_ATTRIBS); - mVertexArrayMap[handle] = vertexArray; - return handle; + GLuint vertexArray = mVertexArrayHandleAllocator.allocate(); + mVertexArrayMap[vertexArray] = nullptr; + return vertexArray; } GLuint Context::createSampler() @@ -296,11 +438,9 @@ GLuint Context::createSampler() GLuint Context::createTransformFeedback() { - GLuint handle = mTransformFeedbackAllocator.allocate(); - TransformFeedback *transformFeedback = new TransformFeedback(mRenderer->createTransformFeedback(), handle, mCaps); - transformFeedback->addRef(); - mTransformFeedbackMap[handle] = transformFeedback; - return handle; + GLuint transformFeedback = mTransformFeedbackAllocator.allocate(); + mTransformFeedbackMap[transformFeedback] = nullptr; + return transformFeedback; } // Returns an unused framebuffer name @@ -383,15 +523,18 @@ void Context::deleteFenceSync(GLsync fenceSync) void Context::deleteVertexArray(GLuint vertexArray) { - auto vertexArrayObject = mVertexArrayMap.find(vertexArray); - - if (vertexArrayObject != mVertexArrayMap.end()) + auto iter = mVertexArrayMap.find(vertexArray); + if (iter != mVertexArrayMap.end()) { - detachVertexArray(vertexArray); + VertexArray *vertexArrayObject = iter->second; + if (vertexArrayObject != nullptr) + { + detachVertexArray(vertexArray); + delete vertexArrayObject; + } - mVertexArrayHandleAllocator.release(vertexArrayObject->first); - delete vertexArrayObject->second; - mVertexArrayMap.erase(vertexArrayObject); + mVertexArrayMap.erase(iter); + mVertexArrayHandleAllocator.release(vertexArray); } } @@ -410,16 +553,21 @@ void Context::deleteTransformFeedback(GLuint transformFeedback) auto iter = mTransformFeedbackMap.find(transformFeedback); if (iter != mTransformFeedbackMap.end()) { - detachTransformFeedback(transformFeedback); - mTransformFeedbackAllocator.release(transformFeedback); - iter->second->release(); + TransformFeedback *transformFeedbackObject = iter->second; + if (transformFeedbackObject != nullptr) + { + detachTransformFeedback(transformFeedback); + transformFeedbackObject->release(); + } + mTransformFeedbackMap.erase(iter); + mTransformFeedbackAllocator.release(transformFeedback); } } void Context::deleteFramebuffer(GLuint framebuffer) { - FramebufferMap::iterator framebufferObject = mFramebufferMap.find(framebuffer); + auto framebufferObject = mFramebufferMap.find(framebuffer); if (framebufferObject != mFramebufferMap.end()) { @@ -433,7 +581,7 @@ void Context::deleteFramebuffer(GLuint framebuffer) void Context::deleteFenceNV(GLuint fence) { - FenceNVMap::iterator fenceObject = mFenceNVMap.find(fence); + auto fenceObject = mFenceNVMap.find(fence); if (fenceObject != mFenceNVMap.end()) { @@ -445,7 +593,7 @@ void Context::deleteFenceNV(GLuint fence) void Context::deleteQuery(GLuint query) { - QueryMap::iterator queryObject = mQueryMap.find(query); + auto queryObject = mQueryMap.find(query); if (queryObject != mQueryMap.end()) { mQueryHandleAllocator.release(queryObject->first); @@ -457,7 +605,7 @@ void Context::deleteQuery(GLuint query) } } -Buffer *Context::getBuffer(GLuint handle) +Buffer *Context::getBuffer(GLuint handle) const { return mResourceManager->getBuffer(handle); } @@ -477,7 +625,7 @@ Texture *Context::getTexture(GLuint handle) const return mResourceManager->getTexture(handle); } -Renderbuffer *Context::getRenderbuffer(GLuint handle) +Renderbuffer *Context::getRenderbuffer(GLuint handle) const { return mResourceManager->getRenderbuffer(handle); } @@ -490,15 +638,7 @@ FenceSync *Context::getFenceSync(GLsync handle) const VertexArray *Context::getVertexArray(GLuint handle) const { auto vertexArray = mVertexArrayMap.find(handle); - - if (vertexArray == mVertexArrayMap.end()) - { - return NULL; - } - else - { - return vertexArray->second; - } + return (vertexArray != mVertexArrayMap.end()) ? vertexArray->second : nullptr; } Sampler *Context::getSampler(GLuint handle) const @@ -508,39 +648,65 @@ Sampler *Context::getSampler(GLuint handle) const TransformFeedback *Context::getTransformFeedback(GLuint handle) const { - if (handle == 0) - { - return mTransformFeedbackZero.get(); - } - else + auto iter = mTransformFeedbackMap.find(handle); + return (iter != mTransformFeedbackMap.end()) ? iter->second : nullptr; +} + +LabeledObject *Context::getLabeledObject(GLenum identifier, GLuint name) const +{ + switch (identifier) { - TransformFeedbackMap::const_iterator iter = mTransformFeedbackMap.find(handle); - return (iter != mTransformFeedbackMap.end()) ? iter->second : NULL; + case GL_BUFFER: + return getBuffer(name); + case GL_SHADER: + return getShader(name); + case GL_PROGRAM: + return getProgram(name); + case GL_VERTEX_ARRAY: + return getVertexArray(name); + case GL_QUERY: + 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); + default: + UNREACHABLE(); + return nullptr; } } +LabeledObject *Context::getLabeledObjectFromPtr(const void *ptr) const +{ + return getFenceSync(reinterpret_cast(const_cast(ptr))); +} + bool Context::isSampler(GLuint samplerName) const { return mResourceManager->isSampler(samplerName); } -void Context::bindArrayBuffer(unsigned int buffer) +void Context::bindArrayBuffer(GLuint bufferHandle) { - mResourceManager->checkBufferAllocation(buffer); - - mState.setArrayBufferBinding(getBuffer(buffer)); + Buffer *buffer = mResourceManager->checkBufferAllocation(bufferHandle); + mState.setArrayBufferBinding(buffer); } -void Context::bindElementArrayBuffer(unsigned int buffer) +void Context::bindElementArrayBuffer(GLuint bufferHandle) { - mResourceManager->checkBufferAllocation(buffer); - - mState.getVertexArray()->setElementArrayBuffer(getBuffer(buffer)); + Buffer *buffer = mResourceManager->checkBufferAllocation(bufferHandle); + mState.getVertexArray()->setElementArrayBuffer(buffer); } void Context::bindTexture(GLenum target, GLuint handle) { - Texture *texture = NULL; + Texture *texture = nullptr; if (handle == 0) { @@ -548,115 +714,96 @@ void Context::bindTexture(GLenum target, GLuint handle) } else { - mResourceManager->checkTextureAllocation(handle, target); - texture = getTexture(handle); + texture = mResourceManager->checkTextureAllocation(handle, target); } ASSERT(texture); - mState.setSamplerTexture(target, texture); } -void Context::bindReadFramebuffer(GLuint framebuffer) +void Context::bindReadFramebuffer(GLuint framebufferHandle) { - if (!getFramebuffer(framebuffer)) - { - mFramebufferMap[framebuffer] = new Framebuffer(mCaps, mRenderer, framebuffer); - } - - mState.setReadFramebufferBinding(getFramebuffer(framebuffer)); + Framebuffer *framebuffer = checkFramebufferAllocation(framebufferHandle); + mState.setReadFramebufferBinding(framebuffer); } -void Context::bindDrawFramebuffer(GLuint framebuffer) +void Context::bindDrawFramebuffer(GLuint framebufferHandle) { - if (!getFramebuffer(framebuffer)) - { - mFramebufferMap[framebuffer] = new Framebuffer(mCaps, mRenderer, framebuffer); - } - - mState.setDrawFramebufferBinding(getFramebuffer(framebuffer)); + Framebuffer *framebuffer = checkFramebufferAllocation(framebufferHandle); + mState.setDrawFramebufferBinding(framebuffer); } -void Context::bindRenderbuffer(GLuint renderbuffer) +void Context::bindRenderbuffer(GLuint renderbufferHandle) { - mResourceManager->checkRenderbufferAllocation(renderbuffer); - - mState.setRenderbufferBinding(getRenderbuffer(renderbuffer)); + Renderbuffer *renderbuffer = mResourceManager->checkRenderbufferAllocation(renderbufferHandle); + mState.setRenderbufferBinding(renderbuffer); } -void Context::bindVertexArray(GLuint vertexArray) +void Context::bindVertexArray(GLuint vertexArrayHandle) { - if (!getVertexArray(vertexArray)) - { - VertexArray *vertexArrayObject = new VertexArray(mRenderer->createVertexArray(), vertexArray, MAX_VERTEX_ATTRIBS); - mVertexArrayMap[vertexArray] = vertexArrayObject; - } - - mState.setVertexArrayBinding(getVertexArray(vertexArray)); + VertexArray *vertexArray = checkVertexArrayAllocation(vertexArrayHandle); + mState.setVertexArrayBinding(vertexArray); } -void Context::bindSampler(GLuint textureUnit, GLuint sampler) +void Context::bindSampler(GLuint textureUnit, GLuint samplerHandle) { ASSERT(textureUnit < mCaps.maxCombinedTextureImageUnits); - mResourceManager->checkSamplerAllocation(sampler); - - mState.setSamplerBinding(textureUnit, getSampler(sampler)); + Sampler *sampler = mResourceManager->checkSamplerAllocation(samplerHandle); + mState.setSamplerBinding(textureUnit, sampler); } -void Context::bindGenericUniformBuffer(GLuint buffer) +void Context::bindGenericUniformBuffer(GLuint bufferHandle) { - mResourceManager->checkBufferAllocation(buffer); - - mState.setGenericUniformBufferBinding(getBuffer(buffer)); + Buffer *buffer = mResourceManager->checkBufferAllocation(bufferHandle); + mState.setGenericUniformBufferBinding(buffer); } -void Context::bindIndexedUniformBuffer(GLuint buffer, GLuint index, GLintptr offset, GLsizeiptr size) +void Context::bindIndexedUniformBuffer(GLuint bufferHandle, + GLuint index, + GLintptr offset, + GLsizeiptr size) { - mResourceManager->checkBufferAllocation(buffer); - - mState.setIndexedUniformBufferBinding(index, getBuffer(buffer), offset, size); + Buffer *buffer = mResourceManager->checkBufferAllocation(bufferHandle); + mState.setIndexedUniformBufferBinding(index, buffer, offset, size); } -void Context::bindGenericTransformFeedbackBuffer(GLuint buffer) +void Context::bindGenericTransformFeedbackBuffer(GLuint bufferHandle) { - mResourceManager->checkBufferAllocation(buffer); - - mState.getCurrentTransformFeedback()->bindGenericBuffer(getBuffer(buffer)); + Buffer *buffer = mResourceManager->checkBufferAllocation(bufferHandle); + mState.getCurrentTransformFeedback()->bindGenericBuffer(buffer); } -void Context::bindIndexedTransformFeedbackBuffer(GLuint buffer, GLuint index, GLintptr offset, GLsizeiptr size) +void Context::bindIndexedTransformFeedbackBuffer(GLuint bufferHandle, + GLuint index, + GLintptr offset, + GLsizeiptr size) { - mResourceManager->checkBufferAllocation(buffer); - - mState.getCurrentTransformFeedback()->bindIndexedBuffer(index, getBuffer(buffer), offset, size); + Buffer *buffer = mResourceManager->checkBufferAllocation(bufferHandle); + mState.getCurrentTransformFeedback()->bindIndexedBuffer(index, buffer, offset, size); } -void Context::bindCopyReadBuffer(GLuint buffer) +void Context::bindCopyReadBuffer(GLuint bufferHandle) { - mResourceManager->checkBufferAllocation(buffer); - - mState.setCopyReadBufferBinding(getBuffer(buffer)); + Buffer *buffer = mResourceManager->checkBufferAllocation(bufferHandle); + mState.setCopyReadBufferBinding(buffer); } -void Context::bindCopyWriteBuffer(GLuint buffer) +void Context::bindCopyWriteBuffer(GLuint bufferHandle) { - mResourceManager->checkBufferAllocation(buffer); - - mState.setCopyWriteBufferBinding(getBuffer(buffer)); + Buffer *buffer = mResourceManager->checkBufferAllocation(bufferHandle); + mState.setCopyWriteBufferBinding(buffer); } -void Context::bindPixelPackBuffer(GLuint buffer) +void Context::bindPixelPackBuffer(GLuint bufferHandle) { - mResourceManager->checkBufferAllocation(buffer); - - mState.setPixelPackBufferBinding(getBuffer(buffer)); + Buffer *buffer = mResourceManager->checkBufferAllocation(bufferHandle); + mState.setPixelPackBufferBinding(buffer); } -void Context::bindPixelUnpackBuffer(GLuint buffer) +void Context::bindPixelUnpackBuffer(GLuint bufferHandle) { - mResourceManager->checkBufferAllocation(buffer); - - mState.setPixelUnpackBufferBinding(getBuffer(buffer)); + Buffer *buffer = mResourceManager->checkBufferAllocation(bufferHandle); + mState.setPixelUnpackBufferBinding(buffer); } void Context::useProgram(GLuint program) @@ -664,9 +811,11 @@ void Context::useProgram(GLuint program) mState.setProgram(getProgram(program)); } -void Context::bindTransformFeedback(GLuint transformFeedback) +void Context::bindTransformFeedback(GLuint transformFeedbackHandle) { - mState.setTransformFeedbackBinding(getTransformFeedback(transformFeedback)); + TransformFeedback *transformFeedback = + checkTransformFeedbackAllocation(transformFeedbackHandle); + mState.setTransformFeedbackBinding(transformFeedback); } Error Context::beginQuery(GLenum target, GLuint query) @@ -700,23 +849,73 @@ Error Context::endQuery(GLenum target) return error; } -Framebuffer *Context::getFramebuffer(unsigned int handle) const +Error Context::queryCounter(GLuint id, GLenum target) { - FramebufferMap::const_iterator framebuffer = mFramebufferMap.find(handle); + ASSERT(target == GL_TIMESTAMP_EXT); - if (framebuffer == mFramebufferMap.end()) - { - return NULL; - } - else + Query *queryObject = getQuery(id, true, target); + ASSERT(queryObject); + + return queryObject->queryCounter(); +} + +void Context::getQueryiv(GLenum target, GLenum pname, GLint *params) +{ + switch (pname) { - return framebuffer->second; + case GL_CURRENT_QUERY_EXT: + params[0] = getState().getActiveQueryId(target); + break; + case GL_QUERY_COUNTER_BITS_EXT: + switch (target) + { + case GL_TIME_ELAPSED_EXT: + params[0] = getExtensions().queryCounterBitsTimeElapsed; + break; + case GL_TIMESTAMP_EXT: + params[0] = getExtensions().queryCounterBitsTimestamp; + break; + default: + UNREACHABLE(); + params[0] = 0; + break; + } + break; + default: + UNREACHABLE(); + return; } } +Error Context::getQueryObjectiv(GLuint id, GLenum pname, GLint *params) +{ + return GetQueryObjectParameter(this, id, pname, params); +} + +Error Context::getQueryObjectuiv(GLuint id, GLenum pname, GLuint *params) +{ + return GetQueryObjectParameter(this, id, pname, params); +} + +Error Context::getQueryObjecti64v(GLuint id, GLenum pname, GLint64 *params) +{ + return GetQueryObjectParameter(this, id, pname, params); +} + +Error Context::getQueryObjectui64v(GLuint id, GLenum pname, GLuint64 *params) +{ + return GetQueryObjectParameter(this, id, pname, params); +} + +Framebuffer *Context::getFramebuffer(unsigned int handle) const +{ + auto framebufferIt = mFramebufferMap.find(handle); + return ((framebufferIt == mFramebufferMap.end()) ? nullptr : framebufferIt->second); +} + FenceNV *Context::getFenceNV(unsigned int handle) { - FenceNVMap::iterator fence = mFenceNVMap.find(handle); + auto fence = mFenceNVMap.find(handle); if (fence == mFenceNVMap.end()) { @@ -730,7 +929,7 @@ FenceNV *Context::getFenceNV(unsigned int handle) Query *Context::getQuery(unsigned int handle, bool create, GLenum type) { - QueryMap::iterator query = mQueryMap.find(handle); + auto query = mQueryMap.find(handle); if (query == mQueryMap.end()) { @@ -747,11 +946,16 @@ Query *Context::getQuery(unsigned int handle, bool create, GLenum type) } } +Query *Context::getQuery(GLuint handle) const +{ + auto iter = mQueryMap.find(handle); + return (iter != mQueryMap.end()) ? iter->second : nullptr; +} + Texture *Context::getTargetTexture(GLenum target) const { ASSERT(ValidTextureTarget(this, target)); - - return getSamplerTexture(mState.getActiveSampler(), target); + return mState.getTargetTexture(target); } Texture *Context::getSamplerTexture(unsigned int sampler, GLenum type) const @@ -794,6 +998,9 @@ void Context::getFloatv(GLenum pname, GLfloat *params) ASSERT(mExtensions.textureFilterAnisotropic); *params = mExtensions.maxTextureAnisotropy; break; + case GL_MAX_TEXTURE_LOD_BIAS: + *params = mCaps.maxLODBias; + break; default: mState.getFloatv(pname, params); break; @@ -816,7 +1023,7 @@ void Context::getIntegerv(GLenum pname, GLint *params) case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: *params = mCaps.maxVertexTextureImageUnits; break; case GL_MAX_TEXTURE_IMAGE_UNITS: *params = mCaps.maxTextureImageUnits; break; case GL_MAX_FRAGMENT_UNIFORM_VECTORS: *params = mCaps.maxFragmentUniformVectors; break; - case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS: *params = mCaps.maxFragmentInputComponents; break; + case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS: *params = mCaps.maxFragmentUniformComponents; break; case GL_MAX_RENDERBUFFER_SIZE: *params = mCaps.maxRenderbufferSize; break; case GL_MAX_COLOR_ATTACHMENTS_EXT: *params = mCaps.maxColorAttachments; break; case GL_MAX_DRAW_BUFFERS_EXT: *params = mCaps.maxDrawBuffers; break; @@ -831,6 +1038,10 @@ void Context::getIntegerv(GLenum pname, GLint *params) case GL_MAX_VERTEX_UNIFORM_BLOCKS: *params = mCaps.maxVertexUniformBlocks; break; case GL_MAX_FRAGMENT_UNIFORM_BLOCKS: *params = mCaps.maxFragmentUniformBlocks; break; case GL_MAX_COMBINED_UNIFORM_BLOCKS: *params = mCaps.maxCombinedTextureImageUnits; break; + case GL_MAX_VERTEX_OUTPUT_COMPONENTS: *params = mCaps.maxVertexOutputComponents; break; + case GL_MAX_FRAGMENT_INPUT_COMPONENTS: *params = mCaps.maxFragmentInputComponents; break; + case GL_MIN_PROGRAM_TEXEL_OFFSET: *params = mCaps.minProgramTexelOffset; break; + case GL_MAX_PROGRAM_TEXEL_OFFSET: *params = mCaps.maxProgramTexelOffset; break; case GL_MAJOR_VERSION: *params = mClientVersion; break; case GL_MINOR_VERSION: *params = 0; break; case GL_MAX_ELEMENTS_INDICES: *params = mCaps.maxElementsIndices; break; @@ -838,7 +1049,9 @@ void Context::getIntegerv(GLenum pname, GLint *params) case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS: *params = mCaps.maxTransformFeedbackInterleavedComponents; break; case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS: *params = mCaps.maxTransformFeedbackSeparateAttributes; break; case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS: *params = mCaps.maxTransformFeedbackSeparateComponents; break; - case GL_NUM_COMPRESSED_TEXTURE_FORMATS: *params = static_cast(mCaps.compressedTextureFormats.size()); break; + case GL_NUM_COMPRESSED_TEXTURE_FORMATS: + *params = static_cast(mCaps.compressedTextureFormats.size()); + break; case GL_MAX_SAMPLES_ANGLE: *params = mCaps.maxSamples; break; case GL_MAX_VIEWPORT_DIMS: { @@ -853,13 +1066,13 @@ void Context::getIntegerv(GLenum pname, GLint *params) *params = mResetStrategy; break; case GL_NUM_SHADER_BINARY_FORMATS: - *params = static_cast(mCaps.shaderBinaryFormats.size()); + *params = static_cast(mCaps.shaderBinaryFormats.size()); break; case GL_SHADER_BINARY_FORMATS: std::copy(mCaps.shaderBinaryFormats.begin(), mCaps.shaderBinaryFormats.end(), params); break; case GL_NUM_PROGRAM_BINARY_FORMATS: - *params = static_cast(mCaps.programBinaryFormats.size()); + *params = static_cast(mCaps.programBinaryFormats.size()); break; case GL_PROGRAM_BINARY_FORMATS: std::copy(mCaps.programBinaryFormats.begin(), mCaps.programBinaryFormats.end(), params); @@ -867,6 +1080,26 @@ void Context::getIntegerv(GLenum pname, GLint *params) case GL_NUM_EXTENSIONS: *params = static_cast(mExtensionStrings.size()); break; + + // GL_KHR_debug + case GL_MAX_DEBUG_MESSAGE_LENGTH: + *params = mExtensions.maxDebugMessageLength; + break; + case GL_MAX_DEBUG_LOGGED_MESSAGES: + *params = mExtensions.maxDebugLoggedMessages; + break; + case GL_MAX_DEBUG_GROUP_STACK_DEPTH: + *params = mExtensions.maxDebugGroupStackDepth; + break; + case GL_MAX_LABEL_LENGTH: + *params = mExtensions.maxLabelLength; + break; + + // GL_EXT_disjoint_timer_query + case GL_GPU_DISJOINT_EXT: + *params = mRenderer->getGPUDisjoint(); + break; + default: mState.getIntegerv(getData(), pname, params); break; @@ -894,12 +1127,22 @@ void Context::getInteger64v(GLenum pname, GLint64 *params) case GL_MAX_SERVER_WAIT_TIMEOUT: *params = mCaps.maxServerWaitTimeout; break; + + // GL_EXT_disjoint_timer_query + case GL_TIMESTAMP_EXT: + *params = mRenderer->getTimestamp(); + break; default: UNREACHABLE(); break; } } +void Context::getPointerv(GLenum pname, void **params) const +{ + mState.getPointerv(pname, params); +} + bool Context::getIndexedIntegerv(GLenum target, GLuint index, GLint *data) { // Queries about context capabilities and maximums are answered by Context. @@ -1039,20 +1282,6 @@ bool Context::getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *nu } } return true; - case GL_PIXEL_PACK_BUFFER_BINDING: - case GL_PIXEL_UNPACK_BUFFER_BINDING: - { - if (mExtensions.pixelBufferObject) - { - *type = GL_INT; - *numParams = 1; - } - else - { - return false; - } - } - return true; case GL_MAX_VIEWPORT_DIMS: { *type = GL_INT; @@ -1123,6 +1352,87 @@ bool Context::getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *nu *type = GL_FLOAT; *numParams = 1; return true; + case GL_TIMESTAMP_EXT: + if (!mExtensions.disjointTimerQuery) + { + return false; + } + *type = GL_INT_64_ANGLEX; + *numParams = 1; + return true; + case GL_GPU_DISJOINT_EXT: + if (!mExtensions.disjointTimerQuery) + { + return false; + } + *type = GL_INT; + *numParams = 1; + return true; + } + + if (mExtensions.debug) + { + 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; + } + } + + // Check for ES3.0+ parameter names which are also exposed as ES2 extensions + switch (pname) + { + case GL_PACK_ROW_LENGTH: + case GL_PACK_SKIP_ROWS: + case GL_PACK_SKIP_PIXELS: + if ((mClientVersion < 3) && !mExtensions.packSubimage) + { + 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 ((mClientVersion < 3) && !mExtensions.unpackSubimage) + { + return false; + } + *type = GL_INT; + *numParams = 1; + return true; + case GL_VERTEX_ARRAY_BINDING: + if ((mClientVersion < 3) && !mExtensions.vertexArrayObject) + { + return false; + } + *type = GL_INT; + *numParams = 1; + return true; + case GL_PIXEL_PACK_BUFFER_BINDING: + case GL_PIXEL_UNPACK_BUFFER_BINDING: + if ((mClientVersion < 3) && !mExtensions.pixelBufferObject) + { + return false; + } + *type = GL_INT; + *numParams = 1; + return true; } if (mClientVersion < 3) @@ -1140,6 +1450,8 @@ bool Context::getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *nu 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_3D_TEXTURE_SIZE: @@ -1147,10 +1459,13 @@ bool Context::getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *nu 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_VERTEX_ARRAY_BINDING: 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: @@ -1159,6 +1474,8 @@ bool Context::getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *nu 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: { *type = GL_INT; *numParams = 1; @@ -1178,11 +1495,20 @@ bool Context::getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *nu 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: + { + *type = GL_FLOAT; + *numParams = 1; + } + return true; } return false; @@ -1217,16 +1543,67 @@ bool Context::getIndexedQueryParameterInfo(GLenum target, GLenum *type, unsigned return false; } -Error Context::drawArrays(GLenum mode, GLint first, GLsizei count, GLsizei instances) +Error Context::drawArrays(GLenum mode, GLint first, GLsizei count) +{ + syncRendererState(); + Error error = mRenderer->drawArrays(getData(), mode, first, count); + if (error.isError()) + { + return error; + } + + MarkTransformFeedbackBufferUsage(mState.getCurrentTransformFeedback()); + + return Error(GL_NO_ERROR); +} + +Error Context::drawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount) +{ + syncRendererState(); + Error error = mRenderer->drawArraysInstanced(getData(), mode, first, count, instanceCount); + if (error.isError()) + { + return error; + } + + MarkTransformFeedbackBufferUsage(mState.getCurrentTransformFeedback()); + + return Error(GL_NO_ERROR); +} + +Error Context::drawElements(GLenum mode, + GLsizei count, + GLenum type, + const GLvoid *indices, + const IndexRange &indexRange) +{ + syncRendererState(); + return mRenderer->drawElements(getData(), mode, count, type, indices, indexRange); +} + +Error Context::drawElementsInstanced(GLenum mode, + GLsizei count, + GLenum type, + const GLvoid *indices, + GLsizei instances, + const IndexRange &indexRange) { - return mRenderer->drawArrays(getData(), mode, first, count, instances); + syncRendererState(); + return mRenderer->drawElementsInstanced(getData(), mode, count, type, indices, instances, + indexRange); } -Error Context::drawElements(GLenum mode, GLsizei count, GLenum type, - const GLvoid *indices, GLsizei instances, - const rx::RangeUI &indexRange) +Error Context::drawRangeElements(GLenum mode, + GLuint start, + GLuint end, + GLsizei count, + GLenum type, + const GLvoid *indices, + const IndexRange &indexRange) { - return mRenderer->drawElements(getData(), mode, count, type, indices, instances, indexRange); + syncRendererState(); + return mRenderer->drawRangeElements(getData(), mode, start, end, count, type, indices, + indexRange); } Error Context::flush() @@ -1239,11 +1616,36 @@ Error Context::finish() return mRenderer->finish(); } +void Context::insertEventMarker(GLsizei length, const char *marker) +{ + ASSERT(mRenderer); + mRenderer->insertEventMarker(length, marker); +} + +void Context::pushGroupMarker(GLsizei length, const char *marker) +{ + ASSERT(mRenderer); + mRenderer->pushGroupMarker(length, marker); +} + +void Context::popGroupMarker() +{ + ASSERT(mRenderer); + mRenderer->popGroupMarker(); +} + void Context::recordError(const Error &error) { if (error.isError()) { mErrors.insert(error.getCode()); + + if (!error.getMessage().empty()) + { + auto &debug = mState.getDebug(); + debug.insertMessage(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_ERROR, error.getID(), + GL_DEBUG_SEVERITY_HIGH, error.getMessage()); + } } } @@ -1296,14 +1698,9 @@ bool Context::isResetNotificationEnabled() return (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT); } -int Context::getClientVersion() const -{ - return mClientVersion; -} - -EGLint Context::getConfigID() const +const egl::Config *Context::getConfig() const { - return mConfigID; + return mConfig; } EGLenum Context::getClientType() const @@ -1313,25 +1710,77 @@ EGLenum Context::getClientType() const EGLenum Context::getRenderBuffer() const { - ASSERT(mFramebufferMap.count(0) > 0); - const Framebuffer *framebuffer = mFramebufferMap.find(0)->second; - const FramebufferAttachment *backAttachment = framebuffer->getAttachment(GL_BACK); - return backAttachment ? backAttachment->getSurface()->getRenderBuffer() : EGL_NONE; -} + auto framebufferIt = mFramebufferMap.find(0); + if (framebufferIt != mFramebufferMap.end()) + { + const Framebuffer *framebuffer = framebufferIt->second; + const FramebufferAttachment *backAttachment = framebuffer->getAttachment(GL_BACK); -const Caps &Context::getCaps() const -{ - return mCaps; + ASSERT(backAttachment != nullptr); + return backAttachment->getSurface()->getRenderBuffer(); + } + else + { + return EGL_NONE; + } } -const TextureCapsMap &Context::getTextureCaps() const +VertexArray *Context::checkVertexArrayAllocation(GLuint vertexArrayHandle) { - return mTextureCaps; + // Only called after a prior call to Gen. + VertexArray *vertexArray = getVertexArray(vertexArrayHandle); + if (!vertexArray) + { + vertexArray = new VertexArray(mRenderer, vertexArrayHandle, MAX_VERTEX_ATTRIBS); + mVertexArrayMap[vertexArrayHandle] = vertexArray; + } + + return vertexArray; +} + +TransformFeedback *Context::checkTransformFeedbackAllocation(GLuint transformFeedbackHandle) +{ + // Only called after a prior call to Gen. + TransformFeedback *transformFeedback = getTransformFeedback(transformFeedbackHandle); + if (!transformFeedback) + { + transformFeedback = new TransformFeedback(mRenderer, transformFeedbackHandle, mCaps); + transformFeedback->addRef(); + mTransformFeedbackMap[transformFeedbackHandle] = transformFeedback; + } + + return transformFeedback; +} + +Framebuffer *Context::checkFramebufferAllocation(GLuint framebuffer) +{ + // Can be called from Bind without a prior call to Gen. + auto framebufferIt = mFramebufferMap.find(framebuffer); + bool neverCreated = framebufferIt == mFramebufferMap.end(); + if (neverCreated || framebufferIt->second == nullptr) + { + Framebuffer *newFBO = new Framebuffer(mCaps, mRenderer, framebuffer); + if (neverCreated) + { + mFramebufferHandleAllocator.reserve(framebuffer); + mFramebufferMap[framebuffer] = newFBO; + return newFBO; + } + + framebufferIt->second = newFBO; + } + + return framebufferIt->second; +} + +bool Context::isVertexArrayGenerated(GLuint vertexArray) +{ + return mVertexArrayMap.find(vertexArray) != mVertexArrayMap.end(); } -const Extensions &Context::getExtensions() const +bool Context::isTransformFeedbackGenerated(GLuint transformFeedback) { - return mExtensions; + return mTransformFeedbackMap.find(transformFeedback) != mTransformFeedbackMap.end(); } void Context::detachTexture(GLuint texture) @@ -1345,20 +1794,15 @@ void Context::detachTexture(GLuint texture) void Context::detachBuffer(GLuint buffer) { - // Buffer detachment is handled by Context, because the buffer must also be - // attached from any VAOs in existence, and Context holds the VAO map. + // 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 2.0.24] section 2.9 page 22: - // If a buffer object is deleted while it is bound, all bindings to that object in the current context - // (i.e. in the thread that called Delete-Buffers) are reset to zero. - - mState.removeArrayBufferBinding(buffer); - - // mark as freed among the vertex array objects - for (auto vaoIt = mVertexArrayMap.begin(); vaoIt != mVertexArrayMap.end(); vaoIt++) - { - vaoIt->second->detachBuffer(buffer); - } + // [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 + mState.detachBuffer(buffer); } void Context::detachFramebuffer(GLuint framebuffer) @@ -1414,7 +1858,7 @@ void Context::detachSampler(GLuint sampler) void Context::setVertexAttribDivisor(GLuint index, GLuint divisor) { - mState.getVertexArray()->setVertexAttribDivisor(index, divisor); + mState.setVertexAttribDivisor(index, divisor); } void Context::samplerParameteri(GLuint sampler, GLenum pname, GLint param) @@ -1424,19 +1868,22 @@ void Context::samplerParameteri(GLuint sampler, GLenum pname, GLint param) Sampler *samplerObject = getSampler(sampler); ASSERT(samplerObject); + // clang-format off switch (pname) { - case GL_TEXTURE_MIN_FILTER: samplerObject->setMinFilter(static_cast(param)); break; - case GL_TEXTURE_MAG_FILTER: samplerObject->setMagFilter(static_cast(param)); break; - case GL_TEXTURE_WRAP_S: samplerObject->setWrapS(static_cast(param)); break; - case GL_TEXTURE_WRAP_T: samplerObject->setWrapT(static_cast(param)); break; - case GL_TEXTURE_WRAP_R: samplerObject->setWrapR(static_cast(param)); break; - case GL_TEXTURE_MIN_LOD: samplerObject->setMinLod(static_cast(param)); break; - case GL_TEXTURE_MAX_LOD: samplerObject->setMaxLod(static_cast(param)); break; - case GL_TEXTURE_COMPARE_MODE: samplerObject->setComparisonMode(static_cast(param)); break; - case GL_TEXTURE_COMPARE_FUNC: samplerObject->setComparisonFunc(static_cast(param)); break; - default: UNREACHABLE(); break; + case GL_TEXTURE_MIN_FILTER: samplerObject->setMinFilter(static_cast(param)); break; + case GL_TEXTURE_MAG_FILTER: samplerObject->setMagFilter(static_cast(param)); break; + case GL_TEXTURE_WRAP_S: samplerObject->setWrapS(static_cast(param)); break; + case GL_TEXTURE_WRAP_T: samplerObject->setWrapT(static_cast(param)); break; + case GL_TEXTURE_WRAP_R: samplerObject->setWrapR(static_cast(param)); break; + case GL_TEXTURE_MAX_ANISOTROPY_EXT: samplerObject->setMaxAnisotropy(std::min(static_cast(param), getExtensions().maxTextureAnisotropy)); break; + case GL_TEXTURE_MIN_LOD: samplerObject->setMinLod(static_cast(param)); break; + case GL_TEXTURE_MAX_LOD: samplerObject->setMaxLod(static_cast(param)); break; + case GL_TEXTURE_COMPARE_MODE: samplerObject->setCompareMode(static_cast(param)); break; + case GL_TEXTURE_COMPARE_FUNC: samplerObject->setCompareFunc(static_cast(param)); break; + default: UNREACHABLE(); break; } + // clang-format on } void Context::samplerParameterf(GLuint sampler, GLenum pname, GLfloat param) @@ -1446,19 +1893,22 @@ void Context::samplerParameterf(GLuint sampler, GLenum pname, GLfloat param) Sampler *samplerObject = getSampler(sampler); ASSERT(samplerObject); + // clang-format off switch (pname) { - case GL_TEXTURE_MIN_FILTER: samplerObject->setMinFilter(uiround(param)); break; - case GL_TEXTURE_MAG_FILTER: samplerObject->setMagFilter(uiround(param)); break; - case GL_TEXTURE_WRAP_S: samplerObject->setWrapS(uiround(param)); break; - case GL_TEXTURE_WRAP_T: samplerObject->setWrapT(uiround(param)); break; - case GL_TEXTURE_WRAP_R: samplerObject->setWrapR(uiround(param)); break; - case GL_TEXTURE_MIN_LOD: samplerObject->setMinLod(param); break; - case GL_TEXTURE_MAX_LOD: samplerObject->setMaxLod(param); break; - case GL_TEXTURE_COMPARE_MODE: samplerObject->setComparisonMode(uiround(param)); break; - case GL_TEXTURE_COMPARE_FUNC: samplerObject->setComparisonFunc(uiround(param)); break; - default: UNREACHABLE(); break; + case GL_TEXTURE_MIN_FILTER: samplerObject->setMinFilter(uiround(param)); break; + case GL_TEXTURE_MAG_FILTER: samplerObject->setMagFilter(uiround(param)); break; + case GL_TEXTURE_WRAP_S: samplerObject->setWrapS(uiround(param)); break; + case GL_TEXTURE_WRAP_T: samplerObject->setWrapT(uiround(param)); break; + case GL_TEXTURE_WRAP_R: samplerObject->setWrapR(uiround(param)); break; + case GL_TEXTURE_MAX_ANISOTROPY_EXT: samplerObject->setMaxAnisotropy(std::min(param, getExtensions().maxTextureAnisotropy)); break; + case GL_TEXTURE_MIN_LOD: samplerObject->setMinLod(param); break; + case GL_TEXTURE_MAX_LOD: samplerObject->setMaxLod(param); break; + case GL_TEXTURE_COMPARE_MODE: samplerObject->setCompareMode(uiround(param)); break; + case GL_TEXTURE_COMPARE_FUNC: samplerObject->setCompareFunc(uiround(param)); break; + default: UNREACHABLE(); break; } + // clang-format on } GLint Context::getSamplerParameteri(GLuint sampler, GLenum pname) @@ -1468,19 +1918,22 @@ GLint Context::getSamplerParameteri(GLuint sampler, GLenum pname) Sampler *samplerObject = getSampler(sampler); ASSERT(samplerObject); + // clang-format off switch (pname) { - case GL_TEXTURE_MIN_FILTER: return static_cast(samplerObject->getMinFilter()); - case GL_TEXTURE_MAG_FILTER: return static_cast(samplerObject->getMagFilter()); - case GL_TEXTURE_WRAP_S: return static_cast(samplerObject->getWrapS()); - case GL_TEXTURE_WRAP_T: return static_cast(samplerObject->getWrapT()); - case GL_TEXTURE_WRAP_R: return static_cast(samplerObject->getWrapR()); - case GL_TEXTURE_MIN_LOD: return uiround(samplerObject->getMinLod()); - case GL_TEXTURE_MAX_LOD: return uiround(samplerObject->getMaxLod()); - case GL_TEXTURE_COMPARE_MODE: return static_cast(samplerObject->getComparisonMode()); - case GL_TEXTURE_COMPARE_FUNC: return static_cast(samplerObject->getComparisonFunc()); - default: UNREACHABLE(); return 0; + case GL_TEXTURE_MIN_FILTER: return static_cast(samplerObject->getMinFilter()); + case GL_TEXTURE_MAG_FILTER: return static_cast(samplerObject->getMagFilter()); + case GL_TEXTURE_WRAP_S: return static_cast(samplerObject->getWrapS()); + case GL_TEXTURE_WRAP_T: return static_cast(samplerObject->getWrapT()); + case GL_TEXTURE_WRAP_R: return static_cast(samplerObject->getWrapR()); + case GL_TEXTURE_MAX_ANISOTROPY_EXT: return static_cast(samplerObject->getMaxAnisotropy()); + case GL_TEXTURE_MIN_LOD: return iround(samplerObject->getMinLod()); + case GL_TEXTURE_MAX_LOD: return iround(samplerObject->getMaxLod()); + case GL_TEXTURE_COMPARE_MODE: return static_cast(samplerObject->getCompareMode()); + case GL_TEXTURE_COMPARE_FUNC: return static_cast(samplerObject->getCompareFunc()); + default: UNREACHABLE(); return 0; } + // clang-format on } GLfloat Context::getSamplerParameterf(GLuint sampler, GLenum pname) @@ -1490,19 +1943,31 @@ GLfloat Context::getSamplerParameterf(GLuint sampler, GLenum pname) Sampler *samplerObject = getSampler(sampler); ASSERT(samplerObject); + // clang-format off switch (pname) { - case GL_TEXTURE_MIN_FILTER: return static_cast(samplerObject->getMinFilter()); - case GL_TEXTURE_MAG_FILTER: return static_cast(samplerObject->getMagFilter()); - case GL_TEXTURE_WRAP_S: return static_cast(samplerObject->getWrapS()); - case GL_TEXTURE_WRAP_T: return static_cast(samplerObject->getWrapT()); - case GL_TEXTURE_WRAP_R: return static_cast(samplerObject->getWrapR()); - case GL_TEXTURE_MIN_LOD: return samplerObject->getMinLod(); - case GL_TEXTURE_MAX_LOD: return samplerObject->getMaxLod(); - case GL_TEXTURE_COMPARE_MODE: return static_cast(samplerObject->getComparisonMode()); - case GL_TEXTURE_COMPARE_FUNC: return static_cast(samplerObject->getComparisonFunc()); - default: UNREACHABLE(); return 0; + case GL_TEXTURE_MIN_FILTER: return static_cast(samplerObject->getMinFilter()); + case GL_TEXTURE_MAG_FILTER: return static_cast(samplerObject->getMagFilter()); + case GL_TEXTURE_WRAP_S: return static_cast(samplerObject->getWrapS()); + case GL_TEXTURE_WRAP_T: return static_cast(samplerObject->getWrapT()); + case GL_TEXTURE_WRAP_R: return static_cast(samplerObject->getWrapR()); + case GL_TEXTURE_MAX_ANISOTROPY_EXT: return samplerObject->getMaxAnisotropy(); + case GL_TEXTURE_MIN_LOD: return samplerObject->getMinLod(); + case GL_TEXTURE_MAX_LOD: return samplerObject->getMaxLod(); + case GL_TEXTURE_COMPARE_MODE: return static_cast(samplerObject->getCompareMode()); + case GL_TEXTURE_COMPARE_FUNC: return static_cast(samplerObject->getCompareFunc()); + default: UNREACHABLE(); return 0; } + // clang-format on +} + +void Context::programParameteri(GLuint program, GLenum pname, GLint value) +{ + gl::Program *programObject = getProgram(program); + ASSERT(programObject != nullptr); + + ASSERT(pname == GL_PROGRAM_BINARY_RETRIEVABLE_HINT); + programObject->setBinaryRetrievableHint(value != GL_FALSE); } void Context::initRendererString() @@ -1544,12 +2009,35 @@ size_t Context::getExtensionStringCount() const return mExtensionStrings.size(); } +void Context::beginTransformFeedback(GLenum primitiveMode) +{ + TransformFeedback *transformFeedback = getState().getCurrentTransformFeedback(); + ASSERT(transformFeedback != nullptr); + ASSERT(!transformFeedback->isPaused()); + + transformFeedback->begin(primitiveMode, getState().getProgram()); +} + +bool Context::hasActiveTransformFeedback(GLuint program) const +{ + for (auto pair : mTransformFeedbackMap) + { + if (pair.second != nullptr && pair.second->hasBoundProgram(program)) + { + return true; + } + } + return false; +} + void Context::initCaps(GLuint clientVersion) { mCaps = mRenderer->getRendererCaps(); mExtensions = mRenderer->getRendererExtensions(); + mLimitations = mRenderer->getRendererLimitations(); + if (clientVersion < 3) { // Disable ES3+ extensions @@ -1562,6 +2050,13 @@ void Context::initCaps(GLuint clientVersion) //mExtensions.sRGB = false; } + // Explicitly enable GL_KHR_debug + mExtensions.debug = true; + mExtensions.maxDebugMessageLength = 1024; + mExtensions.maxDebugLoggedMessages = 1024; + mExtensions.maxDebugGroupStackDepth = 1024; + mExtensions.maxLabelLength = 1024; + // Apply implementation limits mCaps.maxVertexAttributes = std::min(mCaps.maxVertexAttributes, MAX_VERTEX_ATTRIBS); mCaps.maxVertexUniformBlocks = std::min(mCaps.maxVertexUniformBlocks, IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS); @@ -1579,10 +2074,15 @@ void Context::initCaps(GLuint clientVersion) const InternalFormat &formatInfo = GetInternalFormatInfo(format); - // Update the format caps based on the client version and extensions - formatCaps.texturable = formatInfo.textureSupport(clientVersion, mExtensions); - formatCaps.renderable = formatInfo.renderSupport(clientVersion, mExtensions); - formatCaps.filterable = formatInfo.filterSupport(clientVersion, mExtensions); + // 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(clientVersion, mExtensions); + formatCaps.renderable = + formatCaps.renderable && formatInfo.renderSupport(clientVersion, mExtensions); + formatCaps.filterable = + formatCaps.filterable && formatInfo.filterSupport(clientVersion, mExtensions); // OpenGL ES does not support multisampling with integer formats if (!formatInfo.renderSupport || formatInfo.componentType == GL_INT || formatInfo.componentType == GL_UNSIGNED_INT) @@ -1599,4 +2099,678 @@ void Context::initCaps(GLuint clientVersion) } } +void Context::syncRendererState() +{ + const State::DirtyBits &dirtyBits = mState.getDirtyBits(); + mRenderer->syncState(mState, dirtyBits); + mState.clearDirtyBits(); + mState.syncDirtyObjects(); +} + +void Context::syncRendererState(const State::DirtyBits &bitMask, + const State::DirtyObjects &objectMask) +{ + const State::DirtyBits &dirtyBits = (mState.getDirtyBits() & bitMask); + mRenderer->syncState(mState, dirtyBits); + mState.clearDirtyBits(dirtyBits); + + mState.syncDirtyObjects(objectMask); +} + +void Context::blitFramebuffer(GLint srcX0, + GLint srcY0, + GLint srcX1, + GLint srcY1, + GLint dstX0, + GLint dstY0, + GLint dstX1, + GLint dstY1, + GLbitfield mask, + GLenum filter) +{ + Framebuffer *readFramebuffer = mState.getReadFramebuffer(); + ASSERT(readFramebuffer); + + Framebuffer *drawFramebuffer = mState.getDrawFramebuffer(); + ASSERT(drawFramebuffer); + + Rectangle srcArea(srcX0, srcY0, srcX1 - srcX0, srcY1 - srcY0); + Rectangle dstArea(dstX0, dstY0, dstX1 - dstX0, dstY1 - dstY0); + + syncStateForBlit(); + + Error error = drawFramebuffer->blit(mState, srcArea, dstArea, mask, filter, readFramebuffer); + if (error.isError()) + { + recordError(error); + return; + } +} + +void Context::clear(GLbitfield mask) +{ + syncStateForClear(); + + Error error = mState.getDrawFramebuffer()->clear(mData, mask); + if (error.isError()) + { + recordError(error); + } +} + +void Context::clearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *values) +{ + syncStateForClear(); + + Error error = mState.getDrawFramebuffer()->clearBufferfv(mData, buffer, drawbuffer, values); + if (error.isError()) + { + recordError(error); + } +} + +void Context::clearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *values) +{ + syncStateForClear(); + + Error error = mState.getDrawFramebuffer()->clearBufferuiv(mData, buffer, drawbuffer, values); + if (error.isError()) + { + recordError(error); + } +} + +void Context::clearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *values) +{ + syncStateForClear(); + + Error error = mState.getDrawFramebuffer()->clearBufferiv(mData, buffer, drawbuffer, values); + if (error.isError()) + { + recordError(error); + } +} + +void Context::clearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil) +{ + Framebuffer *framebufferObject = mState.getDrawFramebuffer(); + ASSERT(framebufferObject); + + // If a buffer is not present, the clear has no effect + if (framebufferObject->getDepthbuffer() == nullptr && + framebufferObject->getStencilbuffer() == nullptr) + { + return; + } + + syncStateForClear(); + + Error error = framebufferObject->clearBufferfi(mData, buffer, drawbuffer, depth, stencil); + if (error.isError()) + { + recordError(error); + } +} + +void Context::readPixels(GLint x, + GLint y, + GLsizei width, + GLsizei height, + GLenum format, + GLenum type, + GLvoid *pixels) +{ + syncStateForReadPixels(); + + Framebuffer *framebufferObject = mState.getReadFramebuffer(); + ASSERT(framebufferObject); + + Rectangle area(x, y, width, height); + Error error = framebufferObject->readPixels(mState, area, format, type, pixels); + if (error.isError()) + { + recordError(error); + } +} + +void Context::copyTexImage2D(GLenum target, + GLint level, + GLenum internalformat, + GLint x, + GLint y, + GLsizei width, + GLsizei height, + GLint border) +{ + // Only sync the read FBO + mState.syncDirtyObject(GL_READ_FRAMEBUFFER); + + Rectangle sourceArea(x, y, width, height); + + const Framebuffer *framebuffer = mState.getReadFramebuffer(); + Texture *texture = + getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target); + Error error = texture->copyImage(target, level, sourceArea, internalformat, framebuffer); + if (error.isError()) + { + recordError(error); + } +} + +void Context::copyTexSubImage2D(GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLint x, + GLint y, + GLsizei width, + GLsizei height) +{ + // Only sync the read FBO + mState.syncDirtyObject(GL_READ_FRAMEBUFFER); + + Offset destOffset(xoffset, yoffset, 0); + Rectangle sourceArea(x, y, width, height); + + const Framebuffer *framebuffer = mState.getReadFramebuffer(); + Texture *texture = + getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target); + Error error = texture->copySubImage(target, level, destOffset, sourceArea, framebuffer); + if (error.isError()) + { + recordError(error); + } +} + +void Context::copyTexSubImage3D(GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLint x, + GLint y, + GLsizei width, + GLsizei height) +{ + // Only sync the read FBO + mState.syncDirtyObject(GL_READ_FRAMEBUFFER); + + Offset destOffset(xoffset, yoffset, zoffset); + Rectangle sourceArea(x, y, width, height); + + const Framebuffer *framebuffer = mState.getReadFramebuffer(); + Texture *texture = getTargetTexture(target); + Error error = texture->copySubImage(target, level, destOffset, sourceArea, framebuffer); + if (error.isError()) + { + recordError(error); + } +} + +void Context::framebufferTexture2D(GLenum target, + GLenum attachment, + GLenum textarget, + GLuint texture, + GLint level) +{ + Framebuffer *framebuffer = mState.getTargetFramebuffer(target); + ASSERT(framebuffer); + + if (texture != 0) + { + Texture *textureObj = getTexture(texture); + + ImageIndex index = ImageIndex::MakeInvalid(); + + if (textarget == GL_TEXTURE_2D) + { + index = ImageIndex::Make2D(level); + } + else + { + ASSERT(IsCubeMapTextureTarget(textarget)); + index = ImageIndex::MakeCube(textarget, level); + } + + framebuffer->setAttachment(GL_TEXTURE, attachment, index, textureObj); + } + else + { + framebuffer->resetAttachment(attachment); + } + + mState.setObjectDirty(target); +} + +void Context::framebufferRenderbuffer(GLenum target, + GLenum attachment, + GLenum renderbuffertarget, + GLuint renderbuffer) +{ + Framebuffer *framebuffer = mState.getTargetFramebuffer(target); + ASSERT(framebuffer); + + if (renderbuffer != 0) + { + Renderbuffer *renderbufferObject = getRenderbuffer(renderbuffer); + framebuffer->setAttachment(GL_RENDERBUFFER, attachment, gl::ImageIndex::MakeInvalid(), + renderbufferObject); + } + else + { + framebuffer->resetAttachment(attachment); + } + + mState.setObjectDirty(target); +} + +void Context::framebufferTextureLayer(GLenum target, + GLenum attachment, + GLuint texture, + GLint level, + GLint layer) +{ + Framebuffer *framebuffer = mState.getTargetFramebuffer(target); + ASSERT(framebuffer); + + if (texture != 0) + { + Texture *textureObject = getTexture(texture); + + ImageIndex index = ImageIndex::MakeInvalid(); + + if (textureObject->getTarget() == GL_TEXTURE_3D) + { + index = ImageIndex::Make3D(level, layer); + } + else + { + ASSERT(textureObject->getTarget() == GL_TEXTURE_2D_ARRAY); + index = ImageIndex::Make2DArray(level, layer); + } + + framebuffer->setAttachment(GL_TEXTURE, attachment, index, textureObject); + } + else + { + framebuffer->resetAttachment(attachment); + } + + mState.setObjectDirty(target); +} + +void Context::drawBuffers(GLsizei n, const GLenum *bufs) +{ + Framebuffer *framebuffer = mState.getDrawFramebuffer(); + ASSERT(framebuffer); + framebuffer->setDrawBuffers(n, bufs); + mState.setObjectDirty(GL_DRAW_FRAMEBUFFER); +} + +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) +{ + // Only sync the FBO + mState.syncDirtyObject(target); + + Framebuffer *framebuffer = mState.getTargetFramebuffer(target); + ASSERT(framebuffer); + + // The specification isn't clear what should be done when the framebuffer isn't complete. + // We leave it up to the framebuffer implementation to decide what to do. + Error error = framebuffer->discard(numAttachments, attachments); + if (error.isError()) + { + recordError(error); + } +} + +void Context::invalidateFramebuffer(GLenum target, + GLsizei numAttachments, + const GLenum *attachments) +{ + // Only sync the FBO + mState.syncDirtyObject(target); + + Framebuffer *framebuffer = mState.getTargetFramebuffer(target); + ASSERT(framebuffer); + + if (framebuffer->checkStatus(mData) == GL_FRAMEBUFFER_COMPLETE) + { + Error error = framebuffer->invalidate(numAttachments, attachments); + if (error.isError()) + { + recordError(error); + return; + } + } +} + +void Context::invalidateSubFramebuffer(GLenum target, + GLsizei numAttachments, + const GLenum *attachments, + GLint x, + GLint y, + GLsizei width, + GLsizei height) +{ + // Only sync the FBO + mState.syncDirtyObject(target); + + Framebuffer *framebuffer = mState.getTargetFramebuffer(target); + ASSERT(framebuffer); + + if (framebuffer->checkStatus(mData) == GL_FRAMEBUFFER_COMPLETE) + { + Rectangle area(x, y, width, height); + Error error = framebuffer->invalidateSub(numAttachments, attachments, area); + if (error.isError()) + { + recordError(error); + return; + } + } +} + +void Context::texImage2D(GLenum target, + GLint level, + GLint internalformat, + GLsizei width, + GLsizei height, + GLint border, + GLenum format, + GLenum type, + const GLvoid *pixels) +{ + syncStateForTexImage(); + + Extents size(width, height, 1); + Texture *texture = + getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target); + Error error = texture->setImage(mState.getUnpackState(), target, level, internalformat, size, + format, type, reinterpret_cast(pixels)); + if (error.isError()) + { + recordError(error); + } +} + +void Context::texImage3D(GLenum target, + GLint level, + GLint internalformat, + GLsizei width, + GLsizei height, + GLsizei depth, + GLint border, + GLenum format, + GLenum type, + const GLvoid *pixels) +{ + syncStateForTexImage(); + + Extents size(width, height, depth); + Texture *texture = getTargetTexture(target); + Error error = texture->setImage(mState.getUnpackState(), target, level, internalformat, size, + format, type, reinterpret_cast(pixels)); + if (error.isError()) + { + recordError(error); + } +} + +void Context::texSubImage2D(GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLsizei width, + GLsizei height, + GLenum format, + GLenum type, + const GLvoid *pixels) +{ + // Zero sized uploads are valid but no-ops + if (width == 0 || height == 0) + { + return; + } + + syncStateForTexImage(); + + Box area(xoffset, yoffset, 0, width, height, 1); + Texture *texture = + getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target); + Error error = texture->setSubImage(mState.getUnpackState(), target, level, area, format, type, + reinterpret_cast(pixels)); + if (error.isError()) + { + recordError(error); + } +} + +void Context::texSubImage3D(GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLsizei width, + GLsizei height, + GLsizei depth, + GLenum format, + GLenum type, + const GLvoid *pixels) +{ + // Zero sized uploads are valid but no-ops + if (width == 0 || height == 0 || depth == 0) + { + return; + } + + syncStateForTexImage(); + + Box area(xoffset, yoffset, zoffset, width, height, depth); + Texture *texture = getTargetTexture(target); + Error error = texture->setSubImage(mState.getUnpackState(), target, level, area, format, type, + reinterpret_cast(pixels)); + if (error.isError()) + { + recordError(error); + } +} + +void Context::compressedTexImage2D(GLenum target, + GLint level, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLint border, + GLsizei imageSize, + const GLvoid *data) +{ + syncStateForTexImage(); + + Extents size(width, height, 1); + Texture *texture = + getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target); + Error error = + texture->setCompressedImage(mState.getUnpackState(), target, level, internalformat, size, + imageSize, reinterpret_cast(data)); + if (error.isError()) + { + recordError(error); + } +} + +void Context::compressedTexImage3D(GLenum target, + GLint level, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLsizei depth, + GLint border, + GLsizei imageSize, + const GLvoid *data) +{ + syncStateForTexImage(); + + Extents size(width, height, depth); + Texture *texture = getTargetTexture(target); + Error error = + texture->setCompressedImage(mState.getUnpackState(), target, level, internalformat, size, + imageSize, reinterpret_cast(data)); + if (error.isError()) + { + recordError(error); + } +} + +void Context::compressedTexSubImage2D(GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLsizei width, + GLsizei height, + GLenum format, + GLsizei imageSize, + const GLvoid *data) +{ + syncStateForTexImage(); + + Box area(xoffset, yoffset, 0, width, height, 1); + Texture *texture = + getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target); + Error error = + texture->setCompressedSubImage(mState.getUnpackState(), target, level, area, format, + imageSize, reinterpret_cast(data)); + if (error.isError()) + { + recordError(error); + } +} + +void Context::compressedTexSubImage3D(GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLsizei width, + GLsizei height, + GLsizei depth, + GLenum format, + GLsizei imageSize, + const GLvoid *data) +{ + // Zero sized uploads are valid but no-ops + if (width == 0 || height == 0) + { + return; + } + + syncStateForTexImage(); + + Box area(xoffset, yoffset, zoffset, width, height, depth); + Texture *texture = getTargetTexture(target); + Error error = + texture->setCompressedSubImage(mState.getUnpackState(), target, level, area, format, + imageSize, reinterpret_cast(data)); + if (error.isError()) + { + recordError(error); + } +} + +void Context::getBufferPointerv(GLenum target, GLenum /*pname*/, void **params) +{ + Buffer *buffer = getState().getTargetBuffer(target); + ASSERT(buffer); + + if (!buffer->isMapped()) + { + *params = nullptr; + } + else + { + *params = buffer->getMapPointer(); + } } + +GLvoid *Context::mapBuffer(GLenum target, GLenum access) +{ + Buffer *buffer = getState().getTargetBuffer(target); + ASSERT(buffer); + + Error error = buffer->map(access); + if (error.isError()) + { + recordError(error); + return nullptr; + } + + return buffer->getMapPointer(); +} + +GLboolean Context::unmapBuffer(GLenum target) +{ + Buffer *buffer = getState().getTargetBuffer(target); + ASSERT(buffer); + + GLboolean result; + Error error = buffer->unmap(&result); + if (error.isError()) + { + recordError(error); + return GL_FALSE; + } + + return result; +} + +GLvoid *Context::mapBufferRange(GLenum target, + GLintptr offset, + GLsizeiptr length, + GLbitfield access) +{ + Buffer *buffer = getState().getTargetBuffer(target); + ASSERT(buffer); + + Error error = buffer->mapRange(offset, length, access); + if (error.isError()) + { + recordError(error); + return nullptr; + } + + return buffer->getMapPointer(); +} + +void Context::flushMappedBufferRange(GLenum /*target*/, GLintptr /*offset*/, GLsizeiptr /*length*/) +{ + // We do not currently support a non-trivial implementation of FlushMappedBufferRange +} + +void Context::syncStateForReadPixels() +{ + syncRendererState(mReadPixelsDirtyBits, mReadPixelsDirtyObjects); +} + +void Context::syncStateForTexImage() +{ + syncRendererState(mTexImageDirtyBits, mTexImageDirtyObjects); +} + +void Context::syncStateForClear() +{ + syncRendererState(mClearDirtyBits, mClearDirtyObjects); +} + +void Context::syncStateForBlit() +{ + syncRendererState(mBlitDirtyBits, mBlitDirtyObjects); +} + +} // namespace gl diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/Context.h b/Source/ThirdParty/ANGLE/src/libANGLE/Context.h index 55a089721fdd..3dbbda79e7fa 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/Context.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/Context.h @@ -10,6 +10,10 @@ #ifndef LIBANGLE_CONTEXT_H_ #define LIBANGLE_CONTEXT_H_ +#include +#include + +#include "angle_gl.h" #include "common/angleutils.h" #include "libANGLE/RefCountObject.h" #include "libANGLE/Caps.h" @@ -20,12 +24,6 @@ #include "libANGLE/VertexAttribute.h" #include "libANGLE/angletypes.h" -#include "angle_gl.h" - -#include -#include -#include - namespace rx { class Renderer; @@ -33,6 +31,7 @@ class Renderer; namespace egl { +class AttributeMap; class Surface; struct Config; } @@ -55,10 +54,13 @@ class VertexArray; class Sampler; class TransformFeedback; -class Context final : angle::NonCopyable +class Context final : public ValidationContext { public: - Context(const egl::Config *config, int clientVersion, const Context *shareContext, rx::Renderer *renderer, bool notifyResets, bool robustAccess); + Context(const egl::Config *config, + const Context *shareContext, + rx::Renderer *renderer, + const egl::AttributeMap &attribs); virtual ~Context(); @@ -104,27 +106,39 @@ class Context final : angle::NonCopyable GLuint createVertexArray(); void deleteVertexArray(GLuint vertexArray); - void bindArrayBuffer(GLuint buffer); - void bindElementArrayBuffer(GLuint buffer); + void bindArrayBuffer(GLuint bufferHandle); + void bindElementArrayBuffer(GLuint bufferHandle); void bindTexture(GLenum target, GLuint handle); - void bindReadFramebuffer(GLuint framebuffer); - void bindDrawFramebuffer(GLuint framebuffer); - void bindRenderbuffer(GLuint renderbuffer); - void bindVertexArray(GLuint vertexArray); - void bindSampler(GLuint textureUnit, GLuint sampler); - void bindGenericUniformBuffer(GLuint buffer); - void bindIndexedUniformBuffer(GLuint buffer, GLuint index, GLintptr offset, GLsizeiptr size); - void bindGenericTransformFeedbackBuffer(GLuint buffer); - void bindIndexedTransformFeedbackBuffer(GLuint buffer, GLuint index, GLintptr offset, GLsizeiptr size); - void bindCopyReadBuffer(GLuint buffer); - void bindCopyWriteBuffer(GLuint buffer); - void bindPixelPackBuffer(GLuint buffer); - void bindPixelUnpackBuffer(GLuint buffer); + void bindReadFramebuffer(GLuint framebufferHandle); + void bindDrawFramebuffer(GLuint framebufferHandle); + void bindRenderbuffer(GLuint renderbufferHandle); + void bindVertexArray(GLuint vertexArrayHandle); + void bindSampler(GLuint textureUnit, GLuint samplerHandle); + void bindGenericUniformBuffer(GLuint bufferHandle); + void bindIndexedUniformBuffer(GLuint bufferHandle, + GLuint index, + GLintptr offset, + GLsizeiptr size); + void bindGenericTransformFeedbackBuffer(GLuint bufferHandle); + void bindIndexedTransformFeedbackBuffer(GLuint bufferHandle, + GLuint index, + GLintptr offset, + GLsizeiptr size); + void bindCopyReadBuffer(GLuint bufferHandle); + void bindCopyWriteBuffer(GLuint bufferHandle); + void bindPixelPackBuffer(GLuint bufferHandle); + void bindPixelUnpackBuffer(GLuint bufferHandle); void useProgram(GLuint program); - void bindTransformFeedback(GLuint transformFeedback); + void bindTransformFeedback(GLuint transformFeedbackHandle); Error beginQuery(GLenum target, GLuint query); Error endQuery(GLenum target); + Error queryCounter(GLuint id, GLenum target); + void getQueryiv(GLenum target, GLenum pname, GLint *params); + Error getQueryObjectiv(GLuint id, GLenum pname, GLint *params); + Error getQueryObjectuiv(GLuint id, GLenum pname, GLuint *params); + Error getQueryObjecti64v(GLuint id, GLenum pname, GLint64 *params); + Error getQueryObjectui64v(GLuint id, GLenum pname, GLuint64 *params); void setVertexAttribDivisor(GLuint index, GLuint divisor); @@ -133,18 +147,23 @@ class Context final : angle::NonCopyable GLint getSamplerParameteri(GLuint sampler, GLenum pname); GLfloat getSamplerParameterf(GLuint sampler, GLenum pname); - Buffer *getBuffer(GLuint handle); + void programParameteri(GLuint program, GLenum pname, GLint value); + + Buffer *getBuffer(GLuint handle) const; FenceNV *getFenceNV(GLuint handle); FenceSync *getFenceSync(GLsync handle) const; Shader *getShader(GLuint handle) const; Program *getProgram(GLuint handle) const; Texture *getTexture(GLuint handle) const; Framebuffer *getFramebuffer(GLuint handle) const; - Renderbuffer *getRenderbuffer(GLuint handle); + Renderbuffer *getRenderbuffer(GLuint handle) const; VertexArray *getVertexArray(GLuint handle) const; Sampler *getSampler(GLuint handle) const; Query *getQuery(GLuint handle, bool create, GLenum type); + Query *getQuery(GLuint handle) const; TransformFeedback *getTransformFeedback(GLuint handle) const; + LabeledObject *getLabeledObject(GLenum identifier, GLuint name) const; + LabeledObject *getLabeledObjectFromPtr(const void *ptr) const; Texture *getTargetTexture(GLenum target) const; Texture *getSamplerTexture(unsigned int sampler, GLenum type) const; @@ -153,10 +172,14 @@ class Context final : angle::NonCopyable bool isSampler(GLuint samplerName) const; + bool isVertexArrayGenerated(GLuint vertexArray); + bool isTransformFeedbackGenerated(GLuint vertexArray); + void getBooleanv(GLenum pname, GLboolean *params); void getFloatv(GLenum pname, GLfloat *params); void getIntegerv(GLenum pname, GLint *params); void getInteger64v(GLenum pname, GLint64 *params); + void getPointerv(GLenum pname, void **params) const; bool getIndexedIntegerv(GLenum target, GLuint index, GLint *data); bool getIndexedInteger64v(GLenum target, GLuint index, GLint64 *data); @@ -164,29 +187,215 @@ class Context final : angle::NonCopyable bool getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *numParams); bool getIndexedQueryParameterInfo(GLenum target, GLenum *type, unsigned int *numParams); - Error drawArrays(GLenum mode, GLint first, GLsizei count, GLsizei instances); - Error drawElements(GLenum mode, GLsizei count, GLenum type, - const GLvoid *indices, GLsizei instances, - const rx::RangeUI &indexRange); + void clear(GLbitfield mask); + void clearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *values); + void clearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *values); + void clearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *values); + void clearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil); + + Error drawArrays(GLenum mode, GLint first, GLsizei count); + Error drawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount); + + Error drawElements(GLenum mode, + GLsizei count, + GLenum type, + const GLvoid *indices, + const IndexRange &indexRange); + Error drawElementsInstanced(GLenum mode, + GLsizei count, + GLenum type, + const GLvoid *indices, + GLsizei instances, + const IndexRange &indexRange); + Error drawRangeElements(GLenum mode, + GLuint start, + GLuint end, + GLsizei count, + GLenum type, + const GLvoid *indices, + const IndexRange &indexRange); + + void blitFramebuffer(GLint srcX0, + GLint srcY0, + GLint srcX1, + GLint srcY1, + GLint dstX0, + GLint dstY0, + GLint dstX1, + GLint dstY1, + GLbitfield mask, + GLenum filter); + + void readPixels(GLint x, + GLint y, + GLsizei width, + GLsizei height, + GLenum format, + GLenum type, + GLvoid *pixels); + + void copyTexImage2D(GLenum target, + GLint level, + GLenum internalformat, + GLint x, + GLint y, + GLsizei width, + GLsizei height, + GLint border); + + void copyTexSubImage2D(GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLint x, + GLint y, + GLsizei width, + GLsizei height); + + void copyTexSubImage3D(GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLint x, + GLint y, + GLsizei width, + GLsizei height); + + void framebufferTexture2D(GLenum target, + GLenum attachment, + GLenum textarget, + GLuint texture, + GLint level); + + void framebufferRenderbuffer(GLenum target, + GLenum attachment, + GLenum renderbuffertarget, + GLuint renderbuffer); + + void framebufferTextureLayer(GLenum target, + GLenum attachment, + GLuint texture, + GLint level, + GLint layer); + + void drawBuffers(GLsizei n, const GLenum *bufs); + void readBuffer(GLenum mode); + + void discardFramebuffer(GLenum target, GLsizei numAttachments, const GLenum *attachments); + 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); + + void texImage2D(GLenum target, + GLint level, + GLint internalformat, + GLsizei width, + GLsizei height, + GLint border, + GLenum format, + GLenum type, + const GLvoid *pixels); + void texImage3D(GLenum target, + GLint level, + GLint internalformat, + GLsizei width, + GLsizei height, + GLsizei depth, + GLint border, + GLenum format, + GLenum type, + const GLvoid *pixels); + void texSubImage2D(GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLsizei width, + GLsizei height, + GLenum format, + GLenum type, + const GLvoid *pixels); + void texSubImage3D(GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLsizei width, + GLsizei height, + GLsizei depth, + GLenum format, + GLenum type, + const GLvoid *pixels); + void compressedTexImage2D(GLenum target, + GLint level, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLint border, + GLsizei imageSize, + const GLvoid *data); + void compressedTexImage3D(GLenum target, + GLint level, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLsizei depth, + GLint border, + GLsizei imageSize, + const GLvoid *data); + void compressedTexSubImage2D(GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLsizei width, + GLsizei height, + GLenum format, + GLsizei imageSize, + const GLvoid *data); + void compressedTexSubImage3D(GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLsizei width, + GLsizei height, + GLsizei depth, + GLenum format, + GLsizei imageSize, + const GLvoid *data); + Error flush(); Error finish(); - void recordError(const Error &error); + void getBufferPointerv(GLenum target, GLenum pname, void **params); + GLvoid *mapBuffer(GLenum target, GLenum access); + GLboolean unmapBuffer(GLenum target); + GLvoid *mapBufferRange(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access); + void flushMappedBufferRange(GLenum target, GLintptr offset, GLsizeiptr length); + + void beginTransformFeedback(GLenum primitiveMode); + + bool hasActiveTransformFeedback(GLuint program) const; + + void insertEventMarker(GLsizei length, const char *marker); + void pushGroupMarker(GLsizei length, const char *marker); + void popGroupMarker(); + + void recordError(const Error &error) override; GLenum getError(); GLenum getResetStatus(); virtual bool isResetNotificationEnabled(); - virtual int getClientVersion() const; - - EGLint getConfigID() const; + const egl::Config *getConfig() const; EGLenum getClientType() const; EGLenum getRenderBuffer() const; - const Caps &getCaps() const; - const TextureCapsMap &getTextureCaps() const; - const Extensions &getExtensions() const; - const std::string &getRendererString() const; const std::string &getExtensionString() const; @@ -196,11 +405,18 @@ class Context final : angle::NonCopyable rx::Renderer *getRenderer() { return mRenderer; } State &getState() { return mState; } - const State &getState() const { return mState; } - - const Data &getData() const { return mData; } private: + void syncRendererState(); + void syncRendererState(const State::DirtyBits &bitMask, const State::DirtyObjects &objectMask); + void syncStateForReadPixels(); + void syncStateForTexImage(); + void syncStateForClear(); + void syncStateForBlit(); + VertexArray *checkVertexArrayAllocation(GLuint vertexArrayHandle); + TransformFeedback *checkTransformFeedbackAllocation(GLuint transformFeedback); + Framebuffer *checkFramebufferAllocation(GLuint framebufferHandle); + void detachBuffer(GLuint buffer); void detachTexture(GLuint texture); void detachFramebuffer(GLuint framebuffer); @@ -218,6 +434,7 @@ class Context final : angle::NonCopyable Caps mCaps; TextureCapsMap mTextureCaps; Extensions mExtensions; + Limitations mLimitations; // Shader compiler Compiler *mCompiler; @@ -227,30 +444,24 @@ class Context final : angle::NonCopyable int mClientVersion; - EGLint mConfigID; + const egl::Config *mConfig; EGLenum mClientType; TextureMap mZeroTextures; - typedef std::map FramebufferMap; - FramebufferMap mFramebufferMap; + ResourceMap mFramebufferMap; HandleAllocator mFramebufferHandleAllocator; - typedef std::map FenceNVMap; - FenceNVMap mFenceNVMap; + ResourceMap mFenceNVMap; HandleAllocator mFenceNVHandleAllocator; - typedef std::map QueryMap; - QueryMap mQueryMap; + ResourceMap mQueryMap; HandleAllocator mQueryHandleAllocator; - typedef std::map VertexArrayMap; - VertexArrayMap mVertexArrayMap; + ResourceMap mVertexArrayMap; HandleAllocator mVertexArrayHandleAllocator; - BindingPointer mTransformFeedbackZero; - typedef std::map TransformFeedbackMap; - TransformFeedbackMap mTransformFeedbackMap; + ResourceMap mTransformFeedbackMap; HandleAllocator mTransformFeedbackAllocator; std::string mRendererString; @@ -267,13 +478,20 @@ class Context final : angle::NonCopyable GLenum mResetStatus; GLenum mResetStrategy; bool mRobustAccess; + egl::Surface *mCurrentSurface; ResourceManager *mResourceManager; - // Cache the Data object to avoid re-calling the constructor - Data mData; + State::DirtyBits mTexImageDirtyBits; + State::DirtyObjects mTexImageDirtyObjects; + State::DirtyBits mReadPixelsDirtyBits; + State::DirtyObjects mReadPixelsDirtyObjects; + State::DirtyBits mClearDirtyBits; + State::DirtyObjects mClearDirtyObjects; + State::DirtyBits mBlitDirtyBits; + State::DirtyObjects mBlitDirtyObjects; }; -} +} // namespace gl #endif // LIBANGLE_CONTEXT_H_ diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/Data.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/Data.cpp index 7832e21b2372..83f04b5a0b54 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/Data.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/Data.cpp @@ -12,40 +12,45 @@ namespace gl { -Data::Data(GLint clientVersionIn, const State &stateIn, const Caps &capsIn, - const TextureCapsMap &textureCapsIn, const Extensions &extensionsIn, - const ResourceManager *resourceManagerIn) - : clientVersion(clientVersionIn), +Data::Data(uintptr_t contextIn, + GLint clientVersionIn, + const State &stateIn, + const Caps &capsIn, + const TextureCapsMap &textureCapsIn, + const Extensions &extensionsIn, + const ResourceManager *resourceManagerIn, + const Limitations &limitationsIn) + : context(contextIn), + clientVersion(clientVersionIn), state(&stateIn), caps(&capsIn), textureCaps(&textureCapsIn), extensions(&extensionsIn), - resourceManager(resourceManagerIn) + resourceManager(resourceManagerIn), + limitations(&limitationsIn) {} Data::~Data() { } -Data::Data(const Data &other) - : clientVersion(other.clientVersion), - state(other.state), - caps(other.caps), - textureCaps(other.textureCaps), - extensions(other.extensions), - resourceManager(other.resourceManager) +ValidationContext::ValidationContext(GLint clientVersion, + const State &state, + const Caps &caps, + const TextureCapsMap &textureCaps, + const Extensions &extensions, + const ResourceManager *resourceManager, + const Limitations &limitations, + bool skipValidation) + : mData(reinterpret_cast(this), + clientVersion, + state, + caps, + textureCaps, + extensions, + resourceManager, + limitations), + mSkipValidation(skipValidation) { } - -Data &Data::operator=(const Data &other) -{ - clientVersion = other.clientVersion; - state = other.state; - caps = other.caps; - textureCaps = other.textureCaps; - extensions = other.extensions; - resourceManager = other.resourceManager; - return *this; -} - -} +} // namespace gl diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/Data.h b/Source/ThirdParty/ANGLE/src/libANGLE/Data.h index 7eb6827dfc8c..f7230d74bcb3 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/Data.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/Data.h @@ -9,28 +9,62 @@ #ifndef LIBANGLE_DATA_H_ #define LIBANGLE_DATA_H_ +#include "common/angleutils.h" #include "libANGLE/State.h" namespace gl { -struct Data final +struct Data final : public angle::NonCopyable { public: - Data(GLint clientVersion, const State &state, const Caps &caps, - const TextureCapsMap &textureCaps, const Extensions &extensions, - const ResourceManager *resourceManager); + Data(uintptr_t context, + GLint clientVersion, + const State &state, + const Caps &caps, + const TextureCapsMap &textureCaps, + const Extensions &extensions, + const ResourceManager *resourceManager, + const Limitations &limitations); ~Data(); - Data(const Data &other); - Data &operator=(const Data &other); - + uintptr_t context; GLint clientVersion; const State *state; const Caps *caps; const TextureCapsMap *textureCaps; const Extensions *extensions; const ResourceManager *resourceManager; + const Limitations *limitations; +}; + +class ValidationContext : angle::NonCopyable +{ + public: + ValidationContext(GLint clientVersion, + const State &state, + const Caps &caps, + const TextureCapsMap &textureCaps, + const Extensions &extensions, + const ResourceManager *resourceManager, + const Limitations &limitations, + bool skipValidation); + virtual ~ValidationContext() {} + + virtual void recordError(const Error &error) = 0; + + const Data &getData() const { return mData; } + int getClientVersion() const { return mData.clientVersion; } + const State &getState() const { return *mData.state; } + const Caps &getCaps() const { return *mData.caps; } + const TextureCapsMap &getTextureCaps() const { return *mData.textureCaps; } + const Extensions &getExtensions() const { return *mData.extensions; } + const Limitations &getLimitations() const { return *mData.limitations; } + bool skipValidation() const { return mSkipValidation; } + + protected: + Data mData; + bool mSkipValidation; }; } diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/Debug.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/Debug.cpp new file mode 100644 index 000000000000..30321f41606b --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/libANGLE/Debug.cpp @@ -0,0 +1,303 @@ +// +// Copyright (c) 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 gl +{ + +Debug::Debug() + : mOutputEnabled(false), + mCallbackFunction(nullptr), + mCallbackUserParam(nullptr), + mMessages(), + mMaxLoggedMessages(0), + mOutputSynchronous(false), + mGroups() +{ + pushDefaultGroup(); +} + +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) +{ + std::string messageCopy(message); + insertMessage(source, type, id, severity, std::move(messageCopy)); +} + +void Debug::insertMessage(GLenum source, + GLenum type, + GLuint id, + GLenum severity, + std::string &&message) +{ + 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()); + } + + mMessages.pop_front(); + + messageCount++; + } + + return messageCount; +} + +size_t Debug::getNextMessageLength() const +{ + return mMessages.empty() ? 0 : mMessages.front().message.length(); +} + +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)); + + 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); +} + +size_t Debug::getGroupStackDepth() const +{ + return mGroups.size(); +} + +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 diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/Debug.h b/Source/ThirdParty/ANGLE/src/libANGLE/Debug.h new file mode 100644 index 000000000000..f545b815e4e4 --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/libANGLE/Debug.h @@ -0,0 +1,120 @@ +// +// Copyright (c) 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/angleutils.h" + +#include +#include +#include + +namespace gl +{ + +class LabeledObject +{ + public: + virtual ~LabeledObject() {} + virtual void setLabel(const std::string &label) = 0; + virtual const std::string &getLabel() const = 0; +}; + +class Debug : angle::NonCopyable +{ + public: + 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); + void insertMessage(GLenum source, + GLenum type, + GLuint id, + GLenum severity, + std::string &&message); + + 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; + + 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 + { + GLenum source; + GLenum type; + GLenum severity; + std::vector ids; + bool enabled; + }; + + struct Group + { + GLenum source; + GLuint id; + std::string message; + + std::vector controls; + }; + + bool mOutputEnabled; + GLDEBUGPROCKHR mCallbackFunction; + const void *mCallbackUserParam; + std::deque mMessages; + GLuint mMaxLoggedMessages; + bool mOutputSynchronous; + std::vector mGroups; +}; +} // namespace gl + +#endif // LIBANGLE_DEBUG_H_ diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/Device.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/Device.cpp index 980ec0930fa4..eb30b2023ff9 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/Device.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/Device.cpp @@ -18,6 +18,10 @@ #include "common/platform.h" #include "libANGLE/renderer/DeviceImpl.h" +#if defined(ANGLE_ENABLE_D3D11) +#include "libANGLE/renderer/d3d/DeviceD3D.h" +#endif + namespace egl { @@ -31,21 +35,75 @@ static std::string GenerateExtensionsString(const T &extensions) return stream.str(); } -Device::Device(Display *display, rx::DeviceImpl *impl) - : mDisplay(display), - mImplementation(impl) +typedef std::set DeviceSet; +static DeviceSet *GetDeviceSet() +{ + static DeviceSet devices; + return &devices; +} + +// Static factory methods +egl::Error Device::CreateDevice(void *devicePointer, EGLint deviceType, Device **outDevice) +{ +#if defined(ANGLE_ENABLE_D3D11) + if (deviceType == EGL_D3D11_DEVICE_ANGLE) + { + rx::DeviceD3D *deviceD3D = new rx::DeviceD3D(); + egl::Error error = deviceD3D->initialize(devicePointer, deviceType, EGL_TRUE); + if (error.isError()) + { + *outDevice = nullptr; + return error; + } + + *outDevice = new Device(nullptr, deviceD3D); + GetDeviceSet()->insert(*outDevice); + return egl::Error(EGL_SUCCESS); + } +#endif + + // Note that creating an EGL device from inputted D3D9 parameters isn't currently supported + *outDevice = nullptr; + return egl::Error(EGL_BAD_ATTRIBUTE); +} + +egl::Error Device::CreateDevice(Display *owningDisplay, rx::DeviceImpl *impl, Device **outDevice) +{ + *outDevice = new Device(owningDisplay, impl); + GetDeviceSet()->insert(*outDevice); + return egl::Error(EGL_SUCCESS); +} + +bool Device::IsValidDevice(Device *device) +{ + const DeviceSet *deviceSet = GetDeviceSet(); + return deviceSet->find(device) != deviceSet->end(); +} + +Device::Device(Display *owningDisplay, rx::DeviceImpl *impl) + : mOwningDisplay(owningDisplay), mImplementation(impl) { initDeviceExtensions(); } Device::~Device() { - + ASSERT(GetDeviceSet()->find(this) != GetDeviceSet()->end()); + GetDeviceSet()->erase(this); + + if (mImplementation->deviceExternallySourced()) + { + // If the device isn't externally sourced then it is up to the renderer to delete the impl + SafeDelete(mImplementation); + } } Error Device::getDevice(EGLAttrib *value) { - return getImplementation()->getDevice(value); + void *nativeDevice = nullptr; + egl::Error error = getImplementation()->getDevice(&nativeDevice); + *value = reinterpret_cast(nativeDevice); + return error; } EGLint Device::getType() diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/Device.h b/Source/ThirdParty/ANGLE/src/libANGLE/Device.h index 5c5f2d5b5250..4bc58ff043a8 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/Device.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/Device.h @@ -24,11 +24,10 @@ namespace egl class Device final : angle::NonCopyable { public: - Device(Display *display, rx::DeviceImpl *impl); virtual ~Device(); Error getDevice(EGLAttrib *value); - Display *getDisplay() { return mDisplay; }; + Display *getOwningDisplay() { return mOwningDisplay; }; EGLint getType(); const DeviceExtensions &getExtensions() const; @@ -36,10 +35,18 @@ class Device final : angle::NonCopyable rx::DeviceImpl *getImplementation() { return mImplementation; } + static egl::Error CreateDevice(void *devicePointer, EGLint deviceType, Device **outDevice); + static egl::Error CreateDevice(Display *owningDisplay, + rx::DeviceImpl *impl, + Device **outDevice); + + static bool IsValidDevice(Device *device); + private: + Device(Display *owningDisplay, rx::DeviceImpl *impl); void initDeviceExtensions(); - Display *mDisplay; + Display *mOwningDisplay; rx::DeviceImpl *mImplementation; DeviceExtensions mDeviceExtensions; diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/Display.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/Display.cpp index 4af5a448eb96..4de579bbca3f 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/Display.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/Display.cpp @@ -22,10 +22,15 @@ #include "common/debug.h" #include "common/mathutil.h" #include "common/platform.h" +#include "common/utilities.h" #include "libANGLE/Context.h" -#include "libANGLE/Surface.h" #include "libANGLE/Device.h" +#include "libANGLE/histogram_macros.h" +#include "libANGLE/Image.h" +#include "libANGLE/Surface.h" +#include "libANGLE/Stream.h" #include "libANGLE/renderer/DisplayImpl.h" +#include "libANGLE/renderer/ImageImpl.h" #include "third_party/trace_event/trace_event.h" #if defined(ANGLE_ENABLE_D3D9) || defined(ANGLE_ENABLE_D3D11) @@ -35,6 +40,10 @@ #if defined(ANGLE_ENABLE_OPENGL) # if defined(ANGLE_PLATFORM_WINDOWS) # include "libANGLE/renderer/gl/wgl/DisplayWGL.h" +# elif defined(ANGLE_USE_X11) +# include "libANGLE/renderer/gl/glx/DisplayGLX.h" +# elif defined(ANGLE_PLATFORM_APPLE) +# include "libANGLE/renderer/gl/cgl/DisplayCGL.h" # else # error Unsupported OpenGL platform. # endif @@ -68,19 +77,6 @@ void InitDefaultPlatformImpl() } } -void DeinitDefaultPlatformImpl() -{ - if (defaultPlatform != nullptr) - { - if (ANGLEPlatformCurrent() == defaultPlatform) - { - ANGLEPlatformShutdown(); - } - - SafeDelete(defaultPlatform); - } -} - typedef std::map WindowSurfaceMap; // Get a map of all EGL window surfaces to validate that no window has more than one EGL surface // associated with it. @@ -90,26 +86,71 @@ static WindowSurfaceMap *GetWindowSurfaces() return &windowSurfaces; } -typedef std::map DisplayMap; -static DisplayMap *GetDisplayMap() +typedef std::map ANGLEPlatformDisplayMap; +static ANGLEPlatformDisplayMap *GetANGLEPlatformDisplayMap() +{ + static ANGLEPlatformDisplayMap displays; + return &displays; +} + +typedef std::map DevicePlatformDisplayMap; +static DevicePlatformDisplayMap *GetDevicePlatformDisplayMap() { - static DisplayMap displays; + static DevicePlatformDisplayMap displays; return &displays; } -rx::DisplayImpl *CreateDisplayImpl(const AttributeMap &attribMap) +rx::DisplayImpl *CreateDisplayFromDevice(Device *eglDevice) { rx::DisplayImpl *impl = nullptr; - EGLint displayType = attribMap.get(EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE); + + switch (eglDevice->getType()) + { +#if defined(ANGLE_ENABLE_D3D11) + case EGL_D3D11_DEVICE_ANGLE: + impl = new rx::DisplayD3D(); + 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; +} + +rx::DisplayImpl *CreateDisplayFromAttribs(const AttributeMap &attribMap) +{ + rx::DisplayImpl *impl = nullptr; + EGLAttrib displayType = + attribMap.get(EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE); switch (displayType) { case EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE: +#if defined(ANGLE_ENABLE_OPENGL) #if defined(ANGLE_ENABLE_D3D9) || defined(ANGLE_ENABLE_D3D11) // Default to D3D displays impl = new rx::DisplayD3D(); +#elif defined(ANGLE_USE_X11) + impl = new rx::DisplayGLX(); +#elif defined(ANGLE_PLATFORM_APPLE) + impl = new rx::DisplayCGL(); #else // No display available UNREACHABLE(); +#endif #endif break; @@ -127,6 +168,10 @@ rx::DisplayImpl *CreateDisplayImpl(const AttributeMap &attribMap) #if defined(ANGLE_ENABLE_OPENGL) #if defined(ANGLE_PLATFORM_WINDOWS) impl = new rx::DisplayWGL(); +#elif defined(ANGLE_USE_X11) + impl = new rx::DisplayGLX(); +#elif defined(ANGLE_PLATFORM_APPLE) + impl = new rx::DisplayCGL(); #else #error Unsupported OpenGL platform. #endif @@ -135,26 +180,40 @@ rx::DisplayImpl *CreateDisplayImpl(const AttributeMap &attribMap) #endif break; +#if defined(ANGLE_ENABLE_OPENGL) + case EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE: +#if defined(ANGLE_PLATFORM_WINDOWS) + impl = new rx::DisplayWGL(); +#elif defined(ANGLE_USE_X11) + impl = new rx::DisplayGLX(); +#else + // No GLES support on this platform, fail display creation. + impl = nullptr; +#endif + break; +#endif + default: UNREACHABLE(); break; } - ASSERT(impl != nullptr); return impl; } } -Display *Display::getDisplay(EGLNativeDisplayType displayId, const AttributeMap &attribMap) +Display *Display::GetDisplayFromAttribs(void *native_display, const AttributeMap &attribMap) { // Initialize the global platform if not already InitDefaultPlatformImpl(); - Display *display = NULL; + Display *display = nullptr; + + EGLNativeDisplayType displayId = reinterpret_cast(native_display); - DisplayMap *displays = GetDisplayMap(); - DisplayMap::const_iterator iter = displays->find(displayId); + ANGLEPlatformDisplayMap *displays = GetANGLEPlatformDisplayMap(); + ANGLEPlatformDisplayMap::const_iterator iter = displays->find(displayId); if (iter != displays->end()) { display = iter->second; @@ -168,32 +227,90 @@ Display *Display::getDisplay(EGLNativeDisplayType displayId, const AttributeMap return NULL; } - display = new Display(displayId); + display = new Display(EGL_PLATFORM_ANGLE_ANGLE, displayId, nullptr); displays->insert(std::make_pair(displayId, display)); } // Apply new attributes if the display is not initialized yet. if (!display->isInitialized()) { - rx::DisplayImpl* impl = CreateDisplayImpl(attribMap); + rx::DisplayImpl *impl = CreateDisplayFromAttribs(attribMap); + if (impl == nullptr) + { + // No valid display implementation for these attributes + return nullptr; + } + display->setAttributes(impl, attribMap); } return display; } -Display::Display(EGLNativeDisplayType displayId) +Display *Display::GetDisplayFromDevice(void *native_display) +{ + // Initialize the global platform if not already + InitDefaultPlatformImpl(); + + Display *display = nullptr; + + Device *eglDevice = reinterpret_cast(native_display); + ASSERT(Device::IsValidDevice(eglDevice)); + + 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() == eglDevice) + { + display = iterDisplay; + } + } + + if (display == nullptr) + { + // See if the eglDevice is in use by a Display created using the DEVICE platform + DevicePlatformDisplayMap::const_iterator iter = devicePlatformDisplays->find(eglDevice); + if (iter != devicePlatformDisplays->end()) + { + display = iter->second; + } + } + + if (display == nullptr) + { + // Otherwise create a new Display + display = new Display(EGL_PLATFORM_DEVICE_EXT, 0, eglDevice); + devicePlatformDisplays->insert(std::make_pair(eglDevice, display)); + } + + // Apply new attributes if the display is not initialized yet. + if (!display->isInitialized()) + { + rx::DisplayImpl *impl = CreateDisplayFromDevice(eglDevice); + display->setAttributes(impl, egl::AttributeMap()); + } + + return display; +} + +Display::Display(EGLenum platform, EGLNativeDisplayType displayId, Device *eglDevice) : mImplementation(nullptr), mDisplayId(displayId), mAttributeMap(), mConfigSet(), mContextSet(), + mStreamSet(), mInitialized(false), mCaps(), mDisplayExtensions(), mDisplayExtensionString(), mVendorString(), - mDevice(nullptr) + mDevice(eglDevice), + mPlatform(platform) { } @@ -201,11 +318,27 @@ Display::~Display() { terminate(); - DisplayMap *displays = GetDisplayMap(); - DisplayMap::iterator iter = displays->find(mDisplayId); - if (iter != displays->end()) + if (mPlatform == EGL_PLATFORM_ANGLE_ANGLE) + { + ANGLEPlatformDisplayMap *displays = GetANGLEPlatformDisplayMap(); + ANGLEPlatformDisplayMap::iterator iter = displays->find(mDisplayId); + if (iter != displays->end()) + { + displays->erase(iter); + } + } + else if (mPlatform == EGL_PLATFORM_DEVICE_EXT) { - displays->erase(iter); + DevicePlatformDisplayMap *displays = GetDevicePlatformDisplayMap(); + DevicePlatformDisplayMap::iterator iter = displays->find(mDevice); + if (iter != displays->end()) + { + displays->erase(iter); + } + } + else + { + UNREACHABLE(); } SafeDelete(mDevice); @@ -225,18 +358,27 @@ void Display::setAttributes(rx::DisplayImpl *impl, const AttributeMap &attribMap Error Display::initialize() { + // Re-initialize default platform if it's needed + InitDefaultPlatformImpl(); + + SCOPED_ANGLE_HISTOGRAM_TIMER("GPU.ANGLE.DisplayInitializeMS"); TRACE_EVENT0("gpu.angle", "egl::Display::initialize"); ASSERT(mImplementation != nullptr); if (isInitialized()) { - return Error(EGL_SUCCESS); + return egl::Error(EGL_SUCCESS); } Error error = mImplementation->initialize(this); if (error.isError()) { + // Log extended error message here + std::stringstream errorStream; + errorStream << "ANGLE Display::initialize error " << error.getID() << ": " + << error.getMessage(); + ANGLEPlatformCurrent()->logError(errorStream.str().c_str()); return error; } @@ -252,23 +394,39 @@ Error Display::initialize() initDisplayExtensions(); initVendorString(); - if (mDisplayExtensions.deviceQuery) + // Populate the Display's EGLDeviceEXT if the Display wasn't created using one + if (mPlatform != EGL_PLATFORM_DEVICE_EXT) { - rx::DeviceImpl *impl = nullptr; - error = mImplementation->getDevice(&impl); - if (error.isError()) + if (mDisplayExtensions.deviceQuery) { - return error; + rx::DeviceImpl *impl = nullptr; + error = mImplementation->getDevice(&impl); + if (error.isError()) + { + return error; + } + + error = Device::CreateDevice(this, impl, &mDevice); + if (error.isError()) + { + return error; + } + } + else + { + mDevice = nullptr; } - mDevice = new Device(this, impl); } else { - mDevice = nullptr; + // For EGL_PLATFORM_DEVICE_EXT, mDevice should always be populated using + // an external device + ASSERT(mDevice != nullptr); } mInitialized = true; - return Error(EGL_SUCCESS); + + return egl::Error(EGL_SUCCESS); } void Display::terminate() @@ -280,14 +438,35 @@ void Display::terminate() destroyContext(*mContextSet.begin()); } + while (!mImageSet.empty()) + { + destroyImage(*mImageSet.begin()); + } + + while (!mStreamSet.empty()) + { + destroyStream(*mStreamSet.begin()); + } + + while (!mImplementation->getSurfaceSet().empty()) + { + destroySurface(*mImplementation->getSurfaceSet().begin()); + } + 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(); mInitialized = false; - // De-init default platform - DeinitDefaultPlatformImpl(); + // Never de-init default platform.. terminate is not that final. } std::vector Display::getConfigs(const egl::AttributeMap &attribs) const @@ -310,6 +489,7 @@ bool Display::getConfigAttrib(const Config *configuration, EGLint attribute, EGL case EGL_CONFIG_ID: *value = configuration->configID; break; case EGL_LEVEL: *value = configuration->level; break; case EGL_NATIVE_RENDERABLE: *value = configuration->nativeRenderable; break; + case EGL_NATIVE_VISUAL_ID: *value = configuration->nativeVisualID; break; case EGL_NATIVE_VISUAL_TYPE: *value = configuration->nativeVisualType; break; case EGL_SAMPLES: *value = configuration->samples; break; case EGL_SAMPLE_BUFFERS: *value = configuration->sampleBuffers; break; @@ -331,6 +511,15 @@ bool Display::getConfigAttrib(const Config *configuration, EGLint attribute, EGL case EGL_MAX_PBUFFER_WIDTH: *value = configuration->maxPBufferWidth; break; case EGL_MAX_PBUFFER_HEIGHT: *value = configuration->maxPBufferHeight; break; case EGL_MAX_PBUFFER_PIXELS: *value = configuration->maxPBufferPixels; break; + + case EGL_OPTIMAL_SURFACE_ORIENTATION_ANGLE: + if (!getExtensions().surfaceOrientation) + { + return false; + } + *value = configuration->optimalOrientation; + break; + default: return false; } @@ -350,14 +539,16 @@ Error Display::createWindowSurface(const Config *configuration, EGLNativeWindowT } } - rx::SurfaceImpl *surfaceImpl = nullptr; - Error error = mImplementation->createWindowSurface(configuration, window, attribs, &surfaceImpl); + rx::SurfaceImpl *surfaceImpl = mImplementation->createWindowSurface(configuration, window, attribs); + ASSERT(surfaceImpl != nullptr); + + Error error = surfaceImpl->initialize(); if (error.isError()) { + SafeDelete(surfaceImpl); return error; } - ASSERT(surfaceImpl != nullptr); Surface *surface = new Surface(surfaceImpl, EGL_WINDOW_BIT, configuration, attribs); mImplementation->getSurfaceSet().insert(surface); @@ -367,7 +558,7 @@ Error Display::createWindowSurface(const Config *configuration, EGLNativeWindowT ASSERT(outSurface != nullptr); *outSurface = surface; - return Error(EGL_SUCCESS); + return egl::Error(EGL_SUCCESS); } Error Display::createPbufferSurface(const Config *configuration, const AttributeMap &attribs, Surface **outSurface) @@ -383,20 +574,22 @@ Error Display::createPbufferSurface(const Config *configuration, const Attribute } } - rx::SurfaceImpl *surfaceImpl = nullptr; - Error error = mImplementation->createPbufferSurface(configuration, attribs, &surfaceImpl); + rx::SurfaceImpl *surfaceImpl = mImplementation->createPbufferSurface(configuration, attribs); + ASSERT(surfaceImpl != nullptr); + + Error error = surfaceImpl->initialize(); if (error.isError()) { + SafeDelete(surfaceImpl); return error; } - ASSERT(surfaceImpl != nullptr); Surface *surface = new Surface(surfaceImpl, EGL_PBUFFER_BIT, configuration, attribs); mImplementation->getSurfaceSet().insert(surface); ASSERT(outSurface != nullptr); *outSurface = surface; - return Error(EGL_SUCCESS); + return egl::Error(EGL_SUCCESS); } Error Display::createPbufferFromClientBuffer(const Config *configuration, EGLClientBuffer shareHandle, @@ -413,20 +606,22 @@ Error Display::createPbufferFromClientBuffer(const Config *configuration, EGLCli } } - rx::SurfaceImpl *surfaceImpl = nullptr; - Error error = mImplementation->createPbufferFromClientBuffer(configuration, shareHandle, attribs, &surfaceImpl); + rx::SurfaceImpl *surfaceImpl = mImplementation->createPbufferFromClientBuffer(configuration, shareHandle, attribs); + ASSERT(surfaceImpl != nullptr); + + Error error = surfaceImpl->initialize(); if (error.isError()) { + SafeDelete(surfaceImpl); return error; } - ASSERT(surfaceImpl != nullptr); Surface *surface = new Surface(surfaceImpl, EGL_PBUFFER_BIT, configuration, attribs); mImplementation->getSurfaceSet().insert(surface); ASSERT(outSurface != nullptr); *outSurface = surface; - return Error(EGL_SUCCESS); + return egl::Error(EGL_SUCCESS); } Error Display::createPixmapSurface(const Config *configuration, NativePixmapType nativePixmap, const AttributeMap &attribs, @@ -443,24 +638,29 @@ Error Display::createPixmapSurface(const Config *configuration, NativePixmapType } } - rx::SurfaceImpl *surfaceImpl = nullptr; - Error error = mImplementation->createPixmapSurface(configuration, nativePixmap, attribs, &surfaceImpl); + rx::SurfaceImpl *surfaceImpl = mImplementation->createPixmapSurface(configuration, nativePixmap, attribs); + ASSERT(surfaceImpl != nullptr); + + Error error = surfaceImpl->initialize(); if (error.isError()) { + SafeDelete(surfaceImpl); return error; } - ASSERT(surfaceImpl != nullptr); Surface *surface = new Surface(surfaceImpl, EGL_PIXMAP_BIT, configuration, attribs); mImplementation->getSurfaceSet().insert(surface); ASSERT(outSurface != nullptr); *outSurface = surface; - return Error(EGL_SUCCESS); + return egl::Error(EGL_SUCCESS); } -Error Display::createContext(const Config *configuration, gl::Context *shareContext, const AttributeMap &attribs, - gl::Context **outContext) +Error Display::createImage(gl::Context *context, + EGLenum target, + EGLClientBuffer buffer, + const AttributeMap &attribs, + Image **outImage) { ASSERT(isInitialized()); @@ -473,19 +673,83 @@ Error Display::createContext(const Config *configuration, gl::Context *shareCont } } - gl::Context *context = nullptr; - Error error = mImplementation->createContext(configuration, shareContext, attribs, &context); + 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 + { + UNREACHABLE(); + } + ASSERT(sibling != nullptr); + + rx::ImageImpl *imageImpl = mImplementation->createImage(target, sibling, attribs); + ASSERT(imageImpl != nullptr); + + Error error = imageImpl->initialize(); if (error.isError()) { return error; } + Image *image = new Image(imageImpl, target, sibling, attribs); + + 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 egl::Error(EGL_SUCCESS); +} + +Error Display::createStream(const AttributeMap &attribs, Stream **outStream) +{ + ASSERT(isInitialized()); + + rx::StreamImpl *streamImpl = mImplementation->createStream(attribs); + ASSERT(streamImpl != nullptr); + + Stream *stream = new Stream(streamImpl, attribs); + + ASSERT(stream != nullptr); + mStreamSet.insert(stream); + + ASSERT(outStream != nullptr); + *outStream = stream; + + return Error(EGL_SUCCESS); +} + +Error Display::createContext(const Config *configuration, gl::Context *shareContext, const AttributeMap &attribs, + gl::Context **outContext) +{ + ASSERT(isInitialized()); + + if (mImplementation->testDeviceLost()) + { + Error error = restoreLostDevice(); + if (error.isError()) + { + return error; + } + } + + gl::Context *context = *outContext = + mImplementation->createContext(configuration, shareContext, attribs); + ASSERT(context != nullptr); mContextSet.insert(context); ASSERT(outContext != nullptr); *outContext = context; - return Error(EGL_SUCCESS); + return egl::Error(EGL_SUCCESS); } Error Display::makeCurrent(egl::Surface *drawSurface, egl::Surface *readSurface, gl::Context *context) @@ -538,11 +802,26 @@ void Display::destroySurface(Surface *surface) } ASSERT(surfaceRemoved); + UNUSED_ASSERTION_VARIABLE(surfaceRemoved); } mImplementation->destroySurface(surface); } +void Display::destroyImage(egl::Image *image) +{ + auto iter = mImageSet.find(image); + ASSERT(iter != mImageSet.end()); + (*iter)->release(); + mImageSet.erase(iter); +} + +void Display::destroyStream(egl::Stream *stream) +{ + mStreamSet.erase(stream); + SafeDelete(stream); +} + void Display::destroyContext(gl::Context *context) { mContextSet.erase(context); @@ -569,6 +848,16 @@ void Display::notifyDeviceLost() } } +Error Display::waitClient() const +{ + return mImplementation->waitClient(); +} + +Error Display::waitNative(EGLint engine, egl::Surface *drawSurface, egl::Surface *readSurface) const +{ + return mImplementation->waitNative(engine, drawSurface, readSurface); +} + const Caps &Display::getCaps() const { return mCaps; @@ -594,6 +883,16 @@ bool Display::isValidSurface(Surface *surface) const return mImplementation->getSurfaceSet().find(surface) != mImplementation->getSurfaceSet().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::hasExistingWindowSurface(EGLNativeWindowType window) { WindowSurfaceMap *windowSurfaces = GetWindowSurfaces(); @@ -612,12 +911,25 @@ static ClientExtensions GenerateClientExtensions() #if defined(ANGLE_ENABLE_D3D9) || defined(ANGLE_ENABLE_D3D11) extensions.platformANGLED3D = true; + extensions.platformDevice = true; #endif #if defined(ANGLE_ENABLE_OPENGL) extensions.platformANGLEOpenGL = true; #endif +#if defined(ANGLE_ENABLE_D3D11) + extensions.deviceCreation = true; + extensions.deviceCreationD3D11 = true; + extensions.experimentalPresentPath = true; +#endif + +#if defined(ANGLE_USE_X11) + extensions.x11Visual = true; +#endif + + extensions.clientGetAllProcAddresses = true; + return extensions; } @@ -646,6 +958,10 @@ const std::string &Display::getClientExtensionString() void Display::initDisplayExtensions() { mDisplayExtensions = mImplementation->getExtensions(); + + // Force EGL_KHR_get_all_proc_addresses on. + mDisplayExtensions.getAllProcAddresses = true; + mDisplayExtensionString = GenerateExtensionsString(mDisplayExtensions); } @@ -654,6 +970,29 @@ bool Display::isValidNativeWindow(EGLNativeWindowType window) const return mImplementation->isValidNativeWindow(window); } +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 diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/Display.h b/Source/ThirdParty/ANGLE/src/libANGLE/Display.h index a2ed1d06915f..339fa5944200 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/Display.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/Display.h @@ -32,8 +32,10 @@ class DisplayImpl; namespace egl { -class Surface; class Device; +class Image; +class Surface; +class Stream; class Display final : angle::NonCopyable { @@ -43,7 +45,8 @@ class Display final : angle::NonCopyable Error initialize(); void terminate(); - static egl::Display *getDisplay(EGLNativeDisplayType displayId, const AttributeMap &attribMap); + static egl::Display *GetDisplayFromDevice(void *native_display); + static egl::Display *GetDisplayFromAttribs(void *native_display, const AttributeMap &attribMap); static const ClientExtensions &getClientExtensions(); static const std::string &getClientExtensionString(); @@ -59,20 +62,33 @@ class Display final : angle::NonCopyable Error createPixmapSurface(const Config *configuration, NativePixmapType nativePixmap, const AttributeMap &attribs, Surface **outSurface); + Error createImage(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 AttributeMap &attribs, gl::Context **outContext); Error makeCurrent(egl::Surface *drawSurface, egl::Surface *readSurface, gl::Context *context); void destroySurface(egl::Surface *surface); + void destroyImage(egl::Image *image); + void destroyStream(egl::Stream *stream); void destroyContext(gl::Context *context); bool isInitialized() const; bool isValidConfig(const Config *config) const; bool isValidContext(gl::Context *context) const; bool isValidSurface(egl::Surface *surface) const; + bool isValidImage(const Image *image) const; + bool isValidStream(const Stream *stream) const; bool isValidNativeWindow(EGLNativeWindowType window) const; + static bool isValidDisplay(const egl::Display *display); static bool isValidNativeDisplay(EGLNativeDisplayType display); static bool hasExistingWindowSurface(EGLNativeWindowType window); @@ -80,6 +96,9 @@ class Display final : angle::NonCopyable bool testDeviceLost(); void notifyDeviceLost(); + Error waitClient() const; + Error waitNative(EGLint engine, egl::Surface *drawSurface, egl::Surface *readSurface) const; + const Caps &getCaps() const; const DisplayExtensions &getExtensions() const; @@ -91,9 +110,10 @@ class Display final : angle::NonCopyable rx::DisplayImpl *getImplementation() { return mImplementation; } Device *getDevice() const; + EGLenum getPlatform() const { return mPlatform; } private: - Display(EGLNativeDisplayType displayId); + Display(EGLenum platform, EGLNativeDisplayType displayId, Device *eglDevice); void setAttributes(rx::DisplayImpl *impl, const AttributeMap &attribMap); @@ -112,6 +132,12 @@ class Display final : angle::NonCopyable typedef std::set ContextSet; ContextSet mContextSet; + typedef std::set ImageSet; + ImageSet mImageSet; + + typedef std::set StreamSet; + StreamSet mStreamSet; + bool mInitialized; Caps mCaps; @@ -121,7 +147,8 @@ class Display final : angle::NonCopyable std::string mVendorString; - Device* mDevice; + Device *mDevice; + EGLenum mPlatform; }; } diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/Error.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/Error.cpp index e17f26bec4ae..fed1594972cb 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/Error.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/Error.cpp @@ -16,9 +16,16 @@ namespace gl { -Error::Error(GLenum errorCode, const char *msg, ...) - : mCode(errorCode), - mMessage(nullptr) +Error::Error(GLenum errorCode, const char *msg, ...) : mCode(errorCode), mID(errorCode) +{ + va_list vararg; + va_start(vararg, msg); + createMessageString(); + *mMessage = FormatString(msg, vararg); + va_end(vararg); +} + +Error::Error(GLenum errorCode, GLuint id, const char *msg, ...) : mCode(errorCode), mID(id) { va_list vararg; va_start(vararg, msg); @@ -29,9 +36,9 @@ Error::Error(GLenum errorCode, const char *msg, ...) void Error::createMessageString() const { - if (mMessage == nullptr) + if (!mMessage) { - mMessage = new std::string(); + mMessage.reset(new std::string); } } @@ -41,15 +48,28 @@ const std::string &Error::getMessage() const return *mMessage; } +bool Error::operator==(const Error &other) const +{ + if (mCode != other.mCode) + return false; + + // TODO(jmadill): Compare extended error codes instead of strings. + if ((!mMessage || !other.mMessage) && (!mMessage != !other.mMessage)) + return false; + + return (*mMessage == *other.mMessage); +} + +bool Error::operator!=(const Error &other) const +{ + return !(*this == other); +} } namespace egl { -Error::Error(EGLint errorCode, const char *msg, ...) - : mCode(errorCode), - mID(0), - mMessage(nullptr) +Error::Error(EGLint errorCode, const char *msg, ...) : mCode(errorCode), mID(0) { va_list vararg; va_start(vararg, msg); @@ -58,10 +78,7 @@ Error::Error(EGLint errorCode, const char *msg, ...) va_end(vararg); } -Error::Error(EGLint errorCode, EGLint id, const char *msg, ...) - : mCode(errorCode), - mID(id), - mMessage(nullptr) +Error::Error(EGLint errorCode, EGLint id, const char *msg, ...) : mCode(errorCode), mID(id) { va_list vararg; va_start(vararg, msg); @@ -69,11 +86,12 @@ Error::Error(EGLint errorCode, EGLint id, const char *msg, ...) *mMessage = FormatString(msg, vararg); va_end(vararg); } + void Error::createMessageString() const { - if (mMessage == nullptr) + if (!mMessage) { - mMessage = new std::string(); + mMessage.reset(new std::string); } } diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/Error.h b/Source/ThirdParty/ANGLE/src/libANGLE/Error.h index 581294343736..de3a50eb030b 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/Error.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/Error.h @@ -13,6 +13,7 @@ #include #include +#include namespace gl { @@ -22,28 +23,64 @@ class Error final public: explicit inline Error(GLenum errorCode); Error(GLenum errorCode, const char *msg, ...); + Error(GLenum errorCode, GLuint id, const char *msg, ...); inline Error(const Error &other); inline Error(Error &&other); - inline ~Error(); - inline Error &operator=(const Error &other); inline Error &operator=(Error &&other); inline GLenum getCode() const; + inline GLuint getID() const; inline bool isError() const; const std::string &getMessage() const; + // Useful for mocking and testing + bool operator==(const Error &other) const; + bool operator!=(const Error &other) const; + private: void createMessageString() const; GLenum mCode; - mutable std::string *mMessage; + GLuint mID; + mutable std::unique_ptr mMessage; }; +template +class ErrorOrResult +{ + public: + ErrorOrResult(const gl::Error &error) : mError(error) {} + ErrorOrResult(gl::Error &&error) : mError(std::move(error)) {} + + ErrorOrResult(T &&result) + : mError(GL_NO_ERROR), mResult(std::forward(result)) + { + } + + ErrorOrResult(const T &result) + : mError(GL_NO_ERROR), mResult(result) + { + } + + bool isError() const { return mError.isError(); } + const gl::Error &getError() const { return mError; } + T &&getResult() { return std::move(mResult); } + + private: + Error mError; + T mResult; +}; + +inline Error NoError() +{ + return Error(GL_NO_ERROR); } +} // namespace gl + namespace egl { @@ -56,8 +93,6 @@ class Error final inline Error(const Error &other); inline Error(Error &&other); - inline ~Error(); - inline Error &operator=(const Error &other); inline Error &operator=(Error &&other); @@ -72,10 +107,39 @@ class Error final EGLint mCode; EGLint mID; - mutable std::string *mMessage; + mutable std::unique_ptr mMessage; }; -} +} // 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(EXPR) \ + { \ + auto ANGLE_LOCAL_VAR = EXPR; \ + if (ANGLE_LOCAL_VAR.isError()) \ + { \ + return ANGLE_LOCAL_VAR; \ + } \ + } \ + ANGLE_EMPTY_STATEMENT + +#define ANGLE_TRY_RESULT(EXPR, RESULT) \ + { \ + auto ANGLE_LOCAL_VAR = EXPR; \ + if (ANGLE_LOCAL_VAR.isError()) \ + { \ + return ANGLE_LOCAL_VAR.getError(); \ + } \ + RESULT = ANGLE_LOCAL_VAR.getResult(); \ + } \ + ANGLE_EMPTY_STATEMENT + +#undef ANGLE_LOCAL_VAR +#undef ANGLE_CONCAT2 +#undef ANGLE_CONCAT1 #include "Error.inl" diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/Error.inl b/Source/ThirdParty/ANGLE/src/libANGLE/Error.inl index 32e8f0582873..900fc5fd033c 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/Error.inl +++ b/Source/ThirdParty/ANGLE/src/libANGLE/Error.inl @@ -15,15 +15,15 @@ namespace gl Error::Error(GLenum errorCode) : mCode(errorCode), - mMessage(nullptr) + mID(errorCode) { } Error::Error(const Error &other) : mCode(other.mCode), - mMessage(nullptr) + mID(other.mID) { - if (other.mMessage != nullptr) + if (other.mMessage) { createMessageString(); *mMessage = *(other.mMessage); @@ -32,28 +32,24 @@ Error::Error(const Error &other) Error::Error(Error &&other) : mCode(other.mCode), - mMessage(other.mMessage) -{ - other.mMessage = nullptr; -} - -Error::~Error() + mID(other.mID), + mMessage(std::move(other.mMessage)) { - SafeDelete(mMessage); } Error &Error::operator=(const Error &other) { mCode = other.mCode; + mID = other.mID; - if (other.mMessage != nullptr) + if (other.mMessage) { createMessageString(); *mMessage = *(other.mMessage); } else { - SafeDelete(mMessage); + mMessage.release(); } return *this; @@ -61,10 +57,12 @@ Error &Error::operator=(const Error &other) Error &Error::operator=(Error &&other) { - mCode = other.mCode; - mMessage = other.mMessage; - - other.mMessage = nullptr; + if (this != &other) + { + mCode = other.mCode; + mID = other.mID; + mMessage = std::move(other.mMessage); + } return *this; } @@ -74,6 +72,11 @@ GLenum Error::getCode() const return mCode; } +GLuint Error::getID() const +{ + return mID; +} + bool Error::isError() const { return (mCode != GL_NO_ERROR); @@ -86,17 +89,15 @@ namespace egl Error::Error(EGLint errorCode) : mCode(errorCode), - mID(0), - mMessage(nullptr) + mID(0) { } Error::Error(const Error &other) : mCode(other.mCode), - mID(other.mID), - mMessage(nullptr) + mID(other.mID) { - if (other.mMessage != nullptr) + if (other.mMessage) { createMessageString(); *mMessage = *(other.mMessage); @@ -106,14 +107,8 @@ Error::Error(const Error &other) Error::Error(Error &&other) : mCode(other.mCode), mID(other.mID), - mMessage(other.mMessage) -{ - other.mMessage = nullptr; -} - -Error::~Error() + mMessage(std::move(other.mMessage)) { - SafeDelete(mMessage); } Error &Error::operator=(const Error &other) @@ -121,14 +116,14 @@ Error &Error::operator=(const Error &other) mCode = other.mCode; mID = other.mID; - if (other.mMessage != nullptr) + if (other.mMessage) { createMessageString(); *mMessage = *(other.mMessage); } else { - SafeDelete(mMessage); + mMessage.release(); } return *this; @@ -136,11 +131,12 @@ Error &Error::operator=(const Error &other) Error &Error::operator=(Error &&other) { - mCode = other.mCode; - mID = other.mID; - mMessage = other.mMessage; - - other.mMessage = nullptr; + if (this != &other) + { + mCode = other.mCode; + mID = other.mID; + mMessage = std::move(other.mMessage); + } return *this; } diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/Fence.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/Fence.cpp index aa76791ee738..ff32f4bbe9a2 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/Fence.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/Fence.cpp @@ -76,10 +76,7 @@ Error FenceNV::finish() } FenceSync::FenceSync(rx::FenceSyncImpl *impl, GLuint id) - : RefCountObject(id), - mFence(impl), - mCondition(GL_NONE), - mFlags(0) + : RefCountObject(id), mFence(impl), mLabel(), mCondition(GL_NONE), mFlags(0) { } @@ -88,6 +85,16 @@ FenceSync::~FenceSync() SafeDelete(mFence); } +void FenceSync::setLabel(const std::string &label) +{ + mLabel = label; +} + +const std::string &FenceSync::getLabel() const +{ + return mLabel; +} + Error FenceSync::set(GLenum condition, GLbitfield flags) { Error error = mFence->set(condition, flags); diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/Fence.h b/Source/ThirdParty/ANGLE/src/libANGLE/Fence.h index 74dad0566e74..b2daed6f0e99 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/Fence.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/Fence.h @@ -10,6 +10,7 @@ #ifndef LIBANGLE_FENCE_H_ #define LIBANGLE_FENCE_H_ +#include "libANGLE/Debug.h" #include "libANGLE/Error.h" #include "libANGLE/RefCountObject.h" @@ -47,12 +48,15 @@ class FenceNV final : angle::NonCopyable GLenum mCondition; }; -class FenceSync final : public RefCountObject +class FenceSync final : public RefCountObject, public LabeledObject { public: - explicit FenceSync(rx::FenceSyncImpl *impl, GLuint id); + FenceSync(rx::FenceSyncImpl *impl, GLuint id); virtual ~FenceSync(); + void setLabel(const std::string &label) override; + const std::string &getLabel() const override; + Error set(GLenum condition, GLbitfield flags); Error clientWait(GLbitfield flags, GLuint64 timeout, GLenum *outResult); Error serverWait(GLbitfield flags, GLuint64 timeout); @@ -64,6 +68,8 @@ class FenceSync final : public RefCountObject private: rx::FenceSyncImpl *mFence; + std::string mLabel; + GLenum mCondition; GLbitfield mFlags; }; diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/Framebuffer.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/Framebuffer.cpp index ba08d35042d3..28b7cabf9e7c 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/Framebuffer.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/Framebuffer.cpp @@ -9,6 +9,7 @@ #include "libANGLE/Framebuffer.h" +#include "common/Optional.h" #include "common/utilities.h" #include "libANGLE/Config.h" #include "libANGLE/Context.h" @@ -20,7 +21,7 @@ #include "libANGLE/renderer/FramebufferImpl.h" #include "libANGLE/renderer/ImplFactory.h" #include "libANGLE/renderer/RenderbufferImpl.h" -#include "libANGLE/renderer/Workarounds.h" +#include "libANGLE/renderer/SurfaceImpl.h" namespace gl { @@ -38,11 +39,22 @@ void DetachMatchingAttachment(FramebufferAttachment *attachment, GLenum matchTyp } } +Framebuffer::Data::Data() + : mLabel(), + mColorAttachments(1), + mDrawBufferStates(1, GL_NONE), + mReadBufferState(GL_COLOR_ATTACHMENT0_EXT) +{ + mDrawBufferStates[0] = GL_COLOR_ATTACHMENT0_EXT; +} + Framebuffer::Data::Data(const Caps &caps) - : mColorAttachments(caps.maxColorAttachments), + : mLabel(), + mColorAttachments(caps.maxColorAttachments), mDrawBufferStates(caps.maxDrawBuffers, GL_NONE), mReadBufferState(GL_COLOR_ATTACHMENT0_EXT) { + ASSERT(mDrawBufferStates.size() > 0); mDrawBufferStates[0] = GL_COLOR_ATTACHMENT0_EXT; } @@ -50,6 +62,11 @@ Framebuffer::Data::~Data() { } +const std::string &Framebuffer::Data::getLabel() +{ + return mLabel; +} + const FramebufferAttachment *Framebuffer::Data::getReadAttachment() const { ASSERT(mReadBufferState == GL_BACK || (mReadBufferState >= GL_COLOR_ATTACHMENT0 && mReadBufferState <= GL_COLOR_ATTACHMENT15)); @@ -84,7 +101,7 @@ const FramebufferAttachment *Framebuffer::Data::getDepthOrStencilAttachment() co return nullptr; } -const FramebufferAttachment *Framebuffer::Data::getColorAttachment(unsigned int colorAttachment) const +const FramebufferAttachment *Framebuffer::Data::getColorAttachment(size_t colorAttachment) const { ASSERT(colorAttachment < mColorAttachments.size()); return mColorAttachments[colorAttachment].isAttached() ? @@ -116,19 +133,52 @@ const FramebufferAttachment *Framebuffer::Data::getDepthStencilAttachment() cons return nullptr; } -Framebuffer::Framebuffer(const Caps &caps, rx::ImplFactory *factory, GLuint id) - : mData(caps), - mImpl(nullptr), - mId(id) +bool Framebuffer::Data::attachmentsHaveSameDimensions() const { - if (mId == 0) + Optional attachmentSize; + + auto hasMismatchedSize = [&attachmentSize](const FramebufferAttachment &attachment) { - mImpl = factory->createDefaultFramebuffer(mData); + if (!attachment.isAttached()) + { + return false; + } + + if (!attachmentSize.valid()) + { + attachmentSize = attachment.getSize(); + return false; + } + + return (attachment.getSize() != attachmentSize.value()); + }; + + for (const auto &attachment : mColorAttachments) + { + if (hasMismatchedSize(attachment)) + { + return false; + } } - else + + if (hasMismatchedSize(mDepthAttachment)) { - mImpl = factory->createFramebuffer(mData); + return false; } + + return !hasMismatchedSize(mStencilAttachment); +} + +Framebuffer::Framebuffer(const Caps &caps, rx::ImplFactory *factory, GLuint id) + : mData(caps), mImpl(factory->createFramebuffer(mData)), mId(id) +{ + ASSERT(mId != 0); + ASSERT(mImpl != nullptr); +} + +Framebuffer::Framebuffer(rx::SurfaceImpl *surface) + : mData(), mImpl(surface->createDefaultFramebuffer(mData)), mId(0) +{ ASSERT(mImpl != nullptr); } @@ -137,6 +187,16 @@ Framebuffer::~Framebuffer() SafeDelete(mImpl); } +void Framebuffer::setLabel(const std::string &label) +{ + mData.mLabel = label; +} + +const std::string &Framebuffer::getLabel() const +{ + return mData.mLabel; +} + void Framebuffer::detachTexture(GLuint textureId) { detachResourceById(GL_TEXTURE, textureId); @@ -158,7 +218,7 @@ void Framebuffer::detachResourceById(GLenum resourceType, GLuint resourceId) DetachMatchingAttachment(&mData.mStencilAttachment, resourceType, resourceId); } -const FramebufferAttachment *Framebuffer::getColorbuffer(unsigned int colorAttachment) const +const FramebufferAttachment *Framebuffer::getColorbuffer(size_t colorAttachment) const { return mData.getColorAttachment(colorAttachment); } @@ -228,10 +288,20 @@ const FramebufferAttachment *Framebuffer::getAttachment(GLenum attachment) const } } -GLenum Framebuffer::getDrawBufferState(unsigned int colorAttachment) const +size_t Framebuffer::getDrawbufferStateCount() const +{ + return mData.mDrawBufferStates.size(); +} + +GLenum Framebuffer::getDrawBufferState(size_t drawBuffer) const +{ + ASSERT(drawBuffer < mData.mDrawBufferStates.size()); + return mData.mDrawBufferStates[drawBuffer]; +} + +const std::vector &Framebuffer::getDrawBufferStates() const { - ASSERT(colorAttachment < mData.mDrawBufferStates.size()); - return mData.mDrawBufferStates[colorAttachment]; + return mData.getDrawBufferStates(); } void Framebuffer::setDrawBuffers(size_t count, const GLenum *buffers) @@ -241,7 +311,37 @@ void Framebuffer::setDrawBuffers(size_t count, const GLenum *buffers) ASSERT(count <= drawStates.size()); std::copy(buffers, buffers + count, drawStates.begin()); std::fill(drawStates.begin() + count, drawStates.end(), GL_NONE); - mImpl->setDrawBuffers(count, buffers); + mDirtyBits.set(DIRTY_BIT_DRAW_BUFFERS); +} + +const FramebufferAttachment *Framebuffer::getDrawBuffer(size_t drawBuffer) const +{ + ASSERT(drawBuffer < mData.mDrawBufferStates.size()); + if (mData.mDrawBufferStates[drawBuffer] != 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(mData.mDrawBufferStates[drawBuffer] == GL_COLOR_ATTACHMENT0 + drawBuffer || + (drawBuffer == 0 && mData.mDrawBufferStates[drawBuffer] == GL_BACK)); + return getAttachment(mData.mDrawBufferStates[drawBuffer]); + } + else + { + return nullptr; + } +} + +bool Framebuffer::hasEnabledDrawBuffer() const +{ + for (size_t drawbufferIdx = 0; drawbufferIdx < mData.mDrawBufferStates.size(); ++drawbufferIdx) + { + if (getDrawBuffer(drawbufferIdx) != nullptr) + { + return true; + } + } + + return false; } GLenum Framebuffer::getReadBufferState() const @@ -255,27 +355,17 @@ void Framebuffer::setReadBuffer(GLenum buffer) (buffer >= GL_COLOR_ATTACHMENT0 && (buffer - GL_COLOR_ATTACHMENT0) < mData.mColorAttachments.size())); mData.mReadBufferState = buffer; - mImpl->setReadBuffer(buffer); + mDirtyBits.set(DIRTY_BIT_READ_BUFFER); } -bool Framebuffer::isEnabledColorAttachment(unsigned int colorAttachment) const +size_t Framebuffer::getNumColorBuffers() const { - ASSERT(colorAttachment < mData.mColorAttachments.size()); - return (mData.mColorAttachments[colorAttachment].isAttached() && - mData.mDrawBufferStates[colorAttachment] != GL_NONE); + return mData.mColorAttachments.size(); } -bool Framebuffer::hasEnabledColorAttachment() const +bool Framebuffer::hasDepth() const { - for (size_t colorAttachment = 0; colorAttachment < mData.mColorAttachments.size(); ++colorAttachment) - { - if (isEnabledColorAttachment(static_cast(colorAttachment))) - { - return true; - } - } - - return false; + return (mData.mDepthAttachment.isAttached() && mData.mDepthAttachment.getDepthSize() > 0); } bool Framebuffer::hasStencil() const @@ -285,9 +375,9 @@ bool Framebuffer::hasStencil() const bool Framebuffer::usingExtendedDrawBuffers() const { - for (size_t colorAttachment = 1; colorAttachment < mData.mColorAttachments.size(); ++colorAttachment) + for (size_t drawbufferIdx = 1; drawbufferIdx < mData.mDrawBufferStates.size(); ++drawbufferIdx) { - if (isEnabledColorAttachment(static_cast(colorAttachment))) + if (getDrawBuffer(drawbufferIdx) != nullptr) { return true; } @@ -305,8 +395,6 @@ GLenum Framebuffer::checkStatus(const gl::Data &data) const return GL_FRAMEBUFFER_COMPLETE; } - int width = 0; - int height = 0; unsigned int colorbufferSize = 0; int samples = -1; bool missingAttachment = true; @@ -315,7 +403,8 @@ GLenum Framebuffer::checkStatus(const gl::Data &data) const { if (colorAttachment.isAttached()) { - if (colorAttachment.getWidth() == 0 || colorAttachment.getHeight() == 0) + const Extents &size = colorAttachment.getSize(); + if (size.width == 0 || size.height == 0) { return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; } @@ -327,13 +416,29 @@ GLenum Framebuffer::checkStatus(const gl::Data &data) const { if (!formatCaps.renderable) { - return GL_FRAMEBUFFER_UNSUPPORTED; + return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; } if (formatInfo.depthBits > 0 || formatInfo.stencilBits > 0) { return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; } + + if (colorAttachment.layer() >= size.depth) + { + return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; + } + + // 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 = colorAttachment.getTexture(); + ASSERT(texture); + if (texture->getTarget() == GL_TEXTURE_CUBE_MAP && !texture->isCubeComplete()) + { + return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; + } } else if (colorAttachment.type() == GL_RENDERBUFFER) { @@ -345,12 +450,6 @@ GLenum Framebuffer::checkStatus(const gl::Data &data) const if (!missingAttachment) { - // all color attachments must have the same width and height - if (colorAttachment.getWidth() != width || colorAttachment.getHeight() != height) - { - return GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS; - } - // 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. if (colorAttachment.getSamples() != samples) @@ -370,8 +469,6 @@ GLenum Framebuffer::checkStatus(const gl::Data &data) const } else { - width = colorAttachment.getWidth(); - height = colorAttachment.getHeight(); samples = colorAttachment.getSamples(); colorbufferSize = formatInfo.pixelBytes; missingAttachment = false; @@ -382,7 +479,8 @@ GLenum Framebuffer::checkStatus(const gl::Data &data) const const FramebufferAttachment &depthAttachment = mData.mDepthAttachment; if (depthAttachment.isAttached()) { - if (depthAttachment.getWidth() == 0 || depthAttachment.getHeight() == 0) + const Extents &size = depthAttachment.getSize(); + if (size.width == 0 || size.height == 0) { return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; } @@ -400,7 +498,7 @@ GLenum Framebuffer::checkStatus(const gl::Data &data) const if (!formatCaps.renderable) { - return GL_FRAMEBUFFER_UNSUPPORTED; + return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; } if (formatInfo.depthBits == 0) @@ -418,15 +516,9 @@ GLenum Framebuffer::checkStatus(const gl::Data &data) const if (missingAttachment) { - width = depthAttachment.getWidth(); - height = depthAttachment.getHeight(); samples = depthAttachment.getSamples(); missingAttachment = false; } - else if (width != depthAttachment.getWidth() || height != depthAttachment.getHeight()) - { - return GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS; - } else if (samples != depthAttachment.getSamples()) { return GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_ANGLE; @@ -436,7 +528,8 @@ GLenum Framebuffer::checkStatus(const gl::Data &data) const const FramebufferAttachment &stencilAttachment = mData.mStencilAttachment; if (stencilAttachment.isAttached()) { - if (stencilAttachment.getWidth() == 0 || stencilAttachment.getHeight() == 0) + const Extents &size = stencilAttachment.getSize(); + if (size.width == 0 || size.height == 0) { return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; } @@ -455,7 +548,7 @@ GLenum Framebuffer::checkStatus(const gl::Data &data) const if (!formatCaps.renderable) { - return GL_FRAMEBUFFER_UNSUPPORTED; + return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; } if (formatInfo.stencilBits == 0) @@ -473,35 +566,40 @@ GLenum Framebuffer::checkStatus(const gl::Data &data) const if (missingAttachment) { - width = stencilAttachment.getWidth(); - height = stencilAttachment.getHeight(); samples = stencilAttachment.getSamples(); missingAttachment = false; } - else if (width != stencilAttachment.getWidth() || height != stencilAttachment.getHeight()) - { - return GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS; - } else if (samples != stencilAttachment.getSamples()) { return GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_ANGLE; } } - // 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 (depthAttachment.isAttached() && stencilAttachment.isAttached() && !hasValidDepthStencil()) - { - return GL_FRAMEBUFFER_UNSUPPORTED; - } - // we need to have at least one attachment to be complete if (missingAttachment) { return GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT; } - return mImpl->checkStatus(); + // In ES 2.0, all color attachments must have the same width and height. + // In ES 3.0, there is no such restriction. + if (data.clientVersion < 3 && !mData.attachmentsHaveSameDimensions()) + { + return GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS; + } + + syncState(); + if (!mImpl->checkStatus()) + { + return GL_FRAMEBUFFER_UNSUPPORTED; + } + + return GL_FRAMEBUFFER_COMPLETE; +} + +Error Framebuffer::discard(size_t count, const GLenum *attachments) +{ + return mImpl->discard(count, attachments); } Error Framebuffer::invalidate(size_t count, const GLenum *attachments) @@ -516,27 +614,65 @@ Error Framebuffer::invalidateSub(size_t count, const GLenum *attachments, const Error Framebuffer::clear(const gl::Data &data, GLbitfield mask) { + if (data.state->isRasterizerDiscardEnabled()) + { + return gl::Error(GL_NO_ERROR); + } + return mImpl->clear(data, mask); } -Error Framebuffer::clearBufferfv(const State &state, GLenum buffer, GLint drawbuffer, const GLfloat *values) +Error Framebuffer::clearBufferfv(const gl::Data &data, + GLenum buffer, + GLint drawbuffer, + const GLfloat *values) { - return mImpl->clearBufferfv(state, buffer, drawbuffer, values); + if (data.state->isRasterizerDiscardEnabled()) + { + return gl::Error(GL_NO_ERROR); + } + + return mImpl->clearBufferfv(data, buffer, drawbuffer, values); } -Error Framebuffer::clearBufferuiv(const State &state, GLenum buffer, GLint drawbuffer, const GLuint *values) +Error Framebuffer::clearBufferuiv(const gl::Data &data, + GLenum buffer, + GLint drawbuffer, + const GLuint *values) { - return mImpl->clearBufferuiv(state, buffer, drawbuffer, values); + if (data.state->isRasterizerDiscardEnabled()) + { + return gl::Error(GL_NO_ERROR); + } + + return mImpl->clearBufferuiv(data, buffer, drawbuffer, values); } -Error Framebuffer::clearBufferiv(const State &state, GLenum buffer, GLint drawbuffer, const GLint *values) +Error Framebuffer::clearBufferiv(const gl::Data &data, + GLenum buffer, + GLint drawbuffer, + const GLint *values) { - return mImpl->clearBufferiv(state, buffer, drawbuffer, values); + if (data.state->isRasterizerDiscardEnabled()) + { + return gl::Error(GL_NO_ERROR); + } + + return mImpl->clearBufferiv(data, buffer, drawbuffer, values); } -Error Framebuffer::clearBufferfi(const State &state, GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil) +Error Framebuffer::clearBufferfi(const gl::Data &data, + GLenum buffer, + GLint drawbuffer, + GLfloat depth, + GLint stencil) { - return mImpl->clearBufferfi(state, buffer, drawbuffer, depth, stencil); + if (data.state->isRasterizerDiscardEnabled()) + { + return gl::Error(GL_NO_ERROR); + } + + return mImpl->clearBufferfi(data, buffer, drawbuffer, depth, stencil); } GLenum Framebuffer::getImplementationColorReadFormat() const @@ -549,13 +685,33 @@ GLenum Framebuffer::getImplementationColorReadType() const return mImpl->getImplementationColorReadType(); } -Error Framebuffer::readPixels(const gl::State &state, const gl::Rectangle &area, GLenum format, GLenum type, GLvoid *pixels) const +Error Framebuffer::readPixels(const State &state, + const Rectangle &area, + GLenum format, + GLenum type, + GLvoid *pixels) const { - return mImpl->readPixels(state, area, format, type, pixels); + Error error = mImpl->readPixels(state, area, format, type, pixels); + if (error.isError()) + { + return error; + } + + Buffer *unpackBuffer = state.getUnpackState().pixelBuffer.get(); + if (unpackBuffer) + { + unpackBuffer->onPixelUnpack(); + } + + return Error(GL_NO_ERROR); } -Error Framebuffer::blit(const gl::State &state, const gl::Rectangle &sourceArea, const gl::Rectangle &destArea, - GLbitfield mask, GLenum filter, const gl::Framebuffer *sourceFramebuffer) +Error Framebuffer::blit(const State &state, + const Rectangle &sourceArea, + const Rectangle &destArea, + GLbitfield mask, + GLenum filter, + const Framebuffer *sourceFramebuffer) { return mImpl->blit(state, sourceArea, destArea, mask, filter, sourceFramebuffer); } @@ -591,45 +747,48 @@ void Framebuffer::setAttachment(GLenum type, if (binding == GL_DEPTH_STENCIL || binding == GL_DEPTH_STENCIL_ATTACHMENT) { // ensure this is a legitimate depth+stencil format - FramebufferAttachment::Target target(binding, textureIndex); - GLenum internalFormat = resource->getAttachmentInternalFormat(target); - const InternalFormat &formatInfo = GetInternalFormatInfo(internalFormat); - if (resource && formatInfo.depthBits > 0 && formatInfo.stencilBits > 0) + FramebufferAttachmentObject *attachmentObj = resource; + if (resource) { - mData.mDepthAttachment.attach(type, binding, textureIndex, resource); - mData.mStencilAttachment.attach(type, binding, textureIndex, resource); - } - else - { - mData.mDepthAttachment.detach(); - mData.mStencilAttachment.detach(); + FramebufferAttachment::Target target(binding, textureIndex); + GLenum internalFormat = resource->getAttachmentInternalFormat(target); + const InternalFormat &formatInfo = GetInternalFormatInfo(internalFormat); + if (formatInfo.depthBits == 0 || formatInfo.stencilBits == 0) + { + // Attaching nullptr detaches the current attachment. + attachmentObj = nullptr; + } } - mImpl->onUpdateDepthStencilAttachment(); + + mData.mDepthAttachment.attach(type, binding, textureIndex, attachmentObj); + mData.mStencilAttachment.attach(type, binding, textureIndex, attachmentObj); + mDirtyBits.set(DIRTY_BIT_DEPTH_ATTACHMENT); + mDirtyBits.set(DIRTY_BIT_STENCIL_ATTACHMENT); } else { switch (binding) { - case GL_DEPTH: - case GL_DEPTH_ATTACHMENT: - mData.mDepthAttachment.attach(type, binding, textureIndex, resource); - mImpl->onUpdateDepthAttachment(); + case GL_DEPTH: + case GL_DEPTH_ATTACHMENT: + mData.mDepthAttachment.attach(type, binding, textureIndex, resource); + mDirtyBits.set(DIRTY_BIT_DEPTH_ATTACHMENT); break; - case GL_STENCIL: - case GL_STENCIL_ATTACHMENT: - mData.mStencilAttachment.attach(type, binding, textureIndex, resource); - mImpl->onUpdateStencilAttachment(); + case GL_STENCIL: + case GL_STENCIL_ATTACHMENT: + mData.mStencilAttachment.attach(type, binding, textureIndex, resource); + mDirtyBits.set(DIRTY_BIT_STENCIL_ATTACHMENT); break; - case GL_BACK: - mData.mColorAttachments[0].attach(type, binding, textureIndex, resource); - mImpl->onUpdateColorAttachment(0); + case GL_BACK: + mData.mColorAttachments[0].attach(type, binding, textureIndex, resource); + mDirtyBits.set(DIRTY_BIT_COLOR_ATTACHMENT_0); break; - default: + default: { size_t colorIndex = binding - GL_COLOR_ATTACHMENT0; ASSERT(colorIndex < mData.mColorAttachments.size()); mData.mColorAttachments[colorIndex].attach(type, binding, textureIndex, resource); - mImpl->onUpdateColorAttachment(colorIndex); + mDirtyBits.set(DIRTY_BIT_COLOR_ATTACHMENT_0 + colorIndex); } break; } @@ -641,4 +800,13 @@ void Framebuffer::resetAttachment(GLenum binding) setAttachment(GL_NONE, binding, ImageIndex::MakeInvalid(), nullptr); } +void Framebuffer::syncState() const +{ + if (mDirtyBits.any()) + { + mImpl->syncState(mDirtyBits); + mDirtyBits.reset(); + } } + +} // namespace gl diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/Framebuffer.h b/Source/ThirdParty/ANGLE/src/libANGLE/Framebuffer.h index 9c5349d74dab..9c48b77d3a90 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/Framebuffer.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/Framebuffer.h @@ -14,6 +14,7 @@ #include "common/angleutils.h" #include "libANGLE/Constants.h" +#include "libANGLE/Debug.h" #include "libANGLE/Error.h" #include "libANGLE/FramebufferAttachment.h" #include "libANGLE/RefCountObject.h" @@ -23,7 +24,7 @@ namespace rx class ImplFactory; class FramebufferImpl; class RenderbufferImpl; -struct Workarounds; +class SurfaceImpl; } namespace egl @@ -33,6 +34,7 @@ class Surface; namespace gl { +class Context; class Renderbuffer; class State; class Texture; @@ -43,30 +45,38 @@ struct Extensions; struct ImageIndex; struct Rectangle; -class Framebuffer +class Framebuffer final : public LabeledObject { public: class Data final : angle::NonCopyable { public: + explicit Data(); explicit Data(const Caps &caps); ~Data(); + const std::string &getLabel(); + const FramebufferAttachment *getReadAttachment() const; const FramebufferAttachment *getFirstColorAttachment() const; const FramebufferAttachment *getDepthOrStencilAttachment() const; - const FramebufferAttachment *getColorAttachment(unsigned int colorAttachment) const; + const FramebufferAttachment *getColorAttachment(size_t colorAttachment) const; const FramebufferAttachment *getDepthAttachment() const; const FramebufferAttachment *getStencilAttachment() const; const FramebufferAttachment *getDepthStencilAttachment() const; const std::vector &getDrawBufferStates() const { return mDrawBufferStates; } + GLenum getReadBufferState() const { return mReadBufferState; } const std::vector &getColorAttachments() const { return mColorAttachments; } + bool attachmentsHaveSameDimensions() const; + private: friend class Framebuffer; + std::string mLabel; + std::vector mColorAttachments; FramebufferAttachment mDepthAttachment; FramebufferAttachment mStencilAttachment; @@ -76,8 +86,12 @@ class Framebuffer }; Framebuffer(const Caps &caps, rx::ImplFactory *factory, GLuint id); + Framebuffer(rx::SurfaceImpl *surface); virtual ~Framebuffer(); + void setLabel(const std::string &label) override; + const std::string &getLabel() const override; + const rx::FramebufferImpl *getImplementation() const { return mImpl; } rx::FramebufferImpl *getImplementation() { return mImpl; } @@ -92,7 +106,7 @@ class Framebuffer void detachTexture(GLuint texture); void detachRenderbuffer(GLuint renderbuffer); - const FramebufferAttachment *getColorbuffer(unsigned int colorAttachment) const; + const FramebufferAttachment *getColorbuffer(size_t colorAttachment) const; const FramebufferAttachment *getDepthbuffer() const; const FramebufferAttachment *getStencilbuffer() const; const FramebufferAttachment *getDepthStencilBuffer() const; @@ -103,14 +117,18 @@ class Framebuffer const FramebufferAttachment *getAttachment(GLenum attachment) const; - GLenum getDrawBufferState(unsigned int colorAttachment) const; + size_t getDrawbufferStateCount() const; + GLenum getDrawBufferState(size_t drawBuffer) const; + const std::vector &getDrawBufferStates() const; void setDrawBuffers(size_t count, const GLenum *buffers); + const FramebufferAttachment *getDrawBuffer(size_t drawBuffer) const; + bool hasEnabledDrawBuffer() const; GLenum getReadBufferState() const; void setReadBuffer(GLenum buffer); - bool isEnabledColorAttachment(unsigned int colorAttachment) const; - bool hasEnabledColorAttachment() const; + size_t getNumColorBuffers() const; + bool hasDepth() const; bool hasStencil() const; int getSamples(const gl::Data &data) const; bool usingExtendedDrawBuffers() const; @@ -118,21 +136,58 @@ class Framebuffer GLenum checkStatus(const gl::Data &data) const; bool hasValidDepthStencil() const; + Error discard(size_t count, const GLenum *attachments); Error invalidate(size_t count, const GLenum *attachments); Error invalidateSub(size_t count, const GLenum *attachments, const gl::Rectangle &area); Error clear(const gl::Data &data, GLbitfield mask); - Error clearBufferfv(const State &state, GLenum buffer, GLint drawbuffer, const GLfloat *values); - Error clearBufferuiv(const State &state, GLenum buffer, GLint drawbuffer, const GLuint *values); - Error clearBufferiv(const State &state, GLenum buffer, GLint drawbuffer, const GLint *values); - Error clearBufferfi(const State &state, GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil); + Error clearBufferfv(const gl::Data &data, + GLenum buffer, + GLint drawbuffer, + const GLfloat *values); + Error clearBufferuiv(const gl::Data &data, + GLenum buffer, + GLint drawbuffer, + const GLuint *values); + Error clearBufferiv(const gl::Data &data, GLenum buffer, GLint drawbuffer, const GLint *values); + Error clearBufferfi(const gl::Data &data, + GLenum buffer, + GLint drawbuffer, + GLfloat depth, + GLint stencil); GLenum getImplementationColorReadFormat() const; GLenum getImplementationColorReadType() const; - Error readPixels(const gl::State &state, const gl::Rectangle &area, GLenum format, GLenum type, GLvoid *pixels) const; + Error readPixels(const gl::State &state, + const gl::Rectangle &area, + GLenum format, + GLenum type, + GLvoid *pixels) const; + + Error blit(const State &state, + const Rectangle &sourceArea, + const Rectangle &destArea, + GLbitfield mask, + GLenum filter, + const Framebuffer *sourceFramebuffer); + + enum DirtyBitType + { + DIRTY_BIT_COLOR_ATTACHMENT_0, + DIRTY_BIT_COLOR_ATTACHMENT_MAX = + DIRTY_BIT_COLOR_ATTACHMENT_0 + gl::IMPLEMENTATION_MAX_FRAMEBUFFER_ATTACHMENTS, + DIRTY_BIT_DEPTH_ATTACHMENT = DIRTY_BIT_COLOR_ATTACHMENT_MAX, + DIRTY_BIT_STENCIL_ATTACHMENT, + DIRTY_BIT_DRAW_BUFFERS, + DIRTY_BIT_READ_BUFFER, + DIRTY_BIT_UNKNOWN, + DIRTY_BIT_MAX = DIRTY_BIT_UNKNOWN, + }; - Error blit(const gl::State &state, const gl::Rectangle &sourceArea, const gl::Rectangle &destArea, - GLbitfield mask, GLenum filter, const gl::Framebuffer *sourceFramebuffer); + typedef std::bitset DirtyBits; + bool hasAnyDirtyBit() const { return mDirtyBits.any(); } + + void syncState() const; protected: void detachResourceById(GLenum resourceType, GLuint resourceId); @@ -140,6 +195,9 @@ class Framebuffer Data mData; rx::FramebufferImpl *mImpl; GLuint mId; + + // TODO(jmadill): See if we can make this non-mutable. + mutable DirtyBits mDirtyBits; }; } diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/FramebufferAttachment.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/FramebufferAttachment.cpp index 8e3a9784e569..352a326c230a 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/FramebufferAttachment.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/FramebufferAttachment.cpp @@ -22,6 +22,12 @@ namespace gl ////// FramebufferAttachment::Target Implementation ////// +FramebufferAttachment::Target::Target() + : mBinding(GL_NONE), + mTextureIndex(ImageIndex::MakeInvalid()) +{ +} + FramebufferAttachment::Target::Target(GLenum binding, const ImageIndex &imageIndex) : mBinding(binding), mTextureIndex(imageIndex) @@ -44,8 +50,7 @@ FramebufferAttachment::Target &FramebufferAttachment::Target::operator=(const Ta ////// FramebufferAttachment Implementation ////// FramebufferAttachment::FramebufferAttachment() - : mType(GL_NONE), - mTarget(GL_NONE, ImageIndex::MakeInvalid()) + : mType(GL_NONE), mResource(nullptr) { } @@ -53,19 +58,39 @@ FramebufferAttachment::FramebufferAttachment(GLenum type, GLenum binding, const ImageIndex &textureIndex, FramebufferAttachmentObject *resource) - : mType(type), - mTarget(binding, textureIndex) + : mResource(nullptr) +{ + attach(type, binding, textureIndex, resource); +} + +FramebufferAttachment::FramebufferAttachment(const FramebufferAttachment &other) + : mResource(nullptr) +{ + attach(other.mType, other.mTarget.binding(), other.mTarget.textureIndex(), other.mResource); +} + +FramebufferAttachment &FramebufferAttachment::operator=(const FramebufferAttachment &other) +{ + attach(other.mType, other.mTarget.binding(), other.mTarget.textureIndex(), other.mResource); + return *this; +} + +FramebufferAttachment::~FramebufferAttachment() { - mResource.set(resource); + detach(); } void FramebufferAttachment::detach() { mType = GL_NONE; - mResource.set(nullptr); + if (mResource != nullptr) + { + mResource->onDetach(); + mResource = nullptr; + } // not technically necessary, could omit for performance - mTarget = Target(GL_NONE, ImageIndex::MakeInvalid()); + mTarget = Target(); } void FramebufferAttachment::attach(GLenum type, @@ -75,12 +100,16 @@ void FramebufferAttachment::attach(GLenum type, { mType = type; mTarget = Target(binding, textureIndex); - mResource.set(resource); -} -FramebufferAttachment::~FramebufferAttachment() -{ - mResource.set(nullptr); + if (resource) + { + resource->onAttach(); + } + if (mResource != nullptr) + { + mResource->onDetach(); + } + mResource = resource; } GLuint FramebufferAttachment::getRedSize() const @@ -123,6 +152,11 @@ GLenum FramebufferAttachment::getColorEncoding() const return GetInternalFormatInfo(getInternalFormat()).colorEncoding; } +GLuint FramebufferAttachment::id() const +{ + return mResource->getId(); +} + const ImageIndex &FramebufferAttachment::getTextureImageIndex() const { ASSERT(type() == GL_TEXTURE); @@ -158,17 +192,17 @@ GLint FramebufferAttachment::layer() const Texture *FramebufferAttachment::getTexture() const { - return rx::GetAs(mResource.get()); + return rx::GetAs(mResource); } Renderbuffer *FramebufferAttachment::getRenderbuffer() const { - return rx::GetAs(mResource.get()); + return rx::GetAs(mResource); } const egl::Surface *FramebufferAttachment::getSurface() const { - return rx::GetAs(mResource.get()); + return rx::GetAs(mResource); } } diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/FramebufferAttachment.h b/Source/ThirdParty/ANGLE/src/libANGLE/FramebufferAttachment.h index 32a8a18ba9d8..33196f5c61f9 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/FramebufferAttachment.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/FramebufferAttachment.h @@ -12,9 +12,9 @@ #include "angle_gl.h" #include "common/angleutils.h" +#include "libANGLE/angletypes.h" #include "libANGLE/Error.h" #include "libANGLE/ImageIndex.h" -#include "libANGLE/RefCountObject.h" namespace egl { @@ -57,20 +57,8 @@ class FramebufferAttachment final const ImageIndex &textureIndex, FramebufferAttachmentObject *resource); - FramebufferAttachment(const FramebufferAttachment &other) - : mType(other.mType), - mTarget(other.mTarget) - { - mResource.set(other.mResource.get()); - } - - FramebufferAttachment &operator=(const FramebufferAttachment &other) - { - mType = other.mType; - mTarget = other.mTarget; - mResource.set(other.mResource.get()); - return *this; - } + FramebufferAttachment(const FramebufferAttachment &other); + FramebufferAttachment &operator=(const FramebufferAttachment &other); ~FramebufferAttachment(); @@ -83,6 +71,7 @@ class FramebufferAttachment final class Target { public: + Target(); Target(GLenum binding, const ImageIndex &imageIndex); Target(const Target &other); Target &operator=(const Target &other); @@ -115,7 +104,7 @@ class FramebufferAttachment final bool isRenderbufferWithId(GLuint renderbufferId) const { return mType == GL_RENDERBUFFER && id() == renderbufferId; } GLenum getBinding() const { return mTarget.binding(); } - GLuint id() const { return mResource.id(); } + GLuint id() const; // These methods are only legal to call on Texture attachments const ImageIndex &getTextureImageIndex() const; @@ -123,8 +112,10 @@ class FramebufferAttachment final GLint mipLevel() const; GLint layer() const; - GLsizei getWidth() const; - GLsizei getHeight() 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; GLenum getInternalFormat() const; GLsizei getSamples() const; GLenum type() const { return mType; } @@ -150,20 +141,24 @@ class FramebufferAttachment final GLenum mType; Target mTarget; - BindingPointer mResource; + FramebufferAttachmentObject *mResource; }; // A base class for objects that FBO Attachments may point to. -class FramebufferAttachmentObject : public RefCountObject +class FramebufferAttachmentObject { public: - FramebufferAttachmentObject(GLuint id) : RefCountObject(id) {} + FramebufferAttachmentObject() {} + virtual ~FramebufferAttachmentObject() {} - virtual GLsizei getAttachmentWidth(const FramebufferAttachment::Target &target) const = 0; - virtual GLsizei getAttachmentHeight(const FramebufferAttachment::Target &target) const = 0; + virtual Extents getAttachmentSize(const FramebufferAttachment::Target &target) const = 0; virtual GLenum getAttachmentInternalFormat(const FramebufferAttachment::Target &target) const = 0; virtual GLsizei getAttachmentSamples(const FramebufferAttachment::Target &target) const = 0; + virtual void onAttach() = 0; + virtual void onDetach() = 0; + virtual GLuint getId() const = 0; + Error getAttachmentRenderTarget(const FramebufferAttachment::Target &target, rx::FramebufferAttachmentRenderTarget **rtOut) const; @@ -171,14 +166,9 @@ class FramebufferAttachmentObject : public RefCountObject virtual rx::FramebufferAttachmentObjectImpl *getAttachmentImpl() const = 0; }; -inline GLsizei FramebufferAttachment::getWidth() const -{ - return mResource->getAttachmentWidth(mTarget); -} - -inline GLsizei FramebufferAttachment::getHeight() const +inline Extents FramebufferAttachment::getSize() const { - return mResource->getAttachmentHeight(mTarget); + return mResource->getAttachmentSize(mTarget); } inline GLenum FramebufferAttachment::getInternalFormat() const diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/HandleAllocator.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/HandleAllocator.cpp index 59d39667588a..4815855d5a58 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/HandleAllocator.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/HandleAllocator.cpp @@ -20,13 +20,13 @@ struct HandleAllocator::HandleRangeComparator { bool operator()(const HandleRange &range, GLuint handle) const { - return (handle < range.begin); + return (range.end < handle); } }; HandleAllocator::HandleAllocator() : mBaseValue(1), mNextValue(1) { - mUnallocatedList.push_back(HandleRange(1, std::numeric_limits::max() - 1)); + mUnallocatedList.push_back(HandleRange(1, std::numeric_limits::max())); } HandleAllocator::HandleAllocator(GLuint maximumHandleValue) : mBaseValue(1), mNextValue(1) @@ -120,14 +120,15 @@ void HandleAllocator::reserve(GLuint handle) // need to split the range auto placementIt = mUnallocatedList.erase(boundIt); - if (begin != handle) + if (handle + 1 != end) { - placementIt = mUnallocatedList.insert(placementIt, HandleRange(begin, handle)); + placementIt = mUnallocatedList.insert(placementIt, HandleRange(handle + 1, end)); } - if (handle + 1 != end) + if (begin != handle) { - mUnallocatedList.insert(placementIt, HandleRange(handle + 1, end)); + ASSERT(begin < handle); + mUnallocatedList.insert(placementIt, HandleRange(begin, handle)); } } -} +} // namespace gl diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/HandleAllocator.h b/Source/ThirdParty/ANGLE/src/libANGLE/HandleAllocator.h index c22f2ba61aef..1888d57cfa0c 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/HandleAllocator.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/HandleAllocator.h @@ -58,6 +58,6 @@ class HandleAllocator final : angle::NonCopyable std::vector mReleasedList; }; -} +} // namespace gl #endif // LIBANGLE_HANDLEALLOCATOR_H_ diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/HandleAllocator_unittest.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/HandleAllocator_unittest.cpp index be067dca1af8..726b64bab733 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/HandleAllocator_unittest.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/HandleAllocator_unittest.cpp @@ -90,4 +90,37 @@ TEST(HandleAllocatorTest, Reallocation) EXPECT_EQ(finalResult, 1); } +// The following test covers reserving a handle with max uint value. +// See http://anglebug.com/1052 +TEST(HandleAllocatorTest, ReserveMaxUintHandle) +{ + gl::HandleAllocator allocator; + + GLuint maxUintHandle = std::numeric_limits::max(); + allocator.reserve(maxUintHandle); + + GLuint normalHandle = allocator.allocate(); + EXPECT_EQ(1u, normalHandle); +} + +// To test if the allocator keep the handle in a sorted order. +TEST(HandleAllocatorTest, SortedOrderHandle) +{ + gl::HandleAllocator allocator; + + allocator.reserve(3); + + GLuint allocatedList[5]; + for (GLuint count = 0; count < 5; count++) + { + allocatedList[count] = allocator.allocate(); + } + + EXPECT_EQ(1u, allocatedList[0]); + EXPECT_EQ(2u, allocatedList[1]); + EXPECT_EQ(4u, allocatedList[2]); + EXPECT_EQ(5u, allocatedList[3]); + EXPECT_EQ(6u, allocatedList[4]); +} + } diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/Image.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/Image.cpp new file mode 100644 index 000000000000..a9448e3f6c89 --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/libANGLE/Image.cpp @@ -0,0 +1,192 @@ +// +// Copyright (c) 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/angletypes.h" +#include "libANGLE/Texture.h" +#include "libANGLE/Renderbuffer.h" +#include "libANGLE/renderer/ImageImpl.h" + +namespace egl +{ +ImageSibling::ImageSibling(GLuint id) : RefCountObject(id), 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. + ASSERT(mSourcesOf.empty()); + orphanImages(); +} + +void ImageSibling::setTargetImage(egl::Image *imageTarget) +{ + ASSERT(imageTarget != nullptr); + mTargetOf.set(imageTarget); + imageTarget->addTargetSibling(this); +} + +gl::Error ImageSibling::orphanImages() +{ + if (mTargetOf.get() != nullptr) + { + // Can't be a target and have sources. + ASSERT(mSourcesOf.empty()); + + gl::Error error = mTargetOf->orphanSibling(this); + if (error.isError()) + { + return error; + } + + mTargetOf.set(nullptr); + } + else + { + for (auto &sourceImage : mSourcesOf) + { + gl::Error error = sourceImage->orphanSibling(this); + if (error.isError()) + { + return error; + } + } + mSourcesOf.clear(); + } + + return gl::Error(GL_NO_ERROR); +} + +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); +} + +Image::Image(rx::ImageImpl *impl, EGLenum target, ImageSibling *buffer, const AttributeMap &attribs) + : RefCountObject(0), + mImplementation(impl), + mInternalFormat(GL_NONE), + mWidth(0), + mHeight(0), + mSamples(0), + mSource(), + mTargets() +{ + ASSERT(mImplementation != nullptr); + ASSERT(buffer != nullptr); + + mSource.set(buffer); + mSource->addImageSource(this); + + if (IsTextureTarget(target)) + { + gl::Texture *texture = rx::GetAs(mSource.get()); + GLenum textureTarget = egl_gl::EGLImageTargetToGLTextureTarget(target); + size_t level = attribs.get(EGL_GL_TEXTURE_LEVEL_KHR, 0); + mInternalFormat = texture->getInternalFormat(textureTarget, level); + mWidth = texture->getWidth(textureTarget, level); + mHeight = texture->getHeight(textureTarget, level); + mSamples = 0; + } + else if (IsRenderbufferTarget(target)) + { + gl::Renderbuffer *renderbuffer = rx::GetAs(mSource.get()); + mInternalFormat = renderbuffer->getInternalFormat(); + mWidth = renderbuffer->getWidth(); + mHeight = renderbuffer->getHeight(); + mSamples = renderbuffer->getSamples(); + } + else + { + UNREACHABLE(); + } +} + +Image::~Image() +{ + SafeDelete(mImplementation); + + // All targets should hold a ref to the egl image and it should not be deleted until there are + // no siblings left. + ASSERT(mTargets.empty()); + + // Tell the source that it is no longer used by this image + if (mSource.get() != nullptr) + { + mSource->removeImageSource(this); + mSource.set(nullptr); + } +} + +void Image::addTargetSibling(ImageSibling *sibling) +{ + mTargets.insert(sibling); +} + +gl::Error Image::orphanSibling(ImageSibling *sibling) +{ + // notify impl + gl::Error error = mImplementation->orphan(sibling); + + if (mSource.get() == sibling) + { + // If the sibling is the source, it cannot be a target. + ASSERT(mTargets.find(sibling) == mTargets.end()); + + mSource.set(nullptr); + } + else + { + mTargets.erase(sibling); + } + + return error; +} + +GLenum Image::getInternalFormat() const +{ + return mInternalFormat; +} + +size_t Image::getWidth() const +{ + return mWidth; +} + +size_t Image::getHeight() const +{ + return mHeight; +} + +size_t Image::getSamples() const +{ + return mSamples; +} + +rx::ImageImpl *Image::getImplementation() +{ + return mImplementation; +} + +const rx::ImageImpl *Image::getImplementation() const +{ + return mImplementation; +} +} diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/Image.h b/Source/ThirdParty/ANGLE/src/libANGLE/Image.h new file mode 100644 index 000000000000..26c9df914c6b --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/libANGLE/Image.h @@ -0,0 +1,91 @@ +// +// Copyright (c) 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/angleutils.h" +#include "libANGLE/AttributeMap.h" +#include "libANGLE/Error.h" +#include "libANGLE/RefCountObject.h" + +#include + +namespace rx +{ +class ImageImpl; +} + +namespace egl +{ +class Image; + +class ImageSibling : public RefCountObject +{ + public: + ImageSibling(GLuint id); + virtual ~ImageSibling(); + + protected: + // Set the image target of this sibling + void setTargetImage(egl::Image *imageTarget); + + // Orphan all EGL image sources and targets + gl::Error orphanImages(); + + 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); + + std::set mSourcesOf; + BindingPointer mTargetOf; +}; + +class Image final : public RefCountObject +{ + public: + Image(rx::ImageImpl *impl, EGLenum target, ImageSibling *buffer, const AttributeMap &attribs); + ~Image(); + + GLenum getInternalFormat() const; + size_t getWidth() const; + size_t getHeight() const; + size_t getSamples() const; + + rx::ImageImpl *getImplementation(); + const rx::ImageImpl *getImplementation() const; + + 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. + gl::Error orphanSibling(ImageSibling *sibling); + + rx::ImageImpl *mImplementation; + + GLenum mInternalFormat; + size_t mWidth; + size_t mHeight; + size_t mSamples; + + BindingPointer mSource; + std::set mTargets; +}; +} + +#endif // LIBANGLE_IMAGE_H_ diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/ImageIndex.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/ImageIndex.cpp index 538258f8b6ce..c84e7c5d65b4 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/ImageIndex.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/ImageIndex.cpp @@ -35,7 +35,8 @@ ImageIndex ImageIndex::Make2D(GLint mipIndex) ImageIndex ImageIndex::MakeCube(GLenum target, GLint mipIndex) { ASSERT(gl::IsCubeMapTextureTarget(target)); - return ImageIndex(target, mipIndex, static_cast(CubeMapTextureTargetToLayerIndex(target))); + return ImageIndex(target, mipIndex, + static_cast(CubeMapTextureTargetToLayerIndex(target))); } ImageIndex ImageIndex::Make2DArray(GLint mipIndex, GLint layerIndex) @@ -50,7 +51,9 @@ ImageIndex ImageIndex::Make3D(GLint mipIndex, GLint layerIndex) ImageIndex ImageIndex::MakeGeneric(GLenum target, GLint mipIndex) { - GLint layerIndex = IsCubeMapTextureTarget(target) ? static_cast(CubeMapTextureTargetToLayerIndex(target)) : ENTIRE_LEVEL; + GLint layerIndex = IsCubeMapTextureTarget(target) + ? static_cast(CubeMapTextureTargetToLayerIndex(target)) + : ENTIRE_LEVEL; return ImageIndex(target, mipIndex, layerIndex); } @@ -83,30 +86,30 @@ ImageIndex::ImageIndex(GLenum typeIn, GLint mipIndexIn, GLint layerIndexIn) ImageIndexIterator ImageIndexIterator::Make2D(GLint minMip, GLint maxMip) { - return ImageIndexIterator(GL_TEXTURE_2D, rx::Range(minMip, maxMip), - rx::Range(ImageIndex::ENTIRE_LEVEL, ImageIndex::ENTIRE_LEVEL), NULL); + return ImageIndexIterator(GL_TEXTURE_2D, Range(minMip, maxMip), + Range(ImageIndex::ENTIRE_LEVEL, ImageIndex::ENTIRE_LEVEL), NULL); } ImageIndexIterator ImageIndexIterator::MakeCube(GLint minMip, GLint maxMip) { - return ImageIndexIterator(GL_TEXTURE_CUBE_MAP, rx::Range(minMip, maxMip), rx::Range(0, 6), NULL); + return ImageIndexIterator(GL_TEXTURE_CUBE_MAP, Range(minMip, maxMip), Range(0, 6), NULL); } ImageIndexIterator ImageIndexIterator::Make3D(GLint minMip, GLint maxMip, GLint minLayer, GLint maxLayer) { - return ImageIndexIterator(GL_TEXTURE_3D, rx::Range(minMip, maxMip), rx::Range(minLayer, maxLayer), NULL); + return ImageIndexIterator(GL_TEXTURE_3D, Range(minMip, maxMip), Range(minLayer, maxLayer), NULL); } ImageIndexIterator ImageIndexIterator::Make2DArray(GLint minMip, GLint maxMip, const GLsizei *layerCounts) { - return ImageIndexIterator(GL_TEXTURE_2D_ARRAY, rx::Range(minMip, maxMip), - rx::Range(0, IMPLEMENTATION_MAX_2D_ARRAY_TEXTURE_LAYERS), layerCounts); + return ImageIndexIterator(GL_TEXTURE_2D_ARRAY, Range(minMip, maxMip), + Range(0, IMPLEMENTATION_MAX_2D_ARRAY_TEXTURE_LAYERS), layerCounts); } -ImageIndexIterator::ImageIndexIterator(GLenum type, const rx::Range &mipRange, - const rx::Range &layerRange, const GLsizei *layerCounts) +ImageIndexIterator::ImageIndexIterator(GLenum type, const Range &mipRange, + const Range &layerRange, const GLsizei *layerCounts) : mType(type), mMipRange(mipRange), mLayerRange(layerRange), diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/ImageIndex.h b/Source/ThirdParty/ANGLE/src/libANGLE/ImageIndex.h index 820c650f2005..b527c7c8ab4a 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/ImageIndex.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/ImageIndex.h @@ -61,14 +61,14 @@ class ImageIndexIterator private: - ImageIndexIterator(GLenum type, const rx::Range &mipRange, - const rx::Range &layerRange, const GLsizei *layerCounts); + ImageIndexIterator(GLenum type, const Range &mipRange, + const Range &layerRange, const GLsizei *layerCounts); GLint maxLayer() const; GLenum mType; - rx::Range mMipRange; - rx::Range mLayerRange; + Range mMipRange; + Range mLayerRange; const GLsizei *mLayerCounts; GLint mCurrentMip; GLint mCurrentLayer; diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/Image_unittest.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/Image_unittest.cpp new file mode 100644 index 000000000000..9c89be0e09e3 --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/libANGLE/Image_unittest.cpp @@ -0,0 +1,131 @@ +// +// Copyright (c) 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_unittest.cpp : Unittets of the Image and ImageSibling classes. + +#include "gmock/gmock.h" +#include "gtest/gtest.h" +#include "libANGLE/Image.h" +#include "libANGLE/Texture.h" +#include "libANGLE/Renderbuffer.h" +#include "libANGLE/renderer/ImageImpl_mock.h" +#include "libANGLE/renderer/TextureImpl_mock.h" +#include "libANGLE/renderer/RenderbufferImpl_mock.h" + +using ::testing::_; +using ::testing::Return; + +namespace angle +{ +// Verify ref counts are maintained between images and their siblings when objects are deleted +TEST(ImageTest, RefCounting) +{ + // Create a texture and an EGL image that uses the texture as its source + rx::MockTextureImpl *textureImpl = new rx::MockTextureImpl(); + gl::Texture *texture = new gl::Texture(textureImpl, 1, GL_TEXTURE_2D); + texture->addRef(); + + rx::MockImageImpl *imageImpl = new rx::MockImageImpl(); + egl::Image *image = new egl::Image(imageImpl, EGL_GL_TEXTURE_2D, texture, egl::AttributeMap()); + image->addRef(); + + // Verify that the image added a ref to the texture and the texture has not added a ref to the + // image + EXPECT_EQ(texture->getRefCount(), 2u); + EXPECT_EQ(image->getRefCount(), 1u); + + // Create a renderbuffer and set it as a target of the EGL image + rx::MockRenderbufferImpl *renderbufferImpl = new rx::MockRenderbufferImpl(); + gl::Renderbuffer *renderbuffer = new gl::Renderbuffer(renderbufferImpl, 1); + renderbuffer->addRef(); + + EXPECT_CALL(*renderbufferImpl, setStorageEGLImageTarget(_)) + .WillOnce(Return(gl::Error(GL_NO_ERROR))) + .RetiresOnSaturation(); + renderbuffer->setStorageEGLImageTarget(image); + + // Verify that the renderbuffer added a ref to the image and the image did not add a ref to + // the renderbuffer + EXPECT_EQ(texture->getRefCount(), 2u); + EXPECT_EQ(image->getRefCount(), 2u); + EXPECT_EQ(renderbuffer->getRefCount(), 1u); + + // Simulate deletion of the texture and verify that it still exists because the image holds a + // ref + texture->release(); + EXPECT_EQ(texture->getRefCount(), 1u); + EXPECT_EQ(image->getRefCount(), 2u); + EXPECT_EQ(renderbuffer->getRefCount(), 1u); + + // Simulate deletion of the image and verify that it still exists because the renderbuffer holds + // a ref + image->release(); + EXPECT_EQ(texture->getRefCount(), 1u); + EXPECT_EQ(image->getRefCount(), 1u); + EXPECT_EQ(renderbuffer->getRefCount(), 1u); + + // Simulate deletion of the renderbuffer and verify that the deletion cascades to all objects + EXPECT_CALL(*imageImpl, destructor()).Times(1).RetiresOnSaturation(); + EXPECT_CALL(*imageImpl, orphan(_)) + .WillOnce(Return(gl::Error(GL_NO_ERROR))) + .RetiresOnSaturation(); + + EXPECT_CALL(*textureImpl, destructor()).Times(1).RetiresOnSaturation(); + EXPECT_CALL(*renderbufferImpl, destructor()).Times(1).RetiresOnSaturation(); + + renderbuffer->release(); +} + +// Verify that respecifiying textures releases references to the Image. +TEST(ImageTest, RespecificationReleasesReferences) +{ + // Create a texture and an EGL image that uses the texture as its source + rx::MockTextureImpl *textureImpl = new rx::MockTextureImpl(); + gl::Texture *texture = new gl::Texture(textureImpl, 1, GL_TEXTURE_2D); + texture->addRef(); + + gl::PixelUnpackState defaultUnpackState; + + EXPECT_CALL(*textureImpl, setImage(_, _, _, _, _, _, _, _)) + .WillOnce(Return(gl::Error(GL_NO_ERROR))) + .RetiresOnSaturation(); + texture->setImage(defaultUnpackState, GL_TEXTURE_2D, 0, GL_RGBA8, gl::Extents(1, 1, 1), GL_RGBA, + GL_UNSIGNED_BYTE, nullptr); + + rx::MockImageImpl *imageImpl = new rx::MockImageImpl(); + egl::Image *image = new egl::Image(imageImpl, EGL_GL_TEXTURE_2D, texture, egl::AttributeMap()); + image->addRef(); + + // Verify that the image added a ref to the texture and the texture has not added a ref to the + // image + EXPECT_EQ(texture->getRefCount(), 2u); + EXPECT_EQ(image->getRefCount(), 1u); + + // Respecify the texture and verify that the image releases its reference + EXPECT_CALL(*imageImpl, orphan(_)) + .WillOnce(Return(gl::Error(GL_NO_ERROR))) + .RetiresOnSaturation(); + EXPECT_CALL(*textureImpl, setImage(_, _, _, _, _, _, _, _)) + .WillOnce(Return(gl::Error(GL_NO_ERROR))) + .RetiresOnSaturation(); + + texture->setImage(defaultUnpackState, GL_TEXTURE_2D, 0, GL_RGBA8, gl::Extents(1, 1, 1), GL_RGBA, + GL_UNSIGNED_BYTE, nullptr); + + EXPECT_EQ(texture->getRefCount(), 1u); + EXPECT_EQ(image->getRefCount(), 1u); + + // Delete the texture and verify that the image still exists + EXPECT_CALL(*textureImpl, destructor()).Times(1).RetiresOnSaturation(); + texture->release(); + + EXPECT_EQ(image->getRefCount(), 1u); + + // Delete the image + EXPECT_CALL(*imageImpl, destructor()).Times(1).RetiresOnSaturation(); + image->release(); +} +} diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/IndexRangeCache.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/IndexRangeCache.cpp new file mode 100644 index 000000000000..4f165c1b285b --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/libANGLE/IndexRangeCache.cpp @@ -0,0 +1,113 @@ +// +// Copyright (c) 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 +{ + +void IndexRangeCache::addRange(GLenum type, + size_t offset, + size_t count, + bool primitiveRestartEnabled, + const IndexRange &range) +{ + mIndexRangeCache[IndexRangeKey(type, offset, count, primitiveRestartEnabled)] = range; +} + +bool IndexRangeCache::findRange(GLenum 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 + (GetTypeInfo(i->first.type).bytes * i->first.count); + + if (invalidateEnd < rangeStart || invalidateStart > rangeEnd) + { + ++i; + } + else + { + mIndexRangeCache.erase(i++); + } + } +} + +void IndexRangeCache::clear() +{ + mIndexRangeCache.clear(); +} + +IndexRangeCache::IndexRangeKey::IndexRangeKey() + : IndexRangeCache::IndexRangeKey(GL_NONE, 0, 0, false) +{ +} + +IndexRangeCache::IndexRangeKey::IndexRangeKey(GLenum 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; +} + +} diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/IndexRangeCache.h b/Source/ThirdParty/ANGLE/src/libANGLE/IndexRangeCache.h new file mode 100644 index 000000000000..69de421c13ca --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/libANGLE/IndexRangeCache.h @@ -0,0 +1,60 @@ +// +// Copyright (c) 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 "common/angleutils.h" +#include "common/mathutil.h" + +#include "angle_gl.h" + +#include + +namespace gl +{ + +class IndexRangeCache +{ + public: + void addRange(GLenum type, + size_t offset, + size_t count, + bool primitiveRestartEnabled, + const IndexRange &range); + bool findRange(GLenum 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(GLenum type, size_t offset, size_t count, bool primitiveRestart); + + bool operator<(const IndexRangeKey &rhs) const; + + GLenum type; + size_t offset; + size_t count; + bool primitiveRestartEnabled; + }; + + typedef std::map IndexRangeMap; + IndexRangeMap mIndexRangeCache; +}; + +} + +#endif // LIBANGLE_INDEXRANGECACHE_H_ diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/Platform.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/Platform.cpp index ab75bbba5af8..bfcdb1494ea8 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/Platform.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/Platform.cpp @@ -16,20 +16,20 @@ angle::Platform *currentPlatform = nullptr; } // static -ANGLE_EXPORT angle::Platform *ANGLEPlatformCurrent() +angle::Platform *ANGLE_APIENTRY ANGLEPlatformCurrent() { return currentPlatform; } // static -ANGLE_EXPORT void ANGLEPlatformInitialize(angle::Platform *platformImpl) +void ANGLE_APIENTRY ANGLEPlatformInitialize(angle::Platform *platformImpl) { ASSERT(platformImpl != nullptr); currentPlatform = platformImpl; } // static -ANGLE_EXPORT void ANGLEPlatformShutdown() +void ANGLE_APIENTRY ANGLEPlatformShutdown() { currentPlatform = nullptr; } diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/Program.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/Program.cpp index 42f09b913a1f..b4aa8dcb0a37 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/Program.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/Program.cpp @@ -11,6 +11,7 @@ #include +#include "common/BitSetIterator.h" #include "common/debug.h" #include "common/platform.h" #include "common/utilities.h" @@ -21,32 +22,122 @@ #include "libANGLE/features.h" #include "libANGLE/renderer/Renderer.h" #include "libANGLE/renderer/ProgramImpl.h" +#include "libANGLE/queryconversions.h" namespace gl { -const char * const g_fakepath = "C:\\fakepath"; namespace { -unsigned int ParseAndStripArrayIndex(std::string* name) +void WriteShaderVar(BinaryOutputStream *stream, const sh::ShaderVariable &var) { - unsigned int subscript = GL_INVALID_INDEX; + stream->writeInt(var.type); + stream->writeInt(var.precision); + stream->writeString(var.name); + stream->writeString(var.mappedName); + stream->writeInt(var.arraySize); + stream->writeInt(var.staticUse); + stream->writeString(var.structName); + ASSERT(var.fields.empty()); +} + +void LoadShaderVar(BinaryInputStream *stream, sh::ShaderVariable *var) +{ + var->type = stream->readInt(); + var->precision = stream->readInt(); + var->name = stream->readString(); + var->mappedName = stream->readString(); + var->arraySize = stream->readInt(); + var->staticUse = stream->readBool(); + var->structName = stream->readString(); +} + +// 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 (value == GL_TRUE ? 1.0f : 0.0f); +} + +template <> +GLint UniformStateQueryCast(GLboolean value) +{ + return (value == GL_TRUE ? 1 : 0); +} + +template <> +GLuint UniformStateQueryCast(GLboolean value) +{ + return (value == GL_TRUE ? 1u : 0u); +} + +// Default to static_cast +template +DestT UniformStateQueryCast(SrcT value) +{ + return static_cast(value); +} - // Strip any trailing array operator and retrieve the subscript - size_t open = name->find_last_of('['); - size_t close = name->find_last_of(']'); - if (open != std::string::npos && close == name->length() - 1) +template +void UniformStateQueryCastLoop(DestT *dataOut, const uint8_t *srcPointer, int components) +{ + for (int comp = 0; comp < components; ++comp) { - subscript = atoi(name->substr(open + 1).c_str()); - name->erase(open); + // 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); } - - return subscript; } +bool UniformInList(const std::vector &list, const std::string &name) +{ + for (const LinkedUniform &uniform : list) + { + if (uniform.name == name) + return true; + } + + return false; } +} // anonymous namespace + +const char *const g_fakepath = "C:\\fakepath"; + AttributeBindings::AttributeBindings() { } @@ -65,10 +156,11 @@ InfoLog::~InfoLog() size_t InfoLog::getLength() const { - return mStream.str().length(); + const std::string &logString = mStream.str(); + return logString.empty() ? 0 : logString.length() + 1; } -void InfoLog::getLog(GLsizei bufSize, GLsizei *length, char *infoLog) +void InfoLog::getLog(GLsizei bufSize, GLsizei *length, char *infoLog) const { size_t index = 0; @@ -109,22 +201,7 @@ void InfoLog::appendSanitized(const char *message) } while (found != std::string::npos); - mStream << message << "\n"; -} - -void InfoLog::append(const char *format, ...) -{ - if (!format) - { - return; - } - - va_list vararg; - va_start(vararg, format); - std::string tempString(FormatString(format, vararg)); - va_end(vararg); - - mStream << tempString << "\n"; + mStream << message << std::endl; } void InfoLog::reset() @@ -145,28 +222,104 @@ VariableLocation::VariableLocation(const std::string &name, unsigned int element { } -LinkedVarying::LinkedVarying() +Program::Data::Data() + : mLabel(), + mAttachedFragmentShader(nullptr), + mAttachedVertexShader(nullptr), + mTransformFeedbackBufferMode(GL_INTERLEAVED_ATTRIBS), + mBinaryRetrieveableHint(false) +{ +} + +Program::Data::~Data() +{ + if (mAttachedVertexShader != nullptr) + { + mAttachedVertexShader->release(); + } + + if (mAttachedFragmentShader != nullptr) + { + mAttachedFragmentShader->release(); + } +} + +const std::string &Program::Data::getLabel() +{ + return mLabel; +} + +const LinkedUniform *Program::Data::getUniformByName(const std::string &name) const +{ + for (const LinkedUniform &linkedUniform : mUniforms) + { + if (linkedUniform.name == name) + { + return &linkedUniform; + } + } + + return nullptr; +} + +GLint Program::Data::getUniformLocation(const std::string &name) const { + size_t subscript = GL_INVALID_INDEX; + std::string baseName = gl::ParseUniformName(name, &subscript); + + for (size_t location = 0; location < mUniformLocations.size(); ++location) + { + const VariableLocation &uniformLocation = mUniformLocations[location]; + const LinkedUniform &uniform = mUniforms[uniformLocation.index]; + + if (uniform.name == baseName) + { + if ((uniform.isArray() && uniformLocation.element == subscript) || + (subscript == GL_INVALID_INDEX)) + { + return static_cast(location); + } + } + } + + return -1; } -LinkedVarying::LinkedVarying(const std::string &name, GLenum type, GLsizei size, const std::string &semanticName, - unsigned int semanticIndex, unsigned int semanticIndexCount) - : name(name), type(type), size(size), semanticName(semanticName), semanticIndex(semanticIndex), semanticIndexCount(semanticIndexCount) +GLuint Program::Data::getUniformIndex(const std::string &name) const { + size_t subscript = GL_INVALID_INDEX; + std::string baseName = gl::ParseUniformName(name, &subscript); + + // The app is not allowed to specify array indices other than 0 for arrays of basic types + if (subscript != 0 && subscript != GL_INVALID_INDEX) + { + return GL_INVALID_INDEX; + } + + for (size_t index = 0; index < mUniforms.size(); index++) + { + const LinkedUniform &uniform = mUniforms[index]; + if (uniform.name == baseName) + { + if (uniform.isArray() || subscript == GL_INVALID_INDEX) + { + return static_cast(index); + } + } + } + + return GL_INVALID_INDEX; } -Program::Program(rx::ProgramImpl *impl, ResourceManager *manager, GLuint handle) - : mProgram(impl), +Program::Program(rx::ImplFactory *factory, ResourceManager *manager, GLuint handle) + : mProgram(factory->createProgram(mData)), mValidated(false), - mTransformFeedbackVaryings(), - mTransformFeedbackBufferMode(GL_NONE), - mFragmentShader(nullptr), - mVertexShader(nullptr), mLinked(false), mDeleteStatus(false), mRefCount(0), mResourceManager(manager), - mHandle(handle) + mHandle(handle), + mSamplerUniformRange(0, 0) { ASSERT(mProgram); @@ -178,40 +331,40 @@ Program::~Program() { unlink(true); - if (mVertexShader != nullptr) - { - mVertexShader->release(); - } + SafeDelete(mProgram); +} - if (mFragmentShader != nullptr) - { - mFragmentShader->release(); - } +void Program::setLabel(const std::string &label) +{ + mData.mLabel = label; +} - SafeDelete(mProgram); +const std::string &Program::getLabel() const +{ + return mData.mLabel; } bool Program::attachShader(Shader *shader) { if (shader->getType() == GL_VERTEX_SHADER) { - if (mVertexShader) + if (mData.mAttachedVertexShader) { return false; } - mVertexShader = shader; - mVertexShader->addRef(); + mData.mAttachedVertexShader = shader; + mData.mAttachedVertexShader->addRef(); } else if (shader->getType() == GL_FRAGMENT_SHADER) { - if (mFragmentShader) + if (mData.mAttachedFragmentShader) { return false; } - mFragmentShader = shader; - mFragmentShader->addRef(); + mData.mAttachedFragmentShader = shader; + mData.mAttachedFragmentShader->addRef(); } else UNREACHABLE(); @@ -222,23 +375,23 @@ bool Program::detachShader(Shader *shader) { if (shader->getType() == GL_VERTEX_SHADER) { - if (mVertexShader != shader) + if (mData.mAttachedVertexShader != shader) { return false; } - mVertexShader->release(); - mVertexShader = nullptr; + shader->release(); + mData.mAttachedVertexShader = nullptr; } else if (shader->getType() == GL_FRAGMENT_SHADER) { - if (mFragmentShader != shader) + if (mData.mAttachedFragmentShader != shader) { return false; } - mFragmentShader->release(); - mFragmentShader = nullptr; + shader->release(); + mData.mAttachedFragmentShader = nullptr; } else UNREACHABLE(); @@ -247,7 +400,7 @@ bool Program::detachShader(Shader *shader) int Program::getAttachedShadersCount() const { - return (mVertexShader ? 1 : 0) + (mFragmentShader ? 1 : 0); + return (mData.mAttachedVertexShader ? 1 : 0) + (mData.mAttachedFragmentShader ? 1 : 0); } void AttributeBindings::bindAttributeLocation(GLuint index, const char *name) @@ -271,65 +424,63 @@ void Program::bindAttributeLocation(GLuint index, const char *name) // Links the HLSL code of the vertex and pixel shader by matching up their varyings, // compiling them into binaries, determining the attribute mappings, and collecting // a list of uniforms -Error Program::link(const Data &data) +Error Program::link(const gl::Data &data) { unlink(false); mInfoLog.reset(); resetUniformBlockBindings(); - if (!mFragmentShader || !mFragmentShader->isCompiled()) + if (!mData.mAttachedFragmentShader || !mData.mAttachedFragmentShader->isCompiled()) { return Error(GL_NO_ERROR); } - ASSERT(mFragmentShader->getType() == GL_FRAGMENT_SHADER); + ASSERT(mData.mAttachedFragmentShader->getType() == GL_FRAGMENT_SHADER); - if (!mVertexShader || !mVertexShader->isCompiled()) + if (!mData.mAttachedVertexShader || !mData.mAttachedVertexShader->isCompiled()) { return Error(GL_NO_ERROR); } - ASSERT(mVertexShader->getType() == GL_VERTEX_SHADER); + ASSERT(mData.mAttachedVertexShader->getType() == GL_VERTEX_SHADER); - if (!linkAttributes(data, mInfoLog, mAttributeBindings, mVertexShader)) + if (!linkAttributes(data, mInfoLog, mAttributeBindings, mData.mAttachedVertexShader)) { return Error(GL_NO_ERROR); } - int registers; - std::vector linkedVaryings; - rx::LinkResult result = mProgram->link(data, mInfoLog, mFragmentShader, mVertexShader, mTransformFeedbackVaryings, mTransformFeedbackBufferMode, - ®isters, &linkedVaryings, &mOutputVariables); - if (result.error.isError() || !result.linkSuccess) + if (!linkVaryings(mInfoLog, mData.mAttachedVertexShader, mData.mAttachedFragmentShader)) { - return result.error; + return Error(GL_NO_ERROR); } - if (!mProgram->linkUniforms(mInfoLog, *mVertexShader, *mFragmentShader, *data.caps)) + if (!linkUniforms(mInfoLog, *data.caps)) { return Error(GL_NO_ERROR); } - if (!linkUniformBlocks(mInfoLog, *mVertexShader, *mFragmentShader, *data.caps)) + if (!linkUniformBlocks(mInfoLog, *data.caps)) { return Error(GL_NO_ERROR); } - if (!gatherTransformFeedbackLinkedVaryings(mInfoLog, linkedVaryings, mTransformFeedbackVaryings, - mTransformFeedbackBufferMode, &mProgram->getTransformFeedbackLinkedVaryings(), *data.caps)) + const auto &mergedVaryings = getMergedVaryings(); + + if (!linkValidateTransformFeedback(mInfoLog, mergedVaryings, *data.caps)) { return Error(GL_NO_ERROR); } - // TODO: The concept of "executables" is D3D only, and as such this belongs in ProgramD3D. It must be called, - // however, last in this function, so it can't simply be moved to ProgramD3D::link without further shuffling. - result = mProgram->compileProgramExecutables(mInfoLog, mFragmentShader, mVertexShader, registers); + linkOutputVariables(); + + rx::LinkResult result = mProgram->link(data, mInfoLog); if (result.error.isError() || !result.linkSuccess) { - mInfoLog.append("Failed to create D3D shaders."); - unlink(false); return result.error; } + gatherTransformFeedbackVaryings(mergedVaryings); + gatherInterfaceBlockInfo(); + mLinked = true; return gl::Error(GL_NO_ERROR); } @@ -352,30 +503,33 @@ void Program::unlink(bool destroy) { if (destroy) // Object being destructed { - if (mFragmentShader) + if (mData.mAttachedFragmentShader) { - mFragmentShader->release(); - mFragmentShader = nullptr; + mData.mAttachedFragmentShader->release(); + mData.mAttachedFragmentShader = nullptr; } - if (mVertexShader) + if (mData.mAttachedVertexShader) { - mVertexShader->release(); - mVertexShader = nullptr; + mData.mAttachedVertexShader->release(); + mData.mAttachedVertexShader = nullptr; } } - std::fill(mLinkedAttribute, mLinkedAttribute + ArraySize(mLinkedAttribute), sh::Attribute()); - mOutputVariables.clear(); - - mProgram->reset(); + mData.mAttributes.clear(); + mData.mActiveAttribLocationsMask.reset(); + mData.mTransformFeedbackVaryingVars.clear(); + mData.mUniforms.clear(); + mData.mUniformLocations.clear(); + mData.mUniformBlocks.clear(); + mData.mOutputVariables.clear(); mValidated = false; mLinked = false; } -bool Program::isLinked() +bool Program::isLinked() const { return mLinked; } @@ -387,22 +541,20 @@ Error Program::loadBinary(GLenum binaryFormat, const void *binary, GLsizei lengt #if ANGLE_PROGRAM_BINARY_LOAD != ANGLE_ENABLED return Error(GL_NO_ERROR); #else - ASSERT(binaryFormat == mProgram->getBinaryFormat()); - - BinaryInputStream stream(binary, length); - - GLenum format = stream.readInt(); - if (format != mProgram->getBinaryFormat()) + ASSERT(binaryFormat == GL_PROGRAM_BINARY_ANGLE); + if (binaryFormat != GL_PROGRAM_BINARY_ANGLE) { - mInfoLog.append("Invalid program binary format."); + mInfoLog << "Invalid program binary format."; return Error(GL_NO_ERROR); } + BinaryInputStream stream(binary, length); + int majorVersion = stream.readInt(); int minorVersion = stream.readInt(); if (majorVersion != ANGLE_MAJOR_VERSION || minorVersion != ANGLE_MINOR_VERSION) { - mInfoLog.append("Invalid program binary version."); + mInfoLog << "Invalid program binary version."; return Error(GL_NO_ERROR); } @@ -410,29 +562,105 @@ Error Program::loadBinary(GLenum binaryFormat, const void *binary, GLsizei lengt stream.readBytes(commitString, ANGLE_COMMIT_HASH_SIZE); if (memcmp(commitString, ANGLE_COMMIT_HASH, sizeof(unsigned char) * ANGLE_COMMIT_HASH_SIZE) != 0) { - mInfoLog.append("Invalid program binary version."); + mInfoLog << "Invalid program binary version."; return Error(GL_NO_ERROR); } - // TODO(jmadill): replace MAX_VERTEX_ATTRIBS - for (int i = 0; i < MAX_VERTEX_ATTRIBS; ++i) - { - stream.readInt(&mLinkedAttribute[i].type); - stream.readString(&mLinkedAttribute[i].name); - stream.readInt(&mProgram->getSemanticIndexes()[i]); - } + static_assert(MAX_VERTEX_ATTRIBS <= sizeof(unsigned long) * 8, + "Too many vertex attribs for mask"); + mData.mActiveAttribLocationsMask = stream.readInt(); unsigned int attribCount = stream.readInt(); + ASSERT(mData.mAttributes.empty()); for (unsigned int attribIndex = 0; attribIndex < attribCount; ++attribIndex) { - GLenum type = stream.readInt(); - GLenum precision = stream.readInt(); - std::string name = stream.readString(); - GLint arraySize = stream.readInt(); - int location = stream.readInt(); - mProgram->setShaderAttribute(attribIndex, type, precision, name, arraySize, location); + sh::Attribute attrib; + LoadShaderVar(&stream, &attrib); + attrib.location = stream.readInt(); + mData.mAttributes.push_back(attrib); + } + + unsigned int uniformCount = stream.readInt(); + ASSERT(mData.mUniforms.empty()); + for (unsigned int uniformIndex = 0; uniformIndex < uniformCount; ++uniformIndex) + { + LinkedUniform uniform; + LoadShaderVar(&stream, &uniform); + + uniform.blockIndex = stream.readInt(); + uniform.blockInfo.offset = stream.readInt(); + uniform.blockInfo.arrayStride = stream.readInt(); + uniform.blockInfo.matrixStride = stream.readInt(); + uniform.blockInfo.isRowMajorMatrix = stream.readBool(); + + mData.mUniforms.push_back(uniform); + } + + const unsigned int uniformIndexCount = stream.readInt(); + ASSERT(mData.mUniformLocations.empty()); + for (unsigned int uniformIndexIndex = 0; uniformIndexIndex < uniformIndexCount; + uniformIndexIndex++) + { + VariableLocation variable; + stream.readString(&variable.name); + stream.readInt(&variable.element); + stream.readInt(&variable.index); + + mData.mUniformLocations.push_back(variable); + } + + unsigned int uniformBlockCount = stream.readInt(); + ASSERT(mData.mUniformBlocks.empty()); + for (unsigned int uniformBlockIndex = 0; uniformBlockIndex < uniformBlockCount; + ++uniformBlockIndex) + { + UniformBlock uniformBlock; + stream.readString(&uniformBlock.name); + stream.readBool(&uniformBlock.isArray); + stream.readInt(&uniformBlock.arrayElement); + stream.readInt(&uniformBlock.dataSize); + stream.readBool(&uniformBlock.vertexStaticUse); + stream.readBool(&uniformBlock.fragmentStaticUse); + + unsigned int numMembers = stream.readInt(); + for (unsigned int blockMemberIndex = 0; blockMemberIndex < numMembers; blockMemberIndex++) + { + uniformBlock.memberUniformIndexes.push_back(stream.readInt()); + } + + mData.mUniformBlocks.push_back(uniformBlock); + } + + unsigned int transformFeedbackVaryingCount = stream.readInt(); + ASSERT(mData.mTransformFeedbackVaryingVars.empty()); + for (unsigned int transformFeedbackVaryingIndex = 0; + transformFeedbackVaryingIndex < transformFeedbackVaryingCount; + ++transformFeedbackVaryingIndex) + { + sh::Varying varying; + stream.readInt(&varying.arraySize); + stream.readInt(&varying.type); + stream.readString(&varying.name); + + mData.mTransformFeedbackVaryingVars.push_back(varying); + } + + stream.readInt(&mData.mTransformFeedbackBufferMode); + + unsigned int outputVarCount = stream.readInt(); + for (unsigned int outputIndex = 0; outputIndex < outputVarCount; ++outputIndex) + { + int locationIndex = stream.readInt(); + VariableLocation locationData; + stream.readInt(&locationData.element); + stream.readInt(&locationData.index); + stream.readString(&locationData.name); + mData.mOutputVariables[locationIndex] = locationData; } + stream.readInt(&mSamplerUniformRange.start); + stream.readInt(&mSamplerUniformRange.end); + rx::LinkResult result = mProgram->load(mInfoLog, &stream); if (result.error.isError() || !result.linkSuccess) { @@ -448,42 +676,93 @@ Error Program::saveBinary(GLenum *binaryFormat, void *binary, GLsizei bufSize, G { if (binaryFormat) { - *binaryFormat = mProgram->getBinaryFormat(); + *binaryFormat = GL_PROGRAM_BINARY_ANGLE; } BinaryOutputStream stream; - stream.writeInt(mProgram->getBinaryFormat()); stream.writeInt(ANGLE_MAJOR_VERSION); stream.writeInt(ANGLE_MINOR_VERSION); stream.writeBytes(reinterpret_cast(ANGLE_COMMIT_HASH), ANGLE_COMMIT_HASH_SIZE); - // TODO(jmadill): replace MAX_VERTEX_ATTRIBS - for (unsigned int i = 0; i < MAX_VERTEX_ATTRIBS; ++i) + stream.writeInt(mData.mActiveAttribLocationsMask.to_ulong()); + + stream.writeInt(mData.mAttributes.size()); + for (const sh::Attribute &attrib : mData.mAttributes) { - stream.writeInt(mLinkedAttribute[i].type); - stream.writeString(mLinkedAttribute[i].name); - stream.writeInt(mProgram->getSemanticIndexes()[i]); + WriteShaderVar(&stream, attrib); + stream.writeInt(attrib.location); } - const auto &shaderAttributes = mProgram->getShaderAttributes(); - stream.writeInt(shaderAttributes.size()); - for (const auto &attrib : shaderAttributes) + stream.writeInt(mData.mUniforms.size()); + for (const gl::LinkedUniform &uniform : mData.mUniforms) { - stream.writeInt(attrib.type); - stream.writeInt(attrib.precision); - stream.writeString(attrib.name); - stream.writeInt(attrib.arraySize); - stream.writeInt(attrib.location); + WriteShaderVar(&stream, uniform); + + // FIXME: referenced + + stream.writeInt(uniform.blockIndex); + stream.writeInt(uniform.blockInfo.offset); + stream.writeInt(uniform.blockInfo.arrayStride); + stream.writeInt(uniform.blockInfo.matrixStride); + stream.writeInt(uniform.blockInfo.isRowMajorMatrix); + } + + stream.writeInt(mData.mUniformLocations.size()); + for (const auto &variable : mData.mUniformLocations) + { + stream.writeString(variable.name); + stream.writeInt(variable.element); + stream.writeInt(variable.index); + } + + stream.writeInt(mData.mUniformBlocks.size()); + for (const UniformBlock &uniformBlock : mData.mUniformBlocks) + { + stream.writeString(uniformBlock.name); + stream.writeInt(uniformBlock.isArray); + stream.writeInt(uniformBlock.arrayElement); + stream.writeInt(uniformBlock.dataSize); + + stream.writeInt(uniformBlock.vertexStaticUse); + stream.writeInt(uniformBlock.fragmentStaticUse); + + stream.writeInt(uniformBlock.memberUniformIndexes.size()); + for (unsigned int memberUniformIndex : uniformBlock.memberUniformIndexes) + { + stream.writeInt(memberUniformIndex); + } } + stream.writeInt(mData.mTransformFeedbackVaryingVars.size()); + for (const sh::Varying &varying : mData.mTransformFeedbackVaryingVars) + { + stream.writeInt(varying.arraySize); + stream.writeInt(varying.type); + stream.writeString(varying.name); + } + + stream.writeInt(mData.mTransformFeedbackBufferMode); + + stream.writeInt(mData.mOutputVariables.size()); + for (const auto &outputPair : mData.mOutputVariables) + { + stream.writeInt(outputPair.first); + stream.writeInt(outputPair.second.element); + stream.writeInt(outputPair.second.index); + stream.writeString(outputPair.second.name); + } + + stream.writeInt(mSamplerUniformRange.start); + stream.writeInt(mSamplerUniformRange.end); + gl::Error error = mProgram->save(&stream); if (error.isError()) { return error; } - GLsizei streamLength = static_cast(stream.length()); + GLsizei streamLength = static_cast(stream.length()); const void *streamData = stream.data(); if (streamLength > bufSize) @@ -529,6 +808,18 @@ GLint Program::getBinaryLength() const return length; } +void Program::setBinaryRetrievableHint(bool retrievable) +{ + // TODO(jmadill) : replace with dirty bits + mProgram->setBinaryRetrievableHint(retrievable); + mData.mBinaryRetrieveableHint = retrievable; +} + +bool Program::getBinaryRetrievableHint() const +{ + return mData.mBinaryRetrieveableHint; +} + void Program::release() { mRefCount--; @@ -554,33 +845,31 @@ int Program::getInfoLogLength() const return static_cast(mInfoLog.getLength()); } -void Program::getInfoLog(GLsizei bufSize, GLsizei *length, char *infoLog) +void Program::getInfoLog(GLsizei bufSize, GLsizei *length, char *infoLog) const { return mInfoLog.getLog(bufSize, length, infoLog); } -void Program::getAttachedShaders(GLsizei maxCount, GLsizei *count, GLuint *shaders) +void Program::getAttachedShaders(GLsizei maxCount, GLsizei *count, GLuint *shaders) const { int total = 0; - if (mVertexShader) + if (mData.mAttachedVertexShader) { if (total < maxCount) { - shaders[total] = mVertexShader->getHandle(); + shaders[total] = mData.mAttachedVertexShader->getHandle(); + total++; } - - total++; } - if (mFragmentShader) + if (mData.mAttachedFragmentShader) { if (total < maxCount) { - shaders[total] = mFragmentShader->getHandle(); + shaders[total] = mData.mAttachedFragmentShader->getHandle(); + total++; } - - total++; } if (count) @@ -589,71 +878,28 @@ void Program::getAttachedShaders(GLsizei maxCount, GLsizei *count, GLuint *shade } } -GLuint Program::getAttributeLocation(const std::string &name) +GLuint Program::getAttributeLocation(const std::string &name) const { - for (int index = 0; index < MAX_VERTEX_ATTRIBS; index++) + for (const sh::Attribute &attribute : mData.mAttributes) { - if (mLinkedAttribute[index].name == name) + if (attribute.name == name && attribute.staticUse) { - return index; + return attribute.location; } } return static_cast(-1); } -const int *Program::getSemanticIndexes() const +bool Program::isAttribLocationActive(size_t attribLocation) const { - return mProgram->getSemanticIndexes(); -} - -int Program::getSemanticIndex(int attributeIndex) -{ - ASSERT(attributeIndex >= 0 && attributeIndex < MAX_VERTEX_ATTRIBS); - - return mProgram->getSemanticIndexes()[attributeIndex]; + ASSERT(attribLocation < mData.mActiveAttribLocationsMask.size()); + return mData.mActiveAttribLocationsMask[attribLocation]; } void Program::getActiveAttribute(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) { - if (mLinked) - { - // Skip over inactive attributes - unsigned int activeAttribute = 0; - unsigned int attribute; - for (attribute = 0; attribute < MAX_VERTEX_ATTRIBS; attribute++) - { - if (mLinkedAttribute[attribute].name.empty()) - { - continue; - } - - if (activeAttribute == index) - { - break; - } - - activeAttribute++; - } - - if (bufsize > 0) - { - const char *string = mLinkedAttribute[attribute].name.c_str(); - - strncpy(name, string, bufsize); - name[bufsize - 1] = '\0'; - - if (length) - { - *length = static_cast(strlen(name)); - } - } - - *size = 1; // Always a single 'type' instance - - *type = mLinkedAttribute[attribute].type; - } - else + if (!mLinked) { if (bufsize > 0) { @@ -667,92 +913,114 @@ void Program::getActiveAttribute(GLuint index, GLsizei bufsize, GLsizei *length, *type = GL_NONE; *size = 1; + return; } -} -GLint Program::getActiveAttributeCount() -{ - int count = 0; + size_t attributeIndex = 0; - if (mLinked) + for (const sh::Attribute &attribute : mData.mAttributes) { - for (int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; attributeIndex++) + // Skip over inactive attributes + if (attribute.staticUse) { - if (!mLinkedAttribute[attributeIndex].name.empty()) + if (static_cast(index) == attributeIndex) { - count++; + break; } + attributeIndex++; } } - return count; -} - -GLint Program::getActiveAttributeMaxLength() -{ - int maxLength = 0; + ASSERT(index == attributeIndex && attributeIndex < mData.mAttributes.size()); + const sh::Attribute &attrib = mData.mAttributes[attributeIndex]; - if (mLinked) + if (bufsize > 0) { - for (int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; attributeIndex++) + const char *string = attrib.name.c_str(); + + strncpy(name, string, bufsize); + name[bufsize - 1] = '\0'; + + if (length) { - if (!mLinkedAttribute[attributeIndex].name.empty()) - { - maxLength = std::max((int)(mLinkedAttribute[attributeIndex].name.length() + 1), maxLength); - } + *length = static_cast(strlen(name)); } } - return maxLength; + // Always a single 'type' instance + *size = 1; + *type = attrib.type; } -// Returns one more than the highest sampler index used. -GLint Program::getUsedSamplerRange(SamplerType type) +GLint Program::getActiveAttributeCount() const { - return mProgram->getUsedSamplerRange(type); -} + if (!mLinked) + { + return 0; + } -bool Program::usesPointSize() const -{ - return mProgram->usesPointSize(); -} + GLint count = 0; -GLint Program::getSamplerMapping(SamplerType type, unsigned int samplerIndex, const Caps &caps) -{ - return mProgram->getSamplerMapping(type, samplerIndex, caps); + for (const sh::Attribute &attrib : mData.mAttributes) + { + count += (attrib.staticUse ? 1 : 0); + } + + return count; } -GLenum Program::getSamplerTextureType(SamplerType type, unsigned int samplerIndex) +GLint Program::getActiveAttributeMaxLength() const { - return mProgram->getSamplerTextureType(type, samplerIndex); + if (!mLinked) + { + return 0; + } + + size_t maxLength = 0; + + for (const sh::Attribute &attrib : mData.mAttributes) + { + if (attrib.staticUse) + { + maxLength = std::max(attrib.name.length() + 1, maxLength); + } + } + + return static_cast(maxLength); } GLint Program::getFragDataLocation(const std::string &name) const { std::string baseName(name); unsigned int arrayIndex = ParseAndStripArrayIndex(&baseName); - for (auto locationIt = mOutputVariables.begin(); locationIt != mOutputVariables.end(); locationIt++) + for (auto outputPair : mData.mOutputVariables) { - const VariableLocation &outputVariable = locationIt->second; + const VariableLocation &outputVariable = outputPair.second; if (outputVariable.name == baseName && (arrayIndex == GL_INVALID_INDEX || arrayIndex == outputVariable.element)) { - return static_cast(locationIt->first); + return static_cast(outputPair.first); } } return -1; } -void Program::getActiveUniform(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) +void Program::getActiveUniform(GLuint index, + GLsizei bufsize, + GLsizei *length, + GLint *size, + GLenum *type, + GLchar *name) const { if (mLinked) { - ASSERT(index < mProgram->getUniforms().size()); // index must be smaller than getActiveUniformCount() - LinkedUniform *uniform = mProgram->getUniforms()[index]; + // index must be smaller than getActiveUniformCount() + ASSERT(index < mData.mUniforms.size()); + const LinkedUniform &uniform = mData.mUniforms[index]; if (bufsize > 0) { - std::string string = uniform->name; - if (uniform->isArray()) + std::string string = uniform.name; + if (uniform.isArray()) { string += "[0]"; } @@ -766,8 +1034,8 @@ void Program::getActiveUniform(GLuint index, GLsizei bufsize, GLsizei *length, G } } - *size = uniform->elementCount(); - *type = uniform->type; + *size = uniform.elementCount(); + *type = uniform.type; } else { @@ -786,11 +1054,11 @@ void Program::getActiveUniform(GLuint index, GLsizei bufsize, GLsizei *length, G } } -GLint Program::getActiveUniformCount() +GLint Program::getActiveUniformCount() const { if (mLinked) { - return static_cast(mProgram->getUniforms().size()); + return static_cast(mData.mUniforms.size()); } else { @@ -798,19 +1066,18 @@ GLint Program::getActiveUniformCount() } } -GLint Program::getActiveUniformMaxLength() +GLint Program::getActiveUniformMaxLength() const { - int maxLength = 0; + size_t maxLength = 0; if (mLinked) { - unsigned int numUniforms = static_cast(mProgram->getUniforms().size()); - for (unsigned int uniformIndex = 0; uniformIndex < numUniforms; uniformIndex++) + for (const LinkedUniform &uniform : mData.mUniforms) { - if (!mProgram->getUniforms()[uniformIndex]->name.empty()) + if (!uniform.name.empty()) { - int length = (int)(mProgram->getUniforms()[uniformIndex]->name.length() + 1); - if (mProgram->getUniforms()[uniformIndex]->isArray()) + size_t length = uniform.name.length() + 1u; + if (uniform.isArray()) { length += 3; // Counting in "[0]". } @@ -819,12 +1086,13 @@ GLint Program::getActiveUniformMaxLength() } } - return maxLength; + return static_cast(maxLength); } GLint Program::getActiveUniformi(GLuint index, GLenum pname) const { - const gl::LinkedUniform& uniform = *mProgram->getUniforms()[index]; + ASSERT(static_cast(index) < mData.mUniforms.size()); + const gl::LinkedUniform &uniform = mData.mUniforms[index]; switch (pname) { case GL_UNIFORM_TYPE: return static_cast(uniform.type); @@ -844,159 +1112,165 @@ GLint Program::getActiveUniformi(GLuint index, GLenum pname) const bool Program::isValidUniformLocation(GLint location) const { - ASSERT(rx::IsIntegerCastSafe(mProgram->getUniformIndices().size())); - return (location >= 0 && location < static_cast(mProgram->getUniformIndices().size())); -} - -LinkedUniform *Program::getUniformByLocation(GLint location) const -{ - return mProgram->getUniformByLocation(location); + ASSERT(rx::IsIntegerCastSafe(mData.mUniformLocations.size())); + return (location >= 0 && static_cast(location) < mData.mUniformLocations.size()); } -LinkedUniform *Program::getUniformByName(const std::string &name) const +const LinkedUniform &Program::getUniformByLocation(GLint location) const { - return mProgram->getUniformByName(name); + ASSERT(location >= 0 && static_cast(location) < mData.mUniformLocations.size()); + return mData.mUniforms[mData.mUniformLocations[location].index]; } -GLint Program::getUniformLocation(const std::string &name) +GLint Program::getUniformLocation(const std::string &name) const { - return mProgram->getUniformLocation(name); + return mData.getUniformLocation(name); } -GLuint Program::getUniformIndex(const std::string &name) +GLuint Program::getUniformIndex(const std::string &name) const { - return mProgram->getUniformIndex(name); + return mData.getUniformIndex(name); } void Program::setUniform1fv(GLint location, GLsizei count, const GLfloat *v) { + setUniformInternal(location, count * 1, v); mProgram->setUniform1fv(location, count, v); } void Program::setUniform2fv(GLint location, GLsizei count, const GLfloat *v) { + setUniformInternal(location, count * 2, v); mProgram->setUniform2fv(location, count, v); } void Program::setUniform3fv(GLint location, GLsizei count, const GLfloat *v) { + setUniformInternal(location, count * 3, v); mProgram->setUniform3fv(location, count, v); } void Program::setUniform4fv(GLint location, GLsizei count, const GLfloat *v) { + setUniformInternal(location, count * 4, v); mProgram->setUniform4fv(location, count, v); } void Program::setUniform1iv(GLint location, GLsizei count, const GLint *v) { + setUniformInternal(location, count * 1, v); mProgram->setUniform1iv(location, count, v); } void Program::setUniform2iv(GLint location, GLsizei count, const GLint *v) { + setUniformInternal(location, count * 2, v); mProgram->setUniform2iv(location, count, v); } void Program::setUniform3iv(GLint location, GLsizei count, const GLint *v) { + setUniformInternal(location, count * 3, v); mProgram->setUniform3iv(location, count, v); } void Program::setUniform4iv(GLint location, GLsizei count, const GLint *v) { + setUniformInternal(location, count * 4, v); mProgram->setUniform4iv(location, count, v); } void Program::setUniform1uiv(GLint location, GLsizei count, const GLuint *v) { + setUniformInternal(location, count * 1, v); mProgram->setUniform1uiv(location, count, v); } void Program::setUniform2uiv(GLint location, GLsizei count, const GLuint *v) { + setUniformInternal(location, count * 2, v); mProgram->setUniform2uiv(location, count, v); } void Program::setUniform3uiv(GLint location, GLsizei count, const GLuint *v) { + setUniformInternal(location, count * 3, v); mProgram->setUniform3uiv(location, count, v); } void Program::setUniform4uiv(GLint location, GLsizei count, const GLuint *v) { + setUniformInternal(location, count * 4, v); mProgram->setUniform4uiv(location, count, v); } void Program::setUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *v) { + setMatrixUniformInternal<2, 2>(location, count, transpose, v); mProgram->setUniformMatrix2fv(location, count, transpose, v); } void Program::setUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *v) { + setMatrixUniformInternal<3, 3>(location, count, transpose, v); mProgram->setUniformMatrix3fv(location, count, transpose, v); } void Program::setUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *v) { + setMatrixUniformInternal<4, 4>(location, count, transpose, v); mProgram->setUniformMatrix4fv(location, count, transpose, v); } void Program::setUniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *v) { + setMatrixUniformInternal<2, 3>(location, count, transpose, v); mProgram->setUniformMatrix2x3fv(location, count, transpose, v); } void Program::setUniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *v) { + setMatrixUniformInternal<2, 4>(location, count, transpose, v); mProgram->setUniformMatrix2x4fv(location, count, transpose, v); } void Program::setUniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *v) { + setMatrixUniformInternal<3, 2>(location, count, transpose, v); mProgram->setUniformMatrix3x2fv(location, count, transpose, v); } void Program::setUniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *v) { + setMatrixUniformInternal<3, 4>(location, count, transpose, v); mProgram->setUniformMatrix3x4fv(location, count, transpose, v); } void Program::setUniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *v) { + setMatrixUniformInternal<4, 2>(location, count, transpose, v); mProgram->setUniformMatrix4x2fv(location, count, transpose, v); } void Program::setUniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *v) { + setMatrixUniformInternal<4, 3>(location, count, transpose, v); mProgram->setUniformMatrix4x3fv(location, count, transpose, v); } -void Program::getUniformfv(GLint location, GLfloat *v) -{ - mProgram->getUniformfv(location, v); -} - -void Program::getUniformiv(GLint location, GLint *v) -{ - mProgram->getUniformiv(location, v); -} - -void Program::getUniformuiv(GLint location, GLuint *v) +void Program::getUniformfv(GLint location, GLfloat *v) const { - mProgram->getUniformuiv(location, v); + getUniformInternal(location, v); } -// Applies all the uniforms set for this program object to the renderer -Error Program::applyUniforms() +void Program::getUniformiv(GLint location, GLint *v) const { - return mProgram->applyUniforms(); + getUniformInternal(location, v); } -Error Program::applyUniformBuffers(const gl::Data &data) +void Program::getUniformuiv(GLint location, GLuint *v) const { - return mProgram->applyUniformBuffers(data, mUniformBlockBindings); + getUniformInternal(location, v); } void Program::flagForDeletion() @@ -1012,52 +1286,117 @@ bool Program::isFlaggedForDeletion() const void Program::validate(const Caps &caps) { mInfoLog.reset(); - mValidated = false; if (mLinked) { - applyUniforms(); - mValidated = mProgram->validateSamplers(&mInfoLog, caps); + mValidated = (mProgram->validate(caps, &mInfoLog) == GL_TRUE); } else { - mInfoLog.append("Program has not been successfully linked."); + mInfoLog << "Program has not been successfully linked."; } } bool Program::validateSamplers(InfoLog *infoLog, const Caps &caps) { - return mProgram->validateSamplers(infoLog, caps); -} + // Skip cache if we're using an infolog, so we get the full error. + // Also skip the cache if the sample mapping has changed, or if we haven't ever validated. + if (infoLog == nullptr && mCachedValidateSamplersResult.valid()) + { + return mCachedValidateSamplersResult.value(); + } -bool Program::isValidated() const -{ - return mValidated; + if (mTextureUnitTypesCache.empty()) + { + mTextureUnitTypesCache.resize(caps.maxCombinedTextureImageUnits, GL_NONE); + } + else + { + std::fill(mTextureUnitTypesCache.begin(), mTextureUnitTypesCache.end(), GL_NONE); + } + + // 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 (unsigned int samplerIndex = mSamplerUniformRange.start; + samplerIndex < mSamplerUniformRange.end; ++samplerIndex) + { + const LinkedUniform &uniform = mData.mUniforms[samplerIndex]; + ASSERT(uniform.isSampler()); + + if (!uniform.staticUse) + continue; + + const GLuint *dataPtr = reinterpret_cast(uniform.getDataPtrToElement(0)); + GLenum textureType = SamplerTypeToTextureType(uniform.type); + + for (unsigned int arrayElement = 0; arrayElement < uniform.elementCount(); ++arrayElement) + { + GLuint textureUnit = dataPtr[arrayElement]; + + if (textureUnit >= caps.maxCombinedTextureImageUnits) + { + if (infoLog) + { + (*infoLog) << "Sampler uniform (" << textureUnit + << ") exceeds GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS (" + << caps.maxCombinedTextureImageUnits << ")"; + } + + mCachedValidateSamplersResult = false; + return false; + } + + if (mTextureUnitTypesCache[textureUnit] != GL_NONE) + { + if (textureType != mTextureUnitTypesCache[textureUnit]) + { + if (infoLog) + { + (*infoLog) << "Samplers of conflicting types refer to the same texture " + "image unit (" + << textureUnit << ")."; + } + + mCachedValidateSamplersResult = false; + return false; + } + } + else + { + mTextureUnitTypesCache[textureUnit] = textureType; + } + } + } + + mCachedValidateSamplersResult = true; + return true; } -void Program::updateSamplerMapping() +bool Program::isValidated() const { - return mProgram->updateSamplerMapping(); + return mValidated; } -GLuint Program::getActiveUniformBlockCount() +GLuint Program::getActiveUniformBlockCount() const { - return static_cast(mProgram->getUniformBlocks().size()); + return static_cast(mData.mUniformBlocks.size()); } void Program::getActiveUniformBlockName(GLuint uniformBlockIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformBlockName) const { - ASSERT(uniformBlockIndex < mProgram->getUniformBlocks().size()); // index must be smaller than getActiveUniformBlockCount() + ASSERT(uniformBlockIndex < + mData.mUniformBlocks.size()); // index must be smaller than getActiveUniformBlockCount() - const UniformBlock &uniformBlock = *mProgram->getUniformBlocks()[uniformBlockIndex]; + const UniformBlock &uniformBlock = mData.mUniformBlocks[uniformBlockIndex]; if (bufSize > 0) { std::string string = uniformBlock.name; - if (uniformBlock.isArrayElement()) + if (uniformBlock.isArray) { - string += ArrayString(uniformBlock.elementIndex); + string += ArrayString(uniformBlock.arrayElement); } strncpy(uniformBlockName, string.c_str(), bufSize); @@ -1072,9 +1411,10 @@ void Program::getActiveUniformBlockName(GLuint uniformBlockIndex, GLsizei bufSiz void Program::getActiveUniformBlockiv(GLuint uniformBlockIndex, GLenum pname, GLint *params) const { - ASSERT(uniformBlockIndex < mProgram->getUniformBlocks().size()); // index must be smaller than getActiveUniformBlockCount() + ASSERT(uniformBlockIndex < + mData.mUniformBlocks.size()); // index must be smaller than getActiveUniformBlockCount() - const UniformBlock &uniformBlock = *mProgram->getUniformBlocks()[uniformBlockIndex]; + const UniformBlock &uniformBlock = mData.mUniformBlocks[uniformBlockIndex]; switch (pname) { @@ -1082,7 +1422,8 @@ void Program::getActiveUniformBlockiv(GLuint uniformBlockIndex, GLenum pname, GL *params = static_cast(uniformBlock.dataSize); break; case GL_UNIFORM_BLOCK_NAME_LENGTH: - *params = static_cast(uniformBlock.name.size() + 1 + (uniformBlock.isArrayElement() ? 3 : 0)); + *params = + static_cast(uniformBlock.name.size() + 1 + (uniformBlock.isArray ? 3 : 0)); break; case GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS: *params = static_cast(uniformBlock.memberUniformIndexes.size()); @@ -1096,31 +1437,31 @@ void Program::getActiveUniformBlockiv(GLuint uniformBlockIndex, GLenum pname, GL } break; case GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER: - *params = static_cast(uniformBlock.isReferencedByVertexShader()); + *params = static_cast(uniformBlock.vertexStaticUse); break; case GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER: - *params = static_cast(uniformBlock.isReferencedByFragmentShader()); + *params = static_cast(uniformBlock.fragmentStaticUse); break; default: UNREACHABLE(); } } -GLint Program::getActiveUniformBlockMaxLength() +GLint Program::getActiveUniformBlockMaxLength() const { int maxLength = 0; if (mLinked) { - unsigned int numUniformBlocks = static_cast(mProgram->getUniformBlocks().size()); + unsigned int numUniformBlocks = static_cast(mData.mUniformBlocks.size()); for (unsigned int uniformBlockIndex = 0; uniformBlockIndex < numUniformBlocks; uniformBlockIndex++) { - const UniformBlock &uniformBlock = *mProgram->getUniformBlocks()[uniformBlockIndex]; + const UniformBlock &uniformBlock = mData.mUniformBlocks[uniformBlockIndex]; if (!uniformBlock.name.empty()) { - const int length = static_cast(uniformBlock.name.length() + 1); + const int length = static_cast(uniformBlock.name.length()) + 1; // Counting in "[0]". - const int arrayLength = (uniformBlock.isArrayElement() ? 3 : 0); + const int arrayLength = (uniformBlock.isArray ? 3 : 0); maxLength = std::max(length + arrayLength, maxLength); } @@ -1130,51 +1471,73 @@ GLint Program::getActiveUniformBlockMaxLength() return maxLength; } -GLuint Program::getUniformBlockIndex(const std::string &name) +GLuint Program::getUniformBlockIndex(const std::string &name) const { - return mProgram->getUniformBlockIndex(name); + size_t subscript = GL_INVALID_INDEX; + std::string baseName = gl::ParseUniformName(name, &subscript); + + unsigned int numUniformBlocks = static_cast(mData.mUniformBlocks.size()); + for (unsigned int blockIndex = 0; blockIndex < numUniformBlocks; blockIndex++) + { + const gl::UniformBlock &uniformBlock = mData.mUniformBlocks[blockIndex]; + if (uniformBlock.name == baseName) + { + const bool arrayElementZero = + (subscript == GL_INVALID_INDEX && + (!uniformBlock.isArray || uniformBlock.arrayElement == 0)); + if (subscript == uniformBlock.arrayElement || arrayElementZero) + { + return blockIndex; + } + } + } + + return GL_INVALID_INDEX; } -const UniformBlock *Program::getUniformBlockByIndex(GLuint index) const +const UniformBlock &Program::getUniformBlockByIndex(GLuint index) const { - return mProgram->getUniformBlockByIndex(index); + ASSERT(index < static_cast(mData.mUniformBlocks.size())); + return mData.mUniformBlocks[index]; } void Program::bindUniformBlock(GLuint uniformBlockIndex, GLuint uniformBlockBinding) { - mUniformBlockBindings[uniformBlockIndex] = uniformBlockBinding; + mData.mUniformBlockBindings[uniformBlockIndex] = uniformBlockBinding; + mProgram->setUniformBlockBinding(uniformBlockIndex, uniformBlockBinding); } GLuint Program::getUniformBlockBinding(GLuint uniformBlockIndex) const { - return mUniformBlockBindings[uniformBlockIndex]; + return mData.getUniformBlockBinding(uniformBlockIndex); } void Program::resetUniformBlockBindings() { for (unsigned int blockId = 0; blockId < IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS; blockId++) { - mUniformBlockBindings[blockId] = 0; + mData.mUniformBlockBindings[blockId] = 0; } + mData.mActiveUniformBlockBindings.reset(); } void Program::setTransformFeedbackVaryings(GLsizei count, const GLchar *const *varyings, GLenum bufferMode) { - mTransformFeedbackVaryings.resize(count); + mData.mTransformFeedbackVaryingNames.resize(count); for (GLsizei i = 0; i < count; i++) { - mTransformFeedbackVaryings[i] = varyings[i]; + mData.mTransformFeedbackVaryingNames[i] = varyings[i]; } - mTransformFeedbackBufferMode = bufferMode; + mData.mTransformFeedbackBufferMode = bufferMode; } void Program::getTransformFeedbackVarying(GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name) const { if (mLinked) { - ASSERT(index < mProgram->getTransformFeedbackLinkedVaryings().size()); - const LinkedVarying &varying = mProgram->getTransformFeedbackLinkedVaryings()[index]; + ASSERT(index < mData.mTransformFeedbackVaryingVars.size()); + const sh::Varying &varying = mData.mTransformFeedbackVaryingVars[index]; GLsizei lastNameIdx = std::min(bufSize - 1, static_cast(varying.name.length())); if (length) { @@ -1182,7 +1545,7 @@ void Program::getTransformFeedbackVarying(GLuint index, GLsizei bufSize, GLsizei } if (size) { - *size = varying.size; + *size = varying.elementCount(); } if (type) { @@ -1200,7 +1563,7 @@ GLsizei Program::getTransformFeedbackVaryingCount() const { if (mLinked) { - return static_cast(mProgram->getTransformFeedbackLinkedVaryings().size()); + return static_cast(mData.mTransformFeedbackVaryingVars.size()); } else { @@ -1213,9 +1576,8 @@ GLsizei Program::getTransformFeedbackVaryingMaxLength() const if (mLinked) { GLsizei maxSize = 0; - for (size_t i = 0; i < mProgram->getTransformFeedbackLinkedVaryings().size(); i++) + for (const sh::Varying &varying : mData.mTransformFeedbackVaryingVars) { - const LinkedVarying &varying = mProgram->getTransformFeedbackLinkedVaryings()[i]; maxSize = std::max(maxSize, static_cast(varying.name.length() + 1)); } @@ -1229,64 +1591,123 @@ GLsizei Program::getTransformFeedbackVaryingMaxLength() const GLenum Program::getTransformFeedbackBufferMode() const { - return mTransformFeedbackBufferMode; + return mData.mTransformFeedbackBufferMode; } -bool Program::linkVaryings(InfoLog &infoLog, Shader *fragmentShader, Shader *vertexShader) +// static +bool Program::linkVaryings(InfoLog &infoLog, + const Shader *vertexShader, + const Shader *fragmentShader) { - std::vector &fragmentVaryings = fragmentShader->getVaryings(); - std::vector &vertexVaryings = vertexShader->getVaryings(); + const std::vector &vertexVaryings = vertexShader->getVaryings(); + const std::vector &fragmentVaryings = fragmentShader->getVaryings(); - for (size_t fragVaryingIndex = 0; fragVaryingIndex < fragmentVaryings.size(); fragVaryingIndex++) + for (const sh::Varying &output : fragmentVaryings) { - PackedVarying *input = &fragmentVaryings[fragVaryingIndex]; bool matched = false; // Built-in varyings obey special rules - if (input->isBuiltIn()) + if (output.isBuiltIn()) { continue; } - for (size_t vertVaryingIndex = 0; vertVaryingIndex < vertexVaryings.size(); vertVaryingIndex++) + for (const sh::Varying &input : vertexVaryings) { - PackedVarying *output = &vertexVaryings[vertVaryingIndex]; - if (output->name == input->name) + if (output.name == input.name) { - if (!linkValidateVaryings(infoLog, output->name, *input, *output)) + ASSERT(!input.isBuiltIn()); + if (!linkValidateVaryings(infoLog, output.name, input, output)) { return false; } - output->registerIndex = input->registerIndex; - output->columnIndex = input->columnIndex; - matched = true; break; } } // We permit unmatched, unreferenced varyings - if (!matched && input->staticUse) + if (!matched && output.staticUse) { - infoLog.append("Fragment varying %s does not match any vertex varying", input->name.c_str()); + infoLog << "Fragment varying " << output.name << " does not match any vertex varying"; return false; } } + // TODO(jmadill): verify no unmatched vertex varyings? + return true; } +bool Program::linkUniforms(gl::InfoLog &infoLog, const gl::Caps &caps) +{ + const std::vector &vertexUniforms = mData.mAttachedVertexShader->getUniforms(); + const std::vector &fragmentUniforms = mData.mAttachedFragmentShader->getUniforms(); + + // Check that uniforms defined in the vertex and fragment shaders are identical + std::map linkedUniforms; + + for (const sh::Uniform &vertexUniform : vertexUniforms) + { + linkedUniforms[vertexUniform.name] = LinkedUniform(vertexUniform); + } + + for (const sh::Uniform &fragmentUniform : fragmentUniforms) + { + auto entry = linkedUniforms.find(fragmentUniform.name); + if (entry != linkedUniforms.end()) + { + LinkedUniform *vertexUniform = &entry->second; + const std::string &uniformName = "uniform '" + vertexUniform->name + "'"; + if (!linkValidateUniforms(infoLog, uniformName, *vertexUniform, fragmentUniform)) + { + 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; + } + + indexUniforms(); + + return true; +} + +void Program::indexUniforms() +{ + for (size_t uniformIndex = 0; uniformIndex < mData.mUniforms.size(); uniformIndex++) + { + const gl::LinkedUniform &uniform = mData.mUniforms[uniformIndex]; + + for (unsigned int arrayIndex = 0; arrayIndex < uniform.elementCount(); arrayIndex++) + { + if (!uniform.isBuiltIn()) + { + // Assign in-order uniform locations + mData.mUniformLocations.push_back(gl::VariableLocation( + uniform.name, arrayIndex, static_cast(uniformIndex))); + } + } + } +} + bool Program::linkValidateInterfaceBlockFields(InfoLog &infoLog, const std::string &uniformName, const sh::InterfaceBlockField &vertexUniform, const sh::InterfaceBlockField &fragmentUniform) { - if (!linkValidateVariablesBase(infoLog, uniformName, vertexUniform, fragmentUniform, true)) + // We don't validate precision on UBO fields. See resolution of Khronos bug 10287. + if (!linkValidateVariablesBase(infoLog, uniformName, vertexUniform, fragmentUniform, false)) { return false; } if (vertexUniform.isRowMajorLayout != fragmentUniform.isRowMajorLayout) { - infoLog.append("Matrix packings for %s differ between vertex and fragment shaders", uniformName.c_str()); + infoLog << "Matrix packings for " << uniformName << " differ between vertex and fragment shaders"; return false; } @@ -1294,155 +1715,168 @@ bool Program::linkValidateInterfaceBlockFields(InfoLog &infoLog, const std::stri } // Determines the mapping between GL attributes and Direct3D 9 vertex stream usage indices -bool Program::linkAttributes(const Data &data, +bool Program::linkAttributes(const gl::Data &data, InfoLog &infoLog, const AttributeBindings &attributeBindings, const Shader *vertexShader) { unsigned int usedLocations = 0; - const std::vector &shaderAttributes = vertexShader->getActiveAttributes(); + mData.mAttributes = vertexShader->getActiveAttributes(); GLuint maxAttribs = data.caps->maxVertexAttributes; // TODO(jmadill): handle aliasing robustly - if (shaderAttributes.size() >= maxAttribs) + if (mData.mAttributes.size() > maxAttribs) { - infoLog.append("Too many vertex attributes."); + infoLog << "Too many vertex attributes."; return false; } + std::vector usedAttribMap(data.caps->maxVertexAttributes, nullptr); + // Link attributes that have a binding location - for (unsigned int attributeIndex = 0; attributeIndex < shaderAttributes.size(); attributeIndex++) + for (sh::Attribute &attribute : mData.mAttributes) { - const sh::Attribute &attribute = shaderAttributes[attributeIndex]; - + // TODO(jmadill): do staticUse filtering step here, or not at all ASSERT(attribute.staticUse); - const int location = attribute.location == -1 ? attributeBindings.getAttributeBinding(attribute.name) : attribute.location; - - mProgram->setShaderAttribute(attributeIndex, attribute); + int bindingLocation = attributeBindings.getAttributeBinding(attribute.name); + if (attribute.location == -1 && bindingLocation != -1) + { + attribute.location = bindingLocation; + } - if (location != -1) // Set by glBindAttribLocation or by location layout qualifier + if (attribute.location != -1) { - const int rows = VariableRegisterCount(attribute.type); + // Location is set by glBindAttribLocation or by location layout qualifier + const int regs = VariableRegisterCount(attribute.type); - if (static_cast(rows + location) > maxAttribs) + if (static_cast(regs + attribute.location) > maxAttribs) { - infoLog.append("Active attribute (%s) at location %d is too big to fit", attribute.name.c_str(), location); + infoLog << "Active attribute (" << attribute.name << ") at location " + << attribute.location << " is too big to fit"; return false; } - for (int row = 0; row < rows; row++) + for (int reg = 0; reg < regs; reg++) { - const int rowLocation = location + row; - sh::ShaderVariable &linkedAttribute = mLinkedAttribute[rowLocation]; + const int regLocation = attribute.location + reg; + sh::ShaderVariable *linkedAttribute = usedAttribMap[regLocation]; // In GLSL 3.00, attribute aliasing produces a link error // In GLSL 1.00, attribute aliasing is allowed, but ANGLE currently has a bug - // TODO(jmadill): fix aliasing on ES2 - // if (mProgram->getShaderVersion() >= 300) + if (linkedAttribute) { - if (!linkedAttribute.name.empty()) + // TODO(jmadill): fix aliasing on ES2 + // if (mProgram->getShaderVersion() >= 300) { - infoLog.append("Attribute '%s' aliases attribute '%s' at location %d", attribute.name.c_str(), linkedAttribute.name.c_str(), rowLocation); + infoLog << "Attribute '" << attribute.name << "' aliases attribute '" + << linkedAttribute->name << "' at location " << regLocation; return false; } } + else + { + usedAttribMap[regLocation] = &attribute; + } - linkedAttribute = attribute; - usedLocations |= 1 << rowLocation; + usedLocations |= 1 << regLocation; } } } // Link attributes that don't have a binding location - for (unsigned int attributeIndex = 0; attributeIndex < shaderAttributes.size(); attributeIndex++) + for (sh::Attribute &attribute : mData.mAttributes) { - const sh::Attribute &attribute = shaderAttributes[attributeIndex]; - ASSERT(attribute.staticUse); - const int location = attribute.location == -1 ? attributeBindings.getAttributeBinding(attribute.name) : attribute.location; - - if (location == -1) // Not set by glBindAttribLocation or by location layout qualifier + // Not set by glBindAttribLocation or by location layout qualifier + if (attribute.location == -1) { - int rows = VariableRegisterCount(attribute.type); - int availableIndex = AllocateFirstFreeBits(&usedLocations, rows, maxAttribs); + int regs = VariableRegisterCount(attribute.type); + int availableIndex = AllocateFirstFreeBits(&usedLocations, regs, maxAttribs); - if (availableIndex == -1 || static_cast(availableIndex + rows) > maxAttribs) + if (availableIndex == -1 || static_cast(availableIndex + regs) > maxAttribs) { - infoLog.append("Too many active attributes (%s)", attribute.name.c_str()); - - return false; // Fail to link + infoLog << "Too many active attributes (" << attribute.name << ")"; + return false; } - mLinkedAttribute[availableIndex] = attribute; + attribute.location = availableIndex; } } - for (GLuint attributeIndex = 0; attributeIndex < maxAttribs;) + for (const sh::Attribute &attribute : mData.mAttributes) { - int index = vertexShader->getSemanticIndex(mLinkedAttribute[attributeIndex].name); - int rows = VariableRegisterCount(mLinkedAttribute[attributeIndex].type); + ASSERT(attribute.staticUse); + ASSERT(attribute.location != -1); + int regs = VariableRegisterCount(attribute.type); - for (int r = 0; r < rows; r++) + for (int r = 0; r < regs; r++) { - mProgram->getSemanticIndexes()[attributeIndex++] = index++; + mData.mActiveAttribLocationsMask.set(attribute.location + r); } } return true; } -bool Program::linkUniformBlocks(InfoLog &infoLog, const Shader &vertexShader, const Shader &fragmentShader, const Caps &caps) +bool Program::linkUniformBlocks(InfoLog &infoLog, const Caps &caps) { + const Shader &vertexShader = *mData.mAttachedVertexShader; + const Shader &fragmentShader = *mData.mAttachedFragmentShader; + const std::vector &vertexInterfaceBlocks = vertexShader.getInterfaceBlocks(); const std::vector &fragmentInterfaceBlocks = fragmentShader.getInterfaceBlocks(); + // Check that interface blocks defined in the vertex and fragment shaders are identical typedef std::map UniformBlockMap; UniformBlockMap linkedUniformBlocks; - for (unsigned int blockIndex = 0; blockIndex < vertexInterfaceBlocks.size(); blockIndex++) + + GLuint vertexBlockCount = 0; + for (const sh::InterfaceBlock &vertexInterfaceBlock : vertexInterfaceBlocks) { - const sh::InterfaceBlock &vertexInterfaceBlock = vertexInterfaceBlocks[blockIndex]; linkedUniformBlocks[vertexInterfaceBlock.name] = &vertexInterfaceBlock; - } - for (unsigned int blockIndex = 0; blockIndex < fragmentInterfaceBlocks.size(); blockIndex++) - { - const sh::InterfaceBlock &fragmentInterfaceBlock = fragmentInterfaceBlocks[blockIndex]; - UniformBlockMap::const_iterator entry = linkedUniformBlocks.find(fragmentInterfaceBlock.name); - if (entry != linkedUniformBlocks.end()) + + // Note: shared and std140 layouts are always considered active + if (vertexInterfaceBlock.staticUse || vertexInterfaceBlock.layout != sh::BLOCKLAYOUT_PACKED) { - const sh::InterfaceBlock &vertexInterfaceBlock = *entry->second; - if (!areMatchingInterfaceBlocks(infoLog, vertexInterfaceBlock, fragmentInterfaceBlock)) + if (++vertexBlockCount > caps.maxVertexUniformBlocks) { + infoLog << "Vertex shader uniform block count exceed GL_MAX_VERTEX_UNIFORM_BLOCKS (" + << caps.maxVertexUniformBlocks << ")"; return false; } } } - for (unsigned int blockIndex = 0; blockIndex < vertexInterfaceBlocks.size(); blockIndex++) + + GLuint fragmentBlockCount = 0; + for (const sh::InterfaceBlock &fragmentInterfaceBlock : fragmentInterfaceBlocks) { - const sh::InterfaceBlock &interfaceBlock = vertexInterfaceBlocks[blockIndex]; - // Note: shared and std140 layouts are always considered active - if (interfaceBlock.staticUse || interfaceBlock.layout != sh::BLOCKLAYOUT_PACKED) + auto entry = linkedUniformBlocks.find(fragmentInterfaceBlock.name); + if (entry != linkedUniformBlocks.end()) { - if (!mProgram->defineUniformBlock(infoLog, vertexShader, interfaceBlock, caps)) + const sh::InterfaceBlock &vertexInterfaceBlock = *entry->second; + if (!areMatchingInterfaceBlocks(infoLog, vertexInterfaceBlock, fragmentInterfaceBlock)) { return false; } } - } - for (unsigned int blockIndex = 0; blockIndex < fragmentInterfaceBlocks.size(); blockIndex++) - { - const sh::InterfaceBlock &interfaceBlock = fragmentInterfaceBlocks[blockIndex]; + // Note: shared and std140 layouts are always considered active - if (interfaceBlock.staticUse || interfaceBlock.layout != sh::BLOCKLAYOUT_PACKED) + if (fragmentInterfaceBlock.staticUse || + fragmentInterfaceBlock.layout != sh::BLOCKLAYOUT_PACKED) { - if (!mProgram->defineUniformBlock(infoLog, fragmentShader, interfaceBlock, caps)) + if (++fragmentBlockCount > caps.maxFragmentUniformBlocks) { + infoLog + << "Fragment shader uniform block count exceed GL_MAX_FRAGMENT_UNIFORM_BLOCKS (" + << caps.maxFragmentUniformBlocks << ")"; return false; } } } + return true; } @@ -1453,28 +1887,34 @@ bool Program::areMatchingInterfaceBlocks(gl::InfoLog &infoLog, const sh::Interfa // validate blocks for the same member types if (vertexInterfaceBlock.fields.size() != fragmentInterfaceBlock.fields.size()) { - infoLog.append("Types for interface block '%s' differ between vertex and fragment shaders", blockName); + infoLog << "Types for interface block '" << blockName + << "' differ between vertex and fragment shaders"; return false; } if (vertexInterfaceBlock.arraySize != fragmentInterfaceBlock.arraySize) { - infoLog.append("Array sizes differ for interface block '%s' between vertex and fragment shaders", blockName); + infoLog << "Array sizes differ for interface block '" << blockName + << "' between vertex and fragment shaders"; return false; } if (vertexInterfaceBlock.layout != fragmentInterfaceBlock.layout || vertexInterfaceBlock.isRowMajorLayout != fragmentInterfaceBlock.isRowMajorLayout) { - infoLog.append("Layout qualifiers differ for interface block '%s' between vertex and fragment shaders", blockName); + infoLog << "Layout qualifiers differ for interface block '" << blockName + << "' between vertex and fragment shaders"; return false; } - const unsigned int numBlockMembers = static_cast(vertexInterfaceBlock.fields.size()); + const unsigned int numBlockMembers = + static_cast(vertexInterfaceBlock.fields.size()); for (unsigned int blockMemberIndex = 0; blockMemberIndex < numBlockMembers; blockMemberIndex++) { const sh::InterfaceBlockField &vertexMember = vertexInterfaceBlock.fields[blockMemberIndex]; const sh::InterfaceBlockField &fragmentMember = fragmentInterfaceBlock.fields[blockMemberIndex]; if (vertexMember.name != fragmentMember.name) { - infoLog.append("Name mismatch for field %d of interface block '%s': (in vertex: '%s', in fragment: '%s')", - blockMemberIndex, blockName, vertexMember.name.c_str(), fragmentMember.name.c_str()); + infoLog << "Name mismatch for field " << blockMemberIndex + << " of interface block '" << blockName + << "': (in vertex: '" << vertexMember.name + << "', in fragment: '" << fragmentMember.name << "')"; return false; } std::string memberName = "interface block '" + vertexInterfaceBlock.name + "' member '" + vertexMember.name + "'"; @@ -1491,23 +1931,23 @@ bool Program::linkValidateVariablesBase(InfoLog &infoLog, const std::string &var { if (vertexVariable.type != fragmentVariable.type) { - infoLog.append("Types for %s differ between vertex and fragment shaders", variableName.c_str()); + infoLog << "Types for " << variableName << " differ between vertex and fragment shaders"; return false; } if (vertexVariable.arraySize != fragmentVariable.arraySize) { - infoLog.append("Array sizes for %s differ between vertex and fragment shaders", variableName.c_str()); + infoLog << "Array sizes for " << variableName << " differ between vertex and fragment shaders"; return false; } if (validatePrecision && vertexVariable.precision != fragmentVariable.precision) { - infoLog.append("Precisions for %s differ between vertex and fragment shaders", variableName.c_str()); + infoLog << "Precisions for " << variableName << " differ between vertex and fragment shaders"; return false; } if (vertexVariable.fields.size() != fragmentVariable.fields.size()) { - infoLog.append("Structure lengths for %s differ between vertex and fragment shaders", variableName.c_str()); + infoLog << "Structure lengths for " << variableName << " differ between vertex and fragment shaders"; return false; } const unsigned int numMembers = static_cast(vertexVariable.fields.size()); @@ -1518,9 +1958,10 @@ bool Program::linkValidateVariablesBase(InfoLog &infoLog, const std::string &var if (vertexMember.name != fragmentMember.name) { - infoLog.append("Name mismatch for field '%d' of %s: (in vertex: '%s', in fragment: '%s')", - memberIndex, variableName.c_str(), - vertexMember.name.c_str(), fragmentMember.name.c_str()); + infoLog << "Name mismatch for field '" << memberIndex + << "' of " << variableName + << ": (in vertex: '" << vertexMember.name + << "', in fragment: '" << fragmentMember.name << "')"; return false; } @@ -1538,7 +1979,13 @@ bool Program::linkValidateVariablesBase(InfoLog &infoLog, const std::string &var bool Program::linkValidateUniforms(InfoLog &infoLog, const std::string &uniformName, const sh::Uniform &vertexUniform, const sh::Uniform &fragmentUniform) { - if (!linkValidateVariablesBase(infoLog, uniformName, vertexUniform, fragmentUniform, true)) +#if ANGLE_PROGRAM_LINK_VALIDATE_UNIFORM_PRECISION == ANGLE_ENABLED + const bool validatePrecision = true; +#else + const bool validatePrecision = false; +#endif + + if (!linkValidateVariablesBase(infoLog, uniformName, vertexUniform, fragmentUniform, validatePrecision)) { return false; } @@ -1555,68 +2002,530 @@ bool Program::linkValidateVaryings(InfoLog &infoLog, const std::string &varyingN if (!sh::InterpolationTypesMatch(vertexVarying.interpolation, fragmentVarying.interpolation)) { - infoLog.append("Interpolation types for %s differ between vertex and fragment shaders", varyingName.c_str()); + infoLog << "Interpolation types for " << varyingName << " differ between vertex and fragment shaders"; return false; } return true; } -bool Program::gatherTransformFeedbackLinkedVaryings(InfoLog &infoLog, const std::vector &linkedVaryings, - const std::vector &transformFeedbackVaryingNames, - GLenum transformFeedbackBufferMode, - std::vector *outTransformFeedbackLinkedVaryings, - const Caps &caps) const +bool Program::linkValidateTransformFeedback(InfoLog &infoLog, + const std::vector &varyings, + const Caps &caps) const { size_t totalComponents = 0; - // Gather the linked varyings that are used for transform feedback, they should all exist. - outTransformFeedbackLinkedVaryings->clear(); - for (size_t i = 0; i < transformFeedbackVaryingNames.size(); i++) + std::set uniqueNames; + + for (const std::string &tfVaryingName : mData.mTransformFeedbackVaryingNames) { bool found = false; - for (size_t j = 0; j < linkedVaryings.size(); j++) + for (const sh::Varying *varying : varyings) { - if (transformFeedbackVaryingNames[i] == linkedVaryings[j].name) + if (tfVaryingName == varying->name) { - for (size_t k = 0; k < outTransformFeedbackLinkedVaryings->size(); k++) + if (uniqueNames.count(tfVaryingName) > 0) { - if (outTransformFeedbackLinkedVaryings->at(k).name == linkedVaryings[j].name) - { - infoLog.append("Two transform feedback varyings specify the same output variable (%s).", linkedVaryings[j].name.c_str()); - return false; - } + infoLog << "Two transform feedback varyings specify the same output variable (" + << tfVaryingName << ")."; + return false; } + uniqueNames.insert(tfVaryingName); - size_t componentCount = linkedVaryings[j].semanticIndexCount * 4; - if (transformFeedbackBufferMode == GL_SEPARATE_ATTRIBS && + if (varying->isArray()) + { + infoLog << "Capture of arrays is undefined and not supported."; + return false; + } + + // TODO(jmadill): Investigate implementation limits on D3D11 + size_t componentCount = gl::VariableComponentCount(varying->type); + if (mData.mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS && componentCount > caps.maxTransformFeedbackSeparateComponents) { - infoLog.append("Transform feedback varying's %s components (%u) exceed the maximum separate components (%u).", - linkedVaryings[j].name.c_str(), componentCount, caps.maxTransformFeedbackSeparateComponents); + infoLog << "Transform feedback varying's " << varying->name << " components (" + << componentCount << ") exceed the maximum separate components (" + << caps.maxTransformFeedbackSeparateComponents << ")."; return false; } totalComponents += componentCount; - - outTransformFeedbackLinkedVaryings->push_back(linkedVaryings[j]); found = true; break; } } + if (tfVaryingName.find('[') != std::string::npos) + { + infoLog << "Capture of array elements is undefined and not supported."; + return false; + } + // All transform feedback varyings are expected to exist since packVaryings checks for them. ASSERT(found); + UNUSED_ASSERTION_VARIABLE(found); } - if (transformFeedbackBufferMode == GL_INTERLEAVED_ATTRIBS && totalComponents > caps.maxTransformFeedbackInterleavedComponents) + if (mData.mTransformFeedbackBufferMode == GL_INTERLEAVED_ATTRIBS && + totalComponents > caps.maxTransformFeedbackInterleavedComponents) { - infoLog.append("Transform feedback varying total components (%u) exceed the maximum interleaved components (%u).", - totalComponents, caps.maxTransformFeedbackInterleavedComponents); + infoLog << "Transform feedback varying total components (" << totalComponents + << ") exceed the maximum interleaved components (" + << caps.maxTransformFeedbackInterleavedComponents << ")."; return false; } return true; } +void Program::gatherTransformFeedbackVaryings(const std::vector &varyings) +{ + // Gather the linked varyings that are used for transform feedback, they should all exist. + mData.mTransformFeedbackVaryingVars.clear(); + for (const std::string &tfVaryingName : mData.mTransformFeedbackVaryingNames) + { + for (const sh::Varying *varying : varyings) + { + if (tfVaryingName == varying->name) + { + mData.mTransformFeedbackVaryingVars.push_back(*varying); + break; + } + } + } +} + +std::vector Program::getMergedVaryings() const +{ + std::set uniqueNames; + std::vector varyings; + + for (const sh::Varying &varying : mData.mAttachedVertexShader->getVaryings()) + { + if (uniqueNames.count(varying.name) == 0) + { + uniqueNames.insert(varying.name); + varyings.push_back(&varying); + } + } + + for (const sh::Varying &varying : mData.mAttachedFragmentShader->getVaryings()) + { + if (uniqueNames.count(varying.name) == 0) + { + uniqueNames.insert(varying.name); + varyings.push_back(&varying); + } + } + + return varyings; +} + +void Program::linkOutputVariables() +{ + const Shader *fragmentShader = mData.mAttachedFragmentShader; + ASSERT(fragmentShader != nullptr); + + // Skip this step for GLES2 shaders. + if (fragmentShader->getShaderVersion() == 100) + return; + + const auto &shaderOutputVars = fragmentShader->getActiveOutputVariables(); + + // TODO(jmadill): any caps validation here? + + for (unsigned int outputVariableIndex = 0; outputVariableIndex < shaderOutputVars.size(); + outputVariableIndex++) + { + const sh::OutputVariable &outputVariable = shaderOutputVars[outputVariableIndex]; + + // Don't store outputs for gl_FragDepth, gl_FragColor, etc. + if (outputVariable.isBuiltIn()) + continue; + + // Since multiple output locations must be specified, use 0 for non-specified locations. + int baseLocation = (outputVariable.location == -1 ? 0 : outputVariable.location); + + ASSERT(outputVariable.staticUse); + + for (unsigned int elementIndex = 0; elementIndex < outputVariable.elementCount(); + elementIndex++) + { + const int location = baseLocation + elementIndex; + ASSERT(mData.mOutputVariables.count(location) == 0); + unsigned int element = outputVariable.isArray() ? elementIndex : GL_INVALID_INDEX; + mData.mOutputVariables[location] = + VariableLocation(outputVariable.name, element, outputVariableIndex); + } + } +} + +bool Program::flattenUniformsAndCheckCaps(const Caps &caps, InfoLog &infoLog) +{ + const gl::Shader *vertexShader = mData.getAttachedVertexShader(); + VectorAndSamplerCount vsCounts; + + std::vector samplerUniforms; + + for (const sh::Uniform &uniform : vertexShader->getUniforms()) + { + if (uniform.staticUse) + { + vsCounts += flattenUniform(uniform, uniform.name, &samplerUniforms); + } + } + + if (vsCounts.vectorCount > caps.maxVertexUniformVectors) + { + infoLog << "Vertex shader active uniforms exceed MAX_VERTEX_UNIFORM_VECTORS (" + << caps.maxVertexUniformVectors << ")."; + return false; + } + + if (vsCounts.samplerCount > caps.maxVertexTextureImageUnits) + { + infoLog << "Vertex shader sampler count exceeds MAX_VERTEX_TEXTURE_IMAGE_UNITS (" + << caps.maxVertexTextureImageUnits << ")."; + return false; + } + + const gl::Shader *fragmentShader = mData.getAttachedFragmentShader(); + VectorAndSamplerCount fsCounts; + + for (const sh::Uniform &uniform : fragmentShader->getUniforms()) + { + if (uniform.staticUse) + { + fsCounts += flattenUniform(uniform, uniform.name, &samplerUniforms); + } + } + + if (fsCounts.vectorCount > caps.maxFragmentUniformVectors) + { + infoLog << "Fragment shader active uniforms exceed MAX_FRAGMENT_UNIFORM_VECTORS (" + << caps.maxFragmentUniformVectors << ")."; + return false; + } + + if (fsCounts.samplerCount > caps.maxTextureImageUnits) + { + infoLog << "Fragment shader sampler count exceeds MAX_TEXTURE_IMAGE_UNITS (" + << caps.maxTextureImageUnits << ")."; + return false; + } + + mSamplerUniformRange.start = static_cast(mData.mUniforms.size()); + mSamplerUniformRange.end = + mSamplerUniformRange.start + static_cast(samplerUniforms.size()); + + mData.mUniforms.insert(mData.mUniforms.end(), samplerUniforms.begin(), samplerUniforms.end()); + + return true; +} + +Program::VectorAndSamplerCount Program::flattenUniform(const sh::ShaderVariable &uniform, + const std::string &fullName, + std::vector *samplerUniforms) +{ + VectorAndSamplerCount vectorAndSamplerCount; + + if (uniform.isStruct()) + { + for (unsigned int elementIndex = 0; elementIndex < uniform.elementCount(); elementIndex++) + { + const std::string &elementString = (uniform.isArray() ? ArrayString(elementIndex) : ""); + + for (size_t fieldIndex = 0; fieldIndex < uniform.fields.size(); fieldIndex++) + { + const sh::ShaderVariable &field = uniform.fields[fieldIndex]; + const std::string &fieldFullName = (fullName + elementString + "." + field.name); + + vectorAndSamplerCount += flattenUniform(field, fieldFullName, samplerUniforms); + } + } + + return vectorAndSamplerCount; + } + + // Not a struct + bool isSampler = IsSamplerType(uniform.type); + if (!UniformInList(mData.getUniforms(), fullName) && !UniformInList(*samplerUniforms, fullName)) + { + gl::LinkedUniform linkedUniform(uniform.type, uniform.precision, fullName, + uniform.arraySize, -1, + sh::BlockMemberInfo::getDefaultBlockInfo()); + linkedUniform.staticUse = true; + + // Store sampler uniforms separately, so we'll append them to the end of the list. + if (isSampler) + { + samplerUniforms->push_back(linkedUniform); + } + else + { + mData.mUniforms.push_back(linkedUniform); + } + } + + unsigned int elementCount = uniform.elementCount(); + + // Samplers aren't "real" uniforms, so they don't count towards register usage. + // Likewise, don't count "real" uniforms towards sampler count. + vectorAndSamplerCount.vectorCount = + (isSampler ? 0 : (VariableRegisterCount(uniform.type) * elementCount)); + vectorAndSamplerCount.samplerCount = (isSampler ? elementCount : 0); + + return vectorAndSamplerCount; +} + +void Program::gatherInterfaceBlockInfo() +{ + std::set visitedList; + + const gl::Shader *vertexShader = mData.getAttachedVertexShader(); + + ASSERT(mData.mUniformBlocks.empty()); + for (const sh::InterfaceBlock &vertexBlock : vertexShader->getInterfaceBlocks()) + { + // Only 'packed' blocks are allowed to be considered inacive. + if (!vertexBlock.staticUse && vertexBlock.layout == sh::BLOCKLAYOUT_PACKED) + continue; + + if (visitedList.count(vertexBlock.name) > 0) + continue; + + defineUniformBlock(vertexBlock, GL_VERTEX_SHADER); + visitedList.insert(vertexBlock.name); + } + + const gl::Shader *fragmentShader = mData.getAttachedFragmentShader(); + + for (const sh::InterfaceBlock &fragmentBlock : fragmentShader->getInterfaceBlocks()) + { + // Only 'packed' blocks are allowed to be considered inacive. + if (!fragmentBlock.staticUse && fragmentBlock.layout == sh::BLOCKLAYOUT_PACKED) + continue; + + if (visitedList.count(fragmentBlock.name) > 0) + { + for (gl::UniformBlock &block : mData.mUniformBlocks) + { + if (block.name == fragmentBlock.name) + { + block.fragmentStaticUse = fragmentBlock.staticUse; + } + } + + continue; + } + + defineUniformBlock(fragmentBlock, GL_FRAGMENT_SHADER); + visitedList.insert(fragmentBlock.name); + } +} + +template +void Program::defineUniformBlockMembers(const std::vector &fields, + const std::string &prefix, + int blockIndex) +{ + for (const VarT &field : fields) + { + const std::string &fullName = (prefix.empty() ? field.name : prefix + "." + field.name); + + if (field.isStruct()) + { + for (unsigned int arrayElement = 0; arrayElement < field.elementCount(); arrayElement++) + { + const std::string uniformElementName = + fullName + (field.isArray() ? ArrayString(arrayElement) : ""); + defineUniformBlockMembers(field.fields, uniformElementName, blockIndex); + } + } + else + { + // If getBlockMemberInfo returns false, the uniform is optimized out. + sh::BlockMemberInfo memberInfo; + if (!mProgram->getUniformBlockMemberInfo(fullName, &memberInfo)) + { + continue; + } + + LinkedUniform newUniform(field.type, field.precision, fullName, field.arraySize, + blockIndex, memberInfo); + + // Since block uniforms have no location, we don't need to store them in the uniform + // locations list. + mData.mUniforms.push_back(newUniform); + } + } +} + +void Program::defineUniformBlock(const sh::InterfaceBlock &interfaceBlock, GLenum shaderType) +{ + int blockIndex = static_cast(mData.mUniformBlocks.size()); + size_t blockSize = 0; + + // Don't define this block at all if it's not active in the implementation. + if (!mProgram->getUniformBlockSize(interfaceBlock.name, &blockSize)) + { + return; + } + + // Track the first and last uniform index to determine the range of active uniforms in the + // block. + size_t firstBlockUniformIndex = mData.mUniforms.size(); + defineUniformBlockMembers(interfaceBlock.fields, interfaceBlock.fieldPrefix(), blockIndex); + size_t lastBlockUniformIndex = mData.mUniforms.size(); + + std::vector blockUniformIndexes; + for (size_t blockUniformIndex = firstBlockUniformIndex; + blockUniformIndex < lastBlockUniformIndex; ++blockUniformIndex) + { + blockUniformIndexes.push_back(static_cast(blockUniformIndex)); + } + + if (interfaceBlock.arraySize > 0) + { + for (unsigned int arrayElement = 0; arrayElement < interfaceBlock.arraySize; ++arrayElement) + { + UniformBlock block(interfaceBlock.name, true, arrayElement); + block.memberUniformIndexes = blockUniformIndexes; + + if (shaderType == GL_VERTEX_SHADER) + { + block.vertexStaticUse = interfaceBlock.staticUse; + } + else + { + ASSERT(shaderType == GL_FRAGMENT_SHADER); + block.fragmentStaticUse = interfaceBlock.staticUse; + } + + // TODO(jmadill): Determine if we can ever have an inactive array element block. + size_t blockElementSize = 0; + if (!mProgram->getUniformBlockSize(block.nameWithArrayIndex(), &blockElementSize)) + { + continue; + } + + ASSERT(blockElementSize == blockSize); + block.dataSize = static_cast(blockElementSize); + mData.mUniformBlocks.push_back(block); + } + } + else + { + UniformBlock block(interfaceBlock.name, false, 0); + block.memberUniformIndexes = blockUniformIndexes; + + if (shaderType == GL_VERTEX_SHADER) + { + block.vertexStaticUse = interfaceBlock.staticUse; + } + else + { + ASSERT(shaderType == GL_FRAGMENT_SHADER); + block.fragmentStaticUse = interfaceBlock.staticUse; + } + + block.dataSize = static_cast(blockSize); + mData.mUniformBlocks.push_back(block); + } +} + +template +void Program::setUniformInternal(GLint location, GLsizei count, const T *v) +{ + const VariableLocation &locationInfo = mData.mUniformLocations[location]; + LinkedUniform *linkedUniform = &mData.mUniforms[locationInfo.index]; + uint8_t *destPointer = linkedUniform->getDataPtrToElement(locationInfo.element); + + if (VariableComponentType(linkedUniform->type) == GL_BOOL) + { + // Do a cast conversion for boolean types. From the spec: + // "The uniform is set to FALSE if the input value is 0 or 0.0f, and set to TRUE otherwise." + GLint *destAsInt = reinterpret_cast(destPointer); + for (GLsizei component = 0; component < count; ++component) + { + destAsInt[component] = (v[component] != static_cast(0) ? GL_TRUE : GL_FALSE); + } + } + else + { + // Invalide the validation cache if we modify the sampler data. + if (linkedUniform->isSampler() && memcmp(destPointer, v, sizeof(T) * count) != 0) + { + mCachedValidateSamplersResult.reset(); + } + + memcpy(destPointer, v, sizeof(T) * count); + } +} + +template +void Program::setMatrixUniformInternal(GLint location, + GLsizei count, + GLboolean transpose, + const T *v) +{ + if (!transpose) + { + setUniformInternal(location, count * cols * rows, v); + return; + } + + // Perform a transposing copy. + const VariableLocation &locationInfo = mData.mUniformLocations[location]; + LinkedUniform *linkedUniform = &mData.mUniforms[locationInfo.index]; + T *destPtr = reinterpret_cast(linkedUniform->getDataPtrToElement(locationInfo.element)); + for (GLsizei element = 0; element < count; ++element) + { + size_t elementOffset = element * rows * cols; + + for (size_t row = 0; row < rows; ++row) + { + for (size_t col = 0; col < cols; ++col) + { + destPtr[col * rows + row + elementOffset] = v[row * cols + col + elementOffset]; + } + } + } +} + +template +void Program::getUniformInternal(GLint location, DestT *dataOut) const +{ + const VariableLocation &locationInfo = mData.mUniformLocations[location]; + const LinkedUniform &uniform = mData.mUniforms[locationInfo.index]; + + const uint8_t *srcPointer = uniform.getDataPtrToElement(locationInfo.element); + + GLenum componentType = VariableComponentType(uniform.type); + if (componentType == GLTypeToGLenum::value) + { + memcpy(dataOut, srcPointer, uniform.getElementSize()); + return; + } + + int components = VariableComponentCount(uniform.type); + + switch (componentType) + { + case GL_INT: + UniformStateQueryCastLoop(dataOut, srcPointer, components); + break; + case GL_UNSIGNED_INT: + UniformStateQueryCastLoop(dataOut, srcPointer, components); + break; + case GL_BOOL: + UniformStateQueryCastLoop(dataOut, srcPointer, components); + break; + case GL_FLOAT: + UniformStateQueryCastLoop(dataOut, srcPointer, components); + break; + default: + UNREACHABLE(); + } +} } diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/Program.h b/Source/ThirdParty/ANGLE/src/libANGLE/Program.h index 6ed34f2e41a9..f885ad1694b3 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/Program.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/Program.h @@ -10,27 +10,29 @@ #ifndef LIBANGLE_PROGRAM_H_ #define LIBANGLE_PROGRAM_H_ -#include "libANGLE/angletypes.h" -#include "libANGLE/Constants.h" -#include "libANGLE/Error.h" -#include "libANGLE/RefCountObject.h" - -#include "common/angleutils.h" - #include #include -#include +#include #include #include -#include +#include + +#include "common/angleutils.h" +#include "common/mathutil.h" +#include "common/Optional.h" + +#include "libANGLE/angletypes.h" +#include "libANGLE/Constants.h" +#include "libANGLE/Debug.h" +#include "libANGLE/Error.h" +#include "libANGLE/RefCountObject.h" namespace rx { -class Renderer; -class Renderer; -struct TranslatedAttribute; +class ImplFactory; class ProgramImpl; +struct TranslatedAttribute; } namespace gl @@ -68,11 +70,65 @@ class InfoLog : angle::NonCopyable ~InfoLog(); size_t getLength() const; - void getLog(GLsizei bufSize, GLsizei *length, char *infoLog); + void getLog(GLsizei bufSize, GLsizei *length, char *infoLog) const; void appendSanitized(const char *message); - void append(const char *info, ...); 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) << 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) + { + StreamHelper helper(&mStream); + helper << value; + return helper; + } + + std::string str() const { return mStream.str(); } + private: std::stringstream mStream; }; @@ -88,32 +144,94 @@ struct VariableLocation unsigned int index; }; -struct LinkedVarying -{ - LinkedVarying(); - LinkedVarying(const std::string &name, GLenum type, GLsizei size, const std::string &semanticName, - unsigned int semanticIndex, unsigned int semanticIndexCount); - - // Original GL name - std::string name; - - GLenum type; - GLsizei size; - - // DirectX semantic information - std::string semanticName; - unsigned int semanticIndex; - unsigned int semanticIndexCount; -}; - -class Program : angle::NonCopyable +class Program final : angle::NonCopyable, public LabeledObject { public: - Program(rx::ProgramImpl *impl, ResourceManager *manager, GLuint handle); + class Data final : angle::NonCopyable + { + public: + Data(); + ~Data(); + + const std::string &getLabel(); + + const Shader *getAttachedVertexShader() const { return mAttachedVertexShader; } + const Shader *getAttachedFragmentShader() const { return mAttachedFragmentShader; } + const std::vector &getTransformFeedbackVaryingNames() const + { + return mTransformFeedbackVaryingNames; + } + GLint getTransformFeedbackBufferMode() const { return mTransformFeedbackBufferMode; } + GLuint getUniformBlockBinding(GLuint uniformBlockIndex) const + { + ASSERT(uniformBlockIndex < IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS); + return mUniformBlockBindings[uniformBlockIndex]; + } + const UniformBlockBindingMask &getActiveUniformBlockBindingsMask() const + { + return mActiveUniformBlockBindings; + } + const std::vector &getAttributes() const { return mAttributes; } + const AttributesMask &getActiveAttribLocationsMask() const + { + return mActiveAttribLocationsMask; + } + const std::map &getOutputVariables() const + { + return mOutputVariables; + } + const std::vector &getUniforms() const { return mUniforms; } + const std::vector &getUniformLocations() const + { + return mUniformLocations; + } + const std::vector &getUniformBlocks() const { return mUniformBlocks; } + + const LinkedUniform *getUniformByName(const std::string &name) const; + GLint getUniformLocation(const std::string &name) const; + GLuint getUniformIndex(const std::string &name) const; + + private: + friend class Program; + + std::string mLabel; + + Shader *mAttachedFragmentShader; + Shader *mAttachedVertexShader; + + std::vector mTransformFeedbackVaryingNames; + std::vector mTransformFeedbackVaryingVars; + GLenum mTransformFeedbackBufferMode; + + GLuint mUniformBlockBindings[IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS]; + UniformBlockBindingMask mActiveUniformBlockBindings; + + std::vector mAttributes; + std::bitset mActiveAttribLocationsMask; + + // Uniforms are sorted in order: + // 1. Non-sampler uniforms + // 2. Sampler uniforms + // 3. Uniform block uniforms + // This makes sampler validation easier, since we don't need a separate list. + std::vector mUniforms; + std::vector mUniformLocations; + std::vector mUniformBlocks; + + // TODO(jmadill): use unordered/hash map when available + std::map mOutputVariables; + + bool mBinaryRetrieveableHint; + }; + + Program(rx::ImplFactory *factory, ResourceManager *manager, GLuint handle); ~Program(); GLuint id() const { return mHandle; } + void setLabel(const std::string &label) override; + const std::string &getLabel() const override; + rx::ProgramImpl *getImplementation() { return mProgram; } const rx::ProgramImpl *getImplementation() const { return mProgram; } @@ -123,42 +241,43 @@ class Program : angle::NonCopyable void bindAttributeLocation(GLuint index, const char *name); - Error link(const Data &data); - bool isLinked(); + Error link(const gl::Data &data); + bool isLinked() const; Error loadBinary(GLenum binaryFormat, const void *binary, GLsizei length); Error saveBinary(GLenum *binaryFormat, void *binary, GLsizei bufSize, GLsizei *length) const; GLint getBinaryLength() const; + void setBinaryRetrievableHint(bool retrievable); + bool getBinaryRetrievableHint() const; int getInfoLogLength() const; - void getInfoLog(GLsizei bufSize, GLsizei *length, char *infoLog); - void getAttachedShaders(GLsizei maxCount, GLsizei *count, GLuint *shaders); + void getInfoLog(GLsizei bufSize, GLsizei *length, char *infoLog) const; + void getAttachedShaders(GLsizei maxCount, GLsizei *count, GLuint *shaders) const; - GLuint getAttributeLocation(const std::string &name); - int getSemanticIndex(int attributeIndex); - const int *getSemanticIndexes() const; + GLuint getAttributeLocation(const std::string &name) const; + bool isAttribLocationActive(size_t attribLocation) const; void getActiveAttribute(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name); - GLint getActiveAttributeCount(); - GLint getActiveAttributeMaxLength(); - - GLint getSamplerMapping(SamplerType type, unsigned int samplerIndex, const Caps &caps); - GLenum getSamplerTextureType(SamplerType type, unsigned int samplerIndex); - GLint getUsedSamplerRange(SamplerType type); - bool usesPointSize() const; + GLint getActiveAttributeCount() const; + GLint getActiveAttributeMaxLength() const; + const std::vector &getAttributes() const { return mData.mAttributes; } GLint getFragDataLocation(const std::string &name) const; - void getActiveUniform(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name); - GLint getActiveUniformCount(); - GLint getActiveUniformMaxLength(); + void getActiveUniform(GLuint index, + GLsizei bufsize, + GLsizei *length, + GLint *size, + GLenum *type, + GLchar *name) const; + GLint getActiveUniformCount() const; + GLint getActiveUniformMaxLength() const; GLint getActiveUniformi(GLuint index, GLenum pname) const; bool isValidUniformLocation(GLint location) const; - LinkedUniform *getUniformByLocation(GLint location) const; - LinkedUniform *getUniformByName(const std::string &name) const; + const LinkedUniform &getUniformByLocation(GLint location) const; - GLint getUniformLocation(const std::string &name); - GLuint getUniformIndex(const std::string &name); + GLint getUniformLocation(const std::string &name) const; + GLuint getUniformIndex(const std::string &name) const; void setUniform1fv(GLint location, GLsizei count, const GLfloat *v); void setUniform2fv(GLint location, GLsizei count, const GLfloat *v); void setUniform3fv(GLint location, GLsizei count, const GLfloat *v); @@ -181,24 +300,21 @@ class Program : angle::NonCopyable void setUniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); void setUniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); - void getUniformfv(GLint location, GLfloat *params); - void getUniformiv(GLint location, GLint *params); - void getUniformuiv(GLint location, GLuint *params); - - Error applyUniforms(); - Error applyUniformBuffers(const gl::Data &data); + void getUniformfv(GLint location, GLfloat *params) const; + void getUniformiv(GLint location, GLint *params) const; + void getUniformuiv(GLint location, GLuint *params) const; void getActiveUniformBlockName(GLuint uniformBlockIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformBlockName) const; void getActiveUniformBlockiv(GLuint uniformBlockIndex, GLenum pname, GLint *params) const; - GLuint getActiveUniformBlockCount(); - GLint getActiveUniformBlockMaxLength(); + GLuint getActiveUniformBlockCount() const; + GLint getActiveUniformBlockMaxLength() const; - GLuint getUniformBlockIndex(const std::string &name); + GLuint getUniformBlockIndex(const std::string &name) const; void bindUniformBlock(GLuint uniformBlockIndex, GLuint uniformBlockBinding); GLuint getUniformBlockBinding(GLuint uniformBlockIndex) const; - const UniformBlock *getUniformBlockByIndex(GLuint index) const; + const UniformBlock &getUniformBlockByIndex(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; @@ -206,7 +322,6 @@ class Program : angle::NonCopyable GLsizei getTransformFeedbackVaryingMaxLength() const; GLenum getTransformFeedbackBufferMode() const; - static bool linkVaryings(InfoLog &infoLog, Shader *fragmentShader, Shader *vertexShader); static bool linkValidateUniforms(InfoLog &infoLog, const std::string &uniformName, const sh::Uniform &vertexUniform, const sh::Uniform &fragmentUniform); static bool linkValidateInterfaceBlockFields(InfoLog &infoLog, const std::string &uniformName, const sh::InterfaceBlockField &vertexUniform, const sh::InterfaceBlockField &fragmentUniform); @@ -219,17 +334,26 @@ class Program : angle::NonCopyable void validate(const Caps &caps); bool validateSamplers(InfoLog *infoLog, const Caps &caps); bool isValidated() const; - void updateSamplerMapping(); + + const AttributesMask &getActiveAttribLocationsMask() const + { + return mData.mActiveAttribLocationsMask; + } private: void unlink(bool destroy = false); void resetUniformBlockBindings(); - bool linkAttributes(const Data &data, + bool linkAttributes(const gl::Data &data, InfoLog &infoLog, const AttributeBindings &attributeBindings, const Shader *vertexShader); - bool linkUniformBlocks(InfoLog &infoLog, const Shader &vertexShader, const Shader &fragmentShader, const Caps &caps); + bool linkUniformBlocks(InfoLog &infoLog, const Caps &caps); + static bool linkVaryings(InfoLog &infoLog, + const Shader *vertexShader, + const Shader *fragmentShader); + bool linkUniforms(gl::InfoLog &infoLog, const gl::Caps &caps); + void indexUniforms(); bool areMatchingInterfaceBlocks(gl::InfoLog &infoLog, const sh::InterfaceBlock &vertexInterfaceBlock, const sh::InterfaceBlock &fragmentInterfaceBlock); @@ -240,31 +364,63 @@ class Program : angle::NonCopyable bool validatePrecision); static bool linkValidateVaryings(InfoLog &infoLog, const std::string &varyingName, const sh::Varying &vertexVarying, const sh::Varying &fragmentVarying); - bool gatherTransformFeedbackLinkedVaryings(InfoLog &infoLog, const std::vector &linkedVaryings, - const std::vector &transformFeedbackVaryingNames, - GLenum transformFeedbackBufferMode, - std::vector *outTransformFeedbackLinkedVaryings, - const Caps &caps) const; + bool linkValidateTransformFeedback(InfoLog &infoLog, + const std::vector &linkedVaryings, + const Caps &caps) const; + + void gatherTransformFeedbackVaryings(const std::vector &varyings); bool assignUniformBlockRegister(InfoLog &infoLog, UniformBlock *uniformBlock, GLenum shader, unsigned int registerIndex, const Caps &caps); void defineOutputVariables(Shader *fragmentShader); - rx::ProgramImpl *mProgram; + std::vector getMergedVaryings() const; + void linkOutputVariables(); - sh::Attribute mLinkedAttribute[MAX_VERTEX_ATTRIBS]; + bool flattenUniformsAndCheckCaps(const Caps &caps, InfoLog &infoLog); - std::map mOutputVariables; + struct VectorAndSamplerCount + { + VectorAndSamplerCount() : vectorCount(0), samplerCount(0) {} + VectorAndSamplerCount(const VectorAndSamplerCount &other) = default; + VectorAndSamplerCount &operator=(const VectorAndSamplerCount &other) = default; - bool mValidated; + VectorAndSamplerCount &operator+=(const VectorAndSamplerCount &other) + { + vectorCount += other.vectorCount; + samplerCount += other.samplerCount; + return *this; + } - Shader *mFragmentShader; - Shader *mVertexShader; + unsigned int vectorCount; + unsigned int samplerCount; + }; - AttributeBindings mAttributeBindings; + VectorAndSamplerCount flattenUniform(const sh::ShaderVariable &uniform, + const std::string &fullName, + std::vector *samplerUniforms); + + void gatherInterfaceBlockInfo(); + template + void defineUniformBlockMembers(const std::vector &fields, + const std::string &prefix, + int blockIndex); + + void defineUniformBlock(const sh::InterfaceBlock &interfaceBlock, GLenum shaderType); - GLuint mUniformBlockBindings[IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS]; + template + void setUniformInternal(GLint location, GLsizei count, const T *v); - std::vector mTransformFeedbackVaryings; - GLenum mTransformFeedbackBufferMode; + template + void setMatrixUniformInternal(GLint location, GLsizei count, GLboolean transpose, const T *v); + + template + void getUniformInternal(GLint location, DestT *dataOut) const; + + Data mData; + rx::ProgramImpl *mProgram; + + bool mValidated; + + AttributeBindings mAttributeBindings; bool mLinked; bool mDeleteStatus; // Flag to indicate that the program can be deleted when no longer in use @@ -275,6 +431,11 @@ class Program : angle::NonCopyable const GLuint mHandle; InfoLog mInfoLog; + + // Cache for sampler validation + Optional mCachedValidateSamplersResult; + std::vector mTextureUnitTypesCache; + RangeUI mSamplerUniformRange; }; } diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/Program_unittest.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/Program_unittest.cpp new file mode 100644 index 000000000000..78b9a80d0940 --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/libANGLE/Program_unittest.cpp @@ -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. +// +// Unit tests for Program and related classes. +// + +#include + +#include "tests/angle_unittests_utils.h" +#include "libANGLE/Program.h" + +using namespace gl; + +namespace +{ + +// Tests that the log length properly counts the terminating \0. +TEST(InfoLogTest, LogLengthCountsTerminator) +{ + InfoLog infoLog; + EXPECT_EQ(0u, infoLog.getLength()); + infoLog << " "; + + // " \n\0" = 3 characters + EXPECT_EQ(3u, infoLog.getLength()); +} + +// Tests that newlines get appended to the info log properly. +TEST(InfoLogTest, AppendingNewline) +{ + InfoLog infoLog; + + infoLog << "First" << 1 << 'x'; + infoLog << "Second" << 2 << 'y'; + + std::string expected = "First1x\nSecond2y\n"; + + EXPECT_EQ(expected, infoLog.str()); +} + +} // namespace diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/Query.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/Query.cpp index a402b732bfad..cd1fb5f4bc7d 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/Query.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/Query.cpp @@ -11,9 +11,7 @@ namespace gl { -Query::Query(rx::QueryImpl *impl, GLuint id) - : RefCountObject(id), - mQuery(impl) +Query::Query(rx::QueryImpl *impl, GLuint id) : RefCountObject(id), mQuery(impl), mLabel() { } @@ -22,6 +20,16 @@ Query::~Query() SafeDelete(mQuery); } +void Query::setLabel(const std::string &label) +{ + mLabel = label; +} + +const std::string &Query::getLabel() const +{ + return mLabel; +} + Error Query::begin() { return mQuery->begin(); @@ -32,12 +40,32 @@ Error Query::end() return mQuery->end(); } +Error Query::queryCounter() +{ + return mQuery->queryCounter(); +} + +Error Query::getResult(GLint *params) +{ + return mQuery->getResult(params); +} + Error Query::getResult(GLuint *params) { return mQuery->getResult(params); } -Error Query::isResultAvailable(GLuint *available) +Error Query::getResult(GLint64 *params) +{ + return mQuery->getResult(params); +} + +Error Query::getResult(GLuint64 *params) +{ + return mQuery->getResult(params); +} + +Error Query::isResultAvailable(bool *available) { return mQuery->isResultAvailable(available); } @@ -47,4 +75,13 @@ GLenum Query::getType() const return mQuery->getType(); } +rx::QueryImpl *Query::getImplementation() +{ + return mQuery; +} + +const rx::QueryImpl *Query::getImplementation() const +{ + return mQuery; +} } diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/Query.h b/Source/ThirdParty/ANGLE/src/libANGLE/Query.h index 8585fde0e22f..5486f983e756 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/Query.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/Query.h @@ -9,6 +9,7 @@ #ifndef LIBANGLE_QUERY_H_ #define LIBANGLE_QUERY_H_ +#include "libANGLE/Debug.h" #include "libANGLE/Error.h" #include "libANGLE/RefCountObject.h" @@ -24,22 +25,33 @@ class QueryImpl; namespace gl { -class Query : public RefCountObject +class Query final : public RefCountObject, public LabeledObject { public: Query(rx::QueryImpl *impl, GLuint id); virtual ~Query(); + void setLabel(const std::string &label) override; + const std::string &getLabel() const override; + Error begin(); Error end(); - + Error queryCounter(); + Error getResult(GLint *params); Error getResult(GLuint *params); - Error isResultAvailable(GLuint *available); + Error getResult(GLint64 *params); + Error getResult(GLuint64 *params); + Error isResultAvailable(bool *available); GLenum getType() const; + rx::QueryImpl *getImplementation(); + const rx::QueryImpl *getImplementation() const; + private: rx::QueryImpl *mQuery; + + std::string mLabel; }; } diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/RefCountObject.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/RefCountObject.cpp deleted file mode 100644 index b1210200cf99..000000000000 --- a/Source/ThirdParty/ANGLE/src/libANGLE/RefCountObject.cpp +++ /dev/null @@ -1,39 +0,0 @@ -// -// Copyright (c) 2002-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. -// - -// RefCountObject.cpp: 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.) - -#include "RefCountObject.h" - -RefCountObject::RefCountObject(GLuint id) - : mId(id), - mRefCount(0) -{ -} - -RefCountObject::~RefCountObject() -{ - ASSERT(mRefCount == 0); -} - -void RefCountObject::addRef() const -{ - mRefCount++; -} - -void RefCountObject::release() const -{ - ASSERT(mRefCount > 0); - - if (--mRefCount == 0) - { - delete this; - } -} - diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/RefCountObject.h b/Source/ThirdParty/ANGLE/src/libANGLE/RefCountObject.h index 8c3a4021fa6f..86e6d788b51e 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/RefCountObject.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/RefCountObject.h @@ -21,14 +21,27 @@ class RefCountObject : angle::NonCopyable { public: - explicit RefCountObject(GLuint id); - virtual ~RefCountObject(); + explicit RefCountObject(GLuint id) : mId(id), mRefCount(0) {} - virtual void addRef() const; - virtual void release() const; + void addRef() const { ++mRefCount; } + + void release() const + { + ASSERT(mRefCount > 0); + + if (--mRefCount == 0) + { + delete this; + } + } GLuint id() const { return mId; } + size_t getRefCount() const { return mRefCount; } + + protected: + virtual ~RefCountObject() { ASSERT(mRefCount == 0); } + private: GLuint mId; @@ -38,7 +51,7 @@ class RefCountObject : angle::NonCopyable template class BindingPointer { -public: + public: BindingPointer() : mObject(nullptr) { @@ -74,6 +87,13 @@ class BindingPointer GLuint id() const { return (mObject != nullptr) ? mObject->id() : 0; } + bool operator==(const BindingPointer &other) const + { + return mObject == other.mObject; + } + + bool operator!=(const BindingPointer &other) const { return !(*this == other); } + private: ObjectType *mObject; }; @@ -101,6 +121,16 @@ class OffsetBindingPointer : public BindingPointer 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); + } + private: GLintptr mOffset; GLsizeiptr mSize; diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/Renderbuffer.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/Renderbuffer.cpp index 34cc365d219d..161fbea797bc 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/Renderbuffer.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/Renderbuffer.cpp @@ -12,20 +12,21 @@ #include "common/utilities.h" #include "libANGLE/FramebufferAttachment.h" +#include "libANGLE/Image.h" #include "libANGLE/Texture.h" #include "libANGLE/formatutils.h" #include "libANGLE/renderer/d3d/RenderTargetD3D.h" namespace gl { - Renderbuffer::Renderbuffer(rx::RenderbufferImpl *impl, GLuint id) - : FramebufferAttachmentObject(id), - mRenderbuffer(impl), - mWidth(0), - mHeight(0), - mInternalFormat(GL_RGBA4), - mSamples(0) + : egl::ImageSibling(id), + mRenderbuffer(impl), + mLabel(), + mWidth(0), + mHeight(0), + mInternalFormat(GL_RGBA4), + mSamples(0) { } @@ -34,16 +35,28 @@ Renderbuffer::~Renderbuffer() SafeDelete(mRenderbuffer); } +void Renderbuffer::setLabel(const std::string &label) +{ + mLabel = label; +} + +const std::string &Renderbuffer::getLabel() const +{ + return mLabel; +} + Error Renderbuffer::setStorage(GLenum internalformat, size_t width, size_t height) { + orphanImages(); + Error error = mRenderbuffer->setStorage(internalformat, width, height); if (error.isError()) { return error; } - mWidth = static_cast(width); - mHeight = static_cast(height); + mWidth = static_cast(width); + mHeight = static_cast(height); mInternalFormat = internalformat; mSamples = 0; @@ -52,16 +65,38 @@ Error Renderbuffer::setStorage(GLenum internalformat, size_t width, size_t heigh Error Renderbuffer::setStorageMultisample(size_t samples, GLenum internalformat, size_t width, size_t height) { + orphanImages(); + Error error = mRenderbuffer->setStorageMultisample(samples, internalformat, width, height); if (error.isError()) { return error; } - mWidth = static_cast(width); - mHeight = static_cast(height); + mWidth = static_cast(width); + mHeight = static_cast(height); mInternalFormat = internalformat; - mSamples = static_cast(samples); + mSamples = static_cast(samples); + + return Error(GL_NO_ERROR); +} + +Error Renderbuffer::setStorageEGLImageTarget(egl::Image *image) +{ + orphanImages(); + + Error error = mRenderbuffer->setStorageEGLImageTarget(image); + if (error.isError()) + { + return error; + } + + setTargetImage(image); + + mWidth = static_cast(image->getWidth()); + mHeight = static_cast(image->getHeight()); + mInternalFormat = image->getInternalFormat(); + mSamples = 0; return Error(GL_NO_ERROR); } @@ -127,4 +162,23 @@ GLuint Renderbuffer::getStencilSize() const return GetInternalFormatInfo(mInternalFormat).stencilBits; } +void Renderbuffer::onAttach() +{ + addRef(); +} + +void Renderbuffer::onDetach() +{ + release(); +} + +GLuint Renderbuffer::getId() const +{ + return id(); +} + +Extents Renderbuffer::getAttachmentSize(const FramebufferAttachment::Target & /*target*/) const +{ + return Extents(mWidth, mHeight, 1); +} } diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/Renderbuffer.h b/Source/ThirdParty/ANGLE/src/libANGLE/Renderbuffer.h index 7356fb233369..04af03e879d7 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/Renderbuffer.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/Renderbuffer.h @@ -13,8 +13,10 @@ #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/renderer/RenderbufferImpl.h" namespace gl @@ -24,14 +26,20 @@ namespace gl // FramebufferAttachment and Framebuffer for how they are applied to an FBO via an // attachment point. -class Renderbuffer : public FramebufferAttachmentObject +class Renderbuffer final : public egl::ImageSibling, + public gl::FramebufferAttachmentObject, + public LabeledObject { public: Renderbuffer(rx::RenderbufferImpl *impl, GLuint id); virtual ~Renderbuffer(); + void setLabel(const std::string &label) override; + const std::string &getLabel() const override; + Error setStorage(GLenum internalformat, size_t width, size_t height); Error setStorageMultisample(size_t samples, GLenum internalformat, size_t width, size_t height); + Error setStorageEGLImageTarget(egl::Image *imageTarget); rx::RenderbufferImpl *getImplementation(); const rx::RenderbufferImpl *getImplementation() const; @@ -48,16 +56,21 @@ class Renderbuffer : public FramebufferAttachmentObject GLuint getStencilSize() const; // FramebufferAttachmentObject Impl - GLsizei getAttachmentWidth(const FramebufferAttachment::Target &/*target*/) const override { return getWidth(); } - GLsizei getAttachmentHeight(const FramebufferAttachment::Target &/*target*/) const override { return getHeight(); } + Extents getAttachmentSize(const FramebufferAttachment::Target &target) const override; GLenum getAttachmentInternalFormat(const FramebufferAttachment::Target &/*target*/) const override { return getInternalFormat(); } GLsizei getAttachmentSamples(const FramebufferAttachment::Target &/*target*/) const override { return getSamples(); } + void onAttach() override; + void onDetach() override; + GLuint getId() const override; + private: rx::FramebufferAttachmentObjectImpl *getAttachmentImpl() const override { return mRenderbuffer; } rx::RenderbufferImpl *mRenderbuffer; + std::string mLabel; + GLsizei mWidth; GLsizei mHeight; GLenum mInternalFormat; diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/ResourceManager.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/ResourceManager.cpp index aaf144cfa922..3872d39f9b6b 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/ResourceManager.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/ResourceManager.cpp @@ -82,19 +82,19 @@ GLuint ResourceManager::createBuffer() { GLuint handle = mBufferHandleAllocator.allocate(); - mBufferMap[handle] = NULL; + mBufferMap[handle] = nullptr; return handle; } // Returns an unused shader/program name -GLuint ResourceManager::createShader(const gl::Data &data, GLenum type) +GLuint ResourceManager::createShader(const gl::Limitations &rendererLimitations, GLenum type) { GLuint handle = mProgramShaderHandleAllocator.allocate(); if (type == GL_VERTEX_SHADER || type == GL_FRAGMENT_SHADER) { - mShaderMap[handle] = new Shader(this, mFactory->createShader(type), type, handle); + mShaderMap[handle] = new Shader(this, mFactory, rendererLimitations, type, handle); } else UNREACHABLE(); @@ -106,7 +106,7 @@ GLuint ResourceManager::createProgram() { GLuint handle = mProgramShaderHandleAllocator.allocate(); - mProgramMap[handle] = new Program(mFactory->createProgram(), this, handle); + mProgramMap[handle] = new Program(mFactory, this, handle); return handle; } @@ -116,7 +116,7 @@ GLuint ResourceManager::createTexture() { GLuint handle = mTextureHandleAllocator.allocate(); - mTextureMap[handle] = NULL; + mTextureMap[handle] = nullptr; return handle; } @@ -126,7 +126,7 @@ GLuint ResourceManager::createRenderbuffer() { GLuint handle = mRenderbufferHandleAllocator.allocate(); - mRenderbufferMap[handle] = NULL; + mRenderbufferMap[handle] = nullptr; return handle; } @@ -136,7 +136,7 @@ GLuint ResourceManager::createSampler() { GLuint handle = mSamplerHandleAllocator.allocate(); - mSamplerMap[handle] = NULL; + mSamplerMap[handle] = nullptr; return handle; } @@ -155,7 +155,7 @@ GLuint ResourceManager::createFenceSync() void ResourceManager::deleteBuffer(GLuint buffer) { - BufferMap::iterator bufferObject = mBufferMap.find(buffer); + auto bufferObject = mBufferMap.find(buffer); if (bufferObject != mBufferMap.end()) { @@ -167,7 +167,7 @@ void ResourceManager::deleteBuffer(GLuint buffer) void ResourceManager::deleteShader(GLuint shader) { - ShaderMap::iterator shaderObject = mShaderMap.find(shader); + auto shaderObject = mShaderMap.find(shader); if (shaderObject != mShaderMap.end()) { @@ -186,7 +186,7 @@ void ResourceManager::deleteShader(GLuint shader) void ResourceManager::deleteProgram(GLuint program) { - ProgramMap::iterator programObject = mProgramMap.find(program); + auto programObject = mProgramMap.find(program); if (programObject != mProgramMap.end()) { @@ -205,7 +205,7 @@ void ResourceManager::deleteProgram(GLuint program) void ResourceManager::deleteTexture(GLuint texture) { - TextureMap::iterator textureObject = mTextureMap.find(texture); + auto textureObject = mTextureMap.find(texture); if (textureObject != mTextureMap.end()) { @@ -217,7 +217,7 @@ void ResourceManager::deleteTexture(GLuint texture) void ResourceManager::deleteRenderbuffer(GLuint renderbuffer) { - RenderbufferMap::iterator renderbufferObject = mRenderbufferMap.find(renderbuffer); + auto renderbufferObject = mRenderbufferMap.find(renderbuffer); if (renderbufferObject != mRenderbufferMap.end()) { @@ -253,11 +253,11 @@ void ResourceManager::deleteFenceSync(GLuint fenceSync) Buffer *ResourceManager::getBuffer(unsigned int handle) { - BufferMap::iterator buffer = mBufferMap.find(handle); + auto buffer = mBufferMap.find(handle); if (buffer == mBufferMap.end()) { - return NULL; + return nullptr; } else { @@ -267,11 +267,11 @@ Buffer *ResourceManager::getBuffer(unsigned int handle) Shader *ResourceManager::getShader(unsigned int handle) { - ShaderMap::iterator shader = mShaderMap.find(handle); + auto shader = mShaderMap.find(handle); if (shader == mShaderMap.end()) { - return NULL; + return nullptr; } else { @@ -281,13 +281,14 @@ Shader *ResourceManager::getShader(unsigned int handle) Texture *ResourceManager::getTexture(unsigned int handle) { - if (handle == 0) return NULL; + if (handle == 0) + return nullptr; - TextureMap::iterator texture = mTextureMap.find(handle); + auto texture = mTextureMap.find(handle); if (texture == mTextureMap.end()) { - return NULL; + return nullptr; } else { @@ -297,11 +298,11 @@ Texture *ResourceManager::getTexture(unsigned int handle) Program *ResourceManager::getProgram(unsigned int handle) const { - ProgramMap::const_iterator program = mProgramMap.find(handle); + auto program = mProgramMap.find(handle); if (program == mProgramMap.end()) { - return NULL; + return nullptr; } else { @@ -311,11 +312,11 @@ Program *ResourceManager::getProgram(unsigned int handle) const Renderbuffer *ResourceManager::getRenderbuffer(unsigned int handle) { - RenderbufferMap::iterator renderbuffer = mRenderbufferMap.find(handle); + auto renderbuffer = mRenderbufferMap.find(handle); if (renderbuffer == mRenderbufferMap.end()) { - return NULL; + return nullptr; } else { @@ -329,7 +330,7 @@ Sampler *ResourceManager::getSampler(unsigned int handle) if (sampler == mSamplerMap.end()) { - return NULL; + return nullptr; } else { @@ -343,7 +344,7 @@ FenceSync *ResourceManager::getFenceSync(unsigned int handle) if (fenceObjectIt == mFenceSyncMap.end()) { - return NULL; + return nullptr; } else { @@ -356,96 +357,117 @@ void ResourceManager::setRenderbuffer(GLuint handle, Renderbuffer *buffer) mRenderbufferMap[handle] = buffer; } -void ResourceManager::checkBufferAllocation(GLuint handle) +Buffer *ResourceManager::checkBufferAllocation(GLuint handle) { - if (handle != 0) + if (handle == 0) { - auto bufferMapIt = mBufferMap.find(handle); - bool handleAllocated = (bufferMapIt != mBufferMap.end()); + return nullptr; + } - if (handleAllocated && bufferMapIt->second != nullptr) - { - return; - } + auto bufferMapIt = mBufferMap.find(handle); + bool handleAllocated = (bufferMapIt != mBufferMap.end()); - Buffer *buffer = new Buffer(mFactory->createBuffer(), handle); - buffer->addRef(); + if (handleAllocated && bufferMapIt->second != nullptr) + { + return bufferMapIt->second; + } - if (handleAllocated) - { - bufferMapIt->second = buffer; - } - else - { - mBufferHandleAllocator.reserve(handle); - mBufferMap[handle] = buffer; - } + Buffer *buffer = new Buffer(mFactory->createBuffer(), handle); + buffer->addRef(); + + if (handleAllocated) + { + bufferMapIt->second = buffer; } + else + { + mBufferHandleAllocator.reserve(handle); + mBufferMap[handle] = buffer; + } + + return buffer; } -void ResourceManager::checkTextureAllocation(GLuint handle, GLenum type) +Texture *ResourceManager::checkTextureAllocation(GLuint handle, GLenum type) { - if (handle != 0) + if (handle == 0) { - auto textureMapIt = mTextureMap.find(handle); - bool handleAllocated = (textureMapIt != mTextureMap.end()); + return nullptr; + } - if (handleAllocated && textureMapIt->second != nullptr) - { - return; - } + auto textureMapIt = mTextureMap.find(handle); + bool handleAllocated = (textureMapIt != mTextureMap.end()); - Texture *texture = new Texture(mFactory->createTexture(type), handle, type); - texture->addRef(); + if (handleAllocated && textureMapIt->second != nullptr) + { + return textureMapIt->second; + } - if (handleAllocated) - { - textureMapIt->second = texture; - } - else - { - mTextureHandleAllocator.reserve(handle); - mTextureMap[handle] = texture; - } + Texture *texture = new Texture(mFactory->createTexture(type), handle, type); + texture->addRef(); + + if (handleAllocated) + { + textureMapIt->second = texture; + } + else + { + mTextureHandleAllocator.reserve(handle); + mTextureMap[handle] = texture; } + + return texture; } -void ResourceManager::checkRenderbufferAllocation(GLuint handle) +Renderbuffer *ResourceManager::checkRenderbufferAllocation(GLuint handle) { - if (handle != 0) + if (handle == 0) { - auto renderbufferMapIt = mRenderbufferMap.find(handle); - bool handleAllocated = (renderbufferMapIt != mRenderbufferMap.end()); + return nullptr; + } - if (handleAllocated && renderbufferMapIt->second != nullptr) - { - return; - } + auto renderbufferMapIt = mRenderbufferMap.find(handle); + bool handleAllocated = (renderbufferMapIt != mRenderbufferMap.end()); - Renderbuffer *renderbuffer = new Renderbuffer(mFactory->createRenderbuffer(), handle); - renderbuffer->addRef(); + if (handleAllocated && renderbufferMapIt->second != nullptr) + { + return renderbufferMapIt->second; + } - if (handleAllocated) - { - renderbufferMapIt->second = renderbuffer; - } - else - { - mRenderbufferHandleAllocator.reserve(handle); - mRenderbufferMap[handle] = renderbuffer; - } + Renderbuffer *renderbuffer = new Renderbuffer(mFactory->createRenderbuffer(), handle); + renderbuffer->addRef(); + + if (handleAllocated) + { + renderbufferMapIt->second = renderbuffer; } + else + { + mRenderbufferHandleAllocator.reserve(handle); + mRenderbufferMap[handle] = renderbuffer; + } + + return renderbuffer; } -void ResourceManager::checkSamplerAllocation(GLuint sampler) +Sampler *ResourceManager::checkSamplerAllocation(GLuint samplerHandle) { - if (sampler != 0 && !getSampler(sampler)) + // Samplers cannot be created via Bind + if (samplerHandle == 0) { - Sampler *samplerObject = new Sampler(sampler); - mSamplerMap[sampler] = samplerObject; - samplerObject->addRef(); - // Samplers cannot be created via Bind + return nullptr; } + + Sampler *sampler = getSampler(samplerHandle); + + if (!sampler) + { + sampler = new Sampler(mFactory, samplerHandle); + mSamplerMap[samplerHandle] = sampler; + sampler->addRef(); + } + + return sampler; } bool ResourceManager::isSampler(GLuint sampler) @@ -453,4 +475,4 @@ bool ResourceManager::isSampler(GLuint sampler) return mSamplerMap.find(sampler) != mSamplerMap.end(); } -} +} // namespace gl diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/ResourceManager.h b/Source/ThirdParty/ANGLE/src/libANGLE/ResourceManager.h index 8e95e8840adc..4845e3980489 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/ResourceManager.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/ResourceManager.h @@ -15,8 +15,6 @@ #include "libANGLE/angletypes.h" #include "libANGLE/HandleAllocator.h" -#include - namespace rx { class ImplFactory; @@ -25,13 +23,14 @@ class ImplFactory; namespace gl { class Buffer; -class Shader; +struct Data; +class FenceSync; +struct Limitations; class Program; -class Texture; class Renderbuffer; class Sampler; -class FenceSync; -struct Data; +class Shader; +class Texture; class ResourceManager : angle::NonCopyable { @@ -43,7 +42,7 @@ class ResourceManager : angle::NonCopyable void release(); GLuint createBuffer(); - GLuint createShader(const gl::Data &data, GLenum type); + GLuint createShader(const gl::Limitations &rendererLimitations, GLenum type); GLuint createProgram(); GLuint createTexture(); GLuint createRenderbuffer(); @@ -68,10 +67,10 @@ class ResourceManager : angle::NonCopyable void setRenderbuffer(GLuint handle, Renderbuffer *renderbuffer); - void checkBufferAllocation(GLuint handle); - void checkTextureAllocation(GLuint handle, GLenum type); - void checkRenderbufferAllocation(GLuint handle); - void checkSamplerAllocation(GLuint sampler); + Buffer *checkBufferAllocation(GLuint handle); + Texture *checkTextureAllocation(GLuint handle, GLenum type); + Renderbuffer *checkRenderbufferAllocation(GLuint handle); + Sampler *checkSamplerAllocation(GLuint samplerHandle); bool isSampler(GLuint sampler); @@ -81,34 +80,27 @@ class ResourceManager : angle::NonCopyable rx::ImplFactory *mFactory; std::size_t mRefCount; - typedef std::map BufferMap; - BufferMap mBufferMap; + ResourceMap mBufferMap; HandleAllocator mBufferHandleAllocator; - typedef std::map ShaderMap; - ShaderMap mShaderMap; + ResourceMap mShaderMap; - typedef std::map ProgramMap; - ProgramMap mProgramMap; + ResourceMap mProgramMap; HandleAllocator mProgramShaderHandleAllocator; - typedef std::map TextureMap; - TextureMap mTextureMap; + ResourceMap mTextureMap; HandleAllocator mTextureHandleAllocator; - typedef std::map RenderbufferMap; - RenderbufferMap mRenderbufferMap; + ResourceMap mRenderbufferMap; HandleAllocator mRenderbufferHandleAllocator; - typedef std::map SamplerMap; - SamplerMap mSamplerMap; + ResourceMap mSamplerMap; HandleAllocator mSamplerHandleAllocator; - typedef std::map FenceMap; - FenceMap mFenceSyncMap; + ResourceMap mFenceSyncMap; HandleAllocator mFenceSyncHandleAllocator; }; -} +} // namespace gl #endif // LIBANGLE_RESOURCEMANAGER_H_ diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/ResourceManager_unittest.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/ResourceManager_unittest.cpp index 589bda9f9c7c..d6ddeaf86af7 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/ResourceManager_unittest.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/ResourceManager_unittest.cpp @@ -9,7 +9,7 @@ #include #include -#include "angle_unittests_utils.h" +#include "tests/angle_unittests_utils.h" #include "libANGLE/ResourceManager.h" using namespace rx; diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/Sampler.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/Sampler.cpp index d58bd5a86246..d8d606a46f66 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/Sampler.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/Sampler.cpp @@ -9,35 +9,144 @@ #include "libANGLE/Sampler.h" #include "libANGLE/angletypes.h" +#include "libANGLE/renderer/ImplFactory.h" +#include "libANGLE/renderer/SamplerImpl.h" namespace gl { -Sampler::Sampler(GLuint id) - : RefCountObject(id), - mMinFilter(GL_NEAREST_MIPMAP_LINEAR), - mMagFilter(GL_LINEAR), - mWrapS(GL_REPEAT), - mWrapT(GL_REPEAT), - mWrapR(GL_REPEAT), - mMinLod(-1000.0f), - mMaxLod(1000.0f), - mComparisonMode(GL_NONE), - mComparisonFunc(GL_LEQUAL) +Sampler::Sampler(rx::ImplFactory *factory, GLuint id) + : RefCountObject(id), mImpl(factory->createSampler()), mLabel(), mSamplerState() { } -void Sampler::getState(SamplerState *samplerState) const +Sampler::~Sampler() { - samplerState->minFilter = mMinFilter; - samplerState->magFilter = mMagFilter; - samplerState->wrapS = mWrapS; - samplerState->wrapT = mWrapT; - samplerState->wrapR = mWrapR; - samplerState->minLod = mMinLod; - samplerState->maxLod = mMaxLod; - samplerState->compareMode = mComparisonMode; - samplerState->compareFunc = mComparisonFunc; + SafeDelete(mImpl); } +void Sampler::setLabel(const std::string &label) +{ + mLabel = label; +} + +const std::string &Sampler::getLabel() const +{ + return mLabel; +} + +void Sampler::setMinFilter(GLenum minFilter) +{ + mSamplerState.minFilter = minFilter; +} + +GLenum Sampler::getMinFilter() const +{ + return mSamplerState.minFilter; +} + +void Sampler::setMagFilter(GLenum magFilter) +{ + mSamplerState.magFilter = magFilter; +} + +GLenum Sampler::getMagFilter() const +{ + return mSamplerState.magFilter; +} + +void Sampler::setWrapS(GLenum wrapS) +{ + mSamplerState.wrapS = wrapS; +} + +GLenum Sampler::getWrapS() const +{ + return mSamplerState.wrapS; +} + +void Sampler::setWrapT(GLenum wrapT) +{ + mSamplerState.wrapT = wrapT; +} + +GLenum Sampler::getWrapT() const +{ + return mSamplerState.wrapT; +} + +void Sampler::setWrapR(GLenum wrapR) +{ + mSamplerState.wrapR = wrapR; +} + +GLenum Sampler::getWrapR() const +{ + return mSamplerState.wrapR; +} + +void Sampler::setMaxAnisotropy(float maxAnisotropy) +{ + mSamplerState.maxAnisotropy = maxAnisotropy; +} + +float Sampler::getMaxAnisotropy() const +{ + return mSamplerState.maxAnisotropy; +} + +void Sampler::setMinLod(GLfloat minLod) +{ + mSamplerState.minLod = minLod; +} + +GLfloat Sampler::getMinLod() const +{ + return mSamplerState.minLod; +} + +void Sampler::setMaxLod(GLfloat maxLod) +{ + mSamplerState.maxLod = maxLod; +} + +GLfloat Sampler::getMaxLod() const +{ + return mSamplerState.maxLod; +} + +void Sampler::setCompareMode(GLenum compareMode) +{ + mSamplerState.compareMode = compareMode; +} + +GLenum Sampler::getCompareMode() const +{ + return mSamplerState.compareMode; +} + +void Sampler::setCompareFunc(GLenum compareFunc) +{ + mSamplerState.compareFunc = compareFunc; +} + +GLenum Sampler::getCompareFunc() const +{ + return mSamplerState.compareFunc; +} + +const SamplerState &Sampler::getSamplerState() const +{ + return mSamplerState; +} + +const rx::SamplerImpl *Sampler::getImplementation() const +{ + return mImpl; +} + +rx::SamplerImpl *Sampler::getImplementation() +{ + return mImpl; +} } diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/Sampler.h b/Source/ThirdParty/ANGLE/src/libANGLE/Sampler.h index d33798ff1553..a40b1655fc41 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/Sampler.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/Sampler.h @@ -10,49 +10,69 @@ #ifndef LIBANGLE_SAMPLER_H_ #define LIBANGLE_SAMPLER_H_ +#include "libANGLE/angletypes.h" +#include "libANGLE/Debug.h" #include "libANGLE/RefCountObject.h" +namespace rx +{ +class ImplFactory; +class SamplerImpl; +} + namespace gl { -struct SamplerState; -class Sampler : public RefCountObject +class Sampler final : public RefCountObject, public LabeledObject { public: - Sampler(GLuint id); - - void setMinFilter(GLenum minFilter) { mMinFilter = minFilter; } - void setMagFilter(GLenum magFilter) { mMagFilter = magFilter; } - void setWrapS(GLenum wrapS) { mWrapS = wrapS; } - void setWrapT(GLenum wrapT) { mWrapT = wrapT; } - void setWrapR(GLenum wrapR) { mWrapR = wrapR; } - void setMinLod(GLfloat minLod) { mMinLod = minLod; } - void setMaxLod(GLfloat maxLod) { mMaxLod = maxLod; } - void setComparisonMode(GLenum comparisonMode) { mComparisonMode = comparisonMode; } - void setComparisonFunc(GLenum comparisonFunc) { mComparisonFunc = comparisonFunc; } - - GLenum getMinFilter() const { return mMinFilter; } - GLenum getMagFilter() const { return mMagFilter; } - GLenum getWrapS() const { return mWrapS; } - GLenum getWrapT() const { return mWrapT; } - GLenum getWrapR() const { return mWrapR; } - GLfloat getMinLod() const { return mMinLod; } - GLfloat getMaxLod() const { return mMaxLod; } - GLenum getComparisonMode() const { return mComparisonMode; } - GLenum getComparisonFunc() const { return mComparisonFunc; } - - void getState(SamplerState *samplerState) const; + Sampler(rx::ImplFactory *factory, GLuint id); + ~Sampler() override; + + void setLabel(const std::string &label) override; + const std::string &getLabel() const override; + + void setMinFilter(GLenum minFilter); + GLenum getMinFilter() const; + + void setMagFilter(GLenum magFilter); + GLenum getMagFilter() const; + + void setWrapS(GLenum wrapS); + GLenum getWrapS() const; + + void setWrapT(GLenum wrapT); + GLenum getWrapT() const; + + void setWrapR(GLenum wrapR); + GLenum getWrapR() const; + + void setMaxAnisotropy(float maxAnisotropy); + float getMaxAnisotropy() const; + + void setMinLod(GLfloat minLod); + GLfloat getMinLod() const; + + void setMaxLod(GLfloat maxLod); + GLfloat getMaxLod() const; + + void setCompareMode(GLenum compareMode); + GLenum getCompareMode() const; + + void setCompareFunc(GLenum compareFunc); + GLenum getCompareFunc() const; + + const SamplerState &getSamplerState() const; + + const rx::SamplerImpl *getImplementation() const; + rx::SamplerImpl *getImplementation(); private: - GLenum mMinFilter; - GLenum mMagFilter; - GLenum mWrapS; - GLenum mWrapT; - GLenum mWrapR; - GLfloat mMinLod; - GLfloat mMaxLod; - GLenum mComparisonMode; - GLenum mComparisonFunc; + rx::SamplerImpl *mImpl; + + std::string mLabel; + + SamplerState mSamplerState; }; } diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/Shader.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/Shader.cpp index 5106e958cb79..bbe9077fc92b 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/Shader.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/Shader.cpp @@ -9,35 +9,108 @@ // functionality. [OpenGL ES 2.0.24] section 2.10 page 24 and section 3.8 page 84. #include "libANGLE/Shader.h" + +#include + +#include "common/utilities.h" +#include "GLSLANG/ShaderLang.h" +#include "libANGLE/Compiler.h" +#include "libANGLE/Constants.h" #include "libANGLE/renderer/Renderer.h" #include "libANGLE/renderer/ShaderImpl.h" -#include "libANGLE/Constants.h" #include "libANGLE/ResourceManager.h" -#include "common/utilities.h" +namespace gl +{ -#include "GLSLANG/ShaderLang.h" +namespace +{ +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.staticUse) + { + result.push_back(var); + } + } + return result; +} -#include +template +const std::vector &GetShaderVariables(const std::vector *variableList) +{ + ASSERT(variableList); + return *variableList; +} -namespace gl +} // 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.arraySize > y.arraySize; + } -Shader::Shader(ResourceManager *manager, rx::ShaderImpl *impl, GLenum type, GLuint handle) - : mShader(impl), - mType(type), + // Special case for handling structs: we sort these to the end of the list + if (x.type == GL_STRUCT_ANGLEX) + { + return false; + } + + if (y.type == GL_STRUCT_ANGLEX) + { + return true; + } + + return gl::VariableSortOrder(x.type) < gl::VariableSortOrder(y.type); +} + +Shader::Data::Data(GLenum shaderType) : mLabel(), mShaderType(shaderType), mShaderVersion(100) +{ +} + +Shader::Data::~Data() +{ +} + +Shader::Shader(ResourceManager *manager, + rx::ImplFactory *implFactory, + const gl::Limitations &rendererLimitations, + GLenum type, + GLuint handle) + : mData(type), + mImplementation(implFactory->createShader(mData)), + mRendererLimitations(rendererLimitations), mHandle(handle), - mResourceManager(manager), + mType(type), mRefCount(0), mDeleteStatus(false), - mCompiled(false) + mCompiled(false), + mResourceManager(manager) { - ASSERT(impl); + ASSERT(mImplementation); } Shader::~Shader() { - SafeDelete(mShader); + SafeDelete(mImplementation); +} + +void Shader::setLabel(const std::string &label) +{ + mData.mLabel = label; +} + +const std::string &Shader::getLabel() const +{ + return mData.mLabel; } GLuint Shader::getHandle() const @@ -61,12 +134,17 @@ void Shader::setSource(GLsizei count, const char *const *string, const GLint *le } } - mSource = stream.str(); + mData.mSource = stream.str(); } int Shader::getInfoLogLength() const { - return mShader->getInfoLog().empty() ? 0 : static_cast(mShader->getInfoLog().length() + 1); + if (mInfoLog.empty()) + { + return 0; + } + + return (static_cast(mInfoLog.length()) + 1); } void Shader::getInfoLog(GLsizei bufSize, GLsizei *length, char *infoLog) const @@ -75,8 +153,8 @@ void Shader::getInfoLog(GLsizei bufSize, GLsizei *length, char *infoLog) const if (bufSize > 0) { - index = std::min(bufSize - 1, static_cast(mShader->getInfoLog().length())); - memcpy(infoLog, mShader->getInfoLog().c_str(), index); + index = std::min(bufSize - 1, static_cast(mInfoLog.length())); + memcpy(infoLog, mInfoLog.c_str(), index); infoLog[index] = '\0'; } @@ -89,12 +167,28 @@ void Shader::getInfoLog(GLsizei bufSize, GLsizei *length, char *infoLog) const int Shader::getSourceLength() const { - return mSource.empty() ? 0 : static_cast(mSource.length() + 1); + return mData.mSource.empty() ? 0 : (static_cast(mData.mSource.length()) + 1); } int Shader::getTranslatedSourceLength() const { - return mShader->getTranslatedSource().empty() ? 0 : static_cast(mShader->getTranslatedSource().length() + 1); + if (mData.mTranslatedSource.empty()) + { + return 0; + } + + return (static_cast(mData.mTranslatedSource.length()) + 1); +} + +int Shader::getTranslatedSourceWithDebugInfoLength() const +{ + const std::string &debugInfo = mImplementation->getDebugInfo(); + if (debugInfo.empty()) + { + return 0; + } + + return (static_cast(debugInfo.length()) + 1); } void Shader::getSourceImpl(const std::string &source, GLsizei bufSize, GLsizei *length, char *buffer) @@ -117,23 +211,117 @@ void Shader::getSourceImpl(const std::string &source, GLsizei bufSize, GLsizei * void Shader::getSource(GLsizei bufSize, GLsizei *length, char *buffer) const { - getSourceImpl(mSource, bufSize, length, buffer); + getSourceImpl(mData.mSource, bufSize, length, buffer); } void Shader::getTranslatedSource(GLsizei bufSize, GLsizei *length, char *buffer) const { - getSourceImpl(mShader->getTranslatedSource(), bufSize, length, buffer); + getSourceImpl(mData.mTranslatedSource, bufSize, length, buffer); } void Shader::getTranslatedSourceWithDebugInfo(GLsizei bufSize, GLsizei *length, char *buffer) const { - std::string debugInfo(mShader->getDebugInfo()); + const std::string &debugInfo = mImplementation->getDebugInfo(); getSourceImpl(debugInfo, bufSize, length, buffer); } void Shader::compile(Compiler *compiler) { - mCompiled = mShader->compile(compiler, mSource); + mData.mTranslatedSource.clear(); + mInfoLog.clear(); + mData.mShaderVersion = 100; + mData.mVaryings.clear(); + mData.mUniforms.clear(); + mData.mInterfaceBlocks.clear(); + mData.mActiveAttributes.clear(); + mData.mActiveOutputVariables.clear(); + + ShHandle compilerHandle = compiler->getCompilerHandle(mData.mShaderType); + + std::stringstream sourceStream; + + std::string sourcePath; + int additionalOptions = + mImplementation->prepareSourceAndReturnOptions(&sourceStream, &sourcePath); + int compileOptions = (SH_OBJECT_CODE | SH_VARIABLES | additionalOptions); + + // Some targets (eg 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) + { + compileOptions |= SH_VALIDATE_LOOP_INDEXING; + } + + std::string sourceString = sourceStream.str(); + std::vector sourceCStrings; + + if (!sourcePath.empty()) + { + sourceCStrings.push_back(sourcePath.c_str()); + } + + sourceCStrings.push_back(sourceString.c_str()); + + bool result = + ShCompile(compilerHandle, &sourceCStrings[0], sourceCStrings.size(), compileOptions); + + if (!result) + { + mInfoLog = ShGetInfoLog(compilerHandle); + TRACE("\n%s", mInfoLog.c_str()); + mCompiled = false; + return; + } + + mData.mTranslatedSource = ShGetObjectCode(compilerHandle); + +#ifndef 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"; + + size_t curPos = 0; + while (curPos != std::string::npos) + { + size_t nextLine = mData.mSource.find("\n", curPos); + size_t len = (nextLine == std::string::npos) ? std::string::npos : (nextLine - curPos + 1); + + shaderStream << "// " << mData.mSource.substr(curPos, len); + + curPos = (nextLine == std::string::npos) ? std::string::npos : (nextLine + 1); + } + shaderStream << "\n\n"; + shaderStream << mData.mTranslatedSource; + mData.mTranslatedSource = shaderStream.str(); +#endif + + // Gather the shader information + mData.mShaderVersion = ShGetShaderVersion(compilerHandle); + + mData.mVaryings = GetShaderVariables(ShGetVaryings(compilerHandle)); + mData.mUniforms = GetShaderVariables(ShGetUniforms(compilerHandle)); + mData.mInterfaceBlocks = GetShaderVariables(ShGetInterfaceBlocks(compilerHandle)); + + if (mData.mShaderType == GL_VERTEX_SHADER) + { + mData.mActiveAttributes = GetActiveShaderVariables(ShGetAttributes(compilerHandle)); + } + else + { + ASSERT(mData.mShaderType == GL_FRAGMENT_SHADER); + + // TODO(jmadill): Figure out why we only sort in the FS, and if we need to. + std::sort(mData.mVaryings.begin(), mData.mVaryings.end(), CompareShaderVar); + mData.mActiveOutputVariables = + GetActiveShaderVariables(ShGetOutputVariables(compilerHandle)); + } + + ASSERT(!mData.mTranslatedSource.empty()); + + mCompiled = mImplementation->postTranslateCompile(compiler, &mInfoLog); } void Shader::addRef() @@ -166,62 +354,41 @@ void Shader::flagForDeletion() mDeleteStatus = true; } -const std::vector &Shader::getVaryings() const -{ - return mShader->getVaryings(); -} - -const std::vector &Shader::getUniforms() const -{ - return mShader->getUniforms(); -} - -const std::vector &Shader::getInterfaceBlocks() const +int Shader::getShaderVersion() const { - return mShader->getInterfaceBlocks(); + return mData.mShaderVersion; } -const std::vector &Shader::getActiveAttributes() const +const std::vector &Shader::getVaryings() const { - return mShader->getActiveAttributes(); + return mData.getVaryings(); } -const std::vector &Shader::getActiveOutputVariables() const -{ - return mShader->getActiveOutputVariables(); -} - -std::vector &Shader::getVaryings() -{ - return mShader->getVaryings(); -} - -std::vector &Shader::getUniforms() +const std::vector &Shader::getUniforms() const { - return mShader->getUniforms(); + return mData.getUniforms(); } -std::vector &Shader::getInterfaceBlocks() +const std::vector &Shader::getInterfaceBlocks() const { - return mShader->getInterfaceBlocks(); + return mData.getInterfaceBlocks(); } -std::vector &Shader::getActiveAttributes() +const std::vector &Shader::getActiveAttributes() const { - return mShader->getActiveAttributes(); + return mData.getActiveAttributes(); } -std::vector &Shader::getActiveOutputVariables() +const std::vector &Shader::getActiveOutputVariables() const { - return mShader->getActiveOutputVariables(); + return mData.getActiveOutputVariables(); } - int Shader::getSemanticIndex(const std::string &attributeName) const { if (!attributeName.empty()) { - const auto &activeAttributes = mShader->getActiveAttributes(); + const auto &activeAttributes = mData.getActiveAttributes(); int semanticIndex = 0; for (size_t attributeIndex = 0; attributeIndex < activeAttributes.size(); attributeIndex++) diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/Shader.h b/Source/ThirdParty/ANGLE/src/libANGLE/Shader.h index 9c31ae8b424d..997977c87bb9 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/Shader.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/Shader.h @@ -21,49 +21,83 @@ #include "common/angleutils.h" #include "libANGLE/angletypes.h" +#include "libANGLE/Debug.h" namespace rx { +class ImplFactory; class ShaderImpl; +class ShaderSh; } namespace gl { class Compiler; +struct Limitations; class ResourceManager; struct Data; -struct PackedVarying : public sh::Varying -{ - unsigned int registerIndex; // Assigned during link - unsigned int columnIndex; // Assigned during link, defaults to 0 - - PackedVarying(const sh::Varying &varying) - : sh::Varying(varying), - registerIndex(GL_INVALID_INDEX), - columnIndex(0) - {} - - bool registerAssigned() const { return registerIndex != GL_INVALID_INDEX; } - - void resetRegisterAssignment() - { - registerIndex = GL_INVALID_INDEX; - } -}; - -class Shader : angle::NonCopyable +class Shader final : angle::NonCopyable, public LabeledObject { public: - Shader(ResourceManager *manager, rx::ShaderImpl *impl, GLenum type, GLuint handle); + class Data final : angle::NonCopyable + { + public: + Data(GLenum shaderType); + ~Data(); + + const std::string &getLabel() const { return mLabel; } + + const std::string &getSource() const { return mSource; } + const std::string &getTranslatedSource() const { return mTranslatedSource; } + + GLenum getShaderType() const { return mShaderType; } + int getShaderVersion() const { return mShaderVersion; } + + const std::vector &getVaryings() const { return mVaryings; } + const std::vector &getUniforms() const { return mUniforms; } + const std::vector &getInterfaceBlocks() const + { + return mInterfaceBlocks; + } + const std::vector &getActiveAttributes() const { return mActiveAttributes; } + const std::vector &getActiveOutputVariables() const + { + return mActiveOutputVariables; + } + + private: + friend class Shader; + + std::string mLabel; + + GLenum mShaderType; + int mShaderVersion; + std::string mTranslatedSource; + std::string mSource; + + std::vector mVaryings; + std::vector mUniforms; + std::vector mInterfaceBlocks; + std::vector mActiveAttributes; + std::vector mActiveOutputVariables; + }; + + Shader(ResourceManager *manager, + rx::ImplFactory *implFactory, + const gl::Limitations &rendererLimitations, + GLenum type, + GLuint handle); virtual ~Shader(); + void setLabel(const std::string &label) override; + const std::string &getLabel() const override; + GLenum getType() const { return mType; } GLuint getHandle() const; - rx::ShaderImpl *getImplementation() { return mShader; } - const rx::ShaderImpl *getImplementation() const { return mShader; } + const rx::ShaderImpl *getImplementation() const { return mImplementation; } void deleteSource(); void setSource(GLsizei count, const char *const *string, const GLint *length); @@ -72,6 +106,8 @@ class Shader : angle::NonCopyable int getSourceLength() const; void getSource(GLsizei bufSize, GLsizei *length, char *buffer) const; int getTranslatedSourceLength() const; + int getTranslatedSourceWithDebugInfoLength() const; + const std::string &getTranslatedSource() const { return mData.getTranslatedSource(); } void getTranslatedSource(GLsizei bufSize, GLsizei *length, char *buffer) const; void getTranslatedSourceWithDebugInfo(GLsizei bufSize, GLsizei *length, char *buffer) const; @@ -84,34 +120,33 @@ class Shader : angle::NonCopyable bool isFlaggedForDeletion() const; void flagForDeletion(); - const std::vector &getVaryings() const; + int getShaderVersion() const; + + const std::vector &getVaryings() const; const std::vector &getUniforms() const; const std::vector &getInterfaceBlocks() const; const std::vector &getActiveAttributes() const; - const std::vector &getActiveOutputVariables() const; - - std::vector &getVaryings(); - std::vector &getUniforms(); - std::vector &getInterfaceBlocks(); - std::vector &getActiveAttributes(); - std::vector &getActiveOutputVariables(); + const std::vector &getActiveOutputVariables() const; int getSemanticIndex(const std::string &attributeName) const; private: static void getSourceImpl(const std::string &source, GLsizei bufSize, GLsizei *length, char *buffer); - rx::ShaderImpl *mShader; + Data mData; + rx::ShaderImpl *mImplementation; + const gl::Limitations &mRendererLimitations; const GLuint mHandle; const GLenum mType; - std::string mSource; 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 bool mCompiled; // Indicates if this shader has been successfully compiled + std::string mInfoLog; ResourceManager *mResourceManager; }; +bool CompareShaderVar(const sh::ShaderVariable &x, const sh::ShaderVariable &y); } #endif // LIBANGLE_SHADER_H_ diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/State.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/State.cpp index f6837f42e12f..bee54568f5ff 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/State.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/State.cpp @@ -8,8 +8,10 @@ #include "libANGLE/State.h" +#include "common/BitSetIterator.h" #include "libANGLE/Context.h" #include "libANGLE/Caps.h" +#include "libANGLE/Debug.h" #include "libANGLE/Framebuffer.h" #include "libANGLE/FramebufferAttachment.h" #include "libANGLE/Query.h" @@ -20,9 +22,28 @@ namespace gl { State::State() + : mMaxDrawBuffers(0), + mMaxCombinedTextureImageUnits(0), + mDepthClearValue(0), + mStencilClearValue(0), + mScissorTest(false), + mSampleCoverage(false), + mSampleCoverageValue(0), + mSampleCoverageInvert(false), + mStencilRef(0), + mStencilBackRef(0), + mLineWidth(0), + mGenerateMipmapHint(GL_NONE), + mFragmentShaderDerivativeHint(GL_NONE), + mNearZ(0), + mFarZ(0), + mReadFramebuffer(nullptr), + mDrawFramebuffer(nullptr), + mProgram(nullptr), + mVertexArray(nullptr), + mActiveSampler(0), + mPrimitiveRestart(false) { - mMaxDrawBuffers = 0; - mMaxCombinedTextureImageUnits = 0; } State::~State() @@ -30,7 +51,10 @@ State::~State() reset(); } -void State::initialize(const Caps &caps, GLuint clientVersion) +void State::initialize(const Caps &caps, + const Extensions &extensions, + GLuint clientVersion, + bool debug) { mMaxDrawBuffers = caps.maxDrawBuffers; mMaxCombinedTextureImageUnits = caps.maxCombinedTextureImageUnits; @@ -112,12 +136,7 @@ void State::initialize(const Caps &caps, GLuint clientVersion) mActiveSampler = 0; - const GLfloat defaultFloatValues[] = { 0.0f, 0.0f, 0.0f, 1.0f }; mVertexAttribCurrentValues.resize(caps.maxVertexAttributes); - for (size_t attribIndex = 0; attribIndex < mVertexAttribCurrentValues.size(); ++attribIndex) - { - mVertexAttribCurrentValues[attribIndex].setFloatValues(defaultFloatValues); - } mUniformBuffers.resize(caps.maxCombinedUniformBlocks); @@ -132,16 +151,20 @@ void State::initialize(const Caps &caps, GLuint clientVersion) mSamplers.resize(caps.maxCombinedTextureImageUnits); - mActiveQueries[GL_ANY_SAMPLES_PASSED].set(NULL); - mActiveQueries[GL_ANY_SAMPLES_PASSED_CONSERVATIVE].set(NULL); - mActiveQueries[GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN].set(NULL); + mActiveQueries[GL_ANY_SAMPLES_PASSED].set(nullptr); + mActiveQueries[GL_ANY_SAMPLES_PASSED_CONSERVATIVE].set(nullptr); + mActiveQueries[GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN].set(nullptr); + mActiveQueries[GL_TIME_ELAPSED_EXT].set(nullptr); - mProgram = NULL; + mProgram = nullptr; - mReadFramebuffer = NULL; - mDrawFramebuffer = NULL; + mReadFramebuffer = nullptr; + mDrawFramebuffer = nullptr; mPrimitiveRestart = false; + + mDebug.setOutputEnabled(debug); + mDebug.setMaxLoggedMessages(extensions.maxDebugLoggedMessages); } void State::reset() @@ -188,6 +211,9 @@ void State::reset() mUnpack.pixelBuffer.set(NULL); mProgram = NULL; + + // TODO(jmadill): Is this necessary? + setAllDirtyBits(); } const RasterizerState &State::getRasterizerState() const @@ -211,16 +237,19 @@ void State::setColorClearValue(float red, float green, float blue, float alpha) 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) @@ -229,11 +258,13 @@ void State::setColorMask(bool red, bool green, bool blue, bool alpha) mBlend.colorMaskGreen = green; mBlend.colorMaskBlue = blue; mBlend.colorMaskAlpha = alpha; + mDirtyBits.set(DIRTY_BIT_COLOR_MASK); } void State::setDepthMask(bool mask) { mDepthStencil.depthMask = mask; + mDirtyBits.set(DIRTY_BIT_DEPTH_MASK); } bool State::isRasterizerDiscardEnabled() const @@ -244,6 +275,7 @@ bool State::isRasterizerDiscardEnabled() const void State::setRasterizerDiscard(bool enabled) { mRasterizer.rasterizerDiscard = enabled; + mDirtyBits.set(DIRTY_BIT_RASTERIZER_DISCARD_ENABLED); } bool State::isCullFaceEnabled() const @@ -254,16 +286,19 @@ bool State::isCullFaceEnabled() const void State::setCullFace(bool enabled) { mRasterizer.cullFace = enabled; + mDirtyBits.set(DIRTY_BIT_CULL_FACE_ENABLED); } void State::setCullMode(GLenum mode) { mRasterizer.cullMode = mode; + mDirtyBits.set(DIRTY_BIT_CULL_FACE); } void State::setFrontFace(GLenum front) { mRasterizer.frontFace = front; + mDirtyBits.set(DIRTY_BIT_FRONT_FACE); } bool State::isDepthTestEnabled() const @@ -274,17 +309,20 @@ bool State::isDepthTestEnabled() const void State::setDepthTest(bool enabled) { mDepthStencil.depthTest = enabled; + mDirtyBits.set(DIRTY_BIT_DEPTH_TEST_ENABLED); } void State::setDepthFunc(GLenum depthFunc) { mDepthStencil.depthFunc = depthFunc; + mDirtyBits.set(DIRTY_BIT_DEPTH_FUNC); } void State::setDepthRange(float zNear, float zFar) { mNearZ = zNear; mFarZ = zFar; + mDirtyBits.set(DIRTY_BIT_DEPTH_RANGE); } float State::getNearPlane() const @@ -305,6 +343,7 @@ bool State::isBlendEnabled() const void State::setBlend(bool enabled) { mBlend.blend = enabled; + mDirtyBits.set(DIRTY_BIT_BLEND_ENABLED); } void State::setBlendFactors(GLenum sourceRGB, GLenum destRGB, GLenum sourceAlpha, GLenum destAlpha) @@ -313,6 +352,7 @@ void State::setBlendFactors(GLenum sourceRGB, GLenum destRGB, GLenum sourceAlpha mBlend.destBlendRGB = destRGB; mBlend.sourceBlendAlpha = sourceAlpha; mBlend.destBlendAlpha = destAlpha; + mDirtyBits.set(DIRTY_BIT_BLEND_FUNCS); } void State::setBlendColor(float red, float green, float blue, float alpha) @@ -321,12 +361,14 @@ void State::setBlendColor(float red, float green, float blue, float alpha) mBlendColor.green = green; mBlendColor.blue = blue; mBlendColor.alpha = alpha; + mDirtyBits.set(DIRTY_BIT_BLEND_COLOR); } void State::setBlendEquation(GLenum rgbEquation, GLenum alphaEquation) { mBlend.blendEquationRGB = rgbEquation; mBlend.blendEquationAlpha = alphaEquation; + mDirtyBits.set(DIRTY_BIT_BLEND_EQUATIONS); } const ColorF &State::getBlendColor() const @@ -342,6 +384,7 @@ bool State::isStencilTestEnabled() const void State::setStencilTest(bool enabled) { mDepthStencil.stencilTest = enabled; + mDirtyBits.set(DIRTY_BIT_STENCIL_TEST_ENABLED); } void State::setStencilParams(GLenum stencilFunc, GLint stencilRef, GLuint stencilMask) @@ -349,6 +392,7 @@ void State::setStencilParams(GLenum stencilFunc, GLint stencilRef, GLuint stenci mDepthStencil.stencilFunc = stencilFunc; mStencilRef = (stencilRef > 0) ? stencilRef : 0; mDepthStencil.stencilMask = stencilMask; + mDirtyBits.set(DIRTY_BIT_STENCIL_FUNCS_FRONT); } void State::setStencilBackParams(GLenum stencilBackFunc, GLint stencilBackRef, GLuint stencilBackMask) @@ -356,16 +400,19 @@ void State::setStencilBackParams(GLenum stencilBackFunc, GLint stencilBackRef, G mDepthStencil.stencilBackFunc = stencilBackFunc; mStencilBackRef = (stencilBackRef > 0) ? stencilBackRef : 0; mDepthStencil.stencilBackMask = stencilBackMask; + mDirtyBits.set(DIRTY_BIT_STENCIL_FUNCS_BACK); } void State::setStencilWritemask(GLuint stencilWritemask) { mDepthStencil.stencilWritemask = stencilWritemask; + mDirtyBits.set(DIRTY_BIT_STENCIL_WRITEMASK_FRONT); } void State::setStencilBackWritemask(GLuint stencilBackWritemask) { mDepthStencil.stencilBackWritemask = stencilBackWritemask; + mDirtyBits.set(DIRTY_BIT_STENCIL_WRITEMASK_BACK); } void State::setStencilOperations(GLenum stencilFail, GLenum stencilPassDepthFail, GLenum stencilPassDepthPass) @@ -373,6 +420,7 @@ void State::setStencilOperations(GLenum stencilFail, GLenum stencilPassDepthFail 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) @@ -380,6 +428,7 @@ void State::setStencilBackOperations(GLenum stencilBackFail, GLenum stencilBackP mDepthStencil.stencilBackFail = stencilBackFail; mDepthStencil.stencilBackPassDepthFail = stencilBackPassDepthFail; mDepthStencil.stencilBackPassDepthPass = stencilBackPassDepthPass; + mDirtyBits.set(DIRTY_BIT_STENCIL_OPS_BACK); } GLint State::getStencilRef() const @@ -399,7 +448,8 @@ bool State::isPolygonOffsetFillEnabled() const void State::setPolygonOffsetFill(bool enabled) { - mRasterizer.polygonOffsetFill = enabled; + mRasterizer.polygonOffsetFill = enabled; + mDirtyBits.set(DIRTY_BIT_POLYGON_OFFSET_FILL_ENABLED); } void State::setPolygonOffsetParams(GLfloat factor, GLfloat units) @@ -407,6 +457,7 @@ 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); } bool State::isSampleAlphaToCoverageEnabled() const @@ -417,6 +468,7 @@ bool State::isSampleAlphaToCoverageEnabled() const void State::setSampleAlphaToCoverage(bool enabled) { mBlend.sampleAlphaToCoverage = enabled; + mDirtyBits.set(DIRTY_BIT_SAMPLE_ALPHA_TO_COVERAGE_ENABLED); } bool State::isSampleCoverageEnabled() const @@ -427,12 +479,14 @@ bool State::isSampleCoverageEnabled() const void State::setSampleCoverage(bool 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); } GLclampf State::getSampleCoverageValue() const @@ -453,6 +507,7 @@ bool State::isScissorTestEnabled() const void State::setScissorTest(bool enabled) { mScissorTest = enabled; + mDirtyBits.set(DIRTY_BIT_SCISSOR_TEST_ENABLED); } void State::setScissorParams(GLint x, GLint y, GLsizei width, GLsizei height) @@ -461,6 +516,7 @@ void State::setScissorParams(GLint x, GLint y, GLsizei width, GLsizei height) mScissor.y = y; mScissor.width = width; mScissor.height = height; + mDirtyBits.set(DIRTY_BIT_SCISSOR); } const Rectangle &State::getScissor() const @@ -476,6 +532,7 @@ bool State::isDitherEnabled() const void State::setDither(bool enabled) { mBlend.dither = enabled; + mDirtyBits.set(DIRTY_BIT_DITHER_ENABLED); } bool State::isPrimitiveRestartEnabled() const @@ -486,6 +543,7 @@ bool State::isPrimitiveRestartEnabled() const void State::setPrimitiveRestart(bool enabled) { mPrimitiveRestart = enabled; + mDirtyBits.set(DIRTY_BIT_PRIMITIVE_RESTART_ENABLED); } void State::setEnableFeature(GLenum feature, bool enabled) @@ -503,6 +561,12 @@ void State::setEnableFeature(GLenum feature, bool enabled) case GL_DITHER: setDither(enabled); break; case GL_PRIMITIVE_RESTART_FIXED_INDEX: setPrimitiveRestart(enabled); break; case GL_RASTERIZER_DISCARD: setRasterizerDiscard(enabled); break; + case GL_DEBUG_OUTPUT_SYNCHRONOUS: + mDebug.setOutputSynchronous(enabled); + break; + case GL_DEBUG_OUTPUT: + mDebug.setOutputEnabled(enabled); + break; default: UNREACHABLE(); } } @@ -522,6 +586,10 @@ bool State::getEnableFeature(GLenum feature) case GL_DITHER: return isDitherEnabled(); case GL_PRIMITIVE_RESTART_FIXED_INDEX: return isPrimitiveRestartEnabled(); case GL_RASTERIZER_DISCARD: return isRasterizerDiscardEnabled(); + case GL_DEBUG_OUTPUT_SYNCHRONOUS: + return mDebug.isOutputSynchronous(); + case GL_DEBUG_OUTPUT: + return mDebug.isOutputEnabled(); default: UNREACHABLE(); return false; } } @@ -529,6 +597,7 @@ bool State::getEnableFeature(GLenum feature) void State::setLineWidth(GLfloat width) { mLineWidth = width; + mDirtyBits.set(DIRTY_BIT_LINE_WIDTH); } float State::getLineWidth() const @@ -539,11 +608,13 @@ float State::getLineWidth() const void State::setGenerateMipmapHint(GLenum hint) { mGenerateMipmapHint = hint; + mDirtyBits.set(DIRTY_BIT_GENERATE_MIPMAP_HINT); } void State::setFragmentShaderDerivativeHint(GLenum hint) { mFragmentShaderDerivativeHint = hint; + mDirtyBits.set(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. @@ -555,6 +626,7 @@ void State::setViewportParams(GLint x, GLint y, GLsizei width, GLsizei height) mViewport.y = y; mViewport.width = width; mViewport.height = height; + mDirtyBits.set(DIRTY_BIT_VIEWPORT); } const Rectangle &State::getViewport() const @@ -577,10 +649,16 @@ void State::setSamplerTexture(GLenum type, Texture *texture) mSamplerTextures[type][mActiveSampler].set(texture); } +Texture *State::getTargetTexture(GLenum target) const +{ + return getSamplerTexture(static_cast(mActiveSampler), target); +} + Texture *State::getSamplerTexture(unsigned int sampler, GLenum type) const { const auto it = mSamplerTextures.find(type); ASSERT(it != mSamplerTextures.end()); + ASSERT(sampler < it->second.size()); return it->second[sampler].get(); } @@ -588,6 +666,7 @@ GLuint State::getSamplerTextureId(unsigned int sampler, GLenum type) const { const auto it = mSamplerTextures.find(type); ASSERT(it != mSamplerTextures.end()); + ASSERT(sampler < it->second.size()); return it->second[sampler].id(); } @@ -728,22 +807,44 @@ void State::detachRenderbuffer(GLuint renderbuffer) 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->hasAnyDirtyBit()) + { + mDirtyObjects.set(DIRTY_OBJECT_DRAW_FRAMEBUFFER); + } } 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 NULL; + case GL_READ_FRAMEBUFFER_ANGLE: + return mReadFramebuffer; + case GL_DRAW_FRAMEBUFFER_ANGLE: + case GL_FRAMEBUFFER: + return mDrawFramebuffer; + default: + UNREACHABLE(); + return NULL; } } @@ -772,7 +873,7 @@ bool State::removeReadFramebufferBinding(GLuint framebuffer) if (mReadFramebuffer != nullptr && mReadFramebuffer->id() == framebuffer) { - mReadFramebuffer = NULL; + setReadFramebufferBinding(nullptr); return true; } @@ -784,7 +885,7 @@ bool State::removeDrawFramebufferBinding(GLuint framebuffer) if (mReadFramebuffer != nullptr && mDrawFramebuffer->id() == framebuffer) { - mDrawFramebuffer = NULL; + setDrawFramebufferBinding(nullptr); return true; } @@ -794,6 +895,12 @@ bool State::removeDrawFramebufferBinding(GLuint framebuffer) void State::setVertexArrayBinding(VertexArray *vertexArray) { mVertexArray = vertexArray; + mDirtyBits.set(DIRTY_BIT_VERTEX_ARRAY_BINDING); + + if (mVertexArray && mVertexArray->hasAnyDirtyBit()) + { + mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY); + } } GLuint State::getVertexArrayId() const @@ -813,6 +920,8 @@ bool State::removeVertexArrayBinding(GLuint vertexArray) if (mVertexArray->id() == vertexArray) { mVertexArray = NULL; + mDirtyBits.set(DIRTY_BIT_VERTEX_ARRAY_BINDING); + mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY); return true; } @@ -868,10 +977,22 @@ void State::detachTransformFeedback(GLuint transformFeedback) bool State::isQueryActive() const { - for (State::ActiveQueryMap::const_iterator i = mActiveQueries.begin(); - i != mActiveQueries.end(); i++) + for (auto &iter : mActiveQueries) { - if (i->second.get() != NULL) + if (iter.second.get() != NULL) + { + return true; + } + } + + return false; +} + +bool State::isQueryActive(Query *query) const +{ + for (auto &iter : mActiveQueries) + { + if (iter.second.get() == query) { return true; } @@ -911,17 +1032,6 @@ GLuint State::getArrayBufferId() const return mArrayBuffer.id(); } -bool State::removeArrayBufferBinding(GLuint buffer) -{ - if (mArrayBuffer.id() == buffer) - { - mArrayBuffer.set(NULL); - return true; - } - - return false; -} - void State::setGenericUniformBufferBinding(Buffer *buffer) { mGenericUniformBuffer.set(buffer); @@ -932,32 +1042,10 @@ void State::setIndexedUniformBufferBinding(GLuint index, Buffer *buffer, GLintpt mUniformBuffers[index].set(buffer, offset, size); } -GLuint State::getIndexedUniformBufferId(GLuint index) const -{ - ASSERT(static_cast(index) < mUniformBuffers.size()); - - return mUniformBuffers[index].id(); -} - -Buffer *State::getIndexedUniformBuffer(GLuint index) const +const OffsetBindingPointer &State::getIndexedUniformBuffer(size_t index) const { ASSERT(static_cast(index) < mUniformBuffers.size()); - - return mUniformBuffers[index].get(); -} - -GLintptr State::getIndexedUniformBufferOffset(GLuint index) const -{ - ASSERT(static_cast(index) < mUniformBuffers.size()); - - return mUniformBuffers[index].getOffset(); -} - -GLsizeiptr State::getIndexedUniformBufferSize(GLuint index) const -{ - ASSERT(static_cast(index) < mUniformBuffers.size()); - - return mUniformBuffers[index].getSize(); + return mUniformBuffers[index]; } void State::setCopyReadBufferBinding(Buffer *buffer) @@ -987,7 +1075,7 @@ Buffer *State::getTargetBuffer(GLenum target) const case GL_ARRAY_BUFFER: return mArrayBuffer.get(); case GL_COPY_READ_BUFFER: return mCopyReadBuffer.get(); case GL_COPY_WRITE_BUFFER: return mCopyWriteBuffer.get(); - case GL_ELEMENT_ARRAY_BUFFER: return getVertexArray()->getElementArrayBuffer(); + case GL_ELEMENT_ARRAY_BUFFER: return getVertexArray()->getElementArrayBuffer().get(); case GL_PIXEL_PACK_BUFFER: return mPack.pixelBuffer.get(); case GL_PIXEL_UNPACK_BUFFER: return mUnpack.pixelBuffer.get(); case GL_TRANSFORM_FEEDBACK_BUFFER: return mTransformFeedback->getGenericBuffer().get(); @@ -996,33 +1084,72 @@ Buffer *State::getTargetBuffer(GLenum target) const } } +void State::detachBuffer(GLuint bufferName) +{ + BindingPointer *buffers[] = {&mArrayBuffer, &mCopyReadBuffer, + &mCopyWriteBuffer, &mPack.pixelBuffer, + &mUnpack.pixelBuffer, &mGenericUniformBuffer}; + for (auto buffer : buffers) + { + if (buffer->id() == bufferName) + { + buffer->set(nullptr); + } + } + + TransformFeedback *curTransformFeedback = getCurrentTransformFeedback(); + if (curTransformFeedback) + { + curTransformFeedback->detachBuffer(bufferName); + } + + getVertexArray()->detachBuffer(bufferName); +} + 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_VALUE_0 + index); } void State::setVertexAttribu(GLuint index, const GLuint values[4]) { ASSERT(static_cast(index) < mVertexAttribCurrentValues.size()); mVertexAttribCurrentValues[index].setUnsignedIntValues(values); + mDirtyBits.set(DIRTY_BIT_CURRENT_VALUE_0 + index); } void State::setVertexAttribi(GLuint index, const GLint values[4]) { ASSERT(static_cast(index) < mVertexAttribCurrentValues.size()); mVertexAttribCurrentValues[index].setIntValues(values); + mDirtyBits.set(DIRTY_BIT_CURRENT_VALUE_0 + index); } -void State::setVertexAttribState(unsigned int attribNum, Buffer *boundBuffer, GLint size, GLenum type, bool normalized, - bool pureInteger, GLsizei stride, const void *pointer) +void State::setVertexAttribState(unsigned int attribNum, + Buffer *boundBuffer, + GLint size, + GLenum type, + bool normalized, + bool pureInteger, + GLsizei stride, + const void *pointer) { getVertexArray()->setAttributeState(attribNum, boundBuffer, size, type, normalized, pureInteger, stride, pointer); + mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY); +} + +void State::setVertexAttribDivisor(GLuint index, GLuint divisor) +{ + getVertexArray()->setVertexAttribDivisor(index, divisor); + mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY); } const VertexAttribCurrentValueData &State::getVertexAttribCurrentValue(unsigned int attribNum) const @@ -1039,6 +1166,7 @@ const void *State::getVertexAttribPointer(unsigned int attribNum) const void State::setPackAlignment(GLint alignment) { mPack.alignment = alignment; + mDirtyBits.set(DIRTY_BIT_PACK_ALIGNMENT); } GLint State::getPackAlignment() const @@ -1049,6 +1177,7 @@ GLint State::getPackAlignment() const void State::setPackReverseRowOrder(bool reverseRowOrder) { mPack.reverseRowOrder = reverseRowOrder; + mDirtyBits.set(DIRTY_BIT_PACK_REVERSE_ROW_ORDER); } bool State::getPackReverseRowOrder() const @@ -1056,6 +1185,39 @@ bool State::getPackReverseRowOrder() const return mPack.reverseRowOrder; } +void State::setPackRowLength(GLint rowLength) +{ + mPack.rowLength = rowLength; + mDirtyBits.set(DIRTY_BIT_PACK_ROW_LENGTH); +} + +GLint State::getPackRowLength() const +{ + return mPack.rowLength; +} + +void State::setPackSkipRows(GLint skipRows) +{ + mPack.skipRows = skipRows; + mDirtyBits.set(DIRTY_BIT_PACK_SKIP_ROWS); +} + +GLint State::getPackSkipRows() const +{ + return mPack.skipRows; +} + +void State::setPackSkipPixels(GLint skipPixels) +{ + mPack.skipPixels = skipPixels; + mDirtyBits.set(DIRTY_BIT_PACK_SKIP_PIXELS); +} + +GLint State::getPackSkipPixels() const +{ + return mPack.skipPixels; +} + const PixelPackState &State::getPackState() const { return mPack; @@ -1069,6 +1231,7 @@ PixelPackState &State::getPackState() void State::setUnpackAlignment(GLint alignment) { mUnpack.alignment = alignment; + mDirtyBits.set(DIRTY_BIT_UNPACK_ALIGNMENT); } GLint State::getUnpackAlignment() const @@ -1079,6 +1242,7 @@ GLint State::getUnpackAlignment() const void State::setUnpackRowLength(GLint rowLength) { mUnpack.rowLength = rowLength; + mDirtyBits.set(DIRTY_BIT_UNPACK_ROW_LENGTH); } GLint State::getUnpackRowLength() const @@ -1086,6 +1250,50 @@ GLint State::getUnpackRowLength() const return mUnpack.rowLength; } +void State::setUnpackImageHeight(GLint imageHeight) +{ + mUnpack.imageHeight = imageHeight; + mDirtyBits.set(DIRTY_BIT_UNPACK_IMAGE_HEIGHT); +} + +GLint State::getUnpackImageHeight() const +{ + return mUnpack.imageHeight; +} + +void State::setUnpackSkipImages(GLint skipImages) +{ + mUnpack.skipImages = skipImages; + mDirtyBits.set(DIRTY_BIT_UNPACK_SKIP_IMAGES); +} + +GLint State::getUnpackSkipImages() const +{ + return mUnpack.skipImages; +} + +void State::setUnpackSkipRows(GLint skipRows) +{ + mUnpack.skipRows = skipRows; + mDirtyBits.set(DIRTY_BIT_UNPACK_SKIP_ROWS); +} + +GLint State::getUnpackSkipRows() const +{ + return mUnpack.skipRows; +} + +void State::setUnpackSkipPixels(GLint skipPixels) +{ + mUnpack.skipPixels = skipPixels; + mDirtyBits.set(DIRTY_BIT_UNPACK_SKIP_PIXELS); +} + +GLint State::getUnpackSkipPixels() const +{ + return mUnpack.skipPixels; +} + const PixelUnpackState &State::getUnpackState() const { return mUnpack; @@ -1096,6 +1304,16 @@ PixelUnpackState &State::getUnpackState() return mUnpack; } +const Debug &State::getDebug() const +{ + return mDebug; +} + +Debug &State::getDebug() +{ + return mDebug; +} + void State::getBooleanv(GLenum pname, GLboolean *params) { switch (pname) @@ -1119,6 +1337,18 @@ void State::getBooleanv(GLenum pname, GLboolean *params) case GL_DITHER: *params = mBlend.dither; 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; default: UNREACHABLE(); break; @@ -1179,7 +1409,7 @@ void State::getIntegerv(const gl::Data &data, GLenum pname, GLint *params) switch (pname) { case GL_ARRAY_BUFFER_BINDING: *params = mArrayBuffer.id(); break; - case GL_ELEMENT_ARRAY_BUFFER_BINDING: *params = getVertexArray()->getElementArrayBufferId(); break; + case GL_ELEMENT_ARRAY_BUFFER_BINDING: *params = getVertexArray()->getElementArrayBuffer().id(); break; //case GL_FRAMEBUFFER_BINDING: // now equivalent to GL_DRAW_FRAMEBUFFER_BINDING_ANGLE case GL_DRAW_FRAMEBUFFER_BINDING_ANGLE: *params = mDrawFramebuffer->id(); break; case GL_READ_FRAMEBUFFER_BINDING_ANGLE: *params = mReadFramebuffer->id(); break; @@ -1188,11 +1418,34 @@ void State::getIntegerv(const gl::Data &data, GLenum pname, GLint *params) case GL_CURRENT_PROGRAM: *params = mProgram ? mProgram->id() : 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_FRAGMENT_SHADER_DERIVATIVE_HINT_OES: *params = mFragmentShaderDerivativeHint; break; - case GL_ACTIVE_TEXTURE: *params = static_cast(mActiveSampler + GL_TEXTURE0); 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 = clampToInt(mDepthStencil.stencilMask); break; @@ -1316,11 +1569,12 @@ void State::getIntegerv(const gl::Data &data, GLenum pname, GLint *params) break; case GL_TEXTURE_BINDING_2D: ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits); - *params = getSamplerTextureId(static_cast(mActiveSampler), GL_TEXTURE_2D) ; + *params = getSamplerTextureId(static_cast(mActiveSampler), GL_TEXTURE_2D); break; case GL_TEXTURE_BINDING_CUBE_MAP: ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits); - *params = getSamplerTextureId(static_cast(mActiveSampler), GL_TEXTURE_CUBE_MAP); + *params = + getSamplerTextureId(static_cast(mActiveSampler), GL_TEXTURE_CUBE_MAP); break; case GL_TEXTURE_BINDING_3D: ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits); @@ -1328,11 +1582,15 @@ void State::getIntegerv(const gl::Data &data, GLenum pname, GLint *params) break; case GL_TEXTURE_BINDING_2D_ARRAY: ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits); - *params = getSamplerTextureId(static_cast(mActiveSampler), GL_TEXTURE_2D_ARRAY); + *params = + getSamplerTextureId(static_cast(mActiveSampler), GL_TEXTURE_2D_ARRAY); break; case GL_UNIFORM_BUFFER_BINDING: *params = mGenericUniformBuffer.id(); break; + case GL_TRANSFORM_FEEDBACK_BINDING: + *params = mTransformFeedback.id(); + break; case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING: *params = mTransformFeedback->getGenericBuffer().id(); break; @@ -1348,12 +1606,44 @@ void State::getIntegerv(const gl::Data &data, GLenum pname, GLint *params) case GL_PIXEL_UNPACK_BUFFER_BINDING: *params = mUnpack.pixelBuffer.id(); break; + case GL_READ_BUFFER: + *params = mReadFramebuffer->getReadBufferState(); + break; + case GL_SAMPLER_BINDING: + ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits); + *params = getSamplerId(static_cast(mActiveSampler)); + 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; default: UNREACHABLE(); break; } } +void State::getPointerv(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; + default: + UNREACHABLE(); + break; + } +} + bool State::getIndexedIntegerv(GLenum target, GLuint index, GLint *data) { switch (target) @@ -1418,7 +1708,7 @@ bool State::hasMappedBuffer(GLenum target) const { const VertexArray *vao = getVertexArray(); const auto &vertexAttribs = vao->getVertexAttributes(); - unsigned int maxEnabledAttrib = vao->getMaxEnabledAttribute(); + size_t maxEnabledAttrib = vao->getMaxEnabledAttribute(); for (size_t attribIndex = 0; attribIndex < maxEnabledAttrib; attribIndex++) { const gl::VertexAttribute &vertexAttrib = vertexAttribs[attribIndex]; @@ -1438,4 +1728,92 @@ bool State::hasMappedBuffer(GLenum target) const } } +void State::syncDirtyObjects() +{ + if (!mDirtyObjects.any()) + return; + + syncDirtyObjects(mDirtyObjects); } + +void State::syncDirtyObjects(const DirtyObjects &bitset) +{ + for (auto dirtyObject : angle::IterateBitSet(bitset)) + { + switch (dirtyObject) + { + case DIRTY_OBJECT_READ_FRAMEBUFFER: + ASSERT(mReadFramebuffer); + mReadFramebuffer->syncState(); + break; + case DIRTY_OBJECT_DRAW_FRAMEBUFFER: + ASSERT(mDrawFramebuffer); + mDrawFramebuffer->syncState(); + break; + case DIRTY_OBJECT_VERTEX_ARRAY: + ASSERT(mVertexArray); + mVertexArray->syncImplState(); + break; + case DIRTY_OBJECT_PROGRAM: + // TODO(jmadill): implement this + break; + default: + UNREACHABLE(); + break; + } + } + + mDirtyObjects &= ~bitset; +} + +void State::syncDirtyObject(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_PROGRAM: + localSet.set(DIRTY_OBJECT_PROGRAM); + break; + } + + syncDirtyObjects(localSet); +} + +void State::setObjectDirty(GLenum target) +{ + switch (target) + { + case GL_READ_FRAMEBUFFER: + mDirtyObjects.set(DIRTY_OBJECT_READ_FRAMEBUFFER); + break; + case GL_DRAW_FRAMEBUFFER: + mDirtyObjects.set(DIRTY_OBJECT_DRAW_FRAMEBUFFER); + break; + case GL_FRAMEBUFFER: + mDirtyObjects.set(DIRTY_OBJECT_READ_FRAMEBUFFER); + mDirtyObjects.set(DIRTY_OBJECT_DRAW_FRAMEBUFFER); + break; + case GL_VERTEX_ARRAY: + mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY); + break; + case GL_PROGRAM: + mDirtyObjects.set(DIRTY_OBJECT_PROGRAM); + break; + } +} + +} // namespace gl diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/State.h b/Source/ThirdParty/ANGLE/src/libANGLE/State.h index 90e757d813b3..465643208c19 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/State.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/State.h @@ -9,15 +9,19 @@ #ifndef LIBANGLE_STATE_H_ #define LIBANGLE_STATE_H_ +#include +#include + #include "common/angleutils.h" +#include "libANGLE/Debug.h" +#include "libANGLE/Program.h" #include "libANGLE/RefCountObject.h" -#include "libANGLE/angletypes.h" -#include "libANGLE/VertexAttribute.h" #include "libANGLE/Renderbuffer.h" +#include "libANGLE/Sampler.h" #include "libANGLE/Texture.h" #include "libANGLE/TransformFeedback.h" -#include "libANGLE/Program.h" -#include "libANGLE/Sampler.h" +#include "libANGLE/VertexAttribute.h" +#include "libANGLE/angletypes.h" namespace gl { @@ -27,7 +31,7 @@ class Context; struct Caps; struct Data; -typedef std::map< GLenum, BindingPointer > TextureMap; +typedef std::map> TextureMap; class State : angle::NonCopyable { @@ -35,7 +39,10 @@ class State : angle::NonCopyable State(); ~State(); - void initialize(const Caps& caps, GLuint clientVersion); + void initialize(const Caps &caps, + const Extensions &extensions, + GLuint clientVersion, + bool debug); void reset(); // State chunk getters @@ -142,6 +149,7 @@ class State : angle::NonCopyable void setActiveSampler(unsigned int active); unsigned int getActiveSampler() const; void setSamplerTexture(GLenum type, Texture *texture); + Texture *getTargetTexture(GLenum target) const; Texture *getSamplerTexture(unsigned int sampler, GLenum type) const; GLuint getSamplerTextureId(unsigned int sampler, GLenum type) const; void detachTexture(const TextureMap &zeroTextures, GLuint texture); @@ -188,6 +196,7 @@ class State : angle::NonCopyable // Query binding manipulation bool isQueryActive() const; + bool isQueryActive(Query *query) const; void setActiveQuery(GLenum target, Query *query); GLuint getActiveQueryId(GLenum target) const; Query *getActiveQuery(GLenum target) const; @@ -196,15 +205,11 @@ class State : angle::NonCopyable // GL_ARRAY_BUFFER void setArrayBufferBinding(Buffer *buffer); GLuint getArrayBufferId() const; - bool removeArrayBufferBinding(GLuint buffer); // GL_UNIFORM_BUFFER - Both indexed and generic targets void setGenericUniformBufferBinding(Buffer *buffer); void setIndexedUniformBufferBinding(GLuint index, Buffer *buffer, GLintptr offset, GLsizeiptr size); - GLuint getIndexedUniformBufferId(GLuint index) const; - Buffer *getIndexedUniformBuffer(GLuint index) const; - GLintptr getIndexedUniformBufferOffset(GLuint index) const; - GLsizeiptr getIndexedUniformBufferSize(GLuint index) const; + const OffsetBindingPointer &getIndexedUniformBuffer(size_t index) const; // GL_COPY_[READ/WRITE]_BUFFER void setCopyReadBufferBinding(Buffer *buffer); @@ -216,6 +221,8 @@ class State : angle::NonCopyable // Retrieve typed buffer by target (non-indexed) Buffer *getTargetBuffer(GLenum target) const; + // Detach a buffer from all bindings + void detachBuffer(GLuint bufferName); // Vertex attrib manipulation void setEnableVertexAttribArray(unsigned int attribNum, bool enabled); @@ -224,6 +231,7 @@ class State : angle::NonCopyable void setVertexAttribi(GLuint index, const GLint values[4]); void setVertexAttribState(unsigned int attribNum, Buffer *boundBuffer, GLint size, GLenum type, bool normalized, bool pureInteger, GLsizei stride, const void *pointer); + void setVertexAttribDivisor(GLuint index, GLuint divisor); const VertexAttribCurrentValueData &getVertexAttribCurrentValue(unsigned int attribNum) const; const void *getVertexAttribPointer(unsigned int attribNum) const; @@ -232,6 +240,12 @@ class State : angle::NonCopyable GLint getPackAlignment() const; void setPackReverseRowOrder(bool reverseRowOrder); bool getPackReverseRowOrder() const; + void setPackRowLength(GLint rowLength); + GLint getPackRowLength() const; + void setPackSkipRows(GLint skipRows); + GLint getPackSkipRows() const; + void setPackSkipPixels(GLint skipPixels); + GLint getPackSkipPixels() const; const PixelPackState &getPackState() const; PixelPackState &getPackState(); @@ -240,18 +254,116 @@ class State : angle::NonCopyable GLint getUnpackAlignment() const; void setUnpackRowLength(GLint rowLength); GLint getUnpackRowLength() const; + void setUnpackImageHeight(GLint imageHeight); + GLint getUnpackImageHeight() const; + void setUnpackSkipImages(GLint skipImages); + GLint getUnpackSkipImages() const; + void setUnpackSkipRows(GLint skipRows); + GLint getUnpackSkipRows() const; + void setUnpackSkipPixels(GLint skipPixels); + GLint getUnpackSkipPixels() const; const PixelUnpackState &getUnpackState() const; PixelUnpackState &getUnpackState(); + // Debug state + const Debug &getDebug() const; + Debug &getDebug(); + // State query functions void getBooleanv(GLenum pname, GLboolean *params); void getFloatv(GLenum pname, GLfloat *params); void getIntegerv(const gl::Data &data, GLenum pname, GLint *params); + void getPointerv(GLenum pname, void **params) const; bool getIndexedIntegerv(GLenum target, GLuint index, GLint *data); bool getIndexedInteger64v(GLenum target, GLuint index, GLint64 *data); bool hasMappedBuffer(GLenum target) const; + enum DirtyBitType + { + 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_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_ALIGNMENT, + DIRTY_BIT_UNPACK_ROW_LENGTH, + DIRTY_BIT_UNPACK_IMAGE_HEIGHT, + DIRTY_BIT_UNPACK_SKIP_IMAGES, + DIRTY_BIT_UNPACK_SKIP_ROWS, + DIRTY_BIT_UNPACK_SKIP_PIXELS, + DIRTY_BIT_PACK_ALIGNMENT, + DIRTY_BIT_PACK_REVERSE_ROW_ORDER, + DIRTY_BIT_PACK_ROW_LENGTH, + DIRTY_BIT_PACK_SKIP_ROWS, + DIRTY_BIT_PACK_SKIP_PIXELS, + DIRTY_BIT_DITHER_ENABLED, + DIRTY_BIT_GENERATE_MIPMAP_HINT, + DIRTY_BIT_SHADER_DERIVATIVE_HINT, + DIRTY_BIT_READ_FRAMEBUFFER_BINDING, + DIRTY_BIT_DRAW_FRAMEBUFFER_BINDING, + DIRTY_BIT_RENDERBUFFER_BINDING, + DIRTY_BIT_VERTEX_ARRAY_BINDING, + DIRTY_BIT_PROGRAM_BINDING, + DIRTY_BIT_CURRENT_VALUE_0, + DIRTY_BIT_CURRENT_VALUE_MAX = DIRTY_BIT_CURRENT_VALUE_0 + MAX_VERTEX_ATTRIBS, + DIRTY_BIT_INVALID = DIRTY_BIT_CURRENT_VALUE_MAX, + DIRTY_BIT_MAX = DIRTY_BIT_INVALID, + }; + + // TODO(jmadill): Consider storing dirty objects in a list instead of by binding. + enum DirtyObjectType + { + DIRTY_OBJECT_READ_FRAMEBUFFER, + DIRTY_OBJECT_DRAW_FRAMEBUFFER, + DIRTY_OBJECT_VERTEX_ARRAY, + DIRTY_OBJECT_PROGRAM, + DIRTY_OBJECT_UNKNOWN, + DIRTY_OBJECT_MAX = DIRTY_OBJECT_UNKNOWN, + }; + + typedef std::bitset DirtyBits; + const DirtyBits &getDirtyBits() const { return mDirtyBits; } + void clearDirtyBits() { mDirtyBits.reset(); } + void clearDirtyBits(const DirtyBits &bitset) { mDirtyBits &= ~bitset; } + void setAllDirtyBits() { mDirtyBits.set(); } + + typedef std::bitset DirtyObjects; + void clearDirtyObjects() { mDirtyObjects.reset(); } + void setAllDirtyObjects() { mDirtyObjects.set(); } + void syncDirtyObjects(); + void syncDirtyObjects(const DirtyObjects &bitset); + void syncDirtyObject(GLenum target); + void setObjectDirty(GLenum target); + private: // Cached values from Context's caps GLuint mMaxDrawBuffers; @@ -297,18 +409,18 @@ class State : angle::NonCopyable // Texture and sampler bindings size_t mActiveSampler; // Active texture unit selector - GL_TEXTURE0 - typedef std::vector< BindingPointer > TextureBindingVector; + typedef std::vector> TextureBindingVector; typedef std::map TextureBindingMap; TextureBindingMap mSamplerTextures; - typedef std::vector< BindingPointer > SamplerBindingVector; + typedef std::vector> SamplerBindingVector; SamplerBindingVector mSamplers; - typedef std::map< GLenum, BindingPointer > ActiveQueryMap; + typedef std::map> ActiveQueryMap; ActiveQueryMap mActiveQueries; BindingPointer mGenericUniformBuffer; - typedef std::vector< OffsetBindingPointer > BufferVector; + typedef std::vector> BufferVector; BufferVector mUniformBuffers; BindingPointer mTransformFeedback; @@ -320,9 +432,14 @@ class State : angle::NonCopyable PixelPackState mPack; bool mPrimitiveRestart; + + Debug mDebug; + + DirtyBits mDirtyBits; + DirtyObjects mDirtyObjects; }; -} +} // namespace gl #endif // LIBANGLE_STATE_H_ diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/Stream.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/Stream.cpp new file mode 100644 index 000000000000..c6d4109e15c1 --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/libANGLE/Stream.cpp @@ -0,0 +1,76 @@ +// +// Copyright (c) 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/renderer/StreamImpl.h" + +namespace egl +{ + +Stream::Stream(rx::StreamImpl *impl, const AttributeMap &attribs) + : mImplementation(impl), + mState(EGL_STREAM_STATE_CREATED_KHR), + mProducerFrame(0), + mConsumerFrame(0), + mConsumerLatency(static_cast(attribs.get(EGL_CONSUMER_LATENCY_USEC_KHR, 0))), + mConsumerAcquireTimeout( + static_cast(attribs.get(EGL_CONSUMER_ACQUIRE_TIMEOUT_USEC_KHR, 0))) +{ +} + +Stream::~Stream() +{ + SafeDelete(mImplementation); +} + +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; +} + +} // namespace egl diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/Stream.h b/Source/ThirdParty/ANGLE/src/libANGLE/Stream.h new file mode 100644 index 000000000000..c92ff4e4e6ca --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/libANGLE/Stream.h @@ -0,0 +1,59 @@ +// +// Copyright (c) 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 "common/angleutils.h" +#include "libANGLE/AttributeMap.h" + +namespace rx +{ +class StreamImpl; +} + +namespace egl +{ + +class Stream final : angle::NonCopyable +{ + public: + Stream(rx::StreamImpl *impl, const AttributeMap &attribs); + ~Stream(); + + EGLenum getState() const; + + void setConsumerLatency(EGLint latency); + EGLint getConsumerLatency() const; + + EGLuint64KHR getProducerFrame() const; + EGLuint64KHR getConsumerFrame() const; + + void setConsumerAcquireTimeout(EGLint timeout); + EGLint getConsumerAcquireTimeout() const; + + private: + // Implementation + rx::StreamImpl *mImplementation; + + // EGL defined attributes + EGLint mState; + EGLuint64KHR mProducerFrame; + EGLuint64KHR mConsumerFrame; + EGLint mConsumerLatency; + + // EGL gltexture consumer attributes + EGLint mConsumerAcquireTimeout; +}; +} // namespace egl + +#endif // LIBANGLE_STREAM_H_ diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/Surface.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/Surface.cpp index 9742f5d99c24..d259da155543 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/Surface.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/Surface.cpp @@ -11,16 +11,25 @@ #include "libANGLE/Surface.h" #include "libANGLE/Config.h" +#include "libANGLE/Framebuffer.h" #include "libANGLE/Texture.h" #include +#include + namespace egl { -Surface::Surface(rx::SurfaceImpl *impl, EGLint surfaceType, const egl::Config *config, const AttributeMap &attributes) - : FramebufferAttachmentObject(0), // id unused +Surface::Surface(rx::SurfaceImpl *impl, + EGLint surfaceType, + const egl::Config *config, + const AttributeMap &attributes) + : FramebufferAttachmentObject(), mImplementation(impl), + mDefaultFramebuffer(nullptr), + mCurrentCount(0), + mDestroyed(false), mType(surfaceType), mConfig(config), mPostSubBufferRequested(false), @@ -32,42 +41,77 @@ Surface::Surface(rx::SurfaceImpl *impl, EGLint surfaceType, const egl::Config *c // FIXME: Determine actual pixel aspect ratio mPixelAspectRatio(static_cast(1.0 * EGL_DISPLAY_SCALING)), mRenderBuffer(EGL_BACK_BUFFER), - mSwapBehavior(EGL_BUFFER_PRESERVED), - mTexture(NULL) + mSwapBehavior(impl->getSwapBehavior()), + mOrientation(0), + mTexture() { - addRef(); - mPostSubBufferRequested = (attributes.get(EGL_POST_SUB_BUFFER_SUPPORTED_NV, EGL_FALSE) == EGL_TRUE); + mFlexibleSurfaceCompatibilityRequested = + (attributes.get(EGL_FLEXIBLE_SURFACE_COMPATIBILITY_SUPPORTED_ANGLE, EGL_FALSE) == EGL_TRUE); + + mDirectComposition = (attributes.get(EGL_DIRECT_COMPOSITION_ANGLE, EGL_FALSE) == EGL_TRUE); mFixedSize = (attributes.get(EGL_FIXED_SIZE_ANGLE, EGL_FALSE) == EGL_TRUE); if (mFixedSize) { - mFixedWidth = attributes.get(EGL_WIDTH, 0); - mFixedHeight = attributes.get(EGL_HEIGHT, 0); + mFixedWidth = static_cast(attributes.get(EGL_WIDTH, 0)); + mFixedHeight = static_cast(attributes.get(EGL_HEIGHT, 0)); } if (mType != EGL_WINDOW_BIT) { - mTextureFormat = attributes.get(EGL_TEXTURE_FORMAT, EGL_NO_TEXTURE); - mTextureTarget = attributes.get(EGL_TEXTURE_TARGET, EGL_NO_TEXTURE); + mTextureFormat = static_cast(attributes.get(EGL_TEXTURE_FORMAT, EGL_NO_TEXTURE)); + mTextureTarget = static_cast(attributes.get(EGL_TEXTURE_TARGET, EGL_NO_TEXTURE)); } + + mOrientation = static_cast(attributes.get(EGL_SURFACE_ORIENTATION_ANGLE, 0)); + + mDefaultFramebuffer = createDefaultFramebuffer(); + ASSERT(mDefaultFramebuffer != nullptr); } Surface::~Surface() { - if (mTexture) + if (mTexture.get()) { if (mImplementation) { mImplementation->releaseTexImage(EGL_BACK_BUFFER); } - mTexture->releaseTexImage(); - mTexture = NULL; + mTexture->releaseTexImageFromSurface(); + mTexture.set(nullptr); } + SafeDelete(mDefaultFramebuffer); SafeDelete(mImplementation); } +void Surface::setIsCurrent(bool isCurrent) +{ + if (isCurrent) + { + mCurrentCount++; + } + else + { + ASSERT(mCurrentCount > 0); + mCurrentCount--; + if (mCurrentCount == 0 && mDestroyed) + { + delete this; + } + } +} + +void Surface::onDestroy() +{ + mDestroyed = true; + if (mCurrentCount == 0) + { + delete this; + } +} + EGLint Surface::getType() const { return mType; @@ -145,23 +189,33 @@ EGLint Surface::getHeight() const Error Surface::bindTexImage(gl::Texture *texture, EGLint buffer) { - ASSERT(!mTexture); + ASSERT(!mTexture.get()); - texture->bindTexImage(this); - mTexture = texture; - return mImplementation->bindTexImage(buffer); + texture->bindTexImageFromSurface(this); + mTexture.set(texture); + return mImplementation->bindTexImage(texture, buffer); } Error Surface::releaseTexImage(EGLint buffer) { - ASSERT(mTexture); - gl::Texture *boundTexture = mTexture; - mTexture = NULL; + ASSERT(mTexture.get()); + mTexture->releaseTexImageFromSurface(); + mTexture.set(nullptr); - boundTexture->releaseTexImage(); return mImplementation->releaseTexImage(buffer); } +void Surface::releaseTexImageFromTexture() +{ + ASSERT(mTexture.get()); + mTexture.set(nullptr); +} + +gl::Extents Surface::getAttachmentSize(const gl::FramebufferAttachment::Target & /*target*/) const +{ + return gl::Extents(getWidth(), getHeight(), 1); +} + GLenum Surface::getAttachmentInternalFormat(const gl::FramebufferAttachment::Target &target) const { const egl::Config *config = getConfig(); @@ -173,4 +227,35 @@ GLsizei Surface::getAttachmentSamples(const gl::FramebufferAttachment::Target &t return getConfig()->samples; } +GLuint Surface::getId() const +{ + UNREACHABLE(); + return 0; +} + +gl::Framebuffer *Surface::createDefaultFramebuffer() +{ + gl::Framebuffer *framebuffer = new gl::Framebuffer(mImplementation); + + GLenum drawBufferState = GL_BACK; + framebuffer->setDrawBuffers(1, &drawBufferState); + framebuffer->setReadBuffer(GL_BACK); + + framebuffer->setAttachment(GL_FRAMEBUFFER_DEFAULT, GL_BACK, gl::ImageIndex::MakeInvalid(), + this); + + if (mConfig->depthSize > 0) + { + framebuffer->setAttachment(GL_FRAMEBUFFER_DEFAULT, GL_DEPTH, gl::ImageIndex::MakeInvalid(), + this); + } + + if (mConfig->stencilSize > 0) + { + framebuffer->setAttachment(GL_FRAMEBUFFER_DEFAULT, GL_STENCIL, + gl::ImageIndex::MakeInvalid(), this); + } + + return framebuffer; +} } diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/Surface.h b/Source/ThirdParty/ANGLE/src/libANGLE/Surface.h index e163060c5980..e110f5da7b87 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/Surface.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/Surface.h @@ -16,10 +16,12 @@ #include "common/angleutils.h" #include "libANGLE/Error.h" #include "libANGLE/FramebufferAttachment.h" +#include "libANGLE/RefCountObject.h" #include "libANGLE/renderer/SurfaceImpl.h" namespace gl { +class Framebuffer; class Texture; } @@ -48,6 +50,8 @@ class Surface final : public gl::FramebufferAttachmentObject EGLint isPostSubBufferSupported() const; void setSwapInterval(EGLint interval); + void setIsCurrent(bool isCurrent); + void onDestroy(); const Config *getConfig() const; @@ -60,32 +64,56 @@ class Surface final : public gl::FramebufferAttachmentObject EGLenum getTextureFormat() const; EGLenum getTextureTarget() const; - gl::Texture *getBoundTexture() const { return mTexture; } + gl::Texture *getBoundTexture() const { return mTexture.get(); } + gl::Framebuffer *getDefaultFramebuffer() { return mDefaultFramebuffer; } EGLint isFixedSize() const; // FramebufferAttachmentObject implementation - GLsizei getAttachmentWidth(const gl::FramebufferAttachment::Target &/*target*/) const override { return getWidth(); } - GLsizei getAttachmentHeight(const gl::FramebufferAttachment::Target &/*target*/) const override { return getHeight(); } + gl::Extents getAttachmentSize(const gl::FramebufferAttachment::Target &target) const override; GLenum getAttachmentInternalFormat(const gl::FramebufferAttachment::Target &target) const override; GLsizei getAttachmentSamples(const gl::FramebufferAttachment::Target &target) const override; + void onAttach() override {} + void onDetach() override {} + GLuint getId() const override; + + bool flexibleSurfaceCompatibilityRequested() const + { + return mFlexibleSurfaceCompatibilityRequested; + } + EGLint getOrientation() const { return mOrientation; } + + bool directComposition() const { return mDirectComposition; } + private: virtual ~Surface(); rx::FramebufferAttachmentObjectImpl *getAttachmentImpl() const override { return mImplementation; } + gl::Framebuffer *createDefaultFramebuffer(); + + // ANGLE-only method, used internally + friend class gl::Texture; + void releaseTexImageFromTexture(); + rx::SurfaceImpl *mImplementation; + gl::Framebuffer *mDefaultFramebuffer; + int mCurrentCount; + bool mDestroyed; EGLint mType; const egl::Config *mConfig; bool mPostSubBufferRequested; + bool mFlexibleSurfaceCompatibilityRequested; bool mFixedSize; size_t mFixedWidth; size_t mFixedHeight; + bool mDirectComposition; + EGLenum mTextureFormat; EGLenum mTextureTarget; @@ -93,7 +121,9 @@ class Surface final : public gl::FramebufferAttachmentObject EGLenum mRenderBuffer; // Render buffer EGLenum mSwapBehavior; // Buffer swap behavior - gl::Texture *mTexture; + EGLint mOrientation; + + BindingPointer mTexture; }; } diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/Surface_unittest.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/Surface_unittest.cpp index e453658022f8..2f40d7d3d373 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/Surface_unittest.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/Surface_unittest.cpp @@ -6,11 +6,17 @@ #include "gmock/gmock.h" #include "gtest/gtest.h" +#include "libANGLE/angletypes.h" #include "libANGLE/AttributeMap.h" #include "libANGLE/Config.h" +#include "libANGLE/Data.h" +#include "libANGLE/State.h" #include "libANGLE/Surface.h" +#include "libANGLE/renderer/FramebufferImpl_mock.h" #include "libANGLE/renderer/SurfaceImpl.h" +using namespace rx; + namespace { @@ -20,47 +26,38 @@ class MockSurfaceImpl : public rx::SurfaceImpl virtual ~MockSurfaceImpl() { destroy(); } MOCK_METHOD0(initialize, egl::Error()); + MOCK_METHOD1(createDefaultFramebuffer, + rx::FramebufferImpl *(const gl::Framebuffer::Data &data)); MOCK_METHOD0(swap, egl::Error()); MOCK_METHOD4(postSubBuffer, egl::Error(EGLint, EGLint, EGLint, EGLint)); MOCK_METHOD2(querySurfacePointerANGLE, egl::Error(EGLint, void**)); - MOCK_METHOD1(bindTexImage, egl::Error(EGLint)); + MOCK_METHOD2(bindTexImage, egl::Error(gl::Texture*, EGLint)); MOCK_METHOD1(releaseTexImage, egl::Error(EGLint)); MOCK_METHOD1(setSwapInterval, void(EGLint)); MOCK_CONST_METHOD0(getWidth, EGLint()); MOCK_CONST_METHOD0(getHeight, EGLint()); MOCK_CONST_METHOD0(isPostSubBufferSupported, EGLint(void)); + MOCK_CONST_METHOD0(getSwapBehavior, EGLint(void)); MOCK_METHOD2(getAttachmentRenderTarget, gl::Error(const gl::FramebufferAttachment::Target &, rx::FramebufferAttachmentRenderTarget **)); MOCK_METHOD0(destroy, void()); }; -class SurfaceTest : public testing::Test +TEST(SurfaceTest, DestructionDeletesImpl) { - protected: - virtual void SetUp() - { - mImpl = new MockSurfaceImpl; - EXPECT_CALL(*mImpl, destroy()); - mSurface = new egl::Surface(mImpl, EGL_WINDOW_BIT, &mConfig, egl::AttributeMap()); - } + MockFramebufferImpl *framebuffer = new MockFramebufferImpl; - virtual void TearDown() - { - mSurface->release(); - } + MockSurfaceImpl *impl = new MockSurfaceImpl; + EXPECT_CALL(*impl, getSwapBehavior()); + EXPECT_CALL(*impl, createDefaultFramebuffer(testing::_)).WillOnce(testing::Return(framebuffer)); - MockSurfaceImpl *mImpl; - egl::Surface *mSurface; - egl::Config mConfig; -}; + egl::Config config; + egl::Surface *surface = new egl::Surface(impl, EGL_WINDOW_BIT, &config, egl::AttributeMap()); -TEST_F(SurfaceTest, DestructionDeletesImpl) -{ - MockSurfaceImpl *impl = new MockSurfaceImpl; + EXPECT_CALL(*framebuffer, destroy()).Times(1).RetiresOnSaturation(); EXPECT_CALL(*impl, destroy()).Times(1).RetiresOnSaturation(); - egl::Surface *surface = new egl::Surface(impl, EGL_WINDOW_BIT, &mConfig, egl::AttributeMap()); - surface->release(); + surface->onDestroy(); // Only needed because the mock is leaked if bugs are present, // which logs an error, but does not cause the test to fail. diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/Texture.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/Texture.cpp index 437ba0d08ffd..702ea599803a 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/Texture.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/Texture.cpp @@ -11,7 +11,9 @@ #include "common/mathutil.h" #include "common/utilities.h" #include "libANGLE/Config.h" +#include "libANGLE/Context.h" #include "libANGLE/Data.h" +#include "libANGLE/Image.h" #include "libANGLE/Surface.h" #include "libANGLE/formatutils.h" @@ -45,14 +47,11 @@ static size_t GetImageDescIndex(GLenum target, size_t level) return IsCubeMapTextureTarget(target) ? ((level * 6) + CubeMapTextureTargetToLayerIndex(target)) : level; } -unsigned int Texture::mCurrentTextureSerial = 1; - Texture::Texture(rx::TextureImpl *impl, GLuint id, GLenum target) - : FramebufferAttachmentObject(id), + : egl::ImageSibling(id), mTexture(impl), - mTextureSerial(issueTextureSerial()), - mUsage(GL_NONE), - mImmutableLevelCount(0), + mLabel(), + mTextureState(), mTarget(target), mImageDescs(IMPLEMENTATION_MAX_TEXTURE_LEVELS * (target == GL_TEXTURE_CUBE_MAP ? 6 : 1)), mCompletenessCache(), @@ -70,20 +69,210 @@ Texture::~Texture() SafeDelete(mTexture); } +void Texture::setLabel(const std::string &label) +{ + mLabel = label; +} + +const std::string &Texture::getLabel() const +{ + return mLabel; +} + GLenum Texture::getTarget() const { return mTarget; } +void Texture::setSwizzleRed(GLenum swizzleRed) +{ + mTextureState.swizzleRed = swizzleRed; +} + +GLenum Texture::getSwizzleRed() const +{ + return mTextureState.swizzleRed; +} + +void Texture::setSwizzleGreen(GLenum swizzleGreen) +{ + mTextureState.swizzleGreen = swizzleGreen; +} + +GLenum Texture::getSwizzleGreen() const +{ + return mTextureState.swizzleGreen; +} + +void Texture::setSwizzleBlue(GLenum swizzleBlue) +{ + mTextureState.swizzleBlue = swizzleBlue; +} + +GLenum Texture::getSwizzleBlue() const +{ + return mTextureState.swizzleBlue; +} + +void Texture::setSwizzleAlpha(GLenum swizzleAlpha) +{ + mTextureState.swizzleAlpha = swizzleAlpha; +} + +GLenum Texture::getSwizzleAlpha() const +{ + return mTextureState.swizzleAlpha; +} + +void Texture::setMinFilter(GLenum minFilter) +{ + mTextureState.samplerState.minFilter = minFilter; +} + +GLenum Texture::getMinFilter() const +{ + return mTextureState.samplerState.minFilter; +} + +void Texture::setMagFilter(GLenum magFilter) +{ + mTextureState.samplerState.magFilter = magFilter; +} + +GLenum Texture::getMagFilter() const +{ + return mTextureState.samplerState.magFilter; +} + +void Texture::setWrapS(GLenum wrapS) +{ + mTextureState.samplerState.wrapS = wrapS; +} + +GLenum Texture::getWrapS() const +{ + return mTextureState.samplerState.wrapS; +} + +void Texture::setWrapT(GLenum wrapT) +{ + mTextureState.samplerState.wrapT = wrapT; +} + +GLenum Texture::getWrapT() const +{ + return mTextureState.samplerState.wrapT; +} + +void Texture::setWrapR(GLenum wrapR) +{ + mTextureState.samplerState.wrapR = wrapR; +} + +GLenum Texture::getWrapR() const +{ + return mTextureState.samplerState.wrapR; +} + +void Texture::setMaxAnisotropy(float maxAnisotropy) +{ + mTextureState.samplerState.maxAnisotropy = maxAnisotropy; +} + +float Texture::getMaxAnisotropy() const +{ + return mTextureState.samplerState.maxAnisotropy; +} + +void Texture::setMinLod(GLfloat minLod) +{ + mTextureState.samplerState.minLod = minLod; +} + +GLfloat Texture::getMinLod() const +{ + return mTextureState.samplerState.minLod; +} + +void Texture::setMaxLod(GLfloat maxLod) +{ + mTextureState.samplerState.maxLod = maxLod; +} + +GLfloat Texture::getMaxLod() const +{ + return mTextureState.samplerState.maxLod; +} + +void Texture::setCompareMode(GLenum compareMode) +{ + mTextureState.samplerState.compareMode = compareMode; +} + +GLenum Texture::getCompareMode() const +{ + return mTextureState.samplerState.compareMode; +} + +void Texture::setCompareFunc(GLenum compareFunc) +{ + mTextureState.samplerState.compareFunc = compareFunc; +} + +GLenum Texture::getCompareFunc() const +{ + return mTextureState.samplerState.compareFunc; +} + +const SamplerState &Texture::getSamplerState() const +{ + return mTextureState.samplerState; +} + +void Texture::setBaseLevel(GLuint baseLevel) +{ + mTextureState.baseLevel = baseLevel; +} + +GLuint Texture::getBaseLevel() const +{ + return mTextureState.baseLevel; +} + +void Texture::setMaxLevel(GLuint maxLevel) +{ + mTextureState.maxLevel = maxLevel; +} + +GLuint Texture::getMaxLevel() const +{ + return mTextureState.maxLevel; +} + +bool Texture::getImmutableFormat() const +{ + return mTextureState.immutableFormat; +} + +GLuint Texture::getImmutableLevels() const +{ + return mTextureState.immutableLevels; +} + void Texture::setUsage(GLenum usage) { - mUsage = usage; + mTextureState.usage = usage; getImplementation()->setUsage(usage); } GLenum Texture::getUsage() const { - return mUsage; + return mTextureState.usage; +} + +const TextureState &Texture::getTextureState() const +{ + return mTextureState; } size_t Texture::getWidth(GLenum target, size_t level) const @@ -112,7 +301,7 @@ GLenum Texture::getInternalFormat(GLenum target, size_t level) const bool Texture::isSamplerComplete(const SamplerState &samplerState, const Data &data) const { - const ImageDesc &baseImageDesc = getImageDesc(getBaseImageTarget(), samplerState.baseLevel); + const ImageDesc &baseImageDesc = getImageDesc(getBaseImageTarget(), mTextureState.baseLevel); const TextureCaps &textureCaps = data.textureCaps->get(baseImageDesc.internalFormat); if (!mCompletenessCache.cacheValid || mCompletenessCache.samplerState != samplerState || @@ -130,6 +319,11 @@ bool Texture::isSamplerComplete(const SamplerState &samplerState, const Data &da return mCompletenessCache.samplerComplete; } +bool Texture::isMipmapComplete() const +{ + return computeMipmapCompleteness(); +} + // Tests for cube texture completeness. [OpenGL ES 2.0.24] section 3.7.10 page 81. bool Texture::isCubeComplete() const { @@ -155,76 +349,103 @@ bool Texture::isCubeComplete() const return true; } -unsigned int Texture::getTextureSerial() const -{ - return mTextureSerial; -} - -unsigned int Texture::issueTextureSerial() -{ - return mCurrentTextureSerial++; -} - -bool Texture::isImmutable() const +size_t Texture::getMipCompleteLevels() const { - return (mImmutableLevelCount > 0); + const ImageDesc &baseImageDesc = getImageDesc(getBaseImageTarget(), 0); + if (mTarget == GL_TEXTURE_3D) + { + const int maxDim = std::max(std::max(baseImageDesc.size.width, baseImageDesc.size.height), + baseImageDesc.size.depth); + return log2(maxDim) + 1; + } + else + { + return log2(std::max(baseImageDesc.size.width, baseImageDesc.size.height)) + 1; + } } -int Texture::immutableLevelCount() +egl::Surface *Texture::getBoundSurface() const { - return mImmutableLevelCount; + return mBoundSurface; } -Error Texture::setImage(GLenum target, size_t level, GLenum internalFormat, const Extents &size, GLenum format, GLenum type, - const PixelUnpackState &unpack, const uint8_t *pixels) +Error Texture::setImage(const PixelUnpackState &unpackState, + GLenum target, + size_t level, + GLenum internalFormat, + const Extents &size, + GLenum format, + GLenum type, + const uint8_t *pixels) { ASSERT(target == mTarget || (mTarget == GL_TEXTURE_CUBE_MAP && IsCubeMapTextureTarget(target))); - Error error = mTexture->setImage(target, level, internalFormat, size, format, type, unpack, pixels); + // Release from previous calls to eglBindTexImage, to avoid calling the Impl after + releaseTexImageInternal(); + orphanImages(); + + Error error = + mTexture->setImage(target, level, internalFormat, size, format, type, unpackState, pixels); if (error.isError()) { return error; } - releaseTexImage(); - setImageDesc(target, level, ImageDesc(size, GetSizedInternalFormat(internalFormat, type))); return Error(GL_NO_ERROR); } -Error Texture::setSubImage(GLenum target, size_t level, const Box &area, GLenum format, GLenum type, - const PixelUnpackState &unpack, const uint8_t *pixels) +Error Texture::setSubImage(const PixelUnpackState &unpackState, + GLenum target, + size_t level, + const Box &area, + GLenum format, + GLenum type, + const uint8_t *pixels) { ASSERT(target == mTarget || (mTarget == GL_TEXTURE_CUBE_MAP && IsCubeMapTextureTarget(target))); - - return mTexture->setSubImage(target, level, area, format, type, unpack, pixels); + return mTexture->setSubImage(target, level, area, format, type, unpackState, pixels); } -Error Texture::setCompressedImage(GLenum target, size_t level, GLenum internalFormat, const Extents &size, - const PixelUnpackState &unpack, const uint8_t *pixels) +Error Texture::setCompressedImage(const PixelUnpackState &unpackState, + GLenum target, + size_t level, + GLenum internalFormat, + const Extents &size, + size_t imageSize, + const uint8_t *pixels) { ASSERT(target == mTarget || (mTarget == GL_TEXTURE_CUBE_MAP && IsCubeMapTextureTarget(target))); - Error error = mTexture->setCompressedImage(target, level, internalFormat, size, unpack, pixels); + // Release from previous calls to eglBindTexImage, to avoid calling the Impl after + releaseTexImageInternal(); + orphanImages(); + + Error error = mTexture->setCompressedImage(target, level, internalFormat, size, unpackState, + imageSize, pixels); if (error.isError()) { return error; } - releaseTexImage(); - setImageDesc(target, level, ImageDesc(size, GetSizedInternalFormat(internalFormat, GL_UNSIGNED_BYTE))); return Error(GL_NO_ERROR); } -Error Texture::setCompressedSubImage(GLenum target, size_t level, const Box &area, GLenum format, - const PixelUnpackState &unpack, const uint8_t *pixels) +Error Texture::setCompressedSubImage(const PixelUnpackState &unpackState, + GLenum target, + size_t level, + const Box &area, + GLenum format, + size_t imageSize, + const uint8_t *pixels) { ASSERT(target == mTarget || (mTarget == GL_TEXTURE_CUBE_MAP && IsCubeMapTextureTarget(target))); - return mTexture->setCompressedSubImage(target, level, area, format, unpack, pixels); + return mTexture->setCompressedSubImage(target, level, area, format, unpackState, imageSize, + pixels); } Error Texture::copyImage(GLenum target, size_t level, const Rectangle &sourceArea, GLenum internalFormat, @@ -232,14 +453,16 @@ Error Texture::copyImage(GLenum target, size_t level, const Rectangle &sourceAre { ASSERT(target == mTarget || (mTarget == GL_TEXTURE_CUBE_MAP && IsCubeMapTextureTarget(target))); + // Release from previous calls to eglBindTexImage, to avoid calling the Impl after + releaseTexImageInternal(); + orphanImages(); + Error error = mTexture->copyImage(target, level, sourceArea, internalFormat, source); if (error.isError()) { return error; } - releaseTexImage(); - setImageDesc(target, level, ImageDesc(Extents(sourceArea.width, sourceArea.height, 1), GetSizedInternalFormat(internalFormat, GL_UNSIGNED_BYTE))); @@ -258,32 +481,42 @@ Error Texture::setStorage(GLenum target, size_t levels, GLenum internalFormat, c { ASSERT(target == mTarget); + // Release from previous calls to eglBindTexImage, to avoid calling the Impl after + releaseTexImageInternal(); + orphanImages(); + Error error = mTexture->setStorage(target, levels, internalFormat, size); if (error.isError()) { return error; } - releaseTexImage(); - - mImmutableLevelCount = static_cast(levels); + mTextureState.immutableFormat = true; + mTextureState.immutableLevels = static_cast(levels); clearImageDescs(); setImageDescChain(levels, size, internalFormat); return Error(GL_NO_ERROR); } - Error Texture::generateMipmaps() { - Error error = mTexture->generateMipmaps(getSamplerState()); + // Release from previous calls to eglBindTexImage, to avoid calling the Impl after + releaseTexImageInternal(); + + // EGL_KHR_gl_image states that images are only orphaned when generating mipmaps if the texture + // is not mip complete. + if (!isMipmapComplete()) + { + orphanImages(); + } + + Error error = mTexture->generateMipmaps(mTextureState); if (error.isError()) { return error; } - releaseTexImage(); - const ImageDesc &baseImageInfo = getImageDesc(getBaseImageTarget(), 0); size_t mipLevels = log2(std::max(std::max(baseImageInfo.size.width, baseImageInfo.size.height), baseImageInfo.size.depth)) + 1; setImageDescChain(mipLevels, baseImageInfo.size, baseImageInfo.internalFormat); @@ -293,18 +526,19 @@ Error Texture::generateMipmaps() void Texture::setImageDescChain(size_t levels, Extents baseSize, GLenum sizedInternalFormat) { - for (size_t level = 0; level < levels; level++) + for (int level = 0; level < static_cast(levels); level++) { - Extents levelSize(std::max(baseSize.width >> level, 1), - std::max(baseSize.height >> level, 1), - (mTarget == GL_TEXTURE_2D_ARRAY) ? baseSize.depth : std::max(baseSize.depth >> level, 1)); + Extents levelSize( + std::max(baseSize.width >> level, 1), std::max(baseSize.height >> level, 1), + (mTarget == GL_TEXTURE_2D_ARRAY) ? baseSize.depth + : std::max(baseSize.depth >> level, 1)); ImageDesc levelInfo(levelSize, sizedInternalFormat); if (mTarget == GL_TEXTURE_CUBE_MAP) { - for (size_t face = FirstCubeMapTextureTarget; face <= LastCubeMapTextureTarget; face++) + for (GLenum face = FirstCubeMapTextureTarget; face <= LastCubeMapTextureTarget; face++) { - setImageDesc(static_cast(face), level, levelInfo); + setImageDesc(face, level, levelInfo); } } else @@ -354,11 +588,15 @@ void Texture::clearImageDescs() mCompletenessCache.cacheValid = false; } -void Texture::bindTexImage(egl::Surface *surface) +void Texture::bindTexImageFromSurface(egl::Surface *surface) { ASSERT(surface); - releaseTexImage(); + if (mBoundSurface) + { + releaseTexImageFromSurface(); + } + mTexture->bindTexImage(surface); mBoundSurface = surface; @@ -369,40 +607,65 @@ void Texture::bindTexImage(egl::Surface *surface) setImageDesc(mTarget, 0, desc); } -void Texture::releaseTexImage() +void Texture::releaseTexImageFromSurface() +{ + ASSERT(mBoundSurface); + mBoundSurface = nullptr; + mTexture->releaseTexImage(); + + // Erase the image info for level 0 + ASSERT(mTarget == GL_TEXTURE_2D); + clearImageDesc(mTarget, 0); +} + +void Texture::releaseTexImageInternal() { if (mBoundSurface) { - mBoundSurface = NULL; - mTexture->releaseTexImage(); + // Notify the surface + mBoundSurface->releaseTexImageFromTexture(); - // Erase the image info for level 0 - ASSERT(mTarget == GL_TEXTURE_2D); - clearImageDesc(mTarget, 0); + // Then, call the same method as from the surface + releaseTexImageFromSurface(); } } -GLenum Texture::getBaseImageTarget() const +Error Texture::setEGLImageTarget(GLenum target, egl::Image *imageTarget) { - return mTarget == GL_TEXTURE_CUBE_MAP ? FirstCubeMapTextureTarget : mTarget; -} + ASSERT(target == mTarget); + ASSERT(target == GL_TEXTURE_2D); -size_t Texture::getExpectedMipLevels() const -{ - const ImageDesc &baseImageDesc = getImageDesc(getBaseImageTarget(), 0); - if (mTarget == GL_TEXTURE_3D) - { - return log2(std::max(std::max(baseImageDesc.size.width, baseImageDesc.size.height), baseImageDesc.size.depth)) + 1; - } - else + // Release from previous calls to eglBindTexImage, to avoid calling the Impl after + releaseTexImageInternal(); + orphanImages(); + + Error error = mTexture->setEGLImageTarget(target, imageTarget); + if (error.isError()) { - return log2(std::max(baseImageDesc.size.width, baseImageDesc.size.height)) + 1; + return error; } + + setTargetImage(imageTarget); + + Extents size(static_cast(imageTarget->getWidth()), + static_cast(imageTarget->getHeight()), 1); + GLenum internalFormat = imageTarget->getInternalFormat(); + GLenum type = GetInternalFormatInfo(internalFormat).type; + + clearImageDescs(); + setImageDesc(target, 0, ImageDesc(size, GetSizedInternalFormat(internalFormat, type))); + + return Error(GL_NO_ERROR); +} + +GLenum Texture::getBaseImageTarget() const +{ + return mTarget == GL_TEXTURE_CUBE_MAP ? FirstCubeMapTextureTarget : mTarget; } bool Texture::computeSamplerCompleteness(const SamplerState &samplerState, const Data &data) const { - const ImageDesc &baseImageDesc = getImageDesc(getBaseImageTarget(), samplerState.baseLevel); + const ImageDesc &baseImageDesc = getImageDesc(getBaseImageTarget(), mTextureState.baseLevel); if (baseImageDesc.size.width == 0 || baseImageDesc.size.height == 0 || baseImageDesc.size.depth == 0) { return false; @@ -439,7 +702,7 @@ bool Texture::computeSamplerCompleteness(const SamplerState &samplerState, const } } - if (!computeMipmapCompleteness(samplerState)) + if (!computeMipmapCompleteness()) { return false; } @@ -473,19 +736,19 @@ bool Texture::computeSamplerCompleteness(const SamplerState &samplerState, const return true; } -bool Texture::computeMipmapCompleteness(const gl::SamplerState &samplerState) const +bool Texture::computeMipmapCompleteness() const { - size_t expectedMipLevels = getExpectedMipLevels(); + size_t expectedMipLevels = getMipCompleteLevels(); - size_t maxLevel = std::min(expectedMipLevels, samplerState.maxLevel + 1); + size_t maxLevel = std::min(expectedMipLevels, mTextureState.maxLevel + 1); - for (size_t level = samplerState.baseLevel; level < maxLevel; level++) + for (size_t level = mTextureState.baseLevel; level < maxLevel; level++) { if (mTarget == GL_TEXTURE_CUBE_MAP) { for (GLenum face = FirstCubeMapTextureTarget; face <= LastCubeMapTextureTarget; face++) { - if (!computeLevelCompleteness(face, level, samplerState)) + if (!computeLevelCompleteness(face, level)) { return false; } @@ -493,7 +756,7 @@ bool Texture::computeMipmapCompleteness(const gl::SamplerState &samplerState) co } else { - if (!computeLevelCompleteness(mTarget, level, samplerState)) + if (!computeLevelCompleteness(mTarget, level)) { return false; } @@ -503,47 +766,48 @@ bool Texture::computeMipmapCompleteness(const gl::SamplerState &samplerState) co return true; } - -bool Texture::computeLevelCompleteness(GLenum target, size_t level, const gl::SamplerState &samplerState) const +bool Texture::computeLevelCompleteness(GLenum target, size_t level) const { ASSERT(level < IMPLEMENTATION_MAX_TEXTURE_LEVELS); - if (isImmutable()) + if (mTextureState.immutableFormat) { return true; } - const ImageDesc &baseImageDesc = getImageDesc(getBaseImageTarget(), samplerState.baseLevel); + const ImageDesc &baseImageDesc = getImageDesc(getBaseImageTarget(), mTextureState.baseLevel); if (baseImageDesc.size.width == 0 || baseImageDesc.size.height == 0 || baseImageDesc.size.depth == 0) { return false; } - // The base image level is complete if the width and height are positive - if (level == 0) + const ImageDesc &levelImageDesc = getImageDesc(target, level); + if (levelImageDesc.size.width == 0 || levelImageDesc.size.height == 0 || + levelImageDesc.size.depth == 0) { - return true; + return false; } - const ImageDesc &levelImageDesc = getImageDesc(target, level); if (levelImageDesc.internalFormat != baseImageDesc.internalFormat) { return false; } - if (levelImageDesc.size.width != std::max(1, baseImageDesc.size.width >> level)) + ASSERT(level >= mTextureState.baseLevel); + const size_t relativeLevel = level - mTextureState.baseLevel; + if (levelImageDesc.size.width != std::max(1, baseImageDesc.size.width >> relativeLevel)) { return false; } - if (levelImageDesc.size.height != std::max(1, baseImageDesc.size.height >> level)) + if (levelImageDesc.size.height != std::max(1, baseImageDesc.size.height >> relativeLevel)) { return false; } if (mTarget == GL_TEXTURE_3D) { - if (levelImageDesc.size.depth != std::max(1, baseImageDesc.size.depth >> level)) + if (levelImageDesc.size.depth != std::max(1, baseImageDesc.size.depth >> relativeLevel)) { return false; } @@ -569,14 +833,9 @@ Texture::SamplerCompletenessCache::SamplerCompletenessCache() { } -GLsizei Texture::getAttachmentWidth(const gl::FramebufferAttachment::Target &target) const -{ - return static_cast(getWidth(target.textureIndex().type, target.textureIndex().mipIndex)); -} - -GLsizei Texture::getAttachmentHeight(const gl::FramebufferAttachment::Target &target) const +Extents Texture::getAttachmentSize(const gl::FramebufferAttachment::Target &target) const { - return static_cast(getHeight(target.textureIndex().type, target.textureIndex().mipIndex)); + return getImageDesc(target.textureIndex().type, target.textureIndex().mipIndex).size; } GLenum Texture::getAttachmentInternalFormat(const gl::FramebufferAttachment::Target &target) const @@ -590,4 +849,18 @@ GLsizei Texture::getAttachmentSamples(const gl::FramebufferAttachment::Target &/ return 0; } +void Texture::onAttach() +{ + addRef(); +} + +void Texture::onDetach() +{ + release(); +} + +GLuint Texture::getId() const +{ + return id(); +} } diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/Texture.h b/Source/ThirdParty/ANGLE/src/libANGLE/Texture.h index 0c3d5ecdb38a..f6cddf14ca34 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/Texture.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/Texture.h @@ -15,9 +15,11 @@ #include "angle_gl.h" #include "common/debug.h" #include "libANGLE/Caps.h" +#include "libANGLE/Debug.h" #include "libANGLE/Constants.h" #include "libANGLE/Error.h" #include "libANGLE/FramebufferAttachment.h" +#include "libANGLE/Image.h" #include "libANGLE/angletypes.h" #include "libANGLE/renderer/TextureImpl.h" @@ -31,85 +33,168 @@ namespace gl class Framebuffer; struct Data; -bool IsMipmapFiltered(const gl::SamplerState &samplerState); +bool IsMipmapFiltered(const SamplerState &samplerState); -class Texture final : public FramebufferAttachmentObject +class Texture final : public egl::ImageSibling, + public FramebufferAttachmentObject, + public LabeledObject { public: Texture(rx::TextureImpl *impl, GLuint id, GLenum target); + ~Texture() override; - virtual ~Texture(); + void setLabel(const std::string &label) override; + const std::string &getLabel() const override; GLenum getTarget() const; - const SamplerState &getSamplerState() const { return mSamplerState; } - SamplerState &getSamplerState() { return mSamplerState; } + void setSwizzleRed(GLenum swizzleRed); + GLenum getSwizzleRed() const; - void setUsage(GLenum usage); - GLenum getUsage() const; + void setSwizzleGreen(GLenum swizzleGreen); + GLenum getSwizzleGreen() const; - size_t getWidth(GLenum target, size_t level) const; - size_t getHeight(GLenum target, size_t level) const; - size_t getDepth(GLenum target, size_t level) const; - GLenum getInternalFormat(GLenum target, size_t level) const; + void setSwizzleBlue(GLenum swizzleBlue); + GLenum getSwizzleBlue() const; - bool isSamplerComplete(const SamplerState &samplerState, const Data &data) const; - bool isCubeComplete() const; + void setSwizzleAlpha(GLenum swizzleAlpha); + GLenum getSwizzleAlpha() const; + + void setMinFilter(GLenum minFilter); + GLenum getMinFilter() const; + + void setMagFilter(GLenum magFilter); + GLenum getMagFilter() const; + + void setWrapS(GLenum wrapS); + GLenum getWrapS() const; + + void setWrapT(GLenum wrapT); + GLenum getWrapT() const; + + void setWrapR(GLenum wrapR); + GLenum getWrapR() const; + + void setMaxAnisotropy(float maxAnisotropy); + float getMaxAnisotropy() const; + + void setMinLod(GLfloat minLod); + GLfloat getMinLod() const; + + void setMaxLod(GLfloat maxLod); + GLfloat getMaxLod() const; - virtual Error setImage(GLenum target, size_t level, GLenum internalFormat, const Extents &size, GLenum format, GLenum type, - const PixelUnpackState &unpack, const uint8_t *pixels); - virtual Error setSubImage(GLenum target, size_t level, const Box &area, GLenum format, GLenum type, - const PixelUnpackState &unpack, const uint8_t *pixels); + void setCompareMode(GLenum compareMode); + GLenum getCompareMode() const; - virtual Error setCompressedImage(GLenum target, size_t level, GLenum internalFormat, const Extents &size, - const PixelUnpackState &unpack, const uint8_t *pixels); - virtual Error setCompressedSubImage(GLenum target, size_t level, const Box &area, GLenum format, - const PixelUnpackState &unpack, const uint8_t *pixels); + void setCompareFunc(GLenum compareFunc); + GLenum getCompareFunc() const; - virtual Error copyImage(GLenum target, size_t level, const Rectangle &sourceArea, GLenum internalFormat, - const Framebuffer *source); - virtual Error copySubImage(GLenum target, size_t level, const Offset &destOffset, const Rectangle &sourceArea, - const Framebuffer *source); + const SamplerState &getSamplerState() const; - virtual Error setStorage(GLenum target, size_t levels, GLenum internalFormat, const Extents &size); + void setBaseLevel(GLuint baseLevel); + GLuint getBaseLevel() const; - virtual Error generateMipmaps(); + void setMaxLevel(GLuint maxLevel); + GLuint getMaxLevel() const; - // Texture serials provide a unique way of identifying a Texture that isn't a raw pointer. - // "id" is not good enough, as Textures can be deleted, then re-allocated with the same id. - unsigned int getTextureSerial() const; + bool getImmutableFormat() const; - bool isImmutable() const; - GLsizei immutableLevelCount(); + GLuint getImmutableLevels() const; - void bindTexImage(egl::Surface *surface); - void releaseTexImage(); + void setUsage(GLenum usage); + GLenum getUsage() const; + + const TextureState &getTextureState() const; + + size_t getWidth(GLenum target, size_t level) const; + size_t getHeight(GLenum target, size_t level) const; + size_t getDepth(GLenum target, size_t level) const; + GLenum getInternalFormat(GLenum target, size_t level) const; + + bool isSamplerComplete(const SamplerState &samplerState, const Data &data) const; + bool isMipmapComplete() const; + bool isCubeComplete() const; + size_t getMipCompleteLevels() const; + + Error setImage(const PixelUnpackState &unpackState, + GLenum target, + size_t level, + GLenum internalFormat, + const Extents &size, + GLenum format, + GLenum type, + const uint8_t *pixels); + Error setSubImage(const PixelUnpackState &unpackState, + GLenum target, + size_t level, + const Box &area, + GLenum format, + GLenum type, + const uint8_t *pixels); + + Error setCompressedImage(const PixelUnpackState &unpackState, + GLenum target, + size_t level, + GLenum internalFormat, + const Extents &size, + size_t imageSize, + const uint8_t *pixels); + Error setCompressedSubImage(const PixelUnpackState &unpackState, + GLenum target, + size_t level, + const Box &area, + GLenum format, + size_t imageSize, + const uint8_t *pixels); + + Error copyImage(GLenum target, + size_t level, + const Rectangle &sourceArea, + GLenum internalFormat, + const Framebuffer *source); + Error copySubImage(GLenum target, + size_t level, + const Offset &destOffset, + const Rectangle &sourceArea, + const Framebuffer *source); + + Error setStorage(GLenum target, size_t levels, GLenum internalFormat, const Extents &size); + + Error setEGLImageTarget(GLenum target, egl::Image *imageTarget); + + Error generateMipmaps(); + + egl::Surface *getBoundSurface() const; rx::TextureImpl *getImplementation() { return mTexture; } const rx::TextureImpl *getImplementation() const { return mTexture; } - static const GLuint INCOMPLETE_TEXTURE_ID = static_cast(-1); // Every texture takes an id at creation time. The value is arbitrary because it is never registered with the resource manager. - // FramebufferAttachmentObject implementation - GLsizei getAttachmentWidth(const FramebufferAttachment::Target &target) const override; - GLsizei getAttachmentHeight(const FramebufferAttachment::Target &target) const override; + Extents getAttachmentSize(const FramebufferAttachment::Target &target) const override; GLenum getAttachmentInternalFormat(const FramebufferAttachment::Target &target) const override; GLsizei getAttachmentSamples(const FramebufferAttachment::Target &target) const override; + void onAttach() override; + void onDetach() override; + GLuint getId() const override; + private: rx::FramebufferAttachmentObjectImpl *getAttachmentImpl() const override { return mTexture; } - static unsigned int issueTextureSerial(); + + // ANGLE-only method, used internally + friend class egl::Surface; + void bindTexImageFromSurface(egl::Surface *surface); + void releaseTexImageFromSurface(); rx::TextureImpl *mTexture; - SamplerState mSamplerState; - GLenum mUsage; + std::string mLabel; - GLsizei mImmutableLevelCount; + TextureState mTextureState; GLenum mTarget; - struct ImageDesc { Extents size; @@ -119,21 +204,18 @@ class Texture final : public FramebufferAttachmentObject ImageDesc(const Extents &size, GLenum internalFormat); }; - const unsigned int mTextureSerial; - static unsigned int mCurrentTextureSerial; - GLenum getBaseImageTarget() const; - size_t getExpectedMipLevels() const; bool computeSamplerCompleteness(const SamplerState &samplerState, const Data &data) const; - bool computeMipmapCompleteness(const gl::SamplerState &samplerState) const; - bool computeLevelCompleteness(GLenum target, size_t level, const gl::SamplerState &samplerState) const; + bool computeMipmapCompleteness() const; + bool computeLevelCompleteness(GLenum target, size_t level) const; const ImageDesc &getImageDesc(GLenum target, size_t level) const; void setImageDesc(GLenum target, size_t level, const ImageDesc &desc); void setImageDescChain(size_t levels, Extents baseSize, GLenum sizedInternalFormat); void clearImageDesc(GLenum target, size_t level); void clearImageDescs(); + void releaseTexImageInternal(); std::vector mImageDescs; diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/TransformFeedback.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/TransformFeedback.cpp index 274872e3fb9d..6ee17006c32d 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/TransformFeedback.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/TransformFeedback.cpp @@ -8,25 +8,34 @@ #include "libANGLE/Buffer.h" #include "libANGLE/Caps.h" +#include "libANGLE/Program.h" +#include "libANGLE/renderer/ImplFactory.h" #include "libANGLE/renderer/TransformFeedbackImpl.h" namespace gl { -TransformFeedback::TransformFeedback(rx::TransformFeedbackImpl* impl, GLuint id, const Caps &caps) +TransformFeedback::TransformFeedback(rx::ImplFactory *implFactory, GLuint id, const Caps &caps) : RefCountObject(id), - mImplementation(impl), + mImplementation(implFactory->createTransformFeedback()), + mLabel(), mActive(false), mPrimitiveMode(GL_NONE), mPaused(false), + mProgram(nullptr), mGenericBuffer(), mIndexedBuffers(caps.maxTransformFeedbackSeparateAttributes) { - ASSERT(impl != NULL); + ASSERT(mImplementation != nullptr); } TransformFeedback::~TransformFeedback() { + if (mProgram) + { + mProgram->release(); + mProgram = nullptr; + } mGenericBuffer.set(nullptr); for (size_t i = 0; i < mIndexedBuffers.size(); i++) { @@ -36,12 +45,23 @@ TransformFeedback::~TransformFeedback() SafeDelete(mImplementation); } -void TransformFeedback::begin(GLenum primitiveMode) +void TransformFeedback::setLabel(const std::string &label) +{ + mLabel = label; +} + +const std::string &TransformFeedback::getLabel() const +{ + return mLabel; +} + +void TransformFeedback::begin(GLenum primitiveMode, Program *program) { mActive = true; mPrimitiveMode = primitiveMode; mPaused = false; mImplementation->begin(primitiveMode); + bindProgram(program); } void TransformFeedback::end() @@ -50,6 +70,11 @@ void TransformFeedback::end() mPrimitiveMode = GL_NONE; mPaused = false; mImplementation->end(); + if (mProgram) + { + mProgram->release(); + mProgram = nullptr; + } } void TransformFeedback::pause() @@ -79,12 +104,51 @@ GLenum TransformFeedback::getPrimitiveMode() const return mPrimitiveMode; } +void TransformFeedback::bindProgram(Program *program) +{ + if (mProgram != program) + { + if (mProgram != nullptr) + { + mProgram->release(); + } + mProgram = program; + if (mProgram != nullptr) + { + mProgram->addRef(); + } + } +} + +bool TransformFeedback::hasBoundProgram(GLuint program) const +{ + return mProgram != nullptr && mProgram->id() == program; +} + void TransformFeedback::bindGenericBuffer(Buffer *buffer) { mGenericBuffer.set(buffer); mImplementation->bindGenericBuffer(mGenericBuffer); } +void TransformFeedback::detachBuffer(GLuint bufferName) +{ + for (size_t index = 0; index < mIndexedBuffers.size(); index++) + { + if (mIndexedBuffers[index].id() == bufferName) + { + mIndexedBuffers[index].set(nullptr); + mImplementation->bindIndexedBuffer(index, mIndexedBuffers[index]); + } + } + + if (mGenericBuffer.id() == bufferName) + { + mGenericBuffer.set(nullptr); + mImplementation->bindGenericBuffer(mGenericBuffer); + } +} + const BindingPointer &TransformFeedback::getGenericBuffer() const { return mGenericBuffer; diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/TransformFeedback.h b/Source/ThirdParty/ANGLE/src/libANGLE/TransformFeedback.h index 4345499f0904..9e8af2e337cf 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/TransformFeedback.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/TransformFeedback.h @@ -10,11 +10,13 @@ #include "libANGLE/RefCountObject.h" #include "common/angleutils.h" +#include "libANGLE/Debug.h" #include "angle_gl.h" namespace rx { +class ImplFactory; class TransformFeedbackImpl; } @@ -22,14 +24,18 @@ namespace gl { class Buffer; struct Caps; +class Program; -class TransformFeedback : public RefCountObject +class TransformFeedback final : public RefCountObject, public LabeledObject { public: - TransformFeedback(rx::TransformFeedbackImpl* impl, GLuint id, const Caps &caps); + TransformFeedback(rx::ImplFactory *implFactory, GLuint id, const Caps &caps); virtual ~TransformFeedback(); - void begin(GLenum primitiveMode); + void setLabel(const std::string &label) override; + const std::string &getLabel() const override; + + void begin(GLenum primitiveMode, Program *program); void end(); void pause(); void resume(); @@ -38,6 +44,8 @@ class TransformFeedback : public RefCountObject bool isPaused() const; GLenum getPrimitiveMode() const; + bool hasBoundProgram(GLuint program) const; + void bindGenericBuffer(Buffer *buffer); const BindingPointer &getGenericBuffer() const; @@ -45,16 +53,24 @@ class TransformFeedback : public RefCountObject const OffsetBindingPointer &getIndexedBuffer(size_t index) const; size_t getIndexedBufferCount() const; + void detachBuffer(GLuint bufferName); + rx::TransformFeedbackImpl *getImplementation(); const rx::TransformFeedbackImpl *getImplementation() const; private: + void bindProgram(Program *program); + rx::TransformFeedbackImpl* mImplementation; + std::string mLabel; + bool mActive; GLenum mPrimitiveMode; bool mPaused; + Program *mProgram; + BindingPointer mGenericBuffer; std::vector> mIndexedBuffers; }; diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/TransformFeedback_unittest.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/TransformFeedback_unittest.cpp index baddfb7cb865..56d02e2621c3 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/TransformFeedback_unittest.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/TransformFeedback_unittest.cpp @@ -6,10 +6,12 @@ #include "gmock/gmock.h" #include "gtest/gtest.h" +#include "libANGLE/Buffer.h" #include "libANGLE/Caps.h" #include "libANGLE/TransformFeedback.h" #include "libANGLE/renderer/BufferImpl_mock.h" #include "libANGLE/renderer/TransformFeedbackImpl_mock.h" +#include "tests/angle_unittests_utils.h" using ::testing::_; using ::testing::Return; @@ -18,52 +20,58 @@ using ::testing::SetArgumentPointee; namespace { +class MockFactory : public rx::NullFactory +{ + public: + MOCK_METHOD0(createTransformFeedback, rx::TransformFeedbackImpl *()); +}; + class TransformFeedbackTest : public testing::Test { protected: - virtual void SetUp() + TransformFeedbackTest() : mImpl(nullptr), mFeedback(nullptr) {} + + void SetUp() override { + mImpl = new rx::MockTransformFeedbackImpl; + EXPECT_CALL(mMockFactory, createTransformFeedback()) + .WillOnce(Return(mImpl)) + .RetiresOnSaturation(); + // Set a reasonable number of tf attributes mCaps.maxTransformFeedbackSeparateAttributes = 8; - mImpl = new rx::MockTransformFeedbackImpl; EXPECT_CALL(*mImpl, destructor()); - mFeedback = new gl::TransformFeedback(mImpl, 1, mCaps); + mFeedback = new gl::TransformFeedback(&mMockFactory, 1, mCaps); mFeedback->addRef(); } - virtual void TearDown() + void TearDown() override { - mFeedback->release(); + if (mFeedback) + { + mFeedback->release(); + } + + // Only needed because the mock is leaked if bugs are present, + // which logs an error, but does not cause the test to fail. + // Ordinarily mocks are verified when destroyed. + testing::Mock::VerifyAndClear(mImpl); } + MockFactory mMockFactory; rx::MockTransformFeedbackImpl* mImpl; gl::TransformFeedback* mFeedback; gl::Caps mCaps; }; -TEST_F(TransformFeedbackTest, DestructionDeletesImpl) -{ - rx::MockTransformFeedbackImpl* impl = new rx::MockTransformFeedbackImpl; - EXPECT_CALL(*impl, destructor()).Times(1).RetiresOnSaturation(); - - gl::TransformFeedback* feedback = new gl::TransformFeedback(impl, 1, mCaps); - feedback->addRef(); - feedback->release(); - - // Only needed because the mock is leaked if bugs are present, - // which logs an error, but does not cause the test to fail. - // Ordinarily mocks are verified when destroyed. - testing::Mock::VerifyAndClear(impl); -} - TEST_F(TransformFeedbackTest, SideEffectsOfStartAndStop) { testing::InSequence seq; EXPECT_FALSE(mFeedback->isActive()); EXPECT_CALL(*mImpl, begin(GL_TRIANGLES)); - mFeedback->begin(GL_TRIANGLES); + mFeedback->begin(GL_TRIANGLES, nullptr); EXPECT_TRUE(mFeedback->isActive()); EXPECT_EQ(static_cast(GL_TRIANGLES), mFeedback->getPrimitiveMode()); EXPECT_CALL(*mImpl, end()); @@ -77,7 +85,7 @@ TEST_F(TransformFeedbackTest, SideEffectsOfPauseAndResume) EXPECT_FALSE(mFeedback->isActive()); EXPECT_CALL(*mImpl, begin(GL_TRIANGLES)); - mFeedback->begin(GL_TRIANGLES); + mFeedback->begin(GL_TRIANGLES, nullptr); EXPECT_FALSE(mFeedback->isPaused()); EXPECT_CALL(*mImpl, pause()); mFeedback->pause(); @@ -97,35 +105,36 @@ TEST_F(TransformFeedbackTest, BufferBinding) static const size_t bindIndex = 0; - rx::MockTransformFeedbackImpl *feedbackImpl = new rx::MockTransformFeedbackImpl; - EXPECT_CALL(*feedbackImpl, destructor()).Times(1).RetiresOnSaturation(); - - gl::TransformFeedback *feedback = new gl::TransformFeedback(feedbackImpl, 1, mCaps); + EXPECT_EQ(mFeedback->getIndexedBufferCount(), mCaps.maxTransformFeedbackSeparateAttributes); - EXPECT_EQ(feedback->getIndexedBufferCount(), mCaps.maxTransformFeedbackSeparateAttributes); + EXPECT_CALL(*mImpl, bindGenericBuffer(_)); + mFeedback->bindGenericBuffer(buffer); + EXPECT_EQ(mFeedback->getGenericBuffer().get(), buffer); - EXPECT_CALL(*feedbackImpl, bindGenericBuffer(_)); - feedback->bindGenericBuffer(buffer); - EXPECT_EQ(feedback->getGenericBuffer().get(), buffer); - - EXPECT_CALL(*feedbackImpl, bindIndexedBuffer(_, _)); - feedback->bindIndexedBuffer(bindIndex, buffer, 0, 1); - for (size_t i = 0; i < feedback->getIndexedBufferCount(); i++) + EXPECT_CALL(*mImpl, bindIndexedBuffer(_, _)); + mFeedback->bindIndexedBuffer(bindIndex, buffer, 0, 1); + for (size_t i = 0; i < mFeedback->getIndexedBufferCount(); i++) { if (i == bindIndex) { - EXPECT_EQ(feedback->getIndexedBuffer(i).get(), buffer); + EXPECT_EQ(mFeedback->getIndexedBuffer(i).get(), buffer); } else { - EXPECT_EQ(feedback->getIndexedBuffer(i).get(), nullptr); + EXPECT_EQ(mFeedback->getIndexedBuffer(i).get(), nullptr); } } - feedback->addRef(); - feedback->release(); + // force-release the feedback object to ensure the buffer is released. + const size_t releaseCount = mFeedback->getRefCount(); + for (size_t count = 0; count < releaseCount; ++count) + { + mFeedback->release(); + } + + mFeedback = nullptr; testing::Mock::VerifyAndClear(bufferImpl); } -} // namespace +} // anonymous namespace diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/Uniform.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/Uniform.cpp index 24e7f11309e2..bfae3c014fff 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/Uniform.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/Uniform.cpp @@ -13,55 +13,51 @@ namespace gl { -LinkedUniform::LinkedUniform(GLenum type, GLenum precision, const std::string &name, unsigned int arraySize, - const int blockIndex, const sh::BlockMemberInfo &blockInfo) - : type(type), - precision(precision), - name(name), - arraySize(arraySize), - blockIndex(blockIndex), - blockInfo(blockInfo), - data(NULL), - dirty(true), - psRegisterIndex(GL_INVALID_INDEX), - vsRegisterIndex(GL_INVALID_INDEX), - registerCount(0), - registerElement(0) -{ - // 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 (isInDefaultBlock()) - { - size_t bytes = dataSize(); - data = new unsigned char[bytes]; - memset(data, 0, bytes); - registerCount = VariableRowCount(type) * elementCount(); - } +LinkedUniform::LinkedUniform() + : blockIndex(-1), blockInfo(sh::BlockMemberInfo::getDefaultBlockInfo()) +{ } -LinkedUniform::~LinkedUniform() +LinkedUniform::LinkedUniform(GLenum typeIn, + GLenum precisionIn, + const std::string &nameIn, + unsigned int arraySizeIn, + const int blockIndexIn, + const sh::BlockMemberInfo &blockInfoIn) + : blockIndex(blockIndexIn), blockInfo(blockInfoIn) { - delete[] data; + type = typeIn; + precision = precisionIn; + name = nameIn; + arraySize = arraySizeIn; } -bool LinkedUniform::isArray() const +LinkedUniform::LinkedUniform(const sh::Uniform &uniform) + : sh::Uniform(uniform), blockIndex(-1), blockInfo(sh::BlockMemberInfo::getDefaultBlockInfo()) { - return arraySize > 0; } -unsigned int LinkedUniform::elementCount() const +LinkedUniform::LinkedUniform(const LinkedUniform &uniform) + : sh::Uniform(uniform), blockIndex(uniform.blockIndex), blockInfo(uniform.blockInfo) { - return arraySize > 0 ? arraySize : 1; + // This function is not intended to be called during runtime. + ASSERT(uniform.mLazyData.empty()); } -bool LinkedUniform::isReferencedByVertexShader() const +LinkedUniform &LinkedUniform::operator=(const LinkedUniform &uniform) { - return vsRegisterIndex != GL_INVALID_INDEX; + // This function is not intended to be called during runtime. + ASSERT(uniform.mLazyData.empty()); + + sh::Uniform::operator=(uniform); + blockIndex = uniform.blockIndex; + blockInfo = uniform.blockInfo; + + return *this; } -bool LinkedUniform::isReferencedByFragmentShader() const +LinkedUniform::~LinkedUniform() { - return psRegisterIndex != GL_INVALID_INDEX; } bool LinkedUniform::isInDefaultBlock() const @@ -72,7 +68,30 @@ bool LinkedUniform::isInDefaultBlock() const size_t LinkedUniform::dataSize() const { ASSERT(type != GL_STRUCT_ANGLEX); - return VariableInternalSize(type) * elementCount(); + if (mLazyData.empty()) + { + mLazyData.resize(VariableExternalSize(type) * elementCount()); + ASSERT(!mLazyData.empty()); + } + + return mLazyData.size(); +} + +uint8_t *LinkedUniform::data() +{ + if (mLazyData.empty()) + { + // dataSize() will init the data store. + size_t size = dataSize(); + memset(mLazyData.data(), 0, size); + } + + return mLazyData.data(); +} + +const uint8_t *LinkedUniform::data() const +{ + return const_cast(this)->data(); } bool LinkedUniform::isSampler() const @@ -80,33 +99,51 @@ bool LinkedUniform::isSampler() const return IsSamplerType(type); } -bool LinkedUniform::isBuiltIn() const +bool LinkedUniform::isField() const { - return name.compare(0, 3, "gl_") == 0; + return name.find('.') != std::string::npos; } -UniformBlock::UniformBlock(const std::string &name, unsigned int elementIndex, unsigned int dataSize) - : name(name), - elementIndex(elementIndex), - dataSize(dataSize), - psRegisterIndex(GL_INVALID_INDEX), - vsRegisterIndex(GL_INVALID_INDEX) +size_t LinkedUniform::getElementSize() const { + return VariableExternalSize(type); } -bool UniformBlock::isArrayElement() const +uint8_t *LinkedUniform::getDataPtrToElement(size_t elementIndex) { - return elementIndex != GL_INVALID_INDEX; + ASSERT((!isArray() && elementIndex == 0) || (isArray() && elementIndex < arraySize)); + return data() + getElementSize() * elementIndex; } -bool UniformBlock::isReferencedByVertexShader() const +const uint8_t *LinkedUniform::getDataPtrToElement(size_t elementIndex) const { - return vsRegisterIndex != GL_INVALID_INDEX; + return const_cast(this)->getDataPtrToElement(elementIndex); } -bool UniformBlock::isReferencedByFragmentShader() const +UniformBlock::UniformBlock() + : isArray(false), arrayElement(0), dataSize(0), vertexStaticUse(false), fragmentStaticUse(false) { - return psRegisterIndex != GL_INVALID_INDEX; } +UniformBlock::UniformBlock(const std::string &nameIn, bool isArrayIn, unsigned int arrayElementIn) + : name(nameIn), + isArray(isArrayIn), + arrayElement(arrayElementIn), + dataSize(0), + vertexStaticUse(false), + fragmentStaticUse(false) +{ +} + +std::string UniformBlock::nameWithArrayIndex() const +{ + std::stringstream fullNameStr; + fullNameStr << name; + if (isArray) + { + fullNameStr << "[" << arrayElement << "]"; + } + + return fullNameStr.str(); +} } diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/Uniform.h b/Source/ThirdParty/ANGLE/src/libANGLE/Uniform.h index b73fc9d2d938..e62a583f3dd3 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/Uniform.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/Uniform.h @@ -12,6 +12,7 @@ #include "angle_gl.h" #include "common/debug.h" +#include "common/MemoryBuffer.h" #include "compiler/translator/blocklayout.h" #include "libANGLE/angletypes.h" @@ -19,58 +20,51 @@ namespace gl { // Helper struct representing a single shader uniform -struct LinkedUniform : angle::NonCopyable +struct LinkedUniform : public sh::Uniform { + LinkedUniform(); LinkedUniform(GLenum type, GLenum precision, const std::string &name, unsigned int arraySize, const int blockIndex, const sh::BlockMemberInfo &blockInfo); - + LinkedUniform(const sh::Uniform &uniform); + LinkedUniform(const LinkedUniform &uniform); + LinkedUniform &operator=(const LinkedUniform &uniform); ~LinkedUniform(); - bool isArray() const; - unsigned int elementCount() const; - bool isReferencedByVertexShader() const; - bool isReferencedByFragmentShader() const; - bool isInDefaultBlock() const; size_t dataSize() const; + uint8_t *data(); + const uint8_t *data() const; bool isSampler() const; - bool isBuiltIn() const; - - const GLenum type; - const GLenum precision; - const std::string name; - const unsigned int arraySize; - const int blockIndex; - const sh::BlockMemberInfo blockInfo; - - unsigned char *data; - bool dirty; + bool isInDefaultBlock() const; + bool isField() const; + size_t getElementSize() const; + uint8_t *getDataPtrToElement(size_t elementIndex); + const uint8_t *getDataPtrToElement(size_t elementIndex) const; - unsigned int psRegisterIndex; - unsigned int vsRegisterIndex; - unsigned int registerCount; + int blockIndex; + sh::BlockMemberInfo blockInfo; - // 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; + private: + mutable rx::MemoryBuffer mLazyData; }; // Helper struct representing a single shader uniform block -struct UniformBlock : angle::NonCopyable +struct UniformBlock { - // use GL_INVALID_INDEX for non-array elements - UniformBlock(const std::string &name, unsigned int elementIndex, unsigned int dataSize); + UniformBlock(); + UniformBlock(const std::string &nameIn, bool isArrayIn, unsigned int arrayElementIn); + UniformBlock(const UniformBlock &other) = default; + UniformBlock &operator=(const UniformBlock &other) = default; - bool isArrayElement() const; - bool isReferencedByVertexShader() const; - bool isReferencedByFragmentShader() const; + std::string nameWithArrayIndex() const; - const std::string name; - const unsigned int elementIndex; - const unsigned int dataSize; + std::string name; + bool isArray; + unsigned int arrayElement; + unsigned int dataSize; - std::vector memberUniformIndexes; + bool vertexStaticUse; + bool fragmentStaticUse; - unsigned int psRegisterIndex; - unsigned int vsRegisterIndex; + std::vector memberUniformIndexes; }; } diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/Version.h b/Source/ThirdParty/ANGLE/src/libANGLE/Version.h new file mode 100644 index 000000000000..72dfbb6b8dfd --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/libANGLE/Version.h @@ -0,0 +1,33 @@ +// +// Copyright (c) 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_ + +#include + +namespace gl +{ + +struct Version +{ + Version(); + Version(GLuint major, GLuint minor); + + GLuint major; + GLuint minor; +}; + +bool operator>=(const Version &a, const Version &b); +bool operator<(const Version &a, const Version &b); + +} + +#include "Version.inl" + +#endif // LIBANGLE_VERSION_H_ diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/Version.inl b/Source/ThirdParty/ANGLE/src/libANGLE/Version.inl new file mode 100644 index 000000000000..f64f7cae7722 --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/libANGLE/Version.inl @@ -0,0 +1,33 @@ +// +// Copyright (c) 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.inl: Encapsulation of a GL version. + +namespace gl +{ + +inline Version::Version() + : Version(0, 0) +{ +} + +inline Version::Version(GLuint major_, GLuint minor_) +{ + major = major_; + minor = minor_; +} + +inline bool operator>=(const Version &a, const Version &b) +{ + return a.major > b.major || (a.major == b.major && a.minor >= b.minor); +} + +inline bool operator<(const Version &a, const Version &b) +{ + return !(a >= b); +} + +} diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/VertexArray.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/VertexArray.cpp index a920a779b8c7..a1ca19a5d737 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/VertexArray.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/VertexArray.cpp @@ -8,29 +8,34 @@ #include "libANGLE/VertexArray.h" #include "libANGLE/Buffer.h" +#include "libANGLE/renderer/ImplFactory.h" #include "libANGLE/renderer/VertexArrayImpl.h" namespace gl { -VertexArray::VertexArray(rx::VertexArrayImpl *impl, GLuint id, size_t maxAttribs) - : mId(id), - mVertexArray(impl), - mVertexAttributes(maxAttribs), - mMaxEnabledAttribute(0) +VertexArray::Data::Data(size_t maxAttribs) + : mLabel(), mVertexAttributes(maxAttribs), mMaxEnabledAttribute(0) { - ASSERT(impl != NULL); } -VertexArray::~VertexArray() +VertexArray::Data::~Data() { - SafeDelete(mVertexArray); - for (size_t i = 0; i < getMaxAttribs(); i++) { - mVertexAttributes[i].buffer.set(NULL); + mVertexAttributes[i].buffer.set(nullptr); } - mElementArrayBuffer.set(NULL); + mElementArrayBuffer.set(nullptr); +} + +VertexArray::VertexArray(rx::ImplFactory *factory, GLuint id, size_t maxAttribs) + : mId(id), mData(maxAttribs), mVertexArray(factory->createVertexArray(mData)) +{ +} + +VertexArray::~VertexArray() +{ + SafeDelete(mVertexArray); } GLuint VertexArray::id() const @@ -38,78 +43,96 @@ GLuint VertexArray::id() const return mId; } +void VertexArray::setLabel(const std::string &label) +{ + mData.mLabel = label; +} + +const std::string &VertexArray::getLabel() const +{ + return mData.mLabel; +} + void VertexArray::detachBuffer(GLuint bufferName) { for (size_t attribute = 0; attribute < getMaxAttribs(); attribute++) { - if (mVertexAttributes[attribute].buffer.id() == bufferName) + if (mData.mVertexAttributes[attribute].buffer.id() == bufferName) { - mVertexAttributes[attribute].buffer.set(NULL); + mData.mVertexAttributes[attribute].buffer.set(nullptr); } } - if (mElementArrayBuffer.id() == bufferName) + if (mData.mElementArrayBuffer.id() == bufferName) { - mElementArrayBuffer.set(NULL); + mData.mElementArrayBuffer.set(nullptr); } } -const VertexAttribute& VertexArray::getVertexAttribute(size_t attributeIndex) const +const VertexAttribute &VertexArray::getVertexAttribute(size_t attributeIndex) const { ASSERT(attributeIndex < getMaxAttribs()); - return mVertexAttributes[attributeIndex]; + return mData.mVertexAttributes[attributeIndex]; } -const std::vector &VertexArray::getVertexAttributes() const -{ - return mVertexAttributes; -} - -void VertexArray::setVertexAttribDivisor(GLuint index, GLuint divisor) +void VertexArray::setVertexAttribDivisor(size_t index, GLuint divisor) { ASSERT(index < getMaxAttribs()); - mVertexAttributes[index].divisor = divisor; - mVertexArray->setAttributeDivisor(index, divisor); + mData.mVertexAttributes[index].divisor = divisor; + mDirtyBits.set(DIRTY_BIT_ATTRIB_0_DIVISOR + index); } -void VertexArray::enableAttribute(unsigned int attributeIndex, bool enabledState) +void VertexArray::enableAttribute(size_t attributeIndex, bool enabledState) { ASSERT(attributeIndex < getMaxAttribs()); - mVertexAttributes[attributeIndex].enabled = enabledState; - mVertexArray->enableAttribute(attributeIndex, enabledState); + mData.mVertexAttributes[attributeIndex].enabled = enabledState; + mDirtyBits.set(DIRTY_BIT_ATTRIB_0_ENABLED + attributeIndex); // Update state cache if (enabledState) { - mMaxEnabledAttribute = std::max(attributeIndex, mMaxEnabledAttribute); + mData.mMaxEnabledAttribute = std::max(attributeIndex + 1, mData.mMaxEnabledAttribute); } - else if (mMaxEnabledAttribute == attributeIndex) + else if (mData.mMaxEnabledAttribute == attributeIndex + 1) { - while (mMaxEnabledAttribute > 0 && !mVertexAttributes[mMaxEnabledAttribute].enabled) + while (mData.mMaxEnabledAttribute > 0 && + !mData.mVertexAttributes[mData.mMaxEnabledAttribute - 1].enabled) { - --mMaxEnabledAttribute; + --mData.mMaxEnabledAttribute; } } } -void VertexArray::setAttributeState(unsigned int attributeIndex, gl::Buffer *boundBuffer, GLint size, GLenum type, +void VertexArray::setAttributeState(size_t attributeIndex, gl::Buffer *boundBuffer, GLint size, GLenum type, bool normalized, bool pureInteger, GLsizei stride, const void *pointer) { ASSERT(attributeIndex < getMaxAttribs()); - mVertexAttributes[attributeIndex].buffer.set(boundBuffer); - mVertexAttributes[attributeIndex].size = size; - mVertexAttributes[attributeIndex].type = type; - mVertexAttributes[attributeIndex].normalized = normalized; - mVertexAttributes[attributeIndex].pureInteger = pureInteger; - mVertexAttributes[attributeIndex].stride = stride; - mVertexAttributes[attributeIndex].pointer = pointer; - mVertexArray->setAttribute(attributeIndex, mVertexAttributes[attributeIndex]); + + VertexAttribute *attrib = &mData.mVertexAttributes[attributeIndex]; + + attrib->buffer.set(boundBuffer); + attrib->size = size; + attrib->type = type; + attrib->normalized = normalized; + attrib->pureInteger = pureInteger; + attrib->stride = stride; + attrib->pointer = pointer; + mDirtyBits.set(DIRTY_BIT_ATTRIB_0_POINTER + attributeIndex); } void VertexArray::setElementArrayBuffer(Buffer *buffer) { - mElementArrayBuffer.set(buffer); - mVertexArray->setElementArrayBuffer(buffer); + mData.mElementArrayBuffer.set(buffer); + mDirtyBits.set(DIRTY_BIT_ELEMENT_ARRAY_BUFFER); +} + +void VertexArray::syncImplState() +{ + if (mDirtyBits.any()) + { + mVertexArray->syncState(mDirtyBits); + mDirtyBits.reset(); + } } } diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/VertexArray.h b/Source/ThirdParty/ANGLE/src/libANGLE/VertexArray.h index acedf91a593a..fe262fde3b0d 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/VertexArray.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/VertexArray.h @@ -15,12 +15,15 @@ #include "libANGLE/RefCountObject.h" #include "libANGLE/Constants.h" +#include "libANGLE/Debug.h" +#include "libANGLE/State.h" #include "libANGLE/VertexAttribute.h" #include namespace rx { +class ImplFactory; class VertexArrayImpl; } @@ -28,40 +31,93 @@ namespace gl { class Buffer; -class VertexArray +class VertexArray final : public LabeledObject { public: - VertexArray(rx::VertexArrayImpl *impl, GLuint id, size_t maxAttribs); + VertexArray(rx::ImplFactory *factory, GLuint id, size_t maxAttribs); ~VertexArray(); GLuint id() const; - const VertexAttribute& getVertexAttribute(size_t attributeIndex) const; - const std::vector &getVertexAttributes() const; + void setLabel(const std::string &label) override; + const std::string &getLabel() const override; + + const VertexAttribute &getVertexAttribute(size_t attributeIndex) const; void detachBuffer(GLuint bufferName); - void setVertexAttribDivisor(GLuint index, GLuint divisor); - void enableAttribute(unsigned int attributeIndex, bool enabledState); - void setAttributeState(unsigned int attributeIndex, gl::Buffer *boundBuffer, GLint size, GLenum type, + void setVertexAttribDivisor(size_t index, GLuint divisor); + void enableAttribute(size_t attributeIndex, bool enabledState); + void setAttributeState(size_t attributeIndex, gl::Buffer *boundBuffer, GLint size, GLenum type, bool normalized, bool pureInteger, GLsizei stride, const void *pointer); - Buffer *getElementArrayBuffer() const { return mElementArrayBuffer.get(); } void setElementArrayBuffer(Buffer *buffer); - GLuint getElementArrayBufferId() const { return mElementArrayBuffer.id(); } - size_t getMaxAttribs() const { return mVertexAttributes.size(); } + + const BindingPointer &getElementArrayBuffer() const { return mData.getElementArrayBuffer(); } + size_t getMaxAttribs() const { return mData.getVertexAttributes().size(); } + const std::vector &getVertexAttributes() const { return mData.getVertexAttributes(); } rx::VertexArrayImpl *getImplementation() { return mVertexArray; } const rx::VertexArrayImpl *getImplementation() const { return mVertexArray; } - unsigned int getMaxEnabledAttribute() const { return mMaxEnabledAttribute; } + size_t getMaxEnabledAttribute() const { return mData.getMaxEnabledAttribute(); } + + class Data final : public angle::NonCopyable + { + public: + explicit Data(size_t maxAttribs); + ~Data(); + + const std::string &getLabel() const { return mLabel; } + + const BindingPointer &getElementArrayBuffer() const { return mElementArrayBuffer; } + size_t getMaxAttribs() const { return mVertexAttributes.size(); } + size_t getMaxEnabledAttribute() const { return mMaxEnabledAttribute; } + const std::vector &getVertexAttributes() const { return mVertexAttributes; } + const VertexAttribute &getVertexAttribute(size_t index) const + { + return mVertexAttributes[index]; + } + + private: + friend class VertexArray; + std::string mLabel; + std::vector mVertexAttributes; + BindingPointer mElementArrayBuffer; + size_t mMaxEnabledAttribute; + }; + + enum DirtyBitType + { + DIRTY_BIT_ELEMENT_ARRAY_BUFFER, + + // Reserve bits for enabled flags + DIRTY_BIT_ATTRIB_0_ENABLED, + DIRTY_BIT_ATTRIB_MAX_ENABLED = DIRTY_BIT_ATTRIB_0_ENABLED + gl::MAX_VERTEX_ATTRIBS, + + // Reserve bits for attrib pointers + DIRTY_BIT_ATTRIB_0_POINTER = DIRTY_BIT_ATTRIB_MAX_ENABLED, + DIRTY_BIT_ATTRIB_MAX_POINTER = DIRTY_BIT_ATTRIB_0_POINTER + gl::MAX_VERTEX_ATTRIBS, + + // Reserve bits for divisors + DIRTY_BIT_ATTRIB_0_DIVISOR = DIRTY_BIT_ATTRIB_MAX_POINTER, + DIRTY_BIT_ATTRIB_MAX_DIVISOR = DIRTY_BIT_ATTRIB_0_DIVISOR + gl::MAX_VERTEX_ATTRIBS, + + DIRTY_BIT_UNKNOWN = DIRTY_BIT_ATTRIB_MAX_DIVISOR, + DIRTY_BIT_MAX = DIRTY_BIT_UNKNOWN, + }; + + typedef std::bitset DirtyBits; + + void syncImplState(); + bool hasAnyDirtyBit() const { return mDirtyBits.any(); } private: GLuint mId; + Data mData; + DirtyBits mDirtyBits; + rx::VertexArrayImpl *mVertexArray; - std::vector mVertexAttributes; - BindingPointer mElementArrayBuffer; - unsigned int mMaxEnabledAttribute; }; } diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/VertexAttribute.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/VertexAttribute.cpp index 19934e7face5..13d78fd13c1d 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/VertexAttribute.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/VertexAttribute.cpp @@ -23,24 +23,6 @@ VertexAttribute::VertexAttribute() { } -bool operator==(const VertexAttribute &a, const VertexAttribute &b) -{ - return a.enabled == b.enabled && - a.type == b.type && - a.size == b.size && - a.normalized == b.normalized && - a.pureInteger == b.pureInteger && - a.stride == b.stride && - a.pointer == b.pointer && - a.buffer.get() == b.buffer.get() && - a.divisor == b.divisor; -} - -bool operator!=(const VertexAttribute &a, const VertexAttribute &b) -{ - return !(a == b); -} - size_t ComputeVertexAttributeTypeSize(const VertexAttribute& attrib) { GLuint size = attrib.size; @@ -70,4 +52,23 @@ size_t ComputeVertexAttributeStride(const VertexAttribute& attrib) return attrib.stride ? attrib.stride : ComputeVertexAttributeTypeSize(attrib); } +size_t ComputeVertexAttributeElementCount(const VertexAttribute &attrib, + 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 && attrib.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 + attrib.divisor - 1u) / attrib.divisor; + } + + return drawCount; +} } diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/VertexAttribute.h b/Source/ThirdParty/ANGLE/src/libANGLE/VertexAttribute.h index bdffe9746606..d1ee1b47a2b0 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/VertexAttribute.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/VertexAttribute.h @@ -40,34 +40,13 @@ bool operator==(const VertexAttribute &a, const VertexAttribute &b); bool operator!=(const VertexAttribute &a, const VertexAttribute &b); template -T QuerySingleVertexAttributeParameter(const VertexAttribute& attrib, GLenum pname) -{ - switch (pname) - { - case GL_VERTEX_ATTRIB_ARRAY_ENABLED: - return static_cast(attrib.enabled ? GL_TRUE : GL_FALSE); - case GL_VERTEX_ATTRIB_ARRAY_SIZE: - return static_cast(attrib.size); - case GL_VERTEX_ATTRIB_ARRAY_STRIDE: - return static_cast(attrib.stride); - case GL_VERTEX_ATTRIB_ARRAY_TYPE: - return static_cast(attrib.type); - case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED: - return static_cast(attrib.normalized ? GL_TRUE : GL_FALSE); - case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING: - return static_cast(attrib.buffer.id()); - case GL_VERTEX_ATTRIB_ARRAY_DIVISOR: - return static_cast(attrib.divisor); - case GL_VERTEX_ATTRIB_ARRAY_INTEGER: - return static_cast(attrib.pureInteger ? GL_TRUE : GL_FALSE); - default: - UNREACHABLE(); - return static_cast(0); - } -} +T QuerySingleVertexAttributeParameter(const VertexAttribute& attrib, GLenum pname); size_t ComputeVertexAttributeTypeSize(const VertexAttribute& attrib); size_t ComputeVertexAttributeStride(const VertexAttribute& attrib); +size_t ComputeVertexAttributeElementCount(const VertexAttribute &attrib, + size_t drawCount, + size_t instanceCount); struct VertexAttribCurrentValueData { @@ -79,44 +58,18 @@ struct VertexAttribCurrentValueData }; GLenum Type; - void setFloatValues(const GLfloat floatValues[4]) - { - for (unsigned int valueIndex = 0; valueIndex < 4; valueIndex++) - { - FloatValues[valueIndex] = floatValues[valueIndex]; - } - Type = GL_FLOAT; - } - - void setIntValues(const GLint intValues[4]) - { - for (unsigned int valueIndex = 0; valueIndex < 4; valueIndex++) - { - IntValues[valueIndex] = intValues[valueIndex]; - } - Type = GL_INT; - } - - void setUnsignedIntValues(const GLuint unsignedIntValues[4]) - { - for (unsigned int valueIndex = 0; valueIndex < 4; valueIndex++) - { - UnsignedIntValues[valueIndex] = unsignedIntValues[valueIndex]; - } - Type = GL_UNSIGNED_INT; - } - - bool operator==(const VertexAttribCurrentValueData &other) - { - return (Type == other.Type && memcmp(FloatValues, other.FloatValues, sizeof(float) * 4) == 0); - } + VertexAttribCurrentValueData(); - bool operator!=(const VertexAttribCurrentValueData &other) - { - return !(*this == other); - } + 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); + } +#include "VertexAttribute.inl" + #endif // LIBANGLE_VERTEXATTRIBUTE_H_ diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/VertexAttribute.inl b/Source/ThirdParty/ANGLE/src/libANGLE/VertexAttribute.inl new file mode 100644 index 000000000000..0cd31f676240 --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/libANGLE/VertexAttribute.inl @@ -0,0 +1,103 @@ +// +// Copyright (c) 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.inl: Inline vertex attribute methods +// + +namespace gl +{ + +inline bool operator==(const VertexAttribute &a, const VertexAttribute &b) +{ + return a.enabled == b.enabled && + a.type == b.type && + a.size == b.size && + a.normalized == b.normalized && + a.pureInteger == b.pureInteger && + a.stride == b.stride && + a.pointer == b.pointer && + a.buffer.get() == b.buffer.get() && + a.divisor == b.divisor; +} + +inline bool operator!=(const VertexAttribute &a, const VertexAttribute &b) +{ + return !(a == b); +} + +template +T QuerySingleVertexAttributeParameter(const VertexAttribute& attrib, GLenum pname) +{ + switch (pname) + { + case GL_VERTEX_ATTRIB_ARRAY_ENABLED: + return static_cast(attrib.enabled ? GL_TRUE : GL_FALSE); + case GL_VERTEX_ATTRIB_ARRAY_SIZE: + return static_cast(attrib.size); + case GL_VERTEX_ATTRIB_ARRAY_STRIDE: + return static_cast(attrib.stride); + case GL_VERTEX_ATTRIB_ARRAY_TYPE: + return static_cast(attrib.type); + case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED: + return static_cast(attrib.normalized ? GL_TRUE : GL_FALSE); + case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING: + return static_cast(attrib.buffer.id()); + case GL_VERTEX_ATTRIB_ARRAY_DIVISOR: + return static_cast(attrib.divisor); + case GL_VERTEX_ATTRIB_ARRAY_INTEGER: + return static_cast(attrib.pureInteger ? GL_TRUE : GL_FALSE); + default: + UNREACHABLE(); + return static_cast(0); + } +} + +inline VertexAttribCurrentValueData::VertexAttribCurrentValueData() + : Type(GL_FLOAT) +{ + FloatValues[0] = 0.0f; + FloatValues[1] = 0.0f; + FloatValues[2] = 0.0f; + FloatValues[3] = 1.0f; +} + +inline void VertexAttribCurrentValueData::setFloatValues(const GLfloat floatValues[4]) +{ + for (unsigned int valueIndex = 0; valueIndex < 4; valueIndex++) + { + FloatValues[valueIndex] = floatValues[valueIndex]; + } + Type = GL_FLOAT; +} + +inline void VertexAttribCurrentValueData::setIntValues(const GLint intValues[4]) +{ + for (unsigned int valueIndex = 0; valueIndex < 4; valueIndex++) + { + IntValues[valueIndex] = intValues[valueIndex]; + } + Type = GL_INT; +} + +inline void VertexAttribCurrentValueData::setUnsignedIntValues(const GLuint unsignedIntValues[4]) +{ + for (unsigned int valueIndex = 0; valueIndex < 4; valueIndex++) + { + UnsignedIntValues[valueIndex] = unsignedIntValues[valueIndex]; + } + Type = GL_UNSIGNED_INT; +} + +inline bool operator==(const VertexAttribCurrentValueData &a, const VertexAttribCurrentValueData &b) +{ + return (a.Type == b.Type && memcmp(a.FloatValues, b.FloatValues, sizeof(float) * 4) == 0); +} + +inline bool operator!=(const VertexAttribCurrentValueData &a, const VertexAttribCurrentValueData &b) +{ + return !(a == b); +} + +} diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/angletypes.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/angletypes.cpp index 16879f804144..dd06d41216aa 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/angletypes.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/angletypes.cpp @@ -15,17 +15,28 @@ namespace gl { -bool operator==(const Rectangle &a, const Rectangle &b) +PrimitiveType GetPrimitiveType(GLenum drawMode) { - return a.x == b.x && - a.y == b.y && - a.width == b.width && - a.height == b.height; -} - -bool operator!=(const Rectangle &a, const Rectangle &b) -{ - return !(a == b); + switch (drawMode) + { + case GL_POINTS: + return PRIMITIVE_POINTS; + case GL_LINES: + return PRIMITIVE_LINES; + case GL_LINE_STRIP: + return PRIMITIVE_LINE_STRIP; + case GL_LINE_LOOP: + return PRIMITIVE_LINE_LOOP; + case GL_TRIANGLES: + return PRIMITIVE_TRIANGLES; + case GL_TRIANGLE_STRIP: + return PRIMITIVE_TRIANGLE_STRIP; + case GL_TRIANGLE_FAN: + return PRIMITIVE_TRIANGLE_FAN; + default: + UNREACHABLE(); + return PRIMITIVE_TYPE_MAX; + } } SamplerState::SamplerState() @@ -35,47 +46,31 @@ SamplerState::SamplerState() wrapT(GL_REPEAT), wrapR(GL_REPEAT), maxAnisotropy(1.0f), - baseLevel(0), - maxLevel(1000), minLod(-1000.0f), maxLod(1000.0f), compareMode(GL_NONE), - compareFunc(GL_LEQUAL), - swizzleRed(GL_RED), - swizzleGreen(GL_GREEN), - swizzleBlue(GL_BLUE), - swizzleAlpha(GL_ALPHA) -{} - -bool SamplerState::swizzleRequired() const + compareFunc(GL_LEQUAL) { - return swizzleRed != GL_RED || swizzleGreen != GL_GREEN || - swizzleBlue != GL_BLUE || swizzleAlpha != GL_ALPHA; } -bool SamplerState::operator==(const SamplerState &other) const +TextureState::TextureState() + : swizzleRed(GL_RED), + swizzleGreen(GL_GREEN), + swizzleBlue(GL_BLUE), + swizzleAlpha(GL_ALPHA), + samplerState(), + baseLevel(0), + maxLevel(1000), + immutableFormat(false), + immutableLevels(0), + usage(GL_NONE) { - return minFilter == other.minFilter && - magFilter == other.magFilter && - wrapS == other.wrapS && - wrapT == other.wrapT && - wrapR == other.wrapR && - maxAnisotropy == other.maxAnisotropy && - baseLevel == other.baseLevel && - maxLevel == other.maxLevel && - minLod == other.minLod && - maxLod == other.maxLod && - compareMode == other.compareMode && - compareFunc == other.compareFunc && - swizzleRed == other.swizzleRed && - swizzleGreen == other.swizzleGreen && - swizzleBlue == other.swizzleBlue && - swizzleAlpha == other.swizzleAlpha; } -bool SamplerState::operator!=(const SamplerState &other) const +bool TextureState::swizzleRequired() const { - return !(*this == other); + return swizzleRed != GL_RED || swizzleGreen != GL_GREEN || + swizzleBlue != GL_BLUE || swizzleAlpha != GL_ALPHA; } static void MinMax(int a, int b, int *minimum, int *maximum) @@ -128,119 +123,24 @@ bool ClipRectangle(const Rectangle &source, const Rectangle &clip, Rectangle *in } } -VertexFormat::VertexFormat() - : mType(GL_NONE), - mNormalized(GL_FALSE), - mComponents(0), - mPureInteger(false) -{} - -VertexFormat::VertexFormat(GLenum type, GLboolean normalized, GLuint components, bool pureInteger) - : mType(type), - mNormalized(normalized), - mComponents(components), - mPureInteger(pureInteger) -{ - // Float data can not be normalized, so ignore the user setting - if (mType == GL_FLOAT || mType == GL_HALF_FLOAT || mType == GL_FIXED) - { - mNormalized = GL_FALSE; - } -} - -VertexFormat::VertexFormat(const VertexAttribute &attrib) - : mType(attrib.type), - mNormalized(attrib.normalized ? GL_TRUE : GL_FALSE), - mComponents(attrib.size), - mPureInteger(attrib.pureInteger) -{ - // Ensure we aren't initializing a vertex format which should be using - // the current-value type - ASSERT(attrib.enabled); - - // Float data can not be normalized, so ignore the user setting - if (mType == GL_FLOAT || mType == GL_HALF_FLOAT || mType == GL_FIXED) - { - mNormalized = GL_FALSE; - } -} - -VertexFormat::VertexFormat(const VertexAttribute &attrib, GLenum currentValueType) - : mType(attrib.type), - mNormalized(attrib.normalized ? GL_TRUE : GL_FALSE), - mComponents(attrib.size), - mPureInteger(attrib.pureInteger) -{ - if (!attrib.enabled) - { - mType = currentValueType; - mNormalized = GL_FALSE; - mComponents = 4; - mPureInteger = (currentValueType != GL_FLOAT); - } - - // Float data can not be normalized, so ignore the user setting - if (mType == GL_FLOAT || mType == GL_HALF_FLOAT || mType == GL_FIXED) - { - mNormalized = GL_FALSE; - } -} - -void VertexFormat::GetInputLayout(VertexFormat *inputLayout, - Program *program, - const State &state) -{ - const std::vector &vertexAttributes = state.getVertexArray()->getVertexAttributes(); - for (unsigned int attributeIndex = 0; attributeIndex < vertexAttributes.size(); attributeIndex++) - { - int semanticIndex = program->getSemanticIndex(attributeIndex); - - if (semanticIndex != -1) - { - inputLayout[semanticIndex] = VertexFormat(vertexAttributes[attributeIndex], state.getVertexAttribCurrentValue(attributeIndex).Type); - } - } -} - -bool VertexFormat::operator==(const VertexFormat &other) const +bool Box::operator==(const Box &other) const { - return (mType == other.mType && - mComponents == other.mComponents && - mNormalized == other.mNormalized && - mPureInteger == other.mPureInteger ); + return (x == other.x && y == other.y && z == other.z && + width == other.width && height == other.height && depth == other.depth); } -bool VertexFormat::operator!=(const VertexFormat &other) const +bool Box::operator!=(const Box &other) const { return !(*this == other); } -bool VertexFormat::operator<(const VertexFormat& other) const -{ - if (mType != other.mType) - { - return mType < other.mType; - } - if (mNormalized != other.mNormalized) - { - return mNormalized < other.mNormalized; - } - if (mComponents != other.mComponents) - { - return mComponents < other.mComponents; - } - return mPureInteger < other.mPureInteger; -} - -bool Box::operator==(const Box &other) const +bool operator==(const Extents &lhs, const Extents &rhs) { - return (x == other.x && y == other.y && z == other.z && - width == other.width && height == other.height && depth == other.depth); + return lhs.width == rhs.width && lhs.height == rhs.height && lhs.depth == rhs.depth; } -bool Box::operator!=(const Box &other) const +bool operator!=(const Extents &lhs, const Extents &rhs) { - return !(*this == other); + return !(lhs == rhs); } - } diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/angletypes.h b/Source/ThirdParty/ANGLE/src/libANGLE/angletypes.h index ceef5017cc78..0842be3a65f3 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/angletypes.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/angletypes.h @@ -14,6 +14,9 @@ #include +#include +#include + namespace gl { class Buffer; @@ -22,6 +25,20 @@ class Program; struct VertexAttribute; struct VertexAttribCurrentValueData; +enum PrimitiveType +{ + PRIMITIVE_POINTS, + PRIMITIVE_LINES, + PRIMITIVE_LINE_STRIP, + PRIMITIVE_LINE_LOOP, + PRIMITIVE_TRIANGLES, + PRIMITIVE_TRIANGLE_STRIP, + PRIMITIVE_TRIANGLE_FAN, + PRIMITIVE_TYPE_MAX, +}; + +PrimitiveType GetPrimitiveType(GLenum drawMode); + enum SamplerType { SAMPLER_PIXEL, @@ -41,19 +58,10 @@ struct Color }; template -bool operator==(const Color &a, const Color &b) -{ - return a.red == b.red && - a.green == b.green && - a.blue == b.blue && - a.alpha == b.alpha; -} +bool operator==(const Color &a, const Color &b); template -bool operator!=(const Color &a, const Color &b) -{ - return !(a == b); -} +bool operator!=(const Color &a, const Color &b); typedef Color ColorF; typedef Color ColorI; @@ -61,13 +69,21 @@ typedef Color ColorUI; struct Rectangle { + Rectangle() : x(0), y(0), width(0), height(0) {} + Rectangle(int x_in, int y_in, int width_in, int height_in) + : x(x_in), y(y_in), width(width_in), height(height_in) + { + } + + int x0() const { return x; } + int y0() const { return y; } + int x1() const { return x + width; } + int y1() const { return y + height; } + int x; int y; int width; int height; - - Rectangle() : x(0), y(0), width(0), height(0) { } - Rectangle(int x_in, int y_in, int width_in, int height_in) : x(x_in), y(y_in), width(width_in), height(height_in) { } }; bool operator==(const Rectangle &a, const Rectangle &b); @@ -97,6 +113,9 @@ struct Extents bool empty() const { return (width * height * depth) == 0; } }; +bool operator==(const Extents &lhs, const Extents &rhs); +bool operator!=(const Extents &lhs, const Extents &rhs); + struct Box { int x; @@ -171,36 +190,58 @@ struct DepthStencilState GLuint stencilBackWritemask; }; +// State from Table 6.10 (state per sampler object) struct SamplerState { SamplerState(); GLenum minFilter; GLenum magFilter; + GLenum wrapS; GLenum wrapT; GLenum wrapR; + + // From EXT_texture_filter_anisotropic float maxAnisotropy; - GLint baseLevel; - GLint maxLevel; GLfloat minLod; GLfloat maxLod; GLenum compareMode; GLenum compareFunc; +}; + +bool operator==(const SamplerState &a, const SamplerState &b); +bool operator!=(const SamplerState &a, const SamplerState &b); + +// State from Table 6.9 (state per texture object) in the OpenGL ES 3.0.2 spec. +struct TextureState +{ + TextureState(); GLenum swizzleRed; GLenum swizzleGreen; GLenum swizzleBlue; GLenum swizzleAlpha; - bool swizzleRequired() const; + SamplerState samplerState; + + GLuint baseLevel; + GLuint maxLevel; - bool operator==(const SamplerState &other) const; - bool operator!=(const SamplerState &other) const; + bool immutableFormat; + GLuint immutableLevels; + + // From GL_ANGLE_texture_usage + GLenum usage; + + bool swizzleRequired() const; }; +bool operator==(const TextureState &a, const TextureState &b); +bool operator!=(const TextureState &a, const TextureState &b); + struct PixelUnpackState { BindingPointer pixelBuffer; @@ -256,37 +297,26 @@ struct PixelPackState {} }; -struct VertexFormat -{ - GLenum mType; - GLboolean mNormalized; - GLuint mComponents; - bool mPureInteger; - - VertexFormat(); - VertexFormat(GLenum type, GLboolean normalized, GLuint components, bool pureInteger); - explicit VertexFormat(const VertexAttribute &attribute); - VertexFormat(const VertexAttribute &attribute, GLenum currentValueType); - - static void GetInputLayout(VertexFormat *inputLayout, - Program *program, - const State& currentValues); - - bool operator==(const VertexFormat &other) const; - bool operator!=(const VertexFormat &other) const; - bool operator<(const VertexFormat& other) const; -}; +// Used in Program and VertexArray. +typedef std::bitset AttributesMask; + +// Use in Program +typedef std::bitset UniformBlockBindingMask; +// A map of GL objects indexed by object ID. The specific map implementation may change. +// Client code should treat it as a std::map. +template +using ResourceMap = std::unordered_map; } namespace rx { - enum VendorID : uint32_t { - VENDOR_ID_AMD = 0x1002, - VENDOR_ID_INTEL = 0x8086, - VENDOR_ID_NVIDIA = 0x10DE, + VENDOR_ID_UNKNOWN = 0x0, + VENDOR_ID_AMD = 0x1002, + VENDOR_ID_INTEL = 0x8086, + VENDOR_ID_NVIDIA = 0x10DE, }; // A macro that determines whether an object has a given runtime type. @@ -337,4 +367,52 @@ inline const DestT *GetImplAs(const SrcT *src) } +#include "angletypes.inl" + +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; + } +} +} + #endif // LIBANGLE_ANGLETYPES_H_ diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/angletypes.inl b/Source/ThirdParty/ANGLE/src/libANGLE/angletypes.inl new file mode 100644 index 000000000000..d51bcaaa7893 --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/libANGLE/angletypes.inl @@ -0,0 +1,78 @@ +// +// Copyright (c) 2012-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. +// + +// angletypes.inl : Inline definitions of some functions from angletypes.h + +namespace gl +{ + +template +bool operator==(const Color &a, const Color &b) +{ + return a.red == b.red && + a.green == b.green && + a.blue == b.blue && + a.alpha == b.alpha; +} + +template +bool operator!=(const Color &a, const Color &b) +{ + return !(a == b); +} + +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 a.minFilter == b.minFilter && + a.magFilter == b.magFilter && + a.wrapS == b.wrapS && + a.wrapT == b.wrapT && + a.wrapR == b.wrapR && + a.maxAnisotropy == b.maxAnisotropy && + a.minLod == b.minLod && + a.maxLod == b.maxLod && + a.compareMode == b.compareMode && + a.compareFunc == b.compareFunc; +} + +inline bool operator!=(const SamplerState &a, const SamplerState &b) +{ + return !(a == b); +} + +inline bool operator==(const TextureState &a, const TextureState &b) +{ + return a.swizzleRed == b.swizzleRed && + a.swizzleGreen == b.swizzleGreen && + a.swizzleBlue == b.swizzleBlue && + a.swizzleAlpha == b.swizzleAlpha && + a.samplerState == b.samplerState && + a.baseLevel == b.baseLevel && + a.maxLevel == b.maxLevel && + a.immutableFormat == b.immutableFormat && + a.immutableLevels == b.immutableLevels && + a.usage == b.usage; +} + +inline bool operator!=(const TextureState &a, const TextureState &b) +{ + return !(a == b); +} + +} diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/features.h b/Source/ThirdParty/ANGLE/src/libANGLE/features.h index fbe013f47d6c..ecf486dcf7d1 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/features.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/features.h @@ -32,9 +32,22 @@ #define ANGLE_PROGRAM_BINARY_LOAD ANGLE_ENABLED #endif -// Shader debug info -#if !defined(ANGLE_SHADER_DEBUG_INFO) -#define ANGLE_SHADER_DEBUG_INFO ANGLE_DISABLED +// 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 #endif // LIBANGLE_FEATURES_H_ diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/formatutils.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/formatutils.cpp index 51e6a5a65d1d..3a4df126c5fc 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/formatutils.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/formatutils.cpp @@ -163,11 +163,6 @@ static bool AlwaysSupported(GLuint, const Extensions &) return true; } -static bool UnimplementedSupport(GLuint, const Extensions &) -{ - return false; -} - static bool NeverSupported(GLuint, const Extensions &) { return false; @@ -217,6 +212,61 @@ static bool RequireExtAndExt(GLuint, const Extensions &extensions) return extensions.*bool1 && extensions.*bool2; } +// Check support for either of two extensions +template +static bool RequireExtOrExt(GLuint, const Extensions &extensions) +{ + return extensions.*bool1 || extensions.*bool2; +} + +// Special function for half float formats with three or four channels. +static bool HalfFloatSupport(GLuint clientVersion, const Extensions &extensions) +{ + return clientVersion >= 3 || extensions.textureHalfFloat; +} + +static bool HalfFloatRenderableSupport(GLuint clientVersion, const Extensions &extensions) +{ + return HalfFloatSupport(clientVersion, extensions) && extensions.colorBufferHalfFloat; +} + +// Special function for half float formats with one or two channels. +static bool HalfFloatSupportRG(GLuint clientVersion, const Extensions &extensions) +{ + return clientVersion >= 3 || (extensions.textureHalfFloat && extensions.textureRG); +} + +static bool HalfFloatRenderableSupportRG(GLuint clientVersion, const Extensions &extensions) +{ + return HalfFloatSupportRG(clientVersion, extensions) && extensions.colorBufferHalfFloat; +} + +// Special function for float formats with three or four channels. +static bool FloatSupport(GLuint clientVersion, const Extensions &extensions) +{ + return clientVersion >= 3 || extensions.textureFloat; +} + +static bool FloatRenderableSupport(GLuint clientVersion, const Extensions &extensions) +{ + // We don't expose colorBufferFloat in ES2, but we silently support rendering to float. + return FloatSupport(clientVersion, extensions) && + (extensions.colorBufferFloat || clientVersion == 2); +} + +// Special function for float formats with one or two channels. +static bool FloatSupportRG(GLuint clientVersion, const Extensions &extensions) +{ + return clientVersion >= 3 || (extensions.textureFloat && extensions.textureRG); +} + +static bool FloatRenderableSupportRG(GLuint clientVersion, const Extensions &extensions) +{ + // We don't expose colorBufferFloat in ES2, but we silently support rendering to float. + return FloatSupportRG(clientVersion, extensions) && + (extensions.colorBufferFloat || clientVersion == 2); +} + InternalFormat::InternalFormat() : redBits(0), greenBits(0), @@ -228,13 +278,13 @@ InternalFormat::InternalFormat() stencilBits(0), pixelBytes(0), componentCount(0), + compressed(false), compressedBlockWidth(0), compressedBlockHeight(0), format(GL_NONE), type(GL_NONE), componentType(GL_NONE), colorEncoding(GL_NONE), - compressed(false), textureSupport(NeverSupported), renderSupport(NeverSupported), filterSupport(NeverSupported) @@ -346,6 +396,7 @@ static InternalFormatInfoMap BuildInternalFormatInfoMap() { InternalFormatInfoMap map; + // clang-format off // From ES 3.0.1 spec, table 3.12 map.insert(InternalFormatInfoPair(GL_NONE, InternalFormat())); @@ -362,7 +413,7 @@ static InternalFormatInfoMap BuildInternalFormatInfoMap() map.insert(InternalFormatInfoPair(GL_RGBA8, RGBAFormat( 8, 8, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, false, RequireESOrExt<3, &Extensions::rgb8rgba8>, RequireESOrExt<3, &Extensions::rgb8rgba8>, AlwaysSupported))); map.insert(InternalFormatInfoPair(GL_RGBA8_SNORM, RGBAFormat( 8, 8, 8, 8, 0, GL_RGBA, GL_BYTE, GL_SIGNED_NORMALIZED, false, RequireES<3>, NeverSupported, AlwaysSupported))); map.insert(InternalFormatInfoPair(GL_RGB10_A2, RGBAFormat(10, 10, 10, 2, 0, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, GL_UNSIGNED_NORMALIZED, false, RequireES<3>, RequireES<3>, AlwaysSupported))); - map.insert(InternalFormatInfoPair(GL_RGB10_A2UI, RGBAFormat(10, 10, 10, 2, 0, GL_RGBA_INTEGER, GL_UNSIGNED_INT_2_10_10_10_REV, GL_UNSIGNED_INT, false, RequireES<3>, NeverSupported, NeverSupported))); + map.insert(InternalFormatInfoPair(GL_RGB10_A2UI, RGBAFormat(10, 10, 10, 2, 0, GL_RGBA_INTEGER, GL_UNSIGNED_INT_2_10_10_10_REV, GL_UNSIGNED_INT, false, RequireES<3>, RequireES<3>, NeverSupported))); map.insert(InternalFormatInfoPair(GL_SRGB8, RGBAFormat( 8, 8, 8, 0, 0, GL_RGB, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, true, RequireESOrExt<3, &Extensions::sRGB>, NeverSupported, AlwaysSupported))); map.insert(InternalFormatInfoPair(GL_SRGB8_ALPHA8, RGBAFormat( 8, 8, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, true, RequireESOrExt<3, &Extensions::sRGB>, RequireESOrExt<3, &Extensions::sRGB>, AlwaysSupported))); map.insert(InternalFormatInfoPair(GL_R11F_G11F_B10F, RGBAFormat(11, 11, 10, 0, 0, GL_RGB, GL_UNSIGNED_INT_10F_11F_11F_REV, GL_FLOAT, false, RequireES<3>, RequireExt<&Extensions::colorBufferFloat>, AlwaysSupported))); @@ -397,23 +448,23 @@ static InternalFormatInfoMap BuildInternalFormatInfoMap() map.insert(InternalFormatInfoPair(GL_BGR5_A1_ANGLEX, RGBAFormat( 5, 5, 5, 1, 0, GL_BGRA_EXT, GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT, GL_UNSIGNED_NORMALIZED, false, RequireExt<&Extensions::textureFormatBGRA8888>, RequireExt<&Extensions::textureFormatBGRA8888>, AlwaysSupported))); // Floating point renderability and filtering is provided by OES_texture_float and OES_texture_half_float - // | Internal format | | D |S | Format | Type | Comp | SRGB | Texture supported | Renderable | Filterable | - // | | | | | | | type | | | | | - map.insert(InternalFormatInfoPair(GL_R16F, RGBAFormat(16, 0, 0, 0, 0, GL_RED, GL_HALF_FLOAT, GL_FLOAT, false, RequireESOrExtAndExt<3, &Extensions::textureHalfFloat, &Extensions::textureRG>, RequireESOrExtAndExt<3, &Extensions::textureHalfFloat, &Extensions::textureRG>, RequireExt<&Extensions::textureHalfFloatLinear>))); - map.insert(InternalFormatInfoPair(GL_RG16F, RGBAFormat(16, 16, 0, 0, 0, GL_RG, GL_HALF_FLOAT, GL_FLOAT, false, RequireESOrExtAndExt<3, &Extensions::textureHalfFloat, &Extensions::textureRG>, RequireESOrExtAndExt<3, &Extensions::textureHalfFloat, &Extensions::textureRG>, RequireExt<&Extensions::textureHalfFloatLinear>))); - map.insert(InternalFormatInfoPair(GL_RGB16F, RGBAFormat(16, 16, 16, 0, 0, GL_RGB, GL_HALF_FLOAT, GL_FLOAT, false, RequireESOrExt<3, &Extensions::textureHalfFloat>, RequireESOrExt<3, &Extensions::textureHalfFloat>, RequireExt<&Extensions::textureHalfFloatLinear>))); - map.insert(InternalFormatInfoPair(GL_RGBA16F, RGBAFormat(16, 16, 16, 16, 0, GL_RGBA, GL_HALF_FLOAT, GL_FLOAT, false, RequireESOrExt<3, &Extensions::textureHalfFloat>, RequireESOrExt<3, &Extensions::textureHalfFloat>, RequireExt<&Extensions::textureHalfFloatLinear>))); - map.insert(InternalFormatInfoPair(GL_R32F, RGBAFormat(32, 0, 0, 0, 0, GL_RED, GL_FLOAT, GL_FLOAT, false, RequireESOrExtAndExt<3, &Extensions::textureFloat, &Extensions::textureRG>, RequireESOrExtAndExt<3, &Extensions::textureFloat, &Extensions::textureRG>, RequireExt<&Extensions::textureFloatLinear> ))); - map.insert(InternalFormatInfoPair(GL_RG32F, RGBAFormat(32, 32, 0, 0, 0, GL_RG, GL_FLOAT, GL_FLOAT, false, RequireESOrExtAndExt<3, &Extensions::textureFloat, &Extensions::textureRG>, RequireESOrExtAndExt<3, &Extensions::textureFloat, &Extensions::textureRG>, RequireExt<&Extensions::textureFloatLinear> ))); - map.insert(InternalFormatInfoPair(GL_RGB32F, RGBAFormat(32, 32, 32, 0, 0, GL_RGB, GL_FLOAT, GL_FLOAT, false, RequireESOrExt<3, &Extensions::textureFloat>, RequireESOrExt<3, &Extensions::textureFloat>, RequireExt<&Extensions::textureFloatLinear> ))); - map.insert(InternalFormatInfoPair(GL_RGBA32F, RGBAFormat(32, 32, 32, 32, 0, GL_RGBA, GL_FLOAT, GL_FLOAT, false, RequireESOrExt<3, &Extensions::textureFloat>, RequireESOrExt<3, &Extensions::textureFloat>, RequireExt<&Extensions::textureFloatLinear> ))); + // | Internal format | | D |S | Format | Type | Comp | SRGB | Texture supported | Renderable | Filterable | + // | | | | | | | type | | | | | + map.insert(InternalFormatInfoPair(GL_R16F, RGBAFormat(16, 0, 0, 0, 0, GL_RED, GL_HALF_FLOAT, GL_FLOAT, false, HalfFloatSupportRG, HalfFloatRenderableSupportRG, RequireExt<&Extensions::textureHalfFloatLinear>))); + map.insert(InternalFormatInfoPair(GL_RG16F, RGBAFormat(16, 16, 0, 0, 0, GL_RG, GL_HALF_FLOAT, GL_FLOAT, false, HalfFloatSupportRG, HalfFloatRenderableSupportRG, RequireExt<&Extensions::textureHalfFloatLinear>))); + map.insert(InternalFormatInfoPair(GL_RGB16F, RGBAFormat(16, 16, 16, 0, 0, GL_RGB, GL_HALF_FLOAT, GL_FLOAT, false, HalfFloatSupport, HalfFloatRenderableSupport, RequireExt<&Extensions::textureHalfFloatLinear>))); + map.insert(InternalFormatInfoPair(GL_RGBA16F, RGBAFormat(16, 16, 16, 16, 0, GL_RGBA, GL_HALF_FLOAT, GL_FLOAT, false, HalfFloatSupport, HalfFloatRenderableSupport, RequireExt<&Extensions::textureHalfFloatLinear>))); + map.insert(InternalFormatInfoPair(GL_R32F, RGBAFormat(32, 0, 0, 0, 0, GL_RED, GL_FLOAT, GL_FLOAT, false, FloatSupportRG, FloatRenderableSupportRG, RequireExt<&Extensions::textureFloatLinear> ))); + map.insert(InternalFormatInfoPair(GL_RG32F, RGBAFormat(32, 32, 0, 0, 0, GL_RG, GL_FLOAT, GL_FLOAT, false, FloatSupportRG, FloatRenderableSupportRG, RequireExt<&Extensions::textureFloatLinear> ))); + map.insert(InternalFormatInfoPair(GL_RGB32F, RGBAFormat(32, 32, 32, 0, 0, GL_RGB, GL_FLOAT, GL_FLOAT, false, FloatSupport, FloatRenderableSupport, RequireExt<&Extensions::textureFloatLinear> ))); + map.insert(InternalFormatInfoPair(GL_RGBA32F, RGBAFormat(32, 32, 32, 32, 0, GL_RGBA, GL_FLOAT, GL_FLOAT, false, FloatSupport, FloatRenderableSupport, RequireExt<&Extensions::textureFloatLinear> ))); // Depth stencil formats // | Internal format | | D |S | X | Format | Type | Component type | Supported | Renderable | Filterable | map.insert(InternalFormatInfoPair(GL_DEPTH_COMPONENT16, DepthStencilFormat(16, 0, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, GL_UNSIGNED_NORMALIZED, RequireES<2>, RequireES<2>, RequireESOrExt<3, &Extensions::depthTextures>))); map.insert(InternalFormatInfoPair(GL_DEPTH_COMPONENT24, DepthStencilFormat(24, 0, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, GL_UNSIGNED_NORMALIZED, RequireES<3>, RequireES<3>, RequireESOrExt<3, &Extensions::depthTextures>))); map.insert(InternalFormatInfoPair(GL_DEPTH_COMPONENT32F, DepthStencilFormat(32, 0, 0, GL_DEPTH_COMPONENT, GL_FLOAT, GL_FLOAT, RequireES<3>, RequireES<3>, RequireESOrExt<3, &Extensions::depthTextures>))); - map.insert(InternalFormatInfoPair(GL_DEPTH_COMPONENT32_OES, DepthStencilFormat(32, 0, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, GL_UNSIGNED_NORMALIZED, RequireExt<&Extensions::depthTextures>, RequireExt<&Extensions::depthTextures>, AlwaysSupported ))); + map.insert(InternalFormatInfoPair(GL_DEPTH_COMPONENT32_OES, DepthStencilFormat(32, 0, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, GL_UNSIGNED_NORMALIZED, RequireExtOrExt<&Extensions::depthTextures, &Extensions::depth32>, RequireExtOrExt<&Extensions::depthTextures, &Extensions::depth32>, AlwaysSupported ))); map.insert(InternalFormatInfoPair(GL_DEPTH24_STENCIL8, DepthStencilFormat(24, 8, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, GL_UNSIGNED_NORMALIZED, RequireESOrExt<3, &Extensions::depthTextures>, RequireESOrExtOrExt<3, &Extensions::depthTextures, &Extensions::packedDepthStencil>, AlwaysSupported ))); map.insert(InternalFormatInfoPair(GL_DEPTH32F_STENCIL8, DepthStencilFormat(32, 8, 24, GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, GL_FLOAT, RequireES<3>, RequireES<3>, AlwaysSupported ))); // STENCIL_INDEX8 is special-cased, see around the bottom of the list. @@ -450,28 +501,63 @@ static InternalFormatInfoMap BuildInternalFormatInfoMap() map.insert(InternalFormatInfoPair(GL_SRGB_ALPHA_EXT, UnsizedFormat(GL_RGBA, RequireESOrExt<3, &Extensions::sRGB>, RequireESOrExt<3, &Extensions::sRGB>, AlwaysSupported))); // Compressed formats, From ES 3.0.1 spec, table 3.16 - // | Internal format | |W |H | BS |CC| Format | Type | SRGB | Supported | Renderable | Filterable | - map.insert(InternalFormatInfoPair(GL_COMPRESSED_R11_EAC, CompressedFormat(4, 4, 64, 1, GL_COMPRESSED_R11_EAC, GL_UNSIGNED_BYTE, false, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport))); - map.insert(InternalFormatInfoPair(GL_COMPRESSED_SIGNED_R11_EAC, CompressedFormat(4, 4, 64, 1, GL_COMPRESSED_SIGNED_R11_EAC, GL_UNSIGNED_BYTE, false, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport))); - map.insert(InternalFormatInfoPair(GL_COMPRESSED_RG11_EAC, CompressedFormat(4, 4, 128, 2, GL_COMPRESSED_RG11_EAC, GL_UNSIGNED_BYTE, false, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport))); - map.insert(InternalFormatInfoPair(GL_COMPRESSED_SIGNED_RG11_EAC, CompressedFormat(4, 4, 128, 2, GL_COMPRESSED_SIGNED_RG11_EAC, GL_UNSIGNED_BYTE, false, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport))); - map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGB8_ETC2, CompressedFormat(4, 4, 64, 3, GL_COMPRESSED_RGB8_ETC2, GL_UNSIGNED_BYTE, false, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport))); - map.insert(InternalFormatInfoPair(GL_COMPRESSED_SRGB8_ETC2, CompressedFormat(4, 4, 64, 3, GL_COMPRESSED_SRGB8_ETC2, GL_UNSIGNED_BYTE, true, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport))); - map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2, CompressedFormat(4, 4, 64, 3, GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2, GL_UNSIGNED_BYTE, false, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport))); - map.insert(InternalFormatInfoPair(GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, CompressedFormat(4, 4, 64, 3, GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, GL_UNSIGNED_BYTE, true, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport))); - map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGBA8_ETC2_EAC, CompressedFormat(4, 4, 128, 4, GL_COMPRESSED_RGBA8_ETC2_EAC, GL_UNSIGNED_BYTE, false, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport))); - map.insert(InternalFormatInfoPair(GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC, CompressedFormat(4, 4, 128, 4, GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC, GL_UNSIGNED_BYTE, true, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport))); + // | Internal format | |W |H | BS |CC| Format | Type | SRGB | Supported | Renderable | Filterable | + map.insert(InternalFormatInfoPair(GL_COMPRESSED_R11_EAC, CompressedFormat(4, 4, 64, 1, GL_COMPRESSED_R11_EAC, GL_UNSIGNED_BYTE, false, RequireES<3>, NeverSupported, AlwaysSupported))); + map.insert(InternalFormatInfoPair(GL_COMPRESSED_SIGNED_R11_EAC, CompressedFormat(4, 4, 64, 1, GL_COMPRESSED_SIGNED_R11_EAC, GL_UNSIGNED_BYTE, false, RequireES<3>, NeverSupported, AlwaysSupported))); + map.insert(InternalFormatInfoPair(GL_COMPRESSED_RG11_EAC, CompressedFormat(4, 4, 128, 2, GL_COMPRESSED_RG11_EAC, GL_UNSIGNED_BYTE, false, RequireES<3>, NeverSupported, AlwaysSupported))); + map.insert(InternalFormatInfoPair(GL_COMPRESSED_SIGNED_RG11_EAC, CompressedFormat(4, 4, 128, 2, GL_COMPRESSED_SIGNED_RG11_EAC, GL_UNSIGNED_BYTE, false, RequireES<3>, NeverSupported, AlwaysSupported))); + map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGB8_ETC2, CompressedFormat(4, 4, 64, 3, GL_COMPRESSED_RGB8_ETC2, GL_UNSIGNED_BYTE, false, RequireES<3>, NeverSupported, AlwaysSupported))); + map.insert(InternalFormatInfoPair(GL_COMPRESSED_SRGB8_ETC2, CompressedFormat(4, 4, 64, 3, GL_COMPRESSED_SRGB8_ETC2, GL_UNSIGNED_BYTE, true, RequireES<3>, NeverSupported, AlwaysSupported))); + map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2, CompressedFormat(4, 4, 64, 3, GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2, GL_UNSIGNED_BYTE, false, RequireES<3>, NeverSupported, AlwaysSupported))); + map.insert(InternalFormatInfoPair(GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, CompressedFormat(4, 4, 64, 3, GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, GL_UNSIGNED_BYTE, true, RequireES<3>, NeverSupported, AlwaysSupported))); + map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGBA8_ETC2_EAC, CompressedFormat(4, 4, 128, 4, GL_COMPRESSED_RGBA8_ETC2_EAC, GL_UNSIGNED_BYTE, false, RequireES<3>, NeverSupported, AlwaysSupported))); + map.insert(InternalFormatInfoPair(GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC, CompressedFormat(4, 4, 128, 4, GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC, GL_UNSIGNED_BYTE, true, RequireES<3>, NeverSupported, AlwaysSupported))); // From GL_EXT_texture_compression_dxt1 - // | Internal format | |W |H | BS |CC| Format | Type | SRGB | Supported | Renderable | Filterable | - map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGB_S3TC_DXT1_EXT, CompressedFormat(4, 4, 64, 3, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, GL_UNSIGNED_BYTE, false, RequireExt<&Extensions::textureCompressionDXT1>, NeverSupported, AlwaysSupported))); - map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, CompressedFormat(4, 4, 64, 4, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_UNSIGNED_BYTE, false, RequireExt<&Extensions::textureCompressionDXT1>, NeverSupported, AlwaysSupported))); + // | Internal format | |W |H | BS |CC| Format | Type | SRGB | Supported | Renderable | Filterable | + map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGB_S3TC_DXT1_EXT, CompressedFormat(4, 4, 64, 3, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, GL_UNSIGNED_BYTE, false, RequireExt<&Extensions::textureCompressionDXT1>, NeverSupported, AlwaysSupported))); + map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, CompressedFormat(4, 4, 64, 4, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_UNSIGNED_BYTE, false, RequireExt<&Extensions::textureCompressionDXT1>, NeverSupported, AlwaysSupported))); // From GL_ANGLE_texture_compression_dxt3 - map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, CompressedFormat(4, 4, 128, 4, GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, GL_UNSIGNED_BYTE, false, RequireExt<&Extensions::textureCompressionDXT5>, NeverSupported, AlwaysSupported))); + map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, CompressedFormat(4, 4, 128, 4, GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, GL_UNSIGNED_BYTE, false, RequireExt<&Extensions::textureCompressionDXT5>, NeverSupported, AlwaysSupported))); // From GL_ANGLE_texture_compression_dxt5 - map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, CompressedFormat(4, 4, 128, 4, GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, GL_UNSIGNED_BYTE, false, RequireExt<&Extensions::textureCompressionDXT5>, NeverSupported, AlwaysSupported))); + map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, CompressedFormat(4, 4, 128, 4, GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, GL_UNSIGNED_BYTE, false, RequireExt<&Extensions::textureCompressionDXT5>, NeverSupported, AlwaysSupported))); + + // From GL_OES_compressed_ETC1_RGB8_texture + map.insert(InternalFormatInfoPair(GL_ETC1_RGB8_OES, CompressedFormat(4, 4, 64, 3, GL_ETC1_RGB8_OES, GL_UNSIGNED_BYTE, false, RequireExt<&Extensions::compressedETC1RGB8Texture>, NeverSupported, AlwaysSupported))); + + // From KHR_texture_compression_astc_hdr + // | Internal format | | W | H | BS |CC| Format | Type | SRGB | Supported | Renderable | Filterable | + map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGBA_ASTC_4x4_KHR, CompressedFormat( 4, 4, 128, 4, GL_COMPRESSED_RGBA_ASTC_4x4_KHR, GL_UNSIGNED_BYTE, false, RequireExtOrExt<&Extensions::textureCompressionASTCHDR, &Extensions::textureCompressionASTCLDR>, NeverSupported, AlwaysSupported))); + map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGBA_ASTC_5x4_KHR, CompressedFormat( 5, 4, 128, 4, GL_COMPRESSED_RGBA_ASTC_5x4_KHR, GL_UNSIGNED_BYTE, false, RequireExtOrExt<&Extensions::textureCompressionASTCHDR, &Extensions::textureCompressionASTCLDR>, NeverSupported, AlwaysSupported))); + map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGBA_ASTC_5x5_KHR, CompressedFormat( 5, 5, 128, 4, GL_COMPRESSED_RGBA_ASTC_5x5_KHR, GL_UNSIGNED_BYTE, false, RequireExtOrExt<&Extensions::textureCompressionASTCHDR, &Extensions::textureCompressionASTCLDR>, NeverSupported, AlwaysSupported))); + map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGBA_ASTC_6x5_KHR, CompressedFormat( 6, 5, 128, 4, GL_COMPRESSED_RGBA_ASTC_6x5_KHR, GL_UNSIGNED_BYTE, false, RequireExtOrExt<&Extensions::textureCompressionASTCHDR, &Extensions::textureCompressionASTCLDR>, NeverSupported, AlwaysSupported))); + map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGBA_ASTC_6x6_KHR, CompressedFormat( 6, 6, 128, 4, GL_COMPRESSED_RGBA_ASTC_6x6_KHR, GL_UNSIGNED_BYTE, false, RequireExtOrExt<&Extensions::textureCompressionASTCHDR, &Extensions::textureCompressionASTCLDR>, NeverSupported, AlwaysSupported))); + map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGBA_ASTC_8x5_KHR, CompressedFormat( 8, 5, 128, 4, GL_COMPRESSED_RGBA_ASTC_8x5_KHR, GL_UNSIGNED_BYTE, false, RequireExtOrExt<&Extensions::textureCompressionASTCHDR, &Extensions::textureCompressionASTCLDR>, NeverSupported, AlwaysSupported))); + map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGBA_ASTC_8x6_KHR, CompressedFormat( 8, 6, 128, 4, GL_COMPRESSED_RGBA_ASTC_8x6_KHR, GL_UNSIGNED_BYTE, false, RequireExtOrExt<&Extensions::textureCompressionASTCHDR, &Extensions::textureCompressionASTCLDR>, NeverSupported, AlwaysSupported))); + map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGBA_ASTC_8x8_KHR, CompressedFormat( 8, 8, 128, 4, GL_COMPRESSED_RGBA_ASTC_8x8_KHR, GL_UNSIGNED_BYTE, false, RequireExtOrExt<&Extensions::textureCompressionASTCHDR, &Extensions::textureCompressionASTCLDR>, NeverSupported, AlwaysSupported))); + map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGBA_ASTC_10x5_KHR, CompressedFormat(10, 5, 128, 4, GL_COMPRESSED_RGBA_ASTC_10x5_KHR, GL_UNSIGNED_BYTE, false, RequireExtOrExt<&Extensions::textureCompressionASTCHDR, &Extensions::textureCompressionASTCLDR>, NeverSupported, AlwaysSupported))); + map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGBA_ASTC_10x6_KHR, CompressedFormat(10, 6, 128, 4, GL_COMPRESSED_RGBA_ASTC_10x6_KHR, GL_UNSIGNED_BYTE, false, RequireExtOrExt<&Extensions::textureCompressionASTCHDR, &Extensions::textureCompressionASTCLDR>, NeverSupported, AlwaysSupported))); + map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGBA_ASTC_10x8_KHR, CompressedFormat(10, 8, 128, 4, GL_COMPRESSED_RGBA_ASTC_10x8_KHR, GL_UNSIGNED_BYTE, false, RequireExtOrExt<&Extensions::textureCompressionASTCHDR, &Extensions::textureCompressionASTCLDR>, NeverSupported, AlwaysSupported))); + map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGBA_ASTC_10x10_KHR, CompressedFormat(10, 10, 128, 4, GL_COMPRESSED_RGBA_ASTC_10x10_KHR, GL_UNSIGNED_BYTE, false, RequireExtOrExt<&Extensions::textureCompressionASTCHDR, &Extensions::textureCompressionASTCLDR>, NeverSupported, AlwaysSupported))); + map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGBA_ASTC_12x10_KHR, CompressedFormat(12, 10, 128, 4, GL_COMPRESSED_RGBA_ASTC_12x10_KHR, GL_UNSIGNED_BYTE, false, RequireExtOrExt<&Extensions::textureCompressionASTCHDR, &Extensions::textureCompressionASTCLDR>, NeverSupported, AlwaysSupported))); + map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGBA_ASTC_12x12_KHR, CompressedFormat(12, 12, 128, 4, GL_COMPRESSED_RGBA_ASTC_12x12_KHR, GL_UNSIGNED_BYTE, false, RequireExtOrExt<&Extensions::textureCompressionASTCHDR, &Extensions::textureCompressionASTCLDR>, NeverSupported, AlwaysSupported))); + + map.insert(InternalFormatInfoPair(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR, CompressedFormat( 4, 4, 128, 4, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR, GL_UNSIGNED_BYTE, true, RequireExtOrExt<&Extensions::textureCompressionASTCHDR, &Extensions::textureCompressionASTCLDR>, NeverSupported, AlwaysSupported))); + map.insert(InternalFormatInfoPair(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR, CompressedFormat( 5, 4, 128, 4, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR, GL_UNSIGNED_BYTE, true, RequireExtOrExt<&Extensions::textureCompressionASTCHDR, &Extensions::textureCompressionASTCLDR>, NeverSupported, AlwaysSupported))); + map.insert(InternalFormatInfoPair(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR, CompressedFormat( 5, 5, 128, 4, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR, GL_UNSIGNED_BYTE, true, RequireExtOrExt<&Extensions::textureCompressionASTCHDR, &Extensions::textureCompressionASTCLDR>, NeverSupported, AlwaysSupported))); + map.insert(InternalFormatInfoPair(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR, CompressedFormat( 6, 5, 128, 4, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR, GL_UNSIGNED_BYTE, true, RequireExtOrExt<&Extensions::textureCompressionASTCHDR, &Extensions::textureCompressionASTCLDR>, NeverSupported, AlwaysSupported))); + map.insert(InternalFormatInfoPair(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR, CompressedFormat( 6, 6, 128, 4, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR, GL_UNSIGNED_BYTE, true, RequireExtOrExt<&Extensions::textureCompressionASTCHDR, &Extensions::textureCompressionASTCLDR>, NeverSupported, AlwaysSupported))); + map.insert(InternalFormatInfoPair(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR, CompressedFormat( 8, 5, 128, 4, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR, GL_UNSIGNED_BYTE, true, RequireExtOrExt<&Extensions::textureCompressionASTCHDR, &Extensions::textureCompressionASTCLDR>, NeverSupported, AlwaysSupported))); + map.insert(InternalFormatInfoPair(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR, CompressedFormat( 8, 6, 128, 4, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR, GL_UNSIGNED_BYTE, true, RequireExtOrExt<&Extensions::textureCompressionASTCHDR, &Extensions::textureCompressionASTCLDR>, NeverSupported, AlwaysSupported))); + map.insert(InternalFormatInfoPair(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR, CompressedFormat( 8, 8, 128, 4, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR, GL_UNSIGNED_BYTE, true, RequireExtOrExt<&Extensions::textureCompressionASTCHDR, &Extensions::textureCompressionASTCLDR>, NeverSupported, AlwaysSupported))); + map.insert(InternalFormatInfoPair(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR, CompressedFormat(10, 5, 128, 4, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR, GL_UNSIGNED_BYTE, true, RequireExtOrExt<&Extensions::textureCompressionASTCHDR, &Extensions::textureCompressionASTCLDR>, NeverSupported, AlwaysSupported))); + map.insert(InternalFormatInfoPair(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR, CompressedFormat(10, 6, 128, 4, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR, GL_UNSIGNED_BYTE, true, RequireExtOrExt<&Extensions::textureCompressionASTCHDR, &Extensions::textureCompressionASTCLDR>, NeverSupported, AlwaysSupported))); + map.insert(InternalFormatInfoPair(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR, CompressedFormat(10, 8, 128, 4, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR, GL_UNSIGNED_BYTE, true, RequireExtOrExt<&Extensions::textureCompressionASTCHDR, &Extensions::textureCompressionASTCLDR>, NeverSupported, AlwaysSupported))); + map.insert(InternalFormatInfoPair(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR, CompressedFormat(10, 10, 128, 4, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR, GL_UNSIGNED_BYTE, true, RequireExtOrExt<&Extensions::textureCompressionASTCHDR, &Extensions::textureCompressionASTCLDR>, NeverSupported, AlwaysSupported))); + map.insert(InternalFormatInfoPair(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR, CompressedFormat(12, 10, 128, 4, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR, GL_UNSIGNED_BYTE, true, RequireExtOrExt<&Extensions::textureCompressionASTCHDR, &Extensions::textureCompressionASTCLDR>, NeverSupported, AlwaysSupported))); + map.insert(InternalFormatInfoPair(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR, CompressedFormat(12, 12, 128, 4, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR, GL_UNSIGNED_BYTE, true, RequireExtOrExt<&Extensions::textureCompressionASTCHDR, &Extensions::textureCompressionASTCLDR>, NeverSupported, AlwaysSupported))); // 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 @@ -480,6 +566,11 @@ static InternalFormatInfoMap BuildInternalFormatInfoMap() // | Internal format | |D |S |X | Format | Type | Component type | Supported | Renderable | Filterable | map.insert(InternalFormatInfoPair(GL_STENCIL_INDEX8, DepthStencilFormat(0, 8, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, RequireES<2>, RequireES<2>, NeverSupported))); + // From GL_ANGLE_lossy_etc_decode + map.insert(InternalFormatInfoPair(GL_ETC1_RGB8_LOSSY_DECODE_ANGLE, CompressedFormat(4, 4, 64, 3, GL_ETC1_RGB8_OES, GL_UNSIGNED_BYTE, false, RequireExt<&Extensions::lossyETCDecode>, NeverSupported, AlwaysSupported))); + + // clang-format on + return map; } @@ -592,9 +683,23 @@ GLuint InternalFormat::computeRowPitch(GLenum formatType, GLsizei width, GLint a return rx::roundUp(rowBytes, static_cast(alignment)); } -GLuint InternalFormat::computeDepthPitch(GLenum formatType, GLsizei width, GLsizei height, GLint alignment, GLint rowLength) const +GLuint InternalFormat::computeDepthPitch(GLenum formatType, + GLsizei width, + GLsizei height, + GLint alignment, + GLint rowLength, + GLint imageHeight) const { - return computeRowPitch(formatType, width, alignment, rowLength) * height; + GLuint rows; + if (imageHeight > 0) + { + rows = imageHeight; + } + else + { + rows = height; + } + return computeRowPitch(formatType, width, alignment, rowLength) * rows; } GLuint InternalFormat::computeBlockSize(GLenum formatType, GLsizei width, GLsizei height) const @@ -619,6 +724,15 @@ GLuint InternalFormat::computeBlockSize(GLenum formatType, GLsizei width, GLsize } } +GLuint InternalFormat::computeSkipPixels(GLint rowPitch, + GLint depthPitch, + GLint skipImages, + GLint skipRows, + GLint skipPixels) const +{ + return skipImages * depthPitch + skipRows * rowPitch + skipPixels * pixelBytes; +} + GLenum GetSizedInternalFormat(GLenum internalFormat, GLenum type) { const InternalFormat& formatInfo = GetInternalFormatInfo(internalFormat); @@ -647,4 +761,796 @@ const FormatSet &GetAllSizedInternalFormats() 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; + } +} + +VertexFormatType GetVertexFormatType(GLenum type, GLboolean normalized, GLuint components, bool pureInteger) +{ + switch (type) + { + case GL_BYTE: + switch (components) + { + case 1: + if (pureInteger) + return VERTEX_FORMAT_SBYTE1_INT; + if (normalized) + return VERTEX_FORMAT_SBYTE1_NORM; + return VERTEX_FORMAT_SBYTE1; + case 2: + if (pureInteger) + return VERTEX_FORMAT_SBYTE2_INT; + if (normalized) + return VERTEX_FORMAT_SBYTE2_NORM; + return VERTEX_FORMAT_SBYTE2; + case 3: + if (pureInteger) + return VERTEX_FORMAT_SBYTE3_INT; + if (normalized) + return VERTEX_FORMAT_SBYTE3_NORM; + return VERTEX_FORMAT_SBYTE3; + case 4: + if (pureInteger) + return VERTEX_FORMAT_SBYTE4_INT; + if (normalized) + return VERTEX_FORMAT_SBYTE4_NORM; + return VERTEX_FORMAT_SBYTE4; + default: + UNREACHABLE(); + break; + } + case GL_UNSIGNED_BYTE: + switch (components) + { + case 1: + if (pureInteger) + return VERTEX_FORMAT_UBYTE1_INT; + if (normalized) + return VERTEX_FORMAT_UBYTE1_NORM; + return VERTEX_FORMAT_UBYTE1; + case 2: + if (pureInteger) + return VERTEX_FORMAT_UBYTE2_INT; + if (normalized) + return VERTEX_FORMAT_UBYTE2_NORM; + return VERTEX_FORMAT_UBYTE2; + case 3: + if (pureInteger) + return VERTEX_FORMAT_UBYTE3_INT; + if (normalized) + return VERTEX_FORMAT_UBYTE3_NORM; + return VERTEX_FORMAT_UBYTE3; + case 4: + if (pureInteger) + return VERTEX_FORMAT_UBYTE4_INT; + if (normalized) + return VERTEX_FORMAT_UBYTE4_NORM; + return VERTEX_FORMAT_UBYTE4; + default: + UNREACHABLE(); + break; + } + case GL_SHORT: + switch (components) + { + case 1: + if (pureInteger) + return VERTEX_FORMAT_SSHORT1_INT; + if (normalized) + return VERTEX_FORMAT_SSHORT1_NORM; + return VERTEX_FORMAT_SSHORT1; + case 2: + if (pureInteger) + return VERTEX_FORMAT_SSHORT2_INT; + if (normalized) + return VERTEX_FORMAT_SSHORT2_NORM; + return VERTEX_FORMAT_SSHORT2; + case 3: + if (pureInteger) + return VERTEX_FORMAT_SSHORT3_INT; + if (normalized) + return VERTEX_FORMAT_SSHORT3_NORM; + return VERTEX_FORMAT_SSHORT3; + case 4: + if (pureInteger) + return VERTEX_FORMAT_SSHORT4_INT; + if (normalized) + return VERTEX_FORMAT_SSHORT4_NORM; + return VERTEX_FORMAT_SSHORT4; + default: + UNREACHABLE(); + break; + } + case GL_UNSIGNED_SHORT: + switch (components) + { + case 1: + if (pureInteger) + return VERTEX_FORMAT_USHORT1_INT; + if (normalized) + return VERTEX_FORMAT_USHORT1_NORM; + return VERTEX_FORMAT_USHORT1; + case 2: + if (pureInteger) + return VERTEX_FORMAT_USHORT2_INT; + if (normalized) + return VERTEX_FORMAT_USHORT2_NORM; + return VERTEX_FORMAT_USHORT2; + case 3: + if (pureInteger) + return VERTEX_FORMAT_USHORT3_INT; + if (normalized) + return VERTEX_FORMAT_USHORT3_NORM; + return VERTEX_FORMAT_USHORT3; + case 4: + if (pureInteger) + return VERTEX_FORMAT_USHORT4_INT; + if (normalized) + return VERTEX_FORMAT_USHORT4_NORM; + return VERTEX_FORMAT_USHORT4; + default: + UNREACHABLE(); + break; + } + case GL_INT: + switch (components) + { + case 1: + if (pureInteger) + return VERTEX_FORMAT_SINT1_INT; + if (normalized) + return VERTEX_FORMAT_SINT1_NORM; + return VERTEX_FORMAT_SINT1; + case 2: + if (pureInteger) + return VERTEX_FORMAT_SINT2_INT; + if (normalized) + return VERTEX_FORMAT_SINT2_NORM; + return VERTEX_FORMAT_SINT2; + case 3: + if (pureInteger) + return VERTEX_FORMAT_SINT3_INT; + if (normalized) + return VERTEX_FORMAT_SINT3_NORM; + return VERTEX_FORMAT_SINT3; + case 4: + if (pureInteger) + return VERTEX_FORMAT_SINT4_INT; + if (normalized) + return VERTEX_FORMAT_SINT4_NORM; + return VERTEX_FORMAT_SINT4; + default: + UNREACHABLE(); + break; + } + case GL_UNSIGNED_INT: + switch (components) + { + case 1: + if (pureInteger) + return VERTEX_FORMAT_UINT1_INT; + if (normalized) + return VERTEX_FORMAT_UINT1_NORM; + return VERTEX_FORMAT_UINT1; + case 2: + if (pureInteger) + return VERTEX_FORMAT_UINT2_INT; + if (normalized) + return VERTEX_FORMAT_UINT2_NORM; + return VERTEX_FORMAT_UINT2; + case 3: + if (pureInteger) + return VERTEX_FORMAT_UINT3_INT; + if (normalized) + return VERTEX_FORMAT_UINT3_NORM; + return VERTEX_FORMAT_UINT3; + case 4: + if (pureInteger) + return VERTEX_FORMAT_UINT4_INT; + if (normalized) + return VERTEX_FORMAT_UINT4_NORM; + return VERTEX_FORMAT_UINT4; + default: + UNREACHABLE(); + break; + } + case GL_FLOAT: + switch (components) + { + case 1: + return VERTEX_FORMAT_FLOAT1; + case 2: + return VERTEX_FORMAT_FLOAT2; + case 3: + return VERTEX_FORMAT_FLOAT3; + case 4: + return VERTEX_FORMAT_FLOAT4; + default: + UNREACHABLE(); + break; + } + case GL_HALF_FLOAT: + switch (components) + { + case 1: + return VERTEX_FORMAT_HALF1; + case 2: + return VERTEX_FORMAT_HALF2; + case 3: + return VERTEX_FORMAT_HALF3; + case 4: + return VERTEX_FORMAT_HALF4; + default: + UNREACHABLE(); + break; + } + case GL_FIXED: + switch (components) + { + case 1: + return VERTEX_FORMAT_FIXED1; + case 2: + return VERTEX_FORMAT_FIXED2; + case 3: + return VERTEX_FORMAT_FIXED3; + case 4: + return VERTEX_FORMAT_FIXED4; + default: + UNREACHABLE(); + break; + } + case GL_INT_2_10_10_10_REV: + if (pureInteger) + return VERTEX_FORMAT_SINT210_INT; + if (normalized) + return VERTEX_FORMAT_SINT210_NORM; + return VERTEX_FORMAT_SINT210; + case GL_UNSIGNED_INT_2_10_10_10_REV: + if (pureInteger) + return VERTEX_FORMAT_UINT210_INT; + if (normalized) + return VERTEX_FORMAT_UINT210_NORM; + return VERTEX_FORMAT_UINT210; + default: + UNREACHABLE(); + break; + } + return VERTEX_FORMAT_UBYTE1; +} + +VertexFormatType GetVertexFormatType(const VertexAttribute &attrib) +{ + return GetVertexFormatType(attrib.type, attrib.normalized, attrib.size, attrib.pureInteger); +} + +VertexFormatType GetVertexFormatType(const VertexAttribute &attrib, GLenum currentValueType) +{ + if (!attrib.enabled) + { + return GetVertexFormatType(currentValueType, GL_FALSE, 4, (currentValueType != GL_FLOAT)); + } + return GetVertexFormatType(attrib); +} + +const VertexFormat &GetVertexFormatFromType(VertexFormatType vertexFormatType) +{ + switch (vertexFormatType) + { + case VERTEX_FORMAT_SBYTE1: + { + static const VertexFormat format(GL_BYTE, GL_FALSE, 1, false); + return format; + } + case VERTEX_FORMAT_SBYTE1_NORM: + { + static const VertexFormat format(GL_BYTE, GL_TRUE, 1, false); + return format; + } + case VERTEX_FORMAT_SBYTE2: + { + static const VertexFormat format(GL_BYTE, GL_FALSE, 2, false); + return format; + } + case VERTEX_FORMAT_SBYTE2_NORM: + { + static const VertexFormat format(GL_BYTE, GL_TRUE, 2, false); + return format; + } + case VERTEX_FORMAT_SBYTE3: + { + static const VertexFormat format(GL_BYTE, GL_FALSE, 3, false); + return format; + } + case VERTEX_FORMAT_SBYTE3_NORM: + { + static const VertexFormat format(GL_BYTE, GL_TRUE, 3, false); + return format; + } + case VERTEX_FORMAT_SBYTE4: + { + static const VertexFormat format(GL_BYTE, GL_FALSE, 4, false); + return format; + } + case VERTEX_FORMAT_SBYTE4_NORM: + { + static const VertexFormat format(GL_BYTE, GL_TRUE, 4, false); + return format; + } + case VERTEX_FORMAT_UBYTE1: + { + static const VertexFormat format(GL_UNSIGNED_BYTE, GL_FALSE, 1, false); + return format; + } + case VERTEX_FORMAT_UBYTE1_NORM: + { + static const VertexFormat format(GL_UNSIGNED_BYTE, GL_TRUE, 1, false); + return format; + } + case VERTEX_FORMAT_UBYTE2: + { + static const VertexFormat format(GL_UNSIGNED_BYTE, GL_FALSE, 2, false); + return format; + } + case VERTEX_FORMAT_UBYTE2_NORM: + { + static const VertexFormat format(GL_UNSIGNED_BYTE, GL_TRUE, 2, false); + return format; + } + case VERTEX_FORMAT_UBYTE3: + { + static const VertexFormat format(GL_UNSIGNED_BYTE, GL_FALSE, 3, false); + return format; + } + case VERTEX_FORMAT_UBYTE3_NORM: + { + static const VertexFormat format(GL_UNSIGNED_BYTE, GL_TRUE, 3, false); + return format; + } + case VERTEX_FORMAT_UBYTE4: + { + static const VertexFormat format(GL_UNSIGNED_BYTE, GL_FALSE, 4, false); + return format; + } + case VERTEX_FORMAT_UBYTE4_NORM: + { + static const VertexFormat format(GL_UNSIGNED_BYTE, GL_TRUE, 4, false); + return format; + } + case VERTEX_FORMAT_SSHORT1: + { + static const VertexFormat format(GL_SHORT, GL_FALSE, 1, false); + return format; + } + case VERTEX_FORMAT_SSHORT1_NORM: + { + static const VertexFormat format(GL_SHORT, GL_TRUE, 1, false); + return format; + } + case VERTEX_FORMAT_SSHORT2: + { + static const VertexFormat format(GL_SHORT, GL_FALSE, 2, false); + return format; + } + case VERTEX_FORMAT_SSHORT2_NORM: + { + static const VertexFormat format(GL_SHORT, GL_TRUE, 2, false); + return format; + } + case VERTEX_FORMAT_SSHORT3: + { + static const VertexFormat format(GL_SHORT, GL_FALSE, 3, false); + return format; + } + case VERTEX_FORMAT_SSHORT3_NORM: + { + static const VertexFormat format(GL_SHORT, GL_TRUE, 3, false); + return format; + } + case VERTEX_FORMAT_SSHORT4: + { + static const VertexFormat format(GL_SHORT, GL_FALSE, 4, false); + return format; + } + case VERTEX_FORMAT_SSHORT4_NORM: + { + static const VertexFormat format(GL_SHORT, GL_TRUE, 4, false); + return format; + } + case VERTEX_FORMAT_USHORT1: + { + static const VertexFormat format(GL_UNSIGNED_SHORT, GL_FALSE, 1, false); + return format; + } + case VERTEX_FORMAT_USHORT1_NORM: + { + static const VertexFormat format(GL_UNSIGNED_SHORT, GL_TRUE, 1, false); + return format; + } + case VERTEX_FORMAT_USHORT2: + { + static const VertexFormat format(GL_UNSIGNED_SHORT, GL_FALSE, 2, false); + return format; + } + case VERTEX_FORMAT_USHORT2_NORM: + { + static const VertexFormat format(GL_UNSIGNED_SHORT, GL_TRUE, 2, false); + return format; + } + case VERTEX_FORMAT_USHORT3: + { + static const VertexFormat format(GL_UNSIGNED_SHORT, GL_FALSE, 3, false); + return format; + } + case VERTEX_FORMAT_USHORT3_NORM: + { + static const VertexFormat format(GL_UNSIGNED_SHORT, GL_TRUE, 3, false); + return format; + } + case VERTEX_FORMAT_USHORT4: + { + static const VertexFormat format(GL_UNSIGNED_SHORT, GL_FALSE, 4, false); + return format; + } + case VERTEX_FORMAT_USHORT4_NORM: + { + static const VertexFormat format(GL_UNSIGNED_SHORT, GL_TRUE, 4, false); + return format; + } + case VERTEX_FORMAT_SINT1: + { + static const VertexFormat format(GL_INT, GL_FALSE, 1, false); + return format; + } + case VERTEX_FORMAT_SINT1_NORM: + { + static const VertexFormat format(GL_INT, GL_TRUE, 1, false); + return format; + } + case VERTEX_FORMAT_SINT2: + { + static const VertexFormat format(GL_INT, GL_FALSE, 2, false); + return format; + } + case VERTEX_FORMAT_SINT2_NORM: + { + static const VertexFormat format(GL_INT, GL_TRUE, 2, false); + return format; + } + case VERTEX_FORMAT_SINT3: + { + static const VertexFormat format(GL_INT, GL_FALSE, 3, false); + return format; + } + case VERTEX_FORMAT_SINT3_NORM: + { + static const VertexFormat format(GL_INT, GL_TRUE, 3, false); + return format; + } + case VERTEX_FORMAT_SINT4: + { + static const VertexFormat format(GL_INT, GL_FALSE, 4, false); + return format; + } + case VERTEX_FORMAT_SINT4_NORM: + { + static const VertexFormat format(GL_INT, GL_TRUE, 4, false); + return format; + } + case VERTEX_FORMAT_UINT1: + { + static const VertexFormat format(GL_UNSIGNED_INT, GL_FALSE, 1, false); + return format; + } + case VERTEX_FORMAT_UINT1_NORM: + { + static const VertexFormat format(GL_UNSIGNED_INT, GL_TRUE, 1, false); + return format; + } + case VERTEX_FORMAT_UINT2: + { + static const VertexFormat format(GL_UNSIGNED_INT, GL_FALSE, 2, false); + return format; + } + case VERTEX_FORMAT_UINT2_NORM: + { + static const VertexFormat format(GL_UNSIGNED_INT, GL_TRUE, 2, false); + return format; + } + case VERTEX_FORMAT_UINT3: + { + static const VertexFormat format(GL_UNSIGNED_INT, GL_FALSE, 3, false); + return format; + } + case VERTEX_FORMAT_UINT3_NORM: + { + static const VertexFormat format(GL_UNSIGNED_INT, GL_TRUE, 3, false); + return format; + } + case VERTEX_FORMAT_UINT4: + { + static const VertexFormat format(GL_UNSIGNED_INT, GL_FALSE, 4, false); + return format; + } + case VERTEX_FORMAT_UINT4_NORM: + { + static const VertexFormat format(GL_UNSIGNED_INT, GL_TRUE, 4, false); + return format; + } + case VERTEX_FORMAT_SBYTE1_INT: + { + static const VertexFormat format(GL_BYTE, GL_FALSE, 1, true); + return format; + } + case VERTEX_FORMAT_SBYTE2_INT: + { + static const VertexFormat format(GL_BYTE, GL_FALSE, 2, true); + return format; + } + case VERTEX_FORMAT_SBYTE3_INT: + { + static const VertexFormat format(GL_BYTE, GL_FALSE, 3, true); + return format; + } + case VERTEX_FORMAT_SBYTE4_INT: + { + static const VertexFormat format(GL_BYTE, GL_FALSE, 4, true); + return format; + } + case VERTEX_FORMAT_UBYTE1_INT: + { + static const VertexFormat format(GL_UNSIGNED_BYTE, GL_FALSE, 1, true); + return format; + } + case VERTEX_FORMAT_UBYTE2_INT: + { + static const VertexFormat format(GL_UNSIGNED_BYTE, GL_FALSE, 2, true); + return format; + } + case VERTEX_FORMAT_UBYTE3_INT: + { + static const VertexFormat format(GL_UNSIGNED_BYTE, GL_FALSE, 3, true); + return format; + } + case VERTEX_FORMAT_UBYTE4_INT: + { + static const VertexFormat format(GL_UNSIGNED_BYTE, GL_FALSE, 4, true); + return format; + } + case VERTEX_FORMAT_SSHORT1_INT: + { + static const VertexFormat format(GL_SHORT, GL_FALSE, 1, true); + return format; + } + case VERTEX_FORMAT_SSHORT2_INT: + { + static const VertexFormat format(GL_SHORT, GL_FALSE, 2, true); + return format; + } + case VERTEX_FORMAT_SSHORT3_INT: + { + static const VertexFormat format(GL_SHORT, GL_FALSE, 3, true); + return format; + } + case VERTEX_FORMAT_SSHORT4_INT: + { + static const VertexFormat format(GL_SHORT, GL_FALSE, 4, true); + return format; + } + case VERTEX_FORMAT_USHORT1_INT: + { + static const VertexFormat format(GL_UNSIGNED_SHORT, GL_FALSE, 1, true); + return format; + } + case VERTEX_FORMAT_USHORT2_INT: + { + static const VertexFormat format(GL_UNSIGNED_SHORT, GL_FALSE, 2, true); + return format; + } + case VERTEX_FORMAT_USHORT3_INT: + { + static const VertexFormat format(GL_UNSIGNED_SHORT, GL_FALSE, 3, true); + return format; + } + case VERTEX_FORMAT_USHORT4_INT: + { + static const VertexFormat format(GL_UNSIGNED_SHORT, GL_FALSE, 4, true); + return format; + } + case VERTEX_FORMAT_SINT1_INT: + { + static const VertexFormat format(GL_INT, GL_FALSE, 1, true); + return format; + } + case VERTEX_FORMAT_SINT2_INT: + { + static const VertexFormat format(GL_INT, GL_FALSE, 2, true); + return format; + } + case VERTEX_FORMAT_SINT3_INT: + { + static const VertexFormat format(GL_INT, GL_FALSE, 3, true); + return format; + } + case VERTEX_FORMAT_SINT4_INT: + { + static const VertexFormat format(GL_INT, GL_FALSE, 4, true); + return format; + } + case VERTEX_FORMAT_UINT1_INT: + { + static const VertexFormat format(GL_UNSIGNED_INT, GL_FALSE, 1, true); + return format; + } + case VERTEX_FORMAT_UINT2_INT: + { + static const VertexFormat format(GL_UNSIGNED_INT, GL_FALSE, 2, true); + return format; + } + case VERTEX_FORMAT_UINT3_INT: + { + static const VertexFormat format(GL_UNSIGNED_INT, GL_FALSE, 3, true); + return format; + } + case VERTEX_FORMAT_UINT4_INT: + { + static const VertexFormat format(GL_UNSIGNED_INT, GL_FALSE, 4, true); + return format; + } + case VERTEX_FORMAT_FIXED1: + { + static const VertexFormat format(GL_FIXED, GL_FALSE, 1, false); + return format; + } + case VERTEX_FORMAT_FIXED2: + { + static const VertexFormat format(GL_FIXED, GL_FALSE, 2, false); + return format; + } + case VERTEX_FORMAT_FIXED3: + { + static const VertexFormat format(GL_FIXED, GL_FALSE, 3, false); + return format; + } + case VERTEX_FORMAT_FIXED4: + { + static const VertexFormat format(GL_FIXED, GL_FALSE, 4, false); + return format; + } + case VERTEX_FORMAT_HALF1: + { + static const VertexFormat format(GL_HALF_FLOAT, GL_FALSE, 1, false); + return format; + } + case VERTEX_FORMAT_HALF2: + { + static const VertexFormat format(GL_HALF_FLOAT, GL_FALSE, 2, false); + return format; + } + case VERTEX_FORMAT_HALF3: + { + static const VertexFormat format(GL_HALF_FLOAT, GL_FALSE, 3, false); + return format; + } + case VERTEX_FORMAT_HALF4: + { + static const VertexFormat format(GL_HALF_FLOAT, GL_FALSE, 4, false); + return format; + } + case VERTEX_FORMAT_FLOAT1: + { + static const VertexFormat format(GL_FLOAT, GL_FALSE, 1, false); + return format; + } + case VERTEX_FORMAT_FLOAT2: + { + static const VertexFormat format(GL_FLOAT, GL_FALSE, 2, false); + return format; + } + case VERTEX_FORMAT_FLOAT3: + { + static const VertexFormat format(GL_FLOAT, GL_FALSE, 3, false); + return format; + } + case VERTEX_FORMAT_FLOAT4: + { + static const VertexFormat format(GL_FLOAT, GL_FALSE, 4, false); + return format; + } + case VERTEX_FORMAT_SINT210: + { + static const VertexFormat format(GL_INT_2_10_10_10_REV, GL_FALSE, 4, false); + return format; + } + case VERTEX_FORMAT_UINT210: + { + static const VertexFormat format(GL_UNSIGNED_INT_2_10_10_10_REV, GL_FALSE, 4, false); + return format; + } + case VERTEX_FORMAT_SINT210_NORM: + { + static const VertexFormat format(GL_INT_2_10_10_10_REV, GL_TRUE, 4, false); + return format; + } + case VERTEX_FORMAT_UINT210_NORM: + { + static const VertexFormat format(GL_UNSIGNED_INT_2_10_10_10_REV, GL_TRUE, 4, false); + return format; + } + case VERTEX_FORMAT_SINT210_INT: + { + static const VertexFormat format(GL_INT_2_10_10_10_REV, GL_FALSE, 4, true); + return format; + } + case VERTEX_FORMAT_UINT210_INT: + { + static const VertexFormat format(GL_UNSIGNED_INT_2_10_10_10_REV, GL_FALSE, 4, true); + return format; + } + default: + { + static const VertexFormat format(GL_NONE, GL_FALSE, 0, false); + return format; + } + } +} + +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); +} + } diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/formatutils.h b/Source/ThirdParty/ANGLE/src/libANGLE/formatutils.h index 37d4a8f8ef10..6863e4ddc42d 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/formatutils.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/formatutils.h @@ -66,8 +66,18 @@ struct InternalFormat SupportCheckFunction filterSupport; GLuint computeRowPitch(GLenum formatType, GLsizei width, GLint alignment, GLint rowLength) const; - GLuint computeDepthPitch(GLenum formatType, GLsizei width, GLsizei height, GLint alignment, GLint rowLength) const; + GLuint computeDepthPitch(GLenum formatType, + GLsizei width, + GLsizei height, + GLint alignment, + GLint rowLength, + GLint imageHeight) const; GLuint computeBlockSize(GLenum formatType, GLsizei width, GLsizei height) const; + GLuint computeSkipPixels(GLint rowPitch, + GLint depthPitch, + GLint skipImages, + GLint skipRows, + GLint skipPixels) const; }; const InternalFormat &GetInternalFormatInfo(GLenum internalFormat); @@ -76,6 +86,149 @@ GLenum GetSizedInternalFormat(GLenum internalFormat, GLenum type); typedef std::set FormatSet; const FormatSet &GetAllSizedInternalFormats(); -} +// 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); + +enum VertexFormatType +{ + VERTEX_FORMAT_INVALID, + VERTEX_FORMAT_SBYTE1, + VERTEX_FORMAT_SBYTE1_NORM, + VERTEX_FORMAT_SBYTE2, + VERTEX_FORMAT_SBYTE2_NORM, + VERTEX_FORMAT_SBYTE3, + VERTEX_FORMAT_SBYTE3_NORM, + VERTEX_FORMAT_SBYTE4, + VERTEX_FORMAT_SBYTE4_NORM, + VERTEX_FORMAT_UBYTE1, + VERTEX_FORMAT_UBYTE1_NORM, + VERTEX_FORMAT_UBYTE2, + VERTEX_FORMAT_UBYTE2_NORM, + VERTEX_FORMAT_UBYTE3, + VERTEX_FORMAT_UBYTE3_NORM, + VERTEX_FORMAT_UBYTE4, + VERTEX_FORMAT_UBYTE4_NORM, + VERTEX_FORMAT_SSHORT1, + VERTEX_FORMAT_SSHORT1_NORM, + VERTEX_FORMAT_SSHORT2, + VERTEX_FORMAT_SSHORT2_NORM, + VERTEX_FORMAT_SSHORT3, + VERTEX_FORMAT_SSHORT3_NORM, + VERTEX_FORMAT_SSHORT4, + VERTEX_FORMAT_SSHORT4_NORM, + VERTEX_FORMAT_USHORT1, + VERTEX_FORMAT_USHORT1_NORM, + VERTEX_FORMAT_USHORT2, + VERTEX_FORMAT_USHORT2_NORM, + VERTEX_FORMAT_USHORT3, + VERTEX_FORMAT_USHORT3_NORM, + VERTEX_FORMAT_USHORT4, + VERTEX_FORMAT_USHORT4_NORM, + VERTEX_FORMAT_SINT1, + VERTEX_FORMAT_SINT1_NORM, + VERTEX_FORMAT_SINT2, + VERTEX_FORMAT_SINT2_NORM, + VERTEX_FORMAT_SINT3, + VERTEX_FORMAT_SINT3_NORM, + VERTEX_FORMAT_SINT4, + VERTEX_FORMAT_SINT4_NORM, + VERTEX_FORMAT_UINT1, + VERTEX_FORMAT_UINT1_NORM, + VERTEX_FORMAT_UINT2, + VERTEX_FORMAT_UINT2_NORM, + VERTEX_FORMAT_UINT3, + VERTEX_FORMAT_UINT3_NORM, + VERTEX_FORMAT_UINT4, + VERTEX_FORMAT_UINT4_NORM, + VERTEX_FORMAT_SBYTE1_INT, + VERTEX_FORMAT_SBYTE2_INT, + VERTEX_FORMAT_SBYTE3_INT, + VERTEX_FORMAT_SBYTE4_INT, + VERTEX_FORMAT_UBYTE1_INT, + VERTEX_FORMAT_UBYTE2_INT, + VERTEX_FORMAT_UBYTE3_INT, + VERTEX_FORMAT_UBYTE4_INT, + VERTEX_FORMAT_SSHORT1_INT, + VERTEX_FORMAT_SSHORT2_INT, + VERTEX_FORMAT_SSHORT3_INT, + VERTEX_FORMAT_SSHORT4_INT, + VERTEX_FORMAT_USHORT1_INT, + VERTEX_FORMAT_USHORT2_INT, + VERTEX_FORMAT_USHORT3_INT, + VERTEX_FORMAT_USHORT4_INT, + VERTEX_FORMAT_SINT1_INT, + VERTEX_FORMAT_SINT2_INT, + VERTEX_FORMAT_SINT3_INT, + VERTEX_FORMAT_SINT4_INT, + VERTEX_FORMAT_UINT1_INT, + VERTEX_FORMAT_UINT2_INT, + VERTEX_FORMAT_UINT3_INT, + VERTEX_FORMAT_UINT4_INT, + VERTEX_FORMAT_FIXED1, + VERTEX_FORMAT_FIXED2, + VERTEX_FORMAT_FIXED3, + VERTEX_FORMAT_FIXED4, + VERTEX_FORMAT_HALF1, + VERTEX_FORMAT_HALF2, + VERTEX_FORMAT_HALF3, + VERTEX_FORMAT_HALF4, + VERTEX_FORMAT_FLOAT1, + VERTEX_FORMAT_FLOAT2, + VERTEX_FORMAT_FLOAT3, + VERTEX_FORMAT_FLOAT4, + VERTEX_FORMAT_SINT210, + VERTEX_FORMAT_UINT210, + VERTEX_FORMAT_SINT210_NORM, + VERTEX_FORMAT_UINT210_NORM, + VERTEX_FORMAT_SINT210_INT, + VERTEX_FORMAT_UINT210_INT, +}; + +typedef std::vector InputLayout; + +struct VertexFormat : angle::NonCopyable +{ + VertexFormat(GLenum typeIn, GLboolean normalizedIn, GLuint componentsIn, bool pureIntegerIn); + + GLenum type; + GLboolean normalized; + GLuint components; + bool pureInteger; +}; + +VertexFormatType GetVertexFormatType(GLenum type, GLboolean normalized, GLuint components, bool pureInteger); +VertexFormatType GetVertexFormatType(const VertexAttribute &attrib); +VertexFormatType GetVertexFormatType(const VertexAttribute &attrib, GLenum currentValueType); +const VertexFormat &GetVertexFormatFromType(VertexFormatType vertexFormatType); + +} // namespace gl #endif // LIBANGLE_FORMATUTILS_H_ diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/histogram_macros.h b/Source/ThirdParty/ANGLE/src/libANGLE/histogram_macros.h index aa95487e4d1b..d1c952a6bd3d 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/histogram_macros.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/histogram_macros.h @@ -48,6 +48,9 @@ #define ANGLE_HISTOGRAM_PERCENTAGE(name, under_one_hundred) \ ANGLE_HISTOGRAM_ENUMERATION(name, under_one_hundred, 101) +#define ANGLE_HISTOGRAM_BOOLEAN(name, sample) \ + ANGLEPlatformCurrent()->histogramBoolean(name, sample) + #define ANGLE_HISTOGRAM_ENUMERATION(name, sample, boundary_value) \ ANGLEPlatformCurrent()->histogramEnumeration(name, sample, boundary_value) @@ -57,4 +60,48 @@ #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(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 ScopedHistogramTimer##key \ + { \ + public: \ + ScopedHistogramTimer##key() : constructed_(ANGLEPlatformCurrent()->currentTime()) {} \ + ~ScopedHistogramTimer##key() \ + { \ + if (constructed_ == 0) \ + return; \ + double elapsed = ANGLEPlatformCurrent()->currentTime() - 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 // BASE_METRICS_HISTOGRAM_MACROS_H_ diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/queryconversions.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/queryconversions.cpp index 13150c2b7184..3a6059a89cb5 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/queryconversions.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/queryconversions.cpp @@ -6,37 +6,44 @@ // queryconversions.cpp: Implementation of state query cast conversions +#include "libANGLE/queryconversions.h" + +#include + #include "libANGLE/Context.h" #include "common/utilities.h" namespace gl { -// 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 CastStateValue, where it eliminates duplicate parameters. +namespace +{ -template -struct CastStateValueEnum { static GLenum mEnumForType; }; +GLint64 ExpandFloatToInteger(GLfloat value) +{ + return static_cast((static_cast(0xFFFFFFFFULL) * value - 1.0) / 2.0); +} -template <> GLenum CastStateValueEnum::mEnumForType = GL_INT; -template <> GLenum CastStateValueEnum::mEnumForType = GL_UNSIGNED_INT; -template <> GLenum CastStateValueEnum::mEnumForType = GL_BOOL; -template <> GLenum CastStateValueEnum::mEnumForType = GL_INT_64_ANGLEX; -template <> GLenum CastStateValueEnum::mEnumForType = GL_FLOAT; +template +QueryT ClampToQueryRange(GLint64 value) +{ + const GLint64 min = static_cast(std::numeric_limits::min()); + const GLint64 max = static_cast(std::numeric_limits::max()); + return static_cast(clamp(value, min, max)); +} template QueryT CastStateValueToInt(GLenum pname, NativeT value) { - GLenum queryType = CastStateValueEnum::mEnumForType; - GLenum nativeType = CastStateValueEnum::mEnumForType; + GLenum queryType = GLTypeToGLenum::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 if (pname == GL_DEPTH_RANGE || pname == GL_COLOR_CLEAR_VALUE || pname == GL_DEPTH_CLEAR_VALUE || pname == GL_BLEND_COLOR) { - return static_cast((static_cast(0xFFFFFFFF) * value - 1.0f) / 2.0f); + return ClampToQueryRange(ExpandFloatToInteger(static_cast(value))); } else { @@ -59,77 +66,80 @@ QueryT CastStateValueToInt(GLenum pname, NativeT value) template QueryT CastStateValue(GLenum pname, NativeT value) { - GLenum queryType = CastStateValueEnum::mEnumForType; + GLenum queryType = GLTypeToGLenum::value; switch (queryType) { - case GL_INT: return CastStateValueToInt(pname, value); - case GL_INT_64_ANGLEX: return CastStateValueToInt(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; + case GL_INT: + return CastStateValueToInt(pname, value); + case GL_INT_64_ANGLEX: + return CastStateValueToInt(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; } } +} // anonymous namespace + +template <> +GLenum GLTypeToGLenum::value = GL_INT; +template <> +GLenum GLTypeToGLenum::value = GL_UNSIGNED_INT; +template <> +GLenum GLTypeToGLenum::value = GL_BOOL; +template <> +GLenum GLTypeToGLenum::value = GL_INT_64_ANGLEX; +template <> +GLenum GLTypeToGLenum::value = GL_FLOAT; + template void CastStateValues(Context *context, GLenum nativeType, GLenum pname, unsigned int numParams, QueryT *outParams) { if (nativeType == GL_INT) { - GLint *intParams = NULL; - intParams = new GLint[numParams]; - - context->getIntegerv(pname, intParams); + std::vector intParams(numParams, 0); + context->getIntegerv(pname, intParams.data()); for (unsigned int i = 0; i < numParams; ++i) { outParams[i] = CastStateValue(pname, intParams[i]); } - - delete [] intParams; } else if (nativeType == GL_BOOL) { - GLboolean *boolParams = NULL; - boolParams = new GLboolean[numParams]; - - context->getBooleanv(pname, boolParams); + std::vector boolParams(numParams, GL_FALSE); + context->getBooleanv(pname, boolParams.data()); for (unsigned int i = 0; i < numParams; ++i) { outParams[i] = (boolParams[i] == GL_FALSE ? static_cast(0) : static_cast(1)); } - - delete [] boolParams; } else if (nativeType == GL_FLOAT) { - GLfloat *floatParams = NULL; - floatParams = new GLfloat[numParams]; - - context->getFloatv(pname, floatParams); + std::vector floatParams(numParams, 0.0f); + context->getFloatv(pname, floatParams.data()); for (unsigned int i = 0; i < numParams; ++i) { outParams[i] = CastStateValue(pname, floatParams[i]); } - - delete [] floatParams; } else if (nativeType == GL_INT_64_ANGLEX) { - GLint64 *int64Params = NULL; - int64Params = new GLint64[numParams]; - - context->getInteger64v(pname, int64Params); + std::vector int64Params(numParams, 0); + context->getInteger64v(pname, int64Params.data()); for (unsigned int i = 0; i < numParams; ++i) { outParams[i] = CastStateValue(pname, int64Params[i]); } - - delete [] int64Params; } else UNREACHABLE(); } diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/queryconversions.h b/Source/ThirdParty/ANGLE/src/libANGLE/queryconversions.h index da7047f730e9..e0fdbe17e0e9 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/queryconversions.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/queryconversions.h @@ -6,8 +6,25 @@ // 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 CastStateValue, where it eliminates duplicate parameters. + +template +struct GLTypeToGLenum +{ + static GLenum value; +}; // The GL state query API types are: bool, int, uint, float, int64 template @@ -15,3 +32,5 @@ void CastStateValues(Context *context, GLenum nativeType, GLenum pname, unsigned int numParams, QueryT *outParams); } + +#endif // LIBANGLE_QUERY_CONVERSIONS_H_ diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/BufferImpl.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/BufferImpl.h index 755e79389377..d77f06cf0968 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/BufferImpl.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/BufferImpl.h @@ -10,7 +10,8 @@ #define LIBANGLE_RENDERER_BUFFERIMPL_H_ #include "common/angleutils.h" -#include "libANGLE/Buffer.h" +#include "common/mathutil.h" +#include "libANGLE/Error.h" #include @@ -29,9 +30,11 @@ class BufferImpl : angle::NonCopyable virtual gl::Error mapRange(size_t offset, size_t length, GLbitfield access, GLvoid **mapPtr) = 0; virtual gl::Error unmap(GLboolean *result) = 0; - // This method may not have a corresponding GL-backed function. It is necessary - // for validation, for certain indexed draw calls. - virtual gl::Error getData(const uint8_t **outData) = 0; + virtual gl::Error getIndexRange(GLenum type, + size_t offset, + size_t count, + bool primitiveRestartEnabled, + gl::IndexRange *outRange) = 0; }; } diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/BufferImpl_mock.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/BufferImpl_mock.h index 88bf3d1b6094..a6387661ceac 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/BufferImpl_mock.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/BufferImpl_mock.h @@ -19,7 +19,7 @@ namespace rx class MockBufferImpl : public BufferImpl { public: - ~MockBufferImpl() override { destructor(); } + ~MockBufferImpl() { destructor(); } MOCK_METHOD3(setData, gl::Error(const void*, size_t, GLenum)); MOCK_METHOD3(setSubData, gl::Error(const void*, size_t, size_t)); @@ -28,7 +28,7 @@ class MockBufferImpl : public BufferImpl MOCK_METHOD4(mapRange, gl::Error(size_t, size_t, GLbitfield, GLvoid **)); MOCK_METHOD1(unmap, gl::Error(GLboolean *result)); - MOCK_METHOD1(getData, gl::Error(const uint8_t **)); + MOCK_METHOD5(getIndexRange, gl::Error(GLenum, size_t, size_t, bool, gl::IndexRange *)); MOCK_METHOD0(destructor, void()); }; diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/CompilerImpl.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/CompilerImpl.h index ccc78d8c2adf..82f1ffe0d35a 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/CompilerImpl.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/CompilerImpl.h @@ -8,6 +8,7 @@ // for the gl::Compiler object. #include "common/angleutils.h" +#include "GLSLANG/ShaderLang.h" #include "libANGLE/Error.h" #ifndef LIBANGLE_RENDERER_COMPILERIMPL_H_ @@ -23,6 +24,9 @@ class CompilerImpl : angle::NonCopyable virtual ~CompilerImpl() {} virtual gl::Error release() = 0; + + // TODO(jmadill): Expose translator built-in resources init method. + virtual ShShaderOutput getTranslatorOutputType() const = 0; }; } diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/DeviceImpl.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/DeviceImpl.h index eb150549e144..550bc1e2d9a6 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/DeviceImpl.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/DeviceImpl.h @@ -26,9 +26,10 @@ class DeviceImpl : angle::NonCopyable DeviceImpl(); virtual ~DeviceImpl(); - virtual egl::Error getDevice(EGLAttrib *value) = 0; + virtual egl::Error getDevice(void **outValue) = 0; virtual EGLint getType() = 0; virtual void generateExtensions(egl::DeviceExtensions *outExtensions) const = 0; + virtual bool deviceExternallySourced() = 0; }; } diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/DisplayImpl.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/DisplayImpl.cpp index 7713ee2d6d86..8061189f0a76 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/DisplayImpl.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/DisplayImpl.cpp @@ -21,16 +21,13 @@ DisplayImpl::DisplayImpl() DisplayImpl::~DisplayImpl() { - while (!mSurfaceSet.empty()) - { - destroySurface(*mSurfaceSet.begin()); - } + ASSERT(mSurfaceSet.empty()); } void DisplayImpl::destroySurface(egl::Surface *surface) { mSurfaceSet.erase(surface); - surface->release(); + surface->onDestroy(); } const egl::DisplayExtensions &DisplayImpl::getExtensions() const diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/DisplayImpl.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/DisplayImpl.h index 6ae2c11a1d44..dabe964ed801 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/DisplayImpl.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/DisplayImpl.h @@ -24,6 +24,7 @@ class AttributeMap; class Display; struct Config; class Surface; +class ImageSibling; } namespace gl @@ -34,8 +35,10 @@ class Context; namespace rx { class SurfaceImpl; +class ImageImpl; struct ConfigDesc; class DeviceImpl; +class StreamImpl; class DisplayImpl : angle::NonCopyable { @@ -46,16 +49,27 @@ class DisplayImpl : angle::NonCopyable virtual egl::Error initialize(egl::Display *display) = 0; virtual void terminate() = 0; - virtual egl::Error createWindowSurface(const egl::Config *configuration, EGLNativeWindowType window, const egl::AttributeMap &attribs, - SurfaceImpl **outSurface) = 0; - virtual egl::Error createPbufferSurface(const egl::Config *configuration, const egl::AttributeMap &attribs, - SurfaceImpl **outSurface) = 0; - virtual egl::Error createPbufferFromClientBuffer(const egl::Config *configuration, EGLClientBuffer shareHandle, - const egl::AttributeMap &attribs, SurfaceImpl **outSurface) = 0; - virtual egl::Error createPixmapSurface(const egl::Config *configuration, NativePixmapType nativePixmap, - const egl::AttributeMap &attribs, SurfaceImpl **outSurface) = 0; - virtual egl::Error createContext(const egl::Config *config, const gl::Context *shareContext, const egl::AttributeMap &attribs, - gl::Context **outContext) = 0; + virtual SurfaceImpl *createWindowSurface(const egl::Config *configuration, + EGLNativeWindowType window, + const egl::AttributeMap &attribs) = 0; + virtual SurfaceImpl *createPbufferSurface(const egl::Config *configuration, + const egl::AttributeMap &attribs) = 0; + virtual SurfaceImpl *createPbufferFromClientBuffer(const egl::Config *configuration, + EGLClientBuffer shareHandle, + const egl::AttributeMap &attribs) = 0; + virtual SurfaceImpl *createPixmapSurface(const egl::Config *configuration, + NativePixmapType nativePixmap, + const egl::AttributeMap &attribs) = 0; + + virtual ImageImpl *createImage(EGLenum target, + egl::ImageSibling *buffer, + const egl::AttributeMap &attribs) = 0; + + virtual gl::Context *createContext(const egl::Config *config, + const gl::Context *shareContext, + const egl::AttributeMap &attribs) = 0; + + virtual StreamImpl *createStream(const egl::AttributeMap &attribs) = 0; virtual egl::Error makeCurrent(egl::Surface *drawSurface, egl::Surface *readSurface, gl::Context *context) = 0; @@ -71,6 +85,11 @@ class DisplayImpl : angle::NonCopyable virtual egl::Error getDevice(DeviceImpl **device) = 0; + virtual egl::Error waitClient() const = 0; + virtual egl::Error waitNative(EGLint engine, + egl::Surface *drawSurface, + egl::Surface *readSurface) const = 0; + const egl::Caps &getCaps() const; typedef std::set SurfaceSet; diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/FramebufferImpl.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/FramebufferImpl.h index 2d3c6e3f5d01..680122d0edbc 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/FramebufferImpl.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/FramebufferImpl.h @@ -31,22 +31,28 @@ class FramebufferImpl : angle::NonCopyable explicit FramebufferImpl(const gl::Framebuffer::Data &data) : mData(data) { } virtual ~FramebufferImpl() { } - virtual void onUpdateColorAttachment(size_t index) = 0; - virtual void onUpdateDepthAttachment() = 0; - virtual void onUpdateStencilAttachment() = 0; - virtual void onUpdateDepthStencilAttachment() = 0; - - virtual void setDrawBuffers(size_t count, const GLenum *buffers) = 0; - virtual void setReadBuffer(GLenum buffer) = 0; - + virtual gl::Error discard(size_t count, const GLenum *attachments) = 0; virtual gl::Error invalidate(size_t count, const GLenum *attachments) = 0; virtual gl::Error invalidateSub(size_t count, const GLenum *attachments, const gl::Rectangle &area) = 0; virtual gl::Error clear(const gl::Data &data, GLbitfield mask) = 0; - virtual gl::Error clearBufferfv(const gl::State &state, GLenum buffer, GLint drawbuffer, const GLfloat *values) = 0; - virtual gl::Error clearBufferuiv(const gl::State &state, GLenum buffer, GLint drawbuffer, const GLuint *values) = 0; - virtual gl::Error clearBufferiv(const gl::State &state, GLenum buffer, GLint drawbuffer, const GLint *values) = 0; - virtual gl::Error clearBufferfi(const gl::State &state, GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil) = 0; + virtual gl::Error clearBufferfv(const gl::Data &data, + GLenum buffer, + GLint drawbuffer, + const GLfloat *values) = 0; + virtual gl::Error clearBufferuiv(const gl::Data &data, + GLenum buffer, + GLint drawbuffer, + const GLuint *values) = 0; + virtual gl::Error clearBufferiv(const gl::Data &data, + GLenum buffer, + GLint drawbuffer, + const GLint *values) = 0; + virtual gl::Error clearBufferfi(const gl::Data &data, + GLenum buffer, + GLint drawbuffer, + GLfloat depth, + GLint stencil) = 0; virtual GLenum getImplementationColorReadFormat() const = 0; virtual GLenum getImplementationColorReadType() const = 0; @@ -55,7 +61,9 @@ class FramebufferImpl : angle::NonCopyable virtual gl::Error blit(const gl::State &state, const gl::Rectangle &sourceArea, const gl::Rectangle &destArea, GLbitfield mask, GLenum filter, const gl::Framebuffer *sourceFramebuffer) = 0; - virtual GLenum checkStatus() const = 0; + virtual bool checkStatus() const = 0; + + virtual void syncState(const gl::Framebuffer::DirtyBits &dirtyBits) = 0; const gl::Framebuffer::Data &getData() const { return mData; } diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/FramebufferImpl_mock.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/FramebufferImpl_mock.h new file mode 100644 index 000000000000..57c95342d7ee --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/FramebufferImpl_mock.h @@ -0,0 +1,72 @@ +// +// 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. +// +// FramebufferImpl_mock.h: +// Defines a mock of the FramebufferImpl class. +// + +#ifndef LIBANGLE_RENDERER_FRAMEBUFFERIMPLMOCK_H_ +#define LIBANGLE_RENDERER_FRAMEBUFFERIMPLMOCK_H_ + +#include "gmock/gmock.h" + +#include "libANGLE/renderer/FramebufferImpl.h" + +namespace rx +{ + +class MockFramebufferImpl : public rx::FramebufferImpl +{ + public: + MockFramebufferImpl() : rx::FramebufferImpl(gl::Framebuffer::Data()) {} + virtual ~MockFramebufferImpl() { destroy(); } + + MOCK_METHOD2(discard, gl::Error(size_t, const GLenum *)); + MOCK_METHOD2(invalidate, gl::Error(size_t, const GLenum *)); + MOCK_METHOD3(invalidateSub, gl::Error(size_t, const GLenum *, const gl::Rectangle &)); + + MOCK_METHOD2(clear, gl::Error(const gl::Data &, GLbitfield)); + MOCK_METHOD4(clearBufferfv, gl::Error(const gl::Data &, GLenum, GLint, const GLfloat *)); + MOCK_METHOD4(clearBufferuiv, gl::Error(const gl::Data &, GLenum, GLint, const GLuint *)); + MOCK_METHOD4(clearBufferiv, gl::Error(const gl::Data &, GLenum, GLint, const GLint *)); + MOCK_METHOD5(clearBufferfi, gl::Error(const gl::Data &, GLenum, GLint, GLfloat, GLint)); + + MOCK_CONST_METHOD0(getImplementationColorReadFormat, GLenum()); + MOCK_CONST_METHOD0(getImplementationColorReadType, GLenum()); + MOCK_CONST_METHOD5( + readPixels, + gl::Error(const gl::State &, const gl::Rectangle &, GLenum, GLenum, GLvoid *)); + + MOCK_METHOD6(blit, + gl::Error(const gl::State &, + const gl::Rectangle &, + const gl::Rectangle &, + GLbitfield, + GLenum, + const gl::Framebuffer *)); + + MOCK_CONST_METHOD0(checkStatus, bool()); + + MOCK_METHOD1(syncState, void(const gl::Framebuffer::DirtyBits &)); + + MOCK_METHOD0(destroy, void()); +}; + +inline ::testing::NiceMock *MakeFramebufferMock() +{ + ::testing::NiceMock *framebufferImpl = + new ::testing::NiceMock(); + // TODO(jmadill): add ON_CALLS for other returning methods + ON_CALL(*framebufferImpl, checkStatus()).WillByDefault(::testing::Return(true)); + + // We must mock the destructor since NiceMock doesn't work for destructors. + EXPECT_CALL(*framebufferImpl, destroy()).Times(1).RetiresOnSaturation(); + + return framebufferImpl; +} + +} // namespace rx + +#endif // LIBANGLE_RENDERER_FRAMEBUFFERIMPLMOCK_H_ diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/ImageImpl.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/ImageImpl.h new file mode 100644 index 000000000000..e48f1946a8c2 --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/ImageImpl.h @@ -0,0 +1,32 @@ +// +// Copyright (c) 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" + +namespace egl +{ +class ImageSibling; +} + +namespace rx +{ +class ImageImpl : angle::NonCopyable +{ + public: + virtual ~ImageImpl() {} + virtual egl::Error initialize() = 0; + + virtual gl::Error orphan(egl::ImageSibling *sibling) = 0; +}; +} + +#endif // LIBANGLE_RENDERER_IMAGEIMPL_H_ diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/ImageImpl_mock.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/ImageImpl_mock.h new file mode 100644 index 000000000000..27fe6a394770 --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/ImageImpl_mock.h @@ -0,0 +1,28 @@ +// +// Copyright (c) 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_mock.h: Defines a mock of the ImageImpl class. + +#ifndef LIBANGLE_RENDERER_IMAGEIMPLMOCK_H_ +#define LIBANGLE_RENDERER_IMAGEIMPLMOCK_H_ + +#include "gmock/gmock.h" + +#include "libANGLE/renderer/ImageImpl.h" + +namespace rx +{ +class MockImageImpl : public ImageImpl +{ + public: + virtual ~MockImageImpl() { destructor(); } + MOCK_METHOD0(initialize, egl::Error(void)); + MOCK_METHOD1(orphan, gl::Error(egl::ImageSibling *)); + MOCK_METHOD0(destructor, void()); +}; +} + +#endif // LIBANGLE_RENDERER_IMAGEIMPLMOCK_H_ diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/ImplFactory.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/ImplFactory.h index d77e59f7df94..8e3e4af27a93 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/ImplFactory.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/ImplFactory.h @@ -11,6 +11,9 @@ #define LIBANGLE_RENDERER_IMPLFACTORY_H_ #include "libANGLE/Framebuffer.h" +#include "libANGLE/Program.h" +#include "libANGLE/Shader.h" +#include "libANGLE/VertexArray.h" namespace rx { @@ -22,10 +25,12 @@ class FramebufferImpl; class ProgramImpl; class QueryImpl; class RenderbufferImpl; +class SamplerImpl; class ShaderImpl; class TextureImpl; class TransformFeedbackImpl; class VertexArrayImpl; +class StreamImpl; class ImplFactory : angle::NonCopyable { @@ -34,12 +39,11 @@ class ImplFactory : angle::NonCopyable virtual ~ImplFactory() {} // Shader creation - virtual CompilerImpl *createCompiler(const gl::Data &data) = 0; - virtual ShaderImpl *createShader(GLenum type) = 0; - virtual ProgramImpl *createProgram() = 0; + virtual CompilerImpl *createCompiler() = 0; + virtual ShaderImpl *createShader(const gl::Shader::Data &data) = 0; + virtual ProgramImpl *createProgram(const gl::Program::Data &data) = 0; // Framebuffer creation - virtual FramebufferImpl *createDefaultFramebuffer(const gl::Framebuffer::Data &data) = 0; virtual FramebufferImpl *createFramebuffer(const gl::Framebuffer::Data &data) = 0; // Texture creation @@ -52,7 +56,7 @@ class ImplFactory : angle::NonCopyable virtual BufferImpl *createBuffer() = 0; // Vertex Array creation - virtual VertexArrayImpl *createVertexArray() = 0; + virtual VertexArrayImpl *createVertexArray(const gl::VertexArray::Data &data) = 0; // Query and Fence creation virtual QueryImpl *createQuery(GLenum type) = 0; @@ -61,6 +65,9 @@ class ImplFactory : angle::NonCopyable // Transform Feedback creation virtual TransformFeedbackImpl *createTransformFeedback() = 0; + + // Sampler object creation + virtual SamplerImpl *createSampler() = 0; }; } diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/ProgramImpl.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/ProgramImpl.h index f83793068c09..1e688045a1b1 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/ProgramImpl.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/ProgramImpl.h @@ -23,33 +23,24 @@ namespace rx struct LinkResult { + LinkResult(bool linkSuccess, const gl::Error &error) : linkSuccess(linkSuccess), error(error) {} + bool linkSuccess; gl::Error error; - LinkResult(bool linkSuccess, const gl::Error &error); }; class ProgramImpl : angle::NonCopyable { public: - typedef int SemanticIndexArray[gl::MAX_VERTEX_ATTRIBS]; - - ProgramImpl() { } - virtual ~ProgramImpl(); - - virtual bool usesPointSize() const = 0; - virtual int getShaderVersion() const = 0; - virtual GLenum getTransformFeedbackBufferMode() const = 0; + ProgramImpl(const gl::Program::Data &data) : mData(data) {} + virtual ~ProgramImpl() {} - virtual GLenum getBinaryFormat() = 0; virtual LinkResult load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream) = 0; virtual gl::Error save(gl::BinaryOutputStream *stream) = 0; + virtual void setBinaryRetrievableHint(bool retrievable) = 0; - virtual LinkResult link(const gl::Data &data, gl::InfoLog &infoLog, - gl::Shader *fragmentShader, gl::Shader *vertexShader, - const std::vector &transformFeedbackVaryings, - GLenum transformFeedbackBufferMode, - int *registers, std::vector *linkedVaryings, - std::map *outputVariables) = 0; + virtual LinkResult link(const gl::Data &data, gl::InfoLog &infoLog) = 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; @@ -73,67 +64,20 @@ class ProgramImpl : angle::NonCopyable 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; - virtual void getUniformfv(GLint location, GLfloat *params) = 0; - virtual void getUniformiv(GLint location, GLint *params) = 0; - virtual void getUniformuiv(GLint location, GLuint *params) = 0; - - // TODO: The following functions are possibly only applicable to D3D backends. The should be carefully evaluated to - // determine if they can be removed from this interface. - virtual GLint getSamplerMapping(gl::SamplerType type, unsigned int samplerIndex, const gl::Caps &caps) const = 0; - virtual GLenum getSamplerTextureType(gl::SamplerType type, unsigned int samplerIndex) const = 0; - virtual GLint getUsedSamplerRange(gl::SamplerType type) const = 0; - virtual void updateSamplerMapping() = 0; - virtual bool validateSamplers(gl::InfoLog *infoLog, const gl::Caps &caps) = 0; - - virtual LinkResult compileProgramExecutables(gl::InfoLog &infoLog, gl::Shader *fragmentShader, gl::Shader *vertexShader, - int registers) = 0; - - virtual bool linkUniforms(gl::InfoLog &infoLog, const gl::Shader &vertexShader, const gl::Shader &fragmentShader, - const gl::Caps &caps) = 0; - virtual bool defineUniformBlock(gl::InfoLog &infoLog, const gl::Shader &shader, const sh::InterfaceBlock &interfaceBlock, - const gl::Caps &caps) = 0; - - virtual gl::Error applyUniforms() = 0; - virtual gl::Error applyUniformBuffers(const gl::Data &data, GLuint uniformBlockBindings[]) = 0; - virtual bool assignUniformBlockRegister(gl::InfoLog &infoLog, gl::UniformBlock *uniformBlock, GLenum shader, - unsigned int registerIndex, const gl::Caps &caps) = 0; - - const std::vector &getUniforms() const { return mUniforms; } - const std::vector &getUniformIndices() const { return mUniformIndex; } - const std::vector &getUniformBlocks() const { return mUniformBlocks; } - const std::vector &getTransformFeedbackLinkedVaryings() const { return mTransformFeedbackLinkedVaryings; } - const std::vector getShaderAttributes() { return mShaderAttributes; } - const SemanticIndexArray &getSemanticIndexes() const { return mSemanticIndex; } - - std::vector &getUniforms() { return mUniforms; } - std::vector &getUniformIndices() { return mUniformIndex; } - std::vector &getUniformBlocks() { return mUniformBlocks; } - std::vector &getTransformFeedbackLinkedVaryings() { return mTransformFeedbackLinkedVaryings; } - SemanticIndexArray &getSemanticIndexes() { return mSemanticIndex; } - - gl::LinkedUniform *getUniformByLocation(GLint location) const; - gl::LinkedUniform *getUniformByName(const std::string &name) const; - gl::UniformBlock *getUniformBlockByIndex(GLuint blockIndex) const; - - GLint getUniformLocation(const std::string &name) const; - GLuint getUniformIndex(const std::string &name) const; - GLuint getUniformBlockIndex(const std::string &name) const; - - void setShaderAttribute(size_t index, const sh::Attribute &attrib); - void setShaderAttribute(size_t index, GLenum type, GLenum precision, const std::string &name, GLint size, int location); - - virtual void reset(); + // TODO: synchronize in syncState when dirty bits exist. + virtual void setUniformBlockBinding(GLuint uniformBlockIndex, GLuint uniformBlockBinding) = 0; - protected: - std::vector mUniforms; - std::vector mUniformIndex; - std::vector mUniformBlocks; - std::vector mTransformFeedbackLinkedVaryings; + // May only be called after a successful link operation. + // Return false for inactive blocks. + virtual bool getUniformBlockSize(const std::string &blockName, size_t *sizeOut) const = 0; - SemanticIndexArray mSemanticIndex; + // May only be called after a successful link operation. + // Returns false for inactive members. + virtual bool getUniformBlockMemberInfo(const std::string &memberUniformName, + sh::BlockMemberInfo *memberInfoOut) const = 0; - private: - std::vector mShaderAttributes; + protected: + const gl::Program::Data &mData; }; } diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/ProgramImpl_mock.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/ProgramImpl_mock.h new file mode 100644 index 000000000000..d6aa238f649f --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/ProgramImpl_mock.h @@ -0,0 +1,75 @@ +// +// 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. +// +// ProgramImpl_mock.h: +// Defines a mock of the ProgramImpl class. +// + +#ifndef LIBANGLE_RENDERER_PROGRAMIMPLMOCK_H_ +#define LIBANGLE_RENDERER_PROGRAMIMPLMOCK_H_ + +#include "gmock/gmock.h" + +#include "libANGLE/renderer/ProgramImpl.h" + +namespace rx +{ + +class MockProgramImpl : public rx::ProgramImpl +{ + public: + MockProgramImpl() : ProgramImpl(gl::Program::Data()) {} + virtual ~MockProgramImpl() { destroy(); } + + MOCK_METHOD2(load, LinkResult(gl::InfoLog &, gl::BinaryInputStream *)); + MOCK_METHOD1(save, gl::Error(gl::BinaryOutputStream *)); + MOCK_METHOD1(setBinaryRetrievableHint, void(bool)); + + MOCK_METHOD2(link, LinkResult(const gl::Data &, gl::InfoLog &)); + MOCK_METHOD2(validate, GLboolean(const gl::Caps &, gl::InfoLog *)); + + MOCK_METHOD3(setUniform1fv, void(GLint, GLsizei, const GLfloat *)); + MOCK_METHOD3(setUniform2fv, void(GLint, GLsizei, const GLfloat *)); + MOCK_METHOD3(setUniform3fv, void(GLint, GLsizei, const GLfloat *)); + MOCK_METHOD3(setUniform4fv, void(GLint, GLsizei, const GLfloat *)); + MOCK_METHOD3(setUniform1iv, void(GLint, GLsizei, const GLint *)); + MOCK_METHOD3(setUniform2iv, void(GLint, GLsizei, const GLint *)); + MOCK_METHOD3(setUniform3iv, void(GLint, GLsizei, const GLint *)); + MOCK_METHOD3(setUniform4iv, void(GLint, GLsizei, const GLint *)); + MOCK_METHOD3(setUniform1uiv, void(GLint, GLsizei, const GLuint *)); + MOCK_METHOD3(setUniform2uiv, void(GLint, GLsizei, const GLuint *)); + MOCK_METHOD3(setUniform3uiv, void(GLint, GLsizei, const GLuint *)); + MOCK_METHOD3(setUniform4uiv, void(GLint, GLsizei, const GLuint *)); + + MOCK_METHOD4(setUniformMatrix2fv, void(GLint, GLsizei, GLboolean, const GLfloat *)); + MOCK_METHOD4(setUniformMatrix3fv, void(GLint, GLsizei, GLboolean, const GLfloat *)); + MOCK_METHOD4(setUniformMatrix4fv, void(GLint, GLsizei, GLboolean, const GLfloat *)); + MOCK_METHOD4(setUniformMatrix2x3fv, void(GLint, GLsizei, GLboolean, const GLfloat *)); + MOCK_METHOD4(setUniformMatrix3x2fv, void(GLint, GLsizei, GLboolean, const GLfloat *)); + MOCK_METHOD4(setUniformMatrix2x4fv, void(GLint, GLsizei, GLboolean, const GLfloat *)); + MOCK_METHOD4(setUniformMatrix4x2fv, void(GLint, GLsizei, GLboolean, const GLfloat *)); + MOCK_METHOD4(setUniformMatrix3x4fv, void(GLint, GLsizei, GLboolean, const GLfloat *)); + MOCK_METHOD4(setUniformMatrix4x3fv, void(GLint, GLsizei, GLboolean, const GLfloat *)); + + MOCK_METHOD2(setUniformBlockBinding, void(GLuint, GLuint)); + MOCK_CONST_METHOD2(getUniformBlockSize, bool(const std::string &, size_t *)); + MOCK_CONST_METHOD2(getUniformBlockMemberInfo, bool(const std::string &, sh::BlockMemberInfo *)); + + MOCK_METHOD0(destroy, void()); +}; + +inline ::testing::NiceMock *MakeProgramMock() +{ + ::testing::NiceMock *programImpl = new ::testing::NiceMock(); + // TODO(jmadill): add ON_CALLS for returning methods + // We must mock the destructor since NiceMock doesn't work for destructors. + EXPECT_CALL(*programImpl, destroy()).Times(1).RetiresOnSaturation(); + + return programImpl; +} + +} // namespace rx + +#endif // LIBANGLE_RENDERER_PROGRAMIMPLMOCK_H_ diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/QueryImpl.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/QueryImpl.h index bed63ea1b0a4..d738eb4ffc7d 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/QueryImpl.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/QueryImpl.h @@ -26,8 +26,12 @@ class QueryImpl : angle::NonCopyable virtual gl::Error begin() = 0; virtual gl::Error end() = 0; + virtual gl::Error queryCounter() = 0; + virtual gl::Error getResult(GLint *params) = 0; virtual gl::Error getResult(GLuint *params) = 0; - virtual gl::Error isResultAvailable(GLuint *available) = 0; + virtual gl::Error getResult(GLint64 *params) = 0; + virtual gl::Error getResult(GLuint64 *params) = 0; + virtual gl::Error isResultAvailable(bool *available) = 0; GLenum getType() const { return mType; } diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/RenderbufferImpl.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/RenderbufferImpl.h index 4dee4da30b20..75b4cdcfee97 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/RenderbufferImpl.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/RenderbufferImpl.h @@ -14,17 +14,23 @@ #include "libANGLE/Error.h" #include "libANGLE/FramebufferAttachment.h" +namespace egl +{ +class Image; +} + namespace rx { class RenderbufferImpl : public FramebufferAttachmentObjectImpl { public: - RenderbufferImpl(); - virtual ~RenderbufferImpl() = 0; + RenderbufferImpl() {} + virtual ~RenderbufferImpl() {} virtual gl::Error setStorage(GLenum internalformat, size_t width, size_t height) = 0; virtual gl::Error setStorageMultisample(size_t samples, GLenum internalformat, size_t width, size_t height) = 0; + virtual gl::Error setStorageEGLImageTarget(egl::Image *image) = 0; }; } diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/RenderbufferImpl_mock.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/RenderbufferImpl_mock.h new file mode 100644 index 000000000000..c2c67cc76a27 --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/RenderbufferImpl_mock.h @@ -0,0 +1,35 @@ +// +// Copyright (c) 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. +// + +// RenderbufferImpl_mock.h: Defines a mock of the RenderbufferImpl class. + +#ifndef LIBANGLE_RENDERER_RENDERBUFFERIMPLMOCK_H_ +#define LIBANGLE_RENDERER_RENDERBUFFERIMPLMOCK_H_ + +#include "gmock/gmock.h" + +#include "libANGLE/Image.h" +#include "libANGLE/renderer/RenderbufferImpl.h" + +namespace rx +{ + +class MockRenderbufferImpl : public RenderbufferImpl +{ + public: + virtual ~MockRenderbufferImpl() { destructor(); } + MOCK_METHOD3(setStorage, gl::Error(GLenum, size_t, size_t)); + MOCK_METHOD4(setStorageMultisample, gl::Error(size_t, GLenum, size_t, size_t)); + MOCK_METHOD1(setStorageEGLImageTarget, gl::Error(egl::Image *)); + + MOCK_METHOD2(getAttachmentRenderTarget, gl::Error(const gl::FramebufferAttachment::Target &, FramebufferAttachmentRenderTarget **)); + + MOCK_METHOD0(destructor, void()); +}; + +} + +#endif // LIBANGLE_RENDERER_RENDERBUFFERIMPLMOCK_H_ diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/Renderer.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/Renderer.cpp index fbc2ad5d1ccd..f3f7f55bb97c 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/Renderer.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/Renderer.cpp @@ -14,10 +14,7 @@ namespace rx { - -Renderer::Renderer() - : mCapsInitialized(false), - mWorkaroundsInitialized(false) +Renderer::Renderer() : mCapsInitialized(false) { } @@ -25,48 +22,41 @@ Renderer::~Renderer() { } -const gl::Caps &Renderer::getRendererCaps() const +void Renderer::ensureCapsInitialized() const { if (!mCapsInitialized) { - generateCaps(&mCaps, &mTextureCaps, &mExtensions); + generateCaps(&mCaps, &mTextureCaps, &mExtensions, &mLimitations); mCapsInitialized = true; } +} + +const gl::Caps &Renderer::getRendererCaps() const +{ + ensureCapsInitialized(); return mCaps; } const gl::TextureCapsMap &Renderer::getRendererTextureCaps() const { - if (!mCapsInitialized) - { - generateCaps(&mCaps, &mTextureCaps, &mExtensions); - mCapsInitialized = true; - } + ensureCapsInitialized(); return mTextureCaps; } const gl::Extensions &Renderer::getRendererExtensions() const { - if (!mCapsInitialized) - { - generateCaps(&mCaps, &mTextureCaps, &mExtensions); - mCapsInitialized = true; - } + ensureCapsInitialized(); return mExtensions; } -const Workarounds &Renderer::getWorkarounds() const +const gl::Limitations &Renderer::getRendererLimitations() const { - if (!mWorkaroundsInitialized) - { - mWorkarounds = generateWorkarounds(); - mWorkaroundsInitialized = true; - } + ensureCapsInitialized(); - return mWorkarounds; + return mLimitations; } } diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/Renderer.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/Renderer.h index b607fe56137f..d0da2b140c48 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/Renderer.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/Renderer.h @@ -13,10 +13,10 @@ #include "libANGLE/Caps.h" #include "libANGLE/Error.h" #include "libANGLE/Framebuffer.h" +#include "libANGLE/State.h" #include "libANGLE/Uniform.h" #include "libANGLE/angletypes.h" #include "libANGLE/renderer/ImplFactory.h" -#include "libANGLE/renderer/Workarounds.h" #include "common/mathutil.h" #include @@ -30,16 +30,11 @@ class Display; class Surface; } -namespace gl -{ -class Buffer; -struct Data; -} - namespace rx { struct TranslatedIndexData; -struct Workarounds; +struct SourceIndexData; +struct WorkaroundsD3D; class DisplayImpl; class Renderer : public ImplFactory @@ -51,11 +46,34 @@ class Renderer : public ImplFactory virtual gl::Error flush() = 0; virtual gl::Error finish() = 0; - virtual gl::Error drawArrays(const gl::Data &data, GLenum mode, - GLint first, GLsizei count, GLsizei instances) = 0; - virtual gl::Error drawElements(const gl::Data &data, GLenum mode, GLsizei count, GLenum type, - const GLvoid *indices, GLsizei instances, - const RangeUI &indexRange) = 0; + virtual gl::Error drawArrays(const gl::Data &data, GLenum mode, GLint first, GLsizei count) = 0; + virtual gl::Error drawArraysInstanced(const gl::Data &data, + GLenum mode, + GLint first, + GLsizei count, + GLsizei instanceCount) = 0; + + virtual gl::Error drawElements(const gl::Data &data, + GLenum mode, + GLsizei count, + GLenum type, + const GLvoid *indices, + const gl::IndexRange &indexRange) = 0; + virtual gl::Error drawElementsInstanced(const gl::Data &data, + GLenum mode, + GLsizei count, + GLenum type, + const GLvoid *indices, + GLsizei instances, + const gl::IndexRange &indexRange) = 0; + virtual gl::Error drawRangeElements(const gl::Data &data, + GLenum mode, + GLuint start, + GLuint end, + GLsizei count, + GLenum type, + const GLvoid *indices, + const gl::IndexRange &indexRange) = 0; // lost device //TODO(jmadill): investigate if this stuff is necessary in GL @@ -64,27 +82,39 @@ class Renderer : public ImplFactory virtual bool testDeviceLost() = 0; virtual bool testDeviceResettable() = 0; - virtual VendorID getVendorId() const = 0; virtual std::string getVendorString() const = 0; virtual std::string getRendererDescription() const = 0; + virtual void insertEventMarker(GLsizei length, const char *marker) = 0; + virtual void pushGroupMarker(GLsizei length, const char *marker) = 0; + virtual void popGroupMarker() = 0; + + virtual void syncState(const gl::State &state, const gl::State::DirtyBits &dirtyBits) = 0; + + // Disjoint timer queries + virtual GLint getGPUDisjoint() = 0; + virtual GLint64 getTimestamp() = 0; + + // Context switching + virtual void onMakeCurrent(const gl::Data &data) = 0; + // Renderer capabilities const gl::Caps &getRendererCaps() const; const gl::TextureCapsMap &getRendererTextureCaps() const; const gl::Extensions &getRendererExtensions() const; - const Workarounds &getWorkarounds() const; + const gl::Limitations &getRendererLimitations() const; private: - virtual void generateCaps(gl::Caps *outCaps, gl::TextureCapsMap* outTextureCaps, gl::Extensions *outExtensions) const = 0; - virtual Workarounds generateWorkarounds() const = 0; + void ensureCapsInitialized() const; + virtual void generateCaps(gl::Caps *outCaps, gl::TextureCapsMap* outTextureCaps, + gl::Extensions *outExtensions, + gl::Limitations *outLimitations) const = 0; mutable bool mCapsInitialized; mutable gl::Caps mCaps; mutable gl::TextureCapsMap mTextureCaps; mutable gl::Extensions mExtensions; - - mutable bool mWorkaroundsInitialized; - mutable Workarounds mWorkarounds; + mutable gl::Limitations mLimitations; }; } diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/SamplerImpl.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/SamplerImpl.h new file mode 100644 index 000000000000..85383cf8e571 --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/SamplerImpl.h @@ -0,0 +1,25 @@ +// +// 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" + +namespace rx +{ + +class SamplerImpl : public angle::NonCopyable +{ + public: + SamplerImpl() {} + virtual ~SamplerImpl() {} +}; +} + +#endif // LIBANGLE_RENDERER_SAMPLERIMPL_H_ diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/ShaderImpl.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/ShaderImpl.h index 3011bc57f809..5a466377a53a 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/ShaderImpl.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/ShaderImpl.h @@ -9,8 +9,6 @@ #ifndef LIBANGLE_RENDERER_SHADERIMPL_H_ #define LIBANGLE_RENDERER_SHADERIMPL_H_ -#include - #include "common/angleutils.h" #include "libANGLE/Shader.h" @@ -20,36 +18,21 @@ namespace rx class ShaderImpl : angle::NonCopyable { public: - ShaderImpl() { } + ShaderImpl(const gl::Shader::Data &data) : mData(data) {} virtual ~ShaderImpl() { } - virtual bool compile(gl::Compiler *compiler, const std::string &source) = 0; - virtual std::string getDebugInfo() const = 0; - - virtual const std::string &getInfoLog() const { return mInfoLog; } - virtual const std::string &getTranslatedSource() const { return mTranslatedSource; } + // Returns additional ShCompile options. + virtual int prepareSourceAndReturnOptions(std::stringstream *sourceStream, + std::string *sourcePath) = 0; + // Returns success for compiling on the driver. Returns success. + virtual bool postTranslateCompile(gl::Compiler *compiler, std::string *infoLog) = 0; - const std::vector &getVaryings() const { return mVaryings; } - const std::vector &getUniforms() const { return mUniforms; } - const std::vector &getInterfaceBlocks() const { return mInterfaceBlocks; } - const std::vector &getActiveAttributes() const { return mActiveAttributes; } - const std::vector &getActiveOutputVariables() const { return mActiveOutputVariables; } + virtual std::string getDebugInfo() const = 0; - std::vector &getVaryings() { return mVaryings; } - std::vector &getUniforms() { return mUniforms; } - std::vector &getInterfaceBlocks() { return mInterfaceBlocks; } - std::vector &getActiveAttributes() { return mActiveAttributes; } - std::vector &getActiveOutputVariables() { return mActiveOutputVariables; } + const gl::Shader::Data &getData() const { return mData; } protected: - std::string mInfoLog; - std::string mTranslatedSource; - - std::vector mVaryings; - std::vector mUniforms; - std::vector mInterfaceBlocks; - std::vector mActiveAttributes; - std::vector mActiveOutputVariables; + const gl::Shader::Data &mData; }; } diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/StreamImpl.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/StreamImpl.h new file mode 100644 index 000000000000..cf0b8169ed04 --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/StreamImpl.h @@ -0,0 +1,25 @@ +// +// Copyright (c) 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. +// + +// StreamImpl.h: Defines the abstract rx::StreamImpl class. + +#ifndef LIBANGLE_RENDERER_STREAMIMPL_H_ +#define LIBANGLE_RENDERER_STREAMIMPL_H_ + +#include "common/angleutils.h" + +namespace rx +{ + +class StreamImpl : angle::NonCopyable +{ + public: + explicit StreamImpl() {} + virtual ~StreamImpl() {} +}; +} // namespace rx + +#endif // LIBANGLE_RENDERER_STREAMIMPL_H_ diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/SurfaceImpl.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/SurfaceImpl.h index acc81e454ecc..32125d542c43 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/SurfaceImpl.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/SurfaceImpl.h @@ -11,6 +11,7 @@ #include "common/angleutils.h" #include "libANGLE/Error.h" +#include "libANGLE/Framebuffer.h" #include "libANGLE/FramebufferAttachment.h" namespace egl @@ -22,6 +23,8 @@ struct Config; namespace rx { +class FramebufferImpl; + class SurfaceImpl : public FramebufferAttachmentObjectImpl { public: @@ -29,10 +32,11 @@ class SurfaceImpl : public FramebufferAttachmentObjectImpl virtual ~SurfaceImpl(); virtual egl::Error initialize() = 0; + virtual FramebufferImpl *createDefaultFramebuffer(const gl::Framebuffer::Data &data) = 0; virtual egl::Error swap() = 0; virtual egl::Error postSubBuffer(EGLint x, EGLint y, EGLint width, EGLint height) = 0; virtual egl::Error querySurfacePointerANGLE(EGLint attribute, void **value) = 0; - virtual egl::Error bindTexImage(EGLint buffer) = 0; + virtual egl::Error bindTexImage(gl::Texture *texture, EGLint buffer) = 0; virtual egl::Error releaseTexImage(EGLint buffer) = 0; virtual void setSwapInterval(EGLint interval) = 0; @@ -41,6 +45,7 @@ class SurfaceImpl : public FramebufferAttachmentObjectImpl virtual EGLint getHeight() const = 0; virtual EGLint isPostSubBufferSupported() const = 0; + virtual EGLint getSwapBehavior() const = 0; }; } diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/TextureImpl.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/TextureImpl.h index bbc71ded8b0b..ad4ec8d830b7 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/TextureImpl.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/TextureImpl.h @@ -20,6 +20,7 @@ namespace egl { class Surface; +class Image; } namespace gl @@ -30,7 +31,7 @@ struct Offset; struct Rectangle; class Framebuffer; struct PixelUnpackState; -struct SamplerState; +struct TextureState; } namespace rx @@ -50,9 +51,9 @@ class TextureImpl : public FramebufferAttachmentObjectImpl const gl::PixelUnpackState &unpack, const uint8_t *pixels) = 0; virtual gl::Error setCompressedImage(GLenum target, size_t level, GLenum internalFormat, const gl::Extents &size, - const gl::PixelUnpackState &unpack, const uint8_t *pixels) = 0; + const gl::PixelUnpackState &unpack, size_t imageSize, const uint8_t *pixels) = 0; virtual gl::Error setCompressedSubImage(GLenum target, size_t level, const gl::Box &area, GLenum format, - const gl::PixelUnpackState &unpack, const uint8_t *pixels) = 0; + const gl::PixelUnpackState &unpack, size_t imageSize, const uint8_t *pixels) = 0; virtual gl::Error copyImage(GLenum target, size_t level, const gl::Rectangle &sourceArea, GLenum internalFormat, const gl::Framebuffer *source) = 0; @@ -61,7 +62,9 @@ class TextureImpl : public FramebufferAttachmentObjectImpl virtual gl::Error setStorage(GLenum target, size_t levels, GLenum internalFormat, const gl::Extents &size) = 0; - virtual gl::Error generateMipmaps(const gl::SamplerState &samplerState) = 0; + virtual gl::Error setEGLImageTarget(GLenum target, egl::Image *image) = 0; + + virtual gl::Error generateMipmaps(const gl::TextureState &textureState) = 0; virtual void bindTexImage(egl::Surface *surface) = 0; virtual void releaseTexImage() = 0; diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/TextureImpl_mock.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/TextureImpl_mock.h new file mode 100644 index 000000000000..3eb43f003379 --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/TextureImpl_mock.h @@ -0,0 +1,43 @@ +// +// Copyright (c) 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. +// + +// TextureImpl_mock.h: Defines a mock of the TextureImpl class. + +#ifndef LIBANGLE_RENDERER_TEXTUREIMPLMOCK_H_ +#define LIBANGLE_RENDERER_TEXTUREIMPLMOCK_H_ + +#include "gmock/gmock.h" + +#include "libANGLE/renderer/TextureImpl.h" + +namespace rx +{ + +class MockTextureImpl : public TextureImpl +{ + public: + virtual ~MockTextureImpl() { destructor(); } + MOCK_METHOD1(setUsage, void(GLenum)); + MOCK_METHOD8(setImage, gl::Error(GLenum, size_t, GLenum, const gl::Extents &, GLenum, GLenum, const gl::PixelUnpackState &, const uint8_t *)); + MOCK_METHOD7(setSubImage, gl::Error(GLenum, size_t, const gl::Box &, GLenum, GLenum, const gl::PixelUnpackState &, const uint8_t *)); + MOCK_METHOD7(setCompressedImage, gl::Error(GLenum, size_t, GLenum, const gl::Extents &, const gl::PixelUnpackState &, size_t, const uint8_t *)); + MOCK_METHOD7(setCompressedSubImage, gl::Error(GLenum, size_t, const gl::Box &, GLenum, const gl::PixelUnpackState &, size_t, const uint8_t *)); + MOCK_METHOD5(copyImage, gl::Error(GLenum, size_t, const gl::Rectangle &, GLenum, const gl::Framebuffer *)); + MOCK_METHOD5(copySubImage, gl::Error(GLenum, size_t, const gl::Offset &, const gl::Rectangle &, const gl::Framebuffer *)); + MOCK_METHOD4(setStorage, gl::Error(GLenum, size_t, GLenum, const gl::Extents &)); + MOCK_METHOD2(setEGLImageTarget, gl::Error(GLenum, egl::Image *)); + MOCK_METHOD1(generateMipmaps, gl::Error(const gl::TextureState &)); + MOCK_METHOD1(bindTexImage, void(egl::Surface *)); + MOCK_METHOD0(releaseTexImage, void(void)); + + MOCK_METHOD2(getAttachmentRenderTarget, gl::Error(const gl::FramebufferAttachment::Target &, FramebufferAttachmentRenderTarget **)); + + MOCK_METHOD0(destructor, void()); +}; + +} + +#endif // LIBANGLE_RENDERER_TEXTUREIMPLMOCK_H_ diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/TransformFeedbackImpl_mock.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/TransformFeedbackImpl_mock.h index 397ea0614d7b..c7d2fc620d46 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/TransformFeedbackImpl_mock.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/TransformFeedbackImpl_mock.h @@ -19,7 +19,7 @@ namespace rx class MockTransformFeedbackImpl : public TransformFeedbackImpl { public: - ~MockTransformFeedbackImpl() override { destructor(); } + ~MockTransformFeedbackImpl() { destructor(); } MOCK_METHOD1(begin, void(GLenum primitiveMode)); MOCK_METHOD0(end, void()); diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/VertexArrayImpl.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/VertexArrayImpl.h index 0e25f952c26d..13617c7ecb5c 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/VertexArrayImpl.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/VertexArrayImpl.h @@ -11,7 +11,7 @@ #include "common/angleutils.h" #include "libANGLE/Buffer.h" -#include "libANGLE/VertexAttribute.h" +#include "libANGLE/VertexArray.h" namespace rx { @@ -19,12 +19,11 @@ namespace rx class VertexArrayImpl : angle::NonCopyable { public: + VertexArrayImpl(const gl::VertexArray::Data &data) : mData(data) { } virtual ~VertexArrayImpl() { } - - virtual void setElementArrayBuffer(const gl::Buffer *buffer) = 0; - virtual void setAttribute(size_t idx, const gl::VertexAttribute &attr) = 0; - virtual void setAttributeDivisor(size_t idx, GLuint divisor) = 0; - virtual void enableAttribute(size_t idx, bool enabledState) = 0; + virtual void syncState(const gl::VertexArray::DirtyBits &dirtyBits) {} + protected: + const gl::VertexArray::Data &mData; }; } diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/BufferD3D.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/BufferD3D.cpp index 1af8794356d1..71399376058c 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/BufferD3D.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/BufferD3D.cpp @@ -8,8 +8,11 @@ #include "libANGLE/renderer/d3d/BufferD3D.h" +#include "common/mathutil.h" +#include "common/utilities.h" #include "libANGLE/renderer/d3d/IndexBuffer.h" #include "libANGLE/renderer/d3d/VertexBuffer.h" +#include "libANGLE/renderer/d3d/RendererD3D.h" namespace rx { @@ -19,29 +22,62 @@ unsigned int BufferD3D::mNextSerial = 1; BufferD3D::BufferD3D(BufferFactoryD3D *factory) : BufferImpl(), mFactory(factory), - mStaticVertexBuffer(nullptr), mStaticIndexBuffer(nullptr), - mUnmodifiedDataUse(0) + mStaticBufferCacheTotalSize(0), + mStaticVertexBufferOutOfDate(false), + mUnmodifiedDataUse(0), + mUsage(D3DBufferUsage::STATIC) { updateSerial(); } BufferD3D::~BufferD3D() { - SafeDelete(mStaticVertexBuffer); SafeDelete(mStaticIndexBuffer); } +void BufferD3D::emptyStaticBufferCache() +{ + mStaticVertexBuffers.clear(); + mStaticBufferCacheTotalSize = 0; +} + void BufferD3D::updateSerial() { mSerial = mNextSerial++; } +void BufferD3D::updateD3DBufferUsage(GLenum usage) +{ + switch (usage) + { + case GL_STATIC_DRAW: + case GL_STATIC_READ: + case GL_STATIC_COPY: + mUsage = D3DBufferUsage::STATIC; + initializeStaticData(); + break; + + case GL_STREAM_DRAW: + case GL_STREAM_READ: + case GL_STREAM_COPY: + case GL_DYNAMIC_READ: + case GL_DYNAMIC_COPY: + case GL_DYNAMIC_DRAW: + mUsage = D3DBufferUsage::DYNAMIC; + break; + default: + UNREACHABLE(); + } +} + void BufferD3D::initializeStaticData() { - if (!mStaticVertexBuffer) + if (mStaticVertexBuffers.empty()) { - mStaticVertexBuffer = new StaticVertexBufferInterface(mFactory); + auto newStaticBuffer = new StaticVertexBufferInterface(mFactory); + mStaticVertexBuffers.push_back( + std::unique_ptr(newStaticBuffer)); } if (!mStaticIndexBuffer) { @@ -49,14 +85,73 @@ void BufferD3D::initializeStaticData() } } +StaticIndexBufferInterface *BufferD3D::getStaticIndexBuffer() +{ + return mStaticIndexBuffer; +} + +StaticVertexBufferInterface *BufferD3D::getStaticVertexBuffer(const gl::VertexAttribute &attribute) +{ + 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)) + { + return staticBuffer.get(); + } + + currentTotalSize += staticBuffer->getBufferSize(); + } + + // Cache size limiting: Clean-up threshold is four times the base buffer size, with a minimum. + ASSERT(IsUnsignedMultiplicationSafe(getSize(), static_cast(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. + auto newStaticBuffer = new StaticVertexBufferInterface(mFactory); + newStaticBuffer->setAttribute(attribute); + mStaticVertexBuffers.push_back(std::unique_ptr(newStaticBuffer)); + return newStaticBuffer; +} + void BufferD3D::invalidateStaticData() { - if ((mStaticVertexBuffer && mStaticVertexBuffer->getBufferSize() != 0) || (mStaticIndexBuffer && mStaticIndexBuffer->getBufferSize() != 0)) + emptyStaticBufferCache(); + + if (mStaticIndexBuffer && mStaticIndexBuffer->getBufferSize() != 0) { - SafeDelete(mStaticVertexBuffer); SafeDelete(mStaticIndexBuffer); + } - // Re-init static data to track that we're in a static buffer + // 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(); } @@ -66,15 +161,32 @@ void BufferD3D::invalidateStaticData() // Creates static buffers if sufficient used data has been left unmodified void BufferD3D::promoteStaticUsage(int dataSize) { - if (!mStaticVertexBuffer && !mStaticIndexBuffer) + if (mUsage == D3DBufferUsage::DYNAMIC) { mUnmodifiedDataUse += dataSize; if (mUnmodifiedDataUse > 3 * getSize()) { - initializeStaticData(); + updateD3DBufferUsage(GL_STATIC_DRAW); } } } -} \ No newline at end of file +gl::Error BufferD3D::getIndexRange(GLenum type, + size_t offset, + size_t count, + bool primitiveRestartEnabled, + gl::IndexRange *outRange) +{ + const uint8_t *data = nullptr; + gl::Error error = getData(&data); + if (error.isError()) + { + return error; + } + + *outRange = gl::ComputeIndexRange(type, data + offset, count, primitiveRestartEnabled); + return gl::Error(GL_NO_ERROR); +} + +} // namespace rx diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/BufferD3D.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/BufferD3D.h index a46398f91178..3c43c0164fd4 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/BufferD3D.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/BufferD3D.h @@ -9,10 +9,11 @@ #ifndef LIBANGLE_RENDERER_D3D_BUFFERD3D_H_ #define LIBANGLE_RENDERER_D3D_BUFFERD3D_H_ -#include "libANGLE/renderer/BufferImpl.h" #include "libANGLE/angletypes.h" +#include "libANGLE/renderer/BufferImpl.h" #include +#include namespace rx { @@ -20,6 +21,12 @@ class BufferFactoryD3D; class StaticIndexBufferInterface; class StaticVertexBufferInterface; +enum class D3DBufferUsage +{ + STATIC, + DYNAMIC, +}; + class BufferD3D : public BufferImpl { public: @@ -30,25 +37,41 @@ class BufferD3D : public BufferImpl virtual size_t getSize() const = 0; virtual bool supportsDirectBinding() const = 0; - virtual void markTransformFeedbackUsage() = 0; + virtual gl::Error markTransformFeedbackUsage() = 0; + virtual gl::Error getData(const uint8_t **outData) = 0; + + StaticVertexBufferInterface *getStaticVertexBuffer(const gl::VertexAttribute &attribute); + StaticIndexBufferInterface *getStaticIndexBuffer(); - StaticVertexBufferInterface *getStaticVertexBuffer() { return mStaticVertexBuffer; } - StaticIndexBufferInterface *getStaticIndexBuffer() { return mStaticIndexBuffer; } + virtual void initializeStaticData(); + virtual void invalidateStaticData(); - void initializeStaticData(); - void invalidateStaticData(); void promoteStaticUsage(int dataSize); + gl::Error getIndexRange(GLenum 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(GLenum usage); + void emptyStaticBufferCache(); BufferFactoryD3D *mFactory; unsigned int mSerial; static unsigned int mNextSerial; - StaticVertexBufferInterface *mStaticVertexBuffer; + std::vector> mStaticVertexBuffers; StaticIndexBufferInterface *mStaticIndexBuffer; + unsigned int mStaticBufferCacheTotalSize; + unsigned int mStaticVertexBufferOutOfDate; unsigned int mUnmodifiedDataUse; + D3DBufferUsage mUsage; }; } diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/CompilerD3D.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/CompilerD3D.cpp index bc720a831531..6f8d1717cd36 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/CompilerD3D.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/CompilerD3D.cpp @@ -1,122 +1,20 @@ // -// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved. +// 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.cpp: Implementation of the rx::CompilerD3D class. +// CompilerD3D: +// Implementation of the D3D compiler methods. +// #include "libANGLE/renderer/d3d/CompilerD3D.h" -#include "libANGLE/Caps.h" -#include "libANGLE/Data.h" - -#include "common/debug.h" - namespace rx { -// Global count of active shader compiler handles. Needed to know when to call ShInitialize and ShFinalize. -static size_t activeCompilerHandles = 0; - -CompilerD3D::CompilerD3D(const gl::Data &data, ShShaderOutput outputType) - : mSpec(data.clientVersion > 2 ? SH_GLES3_SPEC : SH_GLES2_SPEC), - mOutputType(outputType), - mResources(), - mFragmentCompiler(NULL), - mVertexCompiler(NULL) -{ - ASSERT(data.clientVersion == 2 || data.clientVersion == 3); - - const gl::Caps &caps = *data.caps; - const gl::Extensions &extensions = *data.extensions; - - ShInitBuiltInResources(&mResources); - mResources.MaxVertexAttribs = caps.maxVertexAttributes; - mResources.MaxVertexUniformVectors = caps.maxVertexUniformVectors; - mResources.MaxVaryingVectors = caps.maxVaryingVectors; - mResources.MaxVertexTextureImageUnits = caps.maxVertexTextureImageUnits; - mResources.MaxCombinedTextureImageUnits = caps.maxCombinedTextureImageUnits; - mResources.MaxTextureImageUnits = caps.maxTextureImageUnits; - mResources.MaxFragmentUniformVectors = caps.maxFragmentUniformVectors; - mResources.MaxDrawBuffers = caps.maxDrawBuffers; - mResources.OES_standard_derivatives = extensions.standardDerivatives; - mResources.EXT_draw_buffers = extensions.drawBuffers; - mResources.EXT_shader_texture_lod = 1; - // resources.OES_EGL_image_external = mRenderer->getShareHandleSupport() ? 1 : 0; // TODO: commented out until the extension is actually supported. - mResources.FragmentPrecisionHigh = 1; // Shader Model 2+ always supports FP24 (s16e7) which corresponds to highp - mResources.EXT_frag_depth = 1; // Shader Model 2+ always supports explicit depth output - - // GLSL ES 3.0 constants - mResources.MaxVertexOutputVectors = caps.maxVertexOutputComponents / 4; - mResources.MaxFragmentInputVectors = caps.maxFragmentInputComponents / 4; - mResources.MinProgramTexelOffset = caps.minProgramTexelOffset; - mResources.MaxProgramTexelOffset = caps.maxProgramTexelOffset; -} - -CompilerD3D::~CompilerD3D() -{ - release(); -} - -gl::Error CompilerD3D::release() -{ - if (mFragmentCompiler) - { - ShDestruct(mFragmentCompiler); - mFragmentCompiler = NULL; - - ASSERT(activeCompilerHandles > 0); - activeCompilerHandles--; - } - - if (mVertexCompiler) - { - ShDestruct(mVertexCompiler); - mVertexCompiler = NULL; - - ASSERT(activeCompilerHandles > 0); - activeCompilerHandles--; - } - - if (activeCompilerHandles == 0) - { - ShFinalize(); - } - - return gl::Error(GL_NO_ERROR); -} - -ShHandle CompilerD3D::getCompilerHandle(GLenum type) +CompilerD3D::CompilerD3D(ShShaderOutput translatorOutputType) + : mTranslatorOutputType(translatorOutputType) { - ShHandle *compiler = NULL; - switch (type) - { - case GL_VERTEX_SHADER: - compiler = &mVertexCompiler; - break; - - case GL_FRAGMENT_SHADER: - compiler = &mFragmentCompiler; - break; - - default: - UNREACHABLE(); - return NULL; - } - - if (!(*compiler)) - { - if (activeCompilerHandles == 0) - { - ShInitialize(); - } - - *compiler = ShConstructCompiler(type, mSpec, mOutputType, &mResources); - activeCompilerHandles++; - } - - return *compiler; } -} +} // namespace rx diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/CompilerD3D.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/CompilerD3D.h index 40709192da8a..8f4334963d1a 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/CompilerD3D.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/CompilerD3D.h @@ -10,14 +10,7 @@ #define LIBANGLE_RENDERER_COMPILERD3D_H_ #include "libANGLE/renderer/CompilerImpl.h" -#include "libANGLE/Caps.h" - -#include "GLSLANG/ShaderLang.h" - -namespace gl -{ -struct Data; -} +#include "libANGLE/renderer/d3d/RendererD3D.h" namespace rx { @@ -25,20 +18,14 @@ namespace rx class CompilerD3D : public CompilerImpl { public: - CompilerD3D(const gl::Data &data, ShShaderOutput outputType); - virtual ~CompilerD3D(); - - gl::Error release() override; + CompilerD3D(ShShaderOutput translatorOutputType); + ~CompilerD3D() override {} - ShHandle getCompilerHandle(GLenum type); + gl::Error release() override { return gl::Error(GL_NO_ERROR); } + ShShaderOutput getTranslatorOutputType() const override { return mTranslatorOutputType; } private: - ShShaderSpec mSpec; - ShShaderOutput mOutputType; - ShBuiltInResources mResources; - - ShHandle mFragmentCompiler; - ShHandle mVertexCompiler; + ShShaderOutput mTranslatorOutputType; }; } diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/DeviceD3D.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/DeviceD3D.cpp index 938703ac151e..f40e6e6cab58 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/DeviceD3D.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/DeviceD3D.cpp @@ -17,33 +17,81 @@ namespace rx { -DeviceD3D::DeviceD3D(rx::RendererD3D *renderer) - : mRenderer(renderer) +DeviceD3D::DeviceD3D() + : mDevice(0), mDeviceType(0), mDeviceExternallySourced(false), mIsInitialized(false) { } -egl::Error DeviceD3D::getDevice(EGLAttrib *value) +DeviceD3D::~DeviceD3D() { - *value = reinterpret_cast(mRenderer->getD3DDevice()); - if (*value == 0) +#if defined(ANGLE_ENABLE_D3D11) + if (mDeviceType == EGL_D3D11_DEVICE_ANGLE) { + // DeviceD3D holds a ref to an externally-sourced D3D11 device. We must release it. + ID3D11Device *device = reinterpret_cast(mDevice); + device->Release(); + } +#endif +} + +egl::Error DeviceD3D::getDevice(void **outValue) +{ + if (!mIsInitialized) + { + *outValue = nullptr; return egl::Error(EGL_BAD_DEVICE_EXT); } + + *outValue = mDevice; return egl::Error(EGL_SUCCESS); } -EGLint DeviceD3D::getType() +egl::Error DeviceD3D::initialize(void *device, + EGLint deviceType, + EGLBoolean deviceExternallySourced) { - switch (mRenderer->getRendererClass()) + ASSERT(!mIsInitialized); + if (mIsInitialized) { - case RENDERER_D3D11: - return EGL_D3D11_DEVICE_ANGLE; - case RENDERER_D3D9: - return EGL_D3D9_DEVICE_ANGLE; - default: - UNREACHABLE(); - return EGL_NONE; + return egl::Error(EGL_BAD_DEVICE_EXT); } + + mDevice = device; + mDeviceType = deviceType; + mDeviceExternallySourced = !!deviceExternallySourced; + +#if defined(ANGLE_ENABLE_D3D11) + if (mDeviceType == EGL_D3D11_DEVICE_ANGLE) + { + // Validate the device + IUnknown *iunknown = reinterpret_cast(device); + + ID3D11Device *d3dDevice = nullptr; + HRESULT hr = + iunknown->QueryInterface(__uuidof(ID3D11Device), reinterpret_cast(&d3dDevice)); + if (FAILED(hr)) + { + return egl::Error(EGL_BAD_ATTRIBUTE, "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. + } + else +#endif + { + ASSERT(!mDeviceExternallySourced); + } + + mIsInitialized = true; + + return egl::Error(EGL_SUCCESS); +} + +EGLint DeviceD3D::getType() +{ + return mDeviceType; } void DeviceD3D::generateExtensions(egl::DeviceExtensions *outExtensions) const diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/DeviceD3D.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/DeviceD3D.h index 5f9854634525..1dd997970850 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/DeviceD3D.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/DeviceD3D.h @@ -18,14 +18,20 @@ namespace rx class DeviceD3D : public DeviceImpl { public: - DeviceD3D(RendererD3D *renderer); + DeviceD3D(); + ~DeviceD3D() override; - egl::Error getDevice(EGLAttrib *value) override; + egl::Error initialize(void *device, EGLint deviceType, EGLBoolean external); + egl::Error getDevice(void **outValue) override; EGLint getType() override; void generateExtensions(egl::DeviceExtensions *outExtensions) const override; + bool deviceExternallySourced() override { return mDeviceExternallySourced; } private: - RendererD3D *mRenderer; + void *mDevice; + EGLint mDeviceType; + bool mDeviceExternallySourced; + bool mIsInitialized; }; } diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/DisplayD3D.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/DisplayD3D.cpp index d863bcfc6d7c..3b9debe8bcbc 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/DisplayD3D.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/DisplayD3D.cpp @@ -13,6 +13,7 @@ #include "libANGLE/Display.h" #include "libANGLE/Surface.h" #include "libANGLE/histogram_macros.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" @@ -34,7 +35,7 @@ #if !defined(ANGLE_DEFAULT_D3D11) // Enables use of the Direct3D 11 API for a default display, when available -# define ANGLE_DEFAULT_D3D11 0 +# define ANGLE_DEFAULT_D3D11 1 #endif namespace rx @@ -54,10 +55,13 @@ egl::Error CreateRendererD3D(egl::Display *display, RendererD3D **outRenderer) std::vector rendererCreationFunctions; - const auto &attribMap = display->getAttributeMap(); - EGLNativeDisplayType nativeDisplay = display->getNativeDisplayId(); + if (display->getPlatform() == EGL_PLATFORM_ANGLE_ANGLE) + { + const auto &attribMap = display->getAttributeMap(); + EGLNativeDisplayType nativeDisplay = display->getNativeDisplayId(); - EGLint requestedDisplayType = attribMap.get(EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE); + EGLint requestedDisplayType = static_cast( + attribMap.get(EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE)); # if defined(ANGLE_ENABLE_D3D11) if (nativeDisplay == EGL_D3D11_ELSE_D3D9_DISPLAY_ANGLE || @@ -76,27 +80,41 @@ egl::Error CreateRendererD3D(egl::Display *display, RendererD3D **outRenderer) } # endif - if (nativeDisplay != EGL_D3D11_ELSE_D3D9_DISPLAY_ANGLE && - nativeDisplay != EGL_D3D11_ONLY_DISPLAY_ANGLE && - requestedDisplayType == EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE) - { + 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(CreateTypedRendererD3D); + rendererCreationFunctions.push_back(CreateTypedRendererD3D); # endif # if defined(ANGLE_ENABLE_D3D9) - rendererCreationFunctions.push_back(CreateTypedRendererD3D); + rendererCreationFunctions.push_back(CreateTypedRendererD3D); # endif # else # if defined(ANGLE_ENABLE_D3D9) - rendererCreationFunctions.push_back(CreateTypedRendererD3D); + rendererCreationFunctions.push_back(CreateTypedRendererD3D); # endif # if defined(ANGLE_ENABLE_D3D11) - rendererCreationFunctions.push_back(CreateTypedRendererD3D); + rendererCreationFunctions.push_back(CreateTypedRendererD3D); # 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(CreateTypedRendererD3D); + } +#endif + } + else + { + UNIMPLEMENTED(); } egl::Error result(EGL_NOT_INITIALIZED, "No available renderers."); @@ -140,49 +158,23 @@ egl::Error CreateRendererD3D(egl::Display *display, RendererD3D **outRenderer) return result; } -#if !defined(ANGLE_ENABLE_WINDOWS_STORE) -namespace +DisplayD3D::DisplayD3D() : mRenderer(nullptr) { - -LRESULT CALLBACK IntermediateWindowProc(HWND window, UINT message, WPARAM wParam, LPARAM lParam) -{ - switch (message) - { - case WM_ERASEBKGND: - // Prevent windows from erasing the background. - return 1; - case WM_PAINT: - // Do not paint anything. - PAINTSTRUCT paint; - if (BeginPaint(window, &paint)) - { - EndPaint(window, &paint); - } - return 0; - } - - return DefWindowProc(window, message, wParam, lParam); -} - } -#endif -DisplayD3D::DisplayD3D() - : mDisplay(nullptr), - mRenderer(nullptr), - mChildWindowClass(0), - mDevice(nullptr) -{ -} -egl::Error DisplayD3D::createWindowSurface(const egl::Config *configuration, EGLNativeWindowType window, - const egl::AttributeMap &attribs, SurfaceImpl **outSurface) +SurfaceImpl *DisplayD3D::createWindowSurface(const egl::Config *configuration, + EGLNativeWindowType window, + const egl::AttributeMap &attribs) { ASSERT(mRenderer != nullptr); - EGLint width = attribs.get(EGL_WIDTH, 0); - EGLint height = attribs.get(EGL_HEIGHT, 0); - EGLint fixedSize = attribs.get(EGL_FIXED_SIZE_ANGLE, EGL_FALSE); + EGLint width = static_cast(attribs.get(EGL_WIDTH, 0)); + EGLint height = static_cast(attribs.get(EGL_HEIGHT, 0)); + EGLint fixedSize = static_cast(attribs.get(EGL_FIXED_SIZE_ANGLE, EGL_FALSE)); + EGLint orientation = static_cast(attribs.get(EGL_SURFACE_ORIENTATION_ANGLE, 0)); + EGLint directComposition = + static_cast(attribs.get(EGL_DIRECT_COMPOSITION_ANGLE, EGL_FALSE)); if (!fixedSize) { @@ -190,88 +182,66 @@ egl::Error DisplayD3D::createWindowSurface(const egl::Config *configuration, EGL height = -1; } - SurfaceD3D *surface = SurfaceD3D::createFromWindow(mRenderer, mDisplay, configuration, window, fixedSize, - width, height); - egl::Error error = surface->initialize(); - if (error.isError()) - { - SafeDelete(surface); - return error; - } - - *outSurface = surface; - return egl::Error(EGL_SUCCESS); + return SurfaceD3D::createFromWindow(mRenderer, mDisplay, configuration, window, fixedSize, + directComposition, width, height, orientation); } -egl::Error DisplayD3D::createPbufferSurface(const egl::Config *configuration, const egl::AttributeMap &attribs, - SurfaceImpl **outSurface) +SurfaceImpl *DisplayD3D::createPbufferSurface(const egl::Config *configuration, + const egl::AttributeMap &attribs) { ASSERT(mRenderer != nullptr); - EGLint width = attribs.get(EGL_WIDTH, 0); - EGLint height = attribs.get(EGL_HEIGHT, 0); - - SurfaceD3D *surface = SurfaceD3D::createOffscreen(mRenderer, mDisplay, configuration, NULL, width, height); - egl::Error error = surface->initialize(); - if (error.isError()) - { - SafeDelete(surface); - return error; - } + EGLint width = static_cast(attribs.get(EGL_WIDTH, 0)); + EGLint height = static_cast(attribs.get(EGL_HEIGHT, 0)); - *outSurface = surface; - return egl::Error(EGL_SUCCESS); + return SurfaceD3D::createOffscreen(mRenderer, mDisplay, configuration, nullptr, width, height); } -egl::Error DisplayD3D::createPbufferFromClientBuffer(const egl::Config *configuration, EGLClientBuffer shareHandle, - const egl::AttributeMap &attribs, SurfaceImpl **outSurface) +SurfaceImpl *DisplayD3D::createPbufferFromClientBuffer(const egl::Config *configuration, + EGLClientBuffer shareHandle, + const egl::AttributeMap &attribs) { ASSERT(mRenderer != nullptr); - EGLint width = attribs.get(EGL_WIDTH, 0); - EGLint height = attribs.get(EGL_HEIGHT, 0); - - SurfaceD3D *surface = SurfaceD3D::createOffscreen(mRenderer, mDisplay, configuration, shareHandle, - width, height); - egl::Error error = surface->initialize(); - if (error.isError()) - { - SafeDelete(surface); - return error; - } + EGLint width = static_cast(attribs.get(EGL_WIDTH, 0)); + EGLint height = static_cast(attribs.get(EGL_HEIGHT, 0)); - *outSurface = surface; - return egl::Error(EGL_SUCCESS); + return SurfaceD3D::createOffscreen( + mRenderer, mDisplay, configuration, shareHandle, width, height); } -egl::Error DisplayD3D::createPixmapSurface(const egl::Config *configuration, NativePixmapType nativePixmap, - const egl::AttributeMap &attribs, SurfaceImpl **outSurface) +SurfaceImpl *DisplayD3D::createPixmapSurface(const egl::Config *configuration, + NativePixmapType nativePixmap, + const egl::AttributeMap &attribs) { - ASSERT(mRenderer != nullptr); - UNIMPLEMENTED(); - *outSurface = nullptr; - return egl::Error(EGL_BAD_DISPLAY); + return nullptr; +} + +ImageImpl *DisplayD3D::createImage(EGLenum target, + egl::ImageSibling *buffer, + const egl::AttributeMap &attribs) +{ + return new EGLImageD3D(mRenderer, target, buffer, attribs); } egl::Error DisplayD3D::getDevice(DeviceImpl **device) { - *device = reinterpret_cast(mDevice); - ASSERT(*device != nullptr); - return egl::Error(EGL_SUCCESS); + return mRenderer->getEGLDevice(device); } -egl::Error DisplayD3D::createContext(const egl::Config *config, const gl::Context *shareContext, const egl::AttributeMap &attribs, - gl::Context **outContext) +gl::Context *DisplayD3D::createContext(const egl::Config *config, + const gl::Context *shareContext, + const egl::AttributeMap &attribs) { ASSERT(mRenderer != nullptr); + return new gl::Context(config, shareContext, mRenderer, attribs); +} - EGLint clientVersion = attribs.get(EGL_CONTEXT_CLIENT_VERSION, 1); - bool notifyResets = (attribs.get(EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT, EGL_NO_RESET_NOTIFICATION_EXT) == EGL_LOSE_CONTEXT_ON_RESET_EXT); - bool robustAccess = (attribs.get(EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT, EGL_FALSE) == EGL_TRUE); - - *outContext = new gl::Context(config, clientVersion, shareContext, mRenderer, notifyResets, robustAccess); - return egl::Error(EGL_SUCCESS); +StreamImpl *DisplayD3D::createStream(const egl::AttributeMap &attribs) +{ + ASSERT(mRenderer != nullptr); + return mRenderer->createStream(attribs); } egl::Error DisplayD3D::makeCurrent(egl::Surface *drawSurface, egl::Surface *readSurface, gl::Context *context) @@ -289,49 +259,12 @@ egl::Error DisplayD3D::initialize(egl::Display *display) return error; } - ASSERT(mDevice == nullptr); - mDevice = new DeviceD3D(mRenderer); - -#if !defined(ANGLE_ENABLE_WINDOWS_STORE) - // Work around compile error from not defining "UNICODE" while Chromium does - const LPSTR idcArrow = MAKEINTRESOURCEA(32512); - - std::string className = FormatString("ANGLE DisplayD3D 0x%0.8p Child Window Class", mDisplay); - - WNDCLASSA childWindowClassDesc = { 0 }; - childWindowClassDesc.style = CS_OWNDC; - childWindowClassDesc.lpfnWndProc = IntermediateWindowProc; - childWindowClassDesc.cbClsExtra = 0; - childWindowClassDesc.cbWndExtra = 0; - childWindowClassDesc.hInstance = GetModuleHandle(nullptr); - childWindowClassDesc.hIcon = nullptr; - childWindowClassDesc.hCursor = LoadCursorA(nullptr, idcArrow); - childWindowClassDesc.hbrBackground = 0; - childWindowClassDesc.lpszMenuName = nullptr; - childWindowClassDesc.lpszClassName = className.c_str(); - - mChildWindowClass = RegisterClassA(&childWindowClassDesc); - if (!mChildWindowClass) - { - return egl::Error(EGL_NOT_INITIALIZED, "Failed to register child window class."); - } -#endif - return egl::Error(EGL_SUCCESS); } void DisplayD3D::terminate() { - SafeDelete(mDevice); SafeDelete(mRenderer); - -#if !defined(ANGLE_ENABLE_WINDOWS_STORE) - if (mChildWindowClass != 0) - { - UnregisterClassA(reinterpret_cast(mChildWindowClass), NULL); - mChildWindowClass = 0; - } -#endif } egl::ConfigSet DisplayD3D::generateConfigs() const @@ -392,26 +325,7 @@ bool DisplayD3D::isValidNativeWindow(EGLNativeWindowType window) const void DisplayD3D::generateExtensions(egl::DisplayExtensions *outExtensions) const { - outExtensions->createContextRobustness = true; - - // ANGLE-specific extensions - if (mRenderer->getShareHandleSupport()) - { - outExtensions->d3dShareHandleClientBuffer = true; - outExtensions->surfaceD3DTexture2DShareHandle = true; - } - - outExtensions->querySurfacePointer = true; - outExtensions->windowFixedSize = true; - - if (mRenderer->getPostSubBufferSupport()) - { - outExtensions->postSubBuffer = true; - } - - outExtensions->createContext = true; - - outExtensions->deviceQuery = true; + mRenderer->generateDisplayExtensions(outExtensions); } std::string DisplayD3D::getVendorString() const @@ -433,9 +347,17 @@ void DisplayD3D::generateCaps(egl::Caps *outCaps) const outCaps->textureNPOT = mRenderer->getRendererExtensions().textureNPOT; } -ATOM DisplayD3D::getChildWindowClass() const +egl::Error DisplayD3D::waitClient() const { - return mChildWindowClass; + // Unimplemented as it is a noop on D3D + return egl::Error(EGL_SUCCESS); } +egl::Error DisplayD3D::waitNative(EGLint engine, + egl::Surface *drawSurface, + egl::Surface *readSurface) const +{ + // Unimplemented as it is a noop on D3D + return egl::Error(EGL_SUCCESS); +} } diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/DisplayD3D.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/DisplayD3D.h index 41b2b55fa15b..c54eac58b070 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/DisplayD3D.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/DisplayD3D.h @@ -24,17 +24,28 @@ class DisplayD3D : public DisplayImpl egl::Error initialize(egl::Display *display) override; virtual void terminate() override; - egl::Error createWindowSurface(const egl::Config *configuration, EGLNativeWindowType window, const egl::AttributeMap &attribs, - SurfaceImpl **outSurface) override; - egl::Error createPbufferSurface(const egl::Config *configuration, const egl::AttributeMap &attribs, - SurfaceImpl **outSurface) override; - egl::Error createPbufferFromClientBuffer(const egl::Config *configuration, EGLClientBuffer shareHandle, - const egl::AttributeMap &attribs, SurfaceImpl **outSurface) override; - egl::Error createPixmapSurface(const egl::Config *configuration, NativePixmapType nativePixmap, - const egl::AttributeMap &attribs, SurfaceImpl **outSurface) override; - - egl::Error createContext(const egl::Config *config, const gl::Context *shareContext, const egl::AttributeMap &attribs, - gl::Context **outContext) override; + // Surface creation + SurfaceImpl *createWindowSurface(const egl::Config *configuration, + EGLNativeWindowType window, + const egl::AttributeMap &attribs) override; + SurfaceImpl *createPbufferSurface(const egl::Config *configuration, + const egl::AttributeMap &attribs) override; + SurfaceImpl *createPbufferFromClientBuffer(const egl::Config *configuration, + EGLClientBuffer shareHandle, + const egl::AttributeMap &attribs) override; + SurfaceImpl *createPixmapSurface(const egl::Config *configuration, + NativePixmapType nativePixmap, + const egl::AttributeMap &attribs) override; + + ImageImpl *createImage(EGLenum target, + egl::ImageSibling *buffer, + const egl::AttributeMap &attribs) override; + + gl::Context *createContext(const egl::Config *config, + const gl::Context *shareContext, + const egl::AttributeMap &attribs) override; + + StreamImpl *createStream(const egl::AttributeMap &attribs) override; egl::Error makeCurrent(egl::Surface *drawSurface, egl::Surface *readSurface, gl::Context *context) override; @@ -50,7 +61,10 @@ class DisplayD3D : public DisplayImpl std::string getVendorString() const override; - ATOM getChildWindowClass() const; + egl::Error waitClient() const override; + egl::Error waitNative(EGLint engine, + egl::Surface *drawSurface, + egl::Surface *readSurface) const override; private: void generateExtensions(egl::DisplayExtensions *outExtensions) const override; @@ -59,9 +73,6 @@ class DisplayD3D : public DisplayImpl egl::Display *mDisplay; rx::RendererD3D *mRenderer; - ATOM mChildWindowClass; - - DeviceImpl *mDevice; }; } diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/DynamicHLSL.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/DynamicHLSL.cpp index 3f67c2e005da..218d279181b5 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/DynamicHLSL.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/DynamicHLSL.cpp @@ -10,14 +10,13 @@ #include "common/utilities.h" #include "compiler/translator/blocklayoutHLSL.h" -#include "libANGLE/renderer/d3d/ShaderD3D.h" -#include "libANGLE/renderer/d3d/RendererD3D.h" #include "libANGLE/Program.h" #include "libANGLE/Shader.h" #include "libANGLE/formatutils.h" - -// For use with ArrayString, see angleutils.h -static_assert(GL_INVALID_INDEX == UINT_MAX, "GL_INVALID_INDEX must be equal to the max unsigned int."); +#include "libANGLE/renderer/d3d/ProgramD3D.h" +#include "libANGLE/renderer/d3d/RendererD3D.h" +#include "libANGLE/renderer/d3d/ShaderD3D.h" +#include "libANGLE/renderer/d3d/VaryingPacking.h" using namespace gl; @@ -31,12 +30,17 @@ std::string 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"; + 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"; } } @@ -49,16 +53,27 @@ std::string 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"; + 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"; } } @@ -69,11 +84,13 @@ std::string HLSLTypeString(GLenum type) return HLSLMatrixTypeString(type); } - return HLSLComponentTypeString(gl::VariableComponentType(type), gl::VariableComponentCount(type)); + return HLSLComponentTypeString(gl::VariableComponentType(type), + gl::VariableComponentCount(type)); } -const PixelShaderOutputVariable *FindOutputAtLocation(const std::vector &outputVariables, - unsigned int location) +const PixelShaderOutputVariable *FindOutputAtLocation( + const std::vector &outputVariables, + unsigned int location) { for (size_t variableIndex = 0; variableIndex < outputVariables.size(); ++variableIndex) { @@ -83,314 +100,102 @@ const PixelShaderOutputVariable *FindOutputAtLocation(const std::vectorisStruct()) - { - registers = HLSLVariableRegisterCount(*varying, true) * varying->elementCount(); - elements = 4; - } - else + static_assert(GL_INVALID_INDEX == UINT_MAX, + "GL_INVALID_INDEX must be equal to the max unsigned int."); + if (i == UINT_MAX) { - GLenum transposedType = TransposeMatrixType(varying->type); - registers = VariableRowCount(transposedType) * varying->elementCount(); - elements = VariableColumnCount(transposedType); - } - - if (elements >= 2 && elements <= 4) - { - for (int r = 0; r <= maxVaryingVectors - registers; r++) - { - bool available = true; - - for (int y = 0; y < registers && available; y++) - { - for (int x = 0; x < elements && available; x++) - { - if (packing[r + y][x]) - { - available = false; - } - } - } - - if (available) - { - varying->registerIndex = r; - varying->columnIndex = 0; - - for (int y = 0; y < registers; y++) - { - for (int x = 0; x < elements; x++) - { - packing[r + y][x] = &*varying; - } - } - - return true; - } - } - - if (elements == 2) - { - for (int r = maxVaryingVectors - registers; r >= 0; r--) - { - bool available = true; - - for (int y = 0; y < registers && available; y++) - { - for (int x = 2; x < 4 && available; x++) - { - if (packing[r + y][x]) - { - available = false; - } - } - } - - if (available) - { - varying->registerIndex = r; - varying->columnIndex = 2; - - for (int y = 0; y < registers; y++) - { - for (int x = 2; x < 4; x++) - { - packing[r + y][x] = &*varying; - } - } - - return true; - } - } - } + return; } - else if (elements == 1) - { - int space[4] = { 0 }; - for (int y = 0; y < maxVaryingVectors; y++) - { - for (int x = 0; x < 4; x++) - { - space[x] += packing[y][x] ? 0 : 1; - } - } - - int column = 0; - - for (int x = 0; x < 4; x++) - { - if (space[x] >= registers && (space[column] < registers || space[x] < space[column])) - { - column = x; - } - } - - if (space[column] >= registers) - { - for (int r = 0; r < maxVaryingVectors; r++) - { - if (!packing[r][column]) - { - varying->registerIndex = r; - varying->columnIndex = column; + strstr << "["; + strstr << i; + strstr << "]"; +} - for (int y = r; y < r + registers; y++) - { - packing[y][column] = &*varying; - } +const std::string VERTEX_ATTRIBUTE_STUB_STRING = "@@ VERTEX ATTRIBUTES @@"; +const std::string PIXEL_OUTPUT_STUB_STRING = "@@ PIXEL OUTPUT @@"; +} // anonymous namespace - break; - } - } +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"); +} - return true; - } - } - else UNREACHABLE(); +// DynamicHLSL implementation - return false; +DynamicHLSL::DynamicHLSL(RendererD3D *const renderer) : mRenderer(renderer) +{ } -// Packs varyings into generic varying registers, using the algorithm from [OpenGL ES Shading Language 1.00 rev. 17] appendix A section 7 page 111 -// Returns the number of used varying registers, or -1 if unsuccesful -int DynamicHLSL::packVaryings(InfoLog &infoLog, VaryingPacking packing, ShaderD3D *fragmentShader, - ShaderD3D *vertexShader, const std::vector &transformFeedbackVaryings) +void DynamicHLSL::generateVaryingHLSL(const VaryingPacking &varyingPacking, + std::stringstream &hlslStream) const { - // TODO (geofflang): Use context's caps - const int maxVaryingVectors = mRenderer->getRendererCaps().maxVaryingVectors; - - vertexShader->resetVaryingsRegisterAssignment(); - fragmentShader->resetVaryingsRegisterAssignment(); - - std::set packedVaryings; + std::string varyingSemantic = + GetVaryingSemantic(mRenderer->getMajorShaderModel(), varyingPacking.usesPointSize()); - std::vector &fragmentVaryings = fragmentShader->getVaryings(); - std::vector &vertexVaryings = vertexShader->getVaryings(); - for (unsigned int varyingIndex = 0; varyingIndex < fragmentVaryings.size(); varyingIndex++) + for (const PackedVaryingRegister ®isterInfo : varyingPacking.getRegisterList()) { - PackedVarying *varying = &fragmentVaryings[varyingIndex]; - - // Do not assign registers to built-in or unreferenced varyings - if (varying->isBuiltIn() || !varying->staticUse) - { - continue; - } - - if (packVarying(varying, maxVaryingVectors, packing)) - { - packedVaryings.insert(varying->name); - } - else - { - infoLog.append("Could not pack varying %s", varying->name.c_str()); - return -1; - } - } + const auto &varying = *registerInfo.packedVarying->varying; + ASSERT(!varying.isStruct()); - for (unsigned int feedbackVaryingIndex = 0; feedbackVaryingIndex < transformFeedbackVaryings.size(); feedbackVaryingIndex++) - { - const std::string &transformFeedbackVarying = transformFeedbackVaryings[feedbackVaryingIndex]; + // 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. - if (transformFeedbackVarying == "gl_Position" || transformFeedbackVarying == "gl_PointSize") + switch (registerInfo.packedVarying->interpolation) { - // do not pack builtin XFB varyings - continue; + case sh::INTERPOLATION_SMOOTH: + hlslStream << " "; + break; + case sh::INTERPOLATION_FLAT: + hlslStream << " nointerpolation "; + break; + case sh::INTERPOLATION_CENTROID: + hlslStream << " centroid "; + break; + default: + UNREACHABLE(); } - if (packedVaryings.find(transformFeedbackVarying) == packedVaryings.end()) - { - bool found = false; - for (unsigned int varyingIndex = 0; varyingIndex < vertexVaryings.size(); varyingIndex++) - { - PackedVarying *varying = &vertexVaryings[varyingIndex]; - if (transformFeedbackVarying == varying->name) - { - if (!packVarying(varying, maxVaryingVectors, packing)) - { - infoLog.append("Could not pack varying %s", varying->name.c_str()); - return -1; - } - - found = true; - break; - } - } - - if (!found) - { - infoLog.append("Transform feedback varying %s does not exist in the vertex shader.", transformFeedbackVarying.c_str()); - return -1; - } - } - } - - // Return the number of used registers - int registers = 0; - - for (int r = 0; r < maxVaryingVectors; r++) - { - if (packing[r][0] || packing[r][1] || packing[r][2] || packing[r][3]) - { - registers++; - } + GLenum transposedType = gl::TransposeMatrixType(varying.type); + GLenum componentType = gl::VariableComponentType(transposedType); + int columnCount = gl::VariableColumnCount(transposedType); + hlslStream << HLSLComponentTypeString(componentType, columnCount); + unsigned int semanticIndex = registerInfo.semanticIndex; + hlslStream << " v" << semanticIndex << " : " << varyingSemantic << semanticIndex << ";\n"; } - - return registers; } -std::string DynamicHLSL::generateVaryingHLSL(const ShaderD3D *shader) const +std::string DynamicHLSL::generateVertexShaderForInputLayout( + const std::string &sourceShader, + const InputLayout &inputLayout, + const std::vector &shaderAttributes) const { - std::string varyingSemantic = getVaryingSemantic(shader->mUsesPointSize); - std::string varyingHLSL; + std::stringstream structStream; + std::stringstream initStream; - const std::vector &varyings = shader->getVaryings(); + structStream << "struct VS_INPUT\n" + << "{\n"; - for (unsigned int varyingIndex = 0; varyingIndex < varyings.size(); varyingIndex++) - { - const PackedVarying &varying = varyings[varyingIndex]; - if (varying.registerAssigned()) - { - ASSERT(!varying.isBuiltIn()); - GLenum transposedType = TransposeMatrixType(varying.type); - int variableRows = (varying.isStruct() ? 1 : VariableRowCount(transposedType)); - - for (unsigned int elementIndex = 0; elementIndex < varying.elementCount(); elementIndex++) - { - for (int row = 0; row < variableRows; row++) - { - // 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 (varying.interpolation) - { - case sh::INTERPOLATION_SMOOTH: varyingHLSL += " "; break; - case sh::INTERPOLATION_FLAT: varyingHLSL += " nointerpolation "; break; - case sh::INTERPOLATION_CENTROID: varyingHLSL += " centroid "; break; - default: UNREACHABLE(); - } - - unsigned int semanticIndex = elementIndex * variableRows + - varying.columnIndex * mRenderer->getRendererCaps().maxVaryingVectors + - varying.registerIndex + row; - std::string n = Str(semanticIndex); - - std::string typeString; - - if (varying.isStruct()) - { - // TODO(jmadill): pass back translated name from the shader translator - typeString = decorateVariable(varying.structName); - } - else - { - GLenum componentType = VariableComponentType(transposedType); - int columnCount = VariableColumnCount(transposedType); - typeString = HLSLComponentTypeString(componentType, columnCount); - } - varyingHLSL += typeString + " v" + n + " : " + varyingSemantic + n + ";\n"; - } - } - } - } - - return varyingHLSL; -} - -std::string DynamicHLSL::generateVertexShaderForInputLayout(const std::string &sourceShader, - const VertexFormat inputLayout[], - const std::vector &shaderAttributes) const -{ - std::string structHLSL, initHLSL; - - int semanticIndex = 0; + 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->getWorkarounds().useInstancedPointSpriteEmulation; + bool useInstancedPointSpriteEmulation = + usesPointSize && mRenderer->getWorkarounds().useInstancedPointSpriteEmulation; // Instanced PointSprite emulation requires additional entries in the // VS_INPUT structure to support the vertices that make up the quad vertices. @@ -402,8 +207,8 @@ std::string DynamicHLSL::generateVertexShaderForInputLayout(const std::string &s // before per instance data in the shader. if (useInstancedPointSpriteEmulation) { - structHLSL += " float3 spriteVertexPos : SPRITEPOSITION0;\n"; - structHLSL += " float2 spriteTexCoord : SPRITETEXCOORD0;\n"; + structStream << " float3 spriteVertexPos : SPRITEPOSITION0;\n" + << " float2 spriteTexCoord : SPRITETEXCOORD0;\n"; } for (size_t attributeIndex = 0; attributeIndex < shaderAttributes.size(); ++attributeIndex) @@ -412,92 +217,104 @@ std::string DynamicHLSL::generateVertexShaderForInputLayout(const std::string &s if (!shaderAttribute.name.empty()) { ASSERT(inputIndex < MAX_VERTEX_ATTRIBS); - const VertexFormat &vertexFormat = inputLayout[inputIndex]; + VertexFormatType vertexFormatType = + inputIndex < inputLayout.size() ? inputLayout[inputIndex] : VERTEX_FORMAT_INVALID; // HLSL code for input structure if (IsMatrixType(shaderAttribute.type)) { // Matrix types are always transposed - structHLSL += " " + HLSLMatrixTypeString(TransposeMatrixType(shaderAttribute.type)); + structStream << " " + << HLSLMatrixTypeString(TransposeMatrixType(shaderAttribute.type)); } else { - GLenum componentType = mRenderer->getVertexComponentType(vertexFormat); + GLenum componentType = mRenderer->getVertexComponentType(vertexFormatType); - if (shaderAttribute.name == "gl_InstanceID") + if (shaderAttribute.name == "gl_InstanceID" || + shaderAttribute.name == "gl_VertexID") { - // The input type of the instance ID in HLSL (uint) differs from the one in ESSL (int). - structHLSL += " uint"; + // The input types of the instance ID and vertex ID in HLSL (uint) differs from + // the ones in ESSL (int). + structStream << " uint"; } else { - structHLSL += " " + HLSLComponentTypeString(componentType, VariableComponentCount(shaderAttribute.type)); + structStream << " " << HLSLComponentTypeString( + componentType, + VariableComponentCount(shaderAttribute.type)); } } - structHLSL += " " + decorateVariable(shaderAttribute.name) + " : "; + structStream << " " << decorateVariable(shaderAttribute.name) << " : "; if (shaderAttribute.name == "gl_InstanceID") { - structHLSL += "SV_InstanceID"; + structStream << "SV_InstanceID"; + } + else if (shaderAttribute.name == "gl_VertexID") + { + structStream << "SV_VertexID"; } else { - structHLSL += "TEXCOORD" + Str(semanticIndex); + structStream << "TEXCOORD" << semanticIndex; semanticIndex += VariableRegisterCount(shaderAttribute.type); } - structHLSL += ";\n"; + structStream << ";\n"; // HLSL code for initialization - initHLSL += " " + decorateVariable(shaderAttribute.name) + " = "; + 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(vertexFormat) & VERTEX_CONVERT_GPU) != 0) + (mRenderer->getVertexConversionType(vertexFormatType) & VERTEX_CONVERT_GPU) != 0) { - initHLSL += generateAttributeConversionHLSL(vertexFormat, shaderAttribute); + initStream << generateAttributeConversionHLSL(vertexFormatType, shaderAttribute); } else { - initHLSL += "input." + decorateVariable(shaderAttribute.name); + initStream << "input." << decorateVariable(shaderAttribute.name); } - initHLSL += ";\n"; + initStream << ";\n"; inputIndex += VariableRowCount(TransposeMatrixType(shaderAttribute.type)); } } - std::string replacementHLSL = "struct VS_INPUT\n" - "{\n" + - structHLSL + - "};\n" - "\n" - "void initAttributes(VS_INPUT input)\n" - "{\n" + - initHLSL + - "}\n"; + structStream << "};\n" + "\n" + "void initAttributes(VS_INPUT input)\n" + "{\n" + << initStream.str() << "}\n"; std::string vertexHLSL(sourceShader); size_t copyInsertionPos = vertexHLSL.find(VERTEX_ATTRIBUTE_STUB_STRING); - vertexHLSL.replace(copyInsertionPos, VERTEX_ATTRIBUTE_STUB_STRING.length(), replacementHLSL); + vertexHLSL.replace(copyInsertionPos, VERTEX_ATTRIBUTE_STUB_STRING.length(), structStream.str()); return vertexHLSL; } -std::string DynamicHLSL::generatePixelShaderForOutputSignature(const std::string &sourceShader, const std::vector &outputVariables, - bool usesFragDepth, const std::vector &outputLayout) const +std::string DynamicHLSL::generatePixelShaderForOutputSignature( + const std::string &sourceShader, + const std::vector &outputVariables, + bool usesFragDepth, + const std::vector &outputLayout) const { - const int shaderModel = mRenderer->getMajorShaderModel(); + const int shaderModel = mRenderer->getMajorShaderModel(); std::string targetSemantic = (shaderModel >= 4) ? "SV_TARGET" : "COLOR"; - std::string depthSemantic = (shaderModel >= 4) ? "SV_Depth" : "DEPTH"; + std::string depthSemantic = (shaderModel >= 4) ? "SV_Depth" : "DEPTH"; - std::string declarationHLSL; - std::string copyHLSL; + std::stringstream declarationStream; + std::stringstream copyStream; + + declarationStream << "struct PS_OUTPUT\n" + "{\n"; for (size_t layoutIndex = 0; layoutIndex < outputLayout.size(); ++layoutIndex) { @@ -507,703 +324,667 @@ std::string DynamicHLSL::generatePixelShaderForOutputSignature(const std::string { unsigned int location = (binding - GL_COLOR_ATTACHMENT0); - const PixelShaderOutputVariable *outputVariable = FindOutputAtLocation(outputVariables, location); + const PixelShaderOutputVariable *outputVariable = + FindOutputAtLocation(outputVariables, location); // OpenGL ES 3.0 spec $4.2.1 - // If [...] not all user-defined output variables are written, the values of fragment colors + // If [...] not all user-defined output variables are written, the values of fragment + // colors // corresponding to unwritten variables are similarly undefined. if (outputVariable) { - declarationHLSL += " " + HLSLTypeString(outputVariable->type) + " " + outputVariable->name + - " : " + targetSemantic + Str(layoutIndex) + ";\n"; + declarationStream << " " + HLSLTypeString(outputVariable->type) << " " + << outputVariable->name << " : " << targetSemantic + << static_cast(layoutIndex) << ";\n"; - copyHLSL += " output." + outputVariable->name + " = " + outputVariable->source + ";\n"; + copyStream << " output." << outputVariable->name << " = " + << outputVariable->source << ";\n"; } } } if (usesFragDepth) { - declarationHLSL += " float gl_Depth : " + depthSemantic + ";\n"; - copyHLSL += " output.gl_Depth = gl_Depth; \n"; + declarationStream << " float gl_Depth : " << depthSemantic << ";\n"; + copyStream << " output.gl_Depth = gl_Depth; \n"; } - std::string replacementHLSL = "struct PS_OUTPUT\n" - "{\n" + - declarationHLSL + - "};\n" - "\n" - "PS_OUTPUT generateOutput()\n" - "{\n" - " PS_OUTPUT output;\n" + - copyHLSL + - " return output;\n" - "}\n"; + declarationStream << "};\n" + "\n" + "PS_OUTPUT generateOutput()\n" + "{\n" + " PS_OUTPUT output;\n" + << copyStream.str() << " return output;\n" + "}\n"; std::string pixelHLSL(sourceShader); size_t outputInsertionPos = pixelHLSL.find(PIXEL_OUTPUT_STUB_STRING); - pixelHLSL.replace(outputInsertionPos, PIXEL_OUTPUT_STUB_STRING.length(), replacementHLSL); + pixelHLSL.replace(outputInsertionPos, PIXEL_OUTPUT_STUB_STRING.length(), + declarationStream.str()); return pixelHLSL; } -std::string DynamicHLSL::getVaryingSemantic(bool pointSize) const -{ - // SM3 reserves the TEXCOORD semantic for point sprite texcoords (gl_PointCoord) - // In D3D11 we manually compute gl_PointCoord in the GS. - int shaderModel = mRenderer->getMajorShaderModel(); - return ((pointSize && shaderModel < 4) ? "COLOR" : "TEXCOORD"); -} - -struct DynamicHLSL::SemanticInfo -{ - struct BuiltinInfo - { - BuiltinInfo() - : enabled(false), - index(0), - systemValue(false) - {} - - bool enabled; - std::string semantic; - unsigned int index; - bool systemValue; - - std::string str() const - { - return (systemValue ? semantic : (semantic + Str(index))); - } - - void enableSystem(const std::string &systemValueSemantic) - { - enabled = true; - semantic = systemValueSemantic; - systemValue = true; - } - - void enable(const std::string &semanticVal, unsigned int indexVal) - { - enabled = true; - semantic = semanticVal; - index = indexVal; - } - }; - - BuiltinInfo dxPosition; - BuiltinInfo glPosition; - BuiltinInfo glFragCoord; - BuiltinInfo glPointCoord; - BuiltinInfo glPointSize; -}; - -DynamicHLSL::SemanticInfo DynamicHLSL::getSemanticInfo(int startRegisters, bool position, bool fragCoord, - bool pointCoord, bool pointSize, bool pixelShader) const -{ - SemanticInfo info; - bool hlsl4 = (mRenderer->getMajorShaderModel() >= 4); - const std::string &varyingSemantic = getVaryingSemantic(pointSize); - - int reservedRegisterIndex = startRegisters; - - if (hlsl4) - { - info.dxPosition.enableSystem("SV_Position"); - } - else if (pixelShader) - { - info.dxPosition.enableSystem("VPOS"); - } - else - { - info.dxPosition.enableSystem("POSITION"); - } - - if (position) - { - info.glPosition.enable(varyingSemantic, reservedRegisterIndex++); - } - - if (fragCoord) - { - info.glFragCoord.enable(varyingSemantic, reservedRegisterIndex++); - } - - if (pointCoord) - { - // SM3 reserves the TEXCOORD semantic for point sprite texcoords (gl_PointCoord) - // In D3D11 we manually compute gl_PointCoord in the GS. - if (hlsl4) - { - info.glPointCoord.enable(varyingSemantic, reservedRegisterIndex++); - } - else - { - info.glPointCoord.enable("TEXCOORD", 0); - } - } - - // Special case: do not include PSIZE semantic in HLSL 3 pixel shaders - if (pointSize && (!pixelShader || hlsl4)) - { - info.glPointSize.enableSystem("PSIZE"); - } - - return info; -} - -std::string DynamicHLSL::generateVaryingLinkHLSL(const SemanticInfo &info, const std::string &varyingHLSL) const +void DynamicHLSL::generateVaryingLinkHLSL(ShaderType shaderType, + const VaryingPacking &varyingPacking, + std::stringstream &linkStream) const { - std::string linkHLSL = "{\n"; - - ASSERT(info.dxPosition.enabled); - linkHLSL += " float4 dx_Position : " + info.dxPosition.str() + ";\n"; - - if (info.glPosition.enabled) - { - linkHLSL += " float4 gl_Position : " + info.glPosition.str() + ";\n"; - } + const auto &builtins = varyingPacking.builtins(shaderType); + ASSERT(builtins.dxPosition.enabled); + linkStream << "{\n" + << " float4 dx_Position : " << builtins.dxPosition.str() << ";\n"; - if (info.glFragCoord.enabled) + if (builtins.glPosition.enabled) { - linkHLSL += " float4 gl_FragCoord : " + info.glFragCoord.str() + ";\n"; + linkStream << " float4 gl_Position : " << builtins.glPosition.str() << ";\n"; } - if (info.glPointCoord.enabled) - { - linkHLSL += " float2 gl_PointCoord : " + info.glPointCoord.str() + ";\n"; - } - - if (info.glPointSize.enabled) - { - linkHLSL += " float gl_PointSize : " + info.glPointSize.str() + ";\n"; - } - - // Do this after glPointSize, to potentially combine gl_PointCoord and gl_PointSize into the same register. - linkHLSL += varyingHLSL; - - linkHLSL += "};\n"; - - return linkHLSL; -} - -void DynamicHLSL::storeBuiltinLinkedVaryings(const SemanticInfo &info, - std::vector *linkedVaryings) const -{ - if (info.glPosition.enabled) + if (builtins.glFragCoord.enabled) { - linkedVaryings->push_back(LinkedVarying("gl_Position", GL_FLOAT_VEC4, 1, info.glPosition.semantic, - info.glPosition.index, 1)); + linkStream << " float4 gl_FragCoord : " << builtins.glFragCoord.str() << ";\n"; } - if (info.glFragCoord.enabled) + if (builtins.glPointCoord.enabled) { - linkedVaryings->push_back(LinkedVarying("gl_FragCoord", GL_FLOAT_VEC4, 1, info.glFragCoord.semantic, - info.glFragCoord.index, 1)); + linkStream << " float2 gl_PointCoord : " << builtins.glPointCoord.str() << ";\n"; } - if (info.glPointSize.enabled) + if (builtins.glPointSize.enabled) { - linkedVaryings->push_back(LinkedVarying("gl_PointSize", GL_FLOAT, 1, "PSIZE", 0, 1)); + linkStream << " float gl_PointSize : " << builtins.glPointSize.str() << ";\n"; } -} - -void DynamicHLSL::storeUserLinkedVaryings(const ShaderD3D *vertexShader, - std::vector *linkedVaryings) const -{ - const std::string &varyingSemantic = getVaryingSemantic(vertexShader->mUsesPointSize); - const std::vector &varyings = vertexShader->getVaryings(); - for (unsigned int varyingIndex = 0; varyingIndex < varyings.size(); varyingIndex++) - { - const PackedVarying &varying = varyings[varyingIndex]; - - if (varying.registerAssigned()) - { - ASSERT(!varying.isBuiltIn()); - GLenum transposedType = TransposeMatrixType(varying.type); - int variableRows = (varying.isStruct() ? 1 : VariableRowCount(transposedType)); + // Do this after gl_PointSize, to potentially combine gl_PointCoord and gl_PointSize into the + // same register. + generateVaryingHLSL(varyingPacking, linkStream); - linkedVaryings->push_back(LinkedVarying(varying.name, varying.type, varying.elementCount(), - varyingSemantic, varying.registerIndex, - variableRows * varying.elementCount())); - } - } + linkStream << "};\n"; } -bool DynamicHLSL::generateShaderLinkHLSL(const gl::Data &data, InfoLog &infoLog, int registers, - const VaryingPacking packing, - std::string &pixelHLSL, std::string &vertexHLSL, - ShaderD3D *fragmentShader, ShaderD3D *vertexShader, - const std::vector &transformFeedbackVaryings, - std::vector *linkedVaryings, - std::map *programOutputVars, - std::vector *outPixelShaderKey, - bool *outUsesFragDepth) const +bool DynamicHLSL::generateShaderLinkHLSL(const gl::Data &data, + const gl::Program::Data &programData, + const ProgramD3DMetadata &programMetadata, + const VaryingPacking &varyingPacking, + std::string *pixelHLSL, + std::string *vertexHLSL) const { - if (pixelHLSL.empty() || vertexHLSL.empty()) - { - return false; - } + ASSERT(pixelHLSL->empty() && vertexHLSL->empty()); - bool usesMRT = fragmentShader->mUsesMultipleRenderTargets; - bool usesFragColor = fragmentShader->mUsesFragColor; - bool usesFragData = fragmentShader->mUsesFragData; - bool usesFragCoord = fragmentShader->mUsesFragCoord; - bool usesPointCoord = fragmentShader->mUsesPointCoord; - bool usesPointSize = vertexShader->mUsesPointSize; - bool useInstancedPointSpriteEmulation = usesPointSize && mRenderer->getWorkarounds().useInstancedPointSpriteEmulation; + const gl::Shader *vertexShaderGL = programData.getAttachedVertexShader(); + const gl::Shader *fragmentShaderGL = programData.getAttachedFragmentShader(); + const ShaderD3D *fragmentShader = GetImplAs(fragmentShaderGL); + const int shaderModel = mRenderer->getMajorShaderModel(); - if (usesFragColor && usesFragData) - { - infoLog.append("Cannot use both gl_FragColor and gl_FragData in the same fragment shader."); - return false; - } - - // Write the HLSL input/output declarations - const int shaderModel = mRenderer->getMajorShaderModel(); - const int registersNeeded = registers + (usesFragCoord ? 1 : 0) + (usesPointCoord ? 1 : 0); - - // 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 - const bool broadcast = (fragmentShader->mUsesFragColor && data.clientVersion < 3); - const unsigned int numRenderTargets = (broadcast || usesMRT ? data.caps->maxDrawBuffers : 1); - - // 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. - bool outputPositionFromVS = !(shaderModel >= 4 && mRenderer->getShaderModelSuffix() != ""); - - int shaderVersion = vertexShader->getShaderVersion(); - - if (static_cast(registersNeeded) > data.caps->maxVaryingVectors) - { - infoLog.append("No varying registers left to support gl_FragCoord/gl_PointCoord"); - return false; - } + // usesViewScale() isn't supported in the D3D9 renderer + ASSERT(shaderModel >= 4 || !programMetadata.usesViewScale()); - const std::string &varyingHLSL = generateVaryingHLSL(vertexShader); + bool useInstancedPointSpriteEmulation = + programMetadata.usesPointSize() && + mRenderer->getWorkarounds().useInstancedPointSpriteEmulation; - // Instanced PointSprite emulation requires that gl_PointCoord is present in the vertex shader VS_OUTPUT - // structure to ensure compatibility with the generated PS_INPUT of the pixel shader. - // GeometryShader PointSprite emulation does not require this additional entry because the - // GS_OUTPUT of the Geometry shader contains the pointCoord value and already matches the PS_INPUT of the - // generated pixel shader. - // The Geometry Shader point sprite implementation needs gl_PointSize to be in VS_OUTPUT and GS_INPUT. - // Instanced point sprites doesn't need gl_PointSize in VS_OUTPUT. - const SemanticInfo &vertexSemantics = getSemanticInfo(registers, outputPositionFromVS, - usesFragCoord, (useInstancedPointSpriteEmulation && usesPointCoord), - (!useInstancedPointSpriteEmulation && usesPointSize), false); + // Validation done in the compiler + ASSERT(!fragmentShader->usesFragColor() || !fragmentShader->usesFragData()); - storeUserLinkedVaryings(vertexShader, linkedVaryings); - storeBuiltinLinkedVaryings(vertexSemantics, linkedVaryings); + std::stringstream vertexStream; + vertexStream << vertexShaderGL->getTranslatedSource(); // Instanced PointSprite emulation requires additional entries originally generated in the - // GeometryShader HLSL. These include pointsize clamp values. + // GeometryShader HLSL. These include pointsize clamp values. if (useInstancedPointSpriteEmulation) { - vertexHLSL += "static float minPointSize = " + Str((int)mRenderer->getRendererCaps().minAliasedPointSize) + ".0f;\n" - "static float maxPointSize = " + Str((int)mRenderer->getRendererCaps().maxAliasedPointSize) + ".0f;\n"; + vertexStream << "static float minPointSize = " + << static_cast(data.caps->minAliasedPointSize) << ".0f;\n" + << "static float maxPointSize = " + << static_cast(data.caps->maxAliasedPointSize) << ".0f;\n"; } // Add stub string to be replaced when shader is dynamically defined by its layout - vertexHLSL += "\n" + VERTEX_ATTRIBUTE_STUB_STRING + "\n" - "struct VS_OUTPUT\n" + generateVaryingLinkHLSL(vertexSemantics, varyingHLSL) + "\n" - "VS_OUTPUT main(VS_INPUT input)\n" - "{\n" - " initAttributes(input);\n"; + vertexStream << "\n" << VERTEX_ATTRIBUTE_STUB_STRING + "\n"; - if (vertexShader->usesDeferredInit()) - { - vertexHLSL += "\n" - " initializeDeferredGlobals();\n"; - } + // Write the HLSL input/output declarations + vertexStream << "struct VS_OUTPUT\n"; + generateVaryingLinkHLSL(SHADER_VERTEX, varyingPacking, vertexStream); + vertexStream << "\n" + << "VS_OUTPUT main(VS_INPUT input)\n" + << "{\n" + << " initAttributes(input);\n"; - vertexHLSL += "\n" - " gl_main();\n" - "\n" - " VS_OUTPUT output;\n"; + vertexStream << "\n" + << " gl_main();\n" + << "\n" + << " VS_OUTPUT output;\n"; - if (outputPositionFromVS) + const auto &vertexBuiltins = varyingPacking.builtins(SHADER_VERTEX); + + if (vertexBuiltins.glPosition.enabled) { - vertexHLSL += " output.gl_Position = gl_Position;\n"; + vertexStream << " output.gl_Position = gl_Position;\n"; } // On D3D9 or D3D11 Feature Level 9, we need to emulate large viewports using dx_ViewAdjust. - if (shaderModel >= 4 && mRenderer->getShaderModelSuffix() == "") + if (shaderModel >= 4 && mRenderer->getShaderModelSuffix() == "") { - vertexHLSL += " output.dx_Position.x = gl_Position.x;\n" - " output.dx_Position.y = -gl_Position.y;\n" - " output.dx_Position.z = (gl_Position.z + gl_Position.w) * 0.5;\n" - " output.dx_Position.w = gl_Position.w;\n"; + vertexStream << " 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. + vertexStream << " output.dx_Position.y = dx_ViewScale.y * gl_Position.y;\n"; + } + else + { + vertexStream << " output.dx_Position.y = - gl_Position.y;\n"; + } + + vertexStream << " output.dx_Position.z = (gl_Position.z + gl_Position.w) * 0.5;\n" + << " output.dx_Position.w = gl_Position.w;\n"; } else { - vertexHLSL += " output.dx_Position.x = gl_Position.x * dx_ViewAdjust.z + dx_ViewAdjust.x * gl_Position.w;\n" - " output.dx_Position.y = -(gl_Position.y * dx_ViewAdjust.w + dx_ViewAdjust.y * gl_Position.w);\n" - " output.dx_Position.z = (gl_Position.z + gl_Position.w) * 0.5;\n" - " output.dx_Position.w = gl_Position.w;\n"; + vertexStream << " 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() != "")) + { + vertexStream << " output.dx_Position.y = dx_ViewScale.y * (gl_Position.y * " + "dx_ViewAdjust.w + dx_ViewAdjust.y * gl_Position.w);\n"; + } + else + { + vertexStream << " output.dx_Position.y = -(gl_Position.y * dx_ViewAdjust.w + " + "dx_ViewAdjust.y * gl_Position.w);\n"; + } + + vertexStream << " output.dx_Position.z = (gl_Position.z + gl_Position.w) * 0.5;\n" + << " 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 (usesPointSize && shaderModel >= 3 && !useInstancedPointSpriteEmulation) + if (vertexBuiltins.glPointSize.enabled) { - vertexHLSL += " output.gl_PointSize = gl_PointSize;\n"; + vertexStream << " output.gl_PointSize = gl_PointSize;\n"; } - if (usesFragCoord) + if (vertexBuiltins.glFragCoord.enabled) { - vertexHLSL += " output.gl_FragCoord = gl_Position;\n"; + vertexStream << " output.gl_FragCoord = gl_Position;\n"; } - const std::vector &vertexVaryings = vertexShader->getVaryings(); - for (unsigned int vertVaryingIndex = 0; vertVaryingIndex < vertexVaryings.size(); vertVaryingIndex++) + for (const PackedVaryingRegister ®isterInfo : varyingPacking.getRegisterList()) { - const PackedVarying &varying = vertexVaryings[vertVaryingIndex]; - if (varying.registerAssigned()) - { - for (unsigned int elementIndex = 0; elementIndex < varying.elementCount(); elementIndex++) - { - int variableRows = (varying.isStruct() ? 1 : VariableRowCount(TransposeMatrixType(varying.type))); + const auto &packedVarying = *registerInfo.packedVarying; + const auto &varying = *packedVarying.varying; + ASSERT(!varying.isStruct()); - for (int row = 0; row < variableRows; row++) - { - int r = varying.registerIndex + varying.columnIndex * data.caps->maxVaryingVectors + elementIndex * variableRows + row; - vertexHLSL += " output.v" + Str(r); + vertexStream << " output.v" << registerInfo.semanticIndex << " = "; - vertexHLSL += " = _" + varying.name; + if (packedVarying.isStructField()) + { + vertexStream << decorateVariable(packedVarying.parentStructName) << "."; + } - if (varying.isArray()) - { - vertexHLSL += ArrayString(elementIndex); - } + vertexStream << decorateVariable(varying.name); - if (variableRows > 1) - { - vertexHLSL += ArrayString(row); - } + if (varying.isArray()) + { + WriteArrayString(vertexStream, registerInfo.varyingArrayIndex); + } - vertexHLSL += ";\n"; - } - } + if (VariableRowCount(varying.type) > 1) + { + WriteArrayString(vertexStream, registerInfo.varyingRowIndex); } + + vertexStream << ";\n"; } // Instanced PointSprite emulation requires additional entries to calculate // the final output vertex positions of the quad that represents each sprite. if (useInstancedPointSpriteEmulation) { - vertexHLSL += "\n" - " gl_PointSize = clamp(gl_PointSize, minPointSize, maxPointSize);\n" - " output.dx_Position.xyz += float3(input.spriteVertexPos.x * gl_PointSize / (dx_ViewCoords.x*2), input.spriteVertexPos.y * gl_PointSize / (dx_ViewCoords.y*2), input.spriteVertexPos.z) * output.dx_Position.w;\n"; + vertexStream << "\n" + << " gl_PointSize = clamp(gl_PointSize, minPointSize, maxPointSize);\n"; + + vertexStream << " output.dx_Position.x += (input.spriteVertexPos.x * gl_PointSize / " + "(dx_ViewCoords.x*2)) * output.dx_Position.w;"; - if (usesPointCoord) + if (programMetadata.usesViewScale()) { - vertexHLSL += "\n" - " output.gl_PointCoord = input.spriteTexCoord;\n"; + // Multiply by ViewScale to invert the rendering when appropriate + vertexStream << " output.dx_Position.y += (-dx_ViewScale.y * " + "input.spriteVertexPos.y * gl_PointSize / (dx_ViewCoords.y*2)) * " + "output.dx_Position.w;"; } - } - - vertexHLSL += "\n" - " return output;\n" - "}\n"; - - const SemanticInfo &pixelSemantics = getSemanticInfo(registers, outputPositionFromVS, usesFragCoord, usesPointCoord, - (!useInstancedPointSpriteEmulation && usesPointSize), true); - - pixelHLSL += "struct PS_INPUT\n" + generateVaryingLinkHLSL(pixelSemantics, varyingHLSL) + "\n"; - - if (shaderVersion < 300) - { - for (unsigned int renderTargetIndex = 0; renderTargetIndex < numRenderTargets; renderTargetIndex++) + else { - PixelShaderOutputVariable outputKeyVariable; - outputKeyVariable.type = GL_FLOAT_VEC4; - outputKeyVariable.name = "gl_Color" + Str(renderTargetIndex); - outputKeyVariable.source = broadcast ? "gl_Color[0]" : "gl_Color[" + Str(renderTargetIndex) + "]"; - outputKeyVariable.outputIndex = renderTargetIndex; - - outPixelShaderKey->push_back(outputKeyVariable); + vertexStream << " output.dx_Position.y += (input.spriteVertexPos.y * gl_PointSize / " + "(dx_ViewCoords.y*2)) * output.dx_Position.w;"; } - *outUsesFragDepth = fragmentShader->mUsesFragDepth; - } - else - { - defineOutputVariables(fragmentShader, programOutputVars); + vertexStream + << " output.dx_Position.z += input.spriteVertexPos.z * output.dx_Position.w;\n"; - const std::vector &shaderOutputVars = fragmentShader->getActiveOutputVariables(); - for (auto locationIt = programOutputVars->begin(); locationIt != programOutputVars->end(); locationIt++) + if (programMetadata.usesPointCoord()) { - const VariableLocation &outputLocation = locationIt->second; - const sh::ShaderVariable &outputVariable = shaderOutputVars[outputLocation.index]; - const std::string &variableName = "out_" + outputLocation.name; - const std::string &elementString = (outputLocation.element == GL_INVALID_INDEX ? "" : Str(outputLocation.element)); - - ASSERT(outputVariable.staticUse); - - PixelShaderOutputVariable outputKeyVariable; - outputKeyVariable.type = outputVariable.type; - outputKeyVariable.name = variableName + elementString; - outputKeyVariable.source = variableName + ArrayString(outputLocation.element); - outputKeyVariable.outputIndex = locationIt->first; - - outPixelShaderKey->push_back(outputKeyVariable); + vertexStream << "\n" + << " output.gl_PointCoord = input.spriteTexCoord;\n"; } + } - *outUsesFragDepth = false; + // 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); + vertexStream << "\n" + << " output.gl_PointCoord = float2(0.5, 0.5);\n"; } - pixelHLSL += PIXEL_OUTPUT_STUB_STRING + "\n"; + vertexStream << "\n" + << " return output;\n" + << "}\n"; + + std::stringstream pixelStream; + pixelStream << fragmentShaderGL->getTranslatedSource(); + pixelStream << "struct PS_INPUT\n"; + generateVaryingLinkHLSL(SHADER_PIXEL, varyingPacking, pixelStream); + pixelStream << "\n"; + + pixelStream << PIXEL_OUTPUT_STUB_STRING + "\n"; - if (fragmentShader->mUsesFrontFacing) + if (fragmentShader->usesFrontFacing()) { if (shaderModel >= 4) { - pixelHLSL += "PS_OUTPUT main(PS_INPUT input, bool isFrontFace : SV_IsFrontFace)\n" - "{\n"; + pixelStream << "PS_OUTPUT main(PS_INPUT input, bool isFrontFace : SV_IsFrontFace)\n" + << "{\n"; } else { - pixelHLSL += "PS_OUTPUT main(PS_INPUT input, float vFace : VFACE)\n" - "{\n"; + pixelStream << "PS_OUTPUT main(PS_INPUT input, float vFace : VFACE)\n" + << "{\n"; } } else { - pixelHLSL += "PS_OUTPUT main(PS_INPUT input)\n" - "{\n"; + pixelStream << "PS_OUTPUT main(PS_INPUT input)\n" + << "{\n"; } - if (usesFragCoord) + const auto &pixelBuiltins = varyingPacking.builtins(SHADER_PIXEL); + + if (pixelBuiltins.glFragCoord.enabled) { - pixelHLSL += " float rhw = 1.0 / input.gl_FragCoord.w;\n"; + pixelStream << " 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. + // Other Shader Models (4_0_level_9_3 and 2_x) don't support this, so we emulate it using + // dx_ViewCoords. if (shaderModel >= 4 && mRenderer->getShaderModelSuffix() == "") { - pixelHLSL += " gl_FragCoord.x = input.dx_Position.x;\n" - " gl_FragCoord.y = input.dx_Position.y;\n"; + pixelStream << " gl_FragCoord.x = input.dx_Position.x;\n" + << " gl_FragCoord.y = input.dx_Position.y;\n"; } else if (shaderModel == 3) { - pixelHLSL += " gl_FragCoord.x = input.dx_Position.x + 0.5;\n" - " gl_FragCoord.y = input.dx_Position.y + 0.5;\n"; + pixelStream << " gl_FragCoord.x = input.dx_Position.x + 0.5;\n" + << " gl_FragCoord.y = input.dx_Position.y + 0.5;\n"; } else { - // dx_ViewCoords contains the viewport width/2, height/2, center.x and center.y. See Renderer::setViewport() - pixelHLSL += " gl_FragCoord.x = (input.gl_FragCoord.x * rhw) * dx_ViewCoords.x + dx_ViewCoords.z;\n" - " gl_FragCoord.y = (input.gl_FragCoord.y * rhw) * dx_ViewCoords.y + dx_ViewCoords.w;\n"; + // dx_ViewCoords contains the viewport width/2, height/2, center.x and center.y. See + // Renderer::setViewport() + pixelStream << " gl_FragCoord.x = (input.gl_FragCoord.x * rhw) * dx_ViewCoords.x + " + "dx_ViewCoords.z;\n" + << " gl_FragCoord.y = (input.gl_FragCoord.y * rhw) * dx_ViewCoords.y + " + "dx_ViewCoords.w;\n"; } - pixelHLSL += " gl_FragCoord.z = (input.gl_FragCoord.z * rhw) * dx_DepthFront.x + dx_DepthFront.y;\n" - " gl_FragCoord.w = rhw;\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: + pixelStream + << " 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"; + } + } + + pixelStream << " gl_FragCoord.z = (input.gl_FragCoord.z * rhw) * dx_DepthFront.x + " + "dx_DepthFront.y;\n" + << " gl_FragCoord.w = rhw;\n"; } - if (usesPointCoord && shaderModel >= 3) + if (pixelBuiltins.glPointCoord.enabled && shaderModel >= 3) { - pixelHLSL += " gl_PointCoord.x = input.gl_PointCoord.x;\n"; - pixelHLSL += " gl_PointCoord.y = 1.0 - input.gl_PointCoord.y;\n"; + pixelStream << " gl_PointCoord.x = input.gl_PointCoord.x;\n" + << " gl_PointCoord.y = 1.0 - input.gl_PointCoord.y;\n"; } - if (fragmentShader->mUsesFrontFacing) + if (fragmentShader->usesFrontFacing()) { if (shaderModel <= 3) { - pixelHLSL += " gl_FrontFacing = (vFace * dx_DepthFront.z >= 0.0);\n"; + pixelStream << " gl_FrontFacing = (vFace * dx_DepthFront.z >= 0.0);\n"; } else { - pixelHLSL += " gl_FrontFacing = isFrontFace;\n"; + pixelStream << " gl_FrontFacing = isFrontFace;\n"; } } - const std::vector &fragmentVaryings = fragmentShader->getVaryings(); - for (unsigned int varyingIndex = 0; varyingIndex < fragmentVaryings.size(); varyingIndex++) + for (const PackedVaryingRegister ®isterInfo : varyingPacking.getRegisterList()) { - const PackedVarying &varying = fragmentVaryings[varyingIndex]; - if (varying.registerAssigned()) + const auto &packedVarying = *registerInfo.packedVarying; + const auto &varying = *packedVarying.varying; + ASSERT(!varying.isBuiltIn() && !varying.isStruct()); + + // Don't reference VS-only transform feedback varyings in the PS. + if (registerInfo.packedVarying->vertexOnly) + continue; + + pixelStream << " "; + + if (packedVarying.isStructField()) { - ASSERT(!varying.isBuiltIn()); - for (unsigned int elementIndex = 0; elementIndex < varying.elementCount(); elementIndex++) - { - GLenum transposedType = TransposeMatrixType(varying.type); - int variableRows = (varying.isStruct() ? 1 : VariableRowCount(transposedType)); - for (int row = 0; row < variableRows; row++) - { - std::string n = Str(varying.registerIndex + varying.columnIndex * data.caps->maxVaryingVectors + elementIndex * variableRows + row); - pixelHLSL += " _" + varying.name; - - if (varying.isArray()) - { - pixelHLSL += ArrayString(elementIndex); - } - - if (variableRows > 1) - { - pixelHLSL += ArrayString(row); - } - - if (varying.isStruct()) - { - pixelHLSL += " = input.v" + n + ";\n"; break; - } - else - { - switch (VariableColumnCount(transposedType)) - { - case 1: pixelHLSL += " = input.v" + n + ".x;\n"; break; - case 2: pixelHLSL += " = input.v" + n + ".xy;\n"; break; - case 3: pixelHLSL += " = input.v" + n + ".xyz;\n"; break; - case 4: pixelHLSL += " = input.v" + n + ";\n"; break; - default: UNREACHABLE(); - } - } - } - } + pixelStream << decorateVariable(packedVarying.parentStructName) << "."; } - else + + pixelStream << decorateVariable(varying.name); + + if (varying.isArray()) { - ASSERT(varying.isBuiltIn() || !varying.staticUse); + WriteArrayString(pixelStream, registerInfo.varyingArrayIndex); } - } - if (fragmentShader->usesDeferredInit()) - { - pixelHLSL += "\n" - " initializeDeferredGlobals();\n"; + GLenum transposedType = TransposeMatrixType(varying.type); + if (VariableRowCount(transposedType) > 1) + { + WriteArrayString(pixelStream, registerInfo.varyingRowIndex); + } + + pixelStream << " = input.v" << registerInfo.semanticIndex; + + switch (VariableColumnCount(transposedType)) + { + case 1: + pixelStream << ".x"; + break; + case 2: + pixelStream << ".xy"; + break; + case 3: + pixelStream << ".xyz"; + break; + case 4: + break; + default: + UNREACHABLE(); + } + pixelStream << ";\n"; } - pixelHLSL += "\n" - " gl_main();\n" - "\n" - " return generateOutput();\n" - "}\n"; + pixelStream << "\n" + << " gl_main();\n" + << "\n" + << " return generateOutput();\n" + << "}\n"; + + *vertexHLSL = vertexStream.str(); + *pixelHLSL = pixelStream.str(); return true; } -void DynamicHLSL::defineOutputVariables(ShaderD3D *fragmentShader, std::map *programOutputVars) const +std::string DynamicHLSL::generateGeometryShaderPreamble(const VaryingPacking &varyingPacking) const { - const std::vector &shaderOutputVars = fragmentShader->getActiveOutputVariables(); + ASSERT(mRenderer->getMajorShaderModel() >= 4); - for (unsigned int outputVariableIndex = 0; outputVariableIndex < shaderOutputVars.size(); outputVariableIndex++) - { - const sh::Attribute &outputVariable = shaderOutputVars[outputVariableIndex]; - const int baseLocation = outputVariable.location == -1 ? 0 : outputVariable.location; + std::stringstream preambleStream; - ASSERT(outputVariable.staticUse); + const auto &builtins = varyingPacking.builtins(SHADER_VERTEX); - if (outputVariable.arraySize > 0) - { - for (unsigned int elementIndex = 0; elementIndex < outputVariable.arraySize; elementIndex++) - { - const int location = baseLocation + elementIndex; - ASSERT(programOutputVars->count(location) == 0); - (*programOutputVars)[location] = VariableLocation(outputVariable.name, elementIndex, outputVariableIndex); - } - } - else + preambleStream << "struct GS_INPUT\n"; + generateVaryingLinkHLSL(SHADER_VERTEX, varyingPacking, preambleStream); + preambleStream << "\n" + << "struct GS_OUTPUT\n"; + generateVaryingLinkHLSL(SHADER_GEOMETRY, varyingPacking, 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 (builtins.glPointSize.enabled) + { + preambleStream << " output.gl_PointSize = input.gl_PointSize;\n"; + } + + for (const PackedVaryingRegister &varyingRegister : varyingPacking.getRegisterList()) + { + preambleStream << " output.v" << varyingRegister.semanticIndex << " = "; + if (varyingRegister.packedVarying->interpolation == sh::INTERPOLATION_FLAT) { - ASSERT(programOutputVars->count(baseLocation) == 0); - (*programOutputVars)[baseLocation] = VariableLocation(outputVariable.name, GL_INVALID_INDEX, outputVariableIndex); + preambleStream << "flat"; } + preambleStream << "input.v" << varyingRegister.semanticIndex << "; \n"; } -} -std::string DynamicHLSL::generateGeometryShaderHLSL(int registers, ShaderD3D *fragmentShader, ShaderD3D *vertexShader) const -{ - // for now we only handle point sprite emulation - ASSERT(vertexShader->mUsesPointSize && mRenderer->getMajorShaderModel() >= 4); - return generatePointSpriteHLSL(registers, fragmentShader, vertexShader); + if (builtins.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"; + + return preambleStream.str(); } -std::string DynamicHLSL::generatePointSpriteHLSL(int registers, ShaderD3D *fragmentShader, ShaderD3D *vertexShader) const +std::string DynamicHLSL::generateGeometryShaderHLSL(gl::PrimitiveType primitiveType, + const gl::Data &data, + const gl::Program::Data &programData, + const bool useViewScale, + const std::string &preambleString) const { - ASSERT(registers >= 0); - ASSERT(vertexShader->mUsesPointSize); ASSERT(mRenderer->getMajorShaderModel() >= 4); - std::string geomHLSL; - - const SemanticInfo &inSemantics = getSemanticInfo(registers, true, fragmentShader->mUsesFragCoord, - false, true, false); - const SemanticInfo &outSemantics = getSemanticInfo(registers, true, fragmentShader->mUsesFragCoord, - fragmentShader->mUsesPointCoord, true, false); - - std::string varyingHLSL = generateVaryingHLSL(vertexShader); - std::string inLinkHLSL = generateVaryingLinkHLSL(inSemantics, varyingHLSL); - std::string outLinkHLSL = generateVaryingLinkHLSL(outSemantics, varyingHLSL); - - // TODO(geofflang): use context's caps - geomHLSL += "uniform float4 dx_ViewCoords : register(c1);\n" - "\n" - "struct GS_INPUT\n" + inLinkHLSL + "\n" + - "struct GS_OUTPUT\n" + outLinkHLSL + "\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 = " + Str(static_cast(mRenderer->getRendererCaps().minAliasedPointSize)) + ".0f;\n" - "static float maxPointSize = " + Str(static_cast(mRenderer->getRendererCaps().maxAliasedPointSize)) + ".0f;\n" - "\n" - "[maxvertexcount(4)]\n" - "void main(point GS_INPUT input[1], inout TriangleStream outStream)\n" - "{\n" - " GS_OUTPUT output = (GS_OUTPUT)0;\n" - " output.gl_Position = input[0].gl_Position;\n" - " output.gl_PointSize = input[0].gl_PointSize;\n"; - - for (int r = 0; r < registers; r++) + std::stringstream shaderStream; + + const bool pointSprites = (primitiveType == PRIMITIVE_POINTS); + 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) { - geomHLSL += " output.v" + Str(r) + " = input[0].v" + Str(r) + ";\n"; + case PRIMITIVE_POINTS: + inputPT = "point"; + outputPT = "Triangle"; + inputSize = 1; + maxVertexOutput = 4; + break; + + case PRIMITIVE_LINES: + case PRIMITIVE_LINE_STRIP: + case PRIMITIVE_LINE_LOOP: + inputPT = "line"; + outputPT = "Line"; + inputSize = 2; + maxVertexOutput = 2; + break; + + case PRIMITIVE_TRIANGLES: + case PRIMITIVE_TRIANGLE_STRIP: + case PRIMITIVE_TRIANGLE_FAN: + inputPT = "triangle"; + outputPT = "Triangle"; + inputSize = 3; + maxVertexOutput = 3; + break; + + default: + UNREACHABLE(); + break; + } + + if (pointSprites) + { + shaderStream << "#define ANGLE_POINT_SPRITE_SHADER\n" + "\n" + "uniform float4 dx_ViewCoords : register(c1);\n"; + + if (useViewScale) + { + shaderStream << "uniform float2 dx_ViewScale : register(c3);\n"; + } + + shaderStream << "\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(data.caps->minAliasedPointSize) + << ".0f;\n" + "static float maxPointSize = " + << static_cast(data.caps->maxAliasedPointSize) << ".0f;\n" + << "\n"; } - if (fragmentShader->mUsesFragCoord) + shaderStream << preambleString << "\n" + << "[maxvertexcount(" << maxVertexOutput << ")]\n" + << "void main(" << inputPT << " GS_INPUT input[" << inputSize << "], "; + + if (primitiveType == PRIMITIVE_TRIANGLE_STRIP) { - geomHLSL += " output.gl_FragCoord = input[0].gl_FragCoord;\n"; + shaderStream << "uint primitiveID : SV_PrimitiveID, "; } - geomHLSL += " \n" - " float gl_PointSize = clamp(input[0].gl_PointSize, minPointSize, maxPointSize);\n" - " float4 dx_Position = input[0].dx_Position;\n" - " float2 viewportScale = float2(1.0f / dx_ViewCoords.x, 1.0f / dx_ViewCoords.y) * dx_Position.w;\n"; + shaderStream << " inout " << outputPT << "Stream outStream)\n" + << "{\n" + << " GS_OUTPUT output = (GS_OUTPUT)0;\n"; + + if (primitiveType == PRIMITIVE_TRIANGLE_STRIP) + { + shaderStream << " uint lastVertexIndex = (primitiveID % 2 == 0 ? 2 : 1);\n"; + } + else + { + shaderStream << " uint lastVertexIndex = " << (inputSize - 1) << ";\n"; + } - for (int corner = 0; corner < 4; corner++) + for (int vertexIndex = 0; vertexIndex < inputSize; ++vertexIndex) { - geomHLSL += " \n" - " output.dx_Position = dx_Position + float4(pointSpriteCorners[" + Str(corner) + "] * viewportScale * gl_PointSize, 0.0f, 0.0f);\n"; + shaderStream << " copyVertex(output, input[" << vertexIndex + << "], input[lastVertexIndex]);\n"; - if (fragmentShader->mUsesPointCoord) + if (!pointSprites) { - geomHLSL += " output.gl_PointCoord = pointSpriteTexcoords[" + Str(corner) + "];\n"; + ASSERT(inputSize == maxVertexOutput); + shaderStream << " outStream.Append(output);\n"; } + } - geomHLSL += " 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"; + } } - geomHLSL += " \n" - " outStream.RestartStrip();\n" - "}\n"; + shaderStream << " \n" + " outStream.RestartStrip();\n" + "}\n"; - return geomHLSL; + return shaderStream.str(); } // This method needs to match OutputHLSL::decorate @@ -1217,9 +998,12 @@ std::string DynamicHLSL::decorateVariable(const std::string &name) return name; } -std::string DynamicHLSL::generateAttributeConversionHLSL(const VertexFormat &vertexFormat, const sh::ShaderVariable &shaderAttrib) const +std::string DynamicHLSL::generateAttributeConversionHLSL( + gl::VertexFormatType vertexFormatType, + const sh::ShaderVariable &shaderAttrib) const { - std::string attribString = "input." + decorateVariable(shaderAttrib.name); + const gl::VertexFormat &vertexFormat = gl::GetVertexFormatFromType(vertexFormatType); + std::string attribString = "input." + decorateVariable(shaderAttrib.name); // Matrix if (IsMatrixType(shaderAttrib.type)) @@ -1228,15 +1012,16 @@ std::string DynamicHLSL::generateAttributeConversionHLSL(const VertexFormat &ver } GLenum shaderComponentType = VariableComponentType(shaderAttrib.type); - int shaderComponentCount = VariableComponentCount(shaderAttrib.type); + int shaderComponentCount = VariableComponentCount(shaderAttrib.type); // Perform integer to float conversion (if necessary) - bool requiresTypeConversion = (shaderComponentType == GL_FLOAT && vertexFormat.mType != GL_FLOAT); + bool requiresTypeConversion = + (shaderComponentType == GL_FLOAT && vertexFormat.type != GL_FLOAT); if (requiresTypeConversion) { // TODO: normalization for 32-bit integer formats - ASSERT(!vertexFormat.mNormalized && !vertexFormat.mPureInteger); + ASSERT(!vertexFormat.normalized && !vertexFormat.pureInteger); return "float" + Str(shaderComponentCount) + "(" + attribString + ")"; } @@ -1244,22 +1029,57 @@ std::string DynamicHLSL::generateAttributeConversionHLSL(const VertexFormat &ver return attribString; } -void DynamicHLSL::getInputLayoutSignature(const VertexFormat inputLayout[], GLenum signature[]) const +void DynamicHLSL::getPixelShaderOutputKey(const gl::Data &data, + const gl::Program::Data &programData, + const ProgramD3DMetadata &metadata, + std::vector *outPixelShaderKey) { - for (size_t inputIndex = 0; inputIndex < MAX_VERTEX_ATTRIBS; inputIndex++) - { - const VertexFormat &vertexFormat = inputLayout[inputIndex]; + // 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() ? data.caps->maxDrawBuffers : 1); - if (vertexFormat.mType == GL_NONE) + if (metadata.getMajorShaderVersion() < 300) + { + for (unsigned int renderTargetIndex = 0; renderTargetIndex < numRenderTargets; + renderTargetIndex++) { - signature[inputIndex] = GL_NONE; + PixelShaderOutputVariable outputKeyVariable; + outputKeyVariable.type = GL_FLOAT_VEC4; + outputKeyVariable.name = "gl_Color" + Str(renderTargetIndex); + outputKeyVariable.source = + broadcast ? "gl_Color[0]" : "gl_Color[" + Str(renderTargetIndex) + "]"; + outputKeyVariable.outputIndex = renderTargetIndex; + + outPixelShaderKey->push_back(outputKeyVariable); } - else + } + else + { + const auto &shaderOutputVars = + metadata.getFragmentShader()->getData().getActiveOutputVariables(); + + for (auto outputPair : programData.getOutputVariables()) { - bool gpuConverted = ((mRenderer->getVertexConversionType(vertexFormat) & VERTEX_CONVERT_GPU) != 0); - signature[inputIndex] = (gpuConverted ? GL_TRUE : GL_FALSE); + const VariableLocation &outputLocation = outputPair.second; + const sh::ShaderVariable &outputVariable = shaderOutputVars[outputLocation.index]; + const std::string &variableName = "out_" + outputLocation.name; + const std::string &elementString = + (outputLocation.element == GL_INVALID_INDEX ? "" : Str(outputLocation.element)); + + ASSERT(outputVariable.staticUse); + + PixelShaderOutputVariable outputKeyVariable; + outputKeyVariable.type = outputVariable.type; + outputKeyVariable.name = variableName + elementString; + outputKeyVariable.source = variableName + ArrayString(outputLocation.element); + outputKeyVariable.outputIndex = outputPair.first; + + outPixelShaderKey->push_back(outputKeyVariable); } } } -} +} // namespace rx diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/DynamicHLSL.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/DynamicHLSL.h index ea5ceb97a8af..69d941c06a06 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/DynamicHLSL.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/DynamicHLSL.h @@ -9,13 +9,15 @@ #ifndef LIBANGLE_RENDERER_D3D_DYNAMICHLSL_H_ #define LIBANGLE_RENDERER_D3D_DYNAMICHLSL_H_ -#include "common/angleutils.h" -#include "libANGLE/Constants.h" +#include +#include #include "angle_gl.h" - -#include -#include +#include "common/angleutils.h" +#include "libANGLE/Constants.h" +#include "libANGLE/Program.h" +#include "libANGLE/formatutils.h" +#include "libANGLE/renderer/d3d/RendererD3D.h" namespace sh { @@ -27,19 +29,16 @@ namespace gl { class InfoLog; struct VariableLocation; -struct LinkedVarying; struct VertexAttribute; -struct VertexFormat; -struct PackedVarying; struct Data; } namespace rx { -class RendererD3D; +struct PackedVarying; +class ProgramD3DMetadata; class ShaderD3D; - -typedef const gl::PackedVarying *VaryingPacking[gl::IMPLEMENTATION_MAX_VARYING_VECTORS][4]; +class VaryingPacking; struct PixelShaderOutputVariable { @@ -54,47 +53,52 @@ class DynamicHLSL : angle::NonCopyable public: explicit DynamicHLSL(RendererD3D *const renderer); - int packVaryings(gl::InfoLog &infoLog, VaryingPacking packing, ShaderD3D *fragmentShader, - ShaderD3D *vertexShader, const std::vector& transformFeedbackVaryings); - std::string generateVertexShaderForInputLayout(const std::string &sourceShader, - const gl::VertexFormat inputLayout[], - const std::vector &shaderAttributes) const; - std::string generatePixelShaderForOutputSignature(const std::string &sourceShader, const std::vector &outputVariables, - bool usesFragDepth, const std::vector &outputLayout) const; - bool generateShaderLinkHLSL(const gl::Data &data, gl::InfoLog &infoLog, int registers, - const VaryingPacking packing, - std::string &pixelHLSL, std::string &vertexHLSL, - ShaderD3D *fragmentShader, ShaderD3D *vertexShader, - const std::vector &transformFeedbackVaryings, - std::vector *linkedVaryings, - std::map *programOutputVars, - std::vector *outPixelShaderKey, - bool *outUsesFragDepth) const; - - std::string generateGeometryShaderHLSL(int registers, ShaderD3D *fragmentShader, ShaderD3D *vertexShader) const; - void getInputLayoutSignature(const gl::VertexFormat inputLayout[], GLenum signature[]) const; + std::string generateVertexShaderForInputLayout( + const std::string &sourceShader, + const gl::InputLayout &inputLayout, + const std::vector &shaderAttributes) const; + std::string generatePixelShaderForOutputSignature( + const std::string &sourceShader, + const std::vector &outputVariables, + bool usesFragDepth, + const std::vector &outputLayout) const; + bool generateShaderLinkHLSL(const gl::Data &data, + const gl::Program::Data &programData, + const ProgramD3DMetadata &programMetadata, + const VaryingPacking &varyingPacking, + std::string *pixelHLSL, + std::string *vertexHLSL) const; + + std::string generateGeometryShaderPreamble(const VaryingPacking &varyingPacking) const; + + std::string generateGeometryShaderHLSL(gl::PrimitiveType primitiveType, + const gl::Data &data, + const gl::Program::Data &programData, + const bool useViewScale, + const std::string &preambleString) const; + + void getPixelShaderOutputKey(const gl::Data &data, + const gl::Program::Data &programData, + const ProgramD3DMetadata &metadata, + std::vector *outPixelShaderKey); private: RendererD3D *const mRenderer; - struct SemanticInfo; - - std::string getVaryingSemantic(bool pointSize) const; - SemanticInfo getSemanticInfo(int startRegisters, bool position, bool fragCoord, bool pointCoord, - bool pointSize, bool pixelShader) const; - std::string generateVaryingLinkHLSL(const SemanticInfo &info, const std::string &varyingHLSL) const; - std::string generateVaryingHLSL(const ShaderD3D *shader) const; - void storeUserLinkedVaryings(const ShaderD3D *vertexShader, std::vector *linkedVaryings) const; - void storeBuiltinLinkedVaryings(const SemanticInfo &info, std::vector *linkedVaryings) const; - void defineOutputVariables(ShaderD3D *fragmentShader, std::map *programOutputVars) const; - std::string generatePointSpriteHLSL(int registers, ShaderD3D *fragmentShader, ShaderD3D *vertexShader) const; + void generateVaryingLinkHLSL(ShaderType shaderType, + const VaryingPacking &varyingPacking, + std::stringstream &linkStream) const; + void generateVaryingHLSL(const VaryingPacking &varyingPacking, + std::stringstream &hlslStream) const; // Prepend an underscore static std::string decorateVariable(const std::string &name); - std::string generateAttributeConversionHLSL(const gl::VertexFormat &vertexFormat, const sh::ShaderVariable &shaderAttrib) const; + std::string generateAttributeConversionHLSL(gl::VertexFormatType vertexFormatType, + const sh::ShaderVariable &shaderAttrib) const; }; +std::string GetVaryingSemantic(int majorShaderModel, bool programUsesPointSize); } -#endif // LIBANGLE_RENDERER_D3D_DYNAMICHLSL_H_ +#endif // LIBANGLE_RENDERER_D3D_DYNAMICHLSL_H_ diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/EGLImageD3D.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/EGLImageD3D.cpp new file mode 100644 index 000000000000..30cc4d5ff8a4 --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/EGLImageD3D.cpp @@ -0,0 +1,135 @@ +// +// Copyright (c) 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/Texture.h" +#include "libANGLE/renderer/d3d/RenderbufferD3D.h" +#include "libANGLE/renderer/d3d/RendererD3D.h" +#include "libANGLE/renderer/d3d/RenderTargetD3D.h" +#include "libANGLE/renderer/d3d/TextureD3D.h" +#include "libANGLE/renderer/d3d/TextureStorage.h" + +#include + +namespace rx +{ +static gl::ImageIndex GetImageIndex(GLenum target, size_t mip, size_t layer) +{ + if (target == GL_TEXTURE_3D) + { + return gl::ImageIndex::Make3D(static_cast(mip), static_cast(layer)); + } + else + { + ASSERT(layer == 0); + return gl::ImageIndex::MakeGeneric(target, static_cast(mip)); + } +} + +EGLImageD3D::EGLImageD3D(RendererD3D *renderer, + EGLenum target, + egl::ImageSibling *buffer, + const egl::AttributeMap &attribs) + : mRenderer(renderer), mBuffer(buffer), mAttachmentBuffer(nullptr), mRenderTarget(nullptr) +{ + ASSERT(renderer != nullptr); + ASSERT(buffer != nullptr); + + if (egl::IsTextureTarget(target)) + { + mAttachmentBuffer = GetImplAs(GetAs(buffer)); + mAttachmentTarget = gl::FramebufferAttachment::Target( + GL_NONE, GetImageIndex(egl_gl::EGLImageTargetToGLTextureTarget(target), + attribs.get(EGL_GL_TEXTURE_LEVEL_KHR, 0), + attribs.get(EGL_GL_TEXTURE_ZOFFSET_KHR, 0))); + } + else if (egl::IsRenderbufferTarget(target)) + { + mAttachmentBuffer = GetImplAs(GetAs(buffer)); + mAttachmentTarget = + gl::FramebufferAttachment::Target(GL_NONE, gl::ImageIndex::MakeInvalid()); + } + else + { + UNREACHABLE(); + } +} + +EGLImageD3D::~EGLImageD3D() +{ + SafeDelete(mRenderTarget); +} + +egl::Error EGLImageD3D::initialize() +{ + return egl::Error(EGL_SUCCESS); +} + +gl::Error EGLImageD3D::orphan(egl::ImageSibling *sibling) +{ + if (sibling == mBuffer) + { + gl::Error error = copyToLocalRendertarget(); + if (error.isError()) + { + return error; + } + } + + return gl::Error(GL_NO_ERROR); +} + +gl::Error EGLImageD3D::getRenderTarget(RenderTargetD3D **outRT) const +{ + if (mAttachmentBuffer) + { + FramebufferAttachmentRenderTarget *rt = nullptr; + gl::Error error = mAttachmentBuffer->getAttachmentRenderTarget(mAttachmentTarget, &rt); + if (error.isError()) + { + return error; + } + + *outRT = static_cast(rt); + return gl::Error(GL_NO_ERROR); + } + else + { + ASSERT(mRenderTarget); + *outRT = mRenderTarget; + return gl::Error(GL_NO_ERROR); + } +} + +gl::Error EGLImageD3D::copyToLocalRendertarget() +{ + ASSERT(mBuffer != nullptr); + ASSERT(mAttachmentBuffer != nullptr); + ASSERT(mRenderTarget == nullptr); + + RenderTargetD3D *curRenderTarget = nullptr; + gl::Error error = getRenderTarget(&curRenderTarget); + if (error.isError()) + { + return error; + } + + // This only currently applies do D3D11, where it invalidates FBOs with this Image attached. + curRenderTarget->signalDirty(); + + // Clear the source image buffers + mBuffer = nullptr; + mAttachmentBuffer = nullptr; + + return mRenderer->createRenderTargetCopy(curRenderTarget, &mRenderTarget); +} +} diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/EGLImageD3D.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/EGLImageD3D.h new file mode 100644 index 000000000000..6ec33e08f2cc --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/EGLImageD3D.h @@ -0,0 +1,56 @@ +// +// Copyright (c) 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/FramebufferAttachment.h" +#include "libANGLE/renderer/ImageImpl.h" + +namespace egl +{ +class AttributeMap; +} + +namespace rx +{ +class TextureD3D; +class RenderbufferD3D; +class RendererD3D; +class RenderTargetD3D; + +class EGLImageD3D final : public ImageImpl +{ + public: + EGLImageD3D(RendererD3D *renderer, + EGLenum target, + egl::ImageSibling *buffer, + const egl::AttributeMap &attribs); + ~EGLImageD3D() override; + + egl::Error initialize() override; + + gl::Error orphan(egl::ImageSibling *sibling) override; + + gl::Error getRenderTarget(RenderTargetD3D **outRT) const; + + private: + gl::Error copyToLocalRendertarget(); + + RendererD3D *mRenderer; + + egl::ImageSibling *mBuffer; + + gl::FramebufferAttachment::Target mAttachmentTarget; + FramebufferAttachmentObjectImpl *mAttachmentBuffer; + + RenderTargetD3D *mRenderTarget; +}; +} + +#endif // LIBANGLE_RENDERER_D3D_EGLIMAGED3D_H_ diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/FramebufferD3D.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/FramebufferD3D.cpp index 6e7b0ecedc66..82967aced0f0 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/FramebufferD3D.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/FramebufferD3D.cpp @@ -8,6 +8,7 @@ #include "libANGLE/renderer/d3d/FramebufferD3D.h" +#include "common/BitSetIterator.h" #include "libANGLE/formatutils.h" #include "libANGLE/Framebuffer.h" #include "libANGLE/FramebufferAttachment.h" @@ -53,7 +54,7 @@ ClearParameters GetClearParameters(const gl::State &state, GLbitfield mask) const gl::Framebuffer *framebufferObject = state.getDrawFramebuffer(); if (mask & GL_COLOR_BUFFER_BIT) { - if (framebufferObject->hasEnabledColorAttachment()) + if (framebufferObject->hasEnabledDrawBuffer()) { for (unsigned int i = 0; i < ArraySize(clearParams.clearColor); i++) { @@ -85,67 +86,28 @@ ClearParameters GetClearParameters(const gl::State &state, GLbitfield mask) } FramebufferD3D::FramebufferD3D(const gl::Framebuffer::Data &data, RendererD3D *renderer) - : FramebufferImpl(data), - mRenderer(renderer), - mColorAttachmentsForRender(mData.getColorAttachments().size(), nullptr), - mInvalidateColorAttachmentCache(true) + : FramebufferImpl(data), mRenderer(renderer) { - ASSERT(mRenderer != nullptr); } FramebufferD3D::~FramebufferD3D() { } -void FramebufferD3D::onUpdateColorAttachment(size_t /*index*/) -{ - mInvalidateColorAttachmentCache = true; -} - -void FramebufferD3D::onUpdateDepthAttachment() -{ -} - -void FramebufferD3D::onUpdateStencilAttachment() -{ -} - -void FramebufferD3D::onUpdateDepthStencilAttachment() -{ -} - -void FramebufferD3D::setDrawBuffers(size_t, const GLenum *) -{ - mInvalidateColorAttachmentCache = true; -} - -void FramebufferD3D::setReadBuffer(GLenum) -{ -} - -gl::Error FramebufferD3D::invalidate(size_t, const GLenum *) -{ - // No-op in D3D - return gl::Error(GL_NO_ERROR); -} - -gl::Error FramebufferD3D::invalidateSub(size_t, const GLenum *, const gl::Rectangle &) -{ - // No-op in D3D - return gl::Error(GL_NO_ERROR); -} - gl::Error FramebufferD3D::clear(const gl::Data &data, GLbitfield mask) { const gl::State &state = *data.state; ClearParameters clearParams = GetClearParameters(state, mask); - return clear(state, clearParams); + return clear(data, clearParams); } -gl::Error FramebufferD3D::clearBufferfv(const gl::State &state, GLenum buffer, GLint drawbuffer, const GLfloat *values) +gl::Error FramebufferD3D::clearBufferfv(const gl::Data &data, + GLenum buffer, + GLint drawbuffer, + const GLfloat *values) { // glClearBufferfv can be called to clear the color buffer or depth buffer - ClearParameters clearParams = GetClearParameters(state, 0); + ClearParameters clearParams = GetClearParameters(*data.state, 0); if (buffer == GL_COLOR) { @@ -163,13 +125,16 @@ gl::Error FramebufferD3D::clearBufferfv(const gl::State &state, GLenum buffer, G clearParams.depthClearValue = values[0]; } - return clear(state, clearParams); + return clear(data, clearParams); } -gl::Error FramebufferD3D::clearBufferuiv(const gl::State &state, GLenum buffer, GLint drawbuffer, const GLuint *values) +gl::Error FramebufferD3D::clearBufferuiv(const gl::Data &data, + GLenum buffer, + GLint drawbuffer, + const GLuint *values) { // glClearBufferuiv can only be called to clear a color buffer - ClearParameters clearParams = GetClearParameters(state, 0); + ClearParameters clearParams = GetClearParameters(*data.state, 0); for (unsigned int i = 0; i < ArraySize(clearParams.clearColor); i++) { clearParams.clearColor[i] = (drawbuffer == static_cast(i)); @@ -177,13 +142,16 @@ gl::Error FramebufferD3D::clearBufferuiv(const gl::State &state, GLenum buffer, clearParams.colorUIClearValue = gl::ColorUI(values[0], values[1], values[2], values[3]); clearParams.colorClearType = GL_UNSIGNED_INT; - return clear(state, clearParams); + return clear(data, clearParams); } -gl::Error FramebufferD3D::clearBufferiv(const gl::State &state, GLenum buffer, GLint drawbuffer, const GLint *values) +gl::Error FramebufferD3D::clearBufferiv(const gl::Data &data, + GLenum buffer, + GLint drawbuffer, + const GLint *values) { // glClearBufferiv can be called to clear the color buffer or stencil buffer - ClearParameters clearParams = GetClearParameters(state, 0); + ClearParameters clearParams = GetClearParameters(*data.state, 0); if (buffer == GL_COLOR) { @@ -201,19 +169,23 @@ gl::Error FramebufferD3D::clearBufferiv(const gl::State &state, GLenum buffer, G clearParams.stencilClearValue = values[1]; } - return clear(state, clearParams); + return clear(data, clearParams); } -gl::Error FramebufferD3D::clearBufferfi(const gl::State &state, GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil) +gl::Error FramebufferD3D::clearBufferfi(const gl::Data &data, + GLenum buffer, + GLint drawbuffer, + GLfloat depth, + GLint stencil) { // glClearBufferfi can only be called to clear a depth stencil buffer - ClearParameters clearParams = GetClearParameters(state, 0); + ClearParameters clearParams = GetClearParameters(*data.state, 0); clearParams.clearDepth = true; clearParams.depthClearValue = depth; clearParams.clearStencil = true; clearParams.stencilClearValue = stencil; - return clear(state, clearParams); + return clear(data, clearParams); } GLenum FramebufferD3D::getImplementationColorReadFormat() const @@ -264,17 +236,15 @@ gl::Error FramebufferD3D::readPixels(const gl::State &state, const gl::Rectangle { const gl::PixelPackState &packState = state.getPackState(); - if (packState.rowLength != 0 || packState.skipRows != 0 || packState.skipPixels != 0) - { - UNIMPLEMENTED(); - return gl::Error(GL_INVALID_OPERATION, "invalid pixel store parameters in readPixels"); - } - GLenum sizedInternalFormat = gl::GetSizedInternalFormat(format, type); const gl::InternalFormat &sizedFormatInfo = gl::GetInternalFormatInfo(sizedInternalFormat); - GLuint outputPitch = sizedFormatInfo.computeRowPitch(type, area.width, packState.alignment, 0); + GLuint outputPitch = + sizedFormatInfo.computeRowPitch(type, area.width, packState.alignment, packState.rowLength); + GLsizei outputSkipBytes = sizedFormatInfo.computeSkipPixels( + outputPitch, 0, 0, packState.skipRows, packState.skipPixels); - return readPixels(area, format, type, outputPitch, packState, reinterpret_cast(pixels)); + return readPixelsImpl(area, format, type, outputPitch, packState, + reinterpret_cast(pixels) + outputSkipBytes); } gl::Error FramebufferD3D::blit(const gl::State &state, const gl::Rectangle &sourceArea, const gl::Rectangle &destArea, @@ -318,8 +288,16 @@ gl::Error FramebufferD3D::blit(const gl::State &state, const gl::Rectangle &sour return gl::Error(GL_NO_ERROR); } -GLenum FramebufferD3D::checkStatus() const +bool FramebufferD3D::checkStatus() 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 (mData.getDepthAttachment() != nullptr && mData.getStencilAttachment() != nullptr && + mData.getDepthStencilAttachment() == nullptr) + { + return false; + } + // D3D11 does not allow for overlapping RenderTargetViews, so ensure uniqueness const auto &colorAttachments = mData.getColorAttachments(); for (size_t colorAttachment = 0; colorAttachment < colorAttachments.size(); colorAttachment++) @@ -334,27 +312,51 @@ GLenum FramebufferD3D::checkStatus() const (attachment.id() == prevAttachment.id() && attachment.type() == prevAttachment.type())) { - return GL_FRAMEBUFFER_UNSUPPORTED; + return false; } } } } - return GL_FRAMEBUFFER_COMPLETE; + // D3D requires all render targets to have the same dimensions. + if (!mData.attachmentsHaveSameDimensions()) + { + return false; + } + + return true; } -const gl::AttachmentList &FramebufferD3D::getColorAttachmentsForRender(const Workarounds &workarounds) const +void FramebufferD3D::syncState(const gl::Framebuffer::DirtyBits &dirtyBits) { - if (!mInvalidateColorAttachmentCache) + bool invalidateColorAttachmentCache = false; + + if (!mColorAttachmentsForRender.valid()) + { + invalidateColorAttachmentCache = true; + } + + for (auto dirtyBit : angle::IterateBitSet(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) + { + invalidateColorAttachmentCache = true; + } + } + + if (!invalidateColorAttachmentCache) { - return mColorAttachmentsForRender; + return; } // Does not actually free memory - mColorAttachmentsForRender.clear(); + gl::AttachmentList colorAttachmentsForRender; const auto &colorAttachments = mData.getColorAttachments(); const auto &drawBufferStates = mData.getDrawBufferStates(); + const auto &workarounds = mRenderer->getWorkarounds(); for (size_t attachmentIndex = 0; attachmentIndex < colorAttachments.size(); ++attachmentIndex) { @@ -364,57 +366,21 @@ const gl::AttachmentList &FramebufferD3D::getColorAttachmentsForRender(const Wor if (colorAttachment.isAttached() && drawBufferState != GL_NONE) { ASSERT(drawBufferState == GL_BACK || drawBufferState == (GL_COLOR_ATTACHMENT0_EXT + attachmentIndex)); - mColorAttachmentsForRender.push_back(&colorAttachment); + colorAttachmentsForRender.push_back(&colorAttachment); } else if (!workarounds.mrtPerfWorkaround) { - mColorAttachmentsForRender.push_back(nullptr); + colorAttachmentsForRender.push_back(nullptr); } } - mInvalidateColorAttachmentCache = false; - return mColorAttachmentsForRender; + mColorAttachmentsForRender = std::move(colorAttachmentsForRender); } -// Note: RenderTarget serials should ideally be in the RenderTargets themselves. -unsigned int GetAttachmentSerial(const gl::FramebufferAttachment *attachment) +const gl::AttachmentList &FramebufferD3D::getColorAttachmentsForRender() const { - if (attachment->type() == GL_TEXTURE) - { - gl::Texture *texture = attachment->getTexture(); - ASSERT(texture); - TextureD3D *textureD3D = GetImplAs(texture); - const gl::ImageIndex &index = attachment->getTextureImageIndex(); - return textureD3D->getRenderTargetSerial(index); - } - else if (attachment->type() == GL_RENDERBUFFER) - { - gl::Renderbuffer *renderbuffer = attachment->getRenderbuffer(); - ASSERT(renderbuffer); - RenderbufferD3D *renderbufferD3D = GetImplAs(renderbuffer); - return renderbufferD3D->getRenderTargetSerial(); - } - else if (attachment->type() == GL_FRAMEBUFFER_DEFAULT) - { - const egl::Surface *surface = attachment->getSurface(); - ASSERT(surface); - const SurfaceD3D *surfaceD3D = GetImplAs(surface); - ASSERT(surfaceD3D); - - if (attachment->getBinding() == GL_BACK) - { - return surfaceD3D->getSwapChain()->getColorRenderTarget()->getSerial(); - } - else - { - return surfaceD3D->getSwapChain()->getDepthStencilRenderTarget()->getSerial(); - } - } - else - { - UNREACHABLE(); - return 0; - } + ASSERT(mColorAttachmentsForRender.valid()); + return mColorAttachmentsForRender.value(); } -} +} // namespace rx diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/FramebufferD3D.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/FramebufferD3D.h index 7bf71dae140f..eb839c4364c0 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/FramebufferD3D.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/FramebufferD3D.h @@ -12,6 +12,7 @@ #include #include +#include "common/Optional.h" #include "libANGLE/angletypes.h" #include "libANGLE/renderer/FramebufferImpl.h" @@ -26,8 +27,9 @@ typedef std::vector AttachmentList; namespace rx { -class RenderTargetD3D; class RendererD3D; +class RenderTargetD3D; +struct WorkaroundsD3D; struct ClearParameters { @@ -58,22 +60,24 @@ class FramebufferD3D : public FramebufferImpl FramebufferD3D(const gl::Framebuffer::Data &data, RendererD3D *renderer); virtual ~FramebufferD3D(); - void onUpdateColorAttachment(size_t index) override; - void onUpdateDepthAttachment() override; - void onUpdateStencilAttachment() override; - void onUpdateDepthStencilAttachment() override; - - void setDrawBuffers(size_t count, const GLenum *buffers) override; - void setReadBuffer(GLenum buffer) override; - - gl::Error invalidate(size_t count, const GLenum *attachments) override; - gl::Error invalidateSub(size_t count, const GLenum *attachments, const gl::Rectangle &area) override; - gl::Error clear(const gl::Data &data, GLbitfield mask) override; - gl::Error clearBufferfv(const gl::State &state, GLenum buffer, GLint drawbuffer, const GLfloat *values) override; - gl::Error clearBufferuiv(const gl::State &state, GLenum buffer, GLint drawbuffer, const GLuint *values) override; - gl::Error clearBufferiv(const gl::State &state, GLenum buffer, GLint drawbuffer, const GLint *values) override; - gl::Error clearBufferfi(const gl::State &state, GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil) override; + gl::Error clearBufferfv(const gl::Data &data, + GLenum buffer, + GLint drawbuffer, + const GLfloat *values) override; + gl::Error clearBufferuiv(const gl::Data &data, + GLenum buffer, + GLint drawbuffer, + const GLuint *values) override; + gl::Error clearBufferiv(const gl::Data &data, + GLenum buffer, + GLint drawbuffer, + const GLint *values) override; + gl::Error clearBufferfi(const gl::Data &data, + GLenum buffer, + GLint drawbuffer, + GLfloat depth, + GLint stencil) override; GLenum getImplementationColorReadFormat() const override; GLenum getImplementationColorReadType() const override; @@ -82,31 +86,31 @@ class FramebufferD3D : public FramebufferImpl gl::Error blit(const gl::State &state, const gl::Rectangle &sourceArea, const gl::Rectangle &destArea, GLbitfield mask, GLenum filter, const gl::Framebuffer *sourceFramebuffer) override; - GLenum checkStatus() const override; + bool checkStatus() const override; - const gl::AttachmentList &getColorAttachmentsForRender(const Workarounds &workarounds) const; + void syncState(const gl::Framebuffer::DirtyBits &dirtyBits) override; - protected: - // Cache variable - mutable gl::AttachmentList mColorAttachmentsForRender; - mutable bool mInvalidateColorAttachmentCache; + const gl::AttachmentList &getColorAttachmentsForRender() const; private: - RendererD3D *const mRenderer; - - virtual gl::Error clear(const gl::State &state, const ClearParameters &clearParams) = 0; + virtual gl::Error clear(const gl::Data &data, const ClearParameters &clearParams) = 0; - virtual gl::Error readPixels(const gl::Rectangle &area, GLenum format, GLenum type, size_t outputPitch, - const gl::PixelPackState &pack, uint8_t *pixels) const = 0; + virtual gl::Error readPixelsImpl(const gl::Rectangle &area, + GLenum format, + GLenum type, + size_t outputPitch, + const gl::PixelPackState &pack, + uint8_t *pixels) const = 0; virtual gl::Error blit(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; virtual GLenum getRenderTargetImplementationFormat(RenderTargetD3D *renderTarget) const = 0; -}; -unsigned int GetAttachmentSerial(const gl::FramebufferAttachment *attachment); + RendererD3D *mRenderer; + Optional mColorAttachmentsForRender; +}; } diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/HLSLCompiler.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/HLSLCompiler.cpp index 996b9dea5d37..e8b1af312918 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/HLSLCompiler.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/HLSLCompiler.cpp @@ -5,17 +5,16 @@ // #include "libANGLE/renderer/d3d/HLSLCompiler.h" -#include "libANGLE/Program.h" -#include "libANGLE/features.h" #include "common/utilities.h" - +#include "libANGLE/Program.h" +#include "libANGLE/features.h" +#include "libANGLE/histogram_macros.h" #include "third_party/trace_event/trace_event.h" -// Definitions local to the translation unit +#if ANGLE_APPEND_ASSEMBLY_TO_SHADER_DEBUG_INFO == ANGLE_ENABLED namespace { - #ifdef CREATE_COMPILER_FLAG_INFO #undef CREATE_COMPILER_FLAG_INFO #endif @@ -76,19 +75,8 @@ bool IsCompilerFlagSet(UINT mask, UINT flag) return isFlagSet; } } - -const char *GetCompilerFlagName(UINT mask, size_t flagIx) -{ - const CompilerFlagInfo &flagInfo = CompilerFlagInfos[flagIx]; - if (IsCompilerFlagSet(mask, flagInfo.mFlag)) - { - return flagInfo.mName; - } - - return nullptr; -} - -} +} // anonymous namespace +#endif // ANGLE_APPEND_ASSEMBLY_TO_SHADER_DEBUG_INFO == ANGLE_ENABLED namespace rx { @@ -106,9 +94,10 @@ CompileConfig::CompileConfig(UINT flags, const std::string &name) } HLSLCompiler::HLSLCompiler() - : mD3DCompilerModule(NULL), - mD3DCompileFunc(NULL), - mD3DDisassembleFunc(NULL) + : mInitialized(false), + mD3DCompilerModule(nullptr), + mD3DCompileFunc(nullptr), + mD3DDisassembleFunc(nullptr) { } @@ -117,8 +106,13 @@ HLSLCompiler::~HLSLCompiler() release(); } -bool HLSLCompiler::initialize() +gl::Error HLSLCompiler::initialize() { + if (mInitialized) + { + return gl::Error(GL_NO_ERROR); + } + TRACE_EVENT0("gpu.angle", "HLSLCompiler::initialize"); #if !defined(ANGLE_ENABLE_WINDOWS_STORE) #if defined(ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES) @@ -142,8 +136,7 @@ bool HLSLCompiler::initialize() if (!mD3DCompilerModule) { - ERR("No D3D compiler module found - aborting!\n"); - return false; + return gl::Error(GL_INVALID_OPERATION, "No D3D compiler module found - aborting!\n"); } mD3DCompileFunc = reinterpret_cast(GetProcAddress(mD3DCompilerModule, "D3DCompile")); @@ -155,29 +148,42 @@ bool HLSLCompiler::initialize() #else // D3D Shader compiler is linked already into this module, so the export // can be directly assigned. - mD3DCompilerModule = NULL; + mD3DCompilerModule = nullptr; mD3DCompileFunc = reinterpret_cast(D3DCompile); mD3DDisassembleFunc = reinterpret_cast(D3DDisassemble); #endif - return mD3DCompileFunc != NULL; + if (mD3DCompileFunc == nullptr) + { + return gl::Error(GL_INVALID_OPERATION, "Error finding D3DCompile entry point"); + } + + mInitialized = true; + return gl::Error(GL_NO_ERROR); } void HLSLCompiler::release() { - if (mD3DCompilerModule) + if (mInitialized) { FreeLibrary(mD3DCompilerModule); - mD3DCompilerModule = NULL; - mD3DCompileFunc = NULL; - mD3DDisassembleFunc = NULL; + mD3DCompilerModule = nullptr; + mD3DCompileFunc = nullptr; + mD3DDisassembleFunc = nullptr; + mInitialized = false; } } gl::Error HLSLCompiler::compileToBinary(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) const + ID3DBlob **outCompiledBlob, std::string *outDebugInfo) { + gl::Error error = initialize(); + if (error.isError()) + { + return error; + } + #if !defined(ANGLE_ENABLE_WINDOWS_STORE) ASSERT(mD3DCompilerModule); #endif @@ -192,15 +198,21 @@ gl::Error HLSLCompiler::compileToBinary(gl::InfoLog &infoLog, const std::string } #endif - const D3D_SHADER_MACRO *macros = overrideMacros ? overrideMacros : NULL; + const D3D_SHADER_MACRO *macros = overrideMacros ? overrideMacros : nullptr; for (size_t i = 0; i < configs.size(); ++i) { - ID3DBlob *errorMessage = NULL; - ID3DBlob *binary = NULL; + ID3DBlob *errorMessage = nullptr; + ID3DBlob *binary = nullptr; + HRESULT result = S_OK; - HRESULT result = mD3DCompileFunc(hlsl.c_str(), hlsl.length(), gl::g_fakepath, macros, NULL, "main", profile.c_str(), - configs[i].flags, 0, &binary, &errorMessage); + { + TRACE_EVENT0("gpu.angle", "D3DCompile"); + SCOPED_ANGLE_HISTOGRAM_TIMER("GPU.ANGLE.D3DCompileMS"); + result = mD3DCompileFunc(hlsl.c_str(), hlsl.length(), gl::g_fakepath, macros, nullptr, + "main", profile.c_str(), configs[i].flags, 0, &binary, + &errorMessage); + } if (errorMessage) { @@ -211,13 +223,14 @@ gl::Error HLSLCompiler::compileToBinary(gl::InfoLog &infoLog, const std::string TRACE("\n%s", hlsl.c_str()); TRACE("\n%s", message.c_str()); - if (message.find("error X3531:") != std::string::npos || // "can't unroll loops marked with loop attribute" - message.find("error X4014:") != std::string::npos) // "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. + if ((message.find("error X3531:") != std::string::npos || // "can't unroll loops marked with loop attribute" + message.find("error X4014:") != std::string::npos) && // "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. + macros != nullptr) { - macros = NULL; // Disable [loop] and [flatten] + macros = nullptr; // Disable [loop] and [flatten] // Retry without changing compiler flags i--; @@ -229,16 +242,16 @@ gl::Error HLSLCompiler::compileToBinary(gl::InfoLog &infoLog, const std::string { *outCompiledBlob = binary; -#if ANGLE_SHADER_DEBUG_INFO == ANGLE_ENABLED (*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) { - const char *flagName = GetCompilerFlagName(configs[i].flags, fIx); - if (flagName != nullptr) + if (IsCompilerFlagSet(configs[i].flags, CompilerFlagInfos[fIx].mFlag)) { - (*outDebugInfo) += std::string("// ") + flagName + "\n"; + (*outDebugInfo) += std::string("// ") + CompilerFlagInfos[fIx].mName + "\n"; } } @@ -255,52 +268,65 @@ gl::Error HLSLCompiler::compileToBinary(gl::InfoLog &infoLog, const std::string } } - (*outDebugInfo) += "\n" + disassembleBinary(binary) + "\n// ASSEMBLY END\n"; -#endif - + std::string disassembly; + error = disassembleBinary(binary, &disassembly); + if (error.isError()) + { + return error; + } + (*outDebugInfo) += "\n" + disassembly + "\n// ASSEMBLY END\n"; +#endif // ANGLE_APPEND_ASSEMBLY_TO_SHADER_DEBUG_INFO == ANGLE_ENABLED return gl::Error(GL_NO_ERROR); } - else + + if (result == E_OUTOFMEMORY) { - if (result == E_OUTOFMEMORY) - { - *outCompiledBlob = NULL; - return gl::Error(GL_OUT_OF_MEMORY, "HLSL compiler had an unexpected failure, result: 0x%X.", result); - } + *outCompiledBlob = nullptr; + return gl::Error(GL_OUT_OF_MEMORY, "HLSL compiler had an unexpected failure, result: 0x%X.", result); + } - infoLog.append("Warning: D3D shader compilation failed with %s flags.", configs[i].name.c_str()); + infoLog << "Warning: D3D shader compilation failed with " << configs[i].name << " flags. (" + << profile << ")"; - if (i + 1 < configs.size()) - { - infoLog.append(" Retrying with %s.\n", configs[i + 1].name.c_str()); - } + 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 = NULL; + *outCompiledBlob = nullptr; return gl::Error(GL_NO_ERROR); } -std::string HLSLCompiler::disassembleBinary(ID3DBlob *shaderBinary) const +gl::Error HLSLCompiler::disassembleBinary(ID3DBlob *shaderBinary, std::string *disassemblyOut) { + gl::Error error = initialize(); + if (error.isError()) + { + return error; + } + // Retrieve disassembly UINT flags = D3D_DISASM_ENABLE_DEFAULT_VALUE_PRINTS | D3D_DISASM_ENABLE_INSTRUCTION_NUMBERING; - ID3DBlob *disassembly = NULL; + ID3DBlob *disassembly = nullptr; pD3DDisassemble disassembleFunc = reinterpret_cast(mD3DDisassembleFunc); LPCVOID buffer = shaderBinary->GetBufferPointer(); SIZE_T bufSize = shaderBinary->GetBufferSize(); HRESULT result = disassembleFunc(buffer, bufSize, flags, "", &disassembly); - std::string asmSrc; if (SUCCEEDED(result)) { - asmSrc = reinterpret_cast(disassembly->GetBufferPointer()); + *disassemblyOut = std::string(reinterpret_cast(disassembly->GetBufferPointer())); + } + else + { + *disassemblyOut = ""; } SafeRelease(disassembly); - return asmSrc; + return gl::Error(GL_NO_ERROR); } -} +} // namespace rx diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/HLSLCompiler.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/HLSLCompiler.h index a82495255363..3c0d2adcacf6 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/HLSLCompiler.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/HLSLCompiler.h @@ -32,18 +32,20 @@ class HLSLCompiler : angle::NonCopyable HLSLCompiler(); ~HLSLCompiler(); - bool initialize(); 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. gl::Error compileToBinary(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) const; + ID3DBlob **outCompiledBlob, std::string *outDebugInfo); - std::string disassembleBinary(ID3DBlob* shaderBinary) const; + gl::Error disassembleBinary(ID3DBlob *shaderBinary, std::string *disassemblyOut); private: + gl::Error initialize(); + + bool mInitialized; HMODULE mD3DCompilerModule; pD3DCompile mD3DCompileFunc; pD3DDisassemble mD3DDisassembleFunc; diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/ImageD3D.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/ImageD3D.cpp index f323910a98ca..ead5db645356 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/ImageD3D.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/ImageD3D.cpp @@ -23,26 +23,10 @@ ImageD3D::ImageD3D() mHeight(0), mDepth(0), mInternalFormat(GL_NONE), - mTarget(GL_NONE), mRenderable(false), + mTarget(GL_NONE), mDirty(false) { } -gl::Error ImageD3D::copy(const gl::Offset &destOffset, const gl::Rectangle &sourceArea, const gl::Framebuffer *source) -{ - const gl::FramebufferAttachment *srcAttachment = source->getReadColorbuffer(); - ASSERT(srcAttachment); - - RenderTargetD3D *renderTarget = NULL; - gl::Error error = srcAttachment->getRenderTarget(&renderTarget); - if (error.isError()) - { - return error; - } - - ASSERT(renderTarget); - return copy(destOffset, sourceArea, renderTarget); -} - -} +} // namespace rx diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/ImageD3D.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/ImageD3D.h index 0fe88a8f5974..2afe1cfabf5f 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/ImageD3D.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/ImageD3D.h @@ -60,10 +60,11 @@ class ImageD3D : angle::NonCopyable virtual gl::Error setManagedSurface2DArray(TextureStorage *storage, int layer, int level) { return gl::Error(GL_NO_ERROR); }; virtual gl::Error copyToStorage(TextureStorage *storage, const gl::ImageIndex &index, const gl::Box ®ion) = 0; - virtual gl::Error copy(const gl::Offset &destOffset, const gl::Box &sourceArea, - const gl::ImageIndex &sourceIndex, TextureStorage *source) = 0; - - gl::Error copy(const gl::Offset &destOffset, const gl::Rectangle &sourceArea, const gl::Framebuffer *source); + virtual gl::Error copyFromTexStorage(const gl::ImageIndex &imageIndex, + TextureStorage *source) = 0; + virtual gl::Error copyFromFramebuffer(const gl::Offset &destOffset, + const gl::Rectangle &sourceArea, + const gl::Framebuffer *source) = 0; protected: GLsizei mWidth; @@ -74,9 +75,6 @@ class ImageD3D : angle::NonCopyable GLenum mTarget; bool mDirty; - - private: - virtual gl::Error copy(const gl::Offset &destOffset, const gl::Rectangle &sourceArea, RenderTargetD3D *source) = 0; }; } diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/IndexBuffer.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/IndexBuffer.h index 36262f1d092d..0b7b28ddf0d1 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/IndexBuffer.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/IndexBuffer.h @@ -12,7 +12,6 @@ #include "common/angleutils.h" #include "libANGLE/Error.h" -#include "libANGLE/renderer/IndexRangeCache.h" namespace rx { diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/IndexDataManager.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/IndexDataManager.cpp index 7c68c1c5dd00..474c77fce446 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/IndexDataManager.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/IndexDataManager.cpp @@ -8,6 +8,8 @@ // runs the Buffer translation process for index buffers. #include "libANGLE/renderer/d3d/IndexDataManager.h" + +#include "common/utilities.h" #include "libANGLE/renderer/d3d/BufferD3D.h" #include "libANGLE/renderer/d3d/IndexBuffer.h" #include "libANGLE/Buffer.h" @@ -16,45 +18,111 @@ namespace rx { -static void ConvertIndices(GLenum sourceType, GLenum destinationType, const void *input, GLsizei count, void *output) +namespace { - if (sourceType == GL_UNSIGNED_BYTE) - { - ASSERT(destinationType == GL_UNSIGNED_SHORT); - const GLubyte *in = static_cast(input); - GLushort *out = static_cast(output); +template +void ConvertIndexArray(const void *input, + GLenum sourceType, + void *output, + GLenum 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]; + out[i] = (in[i] == srcRestartIndex ? destRestartIndex : static_cast(in[i])); } } - else if (sourceType == GL_UNSIGNED_INT) - { - ASSERT(destinationType == GL_UNSIGNED_INT); - memcpy(output, input, count * sizeof(GLuint)); - } - else if (sourceType == GL_UNSIGNED_SHORT) + else { - if (destinationType == GL_UNSIGNED_SHORT) + for (GLsizei i = 0; i < count; i++) { - memcpy(output, input, count * sizeof(GLushort)); + out[i] = static_cast(in[i]); } - else if (destinationType == GL_UNSIGNED_INT) - { - const GLushort *in = static_cast(input); - GLuint *out = static_cast(output); + } +} - for (GLsizei i = 0; i < count; i++) - { - out[i] = in[i]; - } - } - else UNREACHABLE(); +void ConvertIndices(GLenum sourceType, + GLenum destinationType, + const void *input, + GLsizei count, + void *output, + bool usePrimitiveRestartFixedIndex) +{ + if (sourceType == destinationType) + { + const gl::Type &typeInfo = gl::GetTypeInfo(destinationType); + memcpy(output, input, count * typeInfo.bytes); + return; + } + + if (sourceType == GL_UNSIGNED_BYTE) + { + ASSERT(destinationType == GL_UNSIGNED_SHORT); + ConvertIndexArray(input, sourceType, output, destinationType, count, + usePrimitiveRestartFixedIndex); + } + else if (sourceType == GL_UNSIGNED_SHORT) + { + ASSERT(destinationType == GL_UNSIGNED_INT); + ConvertIndexArray(input, sourceType, output, destinationType, count, + usePrimitiveRestartFixedIndex); } else UNREACHABLE(); } +gl::Error StreamInIndexBuffer(IndexBufferInterface *buffer, + const GLvoid *data, + unsigned int count, + GLenum srcType, + GLenum dstType, + bool usePrimitiveRestartFixedIndex, + unsigned int *offset) +{ + const gl::Type &dstTypeInfo = gl::GetTypeInfo(dstType); + + if (count > (std::numeric_limits::max() >> dstTypeInfo.bytesShift)) + { + return gl::Error(GL_OUT_OF_MEMORY, + "Reserving %u indices of %u bytes each exceeds the maximum buffer size.", + count, dstTypeInfo.bytes); + } + + unsigned int bufferSizeRequired = count << dstTypeInfo.bytesShift; + gl::Error error = buffer->reserveBufferSpace(bufferSizeRequired, dstType); + if (error.isError()) + { + return error; + } + + void *output = nullptr; + error = buffer->mapBuffer(bufferSizeRequired, &output, offset); + if (error.isError()) + { + return error; + } + + ConvertIndices(srcType, dstType, data, count, output, usePrimitiveRestartFixedIndex); + + error = buffer->unmapBuffer(); + if (error.isError()) + { + return error; + } + + return gl::Error(GL_NO_ERROR); +} + +} // anonymous namespace + IndexDataManager::IndexDataManager(BufferFactoryD3D *factory, RendererClass rendererClass) : mFactory(factory), mRendererClass(rendererClass), @@ -69,169 +137,180 @@ IndexDataManager::~IndexDataManager() SafeDelete(mStreamingBufferInt); } -gl::Error IndexDataManager::prepareIndexData(GLenum type, GLsizei count, gl::Buffer *buffer, const GLvoid *indices, TranslatedIndexData *translated) +// 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. +gl::Error IndexDataManager::prepareIndexData(GLenum srcType, + GLsizei count, + gl::Buffer *glBuffer, + const GLvoid *indices, + TranslatedIndexData *translated, + bool primitiveRestartFixedIndexEnabled) { - const gl::Type &typeInfo = gl::GetTypeInfo(type); + // Avoid D3D11's primitive restart index value + // see http://msdn.microsoft.com/en-us/library/windows/desktop/bb205124(v=vs.85).aspx + bool hasPrimitiveRestartIndex = + translated->indexRange.vertexIndexCount < static_cast(count) || + translated->indexRange.end == gl::GetPrimitiveRestartIndex(srcType); + bool primitiveRestartWorkaround = mRendererClass == RENDERER_D3D11 && + !primitiveRestartFixedIndexEnabled && + hasPrimitiveRestartIndex && srcType == GL_UNSIGNED_SHORT; - GLenum destinationIndexType = (type == GL_UNSIGNED_INT) ? GL_UNSIGNED_INT : GL_UNSIGNED_SHORT; + // We should never have to deal with MAX_UINT indices, since we restrict it via + // MAX_ELEMENT_INDEX. + ASSERT(!(mRendererClass == RENDERER_D3D11 && !primitiveRestartFixedIndexEnabled && + hasPrimitiveRestartIndex && srcType == GL_UNSIGNED_INT)); - unsigned int offset = 0; - bool alignedOffset = false; + const GLenum dstType = (srcType == GL_UNSIGNED_INT || primitiveRestartWorkaround) ? + GL_UNSIGNED_INT : GL_UNSIGNED_SHORT; - BufferD3D *storage = NULL; + const gl::Type &srcTypeInfo = gl::GetTypeInfo(srcType); + const gl::Type &dstTypeInfo = gl::GetTypeInfo(dstType); - if (buffer != NULL) - { - offset = static_cast(reinterpret_cast(indices)); + BufferD3D *buffer = glBuffer ? GetImplAs(glBuffer) : nullptr; - storage = GetImplAs(buffer); + translated->indexType = dstType; + translated->srcIndexData.srcBuffer = buffer; + translated->srcIndexData.srcIndices = indices; + translated->srcIndexData.srcIndexType = srcType; + translated->srcIndexData.srcCount = count; - // We'll trust that the compiler will optimize the % below: - // the operands are unsigned and the divisor is a constant. - switch (type) - { - case GL_UNSIGNED_BYTE: alignedOffset = (offset % sizeof(GLubyte) == 0); break; - case GL_UNSIGNED_SHORT: alignedOffset = (offset % sizeof(GLushort) == 0); break; - case GL_UNSIGNED_INT: alignedOffset = (offset % sizeof(GLuint) == 0); break; - default: UNREACHABLE(); alignedOffset = false; - } - - ASSERT(typeInfo.bytes * static_cast(count) + offset <= storage->getSize()); - - const uint8_t *bufferData = NULL; - gl::Error error = storage->getData(&bufferData); - if (error.isError()) - { - return error; - } - - indices = bufferData + offset; + // Case 1: the indices are passed by pointer, which forces the streaming of index data + if (glBuffer == nullptr) + { + translated->storage = nullptr; + return streamIndexData(indices, count, srcType, dstType, primitiveRestartFixedIndexEnabled, + translated); } - StaticIndexBufferInterface *staticBuffer = storage ? storage->getStaticIndexBuffer() : NULL; - IndexBufferInterface *indexBuffer = NULL; - bool directStorage = alignedOffset && storage && storage->supportsDirectBinding() && - destinationIndexType == type; - unsigned int streamOffset = 0; + // Case 2: the indices are already in a buffer + unsigned int offset = static_cast(reinterpret_cast(indices)); + ASSERT(srcTypeInfo.bytes * static_cast(count) + offset <= buffer->getSize()); - // Avoid D3D11's primitive restart index value - // see http://msdn.microsoft.com/en-us/library/windows/desktop/bb205124(v=vs.85).aspx - bool primitiveRestartWorkaround = mRendererClass == RENDERER_D3D11 && - translated->indexRange.end == 0xFFFF && - type == GL_UNSIGNED_SHORT; - - if (primitiveRestartWorkaround) + bool offsetAligned; + switch (srcType) { - destinationIndexType = GL_UNSIGNED_INT; - directStorage = false; + case GL_UNSIGNED_BYTE: offsetAligned = (offset % sizeof(GLubyte) == 0); break; + case GL_UNSIGNED_SHORT: offsetAligned = (offset % sizeof(GLushort) == 0); break; + case GL_UNSIGNED_INT: offsetAligned = (offset % sizeof(GLuint) == 0); break; + default: UNREACHABLE(); offsetAligned = false; } - const gl::Type &destTypeInfo = gl::GetTypeInfo(destinationIndexType); - - if (directStorage) + // Case 2a: the buffer can be used directly + if (offsetAligned && buffer->supportsDirectBinding() && + dstType == srcType && !primitiveRestartWorkaround) { - streamOffset = offset; + translated->storage = buffer; + translated->indexBuffer = nullptr; + translated->serial = buffer->getSerial(); + translated->startIndex = (offset >> srcTypeInfo.bytesShift); + translated->startOffset = offset; + return gl::Error(GL_NO_ERROR); } - else if (staticBuffer && - staticBuffer->getBufferSize() != 0 && - alignedOffset && - staticBuffer->getIndexType() == destinationIndexType) + else { - indexBuffer = staticBuffer; - - // Using bit-shift here is faster than using division. - streamOffset = (offset >> typeInfo.bytesShift) << destTypeInfo.bytesShift; + translated->storage = nullptr; } - if (!directStorage && !indexBuffer) - { - gl::Error error = getStreamingIndexBuffer(destinationIndexType, &indexBuffer); - if (error.isError()) - { - return error; - } - - unsigned int convertCount = count; - - if (staticBuffer) - { - if (staticBuffer->getBufferSize() == 0 && alignedOffset) - { - indexBuffer = staticBuffer; - // Using bit-shift here is faster than using division. - convertCount = storage->getSize() >> typeInfo.bytesShift; - } - else - { - storage->invalidateStaticData(); - staticBuffer = NULL; - } - } + // Case 2b: use a static translated copy or fall back to streaming + StaticIndexBufferInterface *staticBuffer = buffer->getStaticIndexBuffer(); - ASSERT(indexBuffer); + bool staticBufferInitialized = staticBuffer && staticBuffer->getBufferSize() != 0; + bool staticBufferUsable = staticBuffer && + offsetAligned && staticBuffer->getIndexType() == dstType; - // Using bit-shift here is faster than using division. - if (convertCount > (std::numeric_limits::max() >> destTypeInfo.bytesShift)) - { - return gl::Error(GL_OUT_OF_MEMORY, "Reserving %u indices of %u bytes each exceeds the maximum buffer size.", - convertCount, destTypeInfo.bytes); - } + if (staticBufferInitialized && !staticBufferUsable) + { + buffer->invalidateStaticData(); + staticBuffer = nullptr; + } - unsigned int bufferSizeRequired = convertCount << destTypeInfo.bytesShift; - error = indexBuffer->reserveBufferSpace(bufferSizeRequired, destinationIndexType); + if (staticBuffer == nullptr || !offsetAligned) + { + const uint8_t *bufferData = nullptr; + gl::Error error = buffer->getData(&bufferData); if (error.isError()) { return error; } + ASSERT(bufferData != nullptr); - void* output = NULL; - error = indexBuffer->mapBuffer(bufferSizeRequired, &output, &streamOffset); + error = streamIndexData(bufferData + offset, count, srcType, dstType, + primitiveRestartFixedIndexEnabled, translated); if (error.isError()) { return error; } - - const uint8_t *dataPointer = reinterpret_cast(indices); - if (staticBuffer) + buffer->promoteStaticUsage(count << srcTypeInfo.bytesShift); + } + else + { + if (!staticBufferInitialized) { - error = storage->getData(&dataPointer); + const uint8_t *bufferData = nullptr; + gl::Error error = buffer->getData(&bufferData); if (error.isError()) { return error; } - } - ConvertIndices(type, destinationIndexType, dataPointer, convertCount, output); + ASSERT(bufferData != nullptr); - error = indexBuffer->unmapBuffer(); - if (error.isError()) - { - return error; + unsigned int convertCount = + static_cast(buffer->getSize()) >> srcTypeInfo.bytesShift; + error = StreamInIndexBuffer(staticBuffer, bufferData, convertCount, srcType, dstType, + primitiveRestartFixedIndexEnabled, nullptr); + if (error.isError()) + { + return error; + } } + ASSERT(offsetAligned && staticBuffer->getIndexType() == dstType); - if (staticBuffer) - { - // Using bit-shift here is faster than using division. - streamOffset = (offset >> typeInfo.bytesShift) << destTypeInfo.bytesShift; - } + translated->indexBuffer = staticBuffer->getIndexBuffer(); + translated->serial = staticBuffer->getSerial(); + translated->startIndex = (offset >> srcTypeInfo.bytesShift); + translated->startOffset = (offset >> srcTypeInfo.bytesShift) << dstTypeInfo.bytesShift; } - translated->storage = directStorage ? storage : NULL; - translated->indexBuffer = indexBuffer ? indexBuffer->getIndexBuffer() : NULL; - translated->serial = directStorage ? storage->getSerial() : indexBuffer->getSerial(); - // Using bit-shift here is faster than using division. - translated->startIndex = (streamOffset >> destTypeInfo.bytesShift); - translated->startOffset = streamOffset; - translated->indexType = destinationIndexType; + return gl::Error(GL_NO_ERROR); +} + +gl::Error IndexDataManager::streamIndexData(const GLvoid *data, + unsigned int count, + GLenum srcType, + GLenum dstType, + bool usePrimitiveRestartFixedIndex, + TranslatedIndexData *translated) +{ + const gl::Type &dstTypeInfo = gl::GetTypeInfo(dstType); - if (storage) + IndexBufferInterface *indexBuffer = nullptr; + gl::Error error = getStreamingIndexBuffer(dstType, &indexBuffer); + if (error.isError()) { - storage->promoteStaticUsage(count << typeInfo.bytesShift); + return error; } + ASSERT(indexBuffer != nullptr); + + unsigned int offset; + StreamInIndexBuffer(indexBuffer, data, count, srcType, dstType, usePrimitiveRestartFixedIndex, + &offset); + + translated->indexBuffer = indexBuffer->getIndexBuffer(); + translated->serial = indexBuffer->getSerial(); + translated->startIndex = (offset >> dstTypeInfo.bytesShift); + translated->startOffset = offset; return gl::Error(GL_NO_ERROR); } -gl::Error IndexDataManager::getStreamingIndexBuffer(GLenum destinationIndexType, IndexBufferInterface **outBuffer) +gl::Error IndexDataManager::getStreamingIndexBuffer(GLenum destinationIndexType, + IndexBufferInterface **outBuffer) { ASSERT(outBuffer); if (destinationIndexType == GL_UNSIGNED_INT) @@ -239,7 +318,8 @@ gl::Error IndexDataManager::getStreamingIndexBuffer(GLenum destinationIndexType, if (!mStreamingBufferInt) { mStreamingBufferInt = new StreamingIndexBufferInterface(mFactory); - gl::Error error = mStreamingBufferInt->reserveBufferSpace(INITIAL_INDEX_BUFFER_SIZE, GL_UNSIGNED_INT); + gl::Error error = mStreamingBufferInt->reserveBufferSpace(INITIAL_INDEX_BUFFER_SIZE, + GL_UNSIGNED_INT); if (error.isError()) { SafeDelete(mStreamingBufferInt); @@ -257,7 +337,8 @@ gl::Error IndexDataManager::getStreamingIndexBuffer(GLenum destinationIndexType, if (!mStreamingBufferShort) { mStreamingBufferShort = new StreamingIndexBufferInterface(mFactory); - gl::Error error = mStreamingBufferShort->reserveBufferSpace(INITIAL_INDEX_BUFFER_SIZE, GL_UNSIGNED_SHORT); + gl::Error error = mStreamingBufferShort->reserveBufferSpace(INITIAL_INDEX_BUFFER_SIZE, + GL_UNSIGNED_SHORT); if (error.isError()) { SafeDelete(mStreamingBufferShort); diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/IndexDataManager.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/IndexDataManager.h index 275b3720c53e..44eb68c0716d 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/IndexDataManager.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/IndexDataManager.h @@ -36,9 +36,18 @@ class IndexBuffer; class BufferD3D; class RendererD3D; +struct SourceIndexData +{ + BufferD3D *srcBuffer; + const GLvoid *srcIndices; + unsigned int srcCount; + GLenum srcIndexType; + bool srcIndicesChanged; +}; + struct TranslatedIndexData { - RangeUI indexRange; + gl::IndexRange indexRange; unsigned int startIndex; unsigned int startOffset; // In bytes @@ -46,6 +55,8 @@ struct TranslatedIndexData BufferD3D *storage; GLenum indexType; unsigned int serial; + + SourceIndexData srcIndexData; }; class IndexDataManager : angle::NonCopyable @@ -54,10 +65,22 @@ class IndexDataManager : angle::NonCopyable explicit IndexDataManager(BufferFactoryD3D *factory, RendererClass rendererClass); virtual ~IndexDataManager(); - gl::Error prepareIndexData(GLenum type, GLsizei count, gl::Buffer *arrayElementBuffer, const GLvoid *indices, TranslatedIndexData *translated); + gl::Error prepareIndexData(GLenum srcType, + GLsizei count, + gl::Buffer *glBuffer, + const GLvoid *indices, + TranslatedIndexData *translated, + bool primitiveRestartFixedIndexEnabled); private: - gl::Error getStreamingIndexBuffer(GLenum destinationIndexType, IndexBufferInterface **outBuffer); + gl::Error streamIndexData(const GLvoid *data, + unsigned int count, + GLenum srcType, + GLenum dstType, + bool usePrimitiveRestartFixedIndex, + TranslatedIndexData *translated); + gl::Error getStreamingIndexBuffer(GLenum destinationIndexType, + IndexBufferInterface **outBuffer); BufferFactoryD3D *const mFactory; RendererClass mRendererClass; diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/ProgramD3D.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/ProgramD3D.cpp index 71e9dc73095d..b8514ff47c65 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/ProgramD3D.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/ProgramD3D.cpp @@ -8,16 +8,19 @@ #include "libANGLE/renderer/d3d/ProgramD3D.h" +#include "common/BitSetIterator.h" #include "common/utilities.h" #include "libANGLE/Framebuffer.h" #include "libANGLE/FramebufferAttachment.h" #include "libANGLE/Program.h" +#include "libANGLE/VertexArray.h" #include "libANGLE/features.h" #include "libANGLE/renderer/d3d/DynamicHLSL.h" #include "libANGLE/renderer/d3d/FramebufferD3D.h" #include "libANGLE/renderer/d3d/RendererD3D.h" #include "libANGLE/renderer/d3d/ShaderD3D.h" #include "libANGLE/renderer/d3d/ShaderExecutableD3D.h" +#include "libANGLE/renderer/d3d/VaryingPacking.h" #include "libANGLE/renderer/d3d/VertexDataManager.h" namespace rx @@ -26,69 +29,41 @@ namespace rx namespace { -GLenum GetTextureType(GLenum samplerType) -{ - switch (samplerType) - { - case GL_SAMPLER_2D: - case GL_INT_SAMPLER_2D: - case GL_UNSIGNED_INT_SAMPLER_2D: - case GL_SAMPLER_2D_SHADOW: - return GL_TEXTURE_2D; - case GL_SAMPLER_3D: - case GL_INT_SAMPLER_3D: - case GL_UNSIGNED_INT_SAMPLER_3D: - return GL_TEXTURE_3D; - case GL_SAMPLER_CUBE: - case GL_SAMPLER_CUBE_SHADOW: - return GL_TEXTURE_CUBE_MAP; - case GL_INT_SAMPLER_CUBE: - case GL_UNSIGNED_INT_SAMPLER_CUBE: - return GL_TEXTURE_CUBE_MAP; - case GL_SAMPLER_2D_ARRAY: - case GL_INT_SAMPLER_2D_ARRAY: - case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY: - case GL_SAMPLER_2D_ARRAY_SHADOW: - return GL_TEXTURE_2D_ARRAY; - default: UNREACHABLE(); - } - - return GL_TEXTURE_2D; -} - -void GetDefaultInputLayoutFromShader(const std::vector &shaderAttributes, gl::VertexFormat inputLayout[gl::MAX_VERTEX_ATTRIBS]) +gl::InputLayout GetDefaultInputLayoutFromShader(const gl::Shader *vertexShader) { - size_t layoutIndex = 0; - for (size_t attributeIndex = 0; attributeIndex < shaderAttributes.size(); attributeIndex++) + gl::InputLayout defaultLayout; + for (const sh::Attribute &shaderAttr : vertexShader->getActiveAttributes()) { - ASSERT(layoutIndex < gl::MAX_VERTEX_ATTRIBS); - - const sh::Attribute &shaderAttr = shaderAttributes[attributeIndex]; - if (shaderAttr.type != GL_NONE) { GLenum transposedType = gl::TransposeMatrixType(shaderAttr.type); - for (size_t rowIndex = 0; static_cast(rowIndex) < gl::VariableRowCount(transposedType); rowIndex++, layoutIndex++) + for (size_t rowIndex = 0; + static_cast(rowIndex) < gl::VariableRowCount(transposedType); ++rowIndex) { - gl::VertexFormat *defaultFormat = &inputLayout[layoutIndex]; + GLenum componentType = gl::VariableComponentType(transposedType); + GLuint components = static_cast(gl::VariableColumnCount(transposedType)); + bool pureInt = (componentType != GL_FLOAT); + gl::VertexFormatType defaultType = + gl::GetVertexFormatType(componentType, GL_FALSE, components, pureInt); - defaultFormat->mType = gl::VariableComponentType(transposedType); - defaultFormat->mNormalized = false; - defaultFormat->mPureInteger = (defaultFormat->mType != GL_FLOAT); // note: inputs can not be bool - defaultFormat->mComponents = gl::VariableColumnCount(transposedType); + defaultLayout.push_back(defaultType); } } } + + return defaultLayout; } -std::vector GetDefaultOutputLayoutFromShader(const std::vector &shaderOutputVars) +std::vector GetDefaultOutputLayoutFromShader( + const std::vector &shaderOutputVars) { std::vector defaultPixelOutput; if (!shaderOutputVars.empty()) { - defaultPixelOutput.push_back(GL_COLOR_ATTACHMENT0 + shaderOutputVars[0].outputIndex); + defaultPixelOutput.push_back(GL_COLOR_ATTACHMENT0 + + static_cast(shaderOutputVars[0].outputIndex)); } return defaultPixelOutput; @@ -104,61 +79,473 @@ bool IsRowMajorLayout(const sh::ShaderVariable &var) return false; } -struct AttributeSorter +// true if varying x has a higher priority in packing than y +bool ComparePackedVarying(const PackedVarying &x, const PackedVarying &y) { - AttributeSorter(const ProgramImpl::SemanticIndexArray &semanticIndices) - : originalIndices(&semanticIndices) + return gl::CompareShaderVar(*x.varying, *y.varying); +} + +std::vector MergeVaryings(const gl::Shader &vertexShader, + const gl::Shader &fragmentShader, + const std::vector &tfVaryings) +{ + std::vector packedVaryings; + + for (const sh::Varying &output : vertexShader.getVaryings()) { + bool packed = false; + + // Built-in varyings obey special rules + if (output.isBuiltIn()) + { + continue; + } + + for (const sh::Varying &input : fragmentShader.getVaryings()) + { + if (output.name == input.name) + { + if (output.isStruct()) + { + ASSERT(!output.isArray()); + for (const auto &field : output.fields) + { + ASSERT(!field.isStruct() && !field.isArray()); + packedVaryings.push_back( + PackedVarying(field, input.interpolation, input.name)); + } + } + else + { + packedVaryings.push_back(PackedVarying(input, input.interpolation)); + } + packed = true; + break; + } + } + + // Keep Transform FB varyings in the merged list always. + if (!packed) + { + for (const std::string &tfVarying : tfVaryings) + { + if (tfVarying == output.name) + { + // Transform feedback for varying structs is underspecified. + // See Khronos bug 9856. + // TODO(jmadill): Figure out how to be spec-compliant here. + if (!output.isStruct()) + { + packedVaryings.push_back(PackedVarying(output, output.interpolation)); + packedVaryings.back().vertexOnly = true; + } + break; + } + } + } } - bool operator()(int a, int b) + std::sort(packedVaryings.begin(), packedVaryings.end(), ComparePackedVarying); + + return packedVaryings; +} + +template +void GetUniformBlockInfo(const std::vector &fields, + const std::string &prefix, + sh::BlockLayoutEncoder *encoder, + bool inRowMajorLayout, + std::map *blockInfoOut) +{ + for (const VarT &field : fields) { - int indexA = (*originalIndices)[a]; - int indexB = (*originalIndices)[b]; + const std::string &fieldName = (prefix.empty() ? field.name : prefix + "." + field.name); - if (indexA == -1) return false; - if (indexB == -1) return true; - return (indexA < indexB); + if (field.isStruct()) + { + bool rowMajorLayout = (inRowMajorLayout || IsRowMajorLayout(field)); + + for (unsigned int arrayElement = 0; arrayElement < field.elementCount(); arrayElement++) + { + encoder->enterAggregateType(); + + const std::string uniformElementName = + fieldName + (field.isArray() ? ArrayString(arrayElement) : ""); + GetUniformBlockInfo(field.fields, uniformElementName, encoder, rowMajorLayout, + blockInfoOut); + + encoder->exitAggregateType(); + } + } + else + { + bool isRowMajorMatrix = (gl::IsMatrixType(field.type) && inRowMajorLayout); + (*blockInfoOut)[fieldName] = + encoder->encodeType(field.type, field.arraySize, isRowMajorMatrix); + } } +} - const ProgramImpl::SemanticIndexArray *originalIndices; -}; +template +static inline void SetIfDirty(T *dest, const T &source, bool *dirtyFlag) +{ + ASSERT(dest != NULL); + ASSERT(dirtyFlag != NULL); + *dirtyFlag = *dirtyFlag || (memcmp(dest, &source, sizeof(T)) != 0); + *dest = source; } -ProgramD3D::VertexExecutable::VertexExecutable(const gl::VertexFormat inputLayout[], - const GLenum signature[], - ShaderExecutableD3D *shaderExecutable) - : mShaderExecutable(shaderExecutable) +template +bool TransposeMatrix(T *target, + const GLfloat *value, + int targetWidth, + int targetHeight, + int srcWidth, + int srcHeight) +{ + bool dirty = false; + int copyWidth = std::min(targetHeight, srcWidth); + int copyHeight = std::min(targetWidth, srcHeight); + + for (int x = 0; x < copyWidth; x++) + { + for (int y = 0; y < copyHeight; y++) + { + SetIfDirty(target + (x * targetWidth + y), static_cast(value[y * srcWidth + x]), + &dirty); + } + } + // clear unfilled right side + for (int y = 0; y < copyWidth; y++) + { + for (int x = copyHeight; x < targetWidth; x++) + { + SetIfDirty(target + (y * targetWidth + x), static_cast(0), &dirty); + } + } + // clear unfilled bottom. + for (int y = copyWidth; y < targetHeight; y++) + { + for (int x = 0; x < targetWidth; x++) + { + SetIfDirty(target + (y * targetWidth + x), static_cast(0), &dirty); + } + } + + return dirty; +} + +template +bool ExpandMatrix(T *target, + const GLfloat *value, + int targetWidth, + int targetHeight, + int srcWidth, + int srcHeight) +{ + bool dirty = false; + int copyWidth = std::min(targetWidth, srcWidth); + int copyHeight = std::min(targetHeight, srcHeight); + + for (int y = 0; y < copyHeight; y++) + { + for (int x = 0; x < copyWidth; x++) + { + SetIfDirty(target + (y * targetWidth + x), static_cast(value[y * srcWidth + x]), + &dirty); + } + } + // clear unfilled right side + for (int y = 0; y < copyHeight; y++) + { + for (int x = copyWidth; x < targetWidth; x++) + { + SetIfDirty(target + (y * targetWidth + x), static_cast(0), &dirty); + } + } + // clear unfilled bottom. + for (int y = copyHeight; y < targetHeight; y++) + { + for (int x = 0; x < targetWidth; x++) + { + SetIfDirty(target + (y * targetWidth + x), static_cast(0), &dirty); + } + } + + return dirty; +} + +gl::PrimitiveType GetGeometryShaderTypeFromDrawMode(GLenum drawMode) { - for (size_t attributeIndex = 0; attributeIndex < gl::MAX_VERTEX_ATTRIBS; attributeIndex++) + switch (drawMode) { - mInputs[attributeIndex] = inputLayout[attributeIndex]; - mSignature[attributeIndex] = signature[attributeIndex]; + // Uses the point sprite geometry shader. + case GL_POINTS: + return gl::PRIMITIVE_POINTS; + + // All line drawing uses the same geometry shader. + case GL_LINES: + case GL_LINE_STRIP: + case GL_LINE_LOOP: + return gl::PRIMITIVE_LINES; + + // The triangle fan primitive is emulated with strips in D3D11. + case GL_TRIANGLES: + case GL_TRIANGLE_FAN: + return gl::PRIMITIVE_TRIANGLES; + + // Special case for triangle strips. + case GL_TRIANGLE_STRIP: + return gl::PRIMITIVE_TRIANGLE_STRIP; + + default: + UNREACHABLE(); + return gl::PRIMITIVE_TYPE_MAX; + } +} + +} // anonymous namespace + +// D3DUniform Implementation + +D3DUniform::D3DUniform(GLenum typeIn, + const std::string &nameIn, + unsigned int arraySizeIn, + bool defaultBlock) + : type(typeIn), + name(nameIn), + arraySize(arraySizeIn), + data(nullptr), + dirty(true), + vsRegisterIndex(GL_INVALID_INDEX), + psRegisterIndex(GL_INVALID_INDEX), + registerCount(0), + registerElement(0) +{ + // 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) + { + size_t bytes = gl::VariableInternalSize(type) * elementCount(); + data = new uint8_t[bytes]; + memset(data, 0, bytes); + + // TODO(jmadill): is this correct with non-square matrices? + registerCount = gl::VariableRowCount(type) * elementCount(); } } +D3DUniform::~D3DUniform() +{ + SafeDeleteArray(data); +} + +bool D3DUniform::isSampler() const +{ + return gl::IsSamplerType(type); +} + +bool D3DUniform::isReferencedByVertexShader() const +{ + return vsRegisterIndex != GL_INVALID_INDEX; +} + +bool D3DUniform::isReferencedByFragmentShader() const +{ + return psRegisterIndex != GL_INVALID_INDEX; +} + +// 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(int rendererMajorShaderModel, + const std::string &shaderModelSuffix, + bool usesInstancedPointSpriteEmulation, + bool usesViewScale, + const ShaderD3D *vertexShader, + const ShaderD3D *fragmentShader) + : mRendererMajorShaderModel(rendererMajorShaderModel), + mShaderModelSuffix(shaderModelSuffix), + mUsesInstancedPointSpriteEmulation(usesInstancedPointSpriteEmulation), + mUsesViewScale(usesViewScale), + mVertexShader(vertexShader), + mFragmentShader(fragmentShader) +{ +} + +int ProgramD3DMetadata::getRendererMajorShaderModel() const +{ + return mRendererMajorShaderModel; +} + +bool ProgramD3DMetadata::usesBroadcast(const gl::Data &data) const +{ + return (mFragmentShader->usesFragColor() && data.clientVersion < 3); +} + +bool ProgramD3DMetadata::usesFragDepth(const gl::Program::Data &programData) const +{ + return mFragmentShader->usesFragDepth(); +} + +bool ProgramD3DMetadata::usesPointCoord() const +{ + return mFragmentShader->usesPointCoord(); +} + +bool ProgramD3DMetadata::usesFragCoord() const +{ + return mFragmentShader->usesFragCoord(); +} + +bool ProgramD3DMetadata::usesPointSize() const +{ + return mVertexShader->usesPointSize(); +} + +bool ProgramD3DMetadata::usesInsertedPointCoordValue() const +{ + return !usesPointSize() && usesPointCoord() && mRendererMajorShaderModel >= 4; +} + +bool ProgramD3DMetadata::usesViewScale() const +{ + return mUsesViewScale; +} + +bool ProgramD3DMetadata::addsPointCoordToVertexShader() const +{ + // Instanced PointSprite emulation requires that gl_PointCoord is present in the vertex shader + // VS_OUTPUT structure to ensure compatibility with the generated PS_INPUT of the pixel shader. + // GeometryShader PointSprite emulation does not require this additional entry because the + // GS_OUTPUT of the Geometry shader contains the pointCoord value and already matches the + // PS_INPUT of the generated pixel shader. The Geometry Shader point sprite implementation needs + // gl_PointSize to be in VS_OUTPUT and GS_INPUT. Instanced point sprites doesn't need + // gl_PointSize in VS_OUTPUT. + 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 +{ + return mFragmentShader->usesMultipleRenderTargets(); +} + +GLint ProgramD3DMetadata::getMajorShaderVersion() const +{ + return mVertexShader->getData().getShaderVersion(); +} + +const ShaderD3D *ProgramD3DMetadata::getFragmentShader() const +{ + return mFragmentShader; +} + +// 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); } -bool ProgramD3D::VertexExecutable::matchesSignature(const GLenum signature[]) const +// static +ProgramD3D::VertexExecutable::HLSLAttribType ProgramD3D::VertexExecutable::GetAttribType( + GLenum type) { - for (size_t attributeIndex = 0; attributeIndex < gl::MAX_VERTEX_ATTRIBS; attributeIndex++) + switch (type) { - if (mSignature[attributeIndex] != signature[attributeIndex]) - { + 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) + { + gl::VertexFormatType vertexFormatType = inputLayout[index]; + if (vertexFormatType == gl::VERTEX_FORMAT_INVALID) + continue; + + VertexConversionType conversionType = renderer->getVertexConversionType(vertexFormatType); + if ((conversionType & VERTEX_CONVERT_GPU) == 0) + continue; + + GLenum componentType = renderer->getVertexComponentType(vertexFormatType); + (*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(const std::vector &outputSignature, + ShaderExecutableD3D *shaderExecutable) + : mOutputSignature(outputSignature), mShaderExecutable(shaderExecutable) { } @@ -173,19 +560,18 @@ ProgramD3D::Sampler::Sampler() : active(false), logicalTextureUnit(0), textureTy unsigned int ProgramD3D::mCurrentSerial = 1; -ProgramD3D::ProgramD3D(RendererD3D *renderer) - : ProgramImpl(), +ProgramD3D::ProgramD3D(const gl::Program::Data &data, RendererD3D *renderer) + : ProgramImpl(data), mRenderer(renderer), mDynamicHLSL(NULL), - mGeometryExecutable(NULL), + mGeometryExecutables(gl::PRIMITIVE_TYPE_MAX, nullptr), mUsesPointSize(false), + mUsesFlatInterpolation(false), mVertexUniformStorage(NULL), mFragmentUniformStorage(NULL), mUsedVertexSamplerRange(0), mUsedPixelSamplerRange(0), mDirtySamplerMapping(true), - mTextureUnitTypesCache(renderer->getRendererCaps().maxCombinedTextureImageUnits), - mShaderVersion(100), mSerial(issueSerial()) { mDynamicHLSL = new DynamicHLSL(renderer); @@ -202,8 +588,13 @@ bool ProgramD3D::usesPointSpriteEmulation() const return mUsesPointSize && mRenderer->getMajorShaderModel() >= 4; } -bool ProgramD3D::usesGeometryShader() const +bool ProgramD3D::usesGeometryShader(GLenum drawMode) const { + if (drawMode != GL_POINTS) + { + return mUsesFlatInterpolation; + } + return usesPointSpriteEmulation() && !usesInstancedPointSpriteEmulation(); } @@ -212,30 +603,34 @@ bool ProgramD3D::usesInstancedPointSpriteEmulation() const return mRenderer->getWorkarounds().useInstancedPointSpriteEmulation; } -GLint ProgramD3D::getSamplerMapping(gl::SamplerType type, unsigned int samplerIndex, const gl::Caps &caps) const +GLint ProgramD3D::getSamplerMapping(gl::SamplerType type, + unsigned int samplerIndex, + const gl::Caps &caps) const { GLint logicalTextureUnit = -1; switch (type) { - case gl::SAMPLER_PIXEL: - ASSERT(samplerIndex < caps.maxTextureImageUnits); - if (samplerIndex < mSamplersPS.size() && mSamplersPS[samplerIndex].active) - { - logicalTextureUnit = mSamplersPS[samplerIndex].logicalTextureUnit; - } - break; - case gl::SAMPLER_VERTEX: - ASSERT(samplerIndex < caps.maxVertexTextureImageUnits); - if (samplerIndex < mSamplersVS.size() && mSamplersVS[samplerIndex].active) - { - logicalTextureUnit = mSamplersVS[samplerIndex].logicalTextureUnit; - } - break; - default: UNREACHABLE(); + case gl::SAMPLER_PIXEL: + ASSERT(samplerIndex < caps.maxTextureImageUnits); + if (samplerIndex < mSamplersPS.size() && mSamplersPS[samplerIndex].active) + { + logicalTextureUnit = mSamplersPS[samplerIndex].logicalTextureUnit; + } + break; + case gl::SAMPLER_VERTEX: + ASSERT(samplerIndex < caps.maxVertexTextureImageUnits); + if (samplerIndex < mSamplersVS.size() && mSamplersVS[samplerIndex].active) + { + logicalTextureUnit = mSamplersVS[samplerIndex].logicalTextureUnit; + } + break; + default: + UNREACHABLE(); } - if (logicalTextureUnit >= 0 && logicalTextureUnit < static_cast(caps.maxCombinedTextureImageUnits)) + if (logicalTextureUnit >= 0 && + logicalTextureUnit < static_cast(caps.maxCombinedTextureImageUnits)) { return logicalTextureUnit; } @@ -249,31 +644,32 @@ GLenum ProgramD3D::getSamplerTextureType(gl::SamplerType type, unsigned int samp { switch (type) { - case gl::SAMPLER_PIXEL: - ASSERT(samplerIndex < mSamplersPS.size()); - ASSERT(mSamplersPS[samplerIndex].active); - return mSamplersPS[samplerIndex].textureType; - case gl::SAMPLER_VERTEX: - ASSERT(samplerIndex < mSamplersVS.size()); - ASSERT(mSamplersVS[samplerIndex].active); - return mSamplersVS[samplerIndex].textureType; - default: UNREACHABLE(); + case gl::SAMPLER_PIXEL: + ASSERT(samplerIndex < mSamplersPS.size()); + ASSERT(mSamplersPS[samplerIndex].active); + return mSamplersPS[samplerIndex].textureType; + case gl::SAMPLER_VERTEX: + ASSERT(samplerIndex < mSamplersVS.size()); + ASSERT(mSamplersVS[samplerIndex].active); + return mSamplersVS[samplerIndex].textureType; + default: + UNREACHABLE(); } return GL_TEXTURE_2D; } -GLint ProgramD3D::getUsedSamplerRange(gl::SamplerType type) const +GLuint ProgramD3D::getUsedSamplerRange(gl::SamplerType type) const { switch (type) { - case gl::SAMPLER_PIXEL: - return mUsedPixelSamplerRange; - case gl::SAMPLER_VERTEX: - return mUsedVertexSamplerRange; - default: - UNREACHABLE(); - return 0; + case gl::SAMPLER_PIXEL: + return mUsedPixelSamplerRange; + case gl::SAMPLER_VERTEX: + return mUsedVertexSamplerRange; + default: + UNREACHABLE(); + return 0u; } } @@ -287,157 +683,77 @@ void ProgramD3D::updateSamplerMapping() mDirtySamplerMapping = false; // Retrieve sampler uniform values - for (size_t uniformIndex = 0; uniformIndex < mUniforms.size(); uniformIndex++) - { - gl::LinkedUniform *targetUniform = mUniforms[uniformIndex]; - - if (targetUniform->dirty) - { - if (gl::IsSamplerType(targetUniform->type)) - { - int count = targetUniform->elementCount(); - GLint (*v)[4] = reinterpret_cast(targetUniform->data); - - if (targetUniform->isReferencedByFragmentShader()) - { - unsigned int firstIndex = targetUniform->psRegisterIndex; - - for (int i = 0; i < count; i++) - { - unsigned int samplerIndex = firstIndex + i; - - if (samplerIndex < mSamplersPS.size()) - { - ASSERT(mSamplersPS[samplerIndex].active); - mSamplersPS[samplerIndex].logicalTextureUnit = v[i][0]; - } - } - } - - if (targetUniform->isReferencedByVertexShader()) - { - unsigned int firstIndex = targetUniform->vsRegisterIndex; - - for (int i = 0; i < count; i++) - { - unsigned int samplerIndex = firstIndex + i; - - if (samplerIndex < mSamplersVS.size()) - { - ASSERT(mSamplersVS[samplerIndex].active); - mSamplersVS[samplerIndex].logicalTextureUnit = v[i][0]; - } - } - } - } - } - } -} - -bool ProgramD3D::validateSamplers(gl::InfoLog *infoLog, const gl::Caps &caps) -{ - // Skip cache if we're using an infolog, so we get the full error. - // Also skip the cache if the sample mapping has changed, or if we haven't ever validated. - if (!mDirtySamplerMapping && infoLog == nullptr && mCachedValidateSamplersResult.valid()) + for (const D3DUniform *d3dUniform : mD3DUniforms) { - return mCachedValidateSamplersResult.value(); - } + if (!d3dUniform->dirty) + continue; - // 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. - updateSamplerMapping(); + if (!d3dUniform->isSampler()) + continue; - std::fill(mTextureUnitTypesCache.begin(), mTextureUnitTypesCache.end(), GL_NONE); + int count = d3dUniform->elementCount(); + const GLint(*v)[4] = reinterpret_cast(d3dUniform->data); - for (unsigned int i = 0; i < mUsedPixelSamplerRange; ++i) - { - if (mSamplersPS[i].active) + if (d3dUniform->isReferencedByFragmentShader()) { - unsigned int unit = mSamplersPS[i].logicalTextureUnit; + unsigned int firstIndex = d3dUniform->psRegisterIndex; - if (unit >= caps.maxCombinedTextureImageUnits) + for (int i = 0; i < count; i++) { - if (infoLog) - { - infoLog->append("Sampler uniform (%d) exceeds GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS (%d)", unit, caps.maxCombinedTextureImageUnits); - } + unsigned int samplerIndex = firstIndex + i; - mCachedValidateSamplersResult = false; - return false; - } - - if (mTextureUnitTypesCache[unit] != GL_NONE) - { - if (mSamplersPS[i].textureType != mTextureUnitTypesCache[unit]) + if (samplerIndex < mSamplersPS.size()) { - if (infoLog) - { - infoLog->append("Samplers of conflicting types refer to the same texture image unit (%d).", unit); - } - - mCachedValidateSamplersResult = false; - return false; + ASSERT(mSamplersPS[samplerIndex].active); + mSamplersPS[samplerIndex].logicalTextureUnit = v[i][0]; } } - else - { - mTextureUnitTypesCache[unit] = mSamplersPS[i].textureType; - } } - } - for (unsigned int i = 0; i < mUsedVertexSamplerRange; ++i) - { - if (mSamplersVS[i].active) + if (d3dUniform->isReferencedByVertexShader()) { - unsigned int unit = mSamplersVS[i].logicalTextureUnit; + unsigned int firstIndex = d3dUniform->vsRegisterIndex; - if (unit >= caps.maxCombinedTextureImageUnits) + for (int i = 0; i < count; i++) { - if (infoLog) - { - infoLog->append("Sampler uniform (%d) exceeds GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS (%d)", unit, caps.maxCombinedTextureImageUnits); - } - - mCachedValidateSamplersResult = false; - return false; - } + unsigned int samplerIndex = firstIndex + i; - if (mTextureUnitTypesCache[unit] != GL_NONE) - { - if (mSamplersVS[i].textureType != mTextureUnitTypesCache[unit]) + if (samplerIndex < mSamplersVS.size()) { - if (infoLog) - { - infoLog->append("Samplers of conflicting types refer to the same texture image unit (%d).", unit); - } - - mCachedValidateSamplersResult = false; - return false; + ASSERT(mSamplersVS[samplerIndex].active); + mSamplersVS[samplerIndex].logicalTextureUnit = v[i][0]; } } - else - { - mTextureUnitTypesCache[unit] = mSamplersVS[i].textureType; - } } - } - - mCachedValidateSamplersResult = true; - return true; + } } LinkResult ProgramD3D::load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream) { + reset(); + + DeviceIdentifier binaryDeviceIdentifier = {0}; + 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 LinkResult(false, gl::Error(GL_NO_ERROR)); + } + int compileFlags = stream->readInt(); if (compileFlags != ANGLE_COMPILE_OPTIMIZATION_LEVEL) { - infoLog.append("Mismatched compilation flags."); + infoLog << "Mismatched compilation flags."; return LinkResult(false, gl::Error(GL_NO_ERROR)); } - stream->readInt(&mShaderVersion); + for (int &index : mAttribLocationToD3DSemantic) + { + stream->readInt(&index); + } const unsigned int psSamplerCount = stream->readInt(); for (unsigned int i = 0; i < psSamplerCount; ++i) @@ -464,105 +780,69 @@ LinkResult ProgramD3D::load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream) const unsigned int uniformCount = stream->readInt(); if (stream->error()) { - infoLog.append("Invalid program binary."); + infoLog << "Invalid program binary."; return LinkResult(false, gl::Error(GL_NO_ERROR)); } - mUniforms.resize(uniformCount); + const auto &linkedUniforms = mData.getUniforms(); + ASSERT(mD3DUniforms.empty()); for (unsigned int uniformIndex = 0; uniformIndex < uniformCount; uniformIndex++) { - GLenum type = stream->readInt(); - GLenum precision = stream->readInt(); - std::string name = stream->readString(); - unsigned int arraySize = stream->readInt(); - int blockIndex = stream->readInt(); - - int offset = stream->readInt(); - int arrayStride = stream->readInt(); - int matrixStride = stream->readInt(); - bool isRowMajorMatrix = stream->readBool(); - - const sh::BlockMemberInfo blockInfo(offset, arrayStride, matrixStride, isRowMajorMatrix); - - gl::LinkedUniform *uniform = new gl::LinkedUniform(type, precision, name, arraySize, blockIndex, blockInfo); - - stream->readInt(&uniform->psRegisterIndex); - stream->readInt(&uniform->vsRegisterIndex); - stream->readInt(&uniform->registerCount); - stream->readInt(&uniform->registerElement); - - mUniforms[uniformIndex] = uniform; - } + const gl::LinkedUniform &linkedUniform = linkedUniforms[uniformIndex]; - const unsigned int uniformIndexCount = stream->readInt(); - if (stream->error()) - { - infoLog.append("Invalid program binary."); - return LinkResult(false, gl::Error(GL_NO_ERROR)); - } + D3DUniform *d3dUniform = + new D3DUniform(linkedUniform.type, linkedUniform.name, linkedUniform.arraySize, + linkedUniform.isInDefaultBlock()); + stream->readInt(&d3dUniform->psRegisterIndex); + stream->readInt(&d3dUniform->vsRegisterIndex); + stream->readInt(&d3dUniform->registerCount); + stream->readInt(&d3dUniform->registerElement); - mUniformIndex.resize(uniformIndexCount); - for (unsigned int uniformIndexIndex = 0; uniformIndexIndex < uniformIndexCount; uniformIndexIndex++) - { - stream->readString(&mUniformIndex[uniformIndexIndex].name); - stream->readInt(&mUniformIndex[uniformIndexIndex].element); - stream->readInt(&mUniformIndex[uniformIndexIndex].index); + mD3DUniforms.push_back(d3dUniform); } - unsigned int uniformBlockCount = stream->readInt(); + const unsigned int blockCount = stream->readInt(); if (stream->error()) { - infoLog.append("Invalid program binary."); + infoLog << "Invalid program binary."; return LinkResult(false, gl::Error(GL_NO_ERROR)); } - mUniformBlocks.resize(uniformBlockCount); - for (unsigned int uniformBlockIndex = 0; uniformBlockIndex < uniformBlockCount; ++uniformBlockIndex) + ASSERT(mD3DUniformBlocks.empty()); + for (unsigned int blockIndex = 0; blockIndex < blockCount; ++blockIndex) { - std::string name = stream->readString(); - unsigned int elementIndex = stream->readInt(); - unsigned int dataSize = stream->readInt(); - - gl::UniformBlock *uniformBlock = new gl::UniformBlock(name, elementIndex, dataSize); - - stream->readInt(&uniformBlock->psRegisterIndex); - stream->readInt(&uniformBlock->vsRegisterIndex); - - unsigned int numMembers = stream->readInt(); - uniformBlock->memberUniformIndexes.resize(numMembers); - for (unsigned int blockMemberIndex = 0; blockMemberIndex < numMembers; blockMemberIndex++) - { - stream->readInt(&uniformBlock->memberUniformIndexes[blockMemberIndex]); - } - - mUniformBlocks[uniformBlockIndex] = uniformBlock; + D3DUniformBlock uniformBlock; + stream->readInt(&uniformBlock.psRegisterIndex); + stream->readInt(&uniformBlock.vsRegisterIndex); + mD3DUniformBlocks.push_back(uniformBlock); } - stream->readInt(&mTransformFeedbackBufferMode); - const unsigned int transformFeedbackVaryingCount = stream->readInt(); - mTransformFeedbackLinkedVaryings.resize(transformFeedbackVaryingCount); - for (unsigned int varyingIndex = 0; varyingIndex < transformFeedbackVaryingCount; varyingIndex++) + const unsigned int streamOutVaryingCount = stream->readInt(); + mStreamOutVaryings.resize(streamOutVaryingCount); + for (unsigned int varyingIndex = 0; varyingIndex < streamOutVaryingCount; ++varyingIndex) { - gl::LinkedVarying &varying = mTransformFeedbackLinkedVaryings[varyingIndex]; + D3DVarying *varying = &mStreamOutVaryings[varyingIndex]; - stream->readString(&varying.name); - stream->readInt(&varying.type); - stream->readInt(&varying.size); - stream->readString(&varying.semanticName); - stream->readInt(&varying.semanticIndex); - stream->readInt(&varying.semanticIndexCount); + stream->readString(&varying->semanticName); + stream->readInt(&varying->semanticIndex); + stream->readInt(&varying->componentCount); + stream->readInt(&varying->outputSlot); } stream->readString(&mVertexHLSL); - stream->readBytes(reinterpret_cast(&mVertexWorkarounds), sizeof(D3DCompilerWorkarounds)); + stream->readBytes(reinterpret_cast(&mVertexWorkarounds), + sizeof(D3DCompilerWorkarounds)); stream->readString(&mPixelHLSL); - stream->readBytes(reinterpret_cast(&mPixelWorkarounds), sizeof(D3DCompilerWorkarounds)); + stream->readBytes(reinterpret_cast(&mPixelWorkarounds), + sizeof(D3DCompilerWorkarounds)); stream->readBool(&mUsesFragDepth); stream->readBool(&mUsesPointSize); + stream->readBool(&mUsesFlatInterpolation); const size_t pixelShaderKeySize = stream->readInt(); mPixelShaderKey.resize(pixelShaderKeySize); - for (size_t pixelShaderKeyIndex = 0; pixelShaderKeyIndex < pixelShaderKeySize; pixelShaderKeyIndex++) + for (size_t pixelShaderKeyIndex = 0; pixelShaderKeyIndex < pixelShaderKeySize; + pixelShaderKeyIndex++) { stream->readInt(&mPixelShaderKey[pixelShaderKeyIndex].type); stream->readString(&mPixelShaderKey[pixelShaderKeyIndex].name); @@ -570,31 +850,30 @@ LinkResult ProgramD3D::load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream) stream->readInt(&mPixelShaderKey[pixelShaderKeyIndex].outputIndex); } - const unsigned char* binary = reinterpret_cast(stream->data()); + stream->readString(&mGeometryShaderPreamble); + + const unsigned char *binary = reinterpret_cast(stream->data()); const unsigned int vertexShaderCount = stream->readInt(); - for (unsigned int vertexShaderIndex = 0; vertexShaderIndex < vertexShaderCount; vertexShaderIndex++) + for (unsigned int vertexShaderIndex = 0; vertexShaderIndex < vertexShaderCount; + vertexShaderIndex++) { - gl::VertexFormat inputLayout[gl::MAX_VERTEX_ATTRIBS]; + size_t inputLayoutSize = stream->readInt(); + gl::InputLayout inputLayout(inputLayoutSize, gl::VERTEX_FORMAT_INVALID); - for (size_t inputIndex = 0; inputIndex < gl::MAX_VERTEX_ATTRIBS; inputIndex++) + for (size_t inputIndex = 0; inputIndex < inputLayoutSize; inputIndex++) { - gl::VertexFormat *vertexInput = &inputLayout[inputIndex]; - stream->readInt(&vertexInput->mType); - stream->readInt(&vertexInput->mNormalized); - stream->readInt(&vertexInput->mComponents); - stream->readBool(&vertexInput->mPureInteger); + inputLayout[inputIndex] = stream->readInt(); } - unsigned int vertexShaderSize = stream->readInt(); + unsigned int vertexShaderSize = stream->readInt(); const unsigned char *vertexShaderFunction = binary + stream->offset(); - ShaderExecutableD3D *shaderExecutable = NULL; - gl::Error error = mRenderer->loadExecutable(vertexShaderFunction, vertexShaderSize, - SHADER_VERTEX, - mTransformFeedbackLinkedVaryings, - (mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS), - &shaderExecutable); + ShaderExecutableD3D *shaderExecutable = nullptr; + + gl::Error error = mRenderer->loadExecutable( + vertexShaderFunction, vertexShaderSize, SHADER_VERTEX, mStreamOutVaryings, + (mData.getTransformFeedbackBufferMode() == GL_SEPARATE_ATTRIBS), &shaderExecutable); if (error.isError()) { return LinkResult(false, error); @@ -602,16 +881,17 @@ LinkResult ProgramD3D::load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream) if (!shaderExecutable) { - infoLog.append("Could not create vertex shader."); + infoLog << "Could not create vertex shader."; return LinkResult(false, gl::Error(GL_NO_ERROR)); } // generated converted input layout - GLenum signature[gl::MAX_VERTEX_ATTRIBS]; - getInputLayoutSignature(inputLayout, signature); + VertexExecutable::Signature signature; + VertexExecutable::getSignature(mRenderer, inputLayout, &signature); // add new binary - mVertexExecutables.push_back(new VertexExecutable(inputLayout, signature, shaderExecutable)); + mVertexExecutables.push_back( + new VertexExecutable(inputLayout, signature, shaderExecutable)); stream->skip(vertexShaderSize); } @@ -626,13 +906,13 @@ LinkResult ProgramD3D::load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream) stream->readInt(&outputs[outputIndex]); } - const size_t pixelShaderSize = stream->readInt(); + const size_t pixelShaderSize = stream->readInt(); const unsigned char *pixelShaderFunction = binary + stream->offset(); - ShaderExecutableD3D *shaderExecutable = NULL; - gl::Error error = mRenderer->loadExecutable(pixelShaderFunction, pixelShaderSize, SHADER_PIXEL, - mTransformFeedbackLinkedVaryings, - (mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS), - &shaderExecutable); + ShaderExecutableD3D *shaderExecutable = nullptr; + + gl::Error error = mRenderer->loadExecutable( + pixelShaderFunction, pixelShaderSize, SHADER_PIXEL, mStreamOutVaryings, + (mData.getTransformFeedbackBufferMode() == GL_SEPARATE_ATTRIBS), &shaderExecutable); if (error.isError()) { return LinkResult(false, error); @@ -640,7 +920,7 @@ LinkResult ProgramD3D::load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream) if (!shaderExecutable) { - infoLog.append("Could not create pixel shader."); + infoLog << "Could not create pixel shader."; return LinkResult(false, gl::Error(GL_NO_ERROR)); } @@ -650,49 +930,55 @@ LinkResult ProgramD3D::load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream) stream->skip(pixelShaderSize); } - unsigned int geometryShaderSize = stream->readInt(); - - if (geometryShaderSize > 0) + for (unsigned int geometryExeIndex = 0; geometryExeIndex < gl::PRIMITIVE_TYPE_MAX; + ++geometryExeIndex) { + unsigned int geometryShaderSize = stream->readInt(); + if (geometryShaderSize == 0) + { + mGeometryExecutables[geometryExeIndex] = nullptr; + continue; + } + const unsigned char *geometryShaderFunction = binary + stream->offset(); - gl::Error error = mRenderer->loadExecutable(geometryShaderFunction, geometryShaderSize, SHADER_GEOMETRY, - mTransformFeedbackLinkedVaryings, - (mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS), - &mGeometryExecutable); + bool splitAttribs = (mData.getTransformFeedbackBufferMode() == GL_SEPARATE_ATTRIBS); + + gl::Error error = mRenderer->loadExecutable( + geometryShaderFunction, geometryShaderSize, SHADER_GEOMETRY, mStreamOutVaryings, + splitAttribs, &mGeometryExecutables[geometryExeIndex]); if (error.isError()) { return LinkResult(false, error); } - if (!mGeometryExecutable) + if (!mGeometryExecutables[geometryExeIndex]) { - infoLog.append("Could not create geometry shader."); + infoLog << "Could not create geometry shader."; return LinkResult(false, gl::Error(GL_NO_ERROR)); } stream->skip(geometryShaderSize); } - GUID binaryIdentifier = {0}; - stream->readBytes(reinterpret_cast(&binaryIdentifier), sizeof(GUID)); - - GUID identifier = mRenderer->getAdapterIdentifier(); - if (memcmp(&identifier, &binaryIdentifier, sizeof(GUID)) != 0) - { - infoLog.append("Invalid program binary."); - return LinkResult(false, gl::Error(GL_NO_ERROR)); - } - initializeUniformStorage(); - initAttributesByLayout(); return LinkResult(true, gl::Error(GL_NO_ERROR)); } gl::Error ProgramD3D::save(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); - stream->writeInt(mShaderVersion); + for (int d3dSemantic : mAttribLocationToD3DSemantic) + { + stream->writeInt(d3dSemantic); + } stream->writeInt(mSamplersPS.size()); for (unsigned int i = 0; i < mSamplersPS.size(); ++i) @@ -713,79 +999,46 @@ gl::Error ProgramD3D::save(gl::BinaryOutputStream *stream) stream->writeInt(mUsedVertexSamplerRange); stream->writeInt(mUsedPixelSamplerRange); - stream->writeInt(mUniforms.size()); - for (size_t uniformIndex = 0; uniformIndex < mUniforms.size(); ++uniformIndex) - { - const gl::LinkedUniform &uniform = *mUniforms[uniformIndex]; - - stream->writeInt(uniform.type); - stream->writeInt(uniform.precision); - stream->writeString(uniform.name); - stream->writeInt(uniform.arraySize); - stream->writeInt(uniform.blockIndex); - - stream->writeInt(uniform.blockInfo.offset); - stream->writeInt(uniform.blockInfo.arrayStride); - stream->writeInt(uniform.blockInfo.matrixStride); - stream->writeInt(uniform.blockInfo.isRowMajorMatrix); - - stream->writeInt(uniform.psRegisterIndex); - stream->writeInt(uniform.vsRegisterIndex); - stream->writeInt(uniform.registerCount); - stream->writeInt(uniform.registerElement); - } - - stream->writeInt(mUniformIndex.size()); - for (size_t i = 0; i < mUniformIndex.size(); ++i) + stream->writeInt(mD3DUniforms.size()); + for (const D3DUniform *uniform : mD3DUniforms) { - stream->writeString(mUniformIndex[i].name); - stream->writeInt(mUniformIndex[i].element); - stream->writeInt(mUniformIndex[i].index); + // Type, name and arraySize are redundant, so aren't stored in the binary. + stream->writeInt(uniform->psRegisterIndex); + stream->writeInt(uniform->vsRegisterIndex); + stream->writeInt(uniform->registerCount); + stream->writeInt(uniform->registerElement); } - stream->writeInt(mUniformBlocks.size()); - for (size_t uniformBlockIndex = 0; uniformBlockIndex < mUniformBlocks.size(); ++uniformBlockIndex) + stream->writeInt(mD3DUniformBlocks.size()); + for (const D3DUniformBlock &uniformBlock : mD3DUniformBlocks) { - const gl::UniformBlock& uniformBlock = *mUniformBlocks[uniformBlockIndex]; - - stream->writeString(uniformBlock.name); - stream->writeInt(uniformBlock.elementIndex); - stream->writeInt(uniformBlock.dataSize); - - stream->writeInt(uniformBlock.memberUniformIndexes.size()); - for (unsigned int blockMemberIndex = 0; blockMemberIndex < uniformBlock.memberUniformIndexes.size(); blockMemberIndex++) - { - stream->writeInt(uniformBlock.memberUniformIndexes[blockMemberIndex]); - } - stream->writeInt(uniformBlock.psRegisterIndex); stream->writeInt(uniformBlock.vsRegisterIndex); } - stream->writeInt(mTransformFeedbackBufferMode); - stream->writeInt(mTransformFeedbackLinkedVaryings.size()); - for (size_t i = 0; i < mTransformFeedbackLinkedVaryings.size(); i++) + stream->writeInt(mStreamOutVaryings.size()); + for (const auto &varying : mStreamOutVaryings) { - const gl::LinkedVarying &varying = mTransformFeedbackLinkedVaryings[i]; - - stream->writeString(varying.name); - stream->writeInt(varying.type); - stream->writeInt(varying.size); stream->writeString(varying.semanticName); stream->writeInt(varying.semanticIndex); - stream->writeInt(varying.semanticIndexCount); + stream->writeInt(varying.componentCount); + stream->writeInt(varying.outputSlot); } stream->writeString(mVertexHLSL); - stream->writeBytes(reinterpret_cast(&mVertexWorkarounds), sizeof(D3DCompilerWorkarounds)); + stream->writeBytes(reinterpret_cast(&mVertexWorkarounds), + sizeof(D3DCompilerWorkarounds)); stream->writeString(mPixelHLSL); - stream->writeBytes(reinterpret_cast(&mPixelWorkarounds), sizeof(D3DCompilerWorkarounds)); + stream->writeBytes(reinterpret_cast(&mPixelWorkarounds), + sizeof(D3DCompilerWorkarounds)); stream->writeInt(mUsesFragDepth); stream->writeInt(mUsesPointSize); + stream->writeInt(mUsesFlatInterpolation); const std::vector &pixelShaderKey = mPixelShaderKey; stream->writeInt(pixelShaderKey.size()); - for (size_t pixelShaderKeyIndex = 0; pixelShaderKeyIndex < pixelShaderKey.size(); pixelShaderKeyIndex++) + for (size_t pixelShaderKeyIndex = 0; pixelShaderKeyIndex < pixelShaderKey.size(); + pixelShaderKeyIndex++) { const PixelShaderOutputVariable &variable = pixelShaderKey[pixelShaderKeyIndex]; stream->writeInt(variable.type); @@ -794,18 +1047,20 @@ gl::Error ProgramD3D::save(gl::BinaryOutputStream *stream) stream->writeInt(variable.outputIndex); } + stream->writeString(mGeometryShaderPreamble); + stream->writeInt(mVertexExecutables.size()); - for (size_t vertexExecutableIndex = 0; vertexExecutableIndex < mVertexExecutables.size(); vertexExecutableIndex++) + for (size_t vertexExecutableIndex = 0; vertexExecutableIndex < mVertexExecutables.size(); + vertexExecutableIndex++) { VertexExecutable *vertexExecutable = mVertexExecutables[vertexExecutableIndex]; - for (size_t inputIndex = 0; inputIndex < gl::MAX_VERTEX_ATTRIBS; inputIndex++) + const auto &inputLayout = vertexExecutable->inputs(); + stream->writeInt(inputLayout.size()); + + for (size_t inputIndex = 0; inputIndex < inputLayout.size(); inputIndex++) { - const gl::VertexFormat &vertexInput = vertexExecutable->inputs()[inputIndex]; - stream->writeInt(vertexInput.mType); - stream->writeInt(vertexInput.mNormalized); - stream->writeInt(vertexInput.mComponents); - stream->writeInt(vertexInput.mPureInteger); + stream->writeInt(inputLayout[inputIndex]); } size_t vertexShaderSize = vertexExecutable->shaderExecutable()->getLength(); @@ -816,7 +1071,8 @@ gl::Error ProgramD3D::save(gl::BinaryOutputStream *stream) } stream->writeInt(mPixelExecutables.size()); - for (size_t pixelExecutableIndex = 0; pixelExecutableIndex < mPixelExecutables.size(); pixelExecutableIndex++) + for (size_t pixelExecutableIndex = 0; pixelExecutableIndex < mPixelExecutables.size(); + pixelExecutableIndex++) { PixelExecutable *pixelExecutable = mPixelExecutables[pixelExecutableIndex]; @@ -834,27 +1090,33 @@ gl::Error ProgramD3D::save(gl::BinaryOutputStream *stream) stream->writeBytes(pixelBlob, pixelShaderSize); } - size_t geometryShaderSize = (mGeometryExecutable != NULL) ? mGeometryExecutable->getLength() : 0; - stream->writeInt(geometryShaderSize); - - if (mGeometryExecutable != NULL && geometryShaderSize > 0) + for (const ShaderExecutableD3D *geometryExe : mGeometryExecutables) { - const uint8_t *geometryBlob = mGeometryExecutable->getFunction(); - stream->writeBytes(geometryBlob, geometryShaderSize); - } + if (geometryExe == nullptr) + { + stream->writeInt(0); + continue; + } - GUID binaryIdentifier = mRenderer->getAdapterIdentifier(); - stream->writeBytes(reinterpret_cast(&binaryIdentifier), sizeof(GUID)); + size_t geometryShaderSize = geometryExe->getLength(); + stream->writeInt(geometryShaderSize); + stream->writeBytes(geometryExe->getFunction(), geometryShaderSize); + } return gl::Error(GL_NO_ERROR); } -gl::Error ProgramD3D::getPixelExecutableForFramebuffer(const gl::Framebuffer *fbo, ShaderExecutableD3D **outExecutable) +void ProgramD3D::setBinaryRetrievableHint(bool /* retrievable */) +{ +} + +gl::Error ProgramD3D::getPixelExecutableForFramebuffer(const gl::Framebuffer *fbo, + ShaderExecutableD3D **outExecutable) { mPixelShaderOutputFormatCache.clear(); const FramebufferD3D *fboD3D = GetImplAs(fbo); - const gl::AttachmentList &colorbuffers = fboD3D->getColorAttachmentsForRender(mRenderer->getWorkarounds()); + const gl::AttachmentList &colorbuffers = fboD3D->getColorAttachmentsForRender(); for (size_t colorAttachment = 0; colorAttachment < colorbuffers.size(); ++colorAttachment) { @@ -862,7 +1124,9 @@ gl::Error ProgramD3D::getPixelExecutableForFramebuffer(const gl::Framebuffer *fb if (colorbuffer) { - mPixelShaderOutputFormatCache.push_back(colorbuffer->getBinding() == GL_BACK ? GL_COLOR_ATTACHMENT0 : colorbuffer->getBinding()); + mPixelShaderOutputFormatCache.push_back(colorbuffer->getBinding() == GL_BACK + ? GL_COLOR_ATTACHMENT0 + : colorbuffer->getBinding()); } else { @@ -886,8 +1150,8 @@ gl::Error ProgramD3D::getPixelExecutableForOutputLayout(const std::vectorgeneratePixelShaderForOutputSignature(mPixelHLSL, mPixelShaderKey, mUsesFragDepth, - outputSignature); + std::string finalPixelHLSL = mDynamicHLSL->generatePixelShaderForOutputSignature( + mPixelHLSL, mPixelShaderKey, mUsesFragDepth, outputSignature); // Generate new pixel executable ShaderExecutableD3D *pixelExecutable = NULL; @@ -895,10 +1159,10 @@ gl::Error ProgramD3D::getPixelExecutableForOutputLayout(const std::vectorcompileToExecutable(*currentInfoLog, finalPixelHLSL, SHADER_PIXEL, - mTransformFeedbackLinkedVaryings, - (mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS), - mPixelWorkarounds, &pixelExecutable); + gl::Error error = mRenderer->compileToExecutable( + *currentInfoLog, finalPixelHLSL, SHADER_PIXEL, mStreamOutVaryings, + (mData.getTransformFeedbackBufferMode() == GL_SEPARATE_ATTRIBS), mPixelWorkarounds, + &pixelExecutable); if (error.isError()) { return error; @@ -911,7 +1175,7 @@ gl::Error ProgramD3D::getPixelExecutableForOutputLayout(const std::vector tempCharBuffer(tempInfoLog.getLength() + 3); - tempInfoLog.getLog(tempInfoLog.getLength(), NULL, &tempCharBuffer[0]); + tempInfoLog.getLog(static_cast(tempInfoLog.getLength()), NULL, &tempCharBuffer[0]); ERR("Error compiling dynamic pixel executable:\n%s\n", &tempCharBuffer[0]); } @@ -919,16 +1183,15 @@ gl::Error ProgramD3D::getPixelExecutableForOutputLayout(const std::vectormatchesSignature(signature)) + if (mVertexExecutables[executableIndex]->matchesSignature(mCachedVertexSignature)) { *outExectuable = mVertexExecutables[executableIndex]->shaderExecutable(); return gl::Error(GL_NO_ERROR); @@ -936,7 +1199,8 @@ gl::Error ProgramD3D::getVertexExecutableForInputLayout(const gl::VertexFormat i } // Generate new dynamic layout with attribute conversions - std::string finalVertexHLSL = mDynamicHLSL->generateVertexShaderForInputLayout(mVertexHLSL, inputLayout, getShaderAttributes()); + std::string finalVertexHLSL = mDynamicHLSL->generateVertexShaderForInputLayout( + mVertexHLSL, inputLayout, mData.getAttributes()); // Generate new vertex executable ShaderExecutableD3D *vertexExecutable = NULL; @@ -944,10 +1208,10 @@ gl::Error ProgramD3D::getVertexExecutableForInputLayout(const gl::VertexFormat i gl::InfoLog tempInfoLog; gl::InfoLog *currentInfoLog = infoLog ? infoLog : &tempInfoLog; - gl::Error error = mRenderer->compileToExecutable(*currentInfoLog, finalVertexHLSL, SHADER_VERTEX, - mTransformFeedbackLinkedVaryings, - (mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS), - mVertexWorkarounds, &vertexExecutable); + gl::Error error = mRenderer->compileToExecutable( + *currentInfoLog, finalVertexHLSL, SHADER_VERTEX, mStreamOutVaryings, + (mData.getTransformFeedbackBufferMode() == GL_SEPARATE_ATTRIBS), mVertexWorkarounds, + &vertexExecutable); if (error.isError()) { return error; @@ -955,12 +1219,13 @@ gl::Error ProgramD3D::getVertexExecutableForInputLayout(const gl::VertexFormat i if (vertexExecutable) { - mVertexExecutables.push_back(new VertexExecutable(inputLayout, signature, vertexExecutable)); + mVertexExecutables.push_back( + new VertexExecutable(inputLayout, mCachedVertexSignature, vertexExecutable)); } else if (!infoLog) { std::vector tempCharBuffer(tempInfoLog.getLength() + 3); - tempInfoLog.getLog(tempInfoLog.getLength(), NULL, &tempCharBuffer[0]); + tempInfoLog.getLog(static_cast(tempInfoLog.getLength()), NULL, &tempCharBuffer[0]); ERR("Error compiling dynamic vertex executable:\n%s\n", &tempCharBuffer[0]); } @@ -968,50 +1233,96 @@ gl::Error ProgramD3D::getVertexExecutableForInputLayout(const gl::VertexFormat i return gl::Error(GL_NO_ERROR); } -LinkResult ProgramD3D::compileProgramExecutables(gl::InfoLog &infoLog, gl::Shader *fragmentShader, gl::Shader *vertexShader, - int registers) +gl::Error ProgramD3D::getGeometryExecutableForPrimitiveType(const gl::Data &data, + GLenum drawMode, + ShaderExecutableD3D **outExecutable, + gl::InfoLog *infoLog) { - ShaderD3D *vertexShaderD3D = GetImplAs(vertexShader); - ShaderD3D *fragmentShaderD3D = GetImplAs(fragmentShader); + if (outExecutable) + { + *outExecutable = nullptr; + } + + // Return a null shader if the current rendering doesn't use a geometry shader + if (!usesGeometryShader(drawMode)) + { + return gl::Error(GL_NO_ERROR); + } + + gl::PrimitiveType geometryShaderType = GetGeometryShaderTypeFromDrawMode(drawMode); + + if (mGeometryExecutables[geometryShaderType] != nullptr) + { + if (outExecutable) + { + *outExecutable = mGeometryExecutables[geometryShaderType]; + } + return gl::Error(GL_NO_ERROR); + } + + std::string geometryHLSL = mDynamicHLSL->generateGeometryShaderHLSL( + geometryShaderType, data, mData, mRenderer->presentPathFastEnabled(), + mGeometryShaderPreamble); + + gl::InfoLog tempInfoLog; + gl::InfoLog *currentInfoLog = infoLog ? infoLog : &tempInfoLog; + + gl::Error error = mRenderer->compileToExecutable( + *currentInfoLog, geometryHLSL, SHADER_GEOMETRY, mStreamOutVaryings, + (mData.getTransformFeedbackBufferMode() == GL_SEPARATE_ATTRIBS), D3DCompilerWorkarounds(), + &mGeometryExecutables[geometryShaderType]); + + if (!infoLog && error.isError()) + { + std::vector tempCharBuffer(tempInfoLog.getLength() + 3); + tempInfoLog.getLog(static_cast(tempInfoLog.getLength()), NULL, &tempCharBuffer[0]); + ERR("Error compiling dynamic geometry executable:\n%s\n", &tempCharBuffer[0]); + } + + if (outExecutable) + { + *outExecutable = mGeometryExecutables[geometryShaderType]; + } + return error; +} - gl::VertexFormat defaultInputLayout[gl::MAX_VERTEX_ATTRIBS]; - GetDefaultInputLayoutFromShader(vertexShader->getActiveAttributes(), defaultInputLayout); +LinkResult ProgramD3D::compileProgramExecutables(const gl::Data &data, gl::InfoLog &infoLog) +{ + const gl::InputLayout &defaultInputLayout = + GetDefaultInputLayoutFromShader(mData.getAttachedVertexShader()); ShaderExecutableD3D *defaultVertexExecutable = NULL; - gl::Error error = getVertexExecutableForInputLayout(defaultInputLayout, &defaultVertexExecutable, &infoLog); + gl::Error error = + getVertexExecutableForInputLayout(defaultInputLayout, &defaultVertexExecutable, &infoLog); if (error.isError()) { return LinkResult(false, error); } - std::vector defaultPixelOutput = GetDefaultOutputLayoutFromShader(getPixelShaderKey()); + std::vector defaultPixelOutput = GetDefaultOutputLayoutFromShader(getPixelShaderKey()); ShaderExecutableD3D *defaultPixelExecutable = NULL; - error = getPixelExecutableForOutputLayout(defaultPixelOutput, &defaultPixelExecutable, &infoLog); + error = + getPixelExecutableForOutputLayout(defaultPixelOutput, &defaultPixelExecutable, &infoLog); if (error.isError()) { return LinkResult(false, error); } - if (usesGeometryShader()) + // Auto-generate the geometry shader here, if we expect to be using point rendering in D3D11. + ShaderExecutableD3D *pointGS = nullptr; + if (usesGeometryShader(GL_POINTS)) { - std::string geometryHLSL = mDynamicHLSL->generateGeometryShaderHLSL(registers, fragmentShaderD3D, vertexShaderD3D); - - - error = mRenderer->compileToExecutable(infoLog, geometryHLSL, SHADER_GEOMETRY, mTransformFeedbackLinkedVaryings, - (mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS), - D3DCompilerWorkarounds(), &mGeometryExecutable); - if (error.isError()) - { - return LinkResult(false, error); - } + getGeometryExecutableForPrimitiveType(data, GL_POINTS, &pointGS, &infoLog); } -#if ANGLE_SHADER_DEBUG_INFO == ANGLE_ENABLED - if (usesGeometryShader() && mGeometryExecutable) + const ShaderD3D *vertexShaderD3D = GetImplAs(mData.getAttachedVertexShader()); + + if (usesGeometryShader(GL_POINTS) && 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 pre-pended to the vertex shader, this is a bit of a clutch + // 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. vertexShaderD3D->appendDebugInfo("// GEOMETRY SHADER BEGIN\n\n"); - vertexShaderD3D->appendDebugInfo(mGeometryExecutable->getDebugInfo()); + vertexShaderD3D->appendDebugInfo(pointGS->getDebugInfo()); vertexShaderD3D->appendDebugInfo("\nGEOMETRY SHADER END\n\n\n"); } @@ -1022,200 +1333,306 @@ LinkResult ProgramD3D::compileProgramExecutables(gl::InfoLog &infoLog, gl::Shade if (defaultPixelExecutable) { + const ShaderD3D *fragmentShaderD3D = + GetImplAs(mData.getAttachedFragmentShader()); fragmentShaderD3D->appendDebugInfo(defaultPixelExecutable->getDebugInfo()); } -#endif - bool linkSuccess = (defaultVertexExecutable && defaultPixelExecutable && (!usesGeometryShader() || mGeometryExecutable)); + bool linkSuccess = (defaultVertexExecutable && defaultPixelExecutable && + (!usesGeometryShader(GL_POINTS) || pointGS)); return LinkResult(linkSuccess, gl::Error(GL_NO_ERROR)); } -LinkResult ProgramD3D::link(const gl::Data &data, gl::InfoLog &infoLog, - gl::Shader *fragmentShader, gl::Shader *vertexShader, - const std::vector &transformFeedbackVaryings, - GLenum transformFeedbackBufferMode, - int *registers, std::vector *linkedVaryings, - std::map *outputVariables) +LinkResult ProgramD3D::link(const gl::Data &data, gl::InfoLog &infoLog) { - ShaderD3D *vertexShaderD3D = GetImplAs(vertexShader); - ShaderD3D *fragmentShaderD3D = GetImplAs(fragmentShader); + reset(); - mSamplersPS.resize(data.caps->maxTextureImageUnits); - mSamplersVS.resize(data.caps->maxVertexTextureImageUnits); + const gl::Shader *vertexShader = mData.getAttachedVertexShader(); + const gl::Shader *fragmentShader = mData.getAttachedFragmentShader(); - mTransformFeedbackBufferMode = transformFeedbackBufferMode; + const ShaderD3D *vertexShaderD3D = GetImplAs(vertexShader); + const ShaderD3D *fragmentShaderD3D = GetImplAs(fragmentShader); - mPixelHLSL = fragmentShaderD3D->getTranslatedSource(); - fragmentShaderD3D->generateWorkarounds(&mPixelWorkarounds); + mSamplersVS.resize(data.caps->maxVertexTextureImageUnits); + mSamplersPS.resize(data.caps->maxTextureImageUnits); - mVertexHLSL = vertexShaderD3D->getTranslatedSource(); vertexShaderD3D->generateWorkarounds(&mVertexWorkarounds); - mShaderVersion = vertexShaderD3D->getShaderVersion(); + fragmentShaderD3D->generateWorkarounds(&mPixelWorkarounds); + + if (mRenderer->getRendererLimitations().noFrontFacingSupport) + { + if (fragmentShaderD3D->usesFrontFacing()) + { + infoLog << "The current renderer doesn't support gl_FrontFacing"; + return LinkResult(false, gl::Error(GL_NO_ERROR)); + } + } + + std::vector packedVaryings = + MergeVaryings(*vertexShader, *fragmentShader, mData.getTransformFeedbackVaryingNames()); // Map the varyings to the register file - VaryingPacking packing = { NULL }; - *registers = mDynamicHLSL->packVaryings(infoLog, packing, fragmentShaderD3D, vertexShaderD3D, transformFeedbackVaryings); + VaryingPacking varyingPacking(data.caps->maxVaryingVectors); + if (!varyingPacking.packVaryings(infoLog, packedVaryings, + mData.getTransformFeedbackVaryingNames())) + { + return LinkResult(false, gl::Error(GL_NO_ERROR)); + } - if (*registers < 0) + ProgramD3DMetadata metadata(mRenderer->getMajorShaderModel(), mRenderer->getShaderModelSuffix(), + usesInstancedPointSpriteEmulation(), + mRenderer->presentPathFastEnabled(), vertexShaderD3D, + fragmentShaderD3D); + + varyingPacking.enableBuiltins(SHADER_VERTEX, metadata); + varyingPacking.enableBuiltins(SHADER_PIXEL, metadata); + + if (static_cast(varyingPacking.getRegisterCount()) > data.caps->maxVaryingVectors) { + infoLog << "No varying registers left to support gl_FragCoord/gl_PointCoord"; return LinkResult(false, gl::Error(GL_NO_ERROR)); } - if (!gl::Program::linkVaryings(infoLog, fragmentShader, vertexShader)) + // TODO(jmadill): Implement more sophisticated component packing in D3D9. + // We can fail here because we use one semantic per GLSL varying. D3D11 can pack varyings + // intelligently, but D3D9 assumes one semantic per register. + if (mRenderer->getRendererClass() == RENDERER_D3D9 && + varyingPacking.getMaxSemanticIndex() > data.caps->maxVaryingVectors) { + infoLog << "Cannot pack these varyings on D3D9."; return LinkResult(false, gl::Error(GL_NO_ERROR)); } - if (!mDynamicHLSL->generateShaderLinkHLSL(data, infoLog, *registers, packing, mPixelHLSL, mVertexHLSL, - fragmentShaderD3D, vertexShaderD3D, transformFeedbackVaryings, - linkedVaryings, outputVariables, &mPixelShaderKey, &mUsesFragDepth)) + if (!mDynamicHLSL->generateShaderLinkHLSL(data, mData, metadata, varyingPacking, &mPixelHLSL, + &mVertexHLSL)) { return LinkResult(false, gl::Error(GL_NO_ERROR)); } mUsesPointSize = vertexShaderD3D->usesPointSize(); + mDynamicHLSL->getPixelShaderOutputKey(data, mData, metadata, &mPixelShaderKey); + mUsesFragDepth = metadata.usesFragDepth(mData); + + // Cache if we use flat shading + mUsesFlatInterpolation = false; + for (const auto &varying : packedVaryings) + { + if (varying.interpolation == sh::INTERPOLATION_FLAT) + { + mUsesFlatInterpolation = true; + break; + } + } + + if (mRenderer->getMajorShaderModel() >= 4) + { + varyingPacking.enableBuiltins(SHADER_GEOMETRY, metadata); + mGeometryShaderPreamble = mDynamicHLSL->generateGeometryShaderPreamble(varyingPacking); + } + + initAttribLocationsToD3DSemantic(); - initAttributesByLayout(); + defineUniformsAndAssignRegisters(); + + gatherTransformFeedbackVaryings(varyingPacking); + + LinkResult result = compileProgramExecutables(data, infoLog); + if (result.error.isError() || !result.linkSuccess) + { + infoLog << "Failed to create D3D shaders."; + return result; + } + + initUniformBlockInfo(); return LinkResult(true, gl::Error(GL_NO_ERROR)); } -void ProgramD3D::getInputLayoutSignature(const gl::VertexFormat inputLayout[], GLenum signature[]) const +GLboolean ProgramD3D::validate(const gl::Caps & /*caps*/, gl::InfoLog * /*infoLog*/) +{ + // TODO(jmadill): Do something useful here? + return GL_TRUE; +} + +void ProgramD3D::initUniformBlockInfo() +{ + const gl::Shader *vertexShader = mData.getAttachedVertexShader(); + + for (const sh::InterfaceBlock &vertexBlock : vertexShader->getInterfaceBlocks()) + { + if (!vertexBlock.staticUse && vertexBlock.layout == sh::BLOCKLAYOUT_PACKED) + continue; + + if (mBlockDataSizes.count(vertexBlock.name) > 0) + continue; + + size_t dataSize = getUniformBlockInfo(vertexBlock); + mBlockDataSizes[vertexBlock.name] = dataSize; + } + + const gl::Shader *fragmentShader = mData.getAttachedFragmentShader(); + + for (const sh::InterfaceBlock &fragmentBlock : fragmentShader->getInterfaceBlocks()) + { + if (!fragmentBlock.staticUse && fragmentBlock.layout == sh::BLOCKLAYOUT_PACKED) + continue; + + if (mBlockDataSizes.count(fragmentBlock.name) > 0) + continue; + + size_t dataSize = getUniformBlockInfo(fragmentBlock); + mBlockDataSizes[fragmentBlock.name] = dataSize; + } +} + +void ProgramD3D::assignUniformBlockRegisters() { - mDynamicHLSL->getInputLayoutSignature(inputLayout, signature); + mD3DUniformBlocks.clear(); + + // Assign registers and update sizes. + const ShaderD3D *vertexShaderD3D = GetImplAs(mData.getAttachedVertexShader()); + const ShaderD3D *fragmentShaderD3D = GetImplAs(mData.getAttachedFragmentShader()); + + for (const gl::UniformBlock &uniformBlock : mData.getUniformBlocks()) + { + unsigned int uniformBlockElement = uniformBlock.isArray ? uniformBlock.arrayElement : 0; + + D3DUniformBlock d3dUniformBlock; + + if (uniformBlock.vertexStaticUse) + { + unsigned int baseRegister = + vertexShaderD3D->getInterfaceBlockRegister(uniformBlock.name); + d3dUniformBlock.vsRegisterIndex = baseRegister + uniformBlockElement; + } + + if (uniformBlock.fragmentStaticUse) + { + unsigned int baseRegister = + fragmentShaderD3D->getInterfaceBlockRegister(uniformBlock.name); + d3dUniformBlock.psRegisterIndex = baseRegister + uniformBlockElement; + } + + mD3DUniformBlocks.push_back(d3dUniformBlock); + } } void ProgramD3D::initializeUniformStorage() { // Compute total default block size - unsigned int vertexRegisters = 0; + unsigned int vertexRegisters = 0; unsigned int fragmentRegisters = 0; - for (size_t uniformIndex = 0; uniformIndex < mUniforms.size(); uniformIndex++) + for (const D3DUniform *d3dUniform : mD3DUniforms) { - const gl::LinkedUniform &uniform = *mUniforms[uniformIndex]; - - if (!gl::IsSamplerType(uniform.type)) + if (!d3dUniform->isSampler()) { - if (uniform.isReferencedByVertexShader()) + if (d3dUniform->isReferencedByVertexShader()) { - vertexRegisters = std::max(vertexRegisters, uniform.vsRegisterIndex + uniform.registerCount); + vertexRegisters = std::max(vertexRegisters, + d3dUniform->vsRegisterIndex + d3dUniform->registerCount); } - if (uniform.isReferencedByFragmentShader()) + if (d3dUniform->isReferencedByFragmentShader()) { - fragmentRegisters = std::max(fragmentRegisters, uniform.psRegisterIndex + uniform.registerCount); + fragmentRegisters = std::max( + fragmentRegisters, d3dUniform->psRegisterIndex + d3dUniform->registerCount); } } } - mVertexUniformStorage = mRenderer->createUniformStorage(vertexRegisters * 16u); + mVertexUniformStorage = mRenderer->createUniformStorage(vertexRegisters * 16u); mFragmentUniformStorage = mRenderer->createUniformStorage(fragmentRegisters * 16u); } -gl::Error ProgramD3D::applyUniforms() +gl::Error ProgramD3D::applyUniforms(GLenum drawMode) { - updateSamplerMapping(); + ASSERT(!mDirtySamplerMapping); - gl::Error error = mRenderer->applyUniforms(*this, mUniforms); + gl::Error error = mRenderer->applyUniforms(*this, drawMode, mD3DUniforms); if (error.isError()) { return error; } - for (size_t uniformIndex = 0; uniformIndex < mUniforms.size(); uniformIndex++) + for (D3DUniform *d3dUniform : mD3DUniforms) { - mUniforms[uniformIndex]->dirty = false; + d3dUniform->dirty = false; } return gl::Error(GL_NO_ERROR); } -gl::Error ProgramD3D::applyUniformBuffers(const gl::Data &data, GLuint uniformBlockBindings[]) +gl::Error ProgramD3D::applyUniformBuffers(const gl::Data &data) { - GLint vertexUniformBuffers[gl::IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS]; - GLint fragmentUniformBuffers[gl::IMPLEMENTATION_MAX_FRAGMENT_SHADER_UNIFORM_BUFFERS]; - - for (unsigned int registerIndex = 0; registerIndex < gl::IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS; ++registerIndex) + if (mData.getUniformBlocks().empty()) { - vertexUniformBuffers[registerIndex] = -1; + return gl::Error(GL_NO_ERROR); } - for (unsigned int registerIndex = 0; registerIndex < gl::IMPLEMENTATION_MAX_FRAGMENT_SHADER_UNIFORM_BUFFERS; ++registerIndex) + // Lazy init. + if (mD3DUniformBlocks.empty()) { - fragmentUniformBuffers[registerIndex] = -1; + assignUniformBlockRegisters(); } + mVertexUBOCache.clear(); + mFragmentUBOCache.clear(); + const unsigned int reservedBuffersInVS = mRenderer->getReservedVertexUniformBuffers(); const unsigned int reservedBuffersInFS = mRenderer->getReservedFragmentUniformBuffers(); - for (unsigned int uniformBlockIndex = 0; uniformBlockIndex < mUniformBlocks.size(); uniformBlockIndex++) + for (unsigned int uniformBlockIndex = 0; uniformBlockIndex < mD3DUniformBlocks.size(); + uniformBlockIndex++) { - gl::UniformBlock *uniformBlock = mUniformBlocks[uniformBlockIndex]; - GLuint blockBinding = uniformBlockBindings[uniformBlockIndex]; - - ASSERT(uniformBlock); + const D3DUniformBlock &uniformBlock = mD3DUniformBlocks[uniformBlockIndex]; + GLuint blockBinding = mData.getUniformBlockBinding(uniformBlockIndex); // Unnecessary to apply an unreferenced standard or shared UBO - if (!uniformBlock->isReferencedByVertexShader() && !uniformBlock->isReferencedByFragmentShader()) + if (!uniformBlock.vertexStaticUse() && !uniformBlock.fragmentStaticUse()) { continue; } - if (uniformBlock->isReferencedByVertexShader()) + if (uniformBlock.vertexStaticUse()) { - unsigned int registerIndex = uniformBlock->vsRegisterIndex - reservedBuffersInVS; - ASSERT(vertexUniformBuffers[registerIndex] == -1); + unsigned int registerIndex = uniformBlock.vsRegisterIndex - reservedBuffersInVS; ASSERT(registerIndex < data.caps->maxVertexUniformBlocks); - vertexUniformBuffers[registerIndex] = blockBinding; + + if (mVertexUBOCache.size() <= registerIndex) + { + mVertexUBOCache.resize(registerIndex + 1, -1); + } + + ASSERT(mVertexUBOCache[registerIndex] == -1); + mVertexUBOCache[registerIndex] = blockBinding; } - if (uniformBlock->isReferencedByFragmentShader()) + if (uniformBlock.fragmentStaticUse()) { - unsigned int registerIndex = uniformBlock->psRegisterIndex - reservedBuffersInFS; - ASSERT(fragmentUniformBuffers[registerIndex] == -1); + unsigned int registerIndex = uniformBlock.psRegisterIndex - reservedBuffersInFS; ASSERT(registerIndex < data.caps->maxFragmentUniformBlocks); - fragmentUniformBuffers[registerIndex] = blockBinding; - } - } - return mRenderer->setUniformBuffers(data, vertexUniformBuffers, fragmentUniformBuffers); -} + if (mFragmentUBOCache.size() <= registerIndex) + { + mFragmentUBOCache.resize(registerIndex + 1, -1); + } -bool ProgramD3D::assignUniformBlockRegister(gl::InfoLog &infoLog, gl::UniformBlock *uniformBlock, GLenum shader, - unsigned int registerIndex, const gl::Caps &caps) -{ - if (shader == GL_VERTEX_SHADER) - { - uniformBlock->vsRegisterIndex = registerIndex; - if (registerIndex - mRenderer->getReservedVertexUniformBuffers() >= caps.maxVertexUniformBlocks) - { - infoLog.append("Vertex shader uniform block count exceed GL_MAX_VERTEX_UNIFORM_BLOCKS (%u)", caps.maxVertexUniformBlocks); - return false; - } - } - else if (shader == GL_FRAGMENT_SHADER) - { - uniformBlock->psRegisterIndex = registerIndex; - if (registerIndex - mRenderer->getReservedFragmentUniformBuffers() >= caps.maxFragmentUniformBlocks) - { - infoLog.append("Fragment shader uniform block count exceed GL_MAX_FRAGMENT_UNIFORM_BLOCKS (%u)", caps.maxFragmentUniformBlocks); - return false; + ASSERT(mFragmentUBOCache[registerIndex] == -1); + mFragmentUBOCache[registerIndex] = blockBinding; } } - else UNREACHABLE(); - return true; + return mRenderer->setUniformBuffers(data, mVertexUBOCache, mFragmentUBOCache); } void ProgramD3D::dirtyAllUniforms() { - unsigned int numUniforms = mUniforms.size(); - for (unsigned int index = 0; index < numUniforms; index++) + for (D3DUniform *d3dUniform : mD3DUniforms) { - mUniforms[index]->dirty = true; + d3dUniform->dirty = true; } } -void ProgramD3D::setUniform1fv(GLint location, GLsizei count, const GLfloat* v) +void ProgramD3D::setUniform1fv(GLint location, GLsizei count, const GLfloat *v) { setUniform(location, count, v, GL_FLOAT); } @@ -1235,47 +1652,74 @@ void ProgramD3D::setUniform4fv(GLint location, GLsizei count, const GLfloat *v) setUniform(location, count, v, GL_FLOAT_VEC4); } -void ProgramD3D::setUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) +void ProgramD3D::setUniformMatrix2fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) { setUniformMatrixfv<2, 2>(location, count, transpose, value, GL_FLOAT_MAT2); } -void ProgramD3D::setUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) +void ProgramD3D::setUniformMatrix3fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) { setUniformMatrixfv<3, 3>(location, count, transpose, value, GL_FLOAT_MAT3); } -void ProgramD3D::setUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) +void ProgramD3D::setUniformMatrix4fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) { setUniformMatrixfv<4, 4>(location, count, transpose, value, GL_FLOAT_MAT4); } -void ProgramD3D::setUniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) +void ProgramD3D::setUniformMatrix2x3fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) { setUniformMatrixfv<2, 3>(location, count, transpose, value, GL_FLOAT_MAT2x3); } -void ProgramD3D::setUniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) +void ProgramD3D::setUniformMatrix3x2fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) { setUniformMatrixfv<3, 2>(location, count, transpose, value, GL_FLOAT_MAT3x2); } -void ProgramD3D::setUniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) +void ProgramD3D::setUniformMatrix2x4fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) { setUniformMatrixfv<2, 4>(location, count, transpose, value, GL_FLOAT_MAT2x4); } -void ProgramD3D::setUniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) +void ProgramD3D::setUniformMatrix4x2fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) { setUniformMatrixfv<4, 2>(location, count, transpose, value, GL_FLOAT_MAT4x2); } -void ProgramD3D::setUniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) +void ProgramD3D::setUniformMatrix3x4fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) { setUniformMatrixfv<3, 4>(location, count, transpose, value, GL_FLOAT_MAT3x4); } -void ProgramD3D::setUniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) +void ProgramD3D::setUniformMatrix4x3fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) { setUniformMatrixfv<4, 3>(location, count, transpose, value, GL_FLOAT_MAT4x3); } @@ -1320,106 +1764,87 @@ void ProgramD3D::setUniform4uiv(GLint location, GLsizei count, const GLuint *v) setUniform(location, count, v, GL_UNSIGNED_INT_VEC4); } -void ProgramD3D::getUniformfv(GLint location, GLfloat *params) -{ - getUniformv(location, params, GL_FLOAT); -} - -void ProgramD3D::getUniformiv(GLint location, GLint *params) +void ProgramD3D::setUniformBlockBinding(GLuint /*uniformBlockIndex*/, + GLuint /*uniformBlockBinding*/) { - getUniformv(location, params, GL_INT); } -void ProgramD3D::getUniformuiv(GLint location, GLuint *params) +void ProgramD3D::defineUniformsAndAssignRegisters() { - getUniformv(location, params, GL_UNSIGNED_INT); -} - -bool ProgramD3D::linkUniforms(gl::InfoLog &infoLog, const gl::Shader &vertexShader, const gl::Shader &fragmentShader, - const gl::Caps &caps) -{ - const ShaderD3D *vertexShaderD3D = GetImplAs(&vertexShader); - const ShaderD3D *fragmentShaderD3D = GetImplAs(&fragmentShader); - - const std::vector &vertexUniforms = vertexShader.getUniforms(); - const std::vector &fragmentUniforms = fragmentShader.getUniforms(); - - // Check that uniforms defined in the vertex and fragment shaders are identical - typedef std::map UniformMap; - UniformMap linkedUniforms; - - for (unsigned int vertexUniformIndex = 0; vertexUniformIndex < vertexUniforms.size(); vertexUniformIndex++) - { - const sh::Uniform &vertexUniform = vertexUniforms[vertexUniformIndex]; - linkedUniforms[vertexUniform.name] = &vertexUniform; - } + D3DUniformMap uniformMap; + const gl::Shader *vertexShader = mData.getAttachedVertexShader(); + for (const sh::Uniform &vertexUniform : vertexShader->getUniforms()) - for (unsigned int fragmentUniformIndex = 0; fragmentUniformIndex < fragmentUniforms.size(); fragmentUniformIndex++) { - const sh::Uniform &fragmentUniform = fragmentUniforms[fragmentUniformIndex]; - UniformMap::const_iterator entry = linkedUniforms.find(fragmentUniform.name); - if (entry != linkedUniforms.end()) + if (vertexUniform.staticUse) { - const sh::Uniform &vertexUniform = *entry->second; - const std::string &uniformName = "uniform '" + vertexUniform.name + "'"; - if (!gl::Program::linkValidateUniforms(infoLog, uniformName, vertexUniform, fragmentUniform)) - { - return false; - } + defineUniformBase(vertexShader, vertexUniform, &uniformMap); } } - for (unsigned int uniformIndex = 0; uniformIndex < vertexUniforms.size(); uniformIndex++) + const gl::Shader *fragmentShader = mData.getAttachedFragmentShader(); + for (const sh::Uniform &fragmentUniform : fragmentShader->getUniforms()) { - const sh::Uniform &uniform = vertexUniforms[uniformIndex]; - - if (uniform.staticUse) + if (fragmentUniform.staticUse) { - unsigned int registerBase = uniform.isBuiltIn() ? GL_INVALID_INDEX : - vertexShaderD3D->getUniformRegister(uniform.name); - defineUniformBase(vertexShaderD3D, uniform, registerBase); + defineUniformBase(fragmentShader, fragmentUniform, &uniformMap); } } - for (unsigned int uniformIndex = 0; uniformIndex < fragmentUniforms.size(); uniformIndex++) + // Initialize the D3DUniform list to mirror the indexing of the GL layer. + for (const gl::LinkedUniform &glUniform : mData.getUniforms()) { - const sh::Uniform &uniform = fragmentUniforms[uniformIndex]; - - if (uniform.staticUse) - { - unsigned int registerBase = uniform.isBuiltIn() ? GL_INVALID_INDEX : - fragmentShaderD3D->getUniformRegister(uniform.name); - defineUniformBase(fragmentShaderD3D, uniform, registerBase); - } - } + if (!glUniform.isInDefaultBlock()) + continue; - if (!indexUniforms(infoLog, caps)) - { - return false; + auto mapEntry = uniformMap.find(glUniform.name); + ASSERT(mapEntry != uniformMap.end()); + mD3DUniforms.push_back(mapEntry->second); } + assignAllSamplerRegisters(); initializeUniformStorage(); - - return true; } -void ProgramD3D::defineUniformBase(const ShaderD3D *shader, const sh::Uniform &uniform, unsigned int uniformRegister) +void ProgramD3D::defineUniformBase(const gl::Shader *shader, + const sh::Uniform &uniform, + D3DUniformMap *uniformMap) { - if (uniformRegister == GL_INVALID_INDEX) + // Samplers get their registers assigned in assignAllSamplerRegisters. + if (uniform.isBuiltIn() || gl::IsSamplerType(uniform.type)) { - defineUniform(shader, uniform, uniform.name, nullptr); + defineUniform(shader->getType(), uniform, uniform.name, nullptr, uniformMap); return; } - ShShaderOutput outputType = shader->getCompilerOutputType(); + const ShaderD3D *shaderD3D = GetImplAs(shader); + + unsigned int startRegister = shaderD3D->getUniformRegister(uniform.name); + ShShaderOutput outputType = shaderD3D->getCompilerOutputType(); sh::HLSLBlockEncoder encoder(sh::HLSLBlockEncoder::GetStrategyFor(outputType)); - encoder.skipRegisters(uniformRegister); + encoder.skipRegisters(startRegister); + + defineUniform(shader->getType(), uniform, uniform.name, &encoder, uniformMap); +} + +D3DUniform *ProgramD3D::getD3DUniformByName(const std::string &name) +{ + for (D3DUniform *d3dUniform : mD3DUniforms) + { + if (d3dUniform->name == name) + { + return d3dUniform; + } + } - defineUniform(shader, uniform, uniform.name, &encoder); + return nullptr; } -void ProgramD3D::defineUniform(const ShaderD3D *shader, const sh::ShaderVariable &uniform, - const std::string &fullName, sh::HLSLBlockEncoder *encoder) +void ProgramD3D::defineUniform(GLenum shaderType, + const sh::ShaderVariable &uniform, + const std::string &fullName, + sh::HLSLBlockEncoder *encoder, + D3DUniformMap *uniformMap) { if (uniform.isStruct()) { @@ -1432,92 +1857,95 @@ void ProgramD3D::defineUniform(const ShaderD3D *shader, const sh::ShaderVariable for (size_t fieldIndex = 0; fieldIndex < uniform.fields.size(); fieldIndex++) { - const sh::ShaderVariable &field = uniform.fields[fieldIndex]; + const sh::ShaderVariable &field = uniform.fields[fieldIndex]; const std::string &fieldFullName = (fullName + elementString + "." + field.name); - defineUniform(shader, field, fieldFullName, encoder); + // Samplers get their registers assigned in assignAllSamplerRegisters. + // Also they couldn't use the same encoder as the rest of the struct, since they are + // extracted out of the struct by the shader translator. + if (gl::IsSamplerType(field.type)) + { + defineUniform(shaderType, field, fieldFullName, nullptr, uniformMap); + } + else + { + defineUniform(shaderType, field, fieldFullName, encoder, uniformMap); + } } if (encoder) encoder->exitAggregateType(); } + return; } - else // Not a struct + + // Not a struct. Arrays are treated as aggregate types. + if (uniform.isArray() && encoder) { - // Arrays are treated as aggregate types - if (uniform.isArray() && encoder) - { - encoder->enterAggregateType(); - } + encoder->enterAggregateType(); + } - gl::LinkedUniform *linkedUniform = getUniformByName(fullName); + // Advance the uniform offset, to track registers allocation for structs + sh::BlockMemberInfo blockInfo = + encoder ? encoder->encodeType(uniform.type, uniform.arraySize, false) + : sh::BlockMemberInfo::getDefaultBlockInfo(); - // Advance the uniform offset, to track registers allocation for structs - sh::BlockMemberInfo blockInfo = encoder ? - encoder->encodeType(uniform.type, uniform.arraySize, false) : - sh::BlockMemberInfo::getDefaultBlockInfo(); + auto uniformMapEntry = uniformMap->find(fullName); + D3DUniform *d3dUniform = nullptr; - if (!linkedUniform) - { - linkedUniform = new gl::LinkedUniform(uniform.type, uniform.precision, fullName, uniform.arraySize, - -1, sh::BlockMemberInfo::getDefaultBlockInfo()); - ASSERT(linkedUniform); + if (uniformMapEntry != uniformMap->end()) + { + d3dUniform = uniformMapEntry->second; + } + else + { + d3dUniform = new D3DUniform(uniform.type, fullName, uniform.arraySize, true); + (*uniformMap)[fullName] = d3dUniform; + } - if (encoder) - linkedUniform->registerElement = sh::HLSLBlockEncoder::getBlockRegisterElement(blockInfo); - mUniforms.push_back(linkedUniform); + if (encoder) + { + d3dUniform->registerElement = + static_cast(sh::HLSLBlockEncoder::getBlockRegisterElement(blockInfo)); + unsigned int reg = + static_cast(sh::HLSLBlockEncoder::getBlockRegister(blockInfo)); + if (shaderType == GL_FRAGMENT_SHADER) + { + d3dUniform->psRegisterIndex = reg; } - - if (encoder) + else { - if (shader->getShaderType() == GL_FRAGMENT_SHADER) - { - linkedUniform->psRegisterIndex = sh::HLSLBlockEncoder::getBlockRegister(blockInfo); - } - else if (shader->getShaderType() == GL_VERTEX_SHADER) - { - linkedUniform->vsRegisterIndex = sh::HLSLBlockEncoder::getBlockRegister(blockInfo); - } - else UNREACHABLE(); + ASSERT(shaderType == GL_VERTEX_SHADER); + d3dUniform->vsRegisterIndex = reg; } // Arrays are treated as aggregate types - if (uniform.isArray() && encoder) + if (uniform.isArray()) { encoder->exitAggregateType(); - } - } -} - -template -static inline void SetIfDirty(T *dest, const T& source, bool *dirtyFlag) -{ - ASSERT(dest != NULL); - ASSERT(dirtyFlag != NULL); - - *dirtyFlag = *dirtyFlag || (memcmp(dest, &source, sizeof(T)) != 0); - *dest = source; + } + } } template -void ProgramD3D::setUniform(GLint location, GLsizei count, const T* v, GLenum targetUniformType) +void ProgramD3D::setUniform(GLint location, GLsizei countIn, const T *v, GLenum targetUniformType) { - const int components = gl::VariableComponentCount(targetUniformType); + const int components = gl::VariableComponentCount(targetUniformType); const GLenum targetBoolType = gl::VariableBoolVectorType(targetUniformType); - gl::LinkedUniform *targetUniform = getUniformByLocation(location); + D3DUniform *targetUniform = getD3DUniformFromLocation(location); - int elementCount = targetUniform->elementCount(); - - count = std::min(elementCount - (int)mUniformIndex[location].element, count); + unsigned int elementCount = targetUniform->elementCount(); + unsigned int arrayElement = mData.getUniformLocations()[location].element; + unsigned int count = std::min(elementCount - arrayElement, static_cast(countIn)); if (targetUniform->type == targetUniformType) { - T *target = reinterpret_cast(targetUniform->data) + mUniformIndex[location].element * 4; + T *target = reinterpret_cast(targetUniform->data) + arrayElement * 4; - for (int i = 0; i < count; i++) + for (unsigned int i = 0; i < count; i++) { - T *dest = target + (i * 4); + T *dest = target + (i * 4); const T *source = v + (i * components); for (int c = 0; c < components; c++) @@ -1532,16 +1960,17 @@ void ProgramD3D::setUniform(GLint location, GLsizei count, const T* v, GLenum ta } else if (targetUniform->type == targetBoolType) { - GLint *boolParams = reinterpret_cast(targetUniform->data) + mUniformIndex[location].element * 4; + GLint *boolParams = reinterpret_cast(targetUniform->data) + arrayElement * 4; - for (int i = 0; i < count; i++) + for (unsigned int i = 0; i < count; i++) { - GLint *dest = boolParams + (i * 4); + GLint *dest = boolParams + (i * 4); const T *source = v + (i * components); for (int c = 0; c < components; c++) { - SetIfDirty(dest + c, (source[c] == static_cast(0)) ? GL_FALSE : GL_TRUE, &targetUniform->dirty); + SetIfDirty(dest + c, (source[c] == static_cast(0)) ? GL_FALSE : GL_TRUE, + &targetUniform->dirty); } for (int c = components; c < 4; c++) { @@ -1549,18 +1978,18 @@ void ProgramD3D::setUniform(GLint location, GLsizei count, const T* v, GLenum ta } } } - else if (gl::IsSamplerType(targetUniform->type)) + else if (targetUniform->isSampler()) { ASSERT(targetUniformType == GL_INT); - GLint *target = reinterpret_cast(targetUniform->data) + mUniformIndex[location].element * 4; + GLint *target = reinterpret_cast(targetUniform->data) + arrayElement * 4; bool wasDirty = targetUniform->dirty; - for (int i = 0; i < count; i++) + for (unsigned int i = 0; i < count; i++) { - GLint *dest = target + (i * 4); - const GLint *source = reinterpret_cast(v) + (i * components); + GLint *dest = target + (i * 4); + const GLint *source = reinterpret_cast(v) + (i * components); SetIfDirty(dest + 0, source[0], &targetUniform->dirty); SetIfDirty(dest + 1, 0, &targetUniform->dirty); @@ -1573,407 +2002,145 @@ void ProgramD3D::setUniform(GLint location, GLsizei count, const T* v, GLenum ta mDirtySamplerMapping = true; } } - else UNREACHABLE(); -} - -template -bool transposeMatrix(T *target, const GLfloat *value, int targetWidth, int targetHeight, int srcWidth, int srcHeight) -{ - bool dirty = false; - int copyWidth = std::min(targetHeight, srcWidth); - int copyHeight = std::min(targetWidth, srcHeight); - - for (int x = 0; x < copyWidth; x++) - { - for (int y = 0; y < copyHeight; y++) - { - SetIfDirty(target + (x * targetWidth + y), static_cast(value[y * srcWidth + x]), &dirty); - } - } - // clear unfilled right side - for (int y = 0; y < copyWidth; y++) - { - for (int x = copyHeight; x < targetWidth; x++) - { - SetIfDirty(target + (y * targetWidth + x), static_cast(0), &dirty); - } - } - // clear unfilled bottom. - for (int y = copyWidth; y < targetHeight; y++) - { - for (int x = 0; x < targetWidth; x++) - { - SetIfDirty(target + (y * targetWidth + x), static_cast(0), &dirty); - } - } - - return dirty; -} - -template -bool expandMatrix(T *target, const GLfloat *value, int targetWidth, int targetHeight, int srcWidth, int srcHeight) -{ - bool dirty = false; - int copyWidth = std::min(targetWidth, srcWidth); - int copyHeight = std::min(targetHeight, srcHeight); - - for (int y = 0; y < copyHeight; y++) - { - for (int x = 0; x < copyWidth; x++) - { - SetIfDirty(target + (y * targetWidth + x), static_cast(value[y * srcWidth + x]), &dirty); - } - } - // clear unfilled right side - for (int y = 0; y < copyHeight; y++) - { - for (int x = copyWidth; x < targetWidth; x++) - { - SetIfDirty(target + (y * targetWidth + x), static_cast(0), &dirty); - } - } - // clear unfilled bottom. - for (int y = copyHeight; y < targetHeight; y++) - { - for (int x = 0; x < targetWidth; x++) - { - SetIfDirty(target + (y * targetWidth + x), static_cast(0), &dirty); - } - } - - return dirty; + else + UNREACHABLE(); } template -void ProgramD3D::setUniformMatrixfv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value, GLenum targetUniformType) +void ProgramD3D::setUniformMatrixfv(GLint location, + GLsizei countIn, + GLboolean transpose, + const GLfloat *value, + GLenum targetUniformType) { - gl::LinkedUniform *targetUniform = getUniformByLocation(location); + D3DUniform *targetUniform = getD3DUniformFromLocation(location); - int elementCount = targetUniform->elementCount(); + unsigned int elementCount = targetUniform->elementCount(); + unsigned int arrayElement = mData.getUniformLocations()[location].element; + unsigned int count = std::min(elementCount - arrayElement, static_cast(countIn)); - count = std::min(elementCount - (int)mUniformIndex[location].element, count); const unsigned int targetMatrixStride = (4 * rows); - GLfloat *target = (GLfloat*)(targetUniform->data + mUniformIndex[location].element * sizeof(GLfloat) * targetMatrixStride); + GLfloat *target = + (GLfloat *)(targetUniform->data + arrayElement * sizeof(GLfloat) * targetMatrixStride); - for (int i = 0; i < count; i++) + for (unsigned int i = 0; i < count; i++) { // Internally store matrices as transposed versions to accomodate HLSL matrix indexing if (transpose == GL_FALSE) { - targetUniform->dirty = transposeMatrix(target, value, 4, rows, rows, cols) || targetUniform->dirty; + targetUniform->dirty = TransposeMatrix(target, value, 4, rows, rows, cols) || + targetUniform->dirty; } else { - targetUniform->dirty = expandMatrix(target, value, 4, rows, cols, rows) || targetUniform->dirty; + targetUniform->dirty = + ExpandMatrix(target, value, 4, rows, cols, rows) || targetUniform->dirty; } target += targetMatrixStride; value += cols * rows; } } -template -void ProgramD3D::getUniformv(GLint location, T *params, GLenum uniformType) +size_t ProgramD3D::getUniformBlockInfo(const sh::InterfaceBlock &interfaceBlock) { - gl::LinkedUniform *targetUniform = mUniforms[mUniformIndex[location].index]; + ASSERT(interfaceBlock.staticUse || interfaceBlock.layout != sh::BLOCKLAYOUT_PACKED); - if (gl::IsMatrixType(targetUniform->type)) - { - const int rows = gl::VariableRowCount(targetUniform->type); - const int cols = gl::VariableColumnCount(targetUniform->type); - transposeMatrix(params, (GLfloat*)targetUniform->data + mUniformIndex[location].element * 4 * rows, rows, cols, 4, rows); - } - else if (uniformType == gl::VariableComponentType(targetUniform->type)) + // define member uniforms + sh::Std140BlockEncoder std140Encoder; + sh::HLSLBlockEncoder hlslEncoder(sh::HLSLBlockEncoder::ENCODE_PACKED); + sh::BlockLayoutEncoder *encoder = nullptr; + + if (interfaceBlock.layout == sh::BLOCKLAYOUT_STANDARD) { - unsigned int size = gl::VariableComponentCount(targetUniform->type); - memcpy(params, targetUniform->data + mUniformIndex[location].element * 4 * sizeof(T), - size * sizeof(T)); + encoder = &std140Encoder; } else { - unsigned int size = gl::VariableComponentCount(targetUniform->type); - switch (gl::VariableComponentType(targetUniform->type)) - { - case GL_BOOL: - { - GLint *boolParams = (GLint*)targetUniform->data + mUniformIndex[location].element * 4; - - for (unsigned int i = 0; i < size; i++) - { - params[i] = (boolParams[i] == GL_FALSE) ? static_cast(0) : static_cast(1); - } - } - break; - - case GL_FLOAT: - { - GLfloat *floatParams = (GLfloat*)targetUniform->data + mUniformIndex[location].element * 4; - - for (unsigned int i = 0; i < size; i++) - { - params[i] = static_cast(floatParams[i]); - } - } - break; - - case GL_INT: - { - GLint *intParams = (GLint*)targetUniform->data + mUniformIndex[location].element * 4; - - for (unsigned int i = 0; i < size; i++) - { - params[i] = static_cast(intParams[i]); - } - } - break; - - case GL_UNSIGNED_INT: - { - GLuint *uintParams = (GLuint*)targetUniform->data + mUniformIndex[location].element * 4; + encoder = &hlslEncoder; + } - for (unsigned int i = 0; i < size; i++) - { - params[i] = static_cast(uintParams[i]); - } - } - break; + GetUniformBlockInfo(interfaceBlock.fields, interfaceBlock.fieldPrefix(), encoder, + interfaceBlock.isRowMajorLayout, &mBlockInfo); - default: UNREACHABLE(); - } - } + return encoder->getBlockSize(); } -template -void ProgramD3D::defineUniformBlockMembers(const std::vector &fields, const std::string &prefix, int blockIndex, - sh::BlockLayoutEncoder *encoder, std::vector *blockUniformIndexes, - bool inRowMajorLayout) +void ProgramD3D::assignAllSamplerRegisters() { - for (unsigned int uniformIndex = 0; uniformIndex < fields.size(); uniformIndex++) + for (D3DUniform *d3dUniform : mD3DUniforms) { - const VarT &field = fields[uniformIndex]; - const std::string &fieldName = (prefix.empty() ? field.name : prefix + "." + field.name); - - if (field.isStruct()) - { - bool rowMajorLayout = (inRowMajorLayout || IsRowMajorLayout(field)); - - for (unsigned int arrayElement = 0; arrayElement < field.elementCount(); arrayElement++) - { - encoder->enterAggregateType(); - - const std::string uniformElementName = fieldName + (field.isArray() ? ArrayString(arrayElement) : ""); - defineUniformBlockMembers(field.fields, uniformElementName, blockIndex, encoder, blockUniformIndexes, rowMajorLayout); - - encoder->exitAggregateType(); - } - } - else + if (d3dUniform->isSampler()) { - bool isRowMajorMatrix = (gl::IsMatrixType(field.type) && inRowMajorLayout); - - sh::BlockMemberInfo memberInfo = encoder->encodeType(field.type, field.arraySize, isRowMajorMatrix); - - gl::LinkedUniform *newUniform = new gl::LinkedUniform(field.type, field.precision, fieldName, field.arraySize, - blockIndex, memberInfo); - - // add to uniform list, but not index, since uniform block uniforms have no location - blockUniformIndexes->push_back(mUniforms.size()); - mUniforms.push_back(newUniform); + assignSamplerRegisters(d3dUniform); } } } -bool ProgramD3D::defineUniformBlock(gl::InfoLog &infoLog, const gl::Shader &shader, const sh::InterfaceBlock &interfaceBlock, - const gl::Caps &caps) +void ProgramD3D::assignSamplerRegisters(D3DUniform *d3dUniform) { - const ShaderD3D* shaderD3D = GetImplAs(&shader); - - // create uniform block entries if they do not exist - if (getUniformBlockIndex(interfaceBlock.name) == GL_INVALID_INDEX) + ASSERT(d3dUniform->isSampler()); + const ShaderD3D *vertexShaderD3D = GetImplAs(mData.getAttachedVertexShader()); + const ShaderD3D *fragmentShaderD3D = GetImplAs(mData.getAttachedFragmentShader()); + ASSERT(vertexShaderD3D->hasUniform(d3dUniform) || fragmentShaderD3D->hasUniform(d3dUniform)); + if (vertexShaderD3D->hasUniform(d3dUniform)) { - std::vector blockUniformIndexes; - const unsigned int blockIndex = mUniformBlocks.size(); - - // define member uniforms - sh::BlockLayoutEncoder *encoder = NULL; - - if (interfaceBlock.layout == sh::BLOCKLAYOUT_STANDARD) - { - encoder = new sh::Std140BlockEncoder; - } - else - { - encoder = new sh::HLSLBlockEncoder(sh::HLSLBlockEncoder::ENCODE_PACKED); - } - ASSERT(encoder); - - defineUniformBlockMembers(interfaceBlock.fields, "", blockIndex, encoder, &blockUniformIndexes, interfaceBlock.isRowMajorLayout); - - size_t dataSize = encoder->getBlockSize(); - - // create all the uniform blocks - if (interfaceBlock.arraySize > 0) - { - for (unsigned int uniformBlockElement = 0; uniformBlockElement < interfaceBlock.arraySize; uniformBlockElement++) - { - gl::UniformBlock *newUniformBlock = new gl::UniformBlock(interfaceBlock.name, uniformBlockElement, dataSize); - newUniformBlock->memberUniformIndexes = blockUniformIndexes; - mUniformBlocks.push_back(newUniformBlock); - } - } - else - { - gl::UniformBlock *newUniformBlock = new gl::UniformBlock(interfaceBlock.name, GL_INVALID_INDEX, dataSize); - newUniformBlock->memberUniformIndexes = blockUniformIndexes; - mUniformBlocks.push_back(newUniformBlock); - } + d3dUniform->vsRegisterIndex = vertexShaderD3D->getUniformRegister(d3dUniform->name); + ASSERT(d3dUniform->vsRegisterIndex != GL_INVALID_INDEX); + AssignSamplers(d3dUniform->vsRegisterIndex, d3dUniform->type, d3dUniform->arraySize, + mSamplersVS, &mUsedVertexSamplerRange); } - - if (interfaceBlock.staticUse) + if (fragmentShaderD3D->hasUniform(d3dUniform)) { - // Assign registers to the uniform blocks - const GLuint blockIndex = getUniformBlockIndex(interfaceBlock.name); - const unsigned int elementCount = std::max(1u, interfaceBlock.arraySize); - ASSERT(blockIndex != GL_INVALID_INDEX); - ASSERT(blockIndex + elementCount <= mUniformBlocks.size()); - - unsigned int interfaceBlockRegister = shaderD3D->getInterfaceBlockRegister(interfaceBlock.name); - - for (unsigned int uniformBlockElement = 0; uniformBlockElement < elementCount; uniformBlockElement++) - { - gl::UniformBlock *uniformBlock = mUniformBlocks[blockIndex + uniformBlockElement]; - ASSERT(uniformBlock->name == interfaceBlock.name); - - if (!assignUniformBlockRegister(infoLog, uniformBlock, shader.getType(), - interfaceBlockRegister + uniformBlockElement, caps)) - { - return false; - } - } + d3dUniform->psRegisterIndex = fragmentShaderD3D->getUniformRegister(d3dUniform->name); + ASSERT(d3dUniform->psRegisterIndex != GL_INVALID_INDEX); + AssignSamplers(d3dUniform->psRegisterIndex, d3dUniform->type, d3dUniform->arraySize, + mSamplersPS, &mUsedPixelSamplerRange); } - - return true; } -bool ProgramD3D::assignSamplers(unsigned int startSamplerIndex, - GLenum samplerType, - unsigned int samplerCount, - std::vector &outSamplers, - GLuint *outUsedRange) +// static +void ProgramD3D::AssignSamplers(unsigned int startSamplerIndex, + GLenum samplerType, + unsigned int samplerCount, + std::vector &outSamplers, + GLuint *outUsedRange) { unsigned int samplerIndex = startSamplerIndex; do { - if (samplerIndex < outSamplers.size()) - { - Sampler& sampler = outSamplers[samplerIndex]; - sampler.active = true; - sampler.textureType = GetTextureType(samplerType); - sampler.logicalTextureUnit = 0; - *outUsedRange = std::max(samplerIndex + 1, *outUsedRange); - } - else - { - return false; - } - + ASSERT(samplerIndex < outSamplers.size()); + Sampler *sampler = &outSamplers[samplerIndex]; + sampler->active = true; + sampler->textureType = gl::SamplerTypeToTextureType(samplerType); + sampler->logicalTextureUnit = 0; + *outUsedRange = std::max(samplerIndex + 1, *outUsedRange); samplerIndex++; } while (samplerIndex < startSamplerIndex + samplerCount); - - return true; -} - -bool ProgramD3D::indexSamplerUniform(const gl::LinkedUniform &uniform, gl::InfoLog &infoLog, const gl::Caps &caps) -{ - ASSERT(gl::IsSamplerType(uniform.type)); - ASSERT(uniform.vsRegisterIndex != GL_INVALID_INDEX || uniform.psRegisterIndex != GL_INVALID_INDEX); - - if (uniform.vsRegisterIndex != GL_INVALID_INDEX) - { - if (!assignSamplers(uniform.vsRegisterIndex, uniform.type, uniform.arraySize, mSamplersVS, - &mUsedVertexSamplerRange)) - { - infoLog.append("Vertex shader sampler count exceeds the maximum vertex texture units (%d).", - mSamplersVS.size()); - return false; - } - - unsigned int maxVertexVectors = mRenderer->getReservedVertexUniformVectors() + caps.maxVertexUniformVectors; - if (uniform.vsRegisterIndex + uniform.registerCount > maxVertexVectors) - { - infoLog.append("Vertex shader active uniforms exceed GL_MAX_VERTEX_UNIFORM_VECTORS (%u)", - caps.maxVertexUniformVectors); - return false; - } - } - - if (uniform.psRegisterIndex != GL_INVALID_INDEX) - { - if (!assignSamplers(uniform.psRegisterIndex, uniform.type, uniform.arraySize, mSamplersPS, - &mUsedPixelSamplerRange)) - { - infoLog.append("Pixel shader sampler count exceeds MAX_TEXTURE_IMAGE_UNITS (%d).", - mSamplersPS.size()); - return false; - } - - unsigned int maxFragmentVectors = mRenderer->getReservedFragmentUniformVectors() + caps.maxFragmentUniformVectors; - if (uniform.psRegisterIndex + uniform.registerCount > maxFragmentVectors) - { - infoLog.append("Fragment shader active uniforms exceed GL_MAX_FRAGMENT_UNIFORM_VECTORS (%u)", - caps.maxFragmentUniformVectors); - return false; - } - } - - return true; -} - -bool ProgramD3D::indexUniforms(gl::InfoLog &infoLog, const gl::Caps &caps) -{ - for (size_t uniformIndex = 0; uniformIndex < mUniforms.size(); uniformIndex++) - { - const gl::LinkedUniform &uniform = *mUniforms[uniformIndex]; - - if (gl::IsSamplerType(uniform.type)) - { - if (!indexSamplerUniform(uniform, infoLog, caps)) - { - return false; - } - } - - for (unsigned int arrayIndex = 0; arrayIndex < uniform.elementCount(); arrayIndex++) - { - if (!uniform.isBuiltIn()) - { - mUniformIndex.push_back(gl::VariableLocation(uniform.name, arrayIndex, uniformIndex)); - } - } - } - - return true; } void ProgramD3D::reset() { - ProgramImpl::reset(); - SafeDeleteContainer(mVertexExecutables); SafeDeleteContainer(mPixelExecutables); - SafeDelete(mGeometryExecutable); - mTransformFeedbackBufferMode = GL_NONE; + for (auto &element : mGeometryExecutables) + { + SafeDelete(element); + } mVertexHLSL.clear(); - mVertexWorkarounds.reset(); - mShaderVersion = 100; + mVertexWorkarounds = D3DCompilerWorkarounds(); mPixelHLSL.clear(); - mPixelWorkarounds.reset(); + mPixelWorkarounds = D3DCompilerWorkarounds(); mUsesFragDepth = false; mPixelShaderKey.clear(); mUsesPointSize = false; + mUsesFlatInterpolation = false; + + SafeDeleteContainer(mD3DUniforms); + mD3DUniformBlocks.clear(); SafeDelete(mVertexUniformStorage); SafeDelete(mFragmentUniformStorage); @@ -1982,10 +2149,14 @@ void ProgramD3D::reset() mSamplersVS.clear(); mUsedVertexSamplerRange = 0; - mUsedPixelSamplerRange = 0; - mDirtySamplerMapping = true; + mUsedPixelSamplerRange = 0; + mDirtySamplerMapping = true; - std::fill(mAttributesByLayout, mAttributesByLayout + ArraySize(mAttributesByLayout), -1); + mAttribLocationToD3DSemantic.fill(-1); + + mStreamOutVaryings.clear(); + + mGeometryShaderPreamble.clear(); } unsigned int ProgramD3D::getSerial() const @@ -1998,32 +2169,143 @@ unsigned int ProgramD3D::issueSerial() return mCurrentSerial++; } -void ProgramD3D::initAttributesByLayout() +void ProgramD3D::initAttribLocationsToD3DSemantic() { - for (int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++) + const gl::Shader *vertexShader = mData.getAttachedVertexShader(); + ASSERT(vertexShader != nullptr); + + // Init semantic index + for (const sh::Attribute &attribute : mData.getAttributes()) { - mAttributesByLayout[i] = i; + int d3dSemantic = vertexShader->getSemanticIndex(attribute.name); + int regCount = gl::VariableRegisterCount(attribute.type); + + for (int reg = 0; reg < regCount; ++reg) + { + mAttribLocationToD3DSemantic[attribute.location + reg] = d3dSemantic + reg; + } } +} + +void ProgramD3D::updateCachedInputLayout(const gl::State &state) +{ + mCachedInputLayout.clear(); + const auto &vertexAttributes = state.getVertexArray()->getVertexAttributes(); + + for (unsigned int locationIndex : angle::IterateBitSet(mData.getActiveAttribLocationsMask())) + { + int d3dSemantic = mAttribLocationToD3DSemantic[locationIndex]; - std::sort(&mAttributesByLayout[0], &mAttributesByLayout[gl::MAX_VERTEX_ATTRIBS], AttributeSorter(mSemanticIndex)); + if (d3dSemantic != -1) + { + if (mCachedInputLayout.size() < static_cast(d3dSemantic + 1)) + { + mCachedInputLayout.resize(d3dSemantic + 1, gl::VERTEX_FORMAT_INVALID); + } + mCachedInputLayout[d3dSemantic] = + GetVertexFormatType(vertexAttributes[locationIndex], + state.getVertexAttribCurrentValue(locationIndex).Type); + } + } } -void ProgramD3D::sortAttributesByLayout(rx::TranslatedAttribute attributes[gl::MAX_VERTEX_ATTRIBS], - int sortedSemanticIndices[gl::MAX_VERTEX_ATTRIBS]) const +void ProgramD3D::gatherTransformFeedbackVaryings(const VaryingPacking &varyingPacking) { - rx::TranslatedAttribute oldTranslatedAttributes[gl::MAX_VERTEX_ATTRIBS]; + const auto &builtins = varyingPacking.builtins(SHADER_VERTEX); - for (int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++) + 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 = mData.getTransformFeedbackVaryingNames(); + for (unsigned int outputSlot = 0; outputSlot < static_cast(tfVaryingNames.size()); + ++outputSlot) { - oldTranslatedAttributes[i] = attributes[i]; + const auto &tfVaryingName = tfVaryingNames[outputSlot]; + if (tfVaryingName == "gl_Position") + { + if (builtins.glPosition.enabled) + { + mStreamOutVaryings.push_back(D3DVarying(builtins.glPosition.semantic, + builtins.glPosition.index, 4, outputSlot)); + } + } + else if (tfVaryingName == "gl_FragCoord") + { + if (builtins.glFragCoord.enabled) + { + mStreamOutVaryings.push_back(D3DVarying(builtins.glFragCoord.semantic, + builtins.glFragCoord.index, 4, outputSlot)); + } + } + else if (tfVaryingName == "gl_PointSize") + { + if (builtins.glPointSize.enabled) + { + mStreamOutVaryings.push_back(D3DVarying("PSIZE", 0, 1, outputSlot)); + } + } + else + { + for (const PackedVaryingRegister ®isterInfo : varyingPacking.getRegisterList()) + { + const auto &varying = *registerInfo.packedVarying->varying; + GLenum transposedType = gl::TransposeMatrixType(varying.type); + int componentCount = gl::VariableColumnCount(transposedType); + ASSERT(!varying.isBuiltIn()); + + // Transform feedback for varying structs is underspecified. + // See Khronos bug 9856. + // TODO(jmadill): Figure out how to be spec-compliant here. + if (registerInfo.packedVarying->isStructField() || varying.isStruct()) + continue; + + // There can be more than one register assigned to a particular varying, and each + // register needs its own stream out entry. + if (tfVaryingName == varying.name) + { + mStreamOutVaryings.push_back(D3DVarying( + varyingSemantic, registerInfo.semanticIndex, componentCount, outputSlot)); + } + } + } } +} + +D3DUniform *ProgramD3D::getD3DUniformFromLocation(GLint location) +{ + return mD3DUniforms[mData.getUniformLocations()[location].index]; +} + +bool ProgramD3D::getUniformBlockSize(const std::string &blockName, size_t *sizeOut) const +{ + std::string baseName = blockName; + gl::ParseAndStripArrayIndex(&baseName); - for (int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++) + auto sizeIter = mBlockDataSizes.find(baseName); + if (sizeIter == mBlockDataSizes.end()) { - int oldIndex = mAttributesByLayout[i]; - sortedSemanticIndices[i] = mSemanticIndex[oldIndex]; - attributes[i] = oldTranslatedAttributes[oldIndex]; + *sizeOut = 0; + return false; } + + *sizeOut = sizeIter->second; + return true; } +bool ProgramD3D::getUniformBlockMemberInfo(const std::string &memberUniformName, + sh::BlockMemberInfo *memberInfoOut) const +{ + auto infoIter = mBlockInfo.find(memberUniformName); + if (infoIter == mBlockInfo.end()) + { + *memberInfoOut = sh::BlockMemberInfo::getDefaultBlockInfo(); + return false; + } + + *memberInfoOut = infoIter->second; + return true; } +} // namespace rx diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/ProgramD3D.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/ProgramD3D.h index 6b3b87d04c54..c83f701e6109 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/ProgramD3D.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/ProgramD3D.h @@ -9,22 +9,15 @@ #ifndef LIBANGLE_RENDERER_D3D_PROGRAMD3D_H_ #define LIBANGLE_RENDERER_D3D_PROGRAMD3D_H_ -#include "common/Optional.h" +#include +#include + #include "compiler/translator/blocklayoutHLSL.h" #include "libANGLE/Constants.h" +#include "libANGLE/formatutils.h" #include "libANGLE/renderer/ProgramImpl.h" -#include "libANGLE/renderer/Workarounds.h" #include "libANGLE/renderer/d3d/DynamicHLSL.h" - -#include -#include - -namespace gl -{ -struct LinkedUniform; -struct VariableLocation; -struct VertexFormat; -} +#include "libANGLE/renderer/d3d/WorkaroundsD3D.h" namespace rx { @@ -38,53 +31,153 @@ class ShaderExecutableD3D; #define ANGLE_COMPILE_OPTIMIZATION_LEVEL D3DCOMPILE_OPTIMIZATION_LEVEL1 #endif +// Helper struct representing a single shader uniform +struct D3DUniform : angle::NonCopyable +{ + D3DUniform(GLenum typeIn, + const std::string &nameIn, + unsigned int arraySizeIn, + bool defaultBlock); + ~D3DUniform(); + + bool isSampler() const; + unsigned int elementCount() const { return std::max(1u, arraySize); } + bool isReferencedByVertexShader() const; + bool isReferencedByFragmentShader() const; + + // Duplicated from the GL layer + GLenum type; + std::string name; + unsigned int arraySize; + + // Pointer to a system copy of the data. + // TODO(jmadill): remove this in favor of gl::LinkedUniform::data(). + uint8_t *data; + + // Has the data been updated since the last sync? + bool dirty; + + // Register information. + unsigned int vsRegisterIndex; + unsigned int psRegisterIndex; + 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; +}; + +struct D3DUniformBlock +{ + D3DUniformBlock() : vsRegisterIndex(GL_INVALID_INDEX), psRegisterIndex(GL_INVALID_INDEX) {} + + bool vertexStaticUse() const { return vsRegisterIndex != GL_INVALID_INDEX; } + + bool fragmentStaticUse() const { return psRegisterIndex != GL_INVALID_INDEX; } + + unsigned int vsRegisterIndex; + unsigned int psRegisterIndex; +}; + +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 : angle::NonCopyable +{ + public: + ProgramD3DMetadata(int rendererMajorShaderModel, + const std::string &shaderModelSuffix, + bool usesInstancedPointSpriteEmulation, + bool usesViewScale, + const ShaderD3D *vertexShader, + const ShaderD3D *fragmentShader); + + int getRendererMajorShaderModel() const; + bool usesBroadcast(const gl::Data &data) const; + bool usesFragDepth(const gl::Program::Data &programData) const; + bool usesPointCoord() const; + bool usesFragCoord() const; + bool usesPointSize() const; + bool usesInsertedPointCoordValue() const; + bool usesViewScale() const; + bool addsPointCoordToVertexShader() const; + bool usesTransformFeedbackGLPosition() const; + bool usesSystemValuePointSize() const; + bool usesMultipleFragmentOuts() const; + GLint getMajorShaderVersion() const; + const ShaderD3D *getFragmentShader() const; + + private: + const int mRendererMajorShaderModel; + const std::string mShaderModelSuffix; + const bool mUsesInstancedPointSpriteEmulation; + const bool mUsesViewScale; + const ShaderD3D *mVertexShader; + const ShaderD3D *mFragmentShader; +}; + class ProgramD3D : public ProgramImpl { public: - ProgramD3D(RendererD3D *renderer); + ProgramD3D(const gl::Program::Data &data, RendererD3D *renderer); virtual ~ProgramD3D(); const std::vector &getPixelShaderKey() { return mPixelShaderKey; } - int getShaderVersion() const { return mShaderVersion; } - GLenum getTransformFeedbackBufferMode() const { return mTransformFeedbackBufferMode; } - GLint getSamplerMapping(gl::SamplerType type, unsigned int samplerIndex, const gl::Caps &caps) const; + GLint getSamplerMapping(gl::SamplerType type, + unsigned int samplerIndex, + const gl::Caps &caps) const; GLenum getSamplerTextureType(gl::SamplerType type, unsigned int samplerIndex) const; - GLint getUsedSamplerRange(gl::SamplerType type) const; + GLuint getUsedSamplerRange(gl::SamplerType type) const; void updateSamplerMapping(); - bool validateSamplers(gl::InfoLog *infoLog, const gl::Caps &caps); bool usesPointSize() const { return mUsesPointSize; } bool usesPointSpriteEmulation() const; - bool usesGeometryShader() const; + bool usesGeometryShader(GLenum drawMode) const; bool usesInstancedPointSpriteEmulation() const; - GLenum getBinaryFormat() { return GL_PROGRAM_BINARY_ANGLE; } - LinkResult load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream); - gl::Error save(gl::BinaryOutputStream *stream); - - gl::Error getPixelExecutableForFramebuffer(const gl::Framebuffer *fbo, ShaderExecutableD3D **outExectuable); - gl::Error getPixelExecutableForOutputLayout(const std::vector &outputLayout, ShaderExecutableD3D **outExectuable, gl::InfoLog *infoLog); - gl::Error getVertexExecutableForInputLayout(const gl::VertexFormat inputLayout[gl::MAX_VERTEX_ATTRIBS], ShaderExecutableD3D **outExectuable, gl::InfoLog *infoLog); - ShaderExecutableD3D *getGeometryExecutable() const { return mGeometryExecutable; } - - LinkResult compileProgramExecutables(gl::InfoLog &infoLog, gl::Shader *fragmentShader, gl::Shader *vertexShader, - int registers); - - LinkResult link(const gl::Data &data, gl::InfoLog &infoLog, - gl::Shader *fragmentShader, gl::Shader *vertexShader, - const std::vector &transformFeedbackVaryings, - GLenum transformFeedbackBufferMode, - int *registers, std::vector *linkedVaryings, - std::map *outputVariables); - - void getInputLayoutSignature(const gl::VertexFormat inputLayout[], GLenum signature[]) const; + LinkResult load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream) override; + gl::Error save(gl::BinaryOutputStream *stream) override; + void setBinaryRetrievableHint(bool retrievable) override; + + gl::Error getPixelExecutableForFramebuffer(const gl::Framebuffer *fbo, + ShaderExecutableD3D **outExectuable); + gl::Error getPixelExecutableForOutputLayout(const std::vector &outputLayout, + ShaderExecutableD3D **outExectuable, + gl::InfoLog *infoLog); + gl::Error getVertexExecutableForInputLayout(const gl::InputLayout &inputLayout, + ShaderExecutableD3D **outExectuable, + gl::InfoLog *infoLog); + gl::Error getGeometryExecutableForPrimitiveType(const gl::Data &data, + GLenum drawMode, + ShaderExecutableD3D **outExecutable, + gl::InfoLog *infoLog); + + LinkResult link(const gl::Data &data, gl::InfoLog &infoLog) override; + GLboolean validate(const gl::Caps &caps, gl::InfoLog *infoLog) override; + + bool getUniformBlockSize(const std::string &blockName, size_t *sizeOut) const override; + bool getUniformBlockMemberInfo(const std::string &memberUniformName, + sh::BlockMemberInfo *memberInfoOut) const override; void initializeUniformStorage(); - gl::Error applyUniforms(); - gl::Error applyUniformBuffers(const gl::Data &data, GLuint uniformBlockBindings[]) override; - bool assignUniformBlockRegister(gl::InfoLog &infoLog, gl::UniformBlock *uniformBlock, GLenum shader, - unsigned int registerIndex, const gl::Caps &caps); + gl::Error applyUniforms(GLenum drawMode); + gl::Error applyUniformBuffers(const gl::Data &data); void dirtyAllUniforms(); void setUniform1fv(GLint location, GLsizei count, const GLfloat *v); @@ -99,63 +192,106 @@ class ProgramD3D : public ProgramImpl void setUniform2uiv(GLint location, GLsizei count, const GLuint *v); void setUniform3uiv(GLint location, GLsizei count, const GLuint *v); void setUniform4uiv(GLint location, GLsizei count, const GLuint *v); - void setUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); - void setUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); - void setUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); - void setUniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); - void setUniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); - void setUniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); - void setUniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); - void setUniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); - void setUniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); - - void getUniformfv(GLint location, GLfloat *params); - void getUniformiv(GLint location, GLint *params); - void getUniformuiv(GLint location, GLuint *params); + void setUniformMatrix2fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value); + void setUniformMatrix3fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value); + void setUniformMatrix4fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value); + void setUniformMatrix2x3fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value); + void setUniformMatrix3x2fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value); + void setUniformMatrix2x4fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value); + void setUniformMatrix4x2fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value); + void setUniformMatrix3x4fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value); + void setUniformMatrix4x3fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value); + + void setUniformBlockBinding(GLuint uniformBlockIndex, GLuint uniformBlockBinding) override; const UniformStorageD3D &getVertexUniformStorage() const { return *mVertexUniformStorage; } const UniformStorageD3D &getFragmentUniformStorage() const { return *mFragmentUniformStorage; } - bool linkUniforms(gl::InfoLog &infoLog, const gl::Shader &vertexShader, const gl::Shader &fragmentShader, - const gl::Caps &caps); - bool defineUniformBlock(gl::InfoLog &infoLog, const gl::Shader &shader, const sh::InterfaceBlock &interfaceBlock, const gl::Caps &caps); + unsigned int getSerial() const; - void reset(); + const AttribIndexArray &getAttribLocationToD3DSemantics() const + { + return mAttribLocationToD3DSemantic; + } - unsigned int getSerial() const; + void updateCachedInputLayout(const gl::State &state); + const gl::InputLayout &getCachedInputLayout() const { return mCachedInputLayout; } - void initAttributesByLayout(); - void sortAttributesByLayout(rx::TranslatedAttribute attributes[gl::MAX_VERTEX_ATTRIBS], - int sortedSemanticIndices[gl::MAX_VERTEX_ATTRIBS]) const; + bool isSamplerMappingDirty() { return mDirtySamplerMapping; } private: class VertexExecutable { public: - VertexExecutable(const gl::VertexFormat inputLayout[gl::MAX_VERTEX_ATTRIBS], - const GLenum signature[gl::MAX_VERTEX_ATTRIBS], + 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 GLenum convertedLayout[gl::MAX_VERTEX_ATTRIBS]) const; + bool matchesSignature(const Signature &signature) const; + static void getSignature(RendererD3D *renderer, + const gl::InputLayout &inputLayout, + Signature *signatureOut); - const gl::VertexFormat *inputs() const { return mInputs; } - const GLenum *signature() const { return mSignature; } + const gl::InputLayout &inputs() const { return mInputs; } + const Signature &signature() const { return mSignature; } ShaderExecutableD3D *shaderExecutable() const { return mShaderExecutable; } private: - gl::VertexFormat mInputs[gl::MAX_VERTEX_ATTRIBS]; - GLenum mSignature[gl::MAX_VERTEX_ATTRIBS]; + static HLSLAttribType GetAttribType(GLenum type); + + gl::InputLayout mInputs; + Signature mSignature; ShaderExecutableD3D *mShaderExecutable; }; class PixelExecutable { public: - PixelExecutable(const std::vector &outputSignature, ShaderExecutableD3D *shaderExecutable); + PixelExecutable(const std::vector &outputSignature, + ShaderExecutableD3D *shaderExecutable); ~PixelExecutable(); - bool matchesSignature(const std::vector &signature) const { return mOutputSignature == signature; } + bool matchesSignature(const std::vector &signature) const + { + return mOutputSignature == signature; + } const std::vector &outputSignature() const { return mOutputSignature; } ShaderExecutableD3D *shaderExecutable() const { return mShaderExecutable; } @@ -174,34 +310,56 @@ class ProgramD3D : public ProgramImpl GLenum textureType; }; - void defineUniformBase(const ShaderD3D *shader, const sh::Uniform &uniform, unsigned int uniformRegister); - void defineUniform(const ShaderD3D *shader, const sh::ShaderVariable &uniform, const std::string &fullName, - sh::HLSLBlockEncoder *encoder); - bool indexSamplerUniform(const gl::LinkedUniform &uniform, gl::InfoLog &infoLog, const gl::Caps &caps); - bool indexUniforms(gl::InfoLog &infoLog, const gl::Caps &caps); - static bool assignSamplers(unsigned int startSamplerIndex, GLenum samplerType, unsigned int samplerCount, - std::vector &outSamplers, GLuint *outUsedRange); + typedef std::map D3DUniformMap; + + void defineUniformsAndAssignRegisters(); + void defineUniformBase(const gl::Shader *shader, + const sh::Uniform &uniform, + D3DUniformMap *uniformMap); + void defineUniform(GLenum shaderType, + const sh::ShaderVariable &uniform, + const std::string &fullName, + sh::HLSLBlockEncoder *encoder, + D3DUniformMap *uniformMap); + void assignAllSamplerRegisters(); + void assignSamplerRegisters(D3DUniform *d3dUniform); + + static void AssignSamplers(unsigned int startSamplerIndex, + GLenum samplerType, + unsigned int samplerCount, + std::vector &outSamplers, + GLuint *outUsedRange); template - void setUniform(GLint location, GLsizei count, const T* v, GLenum targetUniformType); + void setUniform(GLint location, GLsizei count, const T *v, GLenum targetUniformType); template - void setUniformMatrixfv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value, GLenum targetUniformType); + void setUniformMatrixfv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value, + GLenum targetUniformType); - template - void getUniformv(GLint location, T *params, GLenum uniformType); + LinkResult compileProgramExecutables(const gl::Data &data, gl::InfoLog &infoLog); + + void gatherTransformFeedbackVaryings(const VaryingPacking &varyings); + D3DUniform *getD3DUniformByName(const std::string &name); + D3DUniform *getD3DUniformFromLocation(GLint location); + + void initAttribLocationsToD3DSemantic(); - template - void defineUniformBlockMembers(const std::vector &fields, const std::string &prefix, int blockIndex, - sh::BlockLayoutEncoder *encoder, std::vector *blockUniformIndexes, - bool inRowMajorLayout); + void reset(); + void assignUniformBlockRegisters(); + + void initUniformBlockInfo(); + size_t getUniformBlockInfo(const sh::InterfaceBlock &interfaceBlock); RendererD3D *mRenderer; DynamicHLSL *mDynamicHLSL; std::vector mVertexExecutables; std::vector mPixelExecutables; - ShaderExecutableD3D *mGeometryExecutable; + std::vector mGeometryExecutables; std::string mVertexHLSL; D3DCompilerWorkarounds mVertexWorkarounds; @@ -211,37 +369,45 @@ class ProgramD3D : public ProgramImpl bool mUsesFragDepth; 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; UniformStorageD3D *mVertexUniformStorage; UniformStorageD3D *mFragmentUniformStorage; - GLenum mTransformFeedbackBufferMode; - std::vector mSamplersPS; std::vector mSamplersVS; GLuint mUsedVertexSamplerRange; GLuint mUsedPixelSamplerRange; bool mDirtySamplerMapping; - // Cache for validateSamplers - std::vector mTextureUnitTypesCache; - // Cache for getPixelExecutableForFramebuffer std::vector mPixelShaderOutputFormatCache; - int mShaderVersion; - - int mAttributesByLayout[gl::MAX_VERTEX_ATTRIBS]; + AttribIndexArray mAttribLocationToD3DSemantic; unsigned int mSerial; - Optional mCachedValidateSamplersResult; + std::vector mVertexUBOCache; + std::vector mFragmentUBOCache; + VertexExecutable::Signature mCachedVertexSignature; + gl::InputLayout mCachedInputLayout; + + std::vector mStreamOutVaryings; + std::vector mD3DUniforms; + std::vector mD3DUniformBlocks; + + std::map mBlockInfo; + std::map mBlockDataSizes; static unsigned int issueSerial(); static unsigned int mCurrentSerial; }; - } -#endif // LIBANGLE_RENDERER_D3D_PROGRAMD3D_H_ +#endif // LIBANGLE_RENDERER_D3D_PROGRAMD3D_H_ diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/RenderTargetD3D.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/RenderTargetD3D.h index b2d895d9c642..c96da5ce14e9 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/RenderTargetD3D.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/RenderTargetD3D.h @@ -33,6 +33,9 @@ class RenderTargetD3D : public FramebufferAttachmentRenderTarget virtual unsigned int getSerial() const; static unsigned int issueSerials(unsigned int count); + // Only currently applies to D3D11. + virtual void signalDirty() {} + private: const unsigned int mSerial; static unsigned int mCurrentSerial; diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/RenderbufferD3D.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/RenderbufferD3D.cpp index 6b6f778061b4..991801a0917a 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/RenderbufferD3D.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/RenderbufferD3D.cpp @@ -9,19 +9,22 @@ #include "libANGLE/renderer/d3d/RenderbufferD3D.h" +#include "libANGLE/Image.h" +#include "libANGLE/renderer/d3d/EGLImageD3D.h" #include "libANGLE/renderer/d3d/RendererD3D.h" #include "libANGLE/renderer/d3d/RenderTargetD3D.h" namespace rx { -RenderbufferD3D::RenderbufferD3D(RendererD3D *renderer) : mRenderer(renderer) +RenderbufferD3D::RenderbufferD3D(RendererD3D *renderer) + : mRenderer(renderer), mRenderTarget(nullptr), mImage(nullptr) { - mRenderTarget = NULL; } RenderbufferD3D::~RenderbufferD3D() { SafeDelete(mRenderTarget); + mImage = nullptr; } gl::Error RenderbufferD3D::setStorage(GLenum internalformat, size_t width, size_t height) @@ -53,33 +56,46 @@ gl::Error RenderbufferD3D::setStorageMultisample(size_t samples, GLenum internal } RenderTargetD3D *newRT = NULL; - gl::Error error = mRenderer->createRenderTarget(width, height, creationFormat, samples, &newRT); + gl::Error error = + mRenderer->createRenderTarget(static_cast(width), static_cast(height), + creationFormat, static_cast(samples), &newRT); if (error.isError()) { return error; } SafeDelete(mRenderTarget); + mImage = nullptr; mRenderTarget = newRT; return gl::Error(GL_NO_ERROR); } -RenderTargetD3D *RenderbufferD3D::getRenderTarget() +gl::Error RenderbufferD3D::setStorageEGLImageTarget(egl::Image *image) { - return mRenderTarget; + mImage = GetImplAs(image); + SafeDelete(mRenderTarget); + + return gl::Error(GL_NO_ERROR); } -unsigned int RenderbufferD3D::getRenderTargetSerial() const +gl::Error RenderbufferD3D::getRenderTarget(RenderTargetD3D **outRenderTarget) { - return (mRenderTarget ? mRenderTarget->getSerial() : 0); + if (mImage) + { + return mImage->getRenderTarget(outRenderTarget); + } + else + { + *outRenderTarget = mRenderTarget; + return gl::Error(GL_NO_ERROR); + } } gl::Error RenderbufferD3D::getAttachmentRenderTarget(const gl::FramebufferAttachment::Target &target, FramebufferAttachmentRenderTarget **rtOut) { - *rtOut = mRenderTarget; - return gl::Error(GL_NO_ERROR); + return getRenderTarget(reinterpret_cast(rtOut)); } } diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/RenderbufferD3D.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/RenderbufferD3D.h index 9769def9650b..20f6a10b2d55 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/RenderbufferD3D.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/RenderbufferD3D.h @@ -16,6 +16,7 @@ namespace rx { +class EGLImageD3D; class RendererD3D; class RenderTargetD3D; class SwapChainD3D; @@ -26,19 +27,23 @@ class RenderbufferD3D : public RenderbufferImpl RenderbufferD3D(RendererD3D *renderer); virtual ~RenderbufferD3D(); - virtual gl::Error setStorage(GLenum internalformat, size_t width, size_t height) override; - virtual gl::Error setStorageMultisample(size_t samples, GLenum internalformat, size_t width, size_t height) override; - - RenderTargetD3D *getRenderTarget(); - unsigned int getRenderTargetSerial() const; + gl::Error setStorage(GLenum internalformat, size_t width, size_t height) override; + gl::Error setStorageMultisample(size_t samples, + GLenum internalformat, + size_t width, + size_t height) override; + gl::Error setStorageEGLImageTarget(egl::Image *image) override; + gl::Error getRenderTarget(RenderTargetD3D **outRenderTarget); gl::Error getAttachmentRenderTarget(const gl::FramebufferAttachment::Target &target, FramebufferAttachmentRenderTarget **rtOut) override; private: RendererD3D *mRenderer; RenderTargetD3D *mRenderTarget; + EGLImageD3D *mImage; }; + } #endif // LIBANGLE_RENDERER_D3D_RENDERBUFFERD3D_H_ diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/RendererD3D.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/RendererD3D.cpp index ed758461e646..da86a49569fa 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/RendererD3D.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/RendererD3D.cpp @@ -8,18 +8,22 @@ #include "libANGLE/renderer/d3d/RendererD3D.h" +#include "common/debug.h" #include "common/MemoryBuffer.h" #include "common/utilities.h" #include "libANGLE/Display.h" +#include "libANGLE/formatutils.h" #include "libANGLE/Framebuffer.h" #include "libANGLE/FramebufferAttachment.h" -#include "libANGLE/ResourceManager.h" -#include "libANGLE/State.h" -#include "libANGLE/VertexArray.h" -#include "libANGLE/formatutils.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/ResourceManager.h" +#include "libANGLE/State.h" +#include "libANGLE/VertexArray.h" namespace rx { @@ -30,12 +34,17 @@ namespace // release and recreate the scratch buffer. This ensures we don't have a // degenerate case where we are stuck hogging memory. const int ScratchMemoryBufferLifetime = 1000; -} + +} // anonymous namespace RendererD3D::RendererD3D(egl::Display *display) : mDisplay(display), mDeviceLost(false), - mScratchMemoryBufferResetCounter(0) + mAnnotator(nullptr), + mPresentPathFastEnabled(false), + mScratchMemoryBufferResetCounter(0), + mWorkaroundsInitialized(false), + mDisjoint(false) { } @@ -49,260 +58,190 @@ void RendererD3D::cleanup() mScratchMemoryBuffer.resize(0); for (auto &incompleteTexture : mIncompleteTextures) { - incompleteTexture.second.set(NULL); + incompleteTexture.second.set(nullptr); } mIncompleteTextures.clear(); + + if (mAnnotator != nullptr) + { + gl::UninitializeDebugAnnotations(); + SafeDelete(mAnnotator); + } +} + +SamplerImpl *RendererD3D::createSampler() +{ + return new SamplerD3D(); +} + +gl::Error RendererD3D::drawArrays(const gl::Data &data, GLenum mode, GLint first, GLsizei count) +{ + return genericDrawArrays(data, mode, first, count, 0); +} + +gl::Error RendererD3D::drawArraysInstanced(const gl::Data &data, + GLenum mode, + GLint first, + GLsizei count, + GLsizei instanceCount) +{ + return genericDrawArrays(data, mode, first, count, instanceCount); } gl::Error RendererD3D::drawElements(const gl::Data &data, - GLenum mode, GLsizei count, GLenum type, - const GLvoid *indices, GLsizei instances, - const RangeUI &indexRange) + GLenum mode, + GLsizei count, + GLenum type, + const GLvoid *indices, + const gl::IndexRange &indexRange) { - if (data.state->isPrimitiveRestartEnabled()) - { - UNIMPLEMENTED(); - return gl::Error(GL_INVALID_OPERATION, "Primitive restart not implemented"); - } + return genericDrawElements(data, mode, count, type, indices, 0, indexRange); +} - gl::Program *program = data.state->getProgram(); - ASSERT(program != NULL); +gl::Error RendererD3D::drawElementsInstanced(const gl::Data &data, + GLenum mode, + GLsizei count, + GLenum type, + const GLvoid *indices, + GLsizei instances, + const gl::IndexRange &indexRange) +{ + return genericDrawElements(data, mode, count, type, indices, instances, indexRange); +} - program->updateSamplerMapping(); +gl::Error RendererD3D::drawRangeElements(const gl::Data &data, + GLenum mode, + GLuint start, + GLuint end, + GLsizei count, + GLenum type, + const GLvoid *indices, + const gl::IndexRange &indexRange) +{ + return genericDrawElements(data, mode, count, type, indices, 0, indexRange); +} - gl::Error error = generateSwizzles(data); - if (error.isError()) - { - return error; - } +gl::Error RendererD3D::genericDrawElements(const gl::Data &data, + GLenum mode, + GLsizei count, + GLenum type, + const GLvoid *indices, + GLsizei instances, + const gl::IndexRange &indexRange) +{ + gl::Program *program = data.state->getProgram(); + ASSERT(program != nullptr); + ProgramD3D *programD3D = GetImplAs(program); + bool usesPointSize = programD3D->usesPointSize(); - if (!applyPrimitiveType(mode, count, program->usesPointSize())) - { - return gl::Error(GL_NO_ERROR); - } + programD3D->updateSamplerMapping(); - error = applyRenderTarget(data, mode, false); - if (error.isError()) - { - return error; - } + ANGLE_TRY(generateSwizzles(data)); - error = applyState(data, mode); - if (error.isError()) + if (!applyPrimitiveType(mode, count, usesPointSize)) { - return error; + return gl::NoError(); } - gl::VertexArray *vao = data.state->getVertexArray(); + ANGLE_TRY(updateState(data, mode)); + TranslatedIndexData indexInfo; indexInfo.indexRange = indexRange; - error = applyIndexBuffer(indices, vao->getElementArrayBuffer(), count, mode, type, &indexInfo); - if (error.isError()) - { - return error; - } + + ANGLE_TRY(applyIndexBuffer(data, indices, count, mode, type, &indexInfo)); applyTransformFeedbackBuffers(*data.state); // Transform feedback is not allowed for DrawElements, this error should have been caught at the API validation // layer. ASSERT(!data.state->isTransformFeedbackActiveUnpaused()); - GLsizei vertexCount = indexInfo.indexRange.length() + 1; - error = applyVertexBuffer(*data.state, mode, indexInfo.indexRange.start, vertexCount, instances); - if (error.isError()) - { - return error; - } - - error = applyShaders(data); - if (error.isError()) - { - return error; - } - - error = applyTextures(data); - if (error.isError()) - { - return error; - } - - error = program->applyUniformBuffers(data); - if (error.isError()) - { - return error; - } + size_t vertexCount = indexInfo.indexRange.vertexCount(); + ANGLE_TRY(applyVertexBuffer(*data.state, mode, static_cast(indexInfo.indexRange.start), + static_cast(vertexCount), instances, &indexInfo)); + ANGLE_TRY(applyTextures(data)); + ANGLE_TRY(applyShaders(data, mode)); + ANGLE_TRY(programD3D->applyUniformBuffers(data)); if (!skipDraw(data, mode)) { - error = drawElements(mode, count, type, indices, vao->getElementArrayBuffer(), indexInfo, instances); - if (error.isError()) - { - return error; - } + ANGLE_TRY(drawElementsImpl(data, indexInfo, mode, count, type, indices, instances)); } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -gl::Error RendererD3D::drawArrays(const gl::Data &data, - GLenum mode, GLint first, - GLsizei count, GLsizei instances) +gl::Error RendererD3D::genericDrawArrays(const gl::Data &data, + GLenum mode, + GLint first, + GLsizei count, + GLsizei instances) { gl::Program *program = data.state->getProgram(); - ASSERT(program != NULL); + ASSERT(program != nullptr); + ProgramD3D *programD3D = GetImplAs(program); + bool usesPointSize = programD3D->usesPointSize(); - program->updateSamplerMapping(); + programD3D->updateSamplerMapping(); - gl::Error error = generateSwizzles(data); - if (error.isError()) + ANGLE_TRY(generateSwizzles(data)); + if (!applyPrimitiveType(mode, count, usesPointSize)) { - return error; + return gl::NoError(); } - if (!applyPrimitiveType(mode, count, program->usesPointSize())) - { - return gl::Error(GL_NO_ERROR); - } - - error = applyRenderTarget(data, mode, false); - if (error.isError()) - { - return error; - } - - error = applyState(data, mode); - if (error.isError()) - { - return error; - } - - applyTransformFeedbackBuffers(*data.state); - - error = applyVertexBuffer(*data.state, mode, first, count, instances); - if (error.isError()) - { - return error; - } - - error = applyShaders(data); - if (error.isError()) - { - return error; - } - - error = applyTextures(data); - if (error.isError()) - { - return error; - } - - error = program->applyUniformBuffers(data); - if (error.isError()) - { - return error; - } + ANGLE_TRY(updateState(data, mode)); + ANGLE_TRY(applyTransformFeedbackBuffers(*data.state)); + ANGLE_TRY(applyVertexBuffer(*data.state, mode, first, count, instances, nullptr)); + ANGLE_TRY(applyTextures(data)); + ANGLE_TRY(applyShaders(data, mode)); + ANGLE_TRY(programD3D->applyUniformBuffers(data)); if (!skipDraw(data, mode)) { - error = drawArrays(data, mode, count, instances, program->usesPointSize()); - if (error.isError()) - { - return error; - } + ANGLE_TRY(drawArraysImpl(data, mode, first, count, instances)); if (data.state->isTransformFeedbackActiveUnpaused()) { - markTransformFeedbackUsage(data); + ANGLE_TRY(markTransformFeedbackUsage(data)); } } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } gl::Error RendererD3D::generateSwizzles(const gl::Data &data, gl::SamplerType type) { - gl::Program *program = data.state->getProgram(); + ProgramD3D *programD3D = GetImplAs(data.state->getProgram()); - size_t samplerRange = program->getUsedSamplerRange(type); + unsigned int samplerRange = programD3D->getUsedSamplerRange(type); - for (size_t i = 0; i < samplerRange; i++) + for (unsigned int i = 0; i < samplerRange; i++) { - GLenum textureType = program->getSamplerTextureType(type, i); - GLint textureUnit = program->getSamplerMapping(type, i, *data.caps); + GLenum textureType = programD3D->getSamplerTextureType(type, i); + GLint textureUnit = programD3D->getSamplerMapping(type, i, *data.caps); if (textureUnit != -1) { gl::Texture *texture = data.state->getSamplerTexture(textureUnit, textureType); ASSERT(texture); - if (texture->getSamplerState().swizzleRequired()) + if (texture->getTextureState().swizzleRequired()) { - gl::Error error = generateSwizzle(texture); - if (error.isError()) - { - return error; - } + ANGLE_TRY(generateSwizzle(texture)); } } } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } gl::Error RendererD3D::generateSwizzles(const gl::Data &data) { - gl::Error error = generateSwizzles(data, gl::SAMPLER_VERTEX); - if (error.isError()) - { - return error; - } - - error = generateSwizzles(data, gl::SAMPLER_PIXEL); - if (error.isError()) - { - return error; - } - - return gl::Error(GL_NO_ERROR); -} - -// Applies the render target surface, depth stencil surface, viewport rectangle and -// scissor rectangle to the renderer -gl::Error RendererD3D::applyRenderTarget(const gl::Data &data, GLenum drawMode, bool ignoreViewport) -{ - const gl::Framebuffer *framebufferObject = data.state->getDrawFramebuffer(); - ASSERT(framebufferObject && framebufferObject->checkStatus(data) == GL_FRAMEBUFFER_COMPLETE); - - gl::Error error = applyRenderTarget(framebufferObject); - if (error.isError()) - { - return error; - } - - float nearZ = data.state->getNearPlane(); - float farZ = data.state->getFarPlane(); - setViewport(data.state->getViewport(), nearZ, farZ, drawMode, - data.state->getRasterizerState().frontFace, ignoreViewport); - - setScissorRectangle(data.state->getScissor(), data.state->isScissorTestEnabled()); - - return gl::Error(GL_NO_ERROR); + ANGLE_TRY(generateSwizzles(data, gl::SAMPLER_VERTEX)); + ANGLE_TRY(generateSwizzles(data, gl::SAMPLER_PIXEL)); + return gl::NoError(); } -// Applies the fixed-function state (culling, depth test, alpha blending, stenciling, etc) to the Direct3D device -gl::Error RendererD3D::applyState(const gl::Data &data, GLenum drawMode) +unsigned int RendererD3D::GetBlendSampleMask(const gl::Data &data, int samples) { - const gl::Framebuffer *framebufferObject = data.state->getDrawFramebuffer(); - int samples = framebufferObject->getSamples(data); - - gl::RasterizerState rasterizer = data.state->getRasterizerState(); - rasterizer.pointDrawMode = (drawMode == GL_POINTS); - rasterizer.multiSample = (samples != 0); - - gl::Error error = setRasterizerState(rasterizer); - if (error.isError()) - { - return error; - } - unsigned int mask = 0; if (data.state->isSampleCoverageEnabled()) { @@ -333,147 +272,103 @@ gl::Error RendererD3D::applyState(const gl::Data &data, GLenum drawMode) { mask = 0xFFFFFFFF; } - error = setBlendState(framebufferObject, data.state->getBlendState(), data.state->getBlendColor(), mask); - if (error.isError()) - { - return error; - } - error = setDepthStencilState(data.state->getDepthStencilState(), data.state->getStencilRef(), - data.state->getStencilBackRef(), rasterizer.frontFace == GL_CCW); - if (error.isError()) - { - return error; - } - - return gl::Error(GL_NO_ERROR); + return mask; } // Applies the shaders and shader constants to the Direct3D device -gl::Error RendererD3D::applyShaders(const gl::Data &data) +gl::Error RendererD3D::applyShaders(const gl::Data &data, GLenum drawMode) { gl::Program *program = data.state->getProgram(); + ProgramD3D *programD3D = GetImplAs(program); + programD3D->updateCachedInputLayout(*data.state); - gl::VertexFormat inputLayout[gl::MAX_VERTEX_ATTRIBS]; - gl::VertexFormat::GetInputLayout(inputLayout, program, *data.state); - - const gl::Framebuffer *fbo = data.state->getDrawFramebuffer(); - - gl::Error error = applyShaders(program, inputLayout, fbo, data.state->getRasterizerState().rasterizerDiscard, data.state->isTransformFeedbackActiveUnpaused()); - if (error.isError()) - { - return error; - } + ANGLE_TRY(applyShadersImpl(data, drawMode)); - return program->applyUniforms(); + return programD3D->applyUniforms(drawMode); } // 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. gl::Error RendererD3D::applyTextures(const gl::Data &data, gl::SamplerType shaderType, - const FramebufferTextureSerialArray &framebufferSerials, size_t framebufferSerialCount) + const FramebufferTextureArray &framebufferTextures, size_t framebufferTextureCount) { - gl::Program *program = data.state->getProgram(); + ProgramD3D *programD3D = GetImplAs(data.state->getProgram()); + + ASSERT(!programD3D->isSamplerMappingDirty()); - size_t samplerRange = program->getUsedSamplerRange(shaderType); - for (size_t samplerIndex = 0; samplerIndex < samplerRange; samplerIndex++) + unsigned int samplerRange = programD3D->getUsedSamplerRange(shaderType); + for (unsigned int samplerIndex = 0; samplerIndex < samplerRange; samplerIndex++) { - GLenum textureType = program->getSamplerTextureType(shaderType, samplerIndex); - GLint textureUnit = program->getSamplerMapping(shaderType, samplerIndex, *data.caps); + GLenum textureType = programD3D->getSamplerTextureType(shaderType, samplerIndex); + GLint textureUnit = programD3D->getSamplerMapping(shaderType, samplerIndex, *data.caps); if (textureUnit != -1) { gl::Texture *texture = data.state->getSamplerTexture(textureUnit, textureType); ASSERT(texture); - gl::SamplerState sampler = texture->getSamplerState(); gl::Sampler *samplerObject = data.state->getSampler(textureUnit); - if (samplerObject) - { - samplerObject->getState(&sampler); - } + + const gl::SamplerState &samplerState = + samplerObject ? samplerObject->getSamplerState() : texture->getSamplerState(); // TODO: std::binary_search may become unavailable using older versions of GCC - if (texture->isSamplerComplete(sampler, data) && - !std::binary_search(framebufferSerials.begin(), framebufferSerials.begin() + framebufferSerialCount, texture->getTextureSerial())) + if (texture->isSamplerComplete(samplerState, data) && + !std::binary_search(framebufferTextures.begin(), + framebufferTextures.begin() + framebufferTextureCount, texture)) { - gl::Error error = setSamplerState(shaderType, samplerIndex, texture, sampler); - if (error.isError()) - { - return error; - } - - error = setTexture(shaderType, samplerIndex, texture); - if (error.isError()) - { - return error; - } + ANGLE_TRY(setSamplerState(shaderType, samplerIndex, texture, samplerState)); + ANGLE_TRY(setTexture(shaderType, samplerIndex, texture)); } else { // Texture is not sampler complete or it is in use by the framebuffer. Bind the incomplete texture. gl::Texture *incompleteTexture = getIncompleteTexture(textureType); - gl::Error error = setTexture(shaderType, samplerIndex, incompleteTexture); - if (error.isError()) - { - return error; - } + + ANGLE_TRY(setSamplerState(shaderType, samplerIndex, incompleteTexture, + incompleteTexture->getSamplerState())); + ANGLE_TRY(setTexture(shaderType, samplerIndex, incompleteTexture)); } } else { // No texture bound to this slot even though it is used by the shader, bind a NULL texture - gl::Error error = setTexture(shaderType, samplerIndex, NULL); - if (error.isError()) - { - return error; - } + ANGLE_TRY(setTexture(shaderType, samplerIndex, nullptr)); } } // Set all the remaining textures to NULL size_t samplerCount = (shaderType == gl::SAMPLER_PIXEL) ? data.caps->maxTextureImageUnits : data.caps->maxVertexTextureImageUnits; - for (size_t samplerIndex = samplerRange; samplerIndex < samplerCount; samplerIndex++) - { - gl::Error error = setTexture(shaderType, samplerIndex, NULL); - if (error.isError()) - { - return error; - } - } + clearTextures(shaderType, samplerRange, samplerCount); - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } gl::Error RendererD3D::applyTextures(const gl::Data &data) { - FramebufferTextureSerialArray framebufferSerials; - size_t framebufferSerialCount = getBoundFramebufferTextureSerials(data, &framebufferSerials); - - gl::Error error = applyTextures(data, gl::SAMPLER_VERTEX, framebufferSerials, framebufferSerialCount); - if (error.isError()) - { - return error; - } - - error = applyTextures(data, gl::SAMPLER_PIXEL, framebufferSerials, framebufferSerialCount); - if (error.isError()) - { - return error; - } + FramebufferTextureArray framebufferTextures; + size_t framebufferSerialCount = getBoundFramebufferTextures(data, &framebufferTextures); - return gl::Error(GL_NO_ERROR); + ANGLE_TRY(applyTextures(data, gl::SAMPLER_VERTEX, framebufferTextures, framebufferSerialCount)); + ANGLE_TRY(applyTextures(data, gl::SAMPLER_PIXEL, framebufferTextures, framebufferSerialCount)); + return gl::NoError(); } bool RendererD3D::skipDraw(const gl::Data &data, GLenum drawMode) { + const gl::State &state = *data.state; + if (drawMode == GL_POINTS) { + bool usesPointSize = GetImplAs(state.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 (!data.state->getProgram()->usesPointSize() && !data.state->isTransformFeedbackActiveUnpaused()) + if (!usesPointSize && !state.isTransformFeedbackActiveUnpaused()) { // This is stictly speaking not an error, but developers should be // notified of risking undefined behavior. @@ -484,7 +379,8 @@ bool RendererD3D::skipDraw(const gl::Data &data, GLenum drawMode) } else if (gl::IsTriangleMode(drawMode)) { - if (data.state->getRasterizerState().cullFace && data.state->getRasterizerState().cullMode == GL_FRONT_AND_BACK) + if (state.getRasterizerState().cullFace && + state.getRasterizerState().cullMode == GL_FRONT_AND_BACK) { return true; } @@ -493,7 +389,7 @@ bool RendererD3D::skipDraw(const gl::Data &data, GLenum drawMode) return false; } -void RendererD3D::markTransformFeedbackUsage(const gl::Data &data) +gl::Error RendererD3D::markTransformFeedbackUsage(const gl::Data &data) { const gl::TransformFeedback *transformFeedback = data.state->getCurrentTransformFeedback(); for (size_t i = 0; i < transformFeedback->getIndexedBufferCount(); i++) @@ -502,37 +398,36 @@ void RendererD3D::markTransformFeedbackUsage(const gl::Data &data) if (binding.get() != nullptr) { BufferD3D *bufferD3D = GetImplAs(binding.get()); - bufferD3D->markTransformFeedbackUsage(); + ANGLE_TRY(bufferD3D->markTransformFeedbackUsage()); } } + + return gl::NoError(); } -size_t RendererD3D::getBoundFramebufferTextureSerials(const gl::Data &data, - FramebufferTextureSerialArray *outSerialArray) +size_t RendererD3D::getBoundFramebufferTextures(const gl::Data &data, FramebufferTextureArray *outTextureArray) { - size_t serialCount = 0; + size_t textureCount = 0; const gl::Framebuffer *drawFramebuffer = data.state->getDrawFramebuffer(); - for (unsigned int i = 0; i < data.caps->maxColorAttachments; i++) + for (size_t i = 0; i < drawFramebuffer->getNumColorBuffers(); i++) { const gl::FramebufferAttachment *attachment = drawFramebuffer->getColorbuffer(i); if (attachment && attachment->type() == GL_TEXTURE) { - gl::Texture *texture = attachment->getTexture(); - (*outSerialArray)[serialCount++] = texture->getTextureSerial(); + (*outTextureArray)[textureCount++] = attachment->getTexture(); } } const gl::FramebufferAttachment *depthStencilAttachment = drawFramebuffer->getDepthOrStencilbuffer(); if (depthStencilAttachment && depthStencilAttachment->type() == GL_TEXTURE) { - gl::Texture *depthStencilTexture = depthStencilAttachment->getTexture(); - (*outSerialArray)[serialCount++] = depthStencilTexture->getTextureSerial(); + (*outTextureArray)[textureCount++] = depthStencilAttachment->getTexture(); } - std::sort(outSerialArray->begin(), outSerialArray->begin() + serialCount); + std::sort(outTextureArray->begin(), outTextureArray->begin() + textureCount); - return serialCount; + return textureCount; } gl::Texture *RendererD3D::getIncompleteTexture(GLenum type) @@ -541,20 +436,26 @@ gl::Texture *RendererD3D::getIncompleteTexture(GLenum type) { const GLubyte color[] = { 0, 0, 0, 255 }; const gl::Extents colorSize(1, 1, 1); - const gl::PixelUnpackState incompleteUnpackState(1, 0); + const gl::PixelUnpackState unpack(1, 0); + const gl::Box area(0, 0, 0, 1, 1, 1); - gl::Texture* t = new gl::Texture(createTexture(type), gl::Texture::INCOMPLETE_TEXTURE_ID, type); + // Skip the API layer to avoid needing to pass the Context and mess with dirty bits. + gl::Texture *t = + new gl::Texture(createTexture(type), std::numeric_limits::max(), type); + t->setStorage(type, 1, GL_RGBA8, colorSize); if (type == GL_TEXTURE_CUBE_MAP) { for (GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X; face <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z; face++) { - t->setImage(face, 0, GL_RGBA, colorSize, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color); + t->getImplementation()->setSubImage(face, 0, area, GL_RGBA8, GL_UNSIGNED_BYTE, + unpack, color); } } else { - t->setImage(type, 0, GL_RGBA, colorSize, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color); + t->getImplementation()->setSubImage(type, 0, area, GL_RGBA8, GL_UNSIGNED_BYTE, unpack, + color); } mIncompleteTextures[type].set(t); @@ -618,4 +519,68 @@ gl::Error RendererD3D::getScratchMemoryBuffer(size_t requestedSize, MemoryBuffer return gl::Error(GL_NO_ERROR); } +void RendererD3D::insertEventMarker(GLsizei length, const char *marker) +{ + std::vector wcstring (length + 1); + size_t convertedChars = 0; + errno_t err = mbstowcs_s(&convertedChars, wcstring.data(), length + 1, marker, _TRUNCATE); + if (err == 0) + { + getAnnotator()->setMarker(wcstring.data()); + } +} + +void RendererD3D::pushGroupMarker(GLsizei length, const char *marker) +{ + std::vector wcstring(length + 1); + size_t convertedChars = 0; + errno_t err = mbstowcs_s(&convertedChars, wcstring.data(), length + 1, marker, _TRUNCATE); + if (err == 0) + { + getAnnotator()->beginEvent(wcstring.data()); + } +} + +void RendererD3D::popGroupMarker() +{ + getAnnotator()->endEvent(); +} + +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::onMakeCurrent(const gl::Data &data) +{ +} + +void RendererD3D::initializeDebugAnnotator() +{ + createAnnotator(); + ASSERT(mAnnotator); + gl::InitializeDebugAnnotations(mAnnotator); +} + +gl::DebugAnnotator *RendererD3D::getAnnotator() +{ + ASSERT(mAnnotator); + return mAnnotator; } +} // namespace rx diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/RendererD3D.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/RendererD3D.h index 71c74c1f2cef..b21c7e85cbf4 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/RendererD3D.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/RendererD3D.h @@ -9,10 +9,15 @@ #ifndef LIBANGLE_RENDERER_D3D_RENDERERD3D_H_ #define LIBANGLE_RENDERER_D3D_RENDERERD3D_H_ +#include "common/debug.h" #include "common/MemoryBuffer.h" #include "libANGLE/Data.h" +#include "libANGLE/Device.h" +#include "libANGLE/formatutils.h" #include "libANGLE/renderer/Renderer.h" +#include "libANGLE/renderer/d3d/VertexDataManager.h" #include "libANGLE/renderer/d3d/formatutilsD3D.h" +#include "libANGLE/renderer/d3d/WorkaroundsD3D.h" #include "libANGLE/renderer/d3d/d3d11/NativeWindow.h" //FIXME(jmadill): std::array is currently prohibited by Chromium style guide @@ -25,15 +30,21 @@ class ConfigSet; namespace gl { +class DebugAnnotator; class InfoLog; -struct LinkedVarying; class Texture; +struct LinkedVarying; } namespace rx { +struct D3DUniform; +struct D3DVarying; +class DeviceD3D; +class EGLImageD3D; class ImageD3D; class IndexBuffer; +class ProgramD3D; class RenderTargetD3D; class ShaderExecutableD3D; class SwapChainD3D; @@ -45,7 +56,17 @@ enum ShaderType { SHADER_VERTEX, SHADER_PIXEL, - SHADER_GEOMETRY + SHADER_GEOMETRY, + SHADER_TYPE_MAX +}; + +struct DeviceIdentifier +{ + UINT VendorId; + UINT DeviceId; + UINT SubSysId; + UINT Revision; + UINT FeatureLevel; }; enum RendererClass @@ -65,10 +86,16 @@ class BufferFactoryD3D virtual IndexBuffer *createIndexBuffer() = 0; // TODO(jmadill): add VertexFormatCaps - virtual VertexConversionType getVertexConversionType(const gl::VertexFormat &vertexFormat) const = 0; - virtual GLenum getVertexComponentType(const gl::VertexFormat &vertexFormat) const = 0; + virtual VertexConversionType getVertexConversionType(gl::VertexFormatType vertexFormatType) const = 0; + virtual GLenum getVertexComponentType(gl::VertexFormatType vertexFormatType) const = 0; + virtual gl::ErrorOrResult getVertexSpaceRequired( + const gl::VertexAttribute &attrib, + GLsizei count, + GLsizei instances) const = 0; }; +using AttribIndexArray = std::array; + class RendererD3D : public Renderer, public BufferFactoryD3D { public: @@ -78,66 +105,92 @@ class RendererD3D : public Renderer, public BufferFactoryD3D virtual egl::Error initialize() = 0; virtual egl::ConfigSet generateConfigs() const = 0; + virtual void generateDisplayExtensions(egl::DisplayExtensions *outExtensions) const = 0; - gl::Error drawArrays(const gl::Data &data, - GLenum mode, GLint first, - GLsizei count, GLsizei instances) override; + gl::Error drawArrays(const gl::Data &data, GLenum mode, GLint first, GLsizei count) override; + gl::Error drawArraysInstanced(const gl::Data &data, + GLenum mode, + GLint first, + GLsizei count, + GLsizei instanceCount) override; gl::Error drawElements(const gl::Data &data, - GLenum mode, GLsizei count, GLenum type, - const GLvoid *indices, GLsizei instances, - const RangeUI &indexRange) override; + GLenum mode, + GLsizei count, + GLenum type, + const GLvoid *indices, + const gl::IndexRange &indexRange) override; + gl::Error drawElementsInstanced(const gl::Data &data, + GLenum mode, + GLsizei count, + GLenum type, + const GLvoid *indices, + GLsizei instances, + const gl::IndexRange &indexRange) override; + gl::Error drawRangeElements(const gl::Data &data, + GLenum mode, + GLuint start, + GLuint end, + GLsizei count, + GLenum type, + const GLvoid *indices, + const gl::IndexRange &indexRange) override; bool isDeviceLost() const override; std::string getVendorString() const override; + SamplerImpl *createSampler() override; + virtual int getMinorShaderModel() const = 0; virtual std::string getShaderModelSuffix() const = 0; // Direct3D Specific methods - virtual GUID getAdapterIdentifier() const = 0; + virtual DeviceIdentifier getAdapterIdentifier() const = 0; - virtual bool shouldCreateChildWindowForSurface(EGLNativeWindowType window) const = 0; - virtual SwapChainD3D *createSwapChain(NativeWindow nativeWindow, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat) = 0; + virtual SwapChainD3D *createSwapChain(NativeWindow nativeWindow, + HANDLE shareHandle, + GLenum backBufferFormat, + GLenum depthBufferFormat, + EGLint orientation) = 0; virtual gl::Error generateSwizzle(gl::Texture *texture) = 0; virtual gl::Error setSamplerState(gl::SamplerType type, int index, gl::Texture *texture, const gl::SamplerState &sampler) = 0; virtual gl::Error setTexture(gl::SamplerType type, int index, gl::Texture *texture) = 0; virtual gl::Error setUniformBuffers(const gl::Data &data, - const GLint vertexUniformBuffers[], - const GLint fragmentUniformBuffers[]) = 0; - - virtual gl::Error setRasterizerState(const gl::RasterizerState &rasterState) = 0; - virtual gl::Error setBlendState(const gl::Framebuffer *framebuffer, const gl::BlendState &blendState, const gl::ColorF &blendColor, - unsigned int sampleMask) = 0; - virtual gl::Error setDepthStencilState(const gl::DepthStencilState &depthStencilState, int stencilRef, - int stencilBackRef, bool frontFaceCCW) = 0; + const std::vector &vertexUniformBuffers, + const std::vector &fragmentUniformBuffers) = 0; - virtual void setScissorRectangle(const gl::Rectangle &scissor, bool enabled) = 0; - virtual void setViewport(const gl::Rectangle &viewport, float zNear, float zFar, GLenum drawMode, GLenum frontFace, - bool ignoreViewport) = 0; + virtual gl::Error updateState(const gl::Data &data, GLenum drawMode) = 0; virtual gl::Error applyRenderTarget(const gl::Framebuffer *frameBuffer) = 0; - virtual gl::Error applyShaders(gl::Program *program, const gl::VertexFormat inputLayout[], const gl::Framebuffer *framebuffer, - bool rasterizerDiscard, bool transformFeedbackActive) = 0; - virtual gl::Error applyUniforms(const ProgramImpl &program, const std::vector &uniformArray) = 0; + virtual gl::Error applyUniforms(const ProgramD3D &programD3D, + GLenum drawMode, + const std::vector &uniformArray) = 0; virtual bool applyPrimitiveType(GLenum primitiveType, GLsizei elementCount, bool usesPointSize) = 0; - virtual gl::Error applyVertexBuffer(const gl::State &state, GLenum mode, GLint first, GLsizei count, GLsizei instances) = 0; - virtual gl::Error applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementArrayBuffer, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo) = 0; - virtual void applyTransformFeedbackBuffers(const gl::State& state) = 0; - - virtual void markAllStateDirty() = 0; + virtual gl::Error applyVertexBuffer(const gl::State &state, + GLenum mode, + GLint first, + GLsizei count, + GLsizei instances, + TranslatedIndexData *indexInfo) = 0; + virtual gl::Error applyIndexBuffer(const gl::Data &data, + const GLvoid *indices, + GLsizei count, + GLenum mode, + GLenum type, + TranslatedIndexData *indexInfo) = 0; + virtual gl::Error applyTransformFeedbackBuffers(const gl::State &state) = 0; virtual unsigned int getReservedVertexUniformVectors() const = 0; virtual unsigned int getReservedFragmentUniformVectors() const = 0; virtual unsigned int getReservedVertexUniformBuffers() const = 0; virtual unsigned int getReservedFragmentUniformBuffers() const = 0; - virtual bool getShareHandleSupport() const = 0; - virtual bool getPostSubBufferSupport() const = 0; virtual int getMajorShaderModel() const = 0; + const WorkaroundsD3D &getWorkarounds() const; + // Pixel operations virtual gl::Error copyImage2D(const gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, const gl::Offset &destOffset, TextureStorage *storage, GLint level) = 0; @@ -150,22 +203,31 @@ class RendererD3D : public Renderer, public BufferFactoryD3D // RenderTarget creation virtual gl::Error createRenderTarget(int width, int height, GLenum format, GLsizei samples, RenderTargetD3D **outRT) = 0; + virtual gl::Error createRenderTargetCopy(RenderTargetD3D *source, RenderTargetD3D **outRT) = 0; // Shader operations - virtual gl::Error loadExecutable(const void *function, size_t length, ShaderType type, - const std::vector &transformFeedbackVaryings, - bool separatedOutputBuffers, ShaderExecutableD3D **outExecutable) = 0; - virtual gl::Error compileToExecutable(gl::InfoLog &infoLog, const std::string &shaderHLSL, ShaderType type, - const std::vector &transformFeedbackVaryings, - bool separatedOutputBuffers, const D3DCompilerWorkarounds &workarounds, + virtual gl::Error loadExecutable(const void *function, + size_t length, + ShaderType type, + const std::vector &streamOutVaryings, + bool separatedOutputBuffers, + ShaderExecutableD3D **outExecutable) = 0; + virtual gl::Error compileToExecutable(gl::InfoLog &infoLog, + const std::string &shaderHLSL, + ShaderType type, + const std::vector &streamOutVaryings, + bool separatedOutputBuffers, + const D3DCompilerWorkarounds &workarounds, ShaderExecutableD3D **outExectuable) = 0; virtual UniformStorageD3D *createUniformStorage(size_t storageSize) = 0; // Image operations virtual ImageD3D *createImage() = 0; virtual gl::Error generateMipmap(ImageD3D *dest, ImageD3D *source) = 0; - virtual gl::Error generateMipmapsUsingD3D(TextureStorage *storage, const gl::SamplerState &samplerState) = 0; + virtual gl::Error generateMipmapsUsingD3D(TextureStorage *storage, + const gl::TextureState &textureState) = 0; virtual TextureStorage *createTextureStorage2D(SwapChainD3D *swapChain) = 0; + virtual TextureStorage *createTextureStorageEGLImage(EGLImageD3D *eglImage) = 0; virtual TextureStorage *createTextureStorage2D(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, int levels, bool hintLevelZeroOnly) = 0; virtual TextureStorage *createTextureStorageCube(GLenum internalformat, bool renderTarget, int size, int levels, bool hintLevelZeroOnly) = 0; virtual TextureStorage *createTextureStorage3D(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, GLsizei depth, int levels) = 0; @@ -184,56 +246,105 @@ class RendererD3D : public Renderer, public BufferFactoryD3D gl::Error getScratchMemoryBuffer(size_t requestedSize, MemoryBuffer **bufferOut); - protected: - virtual gl::Error drawArrays(const gl::Data &data, GLenum mode, GLsizei count, GLsizei instances, bool usesPointSize) = 0; - virtual gl::Error drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, - gl::Buffer *elementArrayBuffer, const TranslatedIndexData &indexInfo, GLsizei instances) = 0; + // EXT_debug_marker + void insertEventMarker(GLsizei length, const char *marker) override; + void pushGroupMarker(GLsizei length, const char *marker) override; + void popGroupMarker() override; + + void setGPUDisjoint(); + + GLint getGPUDisjoint() override; + GLint64 getTimestamp() override; + + void onMakeCurrent(const gl::Data &data) override; + + // In D3D11, faster than calling setTexture a jillion times + virtual gl::Error clearTextures(gl::SamplerType samplerType, size_t rangeStart, size_t rangeEnd) = 0; + virtual egl::Error getEGLDevice(DeviceImpl **device) = 0; + + bool presentPathFastEnabled() const { return mPresentPathFastEnabled; } + + // Stream creation + virtual StreamImpl *createStream(const egl::AttributeMap &attribs) = 0; + + protected: virtual bool getLUID(LUID *adapterLuid) const = 0; + virtual gl::Error applyShadersImpl(const gl::Data &data, GLenum drawMode) = 0; void cleanup(); + virtual void createAnnotator() = 0; + + static unsigned int GetBlendSampleMask(const gl::Data &data, int samples); + // dirtyPointer is a special value that will make the comparison with any valid pointer fail and force the renderer to re-apply the state. + egl::Display *mDisplay; bool mDeviceLost; + void initializeDebugAnnotator(); + gl::DebugAnnotator *mAnnotator; + + bool mPresentPathFastEnabled; + private: + gl::Error genericDrawArrays(const gl::Data &data, + GLenum mode, + GLint first, + GLsizei count, + GLsizei instances); + + gl::Error genericDrawElements(const gl::Data &data, + GLenum mode, + GLsizei count, + GLenum type, + const GLvoid *indices, + GLsizei instances, + const gl::IndexRange &indexRange); + + virtual gl::Error drawArraysImpl(const gl::Data &data, + GLenum mode, + GLint startVertex, + GLsizei count, + GLsizei instances) = 0; + virtual gl::Error drawElementsImpl(const gl::Data &data, + const TranslatedIndexData &indexInfo, + GLenum mode, + GLsizei count, + GLenum type, + const GLvoid *indices, + GLsizei instances) = 0; + //FIXME(jmadill): std::array is currently prohibited by Chromium style guide - typedef std::array FramebufferTextureSerialArray; + typedef std::array FramebufferTextureArray; gl::Error generateSwizzles(const gl::Data &data, gl::SamplerType type); gl::Error generateSwizzles(const gl::Data &data); - gl::Error applyRenderTarget(const gl::Data &data, GLenum drawMode, bool ignoreViewport); gl::Error applyState(const gl::Data &data, GLenum drawMode); - gl::Error applyShaders(const gl::Data &data); + gl::Error applyShaders(const gl::Data &data, GLenum drawMode); gl::Error applyTextures(const gl::Data &data, gl::SamplerType shaderType, - const FramebufferTextureSerialArray &framebufferSerials, size_t framebufferSerialCount); + const FramebufferTextureArray &framebufferTextures, size_t framebufferTextureCount); gl::Error applyTextures(const gl::Data &data); bool skipDraw(const gl::Data &data, GLenum drawMode); - void markTransformFeedbackUsage(const gl::Data &data); + gl::Error markTransformFeedbackUsage(const gl::Data &data); - size_t getBoundFramebufferTextureSerials(const gl::Data &data, - FramebufferTextureSerialArray *outSerialArray); + size_t getBoundFramebufferTextures(const gl::Data &data, FramebufferTextureArray *outTextureArray); gl::Texture *getIncompleteTexture(GLenum type); + gl::DebugAnnotator *getAnnotator(); + + virtual WorkaroundsD3D generateWorkarounds() const = 0; + gl::TextureMap mIncompleteTextures; MemoryBuffer mScratchMemoryBuffer; unsigned int mScratchMemoryBufferResetCounter; -}; -struct dx_VertexConstants -{ - float depthRange[4]; - float viewAdjust[4]; - float viewCoords[4]; -}; + mutable bool mWorkaroundsInitialized; + mutable WorkaroundsD3D mWorkarounds; -struct dx_PixelConstants -{ - float depthRange[4]; - float viewCoords[4]; - float depthFront[4]; + bool mDisjoint; }; } diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/SamplerD3D.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/SamplerD3D.h new file mode 100644 index 000000000000..7aabdc8132fe --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/SamplerD3D.h @@ -0,0 +1,25 @@ +// +// 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() {} + ~SamplerD3D() override {} +}; +} + +#endif // LIBANGLE_RENDERER_D3D_SAMPLERD3D_H_ diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/ShaderD3D.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/ShaderD3D.cpp index 1cf68bfaf460..9fd987035c52 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/ShaderD3D.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/ShaderD3D.cpp @@ -6,14 +6,14 @@ // ShaderD3D.cpp: Defines the rx::ShaderD3D class which implements rx::ShaderImpl. -#include "libANGLE/Shader.h" -#include "libANGLE/Compiler.h" -#include "libANGLE/renderer/d3d/RendererD3D.h" #include "libANGLE/renderer/d3d/ShaderD3D.h" -#include "libANGLE/renderer/d3d/CompilerD3D.h" -#include "libANGLE/features.h" #include "common/utilities.h" +#include "libANGLE/Compiler.h" +#include "libANGLE/Shader.h" +#include "libANGLE/features.h" +#include "libANGLE/renderer/d3d/RendererD3D.h" +#include "libANGLE/renderer/d3d/ProgramD3D.h" // Definitions local to the translation unit namespace @@ -23,51 +23,24 @@ const char *GetShaderTypeString(GLenum type) { switch (type) { - case GL_VERTEX_SHADER: - return "VERTEX"; + case GL_VERTEX_SHADER: + return "VERTEX"; - case GL_FRAGMENT_SHADER: - return "FRAGMENT"; + case GL_FRAGMENT_SHADER: + return "FRAGMENT"; - default: - UNREACHABLE(); - return ""; + default: + UNREACHABLE(); + return ""; } } -} +} // anonymous namespace namespace rx { -template -void FilterInactiveVariables(std::vector *variableList) -{ - ASSERT(variableList); - - for (size_t varIndex = 0; varIndex < variableList->size();) - { - if (!(*variableList)[varIndex].staticUse) - { - variableList->erase(variableList->begin() + varIndex); - } - else - { - varIndex++; - } - } -} - -template -const std::vector *GetShaderVariables(const std::vector *variableList) -{ - ASSERT(variableList); - return variableList; -} - -ShaderD3D::ShaderD3D(GLenum type) - : mShaderType(type), - mShaderVersion(100) +ShaderD3D::ShaderD3D(const gl::Shader::Data &data) : ShaderImpl(data) { uncompile(); } @@ -78,44 +51,8 @@ ShaderD3D::~ShaderD3D() std::string ShaderD3D::getDebugInfo() const { - return mDebugInfo + std::string("\n// ") + GetShaderTypeString(mShaderType) + " SHADER END\n"; -} - - -void ShaderD3D::parseVaryings(ShHandle compiler) -{ - if (!mTranslatedSource.empty()) - { - const std::vector *varyings = ShGetVaryings(compiler); - ASSERT(varyings); - - for (size_t varyingIndex = 0; varyingIndex < varyings->size(); varyingIndex++) - { - mVaryings.push_back(gl::PackedVarying((*varyings)[varyingIndex])); - } - - mUsesMultipleRenderTargets = mTranslatedSource.find("GL_USES_MRT") != std::string::npos; - mUsesFragColor = mTranslatedSource.find("GL_USES_FRAG_COLOR") != std::string::npos; - mUsesFragData = mTranslatedSource.find("GL_USES_FRAG_DATA") != std::string::npos; - mUsesFragCoord = mTranslatedSource.find("GL_USES_FRAG_COORD") != std::string::npos; - mUsesFrontFacing = mTranslatedSource.find("GL_USES_FRONT_FACING") != std::string::npos; - mUsesPointSize = mTranslatedSource.find("GL_USES_POINT_SIZE") != std::string::npos; - mUsesPointCoord = mTranslatedSource.find("GL_USES_POINT_COORD") != std::string::npos; - mUsesDepthRange = mTranslatedSource.find("GL_USES_DEPTH_RANGE") != std::string::npos; - mUsesFragDepth = mTranslatedSource.find("GL_USES_FRAG_DEPTH") != std::string::npos; - mUsesDiscardRewriting = mTranslatedSource.find("ANGLE_USES_DISCARD_REWRITING") != std::string::npos; - mUsesNestedBreak = mTranslatedSource.find("ANGLE_USES_NESTED_BREAK") != std::string::npos; - mUsesDeferredInit = mTranslatedSource.find("ANGLE_USES_DEFERRED_INIT") != std::string::npos; - mRequiresIEEEStrictCompiling = mTranslatedSource.find("ANGLE_REQUIRES_IEEE_STRICT_COMPILING") != std::string::npos; - } -} - -void ShaderD3D::resetVaryingsRegisterAssignment() -{ - for (size_t varyingIndex = 0; varyingIndex < mVaryings.size(); varyingIndex++) - { - mVaryings[varyingIndex].resetRegisterAssignment(); - } + return mDebugInfo + std::string("\n// ") + GetShaderTypeString(mData.getShaderType()) + + " SHADER END\n"; } // initialize/clean up previous state @@ -123,8 +60,6 @@ void ShaderD3D::uncompile() { // set by compileToHLSL mCompilerOutputType = SH_ESSL_OUTPUT; - mTranslatedSource.clear(); - mInfoLog.clear(); mUsesMultipleRenderTargets = false; mUsesFragColor = false; @@ -135,125 +70,13 @@ void ShaderD3D::uncompile() mUsesPointCoord = false; mUsesDepthRange = false; mUsesFragDepth = false; - mShaderVersion = 100; mUsesDiscardRewriting = false; mUsesNestedBreak = false; - mUsesDeferredInit = false; mRequiresIEEEStrictCompiling = false; - mVaryings.clear(); - mUniforms.clear(); - mInterfaceBlocks.clear(); - mActiveAttributes.clear(); - mActiveOutputVariables.clear(); mDebugInfo.clear(); } -void ShaderD3D::compileToHLSL(ShHandle compiler, const std::string &source) -{ - int compileOptions = (SH_OBJECT_CODE | SH_VARIABLES); - std::string sourcePath; - -#if !defined (ANGLE_ENABLE_WINDOWS_STORE) - if (gl::DebugAnnotationsActive()) - { - sourcePath = getTempPath(); - writeFile(sourcePath.c_str(), source.c_str(), source.length()); - compileOptions |= SH_LINE_DIRECTIVES; - } -#endif - - int result; - if (sourcePath.empty()) - { - const char* sourceStrings[] = - { - source.c_str(), - }; - - result = ShCompile(compiler, sourceStrings, ArraySize(sourceStrings), compileOptions); - } - else - { - const char* sourceStrings[] = - { - sourcePath.c_str(), - source.c_str(), - }; - - result = ShCompile(compiler, sourceStrings, ArraySize(sourceStrings), compileOptions | SH_SOURCE_PATH); - } - - mShaderVersion = ShGetShaderVersion(compiler); - - if (result) - { - mTranslatedSource = ShGetObjectCode(compiler); - -#ifdef _DEBUG - // Prefix hlsl shader with commented out glsl shader - // Useful in diagnostics tools like pix which capture the hlsl shaders - std::ostringstream hlslStream; - hlslStream << "// GLSL\n"; - hlslStream << "//\n"; - - size_t curPos = 0; - while (curPos != std::string::npos) - { - size_t nextLine = source.find("\n", curPos); - size_t len = (nextLine == std::string::npos) ? std::string::npos : (nextLine - curPos + 1); - - hlslStream << "// " << source.substr(curPos, len); - - curPos = (nextLine == std::string::npos) ? std::string::npos : (nextLine + 1); - } - hlslStream << "\n\n"; - hlslStream << mTranslatedSource; - mTranslatedSource = hlslStream.str(); -#endif - - mUniforms = *GetShaderVariables(ShGetUniforms(compiler)); - - for (size_t uniformIndex = 0; uniformIndex < mUniforms.size(); uniformIndex++) - { - const sh::Uniform &uniform = mUniforms[uniformIndex]; - - if (uniform.staticUse && !uniform.isBuiltIn()) - { - unsigned int index = static_cast(-1); - bool getUniformRegisterResult = ShGetUniformRegister(compiler, uniform.name, &index); - UNUSED_ASSERTION_VARIABLE(getUniformRegisterResult); - ASSERT(getUniformRegisterResult); - - mUniformRegisterMap[uniform.name] = index; - } - } - - mInterfaceBlocks = *GetShaderVariables(ShGetInterfaceBlocks(compiler)); - - for (size_t blockIndex = 0; blockIndex < mInterfaceBlocks.size(); blockIndex++) - { - const sh::InterfaceBlock &interfaceBlock = mInterfaceBlocks[blockIndex]; - - if (interfaceBlock.staticUse) - { - unsigned int index = static_cast(-1); - bool blockRegisterResult = ShGetInterfaceBlockRegister(compiler, interfaceBlock.name, &index); - UNUSED_ASSERTION_VARIABLE(blockRegisterResult); - ASSERT(blockRegisterResult); - - mInterfaceBlockRegisterMap[interfaceBlock.name] = index; - } - } - } - else - { - mInfoLog = ShGetInfoLog(compiler); - - TRACE("\n%s", mInfoLog.c_str()); - } -} - void ShaderD3D::generateWorkarounds(D3DCompilerWorkarounds *workarounds) const { if (mUsesDiscardRewriting) @@ -277,28 +100,6 @@ void ShaderD3D::generateWorkarounds(D3DCompilerWorkarounds *workarounds) const } } -// true if varying x has a higher priority in packing than y -bool ShaderD3D::compareVarying(const gl::PackedVarying &x, const gl::PackedVarying &y) -{ - if (x.type == y.type) - { - return x.arraySize > y.arraySize; - } - - // Special case for handling structs: we sort these to the end of the list - if (x.type == GL_STRUCT_ANGLEX) - { - return false; - } - - if (y.type == GL_STRUCT_ANGLEX) - { - return true; - } - - return gl::VariableSortOrder(x.type) < gl::VariableSortOrder(y.type); -} - unsigned int ShaderD3D::getUniformRegister(const std::string &uniformName) const { ASSERT(mUniformRegisterMap.count(uniformName) > 0); @@ -311,66 +112,91 @@ unsigned int ShaderD3D::getInterfaceBlockRegister(const std::string &blockName) return mInterfaceBlockRegisterMap.find(blockName)->second; } -GLenum ShaderD3D::getShaderType() const -{ - return mShaderType; -} - ShShaderOutput ShaderD3D::getCompilerOutputType() const { return mCompilerOutputType; } -bool ShaderD3D::compile(gl::Compiler *compiler, const std::string &source) +int ShaderD3D::prepareSourceAndReturnOptions(std::stringstream *shaderSourceStream, + std::string *sourcePath) { uncompile(); - CompilerD3D *compilerD3D = GetImplAs(compiler); - ShHandle compilerHandle = compilerD3D->getCompilerHandle(mShaderType); + int additionalOptions = 0; - mCompilerOutputType = ShGetShaderOutputType(compilerHandle); + const std::string &source = mData.getSource(); - compileToHLSL(compilerHandle, source); - - if (mShaderType == GL_VERTEX_SHADER) +#if !defined(ANGLE_ENABLE_WINDOWS_STORE) + if (gl::DebugAnnotationsActive()) { - parseAttributes(compilerHandle); + *sourcePath = getTempPath(); + writeFile(sourcePath->c_str(), source.c_str(), source.length()); + additionalOptions |= SH_LINE_DIRECTIVES | SH_SOURCE_PATH; } +#endif - parseVaryings(compilerHandle); - - if (mShaderType == GL_FRAGMENT_SHADER) - { - std::sort(mVaryings.begin(), mVaryings.end(), compareVarying); - - const std::string &hlsl = getTranslatedSource(); - if (!hlsl.empty()) - { - mActiveOutputVariables = *GetShaderVariables(ShGetOutputVariables(compilerHandle)); - FilterInactiveVariables(&mActiveOutputVariables); - } - } + *shaderSourceStream << source; + return additionalOptions; +} -#if ANGLE_SHADER_DEBUG_INFO == ANGLE_ENABLED - mDebugInfo += std::string("// ") + GetShaderTypeString(mShaderType) + " SHADER BEGIN\n"; - mDebugInfo += "\n// GLSL BEGIN\n\n" + source + "\n\n// GLSL END\n\n\n"; - mDebugInfo += "// INITIAL HLSL BEGIN\n\n" + getTranslatedSource() + "\n// INITIAL HLSL END\n\n\n"; - // Successive steps will append more info -#else - mDebugInfo += getTranslatedSource(); -#endif +bool ShaderD3D::hasUniform(const D3DUniform *d3dUniform) const +{ + return mUniformRegisterMap.find(d3dUniform->name) != mUniformRegisterMap.end(); +} - return !getTranslatedSource().empty(); +const std::map &GetUniformRegisterMap( + const std::map *uniformRegisterMap) +{ + ASSERT(uniformRegisterMap); + return *uniformRegisterMap; } -void ShaderD3D::parseAttributes(ShHandle compiler) +bool ShaderD3D::postTranslateCompile(gl::Compiler *compiler, std::string *infoLog) { - const std::string &hlsl = getTranslatedSource(); - if (!hlsl.empty()) + // TODO(jmadill): We shouldn't need to cache this. + mCompilerOutputType = compiler->getShaderOutputType(); + + const std::string &translatedSource = mData.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; + mUsesFragCoord = translatedSource.find("GL_USES_FRAG_COORD") != std::string::npos; + mUsesFrontFacing = translatedSource.find("GL_USES_FRONT_FACING") != 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; + 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->getCompilerHandle(mData.getShaderType()); + + mUniformRegisterMap = GetUniformRegisterMap(ShGetUniformRegisterMap(compilerHandle)); + + for (const sh::InterfaceBlock &interfaceBlock : mData.getInterfaceBlocks()) { - mActiveAttributes = *GetShaderVariables(ShGetAttributes(compiler)); - FilterInactiveVariables(&mActiveAttributes); + if (interfaceBlock.staticUse) + { + unsigned int index = static_cast(-1); + bool blockRegisterResult = + ShGetInterfaceBlockRegister(compilerHandle, interfaceBlock.name, &index); + UNUSED_ASSERTION_VARIABLE(blockRegisterResult); + ASSERT(blockRegisterResult); + + mInterfaceBlockRegisterMap[interfaceBlock.name] = index; + } } -} + mDebugInfo += + std::string("// ") + GetShaderTypeString(mData.getShaderType()) + " SHADER BEGIN\n"; + mDebugInfo += "\n// GLSL BEGIN\n\n" + mData.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; } + +} // namespace rx diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/ShaderD3D.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/ShaderD3D.h index 5d9fc8b614a6..7ed78e2f8b2a 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/ShaderD3D.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/ShaderD3D.h @@ -10,8 +10,6 @@ #define LIBANGLE_RENDERER_D3D_SHADERD3D_H_ #include "libANGLE/renderer/ShaderImpl.h" -#include "libANGLE/renderer/Workarounds.h" -#include "libANGLE/Shader.h" #include @@ -19,48 +17,48 @@ namespace rx { class DynamicHLSL; class RendererD3D; +struct D3DCompilerWorkarounds; +struct D3DUniform; class ShaderD3D : public ShaderImpl { - friend class DynamicHLSL; - public: - ShaderD3D(GLenum type); + ShaderD3D(const gl::Shader::Data &data); virtual ~ShaderD3D(); // ShaderImpl implementation - virtual std::string getDebugInfo() const; + int prepareSourceAndReturnOptions(std::stringstream *sourceStream, + std::string *sourcePath) override; + bool postTranslateCompile(gl::Compiler *compiler, std::string *infoLog) override; + std::string getDebugInfo() const override; // D3D-specific methods - virtual void uncompile(); - void resetVaryingsRegisterAssignment(); + void uncompile(); + + bool hasUniform(const D3DUniform *d3dUniform) 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 getInterfaceBlockRegister(const std::string &blockName) const; - void appendDebugInfo(const std::string &info) { mDebugInfo += info; } + void appendDebugInfo(const std::string &info) const { mDebugInfo += info; } void generateWorkarounds(D3DCompilerWorkarounds *workarounds) const; - int getShaderVersion() const { return mShaderVersion; } - bool usesDepthRange() const { return mUsesDepthRange; } + + bool usesMultipleRenderTargets() const { return mUsesMultipleRenderTargets; } + bool usesFragColor() const { return mUsesFragColor; } + bool usesFragData() const { return mUsesFragData; } + bool usesFragCoord() const { return mUsesFragCoord; } + bool usesFrontFacing() const { return mUsesFrontFacing; } bool usesPointSize() const { return mUsesPointSize; } - bool usesDeferredInit() const { return mUsesDeferredInit; } + bool usesPointCoord() const { return mUsesPointCoord; } + bool usesDepthRange() const { return mUsesDepthRange; } + bool usesFragDepth() const { return mUsesFragDepth; } - GLenum getShaderType() const; ShShaderOutput getCompilerOutputType() const; - virtual bool compile(gl::Compiler *compiler, const std::string &source); - private: - void compileToHLSL(ShHandle compiler, const std::string &source); - void parseVaryings(ShHandle compiler); - - void parseAttributes(ShHandle compiler); - - static bool compareVarying(const gl::PackedVarying &x, const gl::PackedVarying &y); - - GLenum mShaderType; - - int mShaderVersion; - bool mUsesMultipleRenderTargets; bool mUsesFragColor; bool mUsesFragData; @@ -72,15 +70,13 @@ class ShaderD3D : public ShaderImpl bool mUsesFragDepth; bool mUsesDiscardRewriting; bool mUsesNestedBreak; - bool mUsesDeferredInit; bool mRequiresIEEEStrictCompiling; ShShaderOutput mCompilerOutputType; - std::string mDebugInfo; + mutable std::string mDebugInfo; std::map mUniformRegisterMap; std::map mInterfaceBlockRegisterMap; }; - } -#endif // LIBANGLE_RENDERER_D3D_SHADERD3D_H_ +#endif // LIBANGLE_RENDERER_D3D_SHADERD3D_H_ diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/SurfaceD3D.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/SurfaceD3D.cpp index aa1219ab40ac..93f69904a3d2 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/SurfaceD3D.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/SurfaceD3D.cpp @@ -10,7 +10,6 @@ #include "libANGLE/Display.h" #include "libANGLE/Surface.h" -#include "libANGLE/renderer/d3d/DisplayD3D.h" #include "libANGLE/renderer/d3d/RendererD3D.h" #include "libANGLE/renderer/d3d/RenderTargetD3D.h" #include "libANGLE/renderer/d3d/SwapChainD3D.h" @@ -25,44 +24,54 @@ namespace rx SurfaceD3D *SurfaceD3D::createOffscreen(RendererD3D *renderer, egl::Display *display, const egl::Config *config, EGLClientBuffer shareHandle, EGLint width, EGLint height) { - return new SurfaceD3D(renderer, display, config, width, height, EGL_TRUE, shareHandle, NULL); + return new SurfaceD3D(renderer, display, config, width, height, EGL_TRUE, 0, EGL_FALSE, + shareHandle, NULL); } -SurfaceD3D *SurfaceD3D::createFromWindow(RendererD3D *renderer, egl::Display *display, const egl::Config *config, EGLNativeWindowType window, - EGLint fixedSize, EGLint width, EGLint height) +SurfaceD3D *SurfaceD3D::createFromWindow(RendererD3D *renderer, + egl::Display *display, + const egl::Config *config, + EGLNativeWindowType window, + EGLint fixedSize, + EGLint directComposition, + EGLint width, + EGLint height, + EGLint orientation) { - return new SurfaceD3D(renderer, display, config, width, height, fixedSize, static_cast(0), window); + return new SurfaceD3D(renderer, display, config, width, height, fixedSize, orientation, + directComposition, static_cast(0), window); } -SurfaceD3D::SurfaceD3D(RendererD3D *renderer, egl::Display *display, const egl::Config *config, EGLint width, EGLint height, EGLint fixedSize, - EGLClientBuffer shareHandle, EGLNativeWindowType window) +SurfaceD3D::SurfaceD3D(RendererD3D *renderer, + egl::Display *display, + const egl::Config *config, + EGLint width, + EGLint height, + EGLint fixedSize, + EGLint orientation, + EGLint directComposition, + EGLClientBuffer shareHandle, + EGLNativeWindowType window) : SurfaceImpl(), mRenderer(renderer), mDisplay(display), mFixedSize(fixedSize == EGL_TRUE), + mOrientation(orientation), mRenderTargetFormat(config->renderTargetFormat), mDepthStencilFormat(config->depthStencilFormat), mSwapChain(nullptr), mSwapIntervalDirty(true), - mNativeWindow(window), + mNativeWindow(window, config, directComposition == EGL_TRUE), mWidth(width), mHeight(height), - mChildWindow(nullptr), mSwapInterval(1), - mShareHandle(reinterpret_cast(shareHandle)) + mShareHandle(reinterpret_cast(shareHandle)) { } SurfaceD3D::~SurfaceD3D() { releaseSwapChain(); - -#if !defined(ANGLE_ENABLE_WINDOWS_STORE) - if (mChildWindow.getNativeWindow() != nullptr) - { - DestroyWindow(mChildWindow.getNativeWindow()); - } -#endif } void SurfaceD3D::releaseSwapChain() @@ -74,44 +83,6 @@ egl::Error SurfaceD3D::initialize() { if (mNativeWindow.getNativeWindow()) { -#if !defined(ANGLE_ENABLE_WINDOWS_STORE) - if (mRenderer->shouldCreateChildWindowForSurface(mNativeWindow.getNativeWindow())) - { - RECT rect; - if (!mNativeWindow.getClientRect(&rect)) - { - return egl::Error(EGL_BAD_NATIVE_WINDOW, "Failed to get the size of the native window."); - } - - DisplayD3D *displayD3D = GetImplAs(mDisplay); - ATOM windowClass = displayD3D->getChildWindowClass(); - - HWND childWindow = CreateWindowExA(WS_EX_NOPARENTNOTIFY, - reinterpret_cast(windowClass), - "ANGLE Intermediate Surface Window", - WS_CHILDWINDOW | WS_DISABLED | WS_VISIBLE, - 0, - 0, - rect.right - rect.left, - rect.bottom - rect.top, - mNativeWindow.getNativeWindow(), - nullptr, - nullptr, - nullptr); - if (!childWindow) - { - return egl::Error(EGL_NOT_INITIALIZED, "Failed to create child window."); - } - - mChildWindow = NativeWindow(childWindow); - - if (!mChildWindow.initialize()) - { - return egl::Error(EGL_BAD_SURFACE); - } - } -#endif - if (!mNativeWindow.initialize()) { return egl::Error(EGL_BAD_SURFACE); @@ -127,7 +98,12 @@ egl::Error SurfaceD3D::initialize() return egl::Error(EGL_SUCCESS); } -egl::Error SurfaceD3D::bindTexImage(EGLint) +FramebufferImpl *SurfaceD3D::createDefaultFramebuffer(const gl::Framebuffer::Data &data) +{ + return mRenderer->createFramebuffer(data); +} + +egl::Error SurfaceD3D::bindTexImage(gl::Texture *, EGLint) { return egl::Error(EGL_SUCCESS); } @@ -164,8 +140,8 @@ egl::Error SurfaceD3D::resetSwapChain() height = mHeight; } - const NativeWindow &window = (mChildWindow.getNativeWindow() != nullptr) ? mChildWindow : mNativeWindow; - mSwapChain = mRenderer->createSwapChain(window, mShareHandle, mRenderTargetFormat, mDepthStencilFormat); + mSwapChain = mRenderer->createSwapChain(mNativeWindow, mShareHandle, mRenderTargetFormat, + mDepthStencilFormat, mOrientation); if (!mSwapChain) { return egl::Error(EGL_BAD_ALLOC); @@ -201,17 +177,6 @@ egl::Error SurfaceD3D::resizeSwapChain(int backbufferWidth, int backbufferHeight mWidth = backbufferWidth; mHeight = backbufferHeight; -#if !defined(ANGLE_ENABLE_WINDOWS_STORE) - if (mChildWindow.getNativeWindow()) - { - // Resize the child window - if (!MoveWindow(mChildWindow.getNativeWindow(), 0, 0, mWidth, mHeight, FALSE)) - { - return egl::Error(EGL_BAD_SURFACE, "Failed to move the child window."); - } - } -#endif - return egl::Error(EGL_SUCCESS); } @@ -354,10 +319,23 @@ EGLint SurfaceD3D::isPostSubBufferSupported() const return EGL_TRUE; } +EGLint SurfaceD3D::getSwapBehavior() const +{ + return EGL_BUFFER_PRESERVED; +} + egl::Error SurfaceD3D::querySurfacePointerANGLE(EGLint attribute, void **value) { - ASSERT(attribute == EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE); - *value = mSwapChain->getShareHandle(); + 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::Error(EGL_SUCCESS); } diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/SurfaceD3D.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/SurfaceD3D.h index 68ca9fa85344..b925bfc8cc71 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/SurfaceD3D.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/SurfaceD3D.h @@ -25,19 +25,27 @@ class RendererD3D; class SurfaceD3D : public SurfaceImpl { public: - static SurfaceD3D *createFromWindow(RendererD3D *renderer, egl::Display *display, const egl::Config *config, - EGLNativeWindowType window, EGLint fixedSize, EGLint width, EGLint height); + static SurfaceD3D *createFromWindow(RendererD3D *renderer, + egl::Display *display, + const egl::Config *config, + EGLNativeWindowType window, + EGLint fixedSize, + EGLint directComposition, + EGLint width, + EGLint height, + EGLint orientation); static SurfaceD3D *createOffscreen(RendererD3D *renderer, egl::Display *display, const egl::Config *config, EGLClientBuffer shareHandle, EGLint width, EGLint height); ~SurfaceD3D() override; void releaseSwapChain(); egl::Error initialize() override; + FramebufferImpl *createDefaultFramebuffer(const gl::Framebuffer::Data &data) override; egl::Error swap() override; egl::Error postSubBuffer(EGLint x, EGLint y, EGLint width, EGLint height) override; egl::Error querySurfacePointerANGLE(EGLint attribute, void **value) override; - egl::Error bindTexImage(EGLint buffer) override; + egl::Error bindTexImage(gl::Texture *texture, EGLint buffer) override; egl::Error releaseTexImage(EGLint buffer) override; void setSwapInterval(EGLint interval) override; @@ -45,6 +53,7 @@ class SurfaceD3D : public SurfaceImpl EGLint getHeight() const override; EGLint isPostSubBufferSupported() const override; + EGLint getSwapBehavior() const override; // D3D implementations SwapChainD3D *getSwapChain() const; @@ -58,8 +67,16 @@ class SurfaceD3D : public SurfaceImpl FramebufferAttachmentRenderTarget **rtOut) override; private: - SurfaceD3D(RendererD3D *renderer, egl::Display *display, const egl::Config *config, EGLint width, EGLint height, - EGLint fixedSize, EGLClientBuffer shareHandle, EGLNativeWindowType window); + SurfaceD3D(RendererD3D *renderer, + egl::Display *display, + const egl::Config *config, + EGLint width, + EGLint height, + EGLint fixedSize, + EGLint orientation, + EGLint directComposition, + EGLClientBuffer shareHandle, + EGLNativeWindowType window); egl::Error swapRect(EGLint x, EGLint y, EGLint width, EGLint height); egl::Error resetSwapChain(int backbufferWidth, int backbufferHeight); @@ -69,6 +86,7 @@ class SurfaceD3D : public SurfaceImpl egl::Display *mDisplay; bool mFixedSize; + GLint mOrientation; GLenum mRenderTargetFormat; GLenum mDepthStencilFormat; @@ -80,8 +98,6 @@ class SurfaceD3D : public SurfaceImpl EGLint mWidth; EGLint mHeight; - NativeWindow mChildWindow; - EGLint mSwapInterval; HANDLE mShareHandle; diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/SwapChainD3D.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/SwapChainD3D.h index 3bde92e43bf4..1ef6611f8a9f 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/SwapChainD3D.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/SwapChainD3D.h @@ -31,7 +31,7 @@ class SwapChainD3D : angle::NonCopyable { public: SwapChainD3D(rx::NativeWindow nativeWindow, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat) - : mNativeWindow(nativeWindow), mShareHandle(shareHandle), mBackBufferFormat(backBufferFormat), mDepthBufferFormat(depthBufferFormat) + : mNativeWindow(nativeWindow), mOffscreenRenderTargetFormat(backBufferFormat), mDepthBufferFormat(depthBufferFormat), mShareHandle(shareHandle) { } @@ -45,14 +45,15 @@ class SwapChainD3D : angle::NonCopyable virtual RenderTargetD3D *getColorRenderTarget() = 0; virtual RenderTargetD3D *getDepthStencilRenderTarget() = 0; - GLenum GetBackBufferInternalFormat() const { return mBackBufferFormat; } + GLenum GetRenderTargetInternalFormat() const { return mOffscreenRenderTargetFormat; } GLenum GetDepthBufferInternalFormat() const { return mDepthBufferFormat; } HANDLE getShareHandle() { return mShareHandle; } + virtual void *getKeyedMutex() = 0; protected: rx::NativeWindow mNativeWindow; // Handler for the Window that the surface is created for. - const GLenum mBackBufferFormat; + const GLenum mOffscreenRenderTargetFormat; const GLenum mDepthBufferFormat; HANDLE mShareHandle; diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/TextureD3D.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/TextureD3D.cpp index 1b816b665459..430576b31862 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/TextureD3D.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/TextureD3D.cpp @@ -13,11 +13,13 @@ #include "libANGLE/Buffer.h" #include "libANGLE/Config.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/EGLImageD3D.h" #include "libANGLE/renderer/d3d/ImageD3D.h" #include "libANGLE/renderer/d3d/RendererD3D.h" #include "libANGLE/renderer/d3d/RenderTargetD3D.h" @@ -157,16 +159,12 @@ bool TextureD3D::shouldUseSetData(const ImageD3D *image) const return (mTexStorage && !internalFormat.compressed); } -gl::Error TextureD3D::setImage(const gl::ImageIndex &index, GLenum type, - const gl::PixelUnpackState &unpack, const uint8_t *pixels, - ptrdiff_t layerOffset) +gl::Error TextureD3D::setImageImpl(const gl::ImageIndex &index, + GLenum type, + const gl::PixelUnpackState &unpack, + const uint8_t *pixels, + ptrdiff_t layerOffset) { - if (unpack.skipRows != 0 || unpack.skipPixels != 0 || unpack.imageHeight != 0 || unpack.skipImages != 0) - { - UNIMPLEMENTED(); - return gl::Error(GL_INVALID_OPERATION, "unimplemented pixel store state"); - } - ImageD3D *image = getImage(index); ASSERT(image); @@ -185,7 +183,7 @@ gl::Error TextureD3D::setImage(const gl::ImageIndex &index, GLenum type, return error; } - if (pixelData != NULL) + if (pixelData != nullptr) { if (shouldUseSetData(image)) { @@ -247,15 +245,11 @@ gl::Error TextureD3D::subImage(const gl::ImageIndex &index, const gl::Box &area, return gl::Error(GL_NO_ERROR); } -gl::Error TextureD3D::setCompressedImage(const gl::ImageIndex &index, const gl::PixelUnpackState &unpack, - const uint8_t *pixels, ptrdiff_t layerOffset) +gl::Error TextureD3D::setCompressedImageImpl(const gl::ImageIndex &index, + const gl::PixelUnpackState &unpack, + const uint8_t *pixels, + ptrdiff_t layerOffset) { - if (unpack.skipRows != 0 || unpack.skipPixels != 0 || unpack.imageHeight != 0 || unpack.skipImages != 0) - { - UNIMPLEMENTED(); - return gl::Error(GL_INVALID_OPERATION, "unimplemented pixel store state"); - } - // 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 = NULL; @@ -287,12 +281,6 @@ gl::Error TextureD3D::subImageCompressed(const gl::ImageIndex &index, const gl:: const gl::PixelUnpackState &unpack, const uint8_t *pixels, ptrdiff_t layerOffset) { - if (unpack.skipRows != 0 || unpack.skipPixels != 0 || unpack.imageHeight != 0 || unpack.skipImages != 0) - { - UNIMPLEMENTED(); - return gl::Error(GL_INVALID_OPERATION, "unimplemented pixel store state"); - } - const uint8_t *pixelData = NULL; gl::Error error = GetUnpackPointer(unpack, pixels, layerOffset, &pixelData); if (error.isError()) @@ -325,6 +313,15 @@ bool TextureD3D::isFastUnpackable(const gl::PixelUnpackState &unpack, GLenum siz gl::Error TextureD3D::fastUnpackPixels(const gl::PixelUnpackState &unpack, const uint8_t *pixels, const gl::Box &destArea, GLenum sizedInternalFormat, GLenum type, RenderTargetD3D *destRenderTarget) { + if (unpack.skipRows != 0 || unpack.skipPixels != 0 || unpack.imageHeight != 0 || + unpack.skipImages != 0) + { + // TODO(jmadill): additional unpack parameters + UNIMPLEMENTED(); + return gl::Error(GL_INVALID_OPERATION, + "Unimplemented pixel store parameters in fastUnpackPixels"); + } + // No-op if (destArea.width <= 0 && destArea.height <= 0 && destArea.depth <= 0) { @@ -376,7 +373,7 @@ ImageD3D *TextureD3D::getBaseLevelImage() const return getImage(getImageIndex(0, 0)); } -gl::Error TextureD3D::generateMipmaps(const gl::SamplerState &samplerState) +gl::Error TextureD3D::generateMipmaps(const gl::TextureState &textureState) { GLint mipCount = mipLevels(); @@ -414,7 +411,7 @@ gl::Error TextureD3D::generateMipmaps(const gl::SamplerState &samplerState) } // Generate the mipmap chain using the ad-hoc DirectX function. - error = mRenderer->generateMipmapsUsingD3D(mTexStorage, samplerState); + error = mRenderer->generateMipmapsUsingD3D(mTexStorage, textureState); if (error.isError()) { return error; @@ -453,9 +450,7 @@ gl::Error TextureD3D::generateMipmapsUsingImages() gl::ImageIndex srcIndex = getImageIndex(0, layer); ImageD3D *image = getImage(srcIndex); - gl::Box area(0, 0, 0, image->getWidth(), image->getHeight(), image->getDepth()); - gl::Offset offset(0, 0, 0); - gl::Error error = image->copy(offset, area, srcIndex, mTexStorage); + gl::Error error = image->copyFromTexStorage(srcIndex, mTexStorage); if (error.isError()) { return error; @@ -620,6 +615,7 @@ gl::Error TextureD3D::getAttachmentRenderTarget(const gl::FramebufferAttachment: TextureD3D_2D::TextureD3D_2D(RendererD3D *renderer) : TextureD3D(renderer) { + mEGLImageTarget = false; for (int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; ++i) { mImageArray[i] = renderer->createImage(); @@ -689,16 +685,23 @@ bool TextureD3D_2D::isDepth(GLint level) const return gl::GetInternalFormatInfo(getInternalFormat(level)).depthBits > 0; } -gl::Error TextureD3D_2D::setImage(GLenum target, size_t level, GLenum internalFormat, const gl::Extents &size, GLenum format, GLenum type, - const gl::PixelUnpackState &unpack, const uint8_t *pixels) +gl::Error TextureD3D_2D::setImage(GLenum target, + size_t imageLevel, + GLenum internalFormat, + const gl::Extents &size, + GLenum format, + GLenum type, + const gl::PixelUnpackState &unpack, + const uint8_t *pixels) { ASSERT(target == GL_TEXTURE_2D && size.depth == 1); GLenum sizedInternalFormat = gl::GetSizedInternalFormat(internalFormat, type); bool fastUnpacked = false; + GLint level = static_cast(imageLevel); - redefineImage(level, sizedInternalFormat, size); + redefineImage(level, sizedInternalFormat, size, false); gl::ImageIndex index = gl::ImageIndex::Make2D(level); @@ -729,7 +732,7 @@ gl::Error TextureD3D_2D::setImage(GLenum target, size_t level, GLenum internalFo if (!fastUnpacked) { - gl::Error error = TextureD3D::setImage(index, type, unpack, pixels, 0); + gl::Error error = setImageImpl(index, type, unpack, pixels, 0); if (error.isError()) { return error; @@ -739,17 +742,17 @@ gl::Error TextureD3D_2D::setImage(GLenum target, size_t level, GLenum internalFo return gl::Error(GL_NO_ERROR); } -gl::Error TextureD3D_2D::setSubImage(GLenum target, size_t level, const gl::Box &area, GLenum format, GLenum type, - const gl::PixelUnpackState &unpack, const uint8_t *pixels) +gl::Error TextureD3D_2D::setSubImage(GLenum target, + size_t imageLevel, + const gl::Box &area, + GLenum format, + GLenum type, + const gl::PixelUnpackState &unpack, + const uint8_t *pixels) { ASSERT(target == GL_TEXTURE_2D && area.depth == 1 && area.z == 0); - if (unpack.skipRows != 0 || unpack.skipPixels != 0 || unpack.imageHeight != 0 || unpack.skipImages != 0) - { - UNIMPLEMENTED(); - return gl::Error(GL_INVALID_OPERATION, "unimplemented pixel store state"); - } - + GLint level = static_cast(imageLevel); gl::ImageIndex index = gl::ImageIndex::Make2D(level); if (isFastUnpackable(unpack, getInternalFormat(level)) && isLevelComplete(level)) { @@ -770,24 +773,29 @@ gl::Error TextureD3D_2D::setSubImage(GLenum target, size_t level, const gl::Box } } - -gl::Error TextureD3D_2D::setCompressedImage(GLenum target, size_t level, GLenum internalFormat, const gl::Extents &size, - const gl::PixelUnpackState &unpack, const uint8_t *pixels) +gl::Error TextureD3D_2D::setCompressedImage(GLenum target, + size_t imageLevel, + GLenum internalFormat, + const gl::Extents &size, + const gl::PixelUnpackState &unpack, + size_t imageSize, + const uint8_t *pixels) { ASSERT(target == GL_TEXTURE_2D && size.depth == 1); + GLint level = static_cast(imageLevel); // compressed formats don't have separate sized internal formats-- we can just use the compressed format directly - redefineImage(level, internalFormat, size); + redefineImage(level, internalFormat, size, false); - return TextureD3D::setCompressedImage(gl::ImageIndex::Make2D(level), unpack, pixels, 0); + return setCompressedImageImpl(gl::ImageIndex::Make2D(level), unpack, pixels, 0); } gl::Error TextureD3D_2D::setCompressedSubImage(GLenum target, size_t level, const gl::Box &area, GLenum format, - const gl::PixelUnpackState &unpack, const uint8_t *pixels) + const gl::PixelUnpackState &unpack, size_t imageSize, const uint8_t *pixels) { ASSERT(target == GL_TEXTURE_2D && area.depth == 1 && area.z == 0); - gl::ImageIndex index = gl::ImageIndex::Make2D(level); + gl::ImageIndex index = gl::ImageIndex::Make2D(static_cast(level)); gl::Error error = TextureD3D::subImageCompressed(index, area, format, unpack, pixels, 0); if (error.isError()) { @@ -797,13 +805,18 @@ gl::Error TextureD3D_2D::setCompressedSubImage(GLenum target, size_t level, cons return commitRegion(index, area); } -gl::Error TextureD3D_2D::copyImage(GLenum target, size_t level, const gl::Rectangle &sourceArea, GLenum internalFormat, +gl::Error TextureD3D_2D::copyImage(GLenum target, + size_t imageLevel, + const gl::Rectangle &sourceArea, + GLenum internalFormat, const gl::Framebuffer *source) { ASSERT(target == GL_TEXTURE_2D); + GLint level = static_cast(imageLevel); GLenum sizedInternalFormat = gl::GetSizedInternalFormat(internalFormat, GL_UNSIGNED_BYTE); - redefineImage(level, sizedInternalFormat, gl::Extents(sourceArea.width, sourceArea.height, 1)); + redefineImage(level, sizedInternalFormat, gl::Extents(sourceArea.width, sourceArea.height, 1), + false); gl::ImageIndex index = gl::ImageIndex::Make2D(level); gl::Offset destOffset(0, 0, 0); @@ -812,7 +825,7 @@ gl::Error TextureD3D_2D::copyImage(GLenum target, size_t level, const gl::Rectan // so we should use the non-rendering copy path. if (!canCreateRenderTargetForImage(index) || mRenderer->getWorkarounds().zeroMaxLodWorkaround) { - gl::Error error = mImageArray[level]->copy(destOffset, sourceArea, source); + gl::Error error = mImageArray[level]->copyFromFramebuffer(destOffset, sourceArea, source); if (error.isError()) { return error; @@ -843,7 +856,10 @@ gl::Error TextureD3D_2D::copyImage(GLenum target, size_t level, const gl::Rectan return gl::Error(GL_NO_ERROR); } -gl::Error TextureD3D_2D::copySubImage(GLenum target, size_t level, const gl::Offset &destOffset, const gl::Rectangle &sourceArea, +gl::Error TextureD3D_2D::copySubImage(GLenum target, + size_t imageLevel, + const gl::Offset &destOffset, + const gl::Rectangle &sourceArea, const gl::Framebuffer *source) { ASSERT(target == GL_TEXTURE_2D && destOffset.z == 0); @@ -851,13 +867,14 @@ gl::Error TextureD3D_2D::copySubImage(GLenum target, size_t level, const gl::Off // 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) + GLint level = static_cast(imageLevel); gl::ImageIndex index = gl::ImageIndex::Make2D(level); // 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->getWorkarounds().zeroMaxLodWorkaround) { - gl::Error error = mImageArray[level]->copy(destOffset, sourceArea, source); + gl::Error error = mImageArray[level]->copyFromFramebuffer(destOffset, sourceArea, source); if (error.isError()) { return error; @@ -903,17 +920,18 @@ gl::Error TextureD3D_2D::setStorage(GLenum target, size_t levels, GLenum interna gl::Extents levelSize(std::max(1, size.width >> level), std::max(1, size.height >> level), 1); - mImageArray[level]->redefine(GL_TEXTURE_2D, internalFormat, levelSize, true); + redefineImage(level, internalFormat, levelSize, true); } - for (int level = levels; level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++) + for (size_t level = levels; level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++) { - mImageArray[level]->redefine(GL_TEXTURE_2D, GL_NONE, gl::Extents(0, 0, 0), true); + redefineImage(level, GL_NONE, gl::Extents(0, 0, 1), true); } // TODO(geofflang): Verify storage creation had no errors bool renderTarget = IsRenderTargetUsage(mUsage); - TextureStorage *storage = mRenderer->createTextureStorage2D(internalFormat, renderTarget, size.width, size.height, levels, false); + TextureStorage *storage = mRenderer->createTextureStorage2D( + internalFormat, renderTarget, size.width, size.height, static_cast(levels), false); gl::Error error = setCompleteTexStorage(storage); if (error.isError()) @@ -939,7 +957,7 @@ void TextureD3D_2D::bindTexImage(egl::Surface *surface) GLenum internalformat = surface->getConfig()->renderTargetFormat; gl::Extents size(surface->getWidth(), surface->getHeight(), 1); - mImageArray[0]->redefine(GL_TEXTURE_2D, internalformat, size, true); + redefineImage(0, internalformat, size, true); if (mTexStorage) { @@ -950,6 +968,7 @@ void TextureD3D_2D::bindTexImage(egl::Surface *surface) ASSERT(surfaceD3D); mTexStorage = mRenderer->createTextureStorage2D(surfaceD3D->getSwapChain()); + mEGLImageTarget = false; mDirtyImages = true; } @@ -963,10 +982,34 @@ void TextureD3D_2D::releaseTexImage() for (int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++) { - mImageArray[i]->redefine(GL_TEXTURE_2D, GL_NONE, gl::Extents(0, 0, 0), true); + redefineImage(i, GL_NONE, gl::Extents(0, 0, 1), true); } } +gl::Error TextureD3D_2D::setEGLImageTarget(GLenum target, egl::Image *image) +{ + EGLImageD3D *eglImaged3d = GetImplAs(image); + + // Set the properties of the base mip level from the EGL image + GLenum internalformat = image->getInternalFormat(); + gl::Extents size(static_cast(image->getWidth()), static_cast(image->getHeight()), 1); + redefineImage(0, internalformat, size, true); + + // Clear all other images. + for (size_t level = 1; level < ArraySize(mImageArray); level++) + { + redefineImage(level, GL_NONE, gl::Extents(0, 0, 1), true); + } + + SafeDelete(mTexStorage); + mImageArray[0]->markClean(); + + mTexStorage = mRenderer->createTextureStorageEGLImage(eglImaged3d); + mEGLImageTarget = true; + + return gl::Error(GL_NO_ERROR); +} + void TextureD3D_2D::initMipmapsImages() { // Purge array levels 1 through q and reset them to represent the generated mipmap levels. @@ -977,16 +1020,10 @@ void TextureD3D_2D::initMipmapsImages() std::max(getBaseLevelHeight() >> level, 1), 1); - redefineImage(level, getBaseLevelInternalFormat(), levelSize); + redefineImage(level, getBaseLevelInternalFormat(), levelSize, false); } } -unsigned int TextureD3D_2D::getRenderTargetSerial(const gl::ImageIndex &index) -{ - ASSERT(!index.hasLayer()); - return (!ensureRenderTarget().isError() ? mTexStorage->getRenderTargetSerial(index) : 0); -} - gl::Error TextureD3D_2D::getRenderTarget(const gl::ImageIndex &index, RenderTargetD3D **outRT) { ASSERT(!index.hasLayer()); @@ -1193,7 +1230,10 @@ gl::Error TextureD3D_2D::updateStorageLevel(int level) return gl::Error(GL_NO_ERROR); } -void TextureD3D_2D::redefineImage(GLint level, GLenum internalformat, const gl::Extents &size) +void TextureD3D_2D::redefineImage(size_t level, + GLenum internalformat, + const gl::Extents &size, + bool forceRelease) { ASSERT(size.depth == 1); @@ -1202,18 +1242,26 @@ void TextureD3D_2D::redefineImage(GLint level, GLenum internalformat, const gl:: const int storageHeight = std::max(1, getBaseLevelHeight() >> level); const GLenum storageFormat = getBaseLevelInternalFormat(); - mImageArray[level]->redefine(GL_TEXTURE_2D, internalformat, size, false); + mImageArray[level]->redefine(GL_TEXTURE_2D, internalformat, size, forceRelease); if (mTexStorage) { - const int storageLevels = mTexStorage->getLevelCount(); + 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) + { + // TODO(jmadill): Don't discard error. + mImageArray[0]->copyFromTexStorage(gl::ImageIndex::Make2D(0), mTexStorage); + } if ((level >= storageLevels && storageLevels != 0) || size.width != storageWidth || size.height != storageHeight || internalformat != storageFormat) // Discard mismatched storage { - for (int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++) + for (size_t i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++) { mImageArray[i]->markDirty(); } @@ -1222,6 +1270,9 @@ void TextureD3D_2D::redefineImage(GLint level, GLenum internalformat, const gl:: mDirtyImages = true; } } + + // Can't be an EGL image target after being redefined + mEGLImageTarget = false; } gl::ImageIndexIterator TextureD3D_2D::imageIterator() const @@ -1302,17 +1353,23 @@ bool TextureD3D_Cube::isDepth(GLint level, GLint layer) const return gl::GetInternalFormatInfo(getInternalFormat(level, layer)).depthBits > 0; } +gl::Error TextureD3D_Cube::setEGLImageTarget(GLenum target, egl::Image *image) +{ + UNREACHABLE(); + return gl::Error(GL_INVALID_OPERATION); +} + gl::Error TextureD3D_Cube::setImage(GLenum target, size_t level, GLenum internalFormat, const gl::Extents &size, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const uint8_t *pixels) { ASSERT(size.depth == 1); GLenum sizedInternalFormat = gl::GetSizedInternalFormat(internalFormat, type); - gl::ImageIndex index = gl::ImageIndex::MakeCube(target, level); + gl::ImageIndex index = gl::ImageIndex::MakeCube(target, static_cast(level)); - redefineImage(index.layerIndex, level, sizedInternalFormat, size); + redefineImage(index.layerIndex, static_cast(level), sizedInternalFormat, size); - return TextureD3D::setImage(index, type, unpack, pixels, 0); + return setImageImpl(index, type, unpack, pixels, 0); } gl::Error TextureD3D_Cube::setSubImage(GLenum target, size_t level, const gl::Box &area, GLenum format, GLenum type, @@ -1320,30 +1377,30 @@ gl::Error TextureD3D_Cube::setSubImage(GLenum target, size_t level, const gl::Bo { ASSERT(area.depth == 1 && area.z == 0); - gl::ImageIndex index = gl::ImageIndex::MakeCube(target, level); + gl::ImageIndex index = gl::ImageIndex::MakeCube(target, static_cast(level)); return TextureD3D::subImage(index, area, format, type, unpack, pixels, 0); } gl::Error TextureD3D_Cube::setCompressedImage(GLenum target, size_t level, GLenum internalFormat, const gl::Extents &size, - const gl::PixelUnpackState &unpack, const uint8_t *pixels) + 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 size_t faceIndex = gl::CubeMapTextureTargetToLayerIndex(target); - redefineImage(faceIndex, level, internalFormat, size); + redefineImage(static_cast(faceIndex), static_cast(level), internalFormat, size); - gl::ImageIndex index = gl::ImageIndex::MakeCube(target, level); - return TextureD3D::setCompressedImage(index, unpack, pixels, 0); + gl::ImageIndex index = gl::ImageIndex::MakeCube(target, static_cast(level)); + return setCompressedImageImpl(index, unpack, pixels, 0); } gl::Error TextureD3D_Cube::setCompressedSubImage(GLenum target, size_t level, const gl::Box &area, GLenum format, - const gl::PixelUnpackState &unpack, const uint8_t *pixels) + const gl::PixelUnpackState &unpack, size_t imageSize, const uint8_t *pixels) { ASSERT(area.depth == 1 && area.z == 0); - gl::ImageIndex index = gl::ImageIndex::MakeCube(target, level); + gl::ImageIndex index = gl::ImageIndex::MakeCube(target, static_cast(level)); gl::Error error = TextureD3D::subImageCompressed(index, area, format, unpack, pixels, 0); if (error.isError()) @@ -1354,14 +1411,19 @@ gl::Error TextureD3D_Cube::setCompressedSubImage(GLenum target, size_t level, co return commitRegion(index, area); } -gl::Error TextureD3D_Cube::copyImage(GLenum target, size_t level, const gl::Rectangle &sourceArea, GLenum internalFormat, +gl::Error TextureD3D_Cube::copyImage(GLenum target, + size_t imageLevel, + const gl::Rectangle &sourceArea, + GLenum internalFormat, const gl::Framebuffer *source) { - size_t faceIndex = gl::CubeMapTextureTargetToLayerIndex(target); + int faceIndex = static_cast(gl::CubeMapTextureTargetToLayerIndex(target)); GLenum sizedInternalFormat = gl::GetSizedInternalFormat(internalFormat, GL_UNSIGNED_BYTE); + GLint level = static_cast(imageLevel); + gl::Extents size(sourceArea.width, sourceArea.height, 1); - redefineImage(faceIndex, level, sizedInternalFormat, size); + redefineImage(static_cast(faceIndex), level, sizedInternalFormat, size); gl::ImageIndex index = gl::ImageIndex::MakeCube(target, level); gl::Offset destOffset(0, 0, 0); @@ -1370,7 +1432,8 @@ gl::Error TextureD3D_Cube::copyImage(GLenum target, size_t level, const gl::Rect // so we should use the non-rendering copy path. if (!canCreateRenderTargetForImage(index) || mRenderer->getWorkarounds().zeroMaxLodWorkaround) { - gl::Error error = mImageArray[faceIndex][level]->copy(destOffset, sourceArea, source); + gl::Error error = + mImageArray[faceIndex][level]->copyFromFramebuffer(destOffset, sourceArea, source); if (error.isError()) { return error; @@ -1403,18 +1466,23 @@ gl::Error TextureD3D_Cube::copyImage(GLenum target, size_t level, const gl::Rect return gl::Error(GL_NO_ERROR); } -gl::Error TextureD3D_Cube::copySubImage(GLenum target, size_t level, const gl::Offset &destOffset, const gl::Rectangle &sourceArea, +gl::Error TextureD3D_Cube::copySubImage(GLenum target, + size_t imageLevel, + const gl::Offset &destOffset, + const gl::Rectangle &sourceArea, const gl::Framebuffer *source) { - size_t faceIndex = gl::CubeMapTextureTargetToLayerIndex(target); + int faceIndex = static_cast(gl::CubeMapTextureTargetToLayerIndex(target)); + GLint level = static_cast(imageLevel); gl::ImageIndex index = gl::ImageIndex::MakeCube(target, level); // 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->getWorkarounds().zeroMaxLodWorkaround) { - gl::Error error = mImageArray[faceIndex][level]->copy(destOffset, sourceArea, source); + gl::Error error = + mImageArray[faceIndex][level]->copyFromFramebuffer(destOffset, sourceArea, source); if (error.isError()) { return error; @@ -1464,7 +1532,7 @@ gl::Error TextureD3D_Cube::setStorage(GLenum target, size_t levels, GLenum inter } } - for (int level = levels; level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++) + for (size_t level = levels; level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++) { for (int faceIndex = 0; faceIndex < 6; faceIndex++) { @@ -1475,7 +1543,8 @@ gl::Error TextureD3D_Cube::setStorage(GLenum target, size_t levels, GLenum inter // TODO(geofflang): Verify storage creation had no errors bool renderTarget = IsRenderTargetUsage(mUsage); - TextureStorage *storage = mRenderer->createTextureStorageCube(internalFormat, renderTarget, size.width, levels, false); + TextureStorage *storage = mRenderer->createTextureStorageCube( + internalFormat, renderTarget, size.width, static_cast(levels), false); gl::Error error = setCompleteTexStorage(storage); if (error.isError()) @@ -1549,11 +1618,6 @@ void TextureD3D_Cube::initMipmapsImages() } } -unsigned int TextureD3D_Cube::getRenderTargetSerial(const gl::ImageIndex &index) -{ - return (!ensureRenderTarget().isError() ? mTexStorage->getRenderTargetSerial(index) : 0); -} - gl::Error TextureD3D_Cube::getRenderTarget(const gl::ImageIndex &index, RenderTargetD3D **outRT) { ASSERT(gl::IsCubeMapTextureTarget(index.type)); @@ -1892,12 +1956,25 @@ bool TextureD3D_3D::isDepth(GLint level) const return gl::GetInternalFormatInfo(getInternalFormat(level)).depthBits > 0; } -gl::Error TextureD3D_3D::setImage(GLenum target, size_t level, GLenum internalFormat, const gl::Extents &size, GLenum format, GLenum type, - const gl::PixelUnpackState &unpack, const uint8_t *pixels) +gl::Error TextureD3D_3D::setEGLImageTarget(GLenum target, egl::Image *image) +{ + UNREACHABLE(); + return gl::Error(GL_INVALID_OPERATION); +} + +gl::Error TextureD3D_3D::setImage(GLenum target, + size_t imageLevel, + GLenum internalFormat, + const gl::Extents &size, + GLenum format, + GLenum type, + const gl::PixelUnpackState &unpack, + const uint8_t *pixels) { ASSERT(target == GL_TEXTURE_3D); GLenum sizedInternalFormat = gl::GetSizedInternalFormat(internalFormat, type); + GLint level = static_cast(imageLevel); redefineImage(level, sizedInternalFormat, size); bool fastUnpacked = false; @@ -1931,7 +2008,7 @@ gl::Error TextureD3D_3D::setImage(GLenum target, size_t level, GLenum internalFo if (!fastUnpacked) { - gl::Error error = TextureD3D::setImage(index, type, unpack, pixels, 0); + gl::Error error = setImageImpl(index, type, unpack, pixels, 0); if (error.isError()) { return error; @@ -1941,11 +2018,17 @@ gl::Error TextureD3D_3D::setImage(GLenum target, size_t level, GLenum internalFo return gl::Error(GL_NO_ERROR); } -gl::Error TextureD3D_3D::setSubImage(GLenum target, size_t level, const gl::Box &area, GLenum format, GLenum type, - const gl::PixelUnpackState &unpack, const uint8_t *pixels) +gl::Error TextureD3D_3D::setSubImage(GLenum target, + size_t imageLevel, + const gl::Box &area, + GLenum format, + GLenum type, + const gl::PixelUnpackState &unpack, + const uint8_t *pixels) { ASSERT(target == GL_TEXTURE_3D); + GLint level = static_cast(imageLevel); gl::ImageIndex index = gl::ImageIndex::Make3D(level); // Attempt a fast gpu copy of the pixel data to the surface if the app bound an unpack buffer @@ -1968,24 +2051,30 @@ gl::Error TextureD3D_3D::setSubImage(GLenum target, size_t level, const gl::Box } } -gl::Error TextureD3D_3D::setCompressedImage(GLenum target, size_t level, GLenum internalFormat, const gl::Extents &size, - const gl::PixelUnpackState &unpack, const uint8_t *pixels) +gl::Error TextureD3D_3D::setCompressedImage(GLenum target, + size_t imageLevel, + GLenum internalFormat, + const gl::Extents &size, + const gl::PixelUnpackState &unpack, + size_t imageSize, + const uint8_t *pixels) { ASSERT(target == GL_TEXTURE_3D); + GLint level = static_cast(imageLevel); // compressed formats don't have separate sized internal formats-- we can just use the compressed format directly redefineImage(level, internalFormat, size); gl::ImageIndex index = gl::ImageIndex::Make3D(level); - return TextureD3D::setCompressedImage(index, unpack, pixels, 0); + return setCompressedImageImpl(index, unpack, pixels, 0); } gl::Error TextureD3D_3D::setCompressedSubImage(GLenum target, size_t level, const gl::Box &area, GLenum format, - const gl::PixelUnpackState &unpack, const uint8_t *pixels) + const gl::PixelUnpackState &unpack, size_t imageSize, const uint8_t *pixels) { ASSERT(target == GL_TEXTURE_3D); - gl::ImageIndex index = gl::ImageIndex::Make3D(level); + gl::ImageIndex index = gl::ImageIndex::Make3D(static_cast(level)); gl::Error error = TextureD3D::subImageCompressed(index, area, format, unpack, pixels, 0); if (error.isError()) { @@ -2002,16 +2091,20 @@ gl::Error TextureD3D_3D::copyImage(GLenum target, size_t level, const gl::Rectan return gl::Error(GL_INVALID_OPERATION, "Copying 3D textures is unimplemented."); } -gl::Error TextureD3D_3D::copySubImage(GLenum target, size_t level, const gl::Offset &destOffset, const gl::Rectangle &sourceArea, +gl::Error TextureD3D_3D::copySubImage(GLenum target, + size_t imageLevel, + const gl::Offset &destOffset, + const gl::Rectangle &sourceArea, const gl::Framebuffer *source) { ASSERT(target == GL_TEXTURE_3D); + GLint level = static_cast(imageLevel); gl::ImageIndex index = gl::ImageIndex::Make3D(level); if (canCreateRenderTargetForImage(index)) { - gl::Error error = mImageArray[level]->copy(destOffset, sourceArea, source); + gl::Error error = mImageArray[level]->copyFromFramebuffer(destOffset, sourceArea, source); if (error.isError()) { return error; @@ -2060,14 +2153,16 @@ gl::Error TextureD3D_3D::setStorage(GLenum target, size_t levels, GLenum interna mImageArray[level]->redefine(GL_TEXTURE_3D, internalFormat, levelSize, true); } - for (int level = levels; level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++) + for (size_t level = levels; level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++) { mImageArray[level]->redefine(GL_TEXTURE_3D, GL_NONE, gl::Extents(0, 0, 0), true); } // TODO(geofflang): Verify storage creation had no errors bool renderTarget = IsRenderTargetUsage(mUsage); - TextureStorage *storage = mRenderer->createTextureStorage3D(internalFormat, renderTarget, size.width, size.height, size.depth, levels); + TextureStorage *storage = + mRenderer->createTextureStorage3D(internalFormat, renderTarget, size.width, size.height, + size.depth, static_cast(levels)); gl::Error error = setCompleteTexStorage(storage); if (error.isError()) @@ -2112,11 +2207,6 @@ void TextureD3D_3D::initMipmapsImages() } } -unsigned int TextureD3D_3D::getRenderTargetSerial(const gl::ImageIndex &index) -{ - return (!ensureRenderTarget().isError() ? mTexStorage->getRenderTargetSerial(index) : 0); -} - gl::Error TextureD3D_3D::getRenderTarget(const gl::ImageIndex &index, RenderTargetD3D **outRT) { // ensure the underlying texture is created @@ -2425,23 +2515,37 @@ bool TextureD3D_2DArray::isDepth(GLint level) const return gl::GetInternalFormatInfo(getInternalFormat(level)).depthBits > 0; } -gl::Error TextureD3D_2DArray::setImage(GLenum target, size_t level, GLenum internalFormat, const gl::Extents &size, GLenum format, GLenum type, - const gl::PixelUnpackState &unpack, const uint8_t *pixels) +gl::Error TextureD3D_2DArray::setEGLImageTarget(GLenum target, egl::Image *image) +{ + UNREACHABLE(); + return gl::Error(GL_INVALID_OPERATION); +} + +gl::Error TextureD3D_2DArray::setImage(GLenum target, + size_t imageLevel, + GLenum internalFormat, + const gl::Extents &size, + GLenum format, + GLenum type, + const gl::PixelUnpackState &unpack, + const uint8_t *pixels) { ASSERT(target == GL_TEXTURE_2D_ARRAY); GLenum sizedInternalFormat = gl::GetSizedInternalFormat(internalFormat, type); + GLint level = static_cast(imageLevel); redefineImage(level, sizedInternalFormat, size); const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(sizedInternalFormat); - GLsizei inputDepthPitch = formatInfo.computeDepthPitch(type, size.width, size.height, unpack.alignment, unpack.rowLength); + GLsizei inputDepthPitch = formatInfo.computeDepthPitch( + type, size.width, size.height, unpack.alignment, unpack.rowLength, unpack.imageHeight); for (int i = 0; i < size.depth; i++) { const ptrdiff_t layerOffset = (inputDepthPitch * i); gl::ImageIndex index = gl::ImageIndex::Make2DArray(level, i); - gl::Error error = TextureD3D::setImage(index, type, unpack, pixels, layerOffset); + gl::Error error = setImageImpl(index, type, unpack, pixels, layerOffset); if (error.isError()) { return error; @@ -2451,13 +2555,19 @@ gl::Error TextureD3D_2DArray::setImage(GLenum target, size_t level, GLenum inter return gl::Error(GL_NO_ERROR); } -gl::Error TextureD3D_2DArray::setSubImage(GLenum target, size_t level, const gl::Box &area, GLenum format, GLenum type, - const gl::PixelUnpackState &unpack, const uint8_t *pixels) +gl::Error TextureD3D_2DArray::setSubImage(GLenum target, + size_t imageLevel, + const gl::Box &area, + GLenum format, + GLenum type, + const gl::PixelUnpackState &unpack, + const uint8_t *pixels) { ASSERT(target == GL_TEXTURE_2D_ARRAY); - + GLint level = static_cast(imageLevel); const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(getInternalFormat(level)); - GLsizei inputDepthPitch = formatInfo.computeDepthPitch(type, area.width, area.height, unpack.alignment, unpack.rowLength); + GLsizei inputDepthPitch = formatInfo.computeDepthPitch( + type, area.width, area.height, unpack.alignment, unpack.rowLength, unpack.imageHeight); for (int i = 0; i < area.depth; i++) { @@ -2477,23 +2587,30 @@ gl::Error TextureD3D_2DArray::setSubImage(GLenum target, size_t level, const gl: return gl::Error(GL_NO_ERROR); } -gl::Error TextureD3D_2DArray::setCompressedImage(GLenum target, size_t level, GLenum internalFormat, const gl::Extents &size, - const gl::PixelUnpackState &unpack, const uint8_t *pixels) +gl::Error TextureD3D_2DArray::setCompressedImage(GLenum target, + size_t imageLevel, + GLenum internalFormat, + const gl::Extents &size, + const gl::PixelUnpackState &unpack, + size_t imageSize, + const uint8_t *pixels) { ASSERT(target == GL_TEXTURE_2D_ARRAY); + GLint level = static_cast(imageLevel); // compressed formats don't have separate sized internal formats-- we can just use the compressed format directly redefineImage(level, internalFormat, size); const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalFormat); - GLsizei inputDepthPitch = formatInfo.computeDepthPitch(GL_UNSIGNED_BYTE, size.width, size.height, 1, 0); + GLsizei inputDepthPitch = + formatInfo.computeDepthPitch(GL_UNSIGNED_BYTE, size.width, size.height, 1, 0, 0); for (int i = 0; i < size.depth; i++) { const ptrdiff_t layerOffset = (inputDepthPitch * i); gl::ImageIndex index = gl::ImageIndex::Make2DArray(level, i); - gl::Error error = TextureD3D::setCompressedImage(index, unpack, pixels, layerOffset); + gl::Error error = setCompressedImageImpl(index, unpack, pixels, layerOffset); if (error.isError()) { return error; @@ -2504,12 +2621,13 @@ gl::Error TextureD3D_2DArray::setCompressedImage(GLenum target, size_t level, GL } gl::Error TextureD3D_2DArray::setCompressedSubImage(GLenum target, size_t level, const gl::Box &area, GLenum format, - const gl::PixelUnpackState &unpack, const uint8_t *pixels) + const gl::PixelUnpackState &unpack, size_t imageSize, const uint8_t *pixels) { ASSERT(target == GL_TEXTURE_2D_ARRAY); const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(format); - GLsizei inputDepthPitch = formatInfo.computeDepthPitch(GL_UNSIGNED_BYTE, area.width, area.height, 1, 0); + GLsizei inputDepthPitch = + formatInfo.computeDepthPitch(GL_UNSIGNED_BYTE, area.width, area.height, 1, 0, 0); for (int i = 0; i < area.depth; i++) { @@ -2518,7 +2636,7 @@ gl::Error TextureD3D_2DArray::setCompressedSubImage(GLenum target, size_t level, gl::Box layerArea(area.x, area.y, 0, area.width, area.height, 1); - gl::ImageIndex index = gl::ImageIndex::Make2DArray(level, layer); + gl::ImageIndex index = gl::ImageIndex::Make2DArray(static_cast(level), layer); gl::Error error = TextureD3D::subImageCompressed(index, layerArea, format, unpack, pixels, layerOffset); if (error.isError()) { @@ -2542,17 +2660,22 @@ gl::Error TextureD3D_2DArray::copyImage(GLenum target, size_t level, const gl::R return gl::Error(GL_INVALID_OPERATION, "Copying 2D array textures is unimplemented."); } -gl::Error TextureD3D_2DArray::copySubImage(GLenum target, size_t level, const gl::Offset &destOffset, const gl::Rectangle &sourceArea, +gl::Error TextureD3D_2DArray::copySubImage(GLenum target, + size_t imageLevel, + const gl::Offset &destOffset, + const gl::Rectangle &sourceArea, const gl::Framebuffer *source) { ASSERT(target == GL_TEXTURE_2D_ARRAY); + GLint level = static_cast(imageLevel); gl::ImageIndex index = gl::ImageIndex::Make2DArray(level, destOffset.z); if (canCreateRenderTargetForImage(index)) { gl::Offset destLayerOffset(destOffset.x, destOffset.y, 0); - gl::Error error = mImageArray[level][destOffset.z]->copy(destLayerOffset, sourceArea, source); + gl::Error error = mImageArray[level][destOffset.z]->copyFromFramebuffer(destLayerOffset, + sourceArea, source); if (error.isError()) { return error; @@ -2616,7 +2739,9 @@ gl::Error TextureD3D_2DArray::setStorage(GLenum target, size_t levels, GLenum in // TODO(geofflang): Verify storage creation had no errors bool renderTarget = IsRenderTargetUsage(mUsage); - TextureStorage *storage = mRenderer->createTextureStorage2DArray(internalFormat, renderTarget, size.width, size.height, size.depth, levels); + TextureStorage *storage = + mRenderer->createTextureStorage2DArray(internalFormat, renderTarget, size.width, + size.height, size.depth, static_cast(levels)); gl::Error error = setCompleteTexStorage(storage); if (error.isError()) @@ -2666,11 +2791,6 @@ void TextureD3D_2DArray::initMipmapsImages() } } -unsigned int TextureD3D_2DArray::getRenderTargetSerial(const gl::ImageIndex &index) -{ - return (!ensureRenderTarget().isError() ? mTexStorage->getRenderTargetSerial(index) : 0); -} - gl::Error TextureD3D_2DArray::getRenderTarget(const gl::ImageIndex &index, RenderTargetD3D **outRT) { // ensure the underlying texture is created @@ -2881,21 +3001,30 @@ void TextureD3D_2DArray::redefineImage(GLint level, GLenum internalformat, const const int storageDepth = getLayerCount(0); const GLenum storageFormat = getBaseLevelInternalFormat(); - for (int layer = 0; layer < mLayerCounts[level]; layer++) + // Only reallocate the layers if the size doesn't match + if (size.depth != mLayerCounts[level]) { - delete mImageArray[level][layer]; + 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(); + } + } } - delete[] mImageArray[level]; - mImageArray[level] = NULL; - 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(); mImageArray[level][layer]->redefine(GL_TEXTURE_2D_ARRAY, internalformat, gl::Extents(size.width, size.height, 1), false); } diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/TextureD3D.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/TextureD3D.h index 152317cf4725..1d5faee70303 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/TextureD3D.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/TextureD3D.h @@ -20,8 +20,7 @@ class Framebuffer; namespace rx { - -class ImageD3D; +class EGLImageD3D; class ImageD3D; class RendererD3D; class RenderTargetD3D; @@ -50,7 +49,6 @@ class TextureD3D : public TextureImpl bool isImmutable() const { return mImmutable; } virtual gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTargetD3D **outRT) = 0; - virtual unsigned int getRenderTargetSerial(const gl::ImageIndex &index) = 0; // Returns an iterator over all "Images" for this particular Texture. virtual gl::ImageIndexIterator imageIterator() const = 0; @@ -60,7 +58,7 @@ class TextureD3D : public TextureImpl virtual gl::ImageIndex getImageIndex(GLint mip, GLint layer) const = 0; virtual bool isValidIndex(const gl::ImageIndex &index) const = 0; - virtual gl::Error generateMipmaps(const gl::SamplerState &samplerState); + gl::Error generateMipmaps(const gl::TextureState &textureState) override; TextureStorage *getStorage(); ImageD3D *getBaseLevelImage() const; @@ -68,13 +66,17 @@ class TextureD3D : public TextureImpl FramebufferAttachmentRenderTarget **rtOut) override; protected: - gl::Error setImage(const gl::ImageIndex &index, GLenum type, - const gl::PixelUnpackState &unpack, const uint8_t *pixels, - ptrdiff_t layerOffset); + gl::Error setImageImpl(const gl::ImageIndex &index, + GLenum type, + const gl::PixelUnpackState &unpack, + const uint8_t *pixels, + ptrdiff_t layerOffset); gl::Error subImage(const gl::ImageIndex &index, const gl::Box &area, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const uint8_t *pixels, ptrdiff_t layerOffset); - gl::Error setCompressedImage(const gl::ImageIndex &index, const gl::PixelUnpackState &unpack, - const uint8_t *pixels, ptrdiff_t layerOffset); + gl::Error setCompressedImageImpl(const gl::ImageIndex &index, + const gl::PixelUnpackState &unpack, + const uint8_t *pixels, + ptrdiff_t layerOffset); gl::Error subImageCompressed(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::PixelUnpackState &unpack, GLenum sizedInternalFormat); @@ -134,9 +136,9 @@ class TextureD3D_2D : public TextureD3D const gl::PixelUnpackState &unpack, const uint8_t *pixels) override; gl::Error setCompressedImage(GLenum target, size_t level, GLenum internalFormat, const gl::Extents &size, - const gl::PixelUnpackState &unpack, const uint8_t *pixels) override; + const gl::PixelUnpackState &unpack, size_t imageSize, const uint8_t *pixels) override; gl::Error setCompressedSubImage(GLenum target, size_t level, const gl::Box &area, GLenum format, - const gl::PixelUnpackState &unpack, const uint8_t *pixels) override; + const gl::PixelUnpackState &unpack, size_t imageSize, const uint8_t *pixels) override; gl::Error copyImage(GLenum target, size_t level, const gl::Rectangle &sourceArea, GLenum internalFormat, const gl::Framebuffer *source) override; @@ -148,8 +150,9 @@ class TextureD3D_2D : public TextureD3D virtual void bindTexImage(egl::Surface *surface); virtual void releaseTexImage(); + gl::Error setEGLImageTarget(GLenum target, egl::Image *image) override; + virtual gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTargetD3D **outRT); - virtual unsigned int getRenderTargetSerial(const gl::ImageIndex &index); virtual gl::ImageIndexIterator imageIterator() const; virtual gl::ImageIndex getImageIndex(GLint mip, GLint layer) const; @@ -169,8 +172,12 @@ class TextureD3D_2D : public TextureD3D gl::Error updateStorageLevel(int level); - void redefineImage(GLint level, GLenum internalformat, const gl::Extents &size); + void redefineImage(size_t level, + GLenum internalformat, + const gl::Extents &size, + bool forceRelease); + bool mEGLImageTarget; ImageD3D *mImageArray[gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS]; }; @@ -197,9 +204,9 @@ class TextureD3D_Cube : public TextureD3D const gl::PixelUnpackState &unpack, const uint8_t *pixels) override; gl::Error setCompressedImage(GLenum target, size_t level, GLenum internalFormat, const gl::Extents &size, - const gl::PixelUnpackState &unpack, const uint8_t *pixels) override; + const gl::PixelUnpackState &unpack, size_t imageSize, const uint8_t *pixels) override; gl::Error setCompressedSubImage(GLenum target, size_t level, const gl::Box &area, GLenum format, - const gl::PixelUnpackState &unpack, const uint8_t *pixels) override; + const gl::PixelUnpackState &unpack, size_t imageSize, const uint8_t *pixels) override; gl::Error copyImage(GLenum target, size_t level, const gl::Rectangle &sourceArea, GLenum internalFormat, const gl::Framebuffer *source) override; @@ -211,8 +218,9 @@ class TextureD3D_Cube : public TextureD3D virtual void bindTexImage(egl::Surface *surface); virtual void releaseTexImage(); + gl::Error setEGLImageTarget(GLenum target, egl::Image *image) override; + virtual gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTargetD3D **outRT); - virtual unsigned int getRenderTargetSerial(const gl::ImageIndex &index); virtual gl::ImageIndexIterator imageIterator() const; virtual gl::ImageIndex getImageIndex(GLint mip, GLint layer) const; @@ -259,9 +267,9 @@ class TextureD3D_3D : public TextureD3D const gl::PixelUnpackState &unpack, const uint8_t *pixels) override; gl::Error setCompressedImage(GLenum target, size_t level, GLenum internalFormat, const gl::Extents &size, - const gl::PixelUnpackState &unpack, const uint8_t *pixels) override; + const gl::PixelUnpackState &unpack, size_t imageSize, const uint8_t *pixels) override; gl::Error setCompressedSubImage(GLenum target, size_t level, const gl::Box &area, GLenum format, - const gl::PixelUnpackState &unpack, const uint8_t *pixels) override; + const gl::PixelUnpackState &unpack, size_t imageSize, const uint8_t *pixels) override; gl::Error copyImage(GLenum target, size_t level, const gl::Rectangle &sourceArea, GLenum internalFormat, const gl::Framebuffer *source) override; @@ -273,8 +281,9 @@ class TextureD3D_3D : public TextureD3D virtual void bindTexImage(egl::Surface *surface); virtual void releaseTexImage(); + gl::Error setEGLImageTarget(GLenum target, egl::Image *image) override; + virtual gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTargetD3D **outRT); - virtual unsigned int getRenderTargetSerial(const gl::ImageIndex &index); virtual gl::ImageIndexIterator imageIterator() const; virtual gl::ImageIndex getImageIndex(GLint mip, GLint layer) const; @@ -319,9 +328,9 @@ class TextureD3D_2DArray : public TextureD3D const gl::PixelUnpackState &unpack, const uint8_t *pixels) override; gl::Error setCompressedImage(GLenum target, size_t level, GLenum internalFormat, const gl::Extents &size, - const gl::PixelUnpackState &unpack, const uint8_t *pixels) override; + const gl::PixelUnpackState &unpack, size_t imageSize, const uint8_t *pixels) override; gl::Error setCompressedSubImage(GLenum target, size_t level, const gl::Box &area, GLenum format, - const gl::PixelUnpackState &unpack, const uint8_t *pixels) override; + const gl::PixelUnpackState &unpack, size_t imageSize, const uint8_t *pixels) override; gl::Error copyImage(GLenum target, size_t level, const gl::Rectangle &sourceArea, GLenum internalFormat, const gl::Framebuffer *source) override; @@ -333,8 +342,9 @@ class TextureD3D_2DArray : public TextureD3D virtual void bindTexImage(egl::Surface *surface); virtual void releaseTexImage(); + gl::Error setEGLImageTarget(GLenum target, egl::Image *image) override; + virtual gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTargetD3D **outRT); - virtual unsigned int getRenderTargetSerial(const gl::ImageIndex &index); virtual gl::ImageIndexIterator imageIterator() const; virtual gl::ImageIndex getImageIndex(GLint mip, GLint layer) const; diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/TextureStorage.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/TextureStorage.h index 9dd6ea82ae39..417237495d67 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/TextureStorage.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/TextureStorage.h @@ -33,8 +33,8 @@ class ImageD3D; class TextureStorage : angle::NonCopyable { public: - TextureStorage(); - virtual ~TextureStorage() {}; + TextureStorage() {} + virtual ~TextureStorage() {} virtual int getTopLevel() const = 0; virtual bool isRenderTarget() const = 0; @@ -49,18 +49,8 @@ class TextureStorage : angle::NonCopyable virtual gl::Error setData(const gl::ImageIndex &index, ImageD3D *image, const gl::Box *destBox, GLenum type, const gl::PixelUnpackState &unpack, const uint8_t *pixelData) = 0; - unsigned int getRenderTargetSerial(const gl::ImageIndex &index) const; - unsigned int getTextureSerial() const; - // This is a no-op for most implementations of TextureStorage. Some (e.g. TextureStorage11_2D) might override it. virtual gl::Error useLevelZeroWorkaroundTexture(bool useLevelZeroTexture) { return gl::Error(GL_NO_ERROR); } - - protected: - void initializeSerials(unsigned int rtSerialsToReserve, unsigned int rtSerialsLayerStride); - - private: - unsigned int mFirstRenderTargetSerial; - unsigned int mRenderTargetSerialsLayerStride; }; } diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/VaryingPacking.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/VaryingPacking.cpp new file mode 100644 index 000000000000..f2654d34e33a --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/VaryingPacking.cpp @@ -0,0 +1,397 @@ +// +// 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 in D3D +// for linking between shader stages. +// + +#include "libANGLE/renderer/d3d/VaryingPacking.h" + +#include "common/utilities.h" +#include "compiler/translator/blocklayoutHLSL.h" +#include "libANGLE/renderer/d3d/DynamicHLSL.h" +#include "libANGLE/renderer/d3d/ProgramD3D.h" + +namespace rx +{ + +// Implementation of VaryingPacking::BuiltinVarying +VaryingPacking::BuiltinVarying::BuiltinVarying() : enabled(false), index(0), systemValue(false) +{ +} + +std::string VaryingPacking::BuiltinVarying::str() const +{ + return (systemValue ? semantic : (semantic + Str(index))); +} + +void VaryingPacking::BuiltinVarying::enableSystem(const std::string &systemValueSemantic) +{ + enabled = true; + semantic = systemValueSemantic; + systemValue = true; +} + +void VaryingPacking::BuiltinVarying::enable(const std::string &semanticVal, unsigned int indexVal) +{ + enabled = true; + semantic = semanticVal; + index = indexVal; +} + +// Implementation of VaryingPacking +VaryingPacking::VaryingPacking(GLuint maxVaryingVectors) + : mRegisterMap(maxVaryingVectors), mBuiltinInfo(SHADER_TYPE_MAX) +{ +} + +// 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::packVarying(const PackedVarying &packedVarying) +{ + unsigned int varyingRows = 0; + unsigned int varyingColumns = 0; + + const auto &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.Variables of type mat2 occupies 2 complete rows." + // 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); + varyingRows = gl::VariableRowCount(transposedType); + varyingColumns = gl::VariableColumnCount(transposedType); + + // "Arrays of size N are assumed to take N times the size of the base type" + varyingRows *= varying.elementCount(); + + unsigned int maxVaryingVectors = static_cast(mRegisterMap.size()); + + // "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 (isFree(row, 0, varyingRows, varyingColumns)) + { + insert(row, 0, 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 (isFree(r, 2, varyingRows, 2)) + { + insert(r, 2, 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 (isFree(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 = arrayIndex; + registerInfo.varyingRowIndex = 0; + mRegisterList.push_back(registerInfo); + mRegisterMap[row + arrayIndex][bestColumn] = true; + } + break; + } + } + return true; + } + + return false; +} + +bool VaryingPacking::isFree(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::insert(unsigned int registerRow, + unsigned int registerColumn, + const PackedVarying &packedVarying) +{ + unsigned int varyingRows = 0; + unsigned int varyingColumns = 0; + + const auto &varying = *packedVarying.varying; + ASSERT(!varying.isStruct()); + GLenum transposedType = gl::TransposeMatrixType(varying.type); + varyingRows = gl::VariableRowCount(transposedType); + varyingColumns = gl::VariableColumnCount(transposedType); + + PackedVaryingRegister registerInfo; + registerInfo.packedVarying = &packedVarying; + registerInfo.registerColumn = registerColumn; + + for (unsigned int arrayElement = 0; arrayElement < varying.elementCount(); ++arrayElement) + { + for (unsigned int varyingRow = 0; varyingRow < varyingRows; ++varyingRow) + { + registerInfo.registerRow = registerRow + (arrayElement * varyingRows) + varyingRow; + registerInfo.varyingRowIndex = varyingRow; + registerInfo.varyingArrayIndex = arrayElement; + mRegisterList.push_back(registerInfo); + + for (unsigned int columnIndex = 0; columnIndex < varyingColumns; ++columnIndex) + { + mRegisterMap[registerInfo.registerRow][registerColumn + columnIndex] = true; + } + } + } +} + +// See comment on packVarying. +bool VaryingPacking::packVaryings(gl::InfoLog &infoLog, + const std::vector &packedVaryings, + const std::vector &transformFeedbackVaryings) +{ + std::set uniqueVaryingNames; + + // "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) + { + const auto &varying = *packedVarying.varying; + + // Do not assign registers to built-in or unreferenced varyings + if (varying.isBuiltIn() || (!varying.staticUse && !packedVarying.isStructField())) + { + continue; + } + + ASSERT(!varying.isStruct()); + ASSERT(uniqueVaryingNames.count(varying.name) == 0); + + if (packVarying(packedVarying)) + { + uniqueVaryingNames.insert(varying.name); + } + else + { + infoLog << "Could not pack varying " << varying.name; + return false; + } + } + + for (const std::string &transformFeedbackVaryingName : transformFeedbackVaryings) + { + if (transformFeedbackVaryingName.compare(0, 3, "gl_") == 0) + { + // do not pack builtin XFB varyings + continue; + } + + for (const PackedVarying &packedVarying : packedVaryings) + { + const auto &varying = *packedVarying.varying; + + // Make sure transform feedback varyings aren't optimized out. + if (uniqueVaryingNames.count(transformFeedbackVaryingName) == 0) + { + bool found = false; + if (transformFeedbackVaryingName == varying.name) + { + if (!packVarying(packedVarying)) + { + infoLog << "Could not pack varying " << varying.name; + return false; + } + + found = true; + break; + } + if (!found) + { + infoLog << "Transform feedback varying " << transformFeedbackVaryingName + << " does not exist in the vertex shader."; + return false; + } + } + } + } + + // Sort the packed register list + std::sort(mRegisterList.begin(), mRegisterList.end()); + + // Assign semantic indices + for (unsigned int semanticIndex = 0; + semanticIndex < static_cast(mRegisterList.size()); ++semanticIndex) + { + mRegisterList[semanticIndex].semanticIndex = semanticIndex; + } + + return true; +} + +unsigned int VaryingPacking::getRegisterCount() const +{ + unsigned int count = 0; + + for (const Register ® : mRegisterMap) + { + if (reg.data[0] || reg.data[1] || reg.data[2] || reg.data[3]) + { + ++count; + } + } + + if (mBuiltinInfo[SHADER_PIXEL].glFragCoord.enabled) + { + ++count; + } + + if (mBuiltinInfo[SHADER_PIXEL].glPointCoord.enabled) + { + ++count; + } + + return count; +} + +void VaryingPacking::enableBuiltins(ShaderType shaderType, + const ProgramD3DMetadata &programMetadata) +{ + int majorShaderModel = programMetadata.getRendererMajorShaderModel(); + bool position = programMetadata.usesTransformFeedbackGLPosition(); + bool fragCoord = programMetadata.usesFragCoord(); + bool pointCoord = shaderType == SHADER_VERTEX ? programMetadata.addsPointCoordToVertexShader() + : programMetadata.usesPointCoord(); + bool pointSize = programMetadata.usesSystemValuePointSize(); + bool hlsl4 = (majorShaderModel >= 4); + const std::string &userSemantic = GetVaryingSemantic(majorShaderModel, pointSize); + + unsigned int reservedSemanticIndex = getMaxSemanticIndex(); + + BuiltinInfo *builtins = &mBuiltinInfo[shaderType]; + + if (hlsl4) + { + builtins->dxPosition.enableSystem("SV_Position"); + } + else if (shaderType == SHADER_PIXEL) + { + builtins->dxPosition.enableSystem("VPOS"); + } + else + { + builtins->dxPosition.enableSystem("POSITION"); + } + + if (position) + { + builtins->glPosition.enable(userSemantic, reservedSemanticIndex++); + } + + if (fragCoord) + { + builtins->glFragCoord.enable(userSemantic, reservedSemanticIndex++); + } + + if (pointCoord) + { + // SM3 reserves the TEXCOORD semantic for point sprite texcoords (gl_PointCoord) + // In D3D11 we manually compute gl_PointCoord in the GS. + if (hlsl4) + { + builtins->glPointCoord.enable(userSemantic, reservedSemanticIndex++); + } + else + { + builtins->glPointCoord.enable("TEXCOORD", 0); + } + } + + // Special case: do not include PSIZE semantic in HLSL 3 pixel shaders + if (pointSize && (shaderType != SHADER_PIXEL || hlsl4)) + { + builtins->glPointSize.enableSystem("PSIZE"); + } +} + +} // namespace rx diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/VaryingPacking.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/VaryingPacking.h new file mode 100644 index 000000000000..ca4640b00020 --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/VaryingPacking.h @@ -0,0 +1,175 @@ +// +// 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 in D3D +// for linking between shader stages. +// + +#ifndef LIBANGLE_RENDERER_D3D_VARYINGPACKING_H_ +#define LIBANGLE_RENDERER_D3D_VARYINGPACKING_H_ + +#include "libANGLE/renderer/d3d/RendererD3D.h" + +namespace rx +{ +class ProgramD3DMetadata; + +struct PackedVarying +{ + PackedVarying(const sh::ShaderVariable &varyingIn, sh::InterpolationType interpolationIn) + : varying(&varyingIn), vertexOnly(false), interpolation(interpolationIn) + { + } + PackedVarying(const sh::ShaderVariable &varyingIn, + sh::InterpolationType interpolationIn, + const std::string &parentStructNameIn) + : varying(&varyingIn), + vertexOnly(false), + interpolation(interpolationIn), + parentStructName(parentStructNameIn) + { + } + + bool isStructField() const { return !parentStructName.empty(); } + + const sh::ShaderVariable *varying; + + // Transform feedback varyings can be only referenced in the VS. + bool vertexOnly; + + // Cached so we can store sh::ShaderVariable to point to varying fields. + sh::InterpolationType interpolation; + + // Struct name + std::string parentStructName; +}; + +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; + } + + bool isStructField() const { return !structFieldName.empty(); } + + // 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; + + // Assigned after packing + unsigned int semanticIndex; + + // Struct member this varying corresponds to. + std::string structFieldName; +}; + +class VaryingPacking final : angle::NonCopyable +{ + public: + VaryingPacking(GLuint maxVaryingVectors); + + bool packVaryings(gl::InfoLog &infoLog, + const std::vector &packedVaryings, + const std::vector &transformFeedbackVaryings); + + 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()); + } + unsigned int getRegisterCount() const; + + void enableBuiltins(ShaderType shaderType, const ProgramD3DMetadata &programMetadata); + + struct BuiltinVarying final : 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 + { + BuiltinVarying dxPosition; + BuiltinVarying glPosition; + BuiltinVarying glFragCoord; + BuiltinVarying glPointCoord; + BuiltinVarying glPointSize; + }; + + const BuiltinInfo &builtins(ShaderType shaderType) const { return mBuiltinInfo[shaderType]; } + + bool usesPointSize() const { return mBuiltinInfo[SHADER_VERTEX].glPointSize.enabled; } + + private: + bool packVarying(const PackedVarying &packedVarying); + bool isFree(unsigned int registerRow, + unsigned int registerColumn, + unsigned int varyingRows, + unsigned int varyingColumns) const; + void insert(unsigned int registerRow, + unsigned int registerColumn, + const PackedVarying &packedVarying); + + std::vector mRegisterMap; + std::vector mRegisterList; + + std::vector mBuiltinInfo; +}; + +} // namespace rx + +#endif // LIBANGLE_RENDERER_D3D_VARYINGPACKING_H_ diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/VertexBuffer.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/VertexBuffer.cpp index 19bd548fceb7..55a1b66f18e7 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/VertexBuffer.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/VertexBuffer.cpp @@ -8,18 +8,19 @@ // class with derivations, classes that perform graphics API agnostic vertex buffer operations. #include "libANGLE/renderer/d3d/VertexBuffer.h" + +#include "common/mathutil.h" #include "libANGLE/renderer/d3d/BufferD3D.h" #include "libANGLE/renderer/d3d/RendererD3D.h" #include "libANGLE/VertexAttribute.h" -#include "common/mathutil.h" - namespace rx { +// VertexBuffer Implementation unsigned int VertexBuffer::mNextSerial = 1; -VertexBuffer::VertexBuffer() +VertexBuffer::VertexBuffer() : mRefCount(1) { updateSerial(); } @@ -38,19 +39,34 @@ unsigned int VertexBuffer::getSerial() const return mSerial; } -VertexBufferInterface::VertexBufferInterface(BufferFactoryD3D *factory, bool dynamic) - : mFactory(factory) +void VertexBuffer::addRef() { - mDynamic = dynamic; - mWritePosition = 0; - mReservedSpace = 0; + mRefCount++; +} + +void VertexBuffer::release() +{ + ASSERT(mRefCount > 0); + mRefCount--; + + if (mRefCount == 0) + { + delete this; + } +} - mVertexBuffer = factory->createVertexBuffer(); +// VertexBufferInterface Implementation +VertexBufferInterface::VertexBufferInterface(BufferFactoryD3D *factory, bool dynamic) + : mFactory(factory), mVertexBuffer(factory->createVertexBuffer()), mDynamic(dynamic) +{ } VertexBufferInterface::~VertexBufferInterface() { - delete mVertexBuffer; + if (mVertexBuffer) + { + mVertexBuffer->release(); + } } unsigned int VertexBufferInterface::getSerial() const @@ -69,56 +85,91 @@ gl::Error VertexBufferInterface::setBufferSize(unsigned int size) { return mVertexBuffer->initialize(size, mDynamic); } - else + + return mVertexBuffer->setBufferSize(size); +} + +gl::ErrorOrResult VertexBufferInterface::getSpaceRequired( + const gl::VertexAttribute &attrib, + GLsizei count, + GLsizei instances) const +{ + unsigned int spaceRequired = 0; + ANGLE_TRY_RESULT(mFactory->getVertexSpaceRequired(attrib, count, instances), spaceRequired); + + // Align to 16-byte boundary + unsigned int alignedSpaceRequired = roundUp(spaceRequired, 16u); + + if (alignedSpaceRequired < spaceRequired) { - return mVertexBuffer->setBufferSize(size); + return gl::Error(GL_OUT_OF_MEMORY, + "Vertex buffer overflow in VertexBufferInterface::getSpaceRequired."); } + + return alignedSpaceRequired; } -unsigned int VertexBufferInterface::getWritePosition() const +gl::Error VertexBufferInterface::discard() { - return mWritePosition; + return mVertexBuffer->discard(); } -void VertexBufferInterface::setWritePosition(unsigned int writePosition) +VertexBuffer *VertexBufferInterface::getVertexBuffer() const { - mWritePosition = writePosition; + return mVertexBuffer; } -gl::Error VertexBufferInterface::discard() +// StreamingVertexBufferInterface Implementation +StreamingVertexBufferInterface::StreamingVertexBufferInterface(BufferFactoryD3D *factory, + std::size_t initialSize) + : VertexBufferInterface(factory, true), mWritePosition(0), mReservedSpace(0) { - return mVertexBuffer->discard(); + setBufferSize(static_cast(initialSize)); } -gl::Error VertexBufferInterface::storeVertexAttributes(const gl::VertexAttribute &attrib, const gl::VertexAttribCurrentValueData ¤tValue, - GLint start, GLsizei count, GLsizei instances, unsigned int *outStreamOffset) +StreamingVertexBufferInterface::~StreamingVertexBufferInterface() { - gl::Error error(GL_NO_ERROR); +} - unsigned int spaceRequired; - error = mVertexBuffer->getSpaceRequired(attrib, count, instances, &spaceRequired); - if (error.isError()) +gl::Error StreamingVertexBufferInterface::reserveSpace(unsigned int size) +{ + unsigned int curBufferSize = getBufferSize(); + if (size > curBufferSize) { - return error; + ANGLE_TRY(setBufferSize(std::max(size, 3 * curBufferSize / 2))); + mWritePosition = 0; } - - if (mWritePosition + spaceRequired < mWritePosition) + else if (mWritePosition + size > curBufferSize) { - return gl::Error(GL_OUT_OF_MEMORY, "Internal error, new vertex buffer write position would overflow."); + ANGLE_TRY(discard()); + mWritePosition = 0; } - error = reserveSpace(mReservedSpace); - if (error.isError()) + return gl::NoError(); +} + +gl::Error StreamingVertexBufferInterface::storeDynamicAttribute(const gl::VertexAttribute &attrib, + GLenum currentValueType, + GLint start, + GLsizei count, + GLsizei instances, + unsigned int *outStreamOffset, + const uint8_t *sourceData) +{ + unsigned int spaceRequired = 0; + ANGLE_TRY_RESULT(getSpaceRequired(attrib, count, instances), spaceRequired); + + // Protect against integer overflow + if (!IsUnsignedAdditionSafe(mWritePosition, spaceRequired)) { - return error; + return gl::Error(GL_OUT_OF_MEMORY, "Internal error, new vertex buffer write position would overflow."); } + + ANGLE_TRY(reserveSpace(mReservedSpace)); mReservedSpace = 0; - error = mVertexBuffer->storeVertexAttributes(attrib, currentValue, start, count, instances, mWritePosition); - if (error.isError()) - { - return error; - } + ANGLE_TRY(mVertexBuffer->storeVertexAttributes(attrib, currentValueType, start, count, + instances, mWritePosition, sourceData)); if (outStreamOffset) { @@ -127,111 +178,63 @@ gl::Error VertexBufferInterface::storeVertexAttributes(const gl::VertexAttribute mWritePosition += spaceRequired; - // Align to 16-byte boundary - mWritePosition = roundUp(mWritePosition, 16u); - - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -gl::Error VertexBufferInterface::reserveVertexSpace(const gl::VertexAttribute &attrib, GLsizei count, GLsizei instances) +gl::Error StreamingVertexBufferInterface::reserveVertexSpace(const gl::VertexAttribute &attrib, + GLsizei count, + GLsizei instances) { - gl::Error error(GL_NO_ERROR); + unsigned int requiredSpace = 0; + ANGLE_TRY_RESULT(mFactory->getVertexSpaceRequired(attrib, count, instances), requiredSpace); - unsigned int requiredSpace; - error = mVertexBuffer->getSpaceRequired(attrib, count, instances, &requiredSpace); - if (error.isError()) - { - return error; - } + // Align to 16-byte boundary + unsigned int alignedRequiredSpace = roundUp(requiredSpace, 16u); // Protect against integer overflow - if (mReservedSpace + requiredSpace < mReservedSpace) + if (!IsUnsignedAdditionSafe(mReservedSpace, alignedRequiredSpace) || + alignedRequiredSpace < requiredSpace) { - return gl::Error(GL_OUT_OF_MEMORY, "Unable to reserve %u extra bytes in internal vertex buffer, " - "it would result in an overflow.", requiredSpace); + return gl::Error(GL_OUT_OF_MEMORY, + "Unable to reserve %u extra bytes in internal vertex buffer, " + "it would result in an overflow.", + requiredSpace); } - mReservedSpace += requiredSpace; - - // Align to 16-byte boundary - mReservedSpace = roundUp(mReservedSpace, 16u); + mReservedSpace += alignedRequiredSpace; - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -VertexBuffer* VertexBufferInterface::getVertexBuffer() const +// StaticVertexBufferInterface Implementation +StaticVertexBufferInterface::AttributeSignature::AttributeSignature() + : type(GL_NONE), size(0), stride(0), normalized(false), pureInteger(false), offset(0) { - return mVertexBuffer; } -bool VertexBufferInterface::directStoragePossible(const gl::VertexAttribute &attrib, - const gl::VertexAttribCurrentValueData ¤tValue) const +bool StaticVertexBufferInterface::AttributeSignature::matchesAttribute( + const gl::VertexAttribute &attrib) const { - gl::Buffer *buffer = attrib.buffer.get(); - BufferD3D *storage = buffer ? GetImplAs(buffer) : NULL; + size_t attribStride = ComputeVertexAttributeStride(attrib); - if (!storage || !storage->supportsDirectBinding()) + if (type != attrib.type || size != attrib.size || static_cast(stride) != attribStride || + normalized != attrib.normalized || pureInteger != attrib.pureInteger) { 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; - bool requiresConversion = false; - - if (attrib.type != GL_FLOAT) - { - gl::VertexFormat vertexFormat(attrib, currentValue.Type); - - unsigned int outputElementSize; - getVertexBuffer()->getSpaceRequired(attrib, 1, 0, &outputElementSize); - alignment = std::min(outputElementSize, 4); - - // TODO(jmadill): add VertexFormatCaps - requiresConversion = (mFactory->getVertexConversionType(vertexFormat) & VERTEX_CONVERT_CPU) != 0; - } - - bool isAligned = (static_cast(ComputeVertexAttributeStride(attrib)) % alignment == 0) && - (static_cast(attrib.offset) % alignment == 0); - - return !requiresConversion && isAligned; -} - -StreamingVertexBufferInterface::StreamingVertexBufferInterface(BufferFactoryD3D *factory, std::size_t initialSize) - : VertexBufferInterface(factory, true) -{ - setBufferSize(initialSize); + size_t attribOffset = (static_cast(attrib.offset) % attribStride); + return (offset == attribOffset); } -StreamingVertexBufferInterface::~StreamingVertexBufferInterface() -{ -} - -gl::Error StreamingVertexBufferInterface::reserveSpace(unsigned int size) +void StaticVertexBufferInterface::AttributeSignature::set(const gl::VertexAttribute &attrib) { - unsigned int curBufferSize = getBufferSize(); - if (size > curBufferSize) - { - gl::Error error = setBufferSize(std::max(size, 3 * curBufferSize / 2)); - if (error.isError()) - { - return error; - } - setWritePosition(0); - } - else if (getWritePosition() + size > curBufferSize) - { - gl::Error error = discard(); - if (error.isError()) - { - return error; - } - setWritePosition(0); - } - - return gl::Error(GL_NO_ERROR); + type = attrib.type; + size = attrib.size; + normalized = attrib.normalized; + pureInteger = attrib.pureInteger; + offset = stride = static_cast(ComputeVertexAttributeStride(attrib)); + offset = static_cast(attrib.offset) % ComputeVertexAttributeStride(attrib); } StaticVertexBufferInterface::StaticVertexBufferInterface(BufferFactoryD3D *factory) @@ -243,69 +246,33 @@ StaticVertexBufferInterface::~StaticVertexBufferInterface() { } -bool StaticVertexBufferInterface::lookupAttribute(const gl::VertexAttribute &attrib, unsigned int *outStreamOffset) +bool StaticVertexBufferInterface::matchesAttribute(const gl::VertexAttribute &attrib) const { - for (unsigned int element = 0; element < mCache.size(); element++) - { - if (mCache[element].type == attrib.type && - mCache[element].size == attrib.size && - mCache[element].stride == ComputeVertexAttributeStride(attrib) && - mCache[element].normalized == attrib.normalized && - mCache[element].pureInteger == attrib.pureInteger) - { - size_t offset = (static_cast(attrib.offset) % ComputeVertexAttributeStride(attrib)); - if (mCache[element].attributeOffset == offset) - { - if (outStreamOffset) - { - *outStreamOffset = mCache[element].streamOffset; - } - return true; - } - } - } - - return false; + return mSignature.matchesAttribute(attrib); } -gl::Error StaticVertexBufferInterface::reserveSpace(unsigned int size) +void StaticVertexBufferInterface::setAttribute(const gl::VertexAttribute &attrib) { - unsigned int curSize = getBufferSize(); - if (curSize == 0) - { - return setBufferSize(size); - } - else if (curSize >= size) - { - return gl::Error(GL_NO_ERROR); - } - else - { - UNREACHABLE(); - return gl::Error(GL_INVALID_OPERATION, "Internal error, Static vertex buffers can't be resized."); - } + return mSignature.set(attrib); } -gl::Error StaticVertexBufferInterface::storeVertexAttributes(const gl::VertexAttribute &attrib, const gl::VertexAttribCurrentValueData ¤tValue, - GLint start, GLsizei count, GLsizei instances, unsigned int *outStreamOffset) +gl::Error StaticVertexBufferInterface::storeStaticAttribute(const gl::VertexAttribute &attrib, + GLint start, + GLsizei count, + GLsizei instances, + const uint8_t *sourceData) { - unsigned int streamOffset; - gl::Error error = VertexBufferInterface::storeVertexAttributes(attrib, currentValue, start, count, instances, &streamOffset); - if (error.isError()) - { - return error; - } + unsigned int spaceRequired = 0; + ANGLE_TRY_RESULT(getSpaceRequired(attrib, count, instances), spaceRequired); + setBufferSize(spaceRequired); - size_t attributeOffset = static_cast(attrib.offset) % ComputeVertexAttributeStride(attrib); - VertexElement element = { attrib.type, attrib.size, static_cast(ComputeVertexAttributeStride(attrib)), attrib.normalized, attrib.pureInteger, attributeOffset, streamOffset }; - mCache.push_back(element); + ASSERT(attrib.enabled); + ANGLE_TRY(mVertexBuffer->storeVertexAttributes(attrib, GL_NONE, start, count, instances, 0, + sourceData)); - if (outStreamOffset) - { - *outStreamOffset = streamOffset; - } - - return gl::Error(GL_NO_ERROR); + mSignature.set(attrib); + mVertexBuffer->hintUnmapResource(); + return gl::NoError(); } -} +} // namespace rx diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/VertexBuffer.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/VertexBuffer.h index 5cb03fe3a14a..b3d98247fb58 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/VertexBuffer.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/VertexBuffer.h @@ -16,6 +16,7 @@ #include #include +#include #include namespace gl @@ -28,18 +29,22 @@ 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 ~VertexBuffer(); virtual gl::Error initialize(unsigned int size, bool dynamicUsage) = 0; - virtual gl::Error storeVertexAttributes(const gl::VertexAttribute &attrib, const gl::VertexAttribCurrentValueData ¤tValue, - GLint start, GLsizei count, GLsizei instances, unsigned int offset) = 0; - virtual gl::Error getSpaceRequired(const gl::VertexAttribute &attrib, GLsizei count, GLsizei instances, - unsigned int *outSpaceRequired) const = 0; + virtual gl::Error storeVertexAttributes(const gl::VertexAttribute &attrib, + GLenum currentValueType, + GLint start, + GLsizei count, + GLsizei instances, + unsigned int offset, + const uint8_t *sourceData) = 0; virtual unsigned int getBufferSize() const = 0; virtual gl::Error setBufferSize(unsigned int size) = 0; @@ -50,12 +55,18 @@ class VertexBuffer : angle::NonCopyable // 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 @@ -64,37 +75,22 @@ class VertexBufferInterface : angle::NonCopyable VertexBufferInterface(BufferFactoryD3D *factory, bool dynamic); virtual ~VertexBufferInterface(); - gl::Error reserveVertexSpace(const gl::VertexAttribute &attribute, GLsizei count, GLsizei instances); - unsigned int getBufferSize() const; + bool empty() const { return getBufferSize() == 0; } unsigned int getSerial() const; - virtual gl::Error storeVertexAttributes(const gl::VertexAttribute &attrib, const gl::VertexAttribCurrentValueData ¤tValue, - GLint start, GLsizei count, GLsizei instances, unsigned int *outStreamOffset); - - bool directStoragePossible(const gl::VertexAttribute &attrib, - const gl::VertexAttribCurrentValueData ¤tValue) const; - - VertexBuffer* getVertexBuffer() const; + VertexBuffer *getVertexBuffer() const; protected: - virtual gl::Error reserveSpace(unsigned int size) = 0; - - unsigned int getWritePosition() const; - void setWritePosition(unsigned int writePosition); - gl::Error discard(); gl::Error setBufferSize(unsigned int size); - - private: + gl::ErrorOrResult getSpaceRequired(const gl::VertexAttribute &attrib, + GLsizei count, + GLsizei instances) const; BufferFactoryD3D *const mFactory; - - VertexBuffer* mVertexBuffer; - - unsigned int mWritePosition; - unsigned int mReservedSpace; + VertexBuffer *mVertexBuffer; bool mDynamic; }; @@ -104,8 +100,23 @@ class StreamingVertexBufferInterface : public VertexBufferInterface StreamingVertexBufferInterface(BufferFactoryD3D *factory, std::size_t initialSize); ~StreamingVertexBufferInterface(); - protected: + gl::Error storeDynamicAttribute(const gl::VertexAttribute &attrib, + GLenum currentValueType, + GLint start, + GLsizei count, + GLsizei instances, + unsigned int *outStreamOffset, + const uint8_t *sourceData); + + gl::Error reserveVertexSpace(const gl::VertexAttribute &attribute, + GLsizei count, + GLsizei instances); + + private: gl::Error reserveSpace(unsigned int size); + + unsigned int mWritePosition; + unsigned int mReservedSpace; }; class StaticVertexBufferInterface : public VertexBufferInterface @@ -114,30 +125,35 @@ class StaticVertexBufferInterface : public VertexBufferInterface explicit StaticVertexBufferInterface(BufferFactoryD3D *factory); ~StaticVertexBufferInterface(); - gl::Error storeVertexAttributes(const gl::VertexAttribute &attrib, const gl::VertexAttribCurrentValueData ¤tValue, - GLint start, GLsizei count, GLsizei instances, unsigned int *outStreamOffset); + gl::Error storeStaticAttribute(const gl::VertexAttribute &attrib, + GLint start, + GLsizei count, + GLsizei instances, + const uint8_t *sourceData); - bool lookupAttribute(const gl::VertexAttribute &attribute, unsigned int* outStreamFffset); - - protected: - gl::Error reserveSpace(unsigned int size); + bool matchesAttribute(const gl::VertexAttribute &attribute) const; + void setAttribute(const gl::VertexAttribute &attribute); private: - struct VertexElement + class AttributeSignature final : angle::NonCopyable { + public: + AttributeSignature(); + bool matchesAttribute(const gl::VertexAttribute &attrib) const; + void set(const gl::VertexAttribute &attrib); + + private: GLenum type; GLuint size; GLuint stride; bool normalized; bool pureInteger; - size_t attributeOffset; - - unsigned int streamOffset; + size_t offset; }; - std::vector mCache; + AttributeSignature mSignature; }; -} +} // namespace rx #endif // LIBANGLE_RENDERER_D3D_VERTEXBUFFER_H_ diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/VertexDataManager.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/VertexDataManager.cpp index 91770dc122fb..3cd94a876796 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/VertexDataManager.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/VertexDataManager.cpp @@ -9,25 +9,32 @@ #include "libANGLE/renderer/d3d/VertexDataManager.h" +#include "common/BitSetIterator.h" #include "libANGLE/Buffer.h" +#include "libANGLE/formatutils.h" #include "libANGLE/Program.h" #include "libANGLE/State.h" #include "libANGLE/VertexAttribute.h" #include "libANGLE/VertexArray.h" #include "libANGLE/renderer/d3d/BufferD3D.h" +#include "libANGLE/renderer/d3d/RendererD3D.h" #include "libANGLE/renderer/d3d/VertexBuffer.h" +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 }; -} - -namespace rx +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 +}; -static int ElementsInBuffer(const gl::VertexAttribute &attrib, unsigned int size) +int ElementsInBuffer(const gl::VertexAttribute &attrib, unsigned int size) { // Size cannot be larger than a GLsizei if (size > static_cast(std::numeric_limits::max())) @@ -35,362 +42,555 @@ static int ElementsInBuffer(const gl::VertexAttribute &attrib, unsigned int size size = static_cast(std::numeric_limits::max()); } - GLsizei stride = ComputeVertexAttributeStride(attrib); - return (size - attrib.offset % stride + (stride - ComputeVertexAttributeTypeSize(attrib))) / stride; + GLsizei stride = static_cast(ComputeVertexAttributeStride(attrib)); + return (size - attrib.offset % stride + + (stride - static_cast(ComputeVertexAttributeTypeSize(attrib)))) / + stride; } -static int StreamingBufferElementCount(const gl::VertexAttribute &attrib, int vertexDrawCount, int instanceDrawCount) +bool DirectStoragePossible(const gl::VertexAttribute &attrib) { - // 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 (instanceDrawCount > 0 && attrib.divisor > 0) + // Current value attribs may not use direct storage. + if (!attrib.enabled) { - // 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 (instanceDrawCount + attrib.divisor - 1) / attrib.divisor; + return false; } - return vertexDrawCount; -} + gl::Buffer *buffer = attrib.buffer.get(); + if (!buffer) + { + return false; + } -VertexDataManager::VertexDataManager(BufferFactoryD3D *factory) - : mFactory(factory) -{ - for (int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++) + BufferD3D *bufferD3D = GetImplAs(buffer); + ASSERT(bufferD3D); + if (!bufferD3D->supportsDirectBinding()) { - mCurrentValue[i].FloatValues[0] = std::numeric_limits::quiet_NaN(); - mCurrentValue[i].FloatValues[1] = std::numeric_limits::quiet_NaN(); - mCurrentValue[i].FloatValues[2] = std::numeric_limits::quiet_NaN(); - mCurrentValue[i].FloatValues[3] = std::numeric_limits::quiet_NaN(); - mCurrentValue[i].Type = GL_FLOAT; - mCurrentValueBuffer[i] = NULL; - mCurrentValueOffsets[i] = 0; + return false; } - mStreamingBuffer = new StreamingVertexBufferInterface(factory, INITIAL_STREAM_BUFFER_SIZE); + // 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; - if (!mStreamingBuffer) + if (attrib.type != GL_FLOAT) { - ERR("Failed to allocate the streaming vertex buffer."); + gl::VertexFormatType vertexFormatType = gl::GetVertexFormatType(attrib); + + // TODO(jmadill): add VertexFormatCaps + BufferFactoryD3D *factory = bufferD3D->getFactory(); + + auto errorOrElementSize = factory->getVertexSpaceRequired(attrib, 1, 0); + if (errorOrElementSize.isError()) + { + ERR("Unlogged error in DirectStoragePossible."); + return false; + } + + alignment = std::min(errorOrElementSize.getResult(), 4); + + // CPU-converted vertex data must be converted (naturally). + if ((factory->getVertexConversionType(vertexFormatType) & VERTEX_CONVERT_CPU) != 0) + { + return false; + } } -} -VertexDataManager::~VertexDataManager() + // Final alignment check - unaligned data must be converted. + return (static_cast(ComputeVertexAttributeStride(attrib)) % alignment == 0) && + (static_cast(attrib.offset) % alignment == 0); +} +} // anonymous namespace + +TranslatedAttribute::TranslatedAttribute() + : active(false), + attribute(nullptr), + currentValueType(GL_NONE), + baseOffset(0), + usesFirstVertexOffset(false), + stride(0), + vertexBuffer(), + storage(nullptr), + serial(0), + divisor(0) { - delete mStreamingBuffer; +} - for (int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++) +gl::ErrorOrResult TranslatedAttribute::computeOffset(GLint startVertex) const +{ + unsigned int offset = baseOffset; + if (usesFirstVertexOffset) { - delete mCurrentValueBuffer[i]; + unsigned int startVertexUnsigned = static_cast(startVertex); + + if (!IsUnsignedMultiplicationSafe(stride, startVertexUnsigned)) + { + return gl::Error(GL_INVALID_OPERATION, + "Multiplication overflow in TranslatedAttribute::computeOffset"); + } + + unsigned int strideOffset = stride * startVertexUnsigned; + if (!IsUnsignedAdditionSafe(offset, strideOffset)) + { + return gl::Error(GL_INVALID_OPERATION, + "Addition overflow in TranslatedAttribute::computeOffset"); + } + + offset += strideOffset; } + return offset; } -void VertexDataManager::hintUnmapAllResources(const std::vector &vertexAttributes) +VertexStorageType ClassifyAttributeStorage(const gl::VertexAttribute &attrib) { - mStreamingBuffer->getVertexBuffer()->hintUnmapResource(); + // If attribute is disabled, we use the current value. + if (!attrib.enabled) + { + return VertexStorageType::CURRENT_VALUE; + } - for (size_t i = 0; i < vertexAttributes.size(); i++) + // If specified with immediate data, we must use dynamic storage. + auto *buffer = attrib.buffer.get(); + if (!buffer) { - const gl::VertexAttribute &attrib = vertexAttributes[i]; - if (attrib.enabled) - { - gl::Buffer *buffer = attrib.buffer.get(); - BufferD3D *storage = buffer ? GetImplAs(buffer) : NULL; - StaticVertexBufferInterface *staticBuffer = storage ? storage->getStaticVertexBuffer() : NULL; + return VertexStorageType::DYNAMIC; + } - if (staticBuffer) - { - staticBuffer->getVertexBuffer()->hintUnmapResource(); - } - } + // Check if the buffer supports direct storage. + if (DirectStoragePossible(attrib)) + { + return VertexStorageType::DIRECT; } - for (int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++) + // Otherwise the storage is static or dynamic. + BufferD3D *bufferD3D = GetImplAs(buffer); + ASSERT(bufferD3D); + switch (bufferD3D->getUsage()) { - if (mCurrentValueBuffer[i] != NULL) - { - mCurrentValueBuffer[i]->getVertexBuffer()->hintUnmapResource(); - } + case D3DBufferUsage::DYNAMIC: + return VertexStorageType::DYNAMIC; + case D3DBufferUsage::STATIC: + return VertexStorageType::STATIC; + default: + UNREACHABLE(); + return VertexStorageType::UNKNOWN; } } -gl::Error VertexDataManager::prepareVertexData(const gl::State &state, GLint start, GLsizei count, - TranslatedAttribute *translated, GLsizei instances) +VertexDataManager::CurrentValueState::CurrentValueState() + : buffer(nullptr), + offset(0) +{ + data.FloatValues[0] = std::numeric_limits::quiet_NaN(); + data.FloatValues[1] = std::numeric_limits::quiet_NaN(); + data.FloatValues[2] = std::numeric_limits::quiet_NaN(); + data.FloatValues[3] = std::numeric_limits::quiet_NaN(); + data.Type = GL_FLOAT; +} + +VertexDataManager::CurrentValueState::~CurrentValueState() +{ + SafeDelete(buffer); +} + +VertexDataManager::VertexDataManager(BufferFactoryD3D *factory) + : mFactory(factory), + mStreamingBuffer(nullptr), + // TODO(jmadill): use context caps + mCurrentValueCache(gl::MAX_VERTEX_ATTRIBS) { + mStreamingBuffer = new StreamingVertexBufferInterface(factory, INITIAL_STREAM_BUFFER_SIZE); + if (!mStreamingBuffer) { - return gl::Error(GL_OUT_OF_MEMORY, "Internal streaming vertex buffer is unexpectedly NULL."); + ERR("Failed to allocate the streaming vertex buffer."); } +} + +VertexDataManager::~VertexDataManager() +{ + SafeDelete(mStreamingBuffer); +} + +gl::Error VertexDataManager::prepareVertexData(const gl::State &state, + GLint start, + GLsizei count, + std::vector *translatedAttribs, + GLsizei instances) +{ + ASSERT(mStreamingBuffer); const gl::VertexArray *vertexArray = state.getVertexArray(); - const std::vector &vertexAttributes = vertexArray->getVertexAttributes(); + const auto &vertexAttributes = vertexArray->getVertexAttributes(); - // Invalidate static buffers that don't contain matching attributes - for (int attributeIndex = 0; attributeIndex < gl::MAX_VERTEX_ATTRIBS; attributeIndex++) - { - translated[attributeIndex].active = (state.getProgram()->getSemanticIndex(attributeIndex) != -1); - if (translated[attributeIndex].active && vertexAttributes[attributeIndex].enabled) - { - invalidateMatchingStaticData(vertexAttributes[attributeIndex], state.getVertexAttribCurrentValue(attributeIndex)); - } - } + mDynamicAttribsMaskCache.reset(); + const gl::Program *program = state.getProgram(); - // Reserve the required space in the buffers - for (int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++) - { - if (translated[i].active && vertexAttributes[i].enabled) - { - gl::Error error = reserveSpaceForAttrib(vertexAttributes[i], state.getVertexAttribCurrentValue(i), count, instances); - if (error.isError()) - { - return error; - } - } - } + translatedAttribs->clear(); - // Perform the vertex data translations - for (int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++) + for (size_t attribIndex = 0; attribIndex < vertexAttributes.size(); ++attribIndex) { - const gl::VertexAttribute &curAttrib = vertexAttributes[i]; - if (translated[i].active) + // Skip attrib locations the program doesn't use. + if (!program->isAttribLocationActive(attribIndex)) + continue; + + const auto &attrib = vertexAttributes[attribIndex]; + + // Resize automatically puts in empty attribs + translatedAttribs->resize(attribIndex + 1); + + TranslatedAttribute *translated = &(*translatedAttribs)[attribIndex]; + auto currentValueData = + state.getVertexAttribCurrentValue(static_cast(attribIndex)); + + // Record the attribute now + translated->active = true; + translated->attribute = &attrib; + translated->currentValueType = currentValueData.Type; + translated->divisor = attrib.divisor; + + switch (ClassifyAttributeStorage(attrib)) { - if (curAttrib.enabled) + case VertexStorageType::STATIC: { - gl::Error error = storeAttribute(curAttrib, state.getVertexAttribCurrentValue(i), - &translated[i], start, count, instances); - - if (error.isError()) - { - hintUnmapAllResources(vertexAttributes); - return error; - } + // Store static attribute. + ANGLE_TRY(StoreStaticAttrib(translated, count, instances)); + break; } - else + case VertexStorageType::DYNAMIC: + // Dynamic attributes must be handled together. + mDynamicAttribsMaskCache.set(attribIndex); + break; + case VertexStorageType::DIRECT: + // Update translated data for direct attributes. + StoreDirectAttrib(translated); + break; + case VertexStorageType::CURRENT_VALUE: { - if (!mCurrentValueBuffer[i]) - { - mCurrentValueBuffer[i] = new StreamingVertexBufferInterface(mFactory, CONSTANT_VERTEX_BUFFER_SIZE); - } - - gl::Error error = storeCurrentValue(curAttrib, state.getVertexAttribCurrentValue(i), &translated[i], - &mCurrentValue[i], &mCurrentValueOffsets[i], - mCurrentValueBuffer[i]); - if (error.isError()) - { - hintUnmapAllResources(vertexAttributes); - return error; - } + ANGLE_TRY(storeCurrentValue(currentValueData, translated, attribIndex)); + break; } + default: + UNREACHABLE(); + break; } } - // Hint to unmap all the resources - hintUnmapAllResources(vertexAttributes); + if (mDynamicAttribsMaskCache.none()) + { + return gl::NoError(); + } - for (int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++) + ANGLE_TRY( + storeDynamicAttribs(translatedAttribs, mDynamicAttribsMaskCache, start, count, instances)); + + PromoteDynamicAttribs(*translatedAttribs, mDynamicAttribsMaskCache, count); + + return gl::NoError(); +} + +// static +void VertexDataManager::StoreDirectAttrib(TranslatedAttribute *directAttrib) +{ + const auto &attrib = *directAttrib->attribute; + gl::Buffer *buffer = attrib.buffer.get(); + BufferD3D *bufferD3D = buffer ? GetImplAs(buffer) : nullptr; + + ASSERT(DirectStoragePossible(attrib)); + directAttrib->vertexBuffer.set(nullptr); + directAttrib->storage = bufferD3D; + directAttrib->serial = bufferD3D->getSerial(); + directAttrib->stride = static_cast(ComputeVertexAttributeStride(attrib)); + directAttrib->baseOffset = static_cast(attrib.offset); + + // Instanced vertices do not apply the 'start' offset + directAttrib->usesFirstVertexOffset = (attrib.divisor == 0); +} + +// static +gl::Error VertexDataManager::StoreStaticAttrib(TranslatedAttribute *translated, + GLsizei count, + GLsizei instances) +{ + const gl::VertexAttribute &attrib = *translated->attribute; + + gl::Buffer *buffer = attrib.buffer.get(); + ASSERT(buffer && attrib.enabled && !DirectStoragePossible(attrib)); + BufferD3D *bufferD3D = GetImplAs(buffer); + + // Compute source data pointer + const uint8_t *sourceData = nullptr; + + ANGLE_TRY(bufferD3D->getData(&sourceData)); + sourceData += static_cast(attrib.offset); + + unsigned int streamOffset = 0; + + translated->storage = nullptr; + ANGLE_TRY_RESULT(bufferD3D->getFactory()->getVertexSpaceRequired(attrib, 1, 0), + translated->stride); + + auto *staticBuffer = bufferD3D->getStaticVertexBuffer(attrib); + ASSERT(staticBuffer); + + if (staticBuffer->empty()) { - const gl::VertexAttribute &curAttrib = vertexAttributes[i]; - if (translated[i].active && curAttrib.enabled) - { - gl::Buffer *buffer = curAttrib.buffer.get(); + // Convert the entire buffer + int totalCount = ElementsInBuffer(attrib, static_cast(bufferD3D->getSize())); + int startIndex = static_cast(attrib.offset) / + static_cast(ComputeVertexAttributeStride(attrib)); - if (buffer) - { - BufferD3D *bufferImpl = GetImplAs(buffer); - bufferImpl->promoteStaticUsage(count * ComputeVertexAttributeTypeSize(curAttrib)); - } - } + ANGLE_TRY( + staticBuffer->storeStaticAttribute(attrib, -startIndex, totalCount, 0, sourceData)); } - return gl::Error(GL_NO_ERROR); + unsigned int firstElementOffset = + (static_cast(attrib.offset) / + static_cast(ComputeVertexAttributeStride(attrib))) * + translated->stride; + + VertexBuffer *vertexBuffer = staticBuffer->getVertexBuffer(); + + if (!IsUnsignedAdditionSafe(streamOffset, firstElementOffset)) + { + return gl::Error(GL_INVALID_OPERATION, + "Integer overflow in VertexDataManager::StoreStaticAttrib"); + } + + translated->vertexBuffer.set(vertexBuffer); + translated->serial = vertexBuffer->getSerial(); + translated->baseOffset = streamOffset + firstElementOffset; + + // Instanced vertices do not apply the 'start' offset + translated->usesFirstVertexOffset = (attrib.divisor == 0); + + return gl::NoError(); } -void VertexDataManager::invalidateMatchingStaticData(const gl::VertexAttribute &attrib, - const gl::VertexAttribCurrentValueData ¤tValue) const +gl::Error VertexDataManager::storeDynamicAttribs( + std::vector *translatedAttribs, + const gl::AttributesMask &dynamicAttribsMask, + GLint start, + GLsizei count, + GLsizei instances) { - gl::Buffer *buffer = attrib.buffer.get(); + // Instantiating this class will ensure the streaming buffer is never left mapped. + class StreamingBufferUnmapper final : angle::NonCopyable + { + public: + StreamingBufferUnmapper(StreamingVertexBufferInterface *streamingBuffer) + : mStreamingBuffer(streamingBuffer) + { + ASSERT(mStreamingBuffer); + } + ~StreamingBufferUnmapper() { mStreamingBuffer->getVertexBuffer()->hintUnmapResource(); } - if (buffer) + private: + StreamingVertexBufferInterface *mStreamingBuffer; + }; + + // Will trigger unmapping on return. + StreamingBufferUnmapper localUnmapper(mStreamingBuffer); + + // Reserve the required space for the dynamic buffers. + for (auto attribIndex : angle::IterateBitSet(dynamicAttribsMask)) + { + const auto &dynamicAttrib = (*translatedAttribs)[attribIndex]; + ANGLE_TRY(reserveSpaceForAttrib(dynamicAttrib, count, instances)); + } + + // Store dynamic attributes + for (auto attribIndex : angle::IterateBitSet(dynamicAttribsMask)) { - BufferD3D *bufferImpl = GetImplAs(buffer); - StaticVertexBufferInterface *staticBuffer = bufferImpl->getStaticVertexBuffer(); + auto *dynamicAttrib = &(*translatedAttribs)[attribIndex]; + ANGLE_TRY(storeDynamicAttrib(dynamicAttrib, start, count, instances)); + } - if (staticBuffer && - staticBuffer->getBufferSize() > 0 && - !staticBuffer->lookupAttribute(attrib, NULL) && - !staticBuffer->directStoragePossible(attrib, currentValue)) + return gl::NoError(); +} + +void VertexDataManager::PromoteDynamicAttribs( + const std::vector &translatedAttribs, + const gl::AttributesMask &dynamicAttribsMask, + GLsizei count) +{ + for (auto attribIndex : angle::IterateBitSet(dynamicAttribsMask)) + { + const auto &dynamicAttrib = translatedAttribs[attribIndex]; + gl::Buffer *buffer = dynamicAttrib.attribute->buffer.get(); + if (buffer) { - bufferImpl->invalidateStaticData(); + BufferD3D *bufferD3D = GetImplAs(buffer); + size_t typeSize = ComputeVertexAttributeTypeSize(*dynamicAttrib.attribute); + bufferD3D->promoteStaticUsage(count * static_cast(typeSize)); } } } -gl::Error VertexDataManager::reserveSpaceForAttrib(const gl::VertexAttribute &attrib, - const gl::VertexAttribCurrentValueData ¤tValue, +gl::Error VertexDataManager::reserveSpaceForAttrib(const TranslatedAttribute &translatedAttrib, GLsizei count, GLsizei instances) const { - gl::Buffer *buffer = attrib.buffer.get(); - BufferD3D *bufferImpl = buffer ? GetImplAs(buffer) : NULL; - StaticVertexBufferInterface *staticBuffer = bufferImpl ? bufferImpl->getStaticVertexBuffer() : NULL; - VertexBufferInterface *vertexBuffer = staticBuffer ? staticBuffer : static_cast(mStreamingBuffer); + const gl::VertexAttribute &attrib = *translatedAttrib.attribute; + ASSERT(!DirectStoragePossible(attrib)); - if (!vertexBuffer->directStoragePossible(attrib, currentValue)) - { - if (staticBuffer) - { - if (staticBuffer->getBufferSize() == 0) - { - int totalCount = ElementsInBuffer(attrib, bufferImpl->getSize()); - gl::Error error = staticBuffer->reserveVertexSpace(attrib, totalCount, 0); - if (error.isError()) - { - return error; - } - } - } - else - { - int totalCount = StreamingBufferElementCount(attrib, count, instances); - ASSERT(!bufferImpl || ElementsInBuffer(attrib, bufferImpl->getSize()) >= totalCount); + gl::Buffer *buffer = attrib.buffer.get(); + BufferD3D *bufferD3D = buffer ? GetImplAs(buffer) : nullptr; + ASSERT(!bufferD3D || bufferD3D->getStaticVertexBuffer(attrib) == nullptr); + UNUSED_ASSERTION_VARIABLE(bufferD3D); - gl::Error error = mStreamingBuffer->reserveVertexSpace(attrib, totalCount, instances); - if (error.isError()) - { - return error; - } - } - } + size_t totalCount = ComputeVertexAttributeElementCount(attrib, count, instances); + ASSERT(!bufferD3D || + ElementsInBuffer(attrib, static_cast(bufferD3D->getSize())) >= + static_cast(totalCount)); - return gl::Error(GL_NO_ERROR); + return mStreamingBuffer->reserveVertexSpace(attrib, static_cast(totalCount), + instances); } -gl::Error VertexDataManager::storeAttribute(const gl::VertexAttribute &attrib, - const gl::VertexAttribCurrentValueData ¤tValue, - TranslatedAttribute *translated, - GLint start, - GLsizei count, - GLsizei instances) +gl::Error VertexDataManager::storeDynamicAttrib(TranslatedAttribute *translated, + GLint start, + GLsizei count, + GLsizei instances) { + const gl::VertexAttribute &attrib = *translated->attribute; + gl::Buffer *buffer = attrib.buffer.get(); ASSERT(buffer || attrib.pointer); + ASSERT(attrib.enabled); - BufferD3D *storage = buffer ? GetImplAs(buffer) : NULL; - StaticVertexBufferInterface *staticBuffer = storage ? storage->getStaticVertexBuffer() : NULL; - VertexBufferInterface *vertexBuffer = staticBuffer ? staticBuffer : static_cast(mStreamingBuffer); - bool directStorage = vertexBuffer->directStoragePossible(attrib, currentValue); - - unsigned int streamOffset = 0; - unsigned int outputElementSize = 0; + BufferD3D *storage = buffer ? GetImplAs(buffer) : nullptr; // Instanced vertices do not apply the 'start' offset - GLint firstVertexIndex = (instances > 0 && attrib.divisor > 0 ? 0 : start); + GLint firstVertexIndex = (attrib.divisor > 0 ? 0 : start); + + // Compute source data pointer + const uint8_t *sourceData = nullptr; - if (directStorage) + if (buffer) { - outputElementSize = ComputeVertexAttributeStride(attrib); - streamOffset = static_cast(attrib.offset + outputElementSize * firstVertexIndex); + ANGLE_TRY(storage->getData(&sourceData)); + sourceData += static_cast(attrib.offset); } - else if (staticBuffer) + else { - gl::Error error = staticBuffer->getVertexBuffer()->getSpaceRequired(attrib, 1, 0, &outputElementSize); - if (error.isError()) - { - return error; - } + sourceData = static_cast(attrib.pointer); + } - if (!staticBuffer->lookupAttribute(attrib, &streamOffset)) - { - // Convert the entire buffer - int totalCount = ElementsInBuffer(attrib, storage->getSize()); - int startIndex = attrib.offset / ComputeVertexAttributeStride(attrib); + unsigned int streamOffset = 0; - error = staticBuffer->storeVertexAttributes(attrib, currentValue, -startIndex, totalCount, - 0, &streamOffset); - if (error.isError()) - { - return error; - } - } + translated->storage = nullptr; + ANGLE_TRY_RESULT(mFactory->getVertexSpaceRequired(attrib, 1, 0), translated->stride); - unsigned int firstElementOffset = (attrib.offset / ComputeVertexAttributeStride(attrib)) * outputElementSize; - unsigned int startOffset = (instances == 0 || attrib.divisor == 0) ? firstVertexIndex * outputElementSize : 0; - if (streamOffset + firstElementOffset + startOffset < streamOffset) - { - return gl::Error(GL_OUT_OF_MEMORY); - } + size_t totalCount = ComputeVertexAttributeElementCount(attrib, count, instances); + + ANGLE_TRY(mStreamingBuffer->storeDynamicAttribute( + attrib, translated->currentValueType, firstVertexIndex, static_cast(totalCount), + instances, &streamOffset, sourceData)); - streamOffset += firstElementOffset + startOffset; + VertexBuffer *vertexBuffer = mStreamingBuffer->getVertexBuffer(); + + translated->vertexBuffer.set(vertexBuffer); + translated->serial = vertexBuffer->getSerial(); + translated->baseOffset = streamOffset; + translated->usesFirstVertexOffset = false; + + return gl::NoError(); +} + +gl::Error VertexDataManager::storeCurrentValue(const gl::VertexAttribCurrentValueData ¤tValue, + TranslatedAttribute *translated, + size_t attribIndex) +{ + CurrentValueState *cachedState = &mCurrentValueCache[attribIndex]; + auto *&buffer = cachedState->buffer; + + if (!buffer) + { + buffer = new StreamingVertexBufferInterface(mFactory, CONSTANT_VERTEX_BUFFER_SIZE); } - else + + if (cachedState->data != currentValue) { - int totalCount = StreamingBufferElementCount(attrib, count, instances); - gl::Error error = mStreamingBuffer->getVertexBuffer()->getSpaceRequired(attrib, 1, 0, &outputElementSize); - if (error.isError()) - { - return error; - } + const gl::VertexAttribute &attrib = *translated->attribute; - error = mStreamingBuffer->storeVertexAttributes(attrib, currentValue, firstVertexIndex, - totalCount, instances, &streamOffset); - if (error.isError()) - { - return error; - } + ANGLE_TRY(buffer->reserveVertexSpace(attrib, 1, 0)); + + const uint8_t *sourceData = reinterpret_cast(currentValue.FloatValues); + unsigned int streamOffset; + ANGLE_TRY(buffer->storeDynamicAttribute(attrib, currentValue.Type, 0, 1, 0, &streamOffset, + sourceData)); + + buffer->getVertexBuffer()->hintUnmapResource(); + + cachedState->data = currentValue; + cachedState->offset = streamOffset; } - translated->storage = directStorage ? storage : NULL; - translated->vertexBuffer = vertexBuffer->getVertexBuffer(); - translated->serial = directStorage ? storage->getSerial() : vertexBuffer->getSerial(); - translated->divisor = attrib.divisor; + translated->vertexBuffer.set(buffer->getVertexBuffer()); - translated->attribute = &attrib; - translated->currentValueType = currentValue.Type; - translated->stride = outputElementSize; - translated->offset = streamOffset; + translated->storage = nullptr; + translated->serial = buffer->getSerial(); + translated->divisor = 0; + translated->stride = 0; + translated->baseOffset = static_cast(cachedState->offset); + translated->usesFirstVertexOffset = false; - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -gl::Error VertexDataManager::storeCurrentValue(const gl::VertexAttribute &attrib, - const gl::VertexAttribCurrentValueData ¤tValue, - TranslatedAttribute *translated, - gl::VertexAttribCurrentValueData *cachedValue, - size_t *cachedOffset, - StreamingVertexBufferInterface *buffer) +// VertexBufferBinding implementation +VertexBufferBinding::VertexBufferBinding() : mBoundVertexBuffer(nullptr) { - if (*cachedValue != currentValue) +} + +VertexBufferBinding::VertexBufferBinding(const VertexBufferBinding &other) + : mBoundVertexBuffer(other.mBoundVertexBuffer) +{ + if (mBoundVertexBuffer) { - gl::Error error = buffer->reserveVertexSpace(attrib, 1, 0); - if (error.isError()) - { - return error; - } + mBoundVertexBuffer->addRef(); + } +} - unsigned int streamOffset; - error = buffer->storeVertexAttributes(attrib, currentValue, 0, 1, 0, &streamOffset); - if (error.isError()) - { - return error; - } +VertexBufferBinding::~VertexBufferBinding() +{ + if (mBoundVertexBuffer) + { + mBoundVertexBuffer->release(); + } +} - *cachedValue = currentValue; - *cachedOffset = streamOffset; +VertexBufferBinding &VertexBufferBinding::operator=(const VertexBufferBinding &other) +{ + mBoundVertexBuffer = other.mBoundVertexBuffer; + if (mBoundVertexBuffer) + { + mBoundVertexBuffer->addRef(); } + return *this; +} - translated->storage = NULL; - translated->vertexBuffer = buffer->getVertexBuffer(); - translated->serial = buffer->getSerial(); - translated->divisor = 0; +void VertexBufferBinding::set(VertexBuffer *vertexBuffer) +{ + if (mBoundVertexBuffer == vertexBuffer) + return; - translated->attribute = &attrib; - translated->currentValueType = currentValue.Type; - translated->stride = 0; - translated->offset = *cachedOffset; + if (mBoundVertexBuffer) + { + mBoundVertexBuffer->release(); + } + if (vertexBuffer) + { + vertexBuffer->addRef(); + } - return gl::Error(GL_NO_ERROR); + mBoundVertexBuffer = vertexBuffer; } +VertexBuffer *VertexBufferBinding::get() const +{ + return mBoundVertexBuffer; } + +} // namespace rx diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/VertexDataManager.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/VertexDataManager.h index 898ed340b836..da46c7a87791 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/VertexDataManager.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/VertexDataManager.h @@ -10,9 +10,10 @@ #ifndef LIBANGLE_RENDERER_D3D_VERTEXDATAMANAGER_H_ #define LIBANGLE_RENDERER_D3D_VERTEXDATAMANAGER_H_ +#include "common/angleutils.h" +#include "libANGLE/angletypes.h" #include "libANGLE/Constants.h" #include "libANGLE/VertexAttribute.h" -#include "common/angleutils.h" namespace gl { @@ -28,68 +29,115 @@ 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() : active(false), attribute(NULL), currentValueType(GL_NONE), - offset(0), stride(0), vertexBuffer(NULL), storage(NULL), - serial(0), divisor(0) {}; + TranslatedAttribute(); + + // Computes the correct offset from baseOffset, usesFirstVertexOffset, stride and startVertex. + // Can throw an error on integer overflow. + gl::ErrorOrResult computeOffset(GLint startVertex) const; + bool active; const gl::VertexAttribute *attribute; GLenum currentValueType; - unsigned int offset; + unsigned int baseOffset; + bool usesFirstVertexOffset; unsigned int stride; // 0 means not to advance the read pointer at all - VertexBuffer *vertexBuffer; + 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::VertexAttribute &attrib); + class VertexDataManager : angle::NonCopyable { public: VertexDataManager(BufferFactoryD3D *factory); virtual ~VertexDataManager(); - gl::Error prepareVertexData(const gl::State &state, GLint start, GLsizei count, - TranslatedAttribute *outAttribs, GLsizei instances); + gl::Error prepareVertexData(const gl::State &state, + GLint start, + GLsizei count, + std::vector *translatedAttribs, + GLsizei instances); - private: - gl::Error reserveSpaceForAttrib(const gl::VertexAttribute &attrib, - const gl::VertexAttribCurrentValueData ¤tValue, - GLsizei count, - GLsizei instances) const; + static void StoreDirectAttrib(TranslatedAttribute *directAttrib); - void invalidateMatchingStaticData(const gl::VertexAttribute &attrib, - const gl::VertexAttribCurrentValueData ¤tValue) const; + static gl::Error StoreStaticAttrib(TranslatedAttribute *translated, + GLsizei count, + GLsizei instances); - gl::Error storeAttribute(const gl::VertexAttribute &attrib, - const gl::VertexAttribCurrentValueData ¤tValue, - TranslatedAttribute *translated, - GLint start, - GLsizei count, - GLsizei instances); + gl::Error storeDynamicAttribs(std::vector *translatedAttribs, + const gl::AttributesMask &dynamicAttribsMask, + GLint start, + GLsizei count, + GLsizei instances); - gl::Error storeCurrentValue(const gl::VertexAttribute &attrib, - const gl::VertexAttribCurrentValueData ¤tValue, + // Promote static usage of dynamic buffers. + static void PromoteDynamicAttribs(const std::vector &translatedAttribs, + const gl::AttributesMask &dynamicAttribsMask, + GLsizei count); + + gl::Error storeCurrentValue(const gl::VertexAttribCurrentValueData ¤tValue, TranslatedAttribute *translated, - gl::VertexAttribCurrentValueData *cachedValue, - size_t *cachedOffset, - StreamingVertexBufferInterface *buffer); + size_t attribIndex); - void hintUnmapAllResources(const std::vector &vertexAttributes); + private: + struct CurrentValueState + { + CurrentValueState(); + ~CurrentValueState(); - BufferFactoryD3D *const mFactory; + StreamingVertexBufferInterface *buffer; + gl::VertexAttribCurrentValueData data; + size_t offset; + }; - StreamingVertexBufferInterface *mStreamingBuffer; + gl::Error reserveSpaceForAttrib(const TranslatedAttribute &translatedAttrib, + GLsizei count, + GLsizei instances) const; - gl::VertexAttribCurrentValueData mCurrentValue[gl::MAX_VERTEX_ATTRIBS]; + gl::Error storeDynamicAttrib(TranslatedAttribute *translated, + GLint start, + GLsizei count, + GLsizei instances); - StreamingVertexBufferInterface *mCurrentValueBuffer[gl::MAX_VERTEX_ATTRIBS]; - std::size_t mCurrentValueOffsets[gl::MAX_VERTEX_ATTRIBS]; + BufferFactoryD3D *const mFactory; + + StreamingVertexBufferInterface *mStreamingBuffer; + std::vector mCurrentValueCache; + gl::AttributesMask mDynamicAttribsMaskCache; }; -} +} // namespace rx #endif // LIBANGLE_RENDERER_D3D_VERTEXDATAMANAGER_H_ diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/WorkaroundsD3D.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/WorkaroundsD3D.h new file mode 100644 index 000000000000..58f65f6496b4 --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/WorkaroundsD3D.h @@ -0,0 +1,66 @@ +// +// Copyright (c) 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. +// + +// WorkaroundsD3D.h: Workarounds for D3D driver bugs and other issues. + +#ifndef LIBANGLE_RENDERER_D3D_WORKAROUNDSD3D_H_ +#define LIBANGLE_RENDERER_D3D_WORKAROUNDSD3D_H_ + +// TODO(jmadill,zmo,geofflang): make a workarounds library that can operate +// independent of ANGLE's renderer. Workarounds should also be accessible +// outside of the Renderer. + +namespace rx +{ +struct D3DCompilerWorkarounds +{ + D3DCompilerWorkarounds() + : skipOptimization(false), useMaxOptimization(false), enableIEEEStrictness(false) + { + } + + bool skipOptimization; + bool useMaxOptimization; + + // IEEE strictness needs to be enabled for NANs to work. + bool enableIEEEStrictness; +}; + +struct WorkaroundsD3D +{ + WorkaroundsD3D() + : mrtPerfWorkaround(false), + setDataFasterThanImageUpload(false), + zeroMaxLodWorkaround(false), + useInstancedPointSpriteEmulation(false) + { + } + + // On some systems, having extra rendertargets than necessary slows down the shader. + // We can fix this by optimizing those out of the shader. At the same time, we can + // work around a bug on some nVidia drivers that they ignore "null" render targets + // in D3D11, by compacting the active color attachments list to omit null entries. + bool mrtPerfWorkaround; + + bool setDataFasterThanImageUpload; + + // Some renderers can't disable mipmaps on a mipmapped texture (i.e. solely sample from level + // zero, and ignore the other levels). D3D11 Feature Level 10+ does this by setting MaxLOD to + // 0.0f in the Sampler state. D3D9 sets D3DSAMP_MIPFILTER to D3DTEXF_NONE. There is no + // equivalent to this in D3D11 Feature Level 9_3. This causes problems when (for example) an + // application creates a mipmapped texture2D, but sets GL_TEXTURE_MIN_FILTER to GL_NEAREST + // (i.e disables mipmaps). To work around this, D3D11 FL9_3 has to create two copies of the + // texture. The textures' level zeros are identical, but only one texture has mips. + bool zeroMaxLodWorkaround; + + // Some renderers do not support Geometry Shaders so the Geometry Shader-based PointSprite + // emulation will not work. To work around this, D3D11 FL9_3 has to use a different pointsprite + // emulation that is implemented using instanced quads. + bool useInstancedPointSpriteEmulation; +}; +} + +#endif // LIBANGLE_RENDERER_D3D_WORKAROUNDSD3D_H_ diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/Blit11.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/Blit11.cpp index a20012b0b7cd..0598fb1a03b6 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/Blit11.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/Blit11.cpp @@ -99,15 +99,15 @@ ID3D11Resource *CreateStagingTexture(ID3D11Device *device, ID3D11DeviceContext * stagingDesc.MiscFlags = 0; stagingDesc.BindFlags = 0; - ID3D11Texture2D *stagingTexture = NULL; - HRESULT result = device->CreateTexture2D(&stagingDesc, NULL, &stagingTexture); + ID3D11Texture2D *stagingTexture = nullptr; + HRESULT result = device->CreateTexture2D(&stagingDesc, nullptr, &stagingTexture); if (FAILED(result)) { ERR("Failed to create staging texture for depth stencil blit. HRESULT: 0x%X.", result); - return NULL; + return nullptr; } - context->CopySubresourceRegion(stagingTexture, 0, 0, 0, 0, source, subresource, NULL); + context->CopySubresourceRegion(stagingTexture, 0, 0, 0, 0, source, subresource, nullptr); return stagingTexture; } @@ -196,40 +196,114 @@ inline unsigned int GetSwizzleIndex(GLenum swizzle) 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 }, +}; + } // namespace Blit11::Blit11(Renderer11 *renderer) : mRenderer(renderer), - mVertexBuffer(NULL), - mPointSampler(NULL), - mLinearSampler(NULL), - mScissorEnabledRasterizerState(NULL), - mScissorDisabledRasterizerState(NULL), - mDepthStencilState(NULL), - mQuad2DIL(NULL), - mQuad2DVS(NULL), - mDepthPS(NULL), - mQuad3DIL(NULL), - mQuad3DVS(NULL), - mQuad3DGS(NULL), - mSwizzleCB(NULL) + mResourcesInitialized(false), + mVertexBuffer(nullptr), + mPointSampler(nullptr), + mLinearSampler(nullptr), + mScissorEnabledRasterizerState(nullptr), + mScissorDisabledRasterizerState(nullptr), + mDepthStencilState(nullptr), + 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(nullptr) +{ +} + +Blit11::~Blit11() +{ + freeResources(); + + mQuad2DIL.release(); + mQuad2DVS.release(); + mDepthPS.release(); + + mQuad3DIL.release(); + mQuad3DVS.release(); + mQuad3DGS.release(); + + clearShaderMap(); +} + +gl::Error Blit11::initResources() { - TRACE_EVENT0("gpu.angle", "Blit11::Blit11"); + if (mResourcesInitialized) + { + return gl::Error(GL_NO_ERROR); + } + + TRACE_EVENT0("gpu.angle", "Blit11::initResources"); HRESULT result; ID3D11Device *device = mRenderer->getDevice(); D3D11_BUFFER_DESC vbDesc; - vbDesc.ByteWidth = std::max(sizeof(d3d11::PositionLayerTexCoord3DVertex), sizeof(d3d11::PositionTexCoordVertex)) * - 6 * renderer->getRendererCaps().max3DTextureSize; + vbDesc.ByteWidth = + static_cast(std::max(sizeof(d3d11::PositionLayerTexCoord3DVertex), + sizeof(d3d11::PositionTexCoordVertex)) * + 6 * mRenderer->getRendererCaps().max3DTextureSize); vbDesc.Usage = D3D11_USAGE_DYNAMIC; vbDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; vbDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; vbDesc.MiscFlags = 0; vbDesc.StructureByteStride = 0; - result = device->CreateBuffer(&vbDesc, NULL, &mVertexBuffer); + result = device->CreateBuffer(&vbDesc, nullptr, &mVertexBuffer); ASSERT(SUCCEEDED(result)); + if (FAILED(result)) + { + freeResources(); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to create blit vertex buffer, HRESULT: 0x%X", + result); + } d3d11::SetDebugName(mVertexBuffer, "Blit11 vertex buffer"); D3D11_SAMPLER_DESC pointSamplerDesc; @@ -249,6 +323,12 @@ Blit11::Blit11(Renderer11 *renderer) result = device->CreateSamplerState(&pointSamplerDesc, &mPointSampler); ASSERT(SUCCEEDED(result)); + if (FAILED(result)) + { + freeResources(); + return gl::Error(GL_OUT_OF_MEMORY, + "Failed to create blit point sampler state, HRESULT: 0x%X", result); + } d3d11::SetDebugName(mPointSampler, "Blit11 point sampler"); D3D11_SAMPLER_DESC linearSamplerDesc; @@ -268,6 +348,12 @@ Blit11::Blit11(Renderer11 *renderer) result = device->CreateSamplerState(&linearSamplerDesc, &mLinearSampler); ASSERT(SUCCEEDED(result)); + if (FAILED(result)) + { + freeResources(); + return gl::Error(GL_OUT_OF_MEMORY, + "Failed to create blit linear sampler state, HRESULT: 0x%X", result); + } d3d11::SetDebugName(mLinearSampler, "Blit11 linear sampler"); // Use a rasterizer state that will not cull so that inverted quads will not be culled @@ -285,11 +371,25 @@ Blit11::Blit11(Renderer11 *renderer) rasterDesc.ScissorEnable = TRUE; result = device->CreateRasterizerState(&rasterDesc, &mScissorEnabledRasterizerState); ASSERT(SUCCEEDED(result)); + if (FAILED(result)) + { + freeResources(); + return gl::Error(GL_OUT_OF_MEMORY, + "Failed to create blit scissoring rasterizer state, HRESULT: 0x%X", + result); + } d3d11::SetDebugName(mScissorEnabledRasterizerState, "Blit11 scissoring rasterizer state"); rasterDesc.ScissorEnable = FALSE; result = device->CreateRasterizerState(&rasterDesc, &mScissorDisabledRasterizerState); ASSERT(SUCCEEDED(result)); + if (FAILED(result)) + { + freeResources(); + return gl::Error(GL_OUT_OF_MEMORY, + "Failed to create blit no scissoring rasterizer state, HRESULT: 0x%X", + result); + } d3d11::SetDebugName(mScissorDisabledRasterizerState, "Blit11 no scissoring rasterizer state"); D3D11_DEPTH_STENCIL_DESC depthStencilDesc; @@ -310,47 +410,13 @@ Blit11::Blit11(Renderer11 *renderer) result = device->CreateDepthStencilState(&depthStencilDesc, &mDepthStencilState); ASSERT(SUCCEEDED(result)); - d3d11::SetDebugName(mDepthStencilState, "Blit11 depth stencil state"); - - 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 }, - }; - - result = device->CreateInputLayout(quad2DLayout, ArraySize(quad2DLayout), g_VS_Passthrough2D, ArraySize(g_VS_Passthrough2D), &mQuad2DIL); - ASSERT(SUCCEEDED(result)); - d3d11::SetDebugName(mQuad2DIL, "Blit11 2D input layout"); - - result = device->CreateVertexShader(g_VS_Passthrough2D, ArraySize(g_VS_Passthrough2D), NULL, &mQuad2DVS); - ASSERT(SUCCEEDED(result)); - d3d11::SetDebugName(mQuad2DVS, "Blit11 2D vertex shader"); - - if (renderer->isES3Capable()) + if (FAILED(result)) { - result = device->CreatePixelShader(g_PS_PassthroughDepth2D, ArraySize(g_PS_PassthroughDepth2D), NULL, &mDepthPS); - ASSERT(SUCCEEDED(result)); - d3d11::SetDebugName(mDepthPS, "Blit11 2D depth pixel shader"); - - 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 }, - }; - - result = device->CreateInputLayout(quad3DLayout, ArraySize(quad3DLayout), g_VS_Passthrough3D, ArraySize(g_VS_Passthrough3D), &mQuad3DIL); - ASSERT(SUCCEEDED(result)); - d3d11::SetDebugName(mQuad3DIL, "Blit11 3D input layout"); - - result = device->CreateVertexShader(g_VS_Passthrough3D, ArraySize(g_VS_Passthrough3D), NULL, &mQuad3DVS); - ASSERT(SUCCEEDED(result)); - d3d11::SetDebugName(mQuad3DVS, "Blit11 3D vertex shader"); - - result = device->CreateGeometryShader(g_GS_Passthrough3D, ArraySize(g_GS_Passthrough3D), NULL, &mQuad3DGS); - ASSERT(SUCCEEDED(result)); - d3d11::SetDebugName(mQuad3DGS, "Renderer11 copy 3D texture geometry shader"); + freeResources(); + return gl::Error(GL_OUT_OF_MEMORY, + "Failed to create blit depth stencil state, HRESULT: 0x%X", result); } + d3d11::SetDebugName(mDepthStencilState, "Blit11 depth stencil state"); D3D11_BUFFER_DESC swizzleBufferDesc; swizzleBufferDesc.ByteWidth = sizeof(unsigned int) * 4; @@ -360,12 +426,22 @@ Blit11::Blit11(Renderer11 *renderer) swizzleBufferDesc.MiscFlags = 0; swizzleBufferDesc.StructureByteStride = 0; - result = device->CreateBuffer(&swizzleBufferDesc, NULL, &mSwizzleCB); + result = device->CreateBuffer(&swizzleBufferDesc, nullptr, &mSwizzleCB); ASSERT(SUCCEEDED(result)); + if (FAILED(result)) + { + freeResources(); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to create blit swizzle buffer, HRESULT: 0x%X", + result); + } d3d11::SetDebugName(mSwizzleCB, "Blit11 swizzle constant buffer"); + + mResourcesInitialized = true; + + return gl::Error(GL_NO_ERROR); } -Blit11::~Blit11() +void Blit11::freeResources() { SafeRelease(mVertexBuffer); SafeRelease(mPointSampler); @@ -373,24 +449,15 @@ Blit11::~Blit11() SafeRelease(mScissorEnabledRasterizerState); SafeRelease(mScissorDisabledRasterizerState); SafeRelease(mDepthStencilState); - - SafeRelease(mQuad2DIL); - SafeRelease(mQuad2DVS); - SafeRelease(mDepthPS); - - SafeRelease(mQuad3DIL); - SafeRelease(mQuad3DVS); - SafeRelease(mQuad3DGS); - SafeRelease(mSwizzleCB); - clearShaderMap(); + mResourcesInitialized = false; } // static -Blit11::BlitShaderType Blit11::GetBlitShaderType(GLenum destinationFormat, bool isSigned, bool is3D) +Blit11::BlitShaderType Blit11::GetBlitShaderType(GLenum destinationFormat, bool isSigned, ShaderDimension dimension) { - if (is3D) + if (dimension == SHADER_3D) { if (isSigned) { @@ -399,7 +466,7 @@ Blit11::BlitShaderType Blit11::GetBlitShaderType(GLenum destinationFormat, bool case GL_RGBA_INTEGER: return BLITSHADER_3D_RGBAI; case GL_RGB_INTEGER: return BLITSHADER_3D_RGBI; case GL_RG_INTEGER: return BLITSHADER_3D_RGI; - case GL_RED: return BLITSHADER_3D_RI; + case GL_RED_INTEGER: return BLITSHADER_3D_RI; default: UNREACHABLE(); return BLITSHADER_INVALID; @@ -434,7 +501,7 @@ Blit11::BlitShaderType Blit11::GetBlitShaderType(GLenum destinationFormat, bool case GL_RGBA_INTEGER: return BLITSHADER_2D_RGBAI; case GL_RGB_INTEGER: return BLITSHADER_2D_RGBI; case GL_RG_INTEGER: return BLITSHADER_2D_RGI; - case GL_RED: return BLITSHADER_2D_RI; + case GL_RED_INTEGER: return BLITSHADER_2D_RI; default: UNREACHABLE(); return BLITSHADER_INVALID; @@ -514,9 +581,44 @@ Blit11::SwizzleShaderType Blit11::GetSwizzleShaderType(GLenum type, D3D11_SRV_DI } } -gl::Error Blit11::swizzleTexture(ID3D11ShaderResourceView *source, ID3D11RenderTargetView *dest, const gl::Extents &size, - GLenum swizzleRed, GLenum swizzleGreen, GLenum swizzleBlue, GLenum swizzleAlpha) +Blit11::ShaderSupport Blit11::getShaderSupport(const Shader &shader) +{ + ID3D11Device *device = mRenderer->getDevice(); + ShaderSupport support; + + if (shader.dimension == SHADER_2D) + { + support.inputLayout = mQuad2DIL.resolve(device); + support.vertexShader = mQuad2DVS.resolve(device); + support.geometryShader = nullptr; + support.vertexWriteFunction = Write2DVertices; + } + else + { + ASSERT(shader.dimension == SHADER_3D); + support.inputLayout = mQuad3DIL.resolve(device); + support.vertexShader = mQuad3DVS.resolve(device); + support.geometryShader = mQuad3DGS.resolve(device); + support.vertexWriteFunction = Write3DVertices; + } + + return support; +} + +gl::Error Blit11::swizzleTexture(ID3D11ShaderResourceView *source, + ID3D11RenderTargetView *dest, + const gl::Extents &size, + GLenum swizzleRed, + GLenum swizzleGreen, + GLenum swizzleBlue, + GLenum swizzleAlpha) { + gl::Error error = initResources(); + if (error.isError()) + { + return error; + } + HRESULT result; ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); @@ -524,10 +626,26 @@ gl::Error Blit11::swizzleTexture(ID3D11ShaderResourceView *source, ID3D11RenderT source->GetDesc(&sourceSRVDesc); const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(sourceSRVDesc.Format); - const gl::InternalFormat &sourceFormatInfo = gl::GetInternalFormatInfo(dxgiFormatInfo.internalFormat); + GLenum componentType = dxgiFormatInfo.componentType; + 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 (sourceFormatInfo.componentType) + switch (componentType) { case GL_UNSIGNED_NORMALIZED: case GL_SIGNED_NORMALIZED: @@ -546,7 +664,7 @@ gl::Error Blit11::swizzleTexture(ID3D11ShaderResourceView *source, ID3D11RenderT } const Shader *shader = nullptr; - gl::Error error = getSwizzleShader(shaderType, sourceSRVDesc.ViewDimension, &shader); + error = getSwizzleShader(shaderType, sourceSRVDesc.ViewDimension, &shader); if (error.isError()) { return error; @@ -560,13 +678,15 @@ gl::Error Blit11::swizzleTexture(ID3D11ShaderResourceView *source, ID3D11RenderT return gl::Error(GL_OUT_OF_MEMORY, "Failed to map internal vertex buffer for swizzle, HRESULT: 0x%X.", result); } + const ShaderSupport &support = getShaderSupport(*shader); + UINT stride = 0; UINT startIdx = 0; UINT drawCount = 0; D3D11_PRIMITIVE_TOPOLOGY topology; gl::Box area(0, 0, 0, size.width, size.height, size.depth); - shader->mVertexWriteFunction(area, size, area, size, mappedResource.pData, &stride, &drawCount, &topology); + support.vertexWriteFunction(area, size, area, size, mappedResource.pData, &stride, &drawCount, &topology); deviceContext->Unmap(mVertexBuffer, 0); @@ -592,23 +712,24 @@ gl::Error Blit11::swizzleTexture(ID3D11ShaderResourceView *source, ID3D11RenderT deviceContext->PSSetConstantBuffers(0, 1, &mSwizzleCB); // Apply state - deviceContext->OMSetBlendState(NULL, NULL, 0xFFFFFFF); - deviceContext->OMSetDepthStencilState(NULL, 0xFFFFFFFF); + deviceContext->OMSetBlendState(nullptr, nullptr, 0xFFFFFFF); + deviceContext->OMSetDepthStencilState(nullptr, 0xFFFFFFFF); deviceContext->RSSetState(mScissorDisabledRasterizerState); // Apply shaders - deviceContext->IASetInputLayout(shader->mInputLayout); + deviceContext->IASetInputLayout(support.inputLayout); deviceContext->IASetPrimitiveTopology(topology); - deviceContext->VSSetShader(shader->mVertexShader, NULL, 0); + deviceContext->VSSetShader(support.vertexShader, nullptr, 0); - deviceContext->PSSetShader(shader->mPixelShader, NULL, 0); - deviceContext->GSSetShader(shader->mGeometryShader, NULL, 0); + deviceContext->PSSetShader(shader->pixelShader, nullptr, 0); + deviceContext->GSSetShader(support.geometryShader, nullptr, 0); // Unset the currently bound shader resource to avoid conflicts - mRenderer->setShaderResource(gl::SAMPLER_PIXEL, 0, NULL); + auto stateManager = mRenderer->getStateManager(); + stateManager->setShaderResource(gl::SAMPLER_PIXEL, 0, nullptr); // Apply render target - mRenderer->setOneTimeRenderTarget(dest); + stateManager->setOneTimeRenderTarget(dest, nullptr); // Set the viewport D3D11_VIEWPORT viewport; @@ -621,7 +742,7 @@ gl::Error Blit11::swizzleTexture(ID3D11ShaderResourceView *source, ID3D11RenderT deviceContext->RSSetViewports(1, &viewport); // Apply textures - mRenderer->setShaderResource(gl::SAMPLER_PIXEL, 0, source); + stateManager->setShaderResource(gl::SAMPLER_PIXEL, 0, source); // Apply samplers deviceContext->PSSetSamplers(0, 1, &mPointSampler); @@ -630,12 +751,10 @@ gl::Error Blit11::swizzleTexture(ID3D11ShaderResourceView *source, ID3D11RenderT deviceContext->Draw(drawCount, 0); // Unbind textures and render targets and vertex buffer - mRenderer->setShaderResource(gl::SAMPLER_PIXEL, 0, NULL); - - mRenderer->unapplyRenderTargets(); + stateManager->setShaderResource(gl::SAMPLER_PIXEL, 0, nullptr); UINT zero = 0; - ID3D11Buffer *const nullBuffer = NULL; + ID3D11Buffer *const nullBuffer = nullptr; deviceContext->IASetVertexBuffers(0, 1, &nullBuffer, &zero, &zero); mRenderer->markAllStateDirty(); @@ -643,10 +762,23 @@ gl::Error Blit11::swizzleTexture(ID3D11ShaderResourceView *source, ID3D11RenderT return gl::Error(GL_NO_ERROR); } -gl::Error Blit11::copyTexture(ID3D11ShaderResourceView *source, const gl::Box &sourceArea, const gl::Extents &sourceSize, - ID3D11RenderTargetView *dest, const gl::Box &destArea, const gl::Extents &destSize, - const gl::Rectangle *scissor, GLenum destFormat, GLenum filter) +gl::Error Blit11::copyTexture(ID3D11ShaderResourceView *source, + const gl::Box &sourceArea, + const gl::Extents &sourceSize, + ID3D11RenderTargetView *dest, + const gl::Box &destArea, + const gl::Extents &destSize, + const gl::Rectangle *scissor, + GLenum destFormat, + GLenum filter, + bool maskOffAlpha) { + gl::Error error = initResources(); + if (error.isError()) + { + return error; + } + HRESULT result; ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); @@ -656,18 +788,23 @@ gl::Error Blit11::copyTexture(ID3D11ShaderResourceView *source, const gl::Box &s source->GetDesc(&sourceSRVDesc); const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(sourceSRVDesc.Format); - const gl::InternalFormat &internalFormatInfo = gl::GetInternalFormatInfo(dxgiFormatInfo.internalFormat); + GLenum componentType = dxgiFormatInfo.componentType; + + ASSERT(componentType != GL_NONE); + ASSERT(componentType != GL_SIGNED_NORMALIZED); + bool isSigned = (componentType == GL_INT); - bool isSigned = (internalFormatInfo.componentType == GL_INT); - bool is3D = (sourceSRVDesc.ViewDimension == D3D11_SRV_DIMENSION_TEXTURE3D); + ShaderDimension dimension = (sourceSRVDesc.ViewDimension == D3D11_SRV_DIMENSION_TEXTURE3D) ? SHADER_3D : SHADER_2D; const Shader *shader = nullptr; - gl::Error error = getBlitShader(destFormat, isSigned, is3D, &shader); + error = getBlitShader(destFormat, isSigned, dimension, &shader); if (error.isError()) { return error; } + const ShaderSupport &support = getShaderSupport(*shader); + // Set vertices D3D11_MAPPED_SUBRESOURCE mappedResource; result = deviceContext->Map(mVertexBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource); @@ -681,8 +818,8 @@ gl::Error Blit11::copyTexture(ID3D11ShaderResourceView *source, const gl::Box &s UINT drawCount = 0; D3D11_PRIMITIVE_TOPOLOGY topology; - shader->mVertexWriteFunction(sourceArea, sourceSize, destArea, destSize, mappedResource.pData, - &stride, &drawCount, &topology); + support.vertexWriteFunction(sourceArea, sourceSize, destArea, destSize, mappedResource.pData, + &stride, &drawCount, &topology); deviceContext->Unmap(mVertexBuffer, 0); @@ -690,8 +827,17 @@ gl::Error Blit11::copyTexture(ID3D11ShaderResourceView *source, const gl::Box &s deviceContext->IASetVertexBuffers(0, 1, &mVertexBuffer, &stride, &startIdx); // Apply state - deviceContext->OMSetBlendState(NULL, NULL, 0xFFFFFFF); - deviceContext->OMSetDepthStencilState(NULL, 0xFFFFFFFF); + if (maskOffAlpha) + { + ID3D11BlendState *blendState = mAlphaMaskBlendState.resolve(mRenderer->getDevice()); + ASSERT(blendState); + deviceContext->OMSetBlendState(blendState, nullptr, 0xFFFFFFF); + } + else + { + deviceContext->OMSetBlendState(nullptr, nullptr, 0xFFFFFFF); + } + deviceContext->OMSetDepthStencilState(nullptr, 0xFFFFFFFF); if (scissor) { @@ -710,18 +856,19 @@ gl::Error Blit11::copyTexture(ID3D11ShaderResourceView *source, const gl::Box &s } // Apply shaders - deviceContext->IASetInputLayout(shader->mInputLayout); + deviceContext->IASetInputLayout(support.inputLayout); deviceContext->IASetPrimitiveTopology(topology); - deviceContext->VSSetShader(shader->mVertexShader, NULL, 0); + deviceContext->VSSetShader(support.vertexShader, nullptr, 0); - deviceContext->PSSetShader(shader->mPixelShader, NULL, 0); - deviceContext->GSSetShader(shader->mGeometryShader, NULL, 0); + deviceContext->PSSetShader(shader->pixelShader, nullptr, 0); + deviceContext->GSSetShader(support.geometryShader, nullptr, 0); // Unset the currently bound shader resource to avoid conflicts - mRenderer->setShaderResource(gl::SAMPLER_PIXEL, 0, NULL); + auto stateManager = mRenderer->getStateManager(); + stateManager->setShaderResource(gl::SAMPLER_PIXEL, 0, nullptr); // Apply render target - mRenderer->setOneTimeRenderTarget(dest); + stateManager->setOneTimeRenderTarget(dest, nullptr); // Set the viewport D3D11_VIEWPORT viewport; @@ -734,10 +881,10 @@ gl::Error Blit11::copyTexture(ID3D11ShaderResourceView *source, const gl::Box &s deviceContext->RSSetViewports(1, &viewport); // Apply textures - mRenderer->setShaderResource(gl::SAMPLER_PIXEL, 0, source); + stateManager->setShaderResource(gl::SAMPLER_PIXEL, 0, source); // Apply samplers - ID3D11SamplerState *sampler = NULL; + ID3D11SamplerState *sampler = nullptr; switch (filter) { case GL_NEAREST: sampler = mPointSampler; break; @@ -753,12 +900,10 @@ gl::Error Blit11::copyTexture(ID3D11ShaderResourceView *source, const gl::Box &s deviceContext->Draw(drawCount, 0); // Unbind textures and render targets and vertex buffer - mRenderer->setShaderResource(gl::SAMPLER_PIXEL, 0, NULL); - - mRenderer->unapplyRenderTargets(); + stateManager->setShaderResource(gl::SAMPLER_PIXEL, 0, nullptr); UINT zero = 0; - ID3D11Buffer *const nullBuffer = NULL; + ID3D11Buffer *const nullBuffer = nullptr; deviceContext->IASetVertexBuffers(0, 1, &nullBuffer, &zero, &zero); mRenderer->markAllStateDirty(); @@ -779,6 +924,12 @@ gl::Error Blit11::copyDepth(ID3D11ShaderResourceView *source, const gl::Box &sou ID3D11DepthStencilView *dest, const gl::Box &destArea, const gl::Extents &destSize, const gl::Rectangle *scissor) { + gl::Error error = initResources(); + if (error.isError()) + { + return error; + } + HRESULT result; ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); @@ -804,7 +955,7 @@ gl::Error Blit11::copyDepth(ID3D11ShaderResourceView *source, const gl::Box &sou deviceContext->IASetVertexBuffers(0, 1, &mVertexBuffer, &stride, &startIdx); // Apply state - deviceContext->OMSetBlendState(NULL, NULL, 0xFFFFFFF); + deviceContext->OMSetBlendState(nullptr, nullptr, 0xFFFFFFF); deviceContext->OMSetDepthStencilState(mDepthStencilState, 0xFFFFFFFF); if (scissor) @@ -823,19 +974,27 @@ gl::Error Blit11::copyDepth(ID3D11ShaderResourceView *source, const gl::Box &sou deviceContext->RSSetState(mScissorDisabledRasterizerState); } + ID3D11Device *device = mRenderer->getDevice(); + ID3D11VertexShader *quad2DVS = mQuad2DVS.resolve(device); + if (quad2DVS == nullptr) + { + return gl::Error(GL_INVALID_OPERATION, "Error compiling internal 2D blit vertex shader"); + } + // Apply shaders - deviceContext->IASetInputLayout(mQuad2DIL); + deviceContext->IASetInputLayout(mQuad2DIL.resolve(device)); deviceContext->IASetPrimitiveTopology(topology); - deviceContext->VSSetShader(mQuad2DVS, NULL, 0); + deviceContext->VSSetShader(quad2DVS, nullptr, 0); - deviceContext->PSSetShader(mDepthPS, NULL, 0); - deviceContext->GSSetShader(NULL, NULL, 0); + deviceContext->PSSetShader(mDepthPS.resolve(device), nullptr, 0); + deviceContext->GSSetShader(nullptr, nullptr, 0); // Unset the currently bound shader resource to avoid conflicts - mRenderer->setShaderResource(gl::SAMPLER_PIXEL, 0, NULL); + auto stateManager = mRenderer->getStateManager(); + stateManager->setShaderResource(gl::SAMPLER_PIXEL, 0, nullptr); // Apply render target - deviceContext->OMSetRenderTargets(0, NULL, dest); + stateManager->setOneTimeRenderTarget(nullptr, dest); // Set the viewport D3D11_VIEWPORT viewport; @@ -848,7 +1007,7 @@ gl::Error Blit11::copyDepth(ID3D11ShaderResourceView *source, const gl::Box &sou deviceContext->RSSetViewports(1, &viewport); // Apply textures - mRenderer->setShaderResource(gl::SAMPLER_PIXEL, 0, source); + stateManager->setShaderResource(gl::SAMPLER_PIXEL, 0, source); // Apply samplers deviceContext->PSSetSamplers(0, 1, &mPointSampler); @@ -857,12 +1016,10 @@ gl::Error Blit11::copyDepth(ID3D11ShaderResourceView *source, const gl::Box &sou deviceContext->Draw(drawCount, 0); // Unbind textures and render targets and vertex buffer - mRenderer->setShaderResource(gl::SAMPLER_PIXEL, 0, NULL); - - mRenderer->unapplyRenderTargets(); + stateManager->setShaderResource(gl::SAMPLER_PIXEL, 0, nullptr); UINT zero = 0; - ID3D11Buffer *const nullBuffer = NULL; + ID3D11Buffer *const nullBuffer = nullptr; deviceContext->IASetVertexBuffers(0, 1, &nullBuffer, &zero, &zero); mRenderer->markAllStateDirty(); @@ -883,6 +1040,12 @@ gl::Error Blit11::copyDepthStencil(ID3D11Resource *source, unsigned int sourceSu ID3D11Resource *dest, unsigned int destSubresource, const gl::Box &destArea, const gl::Extents &destSize, const gl::Rectangle *scissor, bool stencilOnly) { + gl::Error error = initResources(); + if (error.isError()) + { + return error; + } + ID3D11Device *device = mRenderer->getDevice(); ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); @@ -901,19 +1064,25 @@ gl::Error Blit11::copyDepthStencil(ID3D11Resource *source, unsigned int sourceSu DXGI_FORMAT format = GetTextureFormat(source); ASSERT(format == GetTextureFormat(dest)); - const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(format); - unsigned int pixelSize = dxgiFormatInfo.pixelBytes; + const d3d11::DXGIFormatSize &dxgiFormatSizeInfo = d3d11::GetDXGIFormatSizeInfo(format); + unsigned int pixelSize = dxgiFormatSizeInfo.pixelBytes; unsigned int copyOffset = 0; unsigned int copySize = pixelSize; if (stencilOnly) { - copyOffset = dxgiFormatInfo.depthBits / 8; - copySize = dxgiFormatInfo.stencilBits / 8; - - // It would be expensive to have non-byte sized stencil sizes since it would - // require reading from the destination, currently there aren't any though. - ASSERT(dxgiFormatInfo.stencilBits % 8 == 0 && - dxgiFormatInfo.depthBits % 8 == 0); + const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(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((dxgiFormatInfo.redBits != 0) != (dxgiFormatInfo.depthBits != 0)); + GLuint depthBits = dxgiFormatInfo.redBits + dxgiFormatInfo.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; } D3D11_MAPPED_SUBRESOURCE sourceMapping; @@ -999,14 +1168,14 @@ gl::Error Blit11::copyDepthStencil(ID3D11Resource *source, unsigned int sourceSu // HACK: Use ID3D11DevicContext::UpdateSubresource which causes an extra copy compared to ID3D11DevicContext::CopySubresourceRegion // according to MSDN. - deviceContext->UpdateSubresource(dest, destSubresource, NULL, destMapping.pData, destMapping.RowPitch, destMapping.DepthPitch); + deviceContext->UpdateSubresource(dest, destSubresource, nullptr, destMapping.pData, destMapping.RowPitch, destMapping.DepthPitch); deviceContext->Unmap(sourceStaging, 0); deviceContext->Unmap(destStaging, 0); // TODO: Determine why this call to ID3D11DevicContext::CopySubresourceRegion causes a TDR timeout on some // systems when called repeatedly. - // deviceContext->CopySubresourceRegion(dest, destSubresource, 0, 0, 0, destStaging, 0, NULL); + // deviceContext->CopySubresourceRegion(dest, destSubresource, 0, 0, 0, destStaging, 0, nullptr); SafeRelease(sourceStaging); SafeRelease(destStaging); @@ -1014,57 +1183,26 @@ gl::Error Blit11::copyDepthStencil(ID3D11Resource *source, unsigned int sourceSu return gl::Error(GL_NO_ERROR); } -void Blit11::add2DBlitShaderToMap(BlitShaderType blitShaderType, ID3D11PixelShader *ps) +void Blit11::addBlitShaderToMap(BlitShaderType blitShaderType, ShaderDimension dimension, ID3D11PixelShader *ps) { ASSERT(mBlitShaderMap.find(blitShaderType) == mBlitShaderMap.end()); ASSERT(ps); Shader shader; - shader.mVertexWriteFunction = Write2DVertices; - shader.mInputLayout = mQuad2DIL; - shader.mVertexShader = mQuad2DVS; - shader.mGeometryShader = NULL; - shader.mPixelShader = ps; + shader.dimension = dimension; + shader.pixelShader = ps; mBlitShaderMap[blitShaderType] = shader; } -void Blit11::add3DBlitShaderToMap(BlitShaderType blitShaderType, ID3D11PixelShader *ps) -{ - ASSERT(mBlitShaderMap.find(blitShaderType) == mBlitShaderMap.end()); - ASSERT(ps); - - Shader shader; - shader.mVertexWriteFunction = Write3DVertices; - shader.mInputLayout = mQuad3DIL; - shader.mVertexShader = mQuad3DVS; - shader.mGeometryShader = mQuad3DGS; - shader.mPixelShader = ps; - - mBlitShaderMap[blitShaderType] = shader; -} - -void Blit11::addSwizzleShaderToMap(SwizzleShaderType swizzleShaderType, bool is2D, ID3D11PixelShader *ps) +void Blit11::addSwizzleShaderToMap(SwizzleShaderType swizzleShaderType, ShaderDimension dimension, ID3D11PixelShader *ps) { ASSERT(mSwizzleShaderMap.find(swizzleShaderType) == mSwizzleShaderMap.end()); ASSERT(ps); Shader shader; - if (is2D) - { - shader.mVertexWriteFunction = Write2DVertices; - shader.mInputLayout = mQuad2DIL; - shader.mVertexShader = mQuad2DVS; - shader.mGeometryShader = NULL; - } - else - { - shader.mVertexWriteFunction = Write3DVertices; - shader.mInputLayout = mQuad3DIL; - shader.mVertexShader = mQuad3DVS; - shader.mGeometryShader = mQuad3DGS; - } - shader.mPixelShader = ps; + shader.dimension = dimension; + shader.pixelShader = ps; mSwizzleShaderMap[swizzleShaderType] = shader; } @@ -1073,20 +1211,20 @@ void Blit11::clearShaderMap() { for (auto &blitShader : mBlitShaderMap) { - SafeRelease(blitShader.second.mPixelShader); + SafeRelease(blitShader.second.pixelShader); } mBlitShaderMap.clear(); for (auto &swizzleShader : mSwizzleShaderMap) { - SafeRelease(swizzleShader.second.mPixelShader); + SafeRelease(swizzleShader.second.pixelShader); } mSwizzleShaderMap.clear(); } -gl::Error Blit11::getBlitShader(GLenum destFormat, bool isSigned, bool is3D, const Shader **shader) +gl::Error Blit11::getBlitShader(GLenum destFormat, bool isSigned, ShaderDimension dimension, const Shader **shader) { - BlitShaderType blitShaderType = GetBlitShaderType(destFormat, isSigned, is3D); + BlitShaderType blitShaderType = GetBlitShaderType(destFormat, isSigned, dimension); if (blitShaderType == BLITSHADER_INVALID) { @@ -1100,107 +1238,107 @@ gl::Error Blit11::getBlitShader(GLenum destFormat, bool isSigned, bool is3D, con return gl::Error(GL_NO_ERROR); } - ASSERT(!is3D || mRenderer->isES3Capable()); + ASSERT(dimension == SHADER_2D || mRenderer->isES3Capable()); ID3D11Device *device = mRenderer->getDevice(); switch (blitShaderType) { case BLITSHADER_2D_RGBAF: - add2DBlitShaderToMap(blitShaderType, d3d11::CompilePS(device, g_PS_PassthroughRGBA2D, "Blit11 2D RGBA pixel shader")); + addBlitShaderToMap(blitShaderType, SHADER_2D, d3d11::CompilePS(device, g_PS_PassthroughRGBA2D, "Blit11 2D RGBA pixel shader")); break; case BLITSHADER_2D_BGRAF: - add2DBlitShaderToMap(blitShaderType, d3d11::CompilePS(device, g_PS_PassthroughRGBA2D, "Blit11 2D BGRA pixel shader")); + addBlitShaderToMap(blitShaderType, SHADER_2D, d3d11::CompilePS(device, g_PS_PassthroughRGBA2D, "Blit11 2D BGRA pixel shader")); break; case BLITSHADER_2D_RGBF: - add2DBlitShaderToMap(blitShaderType, d3d11::CompilePS(device, g_PS_PassthroughRGB2D, "Blit11 2D RGB pixel shader")); + addBlitShaderToMap(blitShaderType, SHADER_2D, d3d11::CompilePS(device, g_PS_PassthroughRGB2D, "Blit11 2D RGB pixel shader")); break; case BLITSHADER_2D_RGF: - add2DBlitShaderToMap(blitShaderType, d3d11::CompilePS(device, g_PS_PassthroughRG2D, "Blit11 2D RG pixel shader")); + addBlitShaderToMap(blitShaderType, SHADER_2D, d3d11::CompilePS(device, g_PS_PassthroughRG2D, "Blit11 2D RG pixel shader")); break; case BLITSHADER_2D_RF: - add2DBlitShaderToMap(blitShaderType, d3d11::CompilePS(device, g_PS_PassthroughR2D, "Blit11 2D R pixel shader")); + addBlitShaderToMap(blitShaderType, SHADER_2D, d3d11::CompilePS(device, g_PS_PassthroughR2D, "Blit11 2D R pixel shader")); break; case BLITSHADER_2D_ALPHA: - add2DBlitShaderToMap(blitShaderType, d3d11::CompilePS(device, g_PS_PassthroughRGBA2D, "Blit11 2D alpha pixel shader")); + addBlitShaderToMap(blitShaderType, SHADER_2D, d3d11::CompilePS(device, g_PS_PassthroughRGBA2D, "Blit11 2D alpha pixel shader")); break; case BLITSHADER_2D_LUMA: - add2DBlitShaderToMap(blitShaderType, d3d11::CompilePS(device, g_PS_PassthroughLum2D, "Blit11 2D lum pixel shader")); + addBlitShaderToMap(blitShaderType, SHADER_2D, d3d11::CompilePS(device, g_PS_PassthroughLum2D, "Blit11 2D lum pixel shader")); break; case BLITSHADER_2D_LUMAALPHA: - add2DBlitShaderToMap(blitShaderType, d3d11::CompilePS(device, g_PS_PassthroughLumAlpha2D, "Blit11 2D luminance alpha pixel shader")); + addBlitShaderToMap(blitShaderType, SHADER_2D, d3d11::CompilePS(device, g_PS_PassthroughLumAlpha2D, "Blit11 2D luminance alpha pixel shader")); break; case BLITSHADER_2D_RGBAUI: - add2DBlitShaderToMap(blitShaderType, d3d11::CompilePS(device, g_PS_PassthroughRGBA2DUI, "Blit11 2D RGBA UI pixel shader")); + addBlitShaderToMap(blitShaderType, SHADER_2D, d3d11::CompilePS(device, g_PS_PassthroughRGBA2DUI, "Blit11 2D RGBA UI pixel shader")); break; case BLITSHADER_2D_RGBAI: - add2DBlitShaderToMap(blitShaderType, d3d11::CompilePS(device, g_PS_PassthroughRGBA2DI, "Blit11 2D RGBA I pixel shader")); + addBlitShaderToMap(blitShaderType, SHADER_2D, d3d11::CompilePS(device, g_PS_PassthroughRGBA2DI, "Blit11 2D RGBA I pixel shader")); break; case BLITSHADER_2D_RGBUI: - add2DBlitShaderToMap(blitShaderType, d3d11::CompilePS(device, g_PS_PassthroughRGB2DUI, "Blit11 2D RGB UI pixel shader")); + addBlitShaderToMap(blitShaderType, SHADER_2D, d3d11::CompilePS(device, g_PS_PassthroughRGB2DUI, "Blit11 2D RGB UI pixel shader")); break; case BLITSHADER_2D_RGBI: - add2DBlitShaderToMap(blitShaderType, d3d11::CompilePS(device, g_PS_PassthroughRGB2DI, "Blit11 2D RGB I pixel shader")); + addBlitShaderToMap(blitShaderType, SHADER_2D, d3d11::CompilePS(device, g_PS_PassthroughRGB2DI, "Blit11 2D RGB I pixel shader")); break; case BLITSHADER_2D_RGUI: - add2DBlitShaderToMap(blitShaderType, d3d11::CompilePS(device, g_PS_PassthroughRG2DUI, "Blit11 2D RG UI pixel shader")); + addBlitShaderToMap(blitShaderType, SHADER_2D, d3d11::CompilePS(device, g_PS_PassthroughRG2DUI, "Blit11 2D RG UI pixel shader")); break; case BLITSHADER_2D_RGI: - add2DBlitShaderToMap(blitShaderType, d3d11::CompilePS(device, g_PS_PassthroughRG2DI, "Blit11 2D RG I pixel shader")); + addBlitShaderToMap(blitShaderType, SHADER_2D, d3d11::CompilePS(device, g_PS_PassthroughRG2DI, "Blit11 2D RG I pixel shader")); break; case BLITSHADER_2D_RUI: - add2DBlitShaderToMap(blitShaderType, d3d11::CompilePS(device, g_PS_PassthroughR2DUI, "Blit11 2D R UI pixel shader")); + addBlitShaderToMap(blitShaderType, SHADER_2D, d3d11::CompilePS(device, g_PS_PassthroughR2DUI, "Blit11 2D R UI pixel shader")); break; case BLITSHADER_2D_RI: - add2DBlitShaderToMap(blitShaderType, d3d11::CompilePS(device, g_PS_PassthroughR2DI, "Blit11 2D R I pixel shader")); + addBlitShaderToMap(blitShaderType, SHADER_2D, d3d11::CompilePS(device, g_PS_PassthroughR2DI, "Blit11 2D R I pixel shader")); break; case BLITSHADER_3D_RGBAF: - add3DBlitShaderToMap(blitShaderType, d3d11::CompilePS(device, g_PS_PassthroughRGBA3D, "Blit11 3D RGBA pixel shader")); + addBlitShaderToMap(blitShaderType, SHADER_3D, d3d11::CompilePS(device, g_PS_PassthroughRGBA3D, "Blit11 3D RGBA pixel shader")); break; case BLITSHADER_3D_RGBAUI: - add3DBlitShaderToMap(blitShaderType, d3d11::CompilePS(device, g_PS_PassthroughRGBA3DUI, "Blit11 3D UI RGBA pixel shader")); + addBlitShaderToMap(blitShaderType, SHADER_3D, d3d11::CompilePS(device, g_PS_PassthroughRGBA3DUI, "Blit11 3D UI RGBA pixel shader")); break; case BLITSHADER_3D_RGBAI: - add3DBlitShaderToMap(blitShaderType, d3d11::CompilePS(device, g_PS_PassthroughRGBA3DI, "Blit11 3D I RGBA pixel shader")); + addBlitShaderToMap(blitShaderType, SHADER_3D, d3d11::CompilePS(device, g_PS_PassthroughRGBA3DI, "Blit11 3D I RGBA pixel shader")); break; case BLITSHADER_3D_BGRAF: - add3DBlitShaderToMap(blitShaderType, d3d11::CompilePS(device, g_PS_PassthroughRGBA3D, "Blit11 3D BGRA pixel shader")); + addBlitShaderToMap(blitShaderType, SHADER_3D, d3d11::CompilePS(device, g_PS_PassthroughRGBA3D, "Blit11 3D BGRA pixel shader")); break; case BLITSHADER_3D_RGBF: - add3DBlitShaderToMap(blitShaderType, d3d11::CompilePS(device, g_PS_PassthroughRGB3D, "Blit11 3D RGB pixel shader")); + addBlitShaderToMap(blitShaderType, SHADER_3D, d3d11::CompilePS(device, g_PS_PassthroughRGB3D, "Blit11 3D RGB pixel shader")); break; case BLITSHADER_3D_RGBUI: - add3DBlitShaderToMap(blitShaderType, d3d11::CompilePS(device, g_PS_PassthroughRGB3DUI, "Blit11 3D RGB UI pixel shader")); + addBlitShaderToMap(blitShaderType, SHADER_3D, d3d11::CompilePS(device, g_PS_PassthroughRGB3DUI, "Blit11 3D RGB UI pixel shader")); break; case BLITSHADER_3D_RGBI: - add3DBlitShaderToMap(blitShaderType, d3d11::CompilePS(device, g_PS_PassthroughRGB3DI, "Blit11 3D RGB I pixel shader")); + addBlitShaderToMap(blitShaderType, SHADER_3D, d3d11::CompilePS(device, g_PS_PassthroughRGB3DI, "Blit11 3D RGB I pixel shader")); break; case BLITSHADER_3D_RGF: - add3DBlitShaderToMap(blitShaderType, d3d11::CompilePS(device, g_PS_PassthroughRG3D, "Blit11 3D RG pixel shader")); + addBlitShaderToMap(blitShaderType, SHADER_3D, d3d11::CompilePS(device, g_PS_PassthroughRG3D, "Blit11 3D RG pixel shader")); break; case BLITSHADER_3D_RGUI: - add3DBlitShaderToMap(blitShaderType, d3d11::CompilePS(device, g_PS_PassthroughRG3DUI, "Blit11 3D RG UI pixel shader")); + addBlitShaderToMap(blitShaderType, SHADER_3D, d3d11::CompilePS(device, g_PS_PassthroughRG3DUI, "Blit11 3D RG UI pixel shader")); break; case BLITSHADER_3D_RGI: - add3DBlitShaderToMap(blitShaderType, d3d11::CompilePS(device, g_PS_PassthroughRG3DI, "Blit11 3D RG I pixel shader")); + addBlitShaderToMap(blitShaderType, SHADER_3D, d3d11::CompilePS(device, g_PS_PassthroughRG3DI, "Blit11 3D RG I pixel shader")); break; case BLITSHADER_3D_RF: - add3DBlitShaderToMap(blitShaderType, d3d11::CompilePS(device, g_PS_PassthroughR3D, "Blit11 3D R pixel shader")); + addBlitShaderToMap(blitShaderType, SHADER_3D, d3d11::CompilePS(device, g_PS_PassthroughR3D, "Blit11 3D R pixel shader")); break; case BLITSHADER_3D_RUI: - add3DBlitShaderToMap(blitShaderType, d3d11::CompilePS(device, g_PS_PassthroughR3DUI, "Blit11 3D R UI pixel shader")); + addBlitShaderToMap(blitShaderType, SHADER_3D, d3d11::CompilePS(device, g_PS_PassthroughR3DUI, "Blit11 3D R UI pixel shader")); break; case BLITSHADER_3D_RI: - add3DBlitShaderToMap(blitShaderType, d3d11::CompilePS(device, g_PS_PassthroughR3DI, "Blit11 3D R I pixel shader")); + addBlitShaderToMap(blitShaderType, SHADER_3D, d3d11::CompilePS(device, g_PS_PassthroughR3DI, "Blit11 3D R I pixel shader")); break; case BLITSHADER_3D_ALPHA: - add3DBlitShaderToMap(blitShaderType, d3d11::CompilePS(device, g_PS_PassthroughRGBA3D, "Blit11 3D alpha pixel shader")); + addBlitShaderToMap(blitShaderType, SHADER_3D, d3d11::CompilePS(device, g_PS_PassthroughRGBA3D, "Blit11 3D alpha pixel shader")); break; case BLITSHADER_3D_LUMA: - add3DBlitShaderToMap(blitShaderType, d3d11::CompilePS(device, g_PS_PassthroughLum3D, "Blit11 3D luminance pixel shader")); + addBlitShaderToMap(blitShaderType, SHADER_3D, d3d11::CompilePS(device, g_PS_PassthroughLum3D, "Blit11 3D luminance pixel shader")); break; case BLITSHADER_3D_LUMAALPHA: - add3DBlitShaderToMap(blitShaderType, d3d11::CompilePS(device, g_PS_PassthroughLumAlpha3D, "Blit11 3D luminance alpha pixel shader")); + addBlitShaderToMap(blitShaderType, SHADER_3D, d3d11::CompilePS(device, g_PS_PassthroughLumAlpha3D, "Blit11 3D luminance alpha pixel shader")); break; default: UNREACHABLE(); @@ -1237,40 +1375,40 @@ gl::Error Blit11::getSwizzleShader(GLenum type, D3D11_SRV_DIMENSION viewDimensio switch (swizzleShaderType) { case SWIZZLESHADER_2D_FLOAT: - addSwizzleShaderToMap(swizzleShaderType, true, d3d11::CompilePS(device, g_PS_SwizzleF2D, "Blit11 2D F swizzle pixel shader")); + addSwizzleShaderToMap(swizzleShaderType, SHADER_2D, d3d11::CompilePS(device, g_PS_SwizzleF2D, "Blit11 2D F swizzle pixel shader")); break; case SWIZZLESHADER_2D_UINT: - addSwizzleShaderToMap(swizzleShaderType, true, d3d11::CompilePS(device, g_PS_SwizzleUI2D, "Blit11 2D UI swizzle pixel shader")); + addSwizzleShaderToMap(swizzleShaderType, SHADER_2D, d3d11::CompilePS(device, g_PS_SwizzleUI2D, "Blit11 2D UI swizzle pixel shader")); break; case SWIZZLESHADER_2D_INT: - addSwizzleShaderToMap(swizzleShaderType, true, d3d11::CompilePS(device, g_PS_SwizzleI2D, "Blit11 2D I swizzle pixel shader")); + addSwizzleShaderToMap(swizzleShaderType, SHADER_2D, d3d11::CompilePS(device, g_PS_SwizzleI2D, "Blit11 2D I swizzle pixel shader")); break; case SWIZZLESHADER_CUBE_FLOAT: - addSwizzleShaderToMap(swizzleShaderType, false, d3d11::CompilePS(device, g_PS_SwizzleF2DArray, "Blit11 2D Cube F swizzle pixel shader")); + addSwizzleShaderToMap(swizzleShaderType, SHADER_3D, d3d11::CompilePS(device, g_PS_SwizzleF2DArray, "Blit11 2D Cube F swizzle pixel shader")); break; case SWIZZLESHADER_CUBE_UINT: - addSwizzleShaderToMap(swizzleShaderType, false, d3d11::CompilePS(device, g_PS_SwizzleUI2DArray, "Blit11 2D Cube UI swizzle pixel shader")); + addSwizzleShaderToMap(swizzleShaderType, SHADER_3D, d3d11::CompilePS(device, g_PS_SwizzleUI2DArray, "Blit11 2D Cube UI swizzle pixel shader")); break; case SWIZZLESHADER_CUBE_INT: - addSwizzleShaderToMap(swizzleShaderType, false, d3d11::CompilePS(device, g_PS_SwizzleI2DArray, "Blit11 2D Cube I swizzle pixel shader")); + addSwizzleShaderToMap(swizzleShaderType, SHADER_3D, d3d11::CompilePS(device, g_PS_SwizzleI2DArray, "Blit11 2D Cube I swizzle pixel shader")); break; case SWIZZLESHADER_3D_FLOAT: - addSwizzleShaderToMap(swizzleShaderType, false, d3d11::CompilePS(device, g_PS_SwizzleF3D, "Blit11 3D F swizzle pixel shader")); + addSwizzleShaderToMap(swizzleShaderType, SHADER_3D, d3d11::CompilePS(device, g_PS_SwizzleF3D, "Blit11 3D F swizzle pixel shader")); break; case SWIZZLESHADER_3D_UINT: - addSwizzleShaderToMap(swizzleShaderType, false, d3d11::CompilePS(device, g_PS_SwizzleUI3D, "Blit11 3D UI swizzle pixel shader")); + addSwizzleShaderToMap(swizzleShaderType, SHADER_3D, d3d11::CompilePS(device, g_PS_SwizzleUI3D, "Blit11 3D UI swizzle pixel shader")); break; case SWIZZLESHADER_3D_INT: - addSwizzleShaderToMap(swizzleShaderType, false, d3d11::CompilePS(device, g_PS_SwizzleI3D, "Blit11 3D I swizzle pixel shader")); + addSwizzleShaderToMap(swizzleShaderType, SHADER_3D, d3d11::CompilePS(device, g_PS_SwizzleI3D, "Blit11 3D I swizzle pixel shader")); break; case SWIZZLESHADER_ARRAY_FLOAT: - addSwizzleShaderToMap(swizzleShaderType, false, d3d11::CompilePS(device, g_PS_SwizzleF2DArray, "Blit11 2D Array F swizzle pixel shader")); + addSwizzleShaderToMap(swizzleShaderType, SHADER_3D, d3d11::CompilePS(device, g_PS_SwizzleF2DArray, "Blit11 2D Array F swizzle pixel shader")); break; case SWIZZLESHADER_ARRAY_UINT: - addSwizzleShaderToMap(swizzleShaderType, false, d3d11::CompilePS(device, g_PS_SwizzleUI2DArray, "Blit11 2D Array UI swizzle pixel shader")); + addSwizzleShaderToMap(swizzleShaderType, SHADER_3D, d3d11::CompilePS(device, g_PS_SwizzleUI2DArray, "Blit11 2D Array UI swizzle pixel shader")); break; case SWIZZLESHADER_ARRAY_INT: - addSwizzleShaderToMap(swizzleShaderType, false, d3d11::CompilePS(device, g_PS_SwizzleI2DArray, "Blit11 2D Array I swizzle pixel shader")); + addSwizzleShaderToMap(swizzleShaderType, SHADER_3D, d3d11::CompilePS(device, g_PS_SwizzleI2DArray, "Blit11 2D Array I swizzle pixel shader")); break; default: UNREACHABLE(); diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/Blit11.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/Blit11.h index 478b5b0eb208..906616131ec1 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/Blit11.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/Blit11.h @@ -12,6 +12,7 @@ #include "common/angleutils.h" #include "libANGLE/angletypes.h" #include "libANGLE/Error.h" +#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h" #include @@ -28,9 +29,16 @@ class Blit11 : angle::NonCopyable gl::Error swizzleTexture(ID3D11ShaderResourceView *source, ID3D11RenderTargetView *dest, const gl::Extents &size, GLenum swizzleRed, GLenum swizzleGreen, GLenum swizzleBlue, GLenum swizzleAlpha); - gl::Error copyTexture(ID3D11ShaderResourceView *source, const gl::Box &sourceArea, const gl::Extents &sourceSize, - ID3D11RenderTargetView *dest, const gl::Box &destArea, const gl::Extents &destSize, - const gl::Rectangle *scissor, GLenum destFormat, GLenum filter); + gl::Error copyTexture(ID3D11ShaderResourceView *source, + const gl::Box &sourceArea, + const gl::Extents &sourceSize, + ID3D11RenderTargetView *dest, + const gl::Box &destArea, + const gl::Extents &destSize, + const gl::Rectangle *scissor, + GLenum destFormat, + GLenum filter, + bool maskOffAlpha); gl::Error copyStencil(ID3D11Resource *source, unsigned int sourceSubresource, const gl::Box &sourceArea, const gl::Extents &sourceSize, ID3D11Resource *dest, unsigned int destSubresource, const gl::Box &destArea, const gl::Extents &destSize, @@ -82,8 +90,6 @@ class Blit11 : angle::NonCopyable BLITSHADER_3D_LUMAALPHA, }; - static BlitShaderType GetBlitShaderType(GLenum destinationFormat, bool isSigned, bool is3D); - enum SwizzleShaderType { SWIZZLESHADER_INVALID, @@ -101,33 +107,49 @@ class Blit11 : angle::NonCopyable SWIZZLESHADER_ARRAY_INT, }; - static SwizzleShaderType GetSwizzleShaderType(GLenum type, D3D11_SRV_DIMENSION dimensionality); - - gl::Error copyDepthStencil(ID3D11Resource *source, unsigned int sourceSubresource, const gl::Box &sourceArea, const gl::Extents &sourceSize, - ID3D11Resource *dest, unsigned int destSubresource, const gl::Box &destArea, const gl::Extents &destSize, - const gl::Rectangle *scissor, bool stencilOnly); - 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_2D, + SHADER_3D, + }; + struct Shader { - WriteVertexFunction mVertexWriteFunction; - ID3D11InputLayout *mInputLayout; - ID3D11VertexShader *mVertexShader; - ID3D11GeometryShader *mGeometryShader; - ID3D11PixelShader *mPixelShader; + ShaderDimension dimension; + ID3D11PixelShader *pixelShader; + }; + + struct ShaderSupport + { + ID3D11InputLayout *inputLayout; + ID3D11VertexShader *vertexShader; + ID3D11GeometryShader *geometryShader; + WriteVertexFunction vertexWriteFunction; }; - void add2DBlitShaderToMap(BlitShaderType blitShaderType, ID3D11PixelShader *ps); - void add3DBlitShaderToMap(BlitShaderType blitShaderType, ID3D11PixelShader *ps); + gl::Error initResources(); + void freeResources(); + + ShaderSupport getShaderSupport(const Shader &shader); - gl::Error getBlitShader(GLenum destFormat, bool isSigned, bool is3D, const Shader **shaderOut); + static BlitShaderType GetBlitShaderType(GLenum destinationFormat, bool isSigned, ShaderDimension dimension); + static SwizzleShaderType GetSwizzleShaderType(GLenum type, D3D11_SRV_DIMENSION dimensionality); + + gl::Error copyDepthStencil(ID3D11Resource *source, unsigned int sourceSubresource, const gl::Box &sourceArea, const gl::Extents &sourceSize, + ID3D11Resource *dest, unsigned int destSubresource, const gl::Box &destArea, const gl::Extents &destSize, + const gl::Rectangle *scissor, bool stencilOnly); + + void addBlitShaderToMap(BlitShaderType blitShaderType, ShaderDimension dimension, ID3D11PixelShader *ps); + + gl::Error getBlitShader(GLenum destFormat, bool isSigned, ShaderDimension dimension, const Shader **shaderOut); gl::Error getSwizzleShader(GLenum type, D3D11_SRV_DIMENSION viewDimension, const Shader **shaderOut); - void addSwizzleShaderToMap(SwizzleShaderType swizzleShaderType, bool is2D, ID3D11PixelShader *ps); + void addSwizzleShaderToMap(SwizzleShaderType swizzleShaderType, ShaderDimension dimension, ID3D11PixelShader *ps); void clearShaderMap(); @@ -136,6 +158,7 @@ class Blit11 : angle::NonCopyable std::map mBlitShaderMap; std::map mSwizzleShaderMap; + bool mResourcesInitialized; ID3D11Buffer *mVertexBuffer; ID3D11SamplerState *mPointSampler; ID3D11SamplerState *mLinearSampler; @@ -143,13 +166,15 @@ class Blit11 : angle::NonCopyable ID3D11RasterizerState *mScissorDisabledRasterizerState; ID3D11DepthStencilState *mDepthStencilState; - ID3D11InputLayout *mQuad2DIL; - ID3D11VertexShader *mQuad2DVS; - ID3D11PixelShader *mDepthPS; + d3d11::LazyInputLayout mQuad2DIL; + d3d11::LazyShader mQuad2DVS; + d3d11::LazyShader mDepthPS; + + d3d11::LazyInputLayout mQuad3DIL; + d3d11::LazyShader mQuad3DVS; + d3d11::LazyShader mQuad3DGS; - ID3D11InputLayout *mQuad3DIL; - ID3D11VertexShader *mQuad3DVS; - ID3D11GeometryShader *mQuad3DGS; + d3d11::LazyBlendState mAlphaMaskBlendState; ID3D11Buffer *mSwizzleCB; }; diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/Buffer11.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/Buffer11.cpp index 100c9beb69b7..038753e3dca8 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/Buffer11.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/Buffer11.cpp @@ -8,39 +8,64 @@ #include "libANGLE/renderer/d3d/d3d11/Buffer11.h" +#include + #include "common/MemoryBuffer.h" +#include "libANGLE/renderer/d3d/IndexDataManager.h" +#include "libANGLE/renderer/d3d/VertexDataManager.h" #include "libANGLE/renderer/d3d/d3d11/Renderer11.h" +#include "libANGLE/renderer/d3d/d3d11/RenderTarget11.h" #include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h" #include "libANGLE/renderer/d3d/d3d11/formatutils11.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, +}; + +} // anonymous namespace + PackPixelsParams::PackPixelsParams() - : format(GL_NONE), - type(GL_NONE), - outputPitch(0), - packBuffer(NULL), - offset(0) -{} - -PackPixelsParams::PackPixelsParams(const gl::Rectangle &areaIn, GLenum formatIn, GLenum typeIn, GLuint outputPitchIn, - const gl::PixelPackState &packIn, ptrdiff_t offsetIn) - : area(areaIn), - format(formatIn), - type(typeIn), - outputPitch(outputPitchIn), - packBuffer(packIn.pixelBuffer.get()), - pack(packIn.alignment, packIn.reverseRowOrder), - offset(offsetIn) -{} + : format(GL_NONE), type(GL_NONE), outputPitch(0), packBuffer(nullptr), offset(0) +{ +} + +PackPixelsParams::PackPixelsParams(const gl::Rectangle &areaIn, + GLenum formatIn, + GLenum typeIn, + GLuint outputPitchIn, + const gl::PixelPackState &packIn, + ptrdiff_t offsetIn) + : area(areaIn), + format(formatIn), + type(typeIn), + outputPitch(outputPitchIn), + packBuffer(packIn.pixelBuffer.get()), + pack(packIn.alignment, packIn.reverseRowOrder), + offset(offsetIn) +{ +} namespace gl_d3d11 { D3D11_MAP GetD3DMapTypeFromBits(GLbitfield access) { - bool readBit = ((access & GL_MAP_READ_BIT) != 0); + bool readBit = ((access & GL_MAP_READ_BIT) != 0); bool writeBit = ((access & GL_MAP_WRITE_BIT) != 0); ASSERT(readBit || writeBit); @@ -66,8 +91,7 @@ D3D11_MAP GetD3DMapTypeFromBits(GLbitfield access) 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 @@ -86,11 +110,16 @@ class Buffer11::BufferStorage : angle::NonCopyable virtual bool isMappable() const = 0; - virtual bool copyFromStorage(BufferStorage *source, size_t sourceOffset, - size_t size, size_t destOffset) = 0; + virtual gl::ErrorOrResult copyFromStorage(BufferStorage *source, + size_t sourceOffset, + size_t size, + size_t destOffset) = 0; virtual gl::Error resize(size_t size, bool preserveData) = 0; - virtual uint8_t *map(size_t offset, size_t length, GLbitfield access) = 0; + virtual gl::Error map(size_t offset, + size_t length, + GLbitfield access, + uint8_t **mapPointerOut) = 0; virtual void unmap() = 0; gl::Error setData(const uint8_t *data, size_t offset, size_t size); @@ -109,24 +138,66 @@ class Buffer11::BufferStorage : angle::NonCopyable class Buffer11::NativeStorage : public Buffer11::BufferStorage { public: - NativeStorage(Renderer11 *renderer, BufferUsage usage); + NativeStorage(Renderer11 *renderer, BufferUsage usage, const NotificationSet *onStorageChanged); ~NativeStorage() override; bool isMappable() const override { return mUsage == BUFFER_USAGE_STAGING; } ID3D11Buffer *getNativeStorage() const { return mNativeStorage; } - - bool copyFromStorage(BufferStorage *source, size_t sourceOffset, - size_t size, size_t destOffset) override; + gl::ErrorOrResult copyFromStorage(BufferStorage *source, + size_t sourceOffset, + size_t size, + size_t destOffset) override; gl::Error resize(size_t size, bool preserveData) override; - uint8_t *map(size_t offset, size_t length, GLbitfield access) override; + gl::Error map(size_t offset, + size_t length, + GLbitfield access, + uint8_t **mapPointerOut) override; void unmap() override; private: - static void fillBufferDesc(D3D11_BUFFER_DESC* bufferDesc, Renderer11 *renderer, BufferUsage usage, unsigned int bufferSize); + static void fillBufferDesc(D3D11_BUFFER_DESC *bufferDesc, + Renderer11 *renderer, + BufferUsage usage, + unsigned int bufferSize); ID3D11Buffer *mNativeStorage; + const NotificationSet *mOnStorageChanged; +}; + +// 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 isMappable() const override { return true; } + + gl::ErrorOrResult getNativeStorage(SourceIndexData *indexInfo, + const TranslatedAttribute &attribute, + GLint startVertex); + + gl::ErrorOrResult copyFromStorage(BufferStorage *source, + size_t sourceOffset, + size_t size, + size_t destOffset) override; + + gl::Error resize(size_t size, bool preserveData) override; + + gl::Error map(size_t offset, + size_t length, + GLbitfield access, + uint8_t **mapPointerOut) override; + void unmap() override; + + private: + ID3D11Buffer *mNativeStorage; // contains expanded data for use by D3D + MemoryBuffer mMemoryBuffer; // original data (not expanded) + MemoryBuffer mIndicesMemoryBuffer; // indices data }; // Pack storage represents internal storage for pack buffers. We implement pack buffers @@ -138,24 +209,27 @@ class Buffer11::PackStorage : public Buffer11::BufferStorage ~PackStorage() override; bool isMappable() const override { return true; } - - bool copyFromStorage(BufferStorage *source, size_t sourceOffset, - size_t size, size_t destOffset) override; + gl::ErrorOrResult copyFromStorage(BufferStorage *source, + size_t sourceOffset, + size_t size, + size_t destOffset) override; gl::Error resize(size_t size, bool preserveData) override; - uint8_t *map(size_t offset, size_t length, GLbitfield access) override; + gl::Error map(size_t offset, + size_t length, + GLbitfield access, + uint8_t **mapPointerOut) override; void unmap() override; - gl::Error packPixels(ID3D11Texture2D *srcTexure, UINT srcSubresource, const PackPixelsParams ¶ms); + gl::Error packPixels(const gl::FramebufferAttachment &readAttachment, + const PackPixelsParams ¶ms); private: gl::Error flushQueuedPackCommand(); - ID3D11Texture2D *mStagingTexture; - DXGI_FORMAT mTextureFormat; - gl::Extents mTextureSize; + TextureHelper11 mStagingTexture; MemoryBuffer mMemoryBuffer; - PackPixelsParams *mQueuedPackCommand; + std::unique_ptr mQueuedPackCommand; PackPixelsParams mPackParams; bool mDataModified; }; @@ -170,12 +244,16 @@ class Buffer11::SystemMemoryStorage : public Buffer11::BufferStorage ~SystemMemoryStorage() override {} bool isMappable() const override { return true; } - - bool copyFromStorage(BufferStorage *source, size_t sourceOffset, - size_t size, size_t destOffset) override; + gl::ErrorOrResult copyFromStorage(BufferStorage *source, + size_t sourceOffset, + size_t size, + size_t destOffset) override; gl::Error resize(size_t size, bool preserveData) override; - uint8_t *map(size_t offset, size_t length, GLbitfield access) override; + gl::Error map(size_t offset, + size_t length, + GLbitfield access, + uint8_t **mapPointerOut) override; void unmap() override; MemoryBuffer *getSystemCopy() { return &mSystemCopy; } @@ -188,73 +266,54 @@ Buffer11::Buffer11(Renderer11 *renderer) : BufferD3D(renderer), mRenderer(renderer), mSize(0), - mMappedStorage(NULL), + mMappedStorage(nullptr), + mBufferStorages(BUFFER_USAGE_COUNT, nullptr), mConstantBufferStorageAdditionalSize(0), mMaxConstantBufferLruCount(0), - mReadUsageCount(0), - mHasSystemMemoryStorage(false) -{} + mReadUsageCount(0) +{ +} Buffer11::~Buffer11() { - for (auto &p : mBufferStorages) + for (auto &storage : mBufferStorages) { - SafeDelete(p.second); + SafeDelete(storage); } for (auto &p : mConstantBufferRangeStoragesCache) { SafeDelete(p.second.storage); } + + mRenderer->onBufferDelete(this); } gl::Error Buffer11::setData(const void *data, size_t size, GLenum usage) { - gl::Error error = setSubData(data, size, 0); - if (error.isError()) - { - return error; - } - - if (usage == GL_STATIC_DRAW) - { - initializeStaticData(); - } - - return error; + updateD3DBufferUsage(usage); + ANGLE_TRY(setSubData(data, size, 0)); + return gl::NoError(); } gl::Error Buffer11::getData(const uint8_t **outData) { SystemMemoryStorage *systemMemoryStorage = nullptr; - gl::Error error = getSystemMemoryStorage(&systemMemoryStorage); - - if (error.isError()) - { - *outData = nullptr; - return error; - } + ANGLE_TRY_RESULT(getSystemMemoryStorage(), systemMemoryStorage); mReadUsageCount = 0; ASSERT(systemMemoryStorage->getSize() >= mSize); *outData = systemMemoryStorage->getSystemCopy()->data(); - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -gl::Error Buffer11::getSystemMemoryStorage(SystemMemoryStorage **storageOut) +gl::ErrorOrResult Buffer11::getSystemMemoryStorage() { - BufferStorage *memStorageUntyped = getBufferStorage(BUFFER_USAGE_SYSTEM_MEMORY); - - if (memStorageUntyped == nullptr) - { - // TODO(jmadill): convert all to errors - return gl::Error(GL_OUT_OF_MEMORY); - } - - *storageOut = GetAs(memStorageUntyped); - return gl::Error(GL_NO_ERROR); + BufferStorage *storage = nullptr; + ANGLE_TRY_RESULT(getBufferStorage(BUFFER_USAGE_SYSTEM_MEMORY), storage); + return GetAs(storage); } gl::Error Buffer11::setSubData(const void *data, size_t size, size_t offset) @@ -268,23 +327,11 @@ gl::Error Buffer11::setSubData(const void *data, size_t size, size_t offset) BufferStorage *writeBuffer = nullptr; if (supportsDirectBinding()) { - writeBuffer = getStagingStorage(); - - if (!writeBuffer) - { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to allocate internal buffer."); - } + ANGLE_TRY_RESULT(getStagingStorage(), writeBuffer); } else { - SystemMemoryStorage *systemMemoryStorage = nullptr; - gl::Error error = getSystemMemoryStorage(&systemMemoryStorage); - if (error.isError()) - { - return error; - } - - writeBuffer = systemMemoryStorage; + ANGLE_TRY_RESULT(getSystemMemoryStorage(), writeBuffer); } ASSERT(writeBuffer); @@ -294,11 +341,7 @@ gl::Error Buffer11::setSubData(const void *data, size_t size, size_t offset) if (writeBuffer->getSize() < requiredSize) { bool preserveData = (offset > 0); - gl::Error error = writeBuffer->resize(requiredSize, preserveData); - if (error.isError()) - { - return error; - } + ANGLE_TRY(writeBuffer->resize(requiredSize, preserveData)); } writeBuffer->setData(static_cast(data), offset, size); @@ -308,21 +351,27 @@ gl::Error Buffer11::setSubData(const void *data, size_t size, size_t offset) mSize = std::max(mSize, requiredSize); invalidateStaticData(); - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -gl::Error Buffer11::copySubData(BufferImpl* source, GLintptr sourceOffset, GLintptr destOffset, GLsizeiptr size) +gl::Error Buffer11::copySubData(BufferImpl *source, + GLintptr sourceOffset, + GLintptr destOffset, + GLsizeiptr size) { Buffer11 *sourceBuffer = GetAs(source); - ASSERT(sourceBuffer != NULL); + ASSERT(sourceBuffer != nullptr); + + BufferStorage *copyDest = nullptr; + ANGLE_TRY_RESULT(getLatestBufferStorage(), copyDest); - BufferStorage *copyDest = getLatestBufferStorage(); if (!copyDest) { - copyDest = getStagingStorage(); + ANGLE_TRY_RESULT(getStagingStorage(), copyDest); } - BufferStorage *copySource = sourceBuffer->getLatestBufferStorage(); + BufferStorage *copySource = nullptr; + ANGLE_TRY_RESULT(sourceBuffer->getLatestBufferStorage(), copySource); if (!copySource || !copyDest) { @@ -333,11 +382,11 @@ gl::Error Buffer11::copySubData(BufferImpl* source, GLintptr sourceOffset, GLint // pack buffer partner, because other native buffers can't be mapped if (copyDest->getUsage() == BUFFER_USAGE_PIXEL_PACK && !copySource->isMappable()) { - copySource = sourceBuffer->getStagingStorage(); + ANGLE_TRY_RESULT(sourceBuffer->getStagingStorage(), copySource); } else if (copySource->getUsage() == BUFFER_USAGE_PIXEL_PACK && !copyDest->isMappable()) { - copyDest = getStagingStorage(); + ANGLE_TRY_RESULT(getStagingStorage(), copyDest); } // D3D11 does not allow overlapped copies until 11.1, and only if the @@ -347,21 +396,24 @@ gl::Error Buffer11::copySubData(BufferImpl* source, GLintptr sourceOffset, GLint { if (copySource->getUsage() == BUFFER_USAGE_STAGING) { - copySource = getBufferStorage(BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK); + ANGLE_TRY_RESULT(getBufferStorage(BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK), + copySource); } else { - copySource = getStagingStorage(); + ANGLE_TRY_RESULT(getStagingStorage(), copySource); } } - copyDest->copyFromStorage(copySource, sourceOffset, size, destOffset); + CopyResult copyResult = CopyResult::NOT_RECREATED; + ANGLE_TRY_RESULT(copyDest->copyFromStorage(copySource, sourceOffset, size, destOffset), + copyResult); copyDest->setDataRevision(copyDest->getDataRevision() + 1); mSize = std::max(mSize, destOffset + size); invalidateStaticData(); - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } gl::Error Buffer11::map(GLenum access, GLvoid **mapPtr) @@ -376,19 +428,20 @@ gl::Error Buffer11::mapRange(size_t offset, size_t length, GLbitfield access, GL { ASSERT(!mMappedStorage); - BufferStorage *latestStorage = getLatestBufferStorage(); - if (latestStorage && - (latestStorage->getUsage() == BUFFER_USAGE_PIXEL_PACK || - latestStorage->getUsage() == BUFFER_USAGE_STAGING)) + BufferStorage *latestStorage = nullptr; + ANGLE_TRY_RESULT(getLatestBufferStorage(), 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. - mMappedStorage = getStagingStorage(); + // Fall back to using the staging buffer if the latest storage does not exist or is not + // CPU-accessible. + ANGLE_TRY_RESULT(getStagingStorage(), mMappedStorage); } if (!mMappedStorage) @@ -400,33 +453,34 @@ gl::Error Buffer11::mapRange(size_t offset, size_t length, GLbitfield access, GL { // Update the data revision immediately, since the data might be changed at any time mMappedStorage->setDataRevision(mMappedStorage->getDataRevision() + 1); + invalidateStaticData(); } - uint8_t *mappedBuffer = mMappedStorage->map(offset, length, access); - if (!mappedBuffer) - { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to map internal buffer."); - } + uint8_t *mappedBuffer = nullptr; + ANGLE_TRY(mMappedStorage->map(offset, length, access, &mappedBuffer)); + ASSERT(mappedBuffer); *mapPtr = static_cast(mappedBuffer); - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } gl::Error Buffer11::unmap(GLboolean *result) { ASSERT(mMappedStorage); mMappedStorage->unmap(); - mMappedStorage = NULL; + mMappedStorage = nullptr; // TODO: detect if we had corruption. if so, return false. *result = GL_TRUE; - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -void Buffer11::markTransformFeedbackUsage() +gl::Error Buffer11::markTransformFeedbackUsage() { - BufferStorage *transformFeedbackStorage = getBufferStorage(BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK); + BufferStorage *transformFeedbackStorage = nullptr; + ANGLE_TRY_RESULT(getBufferStorage(BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK), + transformFeedbackStorage); if (transformFeedbackStorage) { @@ -434,78 +488,82 @@ void Buffer11::markTransformFeedbackUsage() } invalidateStaticData(); + return gl::NoError(); } -void Buffer11::markBufferUsage() +gl::Error Buffer11::markBufferUsage() { mReadUsageCount++; // Free the system memory storage if we decide it isn't being used very often. const unsigned int usageLimit = 5; - if (mReadUsageCount > usageLimit && mHasSystemMemoryStorage) + BufferStorage *&sysMemUsage = mBufferStorages[BUFFER_USAGE_SYSTEM_MEMORY]; + if (mReadUsageCount > usageLimit && sysMemUsage != nullptr) { - auto systemMemoryStorageIt = mBufferStorages.find(BUFFER_USAGE_SYSTEM_MEMORY); - ASSERT(systemMemoryStorageIt != mBufferStorages.end()); - - if (getLatestBufferStorage() != systemMemoryStorageIt->second) + BufferStorage *latestStorage = nullptr; + ANGLE_TRY_RESULT(getLatestBufferStorage(), latestStorage); + if (latestStorage != sysMemUsage) { - SafeDelete(systemMemoryStorageIt->second); - mBufferStorages.erase(systemMemoryStorageIt); - mHasSystemMemoryStorage = false; + SafeDelete(sysMemUsage); } } + + return gl::NoError(); } -ID3D11Buffer *Buffer11::getBuffer(BufferUsage usage) +gl::ErrorOrResult Buffer11::getBuffer(BufferUsage usage) { - markBufferUsage(); + ANGLE_TRY(markBufferUsage()); - BufferStorage *bufferStorage = getBufferStorage(usage); + BufferStorage *storage = nullptr; + ANGLE_TRY_RESULT(getBufferStorage(usage), storage); + return GetAs(storage)->getNativeStorage(); +} - if (!bufferStorage) - { - // Storage out-of-memory - return NULL; - } +gl::ErrorOrResult Buffer11::getEmulatedIndexedBuffer( + SourceIndexData *indexInfo, + const TranslatedAttribute &attribute, + GLint startVertex) +{ + ASSERT(indexInfo); - return GetAs(bufferStorage)->getNativeStorage(); + ANGLE_TRY(markBufferUsage()); + + BufferStorage *untypedStorage = nullptr; + ANGLE_TRY_RESULT(getBufferStorage(BUFFER_USAGE_EMULATED_INDEXED_VERTEX), untypedStorage); + + EmulatedIndexedStorage *emulatedStorage = GetAs(untypedStorage); + + ID3D11Buffer *nativeStorage = nullptr; + ANGLE_TRY_RESULT(emulatedStorage->getNativeStorage(indexInfo, attribute, startVertex), + nativeStorage); + + return nativeStorage; } -ID3D11Buffer *Buffer11::getConstantBufferRange(GLintptr offset, GLsizeiptr size) +gl::ErrorOrResult Buffer11::getConstantBufferRange(GLintptr offset, GLsizeiptr size) { - markBufferUsage(); + ANGLE_TRY(markBufferUsage()); - BufferStorage *bufferStorage; + BufferStorage *bufferStorage = nullptr; if (offset == 0) { - bufferStorage = getBufferStorage(BUFFER_USAGE_UNIFORM); + ANGLE_TRY_RESULT(getBufferStorage(BUFFER_USAGE_UNIFORM), bufferStorage); } else { - bufferStorage = getContantBufferRangeStorage(offset, size); - } - - if (!bufferStorage) - { - // Storage out-of-memory - return NULL; + ANGLE_TRY_RESULT(getConstantBufferRangeStorage(offset, size), bufferStorage); } return GetAs(bufferStorage)->getNativeStorage(); } -ID3D11ShaderResourceView *Buffer11::getSRV(DXGI_FORMAT srvFormat) +gl::ErrorOrResult Buffer11::getSRV(DXGI_FORMAT srvFormat) { - BufferStorage *storage = getBufferStorage(BUFFER_USAGE_PIXEL_UNPACK); - - if (!storage) - { - // Storage out-of-memory - return NULL; - } - + BufferStorage *storage = nullptr; + ANGLE_TRY_RESULT(getBufferStorage(BUFFER_USAGE_PIXEL_UNPACK), storage); ID3D11Buffer *buffer = GetAs(storage)->getNativeStorage(); auto bufferSRVIt = mBufferResourceViews.find(srvFormat); @@ -523,16 +581,17 @@ ID3D11ShaderResourceView *Buffer11::getSRV(DXGI_FORMAT srvFormat) } } - ID3D11Device *device = mRenderer->getDevice(); - ID3D11ShaderResourceView *bufferSRV = NULL; + ID3D11Device *device = mRenderer->getDevice(); + ID3D11ShaderResourceView *bufferSRV = nullptr; - const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(srvFormat); + const d3d11::DXGIFormatSize &dxgiFormatInfo = d3d11::GetDXGIFormatSizeInfo(srvFormat); D3D11_SHADER_RESOURCE_VIEW_DESC bufferSRVDesc; bufferSRVDesc.Buffer.ElementOffset = 0; - bufferSRVDesc.Buffer.ElementWidth = mSize / dxgiFormatInfo.pixelBytes; - bufferSRVDesc.ViewDimension = D3D11_SRV_DIMENSION_BUFFER; - bufferSRVDesc.Format = srvFormat; + bufferSRVDesc.Buffer.ElementWidth = + static_cast(mSize) / dxgiFormatInfo.pixelBytes; + bufferSRVDesc.ViewDimension = D3D11_SRV_DIMENSION_BUFFER; + bufferSRVDesc.Format = srvFormat; HRESULT result = device->CreateShaderResourceView(buffer, &bufferSRVDesc, &bufferSRV); UNUSED_ASSERTION_VARIABLE(result); @@ -543,84 +602,92 @@ ID3D11ShaderResourceView *Buffer11::getSRV(DXGI_FORMAT srvFormat) return bufferSRV; } -gl::Error Buffer11::packPixels(ID3D11Texture2D *srcTexture, UINT srcSubresource, const PackPixelsParams ¶ms) +gl::Error Buffer11::packPixels(const gl::FramebufferAttachment &readAttachment, + const PackPixelsParams ¶ms) { - PackStorage *packStorage = getPackStorage(); - BufferStorage *latestStorage = getLatestBufferStorage(); + PackStorage *packStorage = nullptr; + ANGLE_TRY_RESULT(getPackStorage(), packStorage); - if (packStorage) - { - gl::Error error = packStorage->packPixels(srcTexture, srcSubresource, params); - if (error.isError()) - { - return error; - } - packStorage->setDataRevision(latestStorage ? latestStorage->getDataRevision() + 1 : 1); - } + BufferStorage *latestStorage = nullptr; + ANGLE_TRY_RESULT(getLatestBufferStorage(), latestStorage); - return gl::Error(GL_NO_ERROR); + ASSERT(packStorage); + ANGLE_TRY(packStorage->packPixels(readAttachment, params)); + packStorage->setDataRevision(latestStorage ? latestStorage->getDataRevision() + 1 : 1); + + return gl::NoError(); } -Buffer11::BufferStorage *Buffer11::getBufferStorage(BufferUsage usage) +size_t Buffer11::getTotalCPUBufferMemoryBytes() const { - BufferStorage *newStorage = NULL; - auto directBufferIt = mBufferStorages.find(usage); - if (directBufferIt != mBufferStorages.end()) - { - newStorage = directBufferIt->second; - } + 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; +} + +gl::ErrorOrResult Buffer11::getBufferStorage(BufferUsage usage) +{ + ASSERT(0 <= usage && usage < BUFFER_USAGE_COUNT); + BufferStorage *&newStorage = mBufferStorages[usage]; if (!newStorage) { - if (usage == BUFFER_USAGE_PIXEL_PACK) - { - newStorage = new PackStorage(mRenderer); - } - else if (usage == BUFFER_USAGE_SYSTEM_MEMORY) - { - newStorage = new SystemMemoryStorage(mRenderer); - mHasSystemMemoryStorage = true; - } - else - { - // buffer is not allocated, create it - newStorage = new NativeStorage(mRenderer, usage); - } - - mBufferStorages.insert(std::make_pair(usage, newStorage)); + newStorage = allocateStorage(usage); } // resize buffer if (newStorage->getSize() < mSize) { - if (newStorage->resize(mSize, true).isError()) - { - // Out of memory error - return NULL; - } + ANGLE_TRY(newStorage->resize(mSize, true)); } - updateBufferStorage(newStorage, 0, mSize); + ANGLE_TRY(updateBufferStorage(newStorage, 0, mSize)); return newStorage; } -Buffer11::BufferStorage *Buffer11::getContantBufferRangeStorage(GLintptr offset, GLsizeiptr size) +Buffer11::BufferStorage *Buffer11::allocateStorage(BufferUsage usage) const +{ + 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_VERTEX_OR_TRANSFORM_FEEDBACK: + return new NativeStorage(mRenderer, usage, &mDirectBufferDirtyCallbacks); + default: + return new NativeStorage(mRenderer, usage, nullptr); + } +} + +gl::ErrorOrResult Buffer11::getConstantBufferRangeStorage( + GLintptr offset, + GLsizeiptr size) { 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. + // Keep the cacheEntry in a limited scope because it may be invalidated later in the code if + // we need to reclaim some space. ConstantBufferCacheEntry *cacheEntry = &mConstantBufferRangeStoragesCache[offset]; if (!cacheEntry->storage) { - cacheEntry->storage = new NativeStorage(mRenderer, BUFFER_USAGE_UNIFORM); + cacheEntry->storage = allocateStorage(BUFFER_USAGE_UNIFORM); cacheEntry->lruCount = ++mMaxConstantBufferLruCount; } cacheEntry->lruCount = ++mMaxConstantBufferLruCount; - newStorage = cacheEntry->storage; + newStorage = cacheEntry->storage; } if (newStorage->getSize() < static_cast(size)) @@ -631,11 +698,13 @@ Buffer11::BufferStorage *Buffer11::getContantBufferRangeStorage(GLintptr offset, while (mConstantBufferStorageAdditionalSize + sizeDelta > maximumAllowedAdditionalSize) { - auto iter = std::min_element(std::begin(mConstantBufferRangeStoragesCache), std::end(mConstantBufferRangeStoragesCache), - [](const ConstantBufferCache::value_type &a, const ConstantBufferCache::value_type &b) - { - return a.second.lruCount < b.second.lruCount; - }); + auto iter = std::min_element(std::begin(mConstantBufferRangeStoragesCache), + std::end(mConstantBufferRangeStoragesCache), + [](const ConstantBufferCache::value_type &a, + const ConstantBufferCache::value_type &b) + { + return a.second.lruCount < b.second.lruCount; + }); ASSERT(iter->second.storage != newStorage); ASSERT(mConstantBufferStorageAdditionalSize >= iter->second.storage->getSize()); @@ -645,27 +714,26 @@ Buffer11::BufferStorage *Buffer11::getContantBufferRangeStorage(GLintptr offset, mConstantBufferRangeStoragesCache.erase(iter); } - if (newStorage->resize(size, false).isError()) - { - // Out of memory error - return nullptr; - } - + ANGLE_TRY(newStorage->resize(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. + // 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); } - updateBufferStorage(newStorage, offset, size); - + ANGLE_TRY(updateBufferStorage(newStorage, offset, size)); return newStorage; } -void Buffer11::updateBufferStorage(BufferStorage *storage, size_t sourceOffset, size_t storageSize) +gl::Error Buffer11::updateBufferStorage(BufferStorage *storage, + size_t sourceOffset, + size_t storageSize) { - BufferStorage *latestBuffer = getLatestBufferStorage(); + BufferStorage *latestBuffer = nullptr; + ANGLE_TRY_RESULT(getLatestBufferStorage(), latestBuffer); + if (latestBuffer && latestBuffer->getDataRevision() > storage->getDataRevision()) { // Copy through a staging buffer if we're copying from or to a non-staging, mappable @@ -675,36 +743,43 @@ void Buffer11::updateBufferStorage(BufferStorage *storage, size_t sourceOffset, storage->getUsage() != BUFFER_USAGE_STAGING && (!latestBuffer->isMappable() || !storage->isMappable())) { - NativeStorage *stagingBuffer = getStagingStorage(); + NativeStorage *stagingBuffer = nullptr; + ANGLE_TRY_RESULT(getStagingStorage(), stagingBuffer); - stagingBuffer->copyFromStorage(latestBuffer, 0, latestBuffer->getSize(), 0); + CopyResult copyResult = CopyResult::NOT_RECREATED; + ANGLE_TRY_RESULT( + stagingBuffer->copyFromStorage(latestBuffer, 0, latestBuffer->getSize(), 0), + copyResult); stagingBuffer->setDataRevision(latestBuffer->getDataRevision()); latestBuffer = stagingBuffer; } - // if copyFromStorage returns true, the D3D buffer has been recreated - // and we should update our serial - if (storage->copyFromStorage(latestBuffer, sourceOffset, storageSize, 0)) + CopyResult copyResult = CopyResult::NOT_RECREATED; + ANGLE_TRY_RESULT(storage->copyFromStorage(latestBuffer, sourceOffset, storageSize, 0), + copyResult); + // If the D3D buffer has been recreated, we should update our serial. + if (copyResult == CopyResult::RECREATED) { updateSerial(); } storage->setDataRevision(latestBuffer->getDataRevision()); } + + return gl::NoError(); } -Buffer11::BufferStorage *Buffer11::getLatestBufferStorage() const +gl::ErrorOrResult Buffer11::getLatestBufferStorage() const { // Even though we iterate over all the direct buffers, it is expected that only // 1 or 2 will be present. - BufferStorage *latestStorage = NULL; + BufferStorage *latestStorage = nullptr; DataRevision latestRevision = 0; - for (auto it = mBufferStorages.begin(); it != mBufferStorages.end(); it++) + for (auto &storage : mBufferStorages) { - BufferStorage *storage = it->second; - if (!latestStorage || storage->getDataRevision() > latestRevision) + if (storage && (!latestStorage || storage->getDataRevision() > latestRevision)) { - latestStorage = storage; + latestStorage = storage; latestRevision = storage->getDataRevision(); } } @@ -712,39 +787,23 @@ Buffer11::BufferStorage *Buffer11::getLatestBufferStorage() const // resize buffer if (latestStorage && latestStorage->getSize() < mSize) { - if (latestStorage->resize(mSize, true).isError()) - { - // Out of memory error - return NULL; - } + ANGLE_TRY(latestStorage->resize(mSize, true)); } return latestStorage; } -Buffer11::NativeStorage *Buffer11::getStagingStorage() +gl::ErrorOrResult Buffer11::getStagingStorage() { - BufferStorage *stagingStorage = getBufferStorage(BUFFER_USAGE_STAGING); - - if (!stagingStorage) - { - // Out-of-memory - return NULL; - } - + BufferStorage *stagingStorage = nullptr; + ANGLE_TRY_RESULT(getBufferStorage(BUFFER_USAGE_STAGING), stagingStorage); return GetAs(stagingStorage); } -Buffer11::PackStorage *Buffer11::getPackStorage() +gl::ErrorOrResult Buffer11::getPackStorage() { - BufferStorage *packStorage = getBufferStorage(BUFFER_USAGE_PIXEL_PACK); - - if (!packStorage) - { - // Out-of-memory - return NULL; - } - + BufferStorage *packStorage = nullptr; + ANGLE_TRY_RESULT(getBufferStorage(BUFFER_USAGE_PIXEL_PACK), packStorage); return GetAs(packStorage); } @@ -752,15 +811,47 @@ bool Buffer11::supportsDirectBinding() const { // Do not support direct buffers for dynamic data. The streaming buffer // offers better performance for data which changes every frame. - // Check for absence of static buffer interfaces to detect dynamic data. - return (mStaticVertexBuffer && mStaticIndexBuffer); + return (mUsage == D3DBufferUsage::STATIC); +} + +void Buffer11::initializeStaticData() +{ + BufferD3D::initializeStaticData(); + + // Notify when static data changes. + mStaticBufferDirtyCallbacks.signal(); +} + +void Buffer11::invalidateStaticData() +{ + BufferD3D::invalidateStaticData(); + + // Notify when static data changes. + mStaticBufferDirtyCallbacks.signal(); +} + +void Buffer11::addStaticBufferDirtyCallback(const NotificationCallback *callback) +{ + mStaticBufferDirtyCallbacks.add(callback); +} + +void Buffer11::removeStaticBufferDirtyCallback(const NotificationCallback *callback) +{ + mStaticBufferDirtyCallbacks.remove(callback); +} + +void Buffer11::addDirectBufferDirtyCallback(const NotificationCallback *callback) +{ + mDirectBufferDirtyCallbacks.add(callback); +} + +void Buffer11::removeDirectBufferDirtyCallback(const NotificationCallback *callback) +{ + mDirectBufferDirtyCallbacks.remove(callback); } Buffer11::BufferStorage::BufferStorage(Renderer11 *renderer, BufferUsage usage) - : mRenderer(renderer), - mUsage(usage), - mRevision(0), - mBufferSize(0) + : mRenderer(renderer), mRevision(0), mUsage(usage), mBufferSize(0) { } @@ -768,22 +859,20 @@ gl::Error Buffer11::BufferStorage::setData(const uint8_t *data, size_t offset, s { ASSERT(isMappable()); - uint8_t *writePointer = map(offset, size, GL_MAP_WRITE_BIT); - if (!writePointer) - { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to map internal buffer."); - } + uint8_t *writePointer = nullptr; + ANGLE_TRY(map(offset, size, GL_MAP_WRITE_BIT, &writePointer)); memcpy(writePointer, data, size); unmap(); - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -Buffer11::NativeStorage::NativeStorage(Renderer11 *renderer, BufferUsage usage) - : BufferStorage(renderer, usage), - mNativeStorage(NULL) +Buffer11::NativeStorage::NativeStorage(Renderer11 *renderer, + BufferUsage usage, + const NotificationSet *onStorageChanged) + : BufferStorage(renderer, usage), mNativeStorage(nullptr), mOnStorageChanged(onStorageChanged) { } @@ -793,13 +882,15 @@ Buffer11::NativeStorage::~NativeStorage() } // Returns true if it recreates the direct buffer -bool Buffer11::NativeStorage::copyFromStorage(BufferStorage *source, size_t sourceOffset, - size_t size, size_t destOffset) +gl::ErrorOrResult Buffer11::NativeStorage::copyFromStorage(BufferStorage *source, + size_t sourceOffset, + size_t size, + size_t destOffset) { ID3D11DeviceContext *context = mRenderer->getDeviceContext(); size_t requiredSize = destOffset + size; - bool createBuffer = !mNativeStorage || mBufferSize < requiredSize; + bool createBuffer = !mNativeStorage || mBufferSize < requiredSize; // (Re)initialize D3D buffer if needed if (createBuffer) @@ -813,12 +904,19 @@ bool Buffer11::NativeStorage::copyFromStorage(BufferStorage *source, size_t sour { ASSERT(source->isMappable()); - uint8_t *sourcePointer = source->map(sourceOffset, size, GL_MAP_READ_BIT); + uint8_t *sourcePointer = nullptr; + ANGLE_TRY(source->map(sourceOffset, size, GL_MAP_READ_BIT, &sourcePointer)); D3D11_MAPPED_SUBRESOURCE mappedResource; HRESULT hr = context->Map(mNativeStorage, 0, D3D11_MAP_WRITE, 0, &mappedResource); - UNUSED_ASSERTION_VARIABLE(hr); ASSERT(SUCCEEDED(hr)); + if (FAILED(hr)) + { + source->unmap(); + return gl::Error( + GL_OUT_OF_MEMORY, + "Failed to map native storage in Buffer11::NativeStorage::copyFromStorage"); + } uint8_t *destPointer = static_cast(mappedResource.pData) + destOffset; @@ -832,35 +930,37 @@ bool Buffer11::NativeStorage::copyFromStorage(BufferStorage *source, size_t sour else { D3D11_BOX srcBox; - srcBox.left = sourceOffset; - srcBox.right = sourceOffset + size; - srcBox.top = 0; + srcBox.left = static_cast(sourceOffset); + srcBox.right = static_cast(sourceOffset + size); + srcBox.top = 0; srcBox.bottom = 1; - srcBox.front = 0; - srcBox.back = 1; + srcBox.front = 0; + srcBox.back = 1; ID3D11Buffer *sourceBuffer = GetAs(source)->getNativeStorage(); - context->CopySubresourceRegion(mNativeStorage, 0, destOffset, 0, 0, sourceBuffer, 0, &srcBox); + context->CopySubresourceRegion(mNativeStorage, 0, static_cast(destOffset), 0, + 0, sourceBuffer, 0, &srcBox); } - return createBuffer; + return createBuffer ? CopyResult::RECREATED : CopyResult::NOT_RECREATED; } gl::Error Buffer11::NativeStorage::resize(size_t size, bool preserveData) { - ID3D11Device *device = mRenderer->getDevice(); + ID3D11Device *device = mRenderer->getDevice(); ID3D11DeviceContext *context = mRenderer->getDeviceContext(); D3D11_BUFFER_DESC bufferDesc; - fillBufferDesc(&bufferDesc, mRenderer, mUsage, size); + fillBufferDesc(&bufferDesc, mRenderer, mUsage, static_cast(size)); ID3D11Buffer *newBuffer; - HRESULT result = device->CreateBuffer(&bufferDesc, NULL, &newBuffer); + HRESULT result = device->CreateBuffer(&bufferDesc, nullptr, &newBuffer); if (FAILED(result)) { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal buffer, result: 0x%X.", result); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal buffer, result: 0x%X.", + result); } d3d11::SetDebugName(newBuffer, "Buffer11::NativeStorage"); @@ -871,12 +971,12 @@ gl::Error Buffer11::NativeStorage::resize(size_t size, bool preserveData) ASSERT(mBufferSize <= size); D3D11_BOX srcBox; - srcBox.left = 0; - srcBox.right = mBufferSize; - srcBox.top = 0; + srcBox.left = 0; + srcBox.right = static_cast(mBufferSize); + srcBox.top = 0; srcBox.bottom = 1; - srcBox.front = 0; - srcBox.back = 1; + srcBox.front = 0; + srcBox.back = 1; context->CopySubresourceRegion(newBuffer, 0, 0, 0, 0, mNativeStorage, 0, &srcBox); } @@ -887,78 +987,96 @@ gl::Error Buffer11::NativeStorage::resize(size_t size, bool preserveData) mBufferSize = bufferDesc.ByteWidth; - return gl::Error(GL_NO_ERROR); + // Notify that the storage has changed. + if (mOnStorageChanged) + { + mOnStorageChanged->signal(); + } + + return gl::NoError(); } -void Buffer11::NativeStorage::fillBufferDesc(D3D11_BUFFER_DESC* bufferDesc, Renderer11 *renderer, - BufferUsage usage, unsigned int bufferSize) +void Buffer11::NativeStorage::fillBufferDesc(D3D11_BUFFER_DESC *bufferDesc, + Renderer11 *renderer, + BufferUsage usage, + unsigned int bufferSize) { - bufferDesc->ByteWidth = bufferSize; - bufferDesc->MiscFlags = 0; + 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_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; + 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; - } + 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_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 = roundUp(bufferDesc->ByteWidth, 16u); - bufferDesc->ByteWidth = std::min(bufferDesc->ByteWidth, static_cast(renderer->getRendererCaps().maxUniformBlockSize)); - break; - - default: - UNREACHABLE(); + 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_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 = roundUp(bufferDesc->ByteWidth, 16u); + bufferDesc->ByteWidth = + std::min(bufferDesc->ByteWidth, + static_cast(renderer->getRendererCaps().maxUniformBlockSize)); + break; + + default: + UNREACHABLE(); } } -uint8_t *Buffer11::NativeStorage::map(size_t offset, size_t length, GLbitfield access) +gl::Error Buffer11::NativeStorage::map(size_t offset, + size_t length, + GLbitfield access, + uint8_t **mapPointerOut) { ASSERT(mUsage == BUFFER_USAGE_STAGING); D3D11_MAPPED_SUBRESOURCE mappedResource; ID3D11DeviceContext *context = mRenderer->getDeviceContext(); - D3D11_MAP d3dMapType = gl_d3d11::GetD3DMapTypeFromBits(access); - UINT d3dMapFlag = ((access & GL_MAP_UNSYNCHRONIZED_BIT) != 0 ? D3D11_MAP_FLAG_DO_NOT_WAIT : 0); + D3D11_MAP d3dMapType = gl_d3d11::GetD3DMapTypeFromBits(access); + UINT d3dMapFlag = ((access & GL_MAP_UNSYNCHRONIZED_BIT) != 0 ? D3D11_MAP_FLAG_DO_NOT_WAIT : 0); HRESULT result = context->Map(mNativeStorage, 0, d3dMapType, d3dMapFlag, &mappedResource); - UNUSED_ASSERTION_VARIABLE(result); ASSERT(SUCCEEDED(result)); - - return static_cast(mappedResource.pData) + offset; + if (FAILED(result)) + { + return gl::Error(GL_OUT_OF_MEMORY, + "Failed to map native storage in Buffer11::NativeStorage::map"); + } + ASSERT(mappedResource.pData); + *mapPointerOut = static_cast(mappedResource.pData) + offset; + return gl::Error(GL_NO_ERROR); } void Buffer11::NativeStorage::unmap() @@ -968,28 +1086,196 @@ void Buffer11::NativeStorage::unmap() context->Unmap(mNativeStorage, 0); } +Buffer11::EmulatedIndexedStorage::EmulatedIndexedStorage(Renderer11 *renderer) + : BufferStorage(renderer, BUFFER_USAGE_EMULATED_INDEXED_VERTEX), mNativeStorage(nullptr) +{ +} + +Buffer11::EmulatedIndexedStorage::~EmulatedIndexedStorage() +{ + SafeRelease(mNativeStorage); +} + +gl::ErrorOrResult Buffer11::EmulatedIndexedStorage::getNativeStorage( + SourceIndexData *indexInfo, + const TranslatedAttribute &attribute, + GLint startVertex) +{ + // 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 (mNativeStorage == nullptr || indexInfo->srcIndicesChanged) + { + SafeRelease(mNativeStorage); + + // 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_UNSIGNED_INT: + indicesDataSize = sizeof(GLuint) * indexInfo->srcCount; + break; + case GL_UNSIGNED_SHORT: + indicesDataSize = sizeof(GLushort) * indexInfo->srcCount; + break; + case GL_UNSIGNED_BYTE: + indicesDataSize = sizeof(GLubyte) * indexInfo->srcCount; + break; + default: + indicesDataSize = sizeof(GLushort) * indexInfo->srcCount; + break; + } + + if (!mIndicesMemoryBuffer.resize(indicesDataSize)) + { + return gl::Error(GL_OUT_OF_MEMORY, + "Error resizing index memory buffer in " + "Buffer11::EmulatedIndexedStorage::getNativeStorage"); + } + + memcpy(mIndicesMemoryBuffer.data(), indexInfo->srcIndices, indicesDataSize); + + indexInfo->srcIndicesChanged = false; + } + + if (!mNativeStorage) + { + unsigned int offset = 0; + ANGLE_TRY_RESULT(attribute.computeOffset(startVertex), offset); + + // Expand the memory storage upon request and cache the results. + unsigned int expandedDataSize = + static_cast((indexInfo->srcCount * attribute.stride) + offset); + MemoryBuffer expandedData; + if (!expandedData.resize(expandedDataSize)) + { + return gl::Error( + GL_OUT_OF_MEMORY, + "Error resizing buffer in Buffer11::EmulatedIndexedStorage::getNativeStorage"); + } + + // 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_UNSIGNED_INT: + readIndexValue = ReadIndexValueFromIndices; + break; + case GL_UNSIGNED_SHORT: + readIndexValue = ReadIndexValueFromIndices; + break; + case GL_UNSIGNED_BYTE: + readIndexValue = ReadIndexValueFromIndices; + break; + } + + // 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. + ID3D11Device *device = mRenderer->getDevice(); + + 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}; + + HRESULT result = device->CreateBuffer(&bufferDesc, &subResourceData, &mNativeStorage); + if (FAILED(result)) + { + return gl::Error(GL_OUT_OF_MEMORY, "Could not create emulated index data buffer: %08lX", + result); + } + d3d11::SetDebugName(mNativeStorage, "Buffer11::EmulatedIndexedStorage"); + } + + return mNativeStorage; +} + +gl::ErrorOrResult Buffer11::EmulatedIndexedStorage::copyFromStorage( + BufferStorage *source, + size_t sourceOffset, + size_t size, + size_t destOffset) +{ + ASSERT(source->isMappable()); + uint8_t *sourceData = nullptr; + ANGLE_TRY(source->map(sourceOffset, size, GL_MAP_READ_BIT, &sourceData)); + ASSERT(destOffset + size <= mMemoryBuffer.size()); + memcpy(mMemoryBuffer.data() + destOffset, sourceData, size); + source->unmap(); + return CopyResult::RECREATED; +} + +gl::Error Buffer11::EmulatedIndexedStorage::resize(size_t size, bool preserveData) +{ + if (mMemoryBuffer.size() < size) + { + if (!mMemoryBuffer.resize(size)) + { + return gl::Error(GL_OUT_OF_MEMORY, "Failed to resize EmulatedIndexedStorage"); + } + mBufferSize = size; + } + + return gl::Error(GL_NO_ERROR); +} + +gl::Error Buffer11::EmulatedIndexedStorage::map(size_t offset, + size_t length, + GLbitfield access, + uint8_t **mapPointerOut) +{ + ASSERT(!mMemoryBuffer.empty() && offset + length <= mMemoryBuffer.size()); + *mapPointerOut = mMemoryBuffer.data() + offset; + return gl::Error(GL_NO_ERROR); +} + +void Buffer11::EmulatedIndexedStorage::unmap() +{ + // No-op +} + Buffer11::PackStorage::PackStorage(Renderer11 *renderer) - : BufferStorage(renderer, BUFFER_USAGE_PIXEL_PACK), - mStagingTexture(NULL), - mTextureFormat(DXGI_FORMAT_UNKNOWN), - mQueuedPackCommand(NULL), - mDataModified(false) + : BufferStorage(renderer, BUFFER_USAGE_PIXEL_PACK), mStagingTexture(), mDataModified(false) { } Buffer11::PackStorage::~PackStorage() { - SafeRelease(mStagingTexture); - SafeDelete(mQueuedPackCommand); } -bool Buffer11::PackStorage::copyFromStorage(BufferStorage *source, size_t sourceOffset, - size_t size, size_t destOffset) +gl::ErrorOrResult Buffer11::PackStorage::copyFromStorage(BufferStorage *source, + size_t sourceOffset, + size_t size, + size_t destOffset) { // We copy through a staging buffer when drawing with a pack buffer, // or for other cases where we access the pack buffer UNREACHABLE(); - return false; + return CopyResult::NOT_RECREATED; } gl::Error Buffer11::PackStorage::resize(size_t size, bool preserveData) @@ -1006,7 +1292,10 @@ gl::Error Buffer11::PackStorage::resize(size_t size, bool preserveData) return gl::Error(GL_NO_ERROR); } -uint8_t *Buffer11::PackStorage::map(size_t offset, size_t length, GLbitfield access) +gl::Error Buffer11::PackStorage::map(size_t offset, + size_t length, + GLbitfield access, + uint8_t **mapPointerOut) { ASSERT(offset + length <= getSize()); // TODO: fast path @@ -1014,15 +1303,12 @@ uint8_t *Buffer11::PackStorage::map(size_t offset, size_t length, GLbitfield acc // and if D3D packs the staging texture memory identically to how we would fill // the pack buffer according to the current pack state. - gl::Error error = flushQueuedPackCommand(); - if (error.isError()) - { - return NULL; - } + ANGLE_TRY(flushQueuedPackCommand()); mDataModified = (mDataModified || (access & GL_MAP_WRITE_BIT) != 0); - return mMemoryBuffer.data() + offset; + *mapPointerOut = mMemoryBuffer.data() + offset; + return gl::Error(GL_NO_ERROR); } void Buffer11::PackStorage::unmap() @@ -1030,62 +1316,35 @@ void Buffer11::PackStorage::unmap() // No-op } -gl::Error Buffer11::PackStorage::packPixels(ID3D11Texture2D *srcTexure, UINT srcSubresource, const PackPixelsParams ¶ms) +gl::Error Buffer11::PackStorage::packPixels(const gl::FramebufferAttachment &readAttachment, + const PackPixelsParams ¶ms) { - gl::Error error = flushQueuedPackCommand(); - if (error.isError()) - { - return error; - } + ANGLE_TRY(flushQueuedPackCommand()); - mQueuedPackCommand = new PackPixelsParams(params); + RenderTarget11 *renderTarget = nullptr; + ANGLE_TRY(readAttachment.getRenderTarget(&renderTarget)); - D3D11_TEXTURE2D_DESC textureDesc; - srcTexure->GetDesc(&textureDesc); + ID3D11Resource *renderTargetResource = renderTarget->getTexture(); + ASSERT(renderTargetResource); - if (mStagingTexture != NULL && - (mTextureFormat != textureDesc.Format || - mTextureSize.width != params.area.width || - mTextureSize.height != params.area.height)) - { - SafeRelease(mStagingTexture); - mTextureSize.width = 0; - mTextureSize.height = 0; - mTextureFormat = DXGI_FORMAT_UNKNOWN; - } + unsigned int srcSubresource = renderTarget->getSubresourceIndex(); + TextureHelper11 srcTexture = + TextureHelper11::MakeAndReference(renderTargetResource, renderTarget->getANGLEFormat()); - if (mStagingTexture == NULL) + mQueuedPackCommand.reset(new PackPixelsParams(params)); + + gl::Extents srcTextureSize(params.area.width, params.area.height, 1); + if (!mStagingTexture.getResource() || mStagingTexture.getFormat() != srcTexture.getFormat() || + mStagingTexture.getExtents() != srcTextureSize) { - ID3D11Device *device = mRenderer->getDevice(); - HRESULT hr; - - mTextureSize.width = params.area.width; - mTextureSize.height = params.area.height; - mTextureFormat = textureDesc.Format; - - D3D11_TEXTURE2D_DESC stagingDesc; - stagingDesc.Width = params.area.width; - stagingDesc.Height = params.area.height; - stagingDesc.MipLevels = 1; - stagingDesc.ArraySize = 1; - stagingDesc.Format = mTextureFormat; - 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; - - hr = device->CreateTexture2D(&stagingDesc, NULL, &mStagingTexture); - if (FAILED(hr)) - { - ASSERT(hr == E_OUTOFMEMORY); - return gl::Error(GL_OUT_OF_MEMORY, "Failed to allocate internal staging texture."); - } + ANGLE_TRY_RESULT(CreateStagingTexture(srcTexture.getTextureType(), srcTexture.getFormat(), + srcTexture.getANGLEFormat(), srcTextureSize, + mRenderer->getDevice()), + mStagingTexture); } // ReadPixels from multisampled FBOs isn't supported in current GL - ASSERT(textureDesc.SampleDesc.Count <= 1); + ASSERT(srcTexture.getSampleCount() <= 1); ID3D11DeviceContext *immediateContext = mRenderer->getDeviceContext(); D3D11_BOX srcBox; @@ -1093,13 +1352,20 @@ gl::Error Buffer11::PackStorage::packPixels(ID3D11Texture2D *srcTexure, UINT src srcBox.right = params.area.x + params.area.width; srcBox.top = params.area.y; srcBox.bottom = params.area.y + params.area.height; - srcBox.front = 0; - srcBox.back = 1; + + // Select the correct layer from a 3D attachment + srcBox.front = 0; + if (mStagingTexture.getTextureType() == GL_TEXTURE_3D) + { + srcBox.front = static_cast(readAttachment.layer()); + } + srcBox.back = srcBox.front + 1; // Asynchronous copy - immediateContext->CopySubresourceRegion(mStagingTexture, 0, 0, 0, 0, srcTexure, srcSubresource, &srcBox); + immediateContext->CopySubresourceRegion(mStagingTexture.getResource(), 0, 0, 0, 0, + srcTexture.getResource(), srcSubresource, &srcBox); - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } gl::Error Buffer11::PackStorage::flushQueuedPackCommand() @@ -1108,30 +1374,31 @@ gl::Error Buffer11::PackStorage::flushQueuedPackCommand() if (mQueuedPackCommand) { - gl::Error error = mRenderer->packPixels(mStagingTexture, *mQueuedPackCommand, mMemoryBuffer.data()); - SafeDelete(mQueuedPackCommand); - if (error.isError()) - { - return error; - } + ANGLE_TRY( + mRenderer->packPixels(mStagingTexture, *mQueuedPackCommand, mMemoryBuffer.data())); + mQueuedPackCommand.reset(nullptr); } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } Buffer11::SystemMemoryStorage::SystemMemoryStorage(Renderer11 *renderer) : Buffer11::BufferStorage(renderer, BUFFER_USAGE_SYSTEM_MEMORY) -{} +{ +} -bool Buffer11::SystemMemoryStorage::copyFromStorage(BufferStorage *source, size_t sourceOffset, - size_t size, size_t destOffset) +gl::ErrorOrResult Buffer11::SystemMemoryStorage::copyFromStorage(BufferStorage *source, + size_t sourceOffset, + size_t size, + size_t destOffset) { ASSERT(source->isMappable()); - const uint8_t *sourceData = source->map(sourceOffset, size, GL_MAP_READ_BIT); + uint8_t *sourceData = nullptr; + ANGLE_TRY(source->map(sourceOffset, size, GL_MAP_READ_BIT, &sourceData)); ASSERT(destOffset + size <= mSystemCopy.size()); memcpy(mSystemCopy.data() + destOffset, sourceData, size); source->unmap(); - return true; + return CopyResult::RECREATED; } gl::Error Buffer11::SystemMemoryStorage::resize(size_t size, bool preserveData) @@ -1145,18 +1412,21 @@ gl::Error Buffer11::SystemMemoryStorage::resize(size_t size, bool preserveData) mBufferSize = size; } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -uint8_t *Buffer11::SystemMemoryStorage::map(size_t offset, size_t length, GLbitfield access) +gl::Error Buffer11::SystemMemoryStorage::map(size_t offset, + size_t length, + GLbitfield access, + uint8_t **mapPointerOut) { ASSERT(!mSystemCopy.empty() && offset + length <= mSystemCopy.size()); - return mSystemCopy.data() + offset; + *mapPointerOut = mSystemCopy.data() + offset; + return gl::Error(GL_NO_ERROR); } void Buffer11::SystemMemoryStorage::unmap() { // No-op } - -} +} // namespace rx diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/Buffer11.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/Buffer11.h index bc5dcaaffe53..db73ca436a5a 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/Buffer11.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/Buffer11.h @@ -9,12 +9,22 @@ #ifndef LIBANGLE_RENDERER_D3D_D3D11_BUFFER11_H_ #define LIBANGLE_RENDERER_D3D_D3D11_BUFFER11_H_ +#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 { class Renderer11; +struct SourceIndexData; +struct TranslatedAttribute; enum BufferUsage { @@ -25,6 +35,9 @@ enum BufferUsage BUFFER_USAGE_PIXEL_PACK, BUFFER_USAGE_UNIFORM, BUFFER_USAGE_SYSTEM_MEMORY, + BUFFER_USAGE_EMULATED_INDEXED_VERTEX, + + BUFFER_USAGE_COUNT, }; struct PackPixelsParams @@ -50,39 +63,52 @@ class Buffer11 : public BufferD3D Buffer11(Renderer11 *renderer); virtual ~Buffer11(); - ID3D11Buffer *getBuffer(BufferUsage usage); - ID3D11Buffer *getConstantBufferRange(GLintptr offset, GLsizeiptr size); - ID3D11ShaderResourceView *getSRV(DXGI_FORMAT srvFormat); - bool isMapped() const { return mMappedStorage != NULL; } - gl::Error packPixels(ID3D11Texture2D *srcTexure, UINT srcSubresource, const PackPixelsParams ¶ms); + gl::ErrorOrResult getBuffer(BufferUsage usage); + gl::ErrorOrResult getEmulatedIndexedBuffer(SourceIndexData *indexInfo, + const TranslatedAttribute &attribute, + GLint startVertex); + gl::ErrorOrResult getConstantBufferRange(GLintptr offset, GLsizeiptr size); + gl::ErrorOrResult getSRV(DXGI_FORMAT srvFormat); + bool isMapped() const { return mMappedStorage != nullptr; } + gl::Error packPixels(const gl::FramebufferAttachment &readAttachment, + const PackPixelsParams ¶ms); + size_t getTotalCPUBufferMemoryBytes() const; // BufferD3D implementation - virtual size_t getSize() const { return mSize; } - virtual bool supportsDirectBinding() const; + size_t getSize() const override { return mSize; } + bool supportsDirectBinding() const override; + gl::Error getData(const uint8_t **outData) override; + void initializeStaticData() override; + void invalidateStaticData() override; // BufferImpl implementation - virtual gl::Error setData(const void* data, size_t size, GLenum usage); - gl::Error getData(const uint8_t **outData) override; - virtual gl::Error setSubData(const void* data, size_t size, size_t offset); - virtual gl::Error copySubData(BufferImpl* source, GLintptr sourceOffset, GLintptr destOffset, GLsizeiptr size); - virtual gl::Error map(GLenum access, GLvoid **mapPtr); - virtual gl::Error mapRange(size_t offset, size_t length, GLbitfield access, GLvoid **mapPtr); - virtual gl::Error unmap(GLboolean *result); - virtual void markTransformFeedbackUsage(); + gl::Error setData(const void *data, size_t size, GLenum usage) override; + gl::Error setSubData(const void *data, size_t size, size_t offset) override; + gl::Error copySubData(BufferImpl *source, + GLintptr sourceOffset, + GLintptr destOffset, + GLsizeiptr size) override; + gl::Error map(GLenum access, GLvoid **mapPtr) override; + gl::Error mapRange(size_t offset, size_t length, GLbitfield access, GLvoid **mapPtr) override; + gl::Error unmap(GLboolean *result) override; + gl::Error markTransformFeedbackUsage() override; + + // We use two set of dirty callbacks for two events. Static buffers are marked dirty whenever + // the data is changed, because they must be re-translated. Direct buffers only need to be + // updated when the underlying ID3D11Buffer pointer changes - hopefully far less often. + void addStaticBufferDirtyCallback(const NotificationCallback *callback); + void removeStaticBufferDirtyCallback(const NotificationCallback *callback); + + void addDirectBufferDirtyCallback(const NotificationCallback *callback); + void removeDirectBufferDirtyCallback(const NotificationCallback *callback); private: class BufferStorage; + class EmulatedIndexedStorage; class NativeStorage; class PackStorage; class SystemMemoryStorage; - Renderer11 *mRenderer; - size_t mSize; - - BufferStorage *mMappedStorage; - - std::map mBufferStorages; - struct ConstantBufferCacheEntry { ConstantBufferCacheEntry() : storage(nullptr), lruCount(0) { } @@ -91,6 +117,27 @@ class Buffer11 : public BufferD3D unsigned int lruCount; }; + gl::Error markBufferUsage(); + gl::ErrorOrResult getStagingStorage(); + gl::ErrorOrResult getPackStorage(); + gl::ErrorOrResult getSystemMemoryStorage(); + + gl::Error updateBufferStorage(BufferStorage *storage, size_t sourceOffset, size_t storageSize); + gl::ErrorOrResult getBufferStorage(BufferUsage usage); + gl::ErrorOrResult getLatestBufferStorage() const; + + gl::ErrorOrResult getConstantBufferRangeStorage(GLintptr offset, + GLsizeiptr size); + + BufferStorage *allocateStorage(BufferUsage usage) const; + + Renderer11 *mRenderer; + size_t mSize; + + BufferStorage *mMappedStorage; + + std::vector mBufferStorages; + // 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. @@ -103,20 +150,11 @@ class Buffer11 : public BufferD3D std::map mBufferResourceViews; unsigned int mReadUsageCount; - bool mHasSystemMemoryStorage; - void markBufferUsage(); - NativeStorage *getStagingStorage(); - PackStorage *getPackStorage(); - gl::Error getSystemMemoryStorage(SystemMemoryStorage **storageOut); - - void updateBufferStorage(BufferStorage *storage, size_t sourceOffset, size_t storageSize); - BufferStorage *getBufferStorage(BufferUsage usage); - BufferStorage *getLatestBufferStorage() const; - - BufferStorage *getContantBufferRangeStorage(GLintptr offset, GLsizeiptr size); + NotificationSet mStaticBufferDirtyCallbacks; + NotificationSet mDirectBufferDirtyCallbacks; }; -} +} // namespace rx #endif // LIBANGLE_RENDERER_D3D_D3D11_BUFFER11_H_ diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/Clear11.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/Clear11.cpp index cb3aa643d2ac..da70970aa849 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/Clear11.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/Clear11.cpp @@ -45,7 +45,7 @@ static void ApplyVertices(const gl::Extents &framebufferSize, const gl::Rectangl float bottom = 1.0f; // Clip the quad coordinates to the scissor if needed - if (scissor != NULL) + if (scissor != nullptr) { left = std::max(left, (scissor->x / float(framebufferSize.width)) * 2.0f - 1.0f); right = std::min(right, ((scissor->x + scissor->width) / float(framebufferSize.width)) * 2.0f - 1.0f); @@ -59,34 +59,43 @@ static void ApplyVertices(const gl::Extents &framebufferSize, const gl::Rectangl d3d11::SetPositionDepthColorVertex(vertices + 3, right, top, depthClear, color); } -template -Clear11::ClearShader Clear11::CreateClearShader(ID3D11Device *device, DXGI_FORMAT colorType, const BYTE (&vsByteCode)[vsSize], const BYTE (&psByteCode)[psSize]) +Clear11::ClearShader::ClearShader(DXGI_FORMAT colorType, + const char *inputLayoutName, + const BYTE *vsByteCode, + size_t vsSize, + const char *vsDebugName, + const BYTE *psByteCode, + size_t psSize, + const char *psDebugName) + : inputLayout(nullptr), + vertexShader(vsByteCode, vsSize, vsDebugName), + pixelShader(psByteCode, psSize, psDebugName) { - HRESULT result; - - ClearShader shader = { 0 }; - D3D11_INPUT_ELEMENT_DESC quadLayout[] = { { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, { "COLOR", 0, colorType, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 }, }; - result = device->CreateInputLayout(quadLayout, ArraySize(quadLayout), vsByteCode, vsSize, &shader.inputLayout); - ASSERT(SUCCEEDED(result)); - - result = device->CreateVertexShader(vsByteCode, vsSize, NULL, &shader.vertexShader); - ASSERT(SUCCEEDED(result)); - - result = device->CreatePixelShader(psByteCode, psSize, NULL, &shader.pixelShader); - ASSERT(SUCCEEDED(result)); + inputLayout = new d3d11::LazyInputLayout(quadLayout, 2, vsByteCode, vsSize, inputLayoutName); +} - return shader; +Clear11::ClearShader::~ClearShader() +{ + SafeDelete(inputLayout); + vertexShader.release(); + pixelShader.release(); } Clear11::Clear11(Renderer11 *renderer) - : mRenderer(renderer), mClearBlendStates(StructLessThan), mClearDepthStencilStates(StructLessThan), - mVertexBuffer(NULL), mRasterizerState(NULL), mSupportsClearView(false) + : mRenderer(renderer), + mClearBlendStates(StructLessThan), + mFloatClearShader(nullptr), + mUintClearShader(nullptr), + mIntClearShader(nullptr), + mClearDepthStencilStates(StructLessThan), + mVertexBuffer(nullptr), + mRasterizerState(nullptr) { TRACE_EVENT0("gpu.angle", "Clear11::Clear11"); @@ -101,7 +110,7 @@ Clear11::Clear11(Renderer11 *renderer) vbDesc.MiscFlags = 0; vbDesc.StructureByteStride = 0; - result = device->CreateBuffer(&vbDesc, NULL, &mVertexBuffer); + result = device->CreateBuffer(&vbDesc, nullptr, &mVertexBuffer); ASSERT(SUCCEEDED(result)); d3d11::SetDebugName(mVertexBuffer, "Clear11 masked clear vertex buffer"); @@ -121,26 +130,47 @@ Clear11::Clear11(Renderer11 *renderer) ASSERT(SUCCEEDED(result)); d3d11::SetDebugName(mRasterizerState, "Clear11 masked clear rasterizer state"); - if (renderer->getFeatureLevel() <= D3D_FEATURE_LEVEL_9_3) + if (mRenderer->getRenderer11DeviceCaps().featureLevel <= D3D_FEATURE_LEVEL_9_3) { - mFloatClearShader = CreateClearShader(device, DXGI_FORMAT_R32G32B32A32_FLOAT, g_VS_ClearFloat, g_PS_ClearFloat_FL9); + mFloatClearShader = new ClearShader(DXGI_FORMAT_R32G32B32A32_FLOAT, + "Clear11 Float IL", + g_VS_ClearFloat, + ArraySize(g_VS_ClearFloat), + "Clear11 Float VS", + g_PS_ClearFloat_FL9, + ArraySize(g_PS_ClearFloat_FL9), + "Clear11 Float PS"); } else { - mFloatClearShader = CreateClearShader(device, DXGI_FORMAT_R32G32B32A32_FLOAT, g_VS_ClearFloat, g_PS_ClearFloat); + mFloatClearShader = new ClearShader(DXGI_FORMAT_R32G32B32A32_FLOAT, + "Clear11 Float IL", + g_VS_ClearFloat, + ArraySize(g_VS_ClearFloat), + "Clear11 Float VS", + g_PS_ClearFloat, + ArraySize(g_PS_ClearFloat), + "Clear11 Float PS"); } if (renderer->isES3Capable()) { - mUintClearShader = CreateClearShader(device, DXGI_FORMAT_R32G32B32A32_UINT, g_VS_ClearUint, g_PS_ClearUint ); - mIntClearShader = CreateClearShader(device, DXGI_FORMAT_R32G32B32A32_SINT, g_VS_ClearSint, g_PS_ClearSint ); - } - - if (renderer->getDeviceContext1IfSupported()) - { - D3D11_FEATURE_DATA_D3D11_OPTIONS d3d11Options; - device->CheckFeatureSupport(D3D11_FEATURE_D3D11_OPTIONS, &d3d11Options, sizeof(D3D11_FEATURE_DATA_D3D11_OPTIONS)); - mSupportsClearView = (d3d11Options.ClearView != FALSE); + mUintClearShader = new ClearShader(DXGI_FORMAT_R32G32B32A32_UINT, + "Clear11 UINT IL", + g_VS_ClearUint, + ArraySize(g_VS_ClearUint), + "Clear11 UINT VS", + g_PS_ClearUint, + ArraySize(g_PS_ClearUint), + "Clear11 UINT PS"); + mIntClearShader = new ClearShader(DXGI_FORMAT_R32G32B32A32_UINT, + "Clear11 SINT IL", + g_VS_ClearSint, + ArraySize(g_VS_ClearSint), + "Clear11 SINT VS", + g_PS_ClearSint, + ArraySize(g_PS_ClearSint), + "Clear11 SINT PS"); } } @@ -152,20 +182,9 @@ Clear11::~Clear11() } mClearBlendStates.clear(); - SafeRelease(mFloatClearShader.inputLayout); - SafeRelease(mFloatClearShader.vertexShader); - SafeRelease(mFloatClearShader.pixelShader); - - if (mRenderer->isES3Capable()) - { - SafeRelease(mUintClearShader.inputLayout); - SafeRelease(mUintClearShader.vertexShader); - SafeRelease(mUintClearShader.pixelShader); - - SafeRelease(mIntClearShader.inputLayout); - SafeRelease(mIntClearShader.vertexShader); - SafeRelease(mIntClearShader.pixelShader); - } + SafeDelete(mFloatClearShader); + SafeDelete(mUintClearShader); + SafeDelete(mIntClearShader); for (ClearDepthStencilStateMap::iterator i = mClearDepthStencilStates.begin(); i != mClearDepthStencilStates.end(); i++) { @@ -210,21 +229,15 @@ gl::Error Clear11::clearFramebuffer(const ClearParameters &clearParams, const gl const gl::FramebufferAttachment *colorAttachment = fboData.getFirstColorAttachment(); if (colorAttachment != nullptr) { - framebufferSize.width = colorAttachment->getWidth(); - framebufferSize.height = colorAttachment->getHeight(); - framebufferSize.depth = 1; + framebufferSize = colorAttachment->getSize(); } else if (depthAttachment != nullptr) { - framebufferSize.width = depthAttachment->getWidth(); - framebufferSize.height = depthAttachment->getHeight(); - framebufferSize.depth = 1; + framebufferSize = depthAttachment->getSize(); } else if (stencilAttachment != nullptr) { - framebufferSize.width = stencilAttachment->getWidth(); - framebufferSize.height = stencilAttachment->getHeight(); - framebufferSize.depth = 1; + framebufferSize = stencilAttachment->getSize(); } else { @@ -246,20 +259,21 @@ gl::Error Clear11::clearFramebuffer(const ClearParameters &clearParams, const gl clearParams.scissor.y + clearParams.scissor.height < framebufferSize.height); std::vector maskedClearRenderTargets; - RenderTarget11* maskedClearDepthStencil = NULL; + RenderTarget11* maskedClearDepthStencil = nullptr; ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); ID3D11DeviceContext1 *deviceContext1 = mRenderer->getDeviceContext1IfSupported(); + ID3D11Device *device = mRenderer->getDevice(); - for (size_t colorAttachment = 0; colorAttachment < colorAttachments.size(); colorAttachment++) + for (size_t colorAttachmentIndex = 0; colorAttachmentIndex < colorAttachments.size(); + colorAttachmentIndex++) { - const gl::FramebufferAttachment &attachment = colorAttachments[colorAttachment]; + const gl::FramebufferAttachment &attachment = colorAttachments[colorAttachmentIndex]; - if (clearParams.clearColor[colorAttachment] && - attachment.isAttached() && - drawBufferStates[colorAttachment] != GL_NONE) + if (clearParams.clearColor[colorAttachmentIndex] && attachment.isAttached() && + drawBufferStates[colorAttachmentIndex] != GL_NONE) { - RenderTarget11 *renderTarget = NULL; + RenderTarget11 *renderTarget = nullptr; gl::Error error = attachment.getRenderTarget(&renderTarget); if (error.isError()) { @@ -271,9 +285,12 @@ gl::Error Clear11::clearFramebuffer(const ClearParameters &clearParams, const gl if (clearParams.colorClearType == GL_FLOAT && !(formatInfo.componentType == GL_FLOAT || formatInfo.componentType == GL_UNSIGNED_NORMALIZED || formatInfo.componentType == GL_SIGNED_NORMALIZED)) { - ERR("It is undefined behaviour to clear a render buffer which is not normalized fixed point or floating-" - "point to floating point values (color attachment %u has internal format 0x%X).", colorAttachment, - attachment.getInternalFormat()); + ERR( + "It is undefined behaviour to clear a render buffer which is not normalized " + "fixed point or floating-" + "point to floating point values (color attachment %u has internal format " + "0x%X).", + colorAttachmentIndex, attachment.getInternalFormat()); } if ((formatInfo.redBits == 0 || !clearParams.colorMaskRed) && @@ -284,7 +301,7 @@ gl::Error Clear11::clearFramebuffer(const ClearParameters &clearParams, const gl // Every channel either does not exist in the render target or is masked out continue; } - else if ((!mSupportsClearView && needScissoredClear) || clearParams.colorClearType != GL_FLOAT || + else if ((!(mRenderer->getRenderer11DeviceCaps().supportsClearView) && needScissoredClear) || clearParams.colorClearType != GL_FLOAT || (formatInfo.redBits > 0 && !clearParams.colorMaskRed) || (formatInfo.greenBits > 0 && !clearParams.colorMaskGreen) || (formatInfo.blueBits > 0 && !clearParams.colorMaskBlue) || @@ -292,7 +309,7 @@ gl::Error Clear11::clearFramebuffer(const ClearParameters &clearParams, const gl { // A masked clear is required, or a scissored clear is required and ID3D11DeviceContext1::ClearView is unavailable MaskedRenderTarget maskAndRt; - bool clearColor = clearParams.clearColor[colorAttachment]; + bool clearColor = clearParams.clearColor[colorAttachmentIndex]; maskAndRt.colorMask[0] = (clearColor && clearParams.colorMaskRed); maskAndRt.colorMask[1] = (clearColor && clearParams.colorMaskGreen); maskAndRt.colorMask[2] = (clearColor && clearParams.colorMaskBlue); @@ -310,11 +327,12 @@ gl::Error Clear11::clearFramebuffer(const ClearParameters &clearParams, const gl return gl::Error(GL_OUT_OF_MEMORY, "Internal render target view pointer unexpectedly null."); } - const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(renderTarget->getDXGIFormat()); + const auto &dxgiFormatInfo = d3d11::GetDXGIFormatInfo( + d3d11::GetANGLEFormatSet(renderTarget->getANGLEFormat()).rtvFormat); // Check if the actual format has a channel that the internal format does not and set them to the // default values - const float clearValues[4] = + float clearValues[4] = { ((formatInfo.redBits == 0 && dxgiFormatInfo.redBits > 0) ? 0.0f : clearParams.colorFClearValue.red), ((formatInfo.greenBits == 0 && dxgiFormatInfo.greenBits > 0) ? 0.0f : clearParams.colorFClearValue.green), @@ -322,6 +340,14 @@ gl::Error Clear11::clearFramebuffer(const ClearParameters &clearParams, const gl ((formatInfo.alphaBits == 0 && dxgiFormatInfo.alphaBits > 0) ? 1.0f : clearParams.colorFClearValue.alpha), }; + if (dxgiFormatInfo.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.colorFClearValue.alpha >= 0.5f) ? 1.0f : 0.0f; + } + if (needScissoredClear) { // We shouldn't reach here if deviceContext1 is unavailable. @@ -348,14 +374,15 @@ gl::Error Clear11::clearFramebuffer(const ClearParameters &clearParams, const gl const gl::FramebufferAttachment *attachment = (depthAttachment != nullptr) ? depthAttachment : stencilAttachment; ASSERT(attachment != nullptr); - RenderTarget11 *renderTarget = NULL; + RenderTarget11 *renderTarget = nullptr; gl::Error error = attachment->getRenderTarget(&renderTarget); if (error.isError()) { return error; } - const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(renderTarget->getDXGIFormat()); + const auto &dxgiFormatInfo = d3d11::GetDXGIFormatInfo( + d3d11::GetANGLEFormatSet(renderTarget->getANGLEFormat()).dsvFormat); unsigned int stencilUnmasked = (stencilAttachment != nullptr) ? (1 << dxgiFormatInfo.stencilBits) - 1 : 0; bool needMaskedStencilClear = clearParams.clearStencil && (clearParams.stencilWriteMask & stencilUnmasked) != stencilUnmasked; @@ -420,7 +447,7 @@ gl::Error Clear11::clearFramebuffer(const ClearParameters &clearParams, const gl rtvs[i] = rtv; } - ID3D11DepthStencilView *dsv = maskedClearDepthStencil ? maskedClearDepthStencil->getDepthStencilView() : NULL; + ID3D11DepthStencilView *dsv = maskedClearDepthStencil ? maskedClearDepthStencil->getDepthStencilView() : nullptr; ID3D11BlendState *blendState = getBlendState(maskedClearRenderTargets); const FLOAT blendFactors[4] = { 1.0f, 1.0f, 1.0f, 1.0f }; @@ -432,7 +459,7 @@ gl::Error Clear11::clearFramebuffer(const ClearParameters &clearParams, const gl // Set the vertices UINT vertexStride = 0; const UINT startIdx = 0; - const ClearShader* shader = NULL; + ClearShader *shader = nullptr; D3D11_MAPPED_SUBRESOURCE mappedResource; HRESULT result = deviceContext->Map(mVertexBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource); if (FAILED(result)) @@ -440,25 +467,25 @@ gl::Error Clear11::clearFramebuffer(const ClearParameters &clearParams, const gl return gl::Error(GL_OUT_OF_MEMORY, "Failed to map internal masked clear vertex buffer, HRESULT: 0x%X.", result); } - const gl::Rectangle *scissorPtr = clearParams.scissorEnabled ? &clearParams.scissor : NULL; + const gl::Rectangle *scissorPtr = clearParams.scissorEnabled ? &clearParams.scissor : nullptr; switch (clearParams.colorClearType) { case GL_FLOAT: ApplyVertices(framebufferSize, scissorPtr, clearParams.colorFClearValue, clearParams.depthClearValue, mappedResource.pData); vertexStride = sizeof(d3d11::PositionDepthColorVertex); - shader = &mFloatClearShader; + shader = mFloatClearShader; break; case GL_UNSIGNED_INT: ApplyVertices(framebufferSize, scissorPtr, clearParams.colorUIClearValue, clearParams.depthClearValue, mappedResource.pData); vertexStride = sizeof(d3d11::PositionDepthColorVertex); - shader = &mUintClearShader; + shader = mUintClearShader; break; case GL_INT: ApplyVertices(framebufferSize, scissorPtr, clearParams.colorIClearValue, clearParams.depthClearValue, mappedResource.pData); vertexStride = sizeof(d3d11::PositionDepthColorVertex); - shader = &mIntClearShader; + shader = mIntClearShader; break; default: @@ -484,17 +511,17 @@ gl::Error Clear11::clearFramebuffer(const ClearParameters &clearParams, const gl deviceContext->RSSetState(mRasterizerState); // Apply shaders - deviceContext->IASetInputLayout(shader->inputLayout); - deviceContext->VSSetShader(shader->vertexShader, NULL, 0); - deviceContext->PSSetShader(shader->pixelShader, NULL, 0); - deviceContext->GSSetShader(NULL, NULL, 0); + deviceContext->IASetInputLayout(shader->inputLayout->resolve(device)); + deviceContext->VSSetShader(shader->vertexShader.resolve(device), nullptr, 0); + deviceContext->PSSetShader(shader->pixelShader.resolve(device), nullptr, 0); + deviceContext->GSSetShader(nullptr, nullptr, 0); // Apply vertex buffer deviceContext->IASetVertexBuffers(0, 1, &mVertexBuffer, &vertexStride, &startIdx); deviceContext->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); // Apply render targets - deviceContext->OMSetRenderTargets(rtvs.size(), (rtvs.empty() ? NULL : &rtvs[0]), dsv); + mRenderer->getStateManager()->setOneTimeRenderTargets(rtvs, dsv); // Draw the clear quad deviceContext->Draw(4, 0); @@ -508,7 +535,7 @@ gl::Error Clear11::clearFramebuffer(const ClearParameters &clearParams, const gl ID3D11BlendState *Clear11::getBlendState(const std::vector& rts) { - ClearBlendInfo blendKey = { 0 }; + ClearBlendInfo blendKey = {}; for (unsigned int i = 0; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; i++) { if (i < rts.size()) @@ -551,12 +578,12 @@ ID3D11BlendState *Clear11::getBlendState(const std::vector& } ID3D11Device *device = mRenderer->getDevice(); - ID3D11BlendState* blendState = NULL; + ID3D11BlendState* blendState = nullptr; HRESULT result = device->CreateBlendState(&blendDesc, &blendState); if (FAILED(result) || !blendState) { ERR("Unable to create a ID3D11BlendState, HRESULT: 0x%X.", result); - return NULL; + return nullptr; } mClearBlendStates[blendKey] = blendState; @@ -596,12 +623,12 @@ ID3D11DepthStencilState *Clear11::getDepthStencilState(const ClearParameters &cl dsDesc.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS; ID3D11Device *device = mRenderer->getDevice(); - ID3D11DepthStencilState* dsState = NULL; + ID3D11DepthStencilState* dsState = nullptr; HRESULT result = device->CreateDepthStencilState(&dsDesc, &dsState); if (FAILED(result) || !dsState) { ERR("Unable to create a ID3D11DepthStencilState, HRESULT: 0x%X.", result); - return NULL; + return nullptr; } mClearDepthStencilStates[dsKey] = dsState; diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/Clear11.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/Clear11.h index 4797ca1aa055..3ff73c85d161 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/Clear11.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/Clear11.h @@ -15,6 +15,7 @@ #include "libANGLE/angletypes.h" #include "libANGLE/Error.h" #include "libANGLE/Framebuffer.h" +#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h" namespace rx { @@ -41,29 +42,32 @@ class Clear11 : angle::NonCopyable ID3D11BlendState *getBlendState(const std::vector &rts); ID3D11DepthStencilState *getDepthStencilState(const ClearParameters &clearParams); - struct ClearShader + struct ClearShader final : public angle::NonCopyable { - ID3D11InputLayout *inputLayout; - ID3D11VertexShader *vertexShader; - ID3D11PixelShader *pixelShader; + ClearShader(DXGI_FORMAT colorType, + const char *inputLayoutName, + const BYTE *vsByteCode, + size_t vsSize, + const char *vsDebugName, + const BYTE *psByteCode, + size_t psSize, + const char *psDebugName); + ~ClearShader(); + + d3d11::LazyInputLayout *inputLayout; + d3d11::LazyShader vertexShader; + d3d11::LazyShader pixelShader; }; template static ClearShader CreateClearShader(ID3D11Device *device, DXGI_FORMAT colorType, const BYTE(&vsByteCode)[vsSize], const BYTE(&psByteCode)[psSize]); - Renderer11 *mRenderer; - struct ClearBlendInfo { bool maskChannels[D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT][4]; }; typedef bool(*ClearBlendInfoComparisonFunction)(const ClearBlendInfo&, const ClearBlendInfo &); typedef std::map ClearBlendStateMap; - ClearBlendStateMap mClearBlendStates; - - ClearShader mFloatClearShader; - ClearShader mUintClearShader; - ClearShader mIntClearShader; struct ClearDepthStencilInfo { @@ -71,14 +75,21 @@ class Clear11 : angle::NonCopyable bool clearStencil; UINT8 stencilWriteMask; }; - typedef bool (*ClearDepthStencilInfoComparisonFunction)(const ClearDepthStencilInfo&, const ClearDepthStencilInfo &); + typedef bool(*ClearDepthStencilInfoComparisonFunction)(const ClearDepthStencilInfo&, const ClearDepthStencilInfo &); typedef std::map ClearDepthStencilStateMap; + + Renderer11 *mRenderer; + + ClearBlendStateMap mClearBlendStates; + + ClearShader *mFloatClearShader; + ClearShader *mUintClearShader; + ClearShader *mIntClearShader; + ClearDepthStencilStateMap mClearDepthStencilStates; ID3D11Buffer *mVertexBuffer; ID3D11RasterizerState *mRasterizerState; - - bool mSupportsClearView; }; } diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/DebugAnnotator11.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/DebugAnnotator11.cpp index bc7cdcc30032..f9d28e840828 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/DebugAnnotator11.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/DebugAnnotator11.cpp @@ -35,44 +35,84 @@ DebugAnnotator11::~DebugAnnotator11() } } -void DebugAnnotator11::beginEvent(const std::wstring &eventName) +void DebugAnnotator11::beginEvent(const wchar_t *eventName) { initializeDevice(); - mUserDefinedAnnotation->BeginEvent(eventName.c_str()); + if (mUserDefinedAnnotation != nullptr) + { + mUserDefinedAnnotation->BeginEvent(eventName); + } } void DebugAnnotator11::endEvent() { initializeDevice(); - mUserDefinedAnnotation->EndEvent(); + if (mUserDefinedAnnotation != nullptr) + { + mUserDefinedAnnotation->EndEvent(); + } } -void DebugAnnotator11::setMarker(const std::wstring &markerName) +void DebugAnnotator11::setMarker(const wchar_t *markerName) { initializeDevice(); - mUserDefinedAnnotation->SetMarker(markerName.c_str()); + if (mUserDefinedAnnotation != nullptr) + { + mUserDefinedAnnotation->SetMarker(markerName); + } } bool DebugAnnotator11::getStatus() { - // ID3DUserDefinedAnnotation::GetStatus doesn't work with the Graphics Diagnostics tools in Visual Studio 2013. +#if defined(ANGLE_ENABLE_WINDOWS_STORE) +#if (NTDDI_VERSION == NTDDI_WIN10) + initializeDevice(); + + if (mUserDefinedAnnotation != nullptr) + { + return !!(mUserDefinedAnnotation->GetStatus()); + } + + return true; // Default if initializeDevice() failed +#elif defined(_DEBUG) + static bool underCapture = true; -#if defined(_DEBUG) && defined(ANGLE_ENABLE_WINDOWS_STORE) - // In the Windows Store, we can use IDXGraphicsAnalysis. The call to GetDebugInterface1 only succeeds if the app is under capture. + // ID3DUserDefinedAnnotation::GetStatus doesn't work with the Graphics Diagnostics tools in + // Windows 8.1/Visual Studio 2013. We can use IDXGraphicsAnalysis, though. + // The call to GetDebugInterface1 only succeeds if the app is under capture. // This should only be called in DEBUG mode. - // If an app links against DXGIGetDebugInterface1 in release mode then it will fail Windows Store ingestion checks. - IDXGraphicsAnalysis *graphicsAnalysis; - DXGIGetDebugInterface1(0, IID_PPV_ARGS(&graphicsAnalysis)); - bool underCapture = (graphicsAnalysis != nullptr); - SafeRelease(graphicsAnalysis); - return underCapture; -#endif // _DEBUG && !ANGLE_ENABLE_WINDOWS_STORE + // If an app links against DXGIGetDebugInterface1 in release mode then it will fail Windows + // Store ingestion checks. + + // Cache the result to reduce the number of calls to DXGIGetDebugInterface1 + static bool triedIDXGraphicsAnalysis = false; + + if (!triedIDXGraphicsAnalysis) + { + IDXGraphicsAnalysis *graphicsAnalysis = nullptr; + + HRESULT result = DXGIGetDebugInterface1(0, IID_PPV_ARGS(&graphicsAnalysis)); + if (SUCCEEDED(result)) + { + underCapture = (graphicsAnalysis != nullptr); + } - // Otherwise, we have to return true here. + SafeRelease(graphicsAnalysis); + triedIDXGraphicsAnalysis = true; + } + + return underCapture; +#else + // We can't detect GetStatus() on release WinRT 8.1 builds, so always return true. + return true; +#endif // (NTDDI_VERSION == NTDDI_WIN10) or _DEBUG +#else + // We can't detect GetStatus() on desktop ANGLE builds so always return true. return true; +#endif // ANGLE_ENABLE_WINDOWS_STORE } void DebugAnnotator11::initializeDevice() @@ -95,14 +135,15 @@ void DebugAnnotator11::initializeDevice() // Create a D3D_DRIVER_TYPE_NULL device, which is much cheaper than other types of device. hr = D3D11CreateDevice(NULL, D3D_DRIVER_TYPE_NULL, nullptr, 0, nullptr, 0, D3D11_SDK_VERSION, &device, nullptr, &context); ASSERT(SUCCEEDED(hr)); - - mUserDefinedAnnotation = d3d11::DynamicCastComObject(context); - ASSERT(mUserDefinedAnnotation != nullptr); + if (SUCCEEDED(hr)) + { + mUserDefinedAnnotation = d3d11::DynamicCastComObject(context); + ASSERT(mUserDefinedAnnotation != nullptr); + mInitialized = true; + } SafeRelease(device); SafeRelease(context); - - mInitialized = true; } } diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/DebugAnnotator11.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/DebugAnnotator11.h index 063836420322..9da4fa22079b 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/DebugAnnotator11.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/DebugAnnotator11.h @@ -19,9 +19,9 @@ class DebugAnnotator11 : public gl::DebugAnnotator public: DebugAnnotator11(); ~DebugAnnotator11() override; - void beginEvent(const std::wstring &eventName) override; + void beginEvent(const wchar_t *eventName) override; void endEvent() override; - void setMarker(const std::wstring &markerName) override; + void setMarker(const wchar_t *markerName) override; bool getStatus() override; private: diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/Fence11.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/Fence11.cpp index e1bfdef77207..53fac65f2a8f 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/Fence11.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/Fence11.cpp @@ -123,7 +123,7 @@ FenceSync11::FenceSync11(Renderer11 *renderer) mRenderer(renderer), mQuery(NULL) { - LARGE_INTEGER counterFreqency = { 0 }; + LARGE_INTEGER counterFreqency = {}; BOOL success = QueryPerformanceFrequency(&counterFreqency); UNUSED_ASSERTION_VARIABLE(success); ASSERT(success); @@ -168,7 +168,7 @@ gl::Error FenceSync11::clientWait(GLbitfield flags, GLuint64 timeout, GLenum *ou return gl::Error(GL_NO_ERROR); } - LARGE_INTEGER currentCounter = { 0 }; + LARGE_INTEGER currentCounter = {}; BOOL success = QueryPerformanceCounter(¤tCounter); UNUSED_ASSERTION_VARIABLE(success); ASSERT(success); diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/Framebuffer11.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/Framebuffer11.cpp index 03c2d6088633..70963bf7f49d 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/Framebuffer11.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/Framebuffer11.cpp @@ -9,6 +9,7 @@ #include "libANGLE/renderer/d3d/d3d11/Framebuffer11.h" #include "common/debug.h" +#include "common/BitSetIterator.h" #include "libANGLE/renderer/d3d/d3d11/Buffer11.h" #include "libANGLE/renderer/d3d/d3d11/Clear11.h" #include "libANGLE/renderer/d3d/d3d11/TextureStorage11.h" @@ -24,18 +25,9 @@ namespace rx { -Framebuffer11::Framebuffer11(const gl::Framebuffer::Data &data, Renderer11 *renderer) - : FramebufferD3D(data, renderer), - mRenderer(renderer) -{ - ASSERT(mRenderer != nullptr); -} - -Framebuffer11::~Framebuffer11() +namespace { -} - -static gl::Error InvalidateAttachmentSwizzles(const gl::FramebufferAttachment *attachment) +gl::Error InvalidateAttachmentSwizzles(const gl::FramebufferAttachment *attachment) { if (attachment && attachment->type() == GL_TEXTURE) { @@ -62,6 +54,67 @@ static gl::Error InvalidateAttachmentSwizzles(const gl::FramebufferAttachment *a return gl::Error(GL_NO_ERROR); } +void UpdateCachedRenderTarget(const gl::FramebufferAttachment *attachment, + RenderTarget11 *&cachedRenderTarget, + const NotificationCallback &callbackFunc) +{ + RenderTarget11 *newRenderTarget = nullptr; + if (attachment) + { + attachment->getRenderTarget(&newRenderTarget); + } + if (newRenderTarget != cachedRenderTarget) + { + if (cachedRenderTarget) + { + cachedRenderTarget->removeDirtyCallback(&callbackFunc); + } + + if (newRenderTarget) + { + newRenderTarget->addDirtyCallback(&callbackFunc); + } + + cachedRenderTarget = newRenderTarget; + } +} +} // anonymous namespace + +Framebuffer11::Framebuffer11(const gl::Framebuffer::Data &data, Renderer11 *renderer) + : FramebufferD3D(data, renderer), mRenderer(renderer), mCachedDepthStencilRenderTarget(nullptr) +{ + ASSERT(mRenderer != nullptr); + mCachedColorRenderTargets.fill(nullptr); + for (size_t colorIndex = 0; colorIndex < data.getColorAttachments().size(); ++colorIndex) + { + auto callback = [this, colorIndex]() + { + this->markColorRenderTargetDirty(colorIndex); + }; + mColorRenderTargetsDirty.push_back(callback); + } + mDepthStencilRenderTargetDirty = [this]() + { + this->markDepthStencilRenderTargetDirty(); + }; +} + +Framebuffer11::~Framebuffer11() +{ + for (size_t colorIndex = 0; colorIndex < mCachedColorRenderTargets.size(); ++colorIndex) + { + auto *colorRenderTarget = mCachedColorRenderTargets[colorIndex]; + if (colorRenderTarget) + { + colorRenderTarget->removeDirtyCallback(&mColorRenderTargetsDirty[colorIndex]); + } + } + if (mCachedDepthStencilRenderTarget) + { + mCachedDepthStencilRenderTarget->removeDirtyCallback(&mDepthStencilRenderTargetDirty); + } +} + gl::Error Framebuffer11::invalidateSwizzles() const { for (const auto &colorAttachment : mData.getColorAttachments()) @@ -91,10 +144,30 @@ gl::Error Framebuffer11::invalidateSwizzles() const return gl::Error(GL_NO_ERROR); } -gl::Error Framebuffer11::clear(const gl::State &state, const ClearParameters &clearParams) +gl::Error Framebuffer11::clear(const gl::Data &data, const ClearParameters &clearParams) { Clear11 *clearer = mRenderer->getClearer(); - gl::Error error = clearer->clearFramebuffer(clearParams, mData); + gl::Error error(GL_NO_ERROR); + + const gl::FramebufferAttachment *colorAttachment = mData.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; + error = clearer->clearFramebuffer(presentPathFastClearParams, mData); + } + else + { + error = clearer->clearFramebuffer(clearParams, mData); + } + if (error.isError()) { return error; @@ -109,76 +182,191 @@ gl::Error Framebuffer11::clear(const gl::State &state, const ClearParameters &cl return gl::Error(GL_NO_ERROR); } -static gl::Error getRenderTargetResource(const gl::FramebufferAttachment *colorbuffer, unsigned int *subresourceIndexOut, - ID3D11Texture2D **texture2DOut) +gl::Error Framebuffer11::invalidate(size_t count, const GLenum *attachments) { - ASSERT(colorbuffer); + return invalidateBase(count, attachments, false); +} - RenderTarget11 *renderTarget = nullptr; - gl::Error error = colorbuffer->getRenderTarget(&renderTarget); - if (error.isError()) +gl::Error Framebuffer11::discard(size_t count, const GLenum *attachments) +{ + return invalidateBase(count, attachments, true); +} + +gl::Error Framebuffer11::invalidateBase(size_t count, const GLenum *attachments, bool useEXTBehavior) const +{ + ID3D11DeviceContext1 *deviceContext1 = mRenderer->getDeviceContext1IfSupported(); + + if (!deviceContext1) { - return error; + // DiscardView() is only supported on ID3D11DeviceContext1 + return gl::Error(GL_NO_ERROR); } - ID3D11Resource *renderTargetResource = renderTarget->getTexture(); - ASSERT(renderTargetResource); + bool foundDepth = false; + bool foundStencil = false; - *subresourceIndexOut = renderTarget->getSubresourceIndex(); - *texture2DOut = d3d11::DynamicCastComObject(renderTargetResource); - - if (!(*texture2DOut)) + for (size_t i = 0; i < count; ++i) { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to query the ID3D11Texture2D from a RenderTarget"); - } + 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)); - return gl::Error(GL_NO_ERROR); -} + RenderTarget11 *renderTarget = nullptr; + ID3D11View *colorView = nullptr; + gl::Error error(GL_NO_ERROR); + size_t colorAttachmentID = 0; -gl::Error Framebuffer11::readPixels(const gl::Rectangle &area, GLenum format, GLenum type, size_t outputPitch, const gl::PixelPackState &pack, uint8_t *pixels) const -{ - ID3D11Texture2D *colorBufferTexture = nullptr; - unsigned int subresourceIndex = 0; + if (attachments[i] == GL_COLOR) + { + colorAttachmentID = 0; + } + else + { + colorAttachmentID = attachments[i] - GL_COLOR_ATTACHMENT0; + } - const gl::FramebufferAttachment *colorbuffer = mData.getReadAttachment(); - ASSERT(colorbuffer); + if (mData.getColorAttachment(static_cast(colorAttachmentID))) + { + error = mData.getColorAttachment(static_cast(colorAttachmentID)) + ->getRenderTarget(&renderTarget); + if (error.isError()) + { + return error; + } + + colorView = renderTarget->getRenderTargetView(); + + if (colorView != nullptr) + { + deviceContext1->DiscardView(colorView); + } + } - gl::Error error = getRenderTargetResource(colorbuffer, &subresourceIndex, &colorBufferTexture); - if (error.isError()) + 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) { - return error; + // 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 || mData.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 && (mData.getStencilAttachment() == nullptr)); + discardStencil = (foundStencil && (mData.getDepthAttachment() == nullptr)); } - gl::Buffer *packBuffer = pack.pixelBuffer.get(); - if (packBuffer != nullptr) + if (discardDepth && mData.getDepthAttachment()) { - Buffer11 *packBufferStorage = GetImplAs(packBuffer); - PackPixelsParams packParams(area, format, type, outputPitch, pack, reinterpret_cast(pixels)); + RenderTarget11 *renderTarget = nullptr; + ID3D11View *depthView = nullptr; + gl::Error error(GL_NO_ERROR); - error = packBufferStorage->packPixels(colorBufferTexture, subresourceIndex, packParams); + error = mData.getDepthAttachment()->getRenderTarget(&renderTarget); if (error.isError()) { - SafeRelease(colorBufferTexture); return error; } - packBuffer->getIndexRangeCache()->clear(); + depthView = renderTarget->getDepthStencilView(); + + if (depthView != nullptr) + { + deviceContext1->DiscardView(depthView); + } } - else + + if (discardStencil && mData.getStencilAttachment()) { - error = mRenderer->readTextureData(colorBufferTexture, subresourceIndex, area, format, type, outputPitch, pack, pixels); + RenderTarget11 *renderTarget = nullptr; + ID3D11View *stencilView = nullptr; + gl::Error error(GL_NO_ERROR); + + error = mData.getStencilAttachment()->getRenderTarget(&renderTarget); if (error.isError()) { - SafeRelease(colorBufferTexture); return error; } + + stencilView = renderTarget->getDepthStencilView(); + + if (stencilView != nullptr) + { + deviceContext1->DiscardView(stencilView); + } } - SafeRelease(colorBufferTexture); + return gl::Error(GL_NO_ERROR); +} +gl::Error Framebuffer11::invalidateSub(size_t, const GLenum *, const gl::Rectangle &) +{ + // A no-op implementation conforms to the spec, so don't call UNIMPLEMENTED() return gl::Error(GL_NO_ERROR); } +gl::Error Framebuffer11::readPixelsImpl(const gl::Rectangle &area, + GLenum format, + GLenum type, + size_t outputPitch, + const gl::PixelPackState &pack, + uint8_t *pixels) const +{ + const gl::FramebufferAttachment *readAttachment = mData.getReadAttachment(); + ASSERT(readAttachment); + + gl::Buffer *packBuffer = pack.pixelBuffer.get(); + if (packBuffer != nullptr) + { + if (pack.rowLength != 0 || pack.skipRows != 0 || pack.skipPixels != 0) + { + UNIMPLEMENTED(); + return gl::Error(GL_INVALID_OPERATION, + "Unimplemented pixel store parameters in readPixelsImpl"); + } + + Buffer11 *packBufferStorage = GetImplAs(packBuffer); + PackPixelsParams packParams(area, format, type, static_cast(outputPitch), pack, + reinterpret_cast(pixels)); + + return packBufferStorage->packPixels(*readAttachment, packParams); + } + + return mRenderer->readFromAttachment(*readAttachment, area, format, type, + static_cast(outputPitch), pack, pixels); +} + gl::Error Framebuffer11::blit(const gl::Rectangle &sourceArea, const gl::Rectangle &destArea, const gl::Rectangle *scissor, bool blitRenderTarget, bool blitDepth, bool blitStencil, GLenum filter, const gl::Framebuffer *sourceFramebuffer) @@ -214,8 +402,27 @@ gl::Error Framebuffer11::blit(const gl::Rectangle &sourceArea, const gl::Rectang } ASSERT(drawRenderTarget); - error = mRenderer->blitRenderbufferRect(sourceArea, destArea, readRenderTarget, drawRenderTarget, - filter, scissor, blitRenderTarget, false, false); + 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; + if (invertColorDest) + { + RenderTarget11 *drawRenderTarget11 = GetAs(drawRenderTarget); + actualDestArea.y = drawRenderTarget11->getHeight() - destArea.y; + actualDestArea.height = -destArea.height; + } + + error = mRenderer->blitRenderbufferRect(actualSourceArea, actualDestArea, + readRenderTarget, drawRenderTarget, filter, + scissor, blitRenderTarget, false, false); if (error.isError()) { return error; @@ -268,8 +475,80 @@ gl::Error Framebuffer11::blit(const gl::Rectangle &sourceArea, const gl::Rectang GLenum Framebuffer11::getRenderTargetImplementationFormat(RenderTargetD3D *renderTarget) const { RenderTarget11 *renderTarget11 = GetAs(renderTarget); - const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(renderTarget11->getDXGIFormat()); - return dxgiFormatInfo.internalFormat; + return d3d11::GetANGLEFormatSet(renderTarget11->getANGLEFormat()).glInternalFormat; +} + +void Framebuffer11::updateColorRenderTarget(size_t colorIndex) +{ + UpdateCachedRenderTarget(mData.getColorAttachment(colorIndex), + mCachedColorRenderTargets[colorIndex], + mColorRenderTargetsDirty[colorIndex]); +} + +void Framebuffer11::updateDepthStencilRenderTarget() +{ + UpdateCachedRenderTarget(mData.getDepthOrStencilAttachment(), mCachedDepthStencilRenderTarget, + mDepthStencilRenderTargetDirty); +} + +void Framebuffer11::syncState(const gl::Framebuffer::DirtyBits &dirtyBits) +{ + mRenderer->getStateManager()->invalidateRenderTarget(); + + const auto &mergedDirtyBits = dirtyBits | mInternalDirtyBits; + mInternalDirtyBits.reset(); + + for (auto dirtyBit : angle::IterateBitSet(mergedDirtyBits)) + { + switch (dirtyBit) + { + case gl::Framebuffer::DIRTY_BIT_DEPTH_ATTACHMENT: + case gl::Framebuffer::DIRTY_BIT_STENCIL_ATTACHMENT: + updateDepthStencilRenderTarget(); + break; + case gl::Framebuffer::DIRTY_BIT_DRAW_BUFFERS: + case gl::Framebuffer::DIRTY_BIT_READ_BUFFER: + break; + default: + { + ASSERT(gl::Framebuffer::DIRTY_BIT_COLOR_ATTACHMENT_0 == 0 && + dirtyBit < gl::Framebuffer::DIRTY_BIT_COLOR_ATTACHMENT_MAX); + size_t colorIndex = + static_cast(dirtyBit - gl::Framebuffer::DIRTY_BIT_COLOR_ATTACHMENT_0); + updateColorRenderTarget(colorIndex); + break; + } + } + } + + // We should not have dirtied any additional state during our sync. + ASSERT(!mInternalDirtyBits.any()); + + FramebufferD3D::syncState(dirtyBits); +} + +void Framebuffer11::markColorRenderTargetDirty(size_t colorIndex) +{ + mInternalDirtyBits.set(gl::Framebuffer::DIRTY_BIT_COLOR_ATTACHMENT_0 + colorIndex); + mCachedColorRenderTargets[colorIndex] = nullptr; } +void Framebuffer11::markDepthStencilRenderTargetDirty() +{ + // Stencil is redundant in this case. + mInternalDirtyBits.set(gl::Framebuffer::DIRTY_BIT_DEPTH_ATTACHMENT); + mCachedDepthStencilRenderTarget = nullptr; +} + +bool Framebuffer11::hasAnyInternalDirtyBit() const +{ + return mInternalDirtyBits.any(); } + +void Framebuffer11::syncInternalState() const +{ + // TODO(jmadill): Clean up this hack. + const_cast(this)->syncState(gl::Framebuffer::DirtyBits()); +} + +} // namespace rx diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/Framebuffer11.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/Framebuffer11.h index 07fa480fa260..0f0cbd6f0956 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/Framebuffer11.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/Framebuffer11.h @@ -10,6 +10,7 @@ #define LIBANGLE_RENDERER_D3D_D3D11_FRAMBUFFER11_H_ #include "libANGLE/renderer/d3d/FramebufferD3D.h" +#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h" namespace rx { @@ -21,23 +22,60 @@ class Framebuffer11 : public FramebufferD3D Framebuffer11(const gl::Framebuffer::Data &data, Renderer11 *renderer); virtual ~Framebuffer11(); + gl::Error discard(size_t count, const GLenum *attachments) override; + gl::Error invalidate(size_t count, const GLenum *attachments) override; + gl::Error invalidateSub(size_t count, const GLenum *attachments, const gl::Rectangle &area) override; + // Invalidate the cached swizzles of all bound texture attachments. gl::Error invalidateSwizzles() const; + void syncState(const gl::Framebuffer::DirtyBits &dirtyBits) override; + + const RenderTargetArray &getCachedColorRenderTargets() const + { + return mCachedColorRenderTargets; + } + const RenderTarget11 *getCachedDepthStencilRenderTarget() const + { + return mCachedDepthStencilRenderTarget; + } + + void markColorRenderTargetDirty(size_t colorIndex); + void markDepthStencilRenderTargetDirty(); + + bool hasAnyInternalDirtyBit() const; + // TODO(jmadill): make this non-const + void syncInternalState() const; + private: - gl::Error clear(const gl::State &state, const ClearParameters &clearParams) override; + gl::Error clear(const gl::Data &data, const ClearParameters &clearParams) override; - gl::Error readPixels(const gl::Rectangle &area, GLenum format, GLenum type, size_t outputPitch, - const gl::PixelPackState &pack, uint8_t *pixels) const override; + gl::Error readPixelsImpl(const gl::Rectangle &area, + GLenum format, + GLenum type, + size_t outputPitch, + const gl::PixelPackState &pack, + uint8_t *pixels) const override; gl::Error blit(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; + gl::Error invalidateBase(size_t count, const GLenum *attachments, bool useEXTBehavior) const; GLenum getRenderTargetImplementationFormat(RenderTargetD3D *renderTarget) const override; + void updateColorRenderTarget(size_t colorIndex); + void updateDepthStencilRenderTarget(); + Renderer11 *const mRenderer; + RenderTargetArray mCachedColorRenderTargets; + RenderTarget11 *mCachedDepthStencilRenderTarget; + + std::vector mColorRenderTargetsDirty; + NotificationCallback mDepthStencilRenderTargetDirty; + + gl::Framebuffer::DirtyBits mInternalDirtyBits; }; } diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/Image11.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/Image11.cpp index ac0310d61185..13253d222e82 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/Image11.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/Image11.cpp @@ -7,17 +7,18 @@ // 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/Renderer11.h" #include "libANGLE/renderer/d3d/d3d11/Image11.h" -#include "libANGLE/renderer/d3d/d3d11/RenderTarget11.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/Framebuffer.h" -#include "libANGLE/FramebufferAttachment.h" -#include "libANGLE/formatutils.h" #include "common/utilities.h" +#include "libANGLE/formatutils.h" +#include "libANGLE/Framebuffer.h" +#include "libANGLE/FramebufferAttachment.h" +#include "libANGLE/renderer/d3d/d3d11/formatutils11.h" +#include "libANGLE/renderer/d3d/d3d11/Renderer11.h" +#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h" +#include "libANGLE/renderer/d3d/d3d11/RenderTarget11.h" +#include "libANGLE/renderer/d3d/d3d11/texture_format_table.h" +#include "libANGLE/renderer/d3d/d3d11/TextureStorage11.h" namespace rx { @@ -32,9 +33,6 @@ Image11::Image11(Renderer11 *renderer) mAssociatedImageIndex(gl::ImageIndex::MakeInvalid()), mRecoveredFromStorageCount(0) { - // mRenderer should remain unchanged during the lifetime of the Image11 object. - // This lets us safely use mRenderer (and its Feature Level) in Image11's methods. - mFeatureLevel = renderer->getFeatureLevel(); } Image11::~Image11() @@ -43,15 +41,14 @@ Image11::~Image11() releaseStagingTexture(); } -gl::Error Image11::generateMipmap(Image11 *dest, Image11 *src) +gl::Error Image11::generateMipmap(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()); - const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(src->getDXGIFormat()); - ASSERT(dxgiFormatInfo.mipGenerationFunction != NULL); - D3D11_MAPPED_SUBRESOURCE destMapped; gl::Error error = dest->map(D3D11_MAP_WRITE, &destMapped); if (error.isError()) @@ -70,9 +67,11 @@ gl::Error Image11::generateMipmap(Image11 *dest, Image11 *src) const uint8_t *sourceData = reinterpret_cast(srcMapped.pData); uint8_t *destData = reinterpret_cast(destMapped.pData); - dxgiFormatInfo.mipGenerationFunction(src->getWidth(), src->getHeight(), src->getDepth(), - sourceData, srcMapped.RowPitch, srcMapped.DepthPitch, - destData, destMapped.RowPitch, destMapped.DepthPitch); + auto mipGenerationFunction = d3d11::GetTextureFormatInfo(src->getInternalFormat(), rendererCaps) + .formatSet->mipGenerationFunction; + mipGenerationFunction(src->getWidth(), src->getHeight(), src->getDepth(), sourceData, + srcMapped.RowPitch, srcMapped.DepthPitch, destData, destMapped.RowPitch, + destMapped.DepthPitch); dest->unmap(); src->unmap(); @@ -88,9 +87,14 @@ bool Image11::isDirty() const // 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) // then isDirty should still return false. - if (mDirty && !mStagingTexture && !mRecoverFromStorage && !(d3d11::GetTextureFormatInfo(mInternalFormat, mFeatureLevel).dataInitializerFunction != NULL)) + if (mDirty && !mStagingTexture && !mRecoverFromStorage) { - return false; + const Renderer11DeviceCaps &deviceCaps = mRenderer->getRenderer11DeviceCaps(); + const auto &formatInfo = d3d11::GetTextureFormatInfo(mInternalFormat, deviceCaps); + if (formatInfo.dataInitializerFunction == nullptr) + { + return false; + } } return mDirty; @@ -216,9 +220,10 @@ bool Image11::redefine(GLenum target, GLenum internalformat, const gl::Extents & mTarget = target; // compute the d3d format that will be used - const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(internalformat, mFeatureLevel); - mDXGIFormat = formatInfo.texFormat; - mRenderable = (formatInfo.rtvFormat != DXGI_FORMAT_UNKNOWN); + const d3d11::TextureFormat &formatInfo = + d3d11::GetTextureFormatInfo(internalformat, mRenderer->getRenderer11DeviceCaps()); + mDXGIFormat = formatInfo.formatSet->texFormat; + mRenderable = (formatInfo.formatSet->rtvFormat != DXGI_FORMAT_UNKNOWN); releaseStagingTexture(); mDirty = (formatInfo.dataInitializerFunction != NULL); @@ -244,13 +249,16 @@ gl::Error Image11::loadData(const gl::Box &area, const gl::PixelUnpackState &unp { const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(mInternalFormat); GLsizei inputRowPitch = formatInfo.computeRowPitch(type, area.width, unpack.alignment, unpack.rowLength); - GLsizei inputDepthPitch = formatInfo.computeDepthPitch(type, area.width, area.height, unpack.alignment, unpack.rowLength); + GLsizei inputDepthPitch = formatInfo.computeDepthPitch( + type, area.width, area.height, unpack.alignment, unpack.rowLength, unpack.imageHeight); + GLsizei inputSkipBytes = formatInfo.computeSkipPixels( + inputRowPitch, inputDepthPitch, unpack.skipImages, unpack.skipRows, unpack.skipPixels); - const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(mDXGIFormat); + const d3d11::DXGIFormatSize &dxgiFormatInfo = d3d11::GetDXGIFormatSizeInfo(mDXGIFormat); GLuint outputPixelSize = dxgiFormatInfo.pixelBytes; - const d3d11::TextureFormat &d3dFormatInfo = d3d11::GetTextureFormatInfo(mInternalFormat, mFeatureLevel); - LoadImageFunction loadFunction = d3dFormatInfo.loadFunctions.at(type); + const d3d11::TextureFormat &d3dFormatInfo = d3d11::GetTextureFormatInfo(mInternalFormat, mRenderer->getRenderer11DeviceCaps()); + LoadImageFunction loadFunction = d3dFormatInfo.loadFunctions.at(type).loadFunction; D3D11_MAPPED_SUBRESOURCE mappedImage; gl::Error error = map(D3D11_MAP_WRITE, &mappedImage); @@ -261,8 +269,8 @@ gl::Error Image11::loadData(const gl::Box &area, const gl::PixelUnpackState &unp uint8_t *offsetMappedData = (reinterpret_cast(mappedImage.pData) + (area.y * mappedImage.RowPitch + area.x * outputPixelSize + area.z * mappedImage.DepthPitch)); loadFunction(area.width, area.height, area.depth, - reinterpret_cast(input), inputRowPitch, inputDepthPitch, - offsetMappedData, mappedImage.RowPitch, mappedImage.DepthPitch); + reinterpret_cast(input) + inputSkipBytes, inputRowPitch, + inputDepthPitch, offsetMappedData, mappedImage.RowPitch, mappedImage.DepthPitch); unmap(); @@ -273,9 +281,10 @@ gl::Error Image11::loadCompressedData(const gl::Box &area, const void *input) { const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(mInternalFormat); GLsizei inputRowPitch = formatInfo.computeRowPitch(GL_UNSIGNED_BYTE, area.width, 1, 0); - GLsizei inputDepthPitch = formatInfo.computeDepthPitch(GL_UNSIGNED_BYTE, area.width, area.height, 1, 0); + GLsizei inputDepthPitch = + formatInfo.computeDepthPitch(GL_UNSIGNED_BYTE, area.width, area.height, 1, 0, 0); - const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(mDXGIFormat); + const d3d11::DXGIFormatSize &dxgiFormatInfo = d3d11::GetDXGIFormatSizeInfo(mDXGIFormat); GLuint outputPixelSize = dxgiFormatInfo.pixelBytes; GLuint outputBlockWidth = dxgiFormatInfo.blockWidth; GLuint outputBlockHeight = dxgiFormatInfo.blockHeight; @@ -283,8 +292,8 @@ gl::Error Image11::loadCompressedData(const gl::Box &area, const void *input) ASSERT(area.x % outputBlockWidth == 0); ASSERT(area.y % outputBlockHeight == 0); - const d3d11::TextureFormat &d3dFormatInfo = d3d11::GetTextureFormatInfo(mInternalFormat, mFeatureLevel); - LoadImageFunction loadFunction = d3dFormatInfo.loadFunctions.at(GL_UNSIGNED_BYTE); + const d3d11::TextureFormat &d3dFormatInfo = d3d11::GetTextureFormatInfo(mInternalFormat, mRenderer->getRenderer11DeviceCaps()); + LoadImageFunction loadFunction = d3dFormatInfo.loadFunctions.at(GL_UNSIGNED_BYTE).loadFunction; D3D11_MAPPED_SUBRESOURCE mappedImage; gl::Error error = map(D3D11_MAP_WRITE, &mappedImage); @@ -306,180 +315,161 @@ gl::Error Image11::loadCompressedData(const gl::Box &area, const void *input) return gl::Error(GL_NO_ERROR); } -gl::Error Image11::copy(const gl::Offset &destOffset, const gl::Rectangle &sourceArea, RenderTargetD3D *source) +gl::Error Image11::copyFromTexStorage(const gl::ImageIndex &imageIndex, TextureStorage *source) { - RenderTarget11 *sourceRenderTarget = GetAs(source); - ASSERT(sourceRenderTarget->getTexture()); - - ID3D11Resource *resource = sourceRenderTarget->getTexture(); - UINT subresourceIndex = sourceRenderTarget->getSubresourceIndex(); + TextureStorage11 *storage11 = GetAs(source); - gl::Box sourceBox(sourceArea.x, sourceArea.y, 0, sourceArea.width, sourceArea.height, 1); - gl::Error error = copy(destOffset, sourceBox, resource, subresourceIndex); - - SafeRelease(resource); - - return error; -} - -gl::Error Image11::copy(const gl::Offset &destOffset, const gl::Box &sourceArea, const gl::ImageIndex &sourceIndex, TextureStorage *source) -{ - TextureStorage11 *sourceStorage11 = GetAs(source); - - UINT subresourceIndex = sourceStorage11->getSubresourceIndex(sourceIndex); - ID3D11Resource *resource = NULL; - gl::Error error = sourceStorage11->getResource(&resource); + ID3D11Resource *resource = nullptr; + gl::Error error = storage11->getResource(&resource); if (error.isError()) { return error; } - error = copy(destOffset, sourceArea, resource, subresourceIndex); - - SafeRelease(resource); + UINT subresourceIndex = storage11->getSubresourceIndex(imageIndex); + TextureHelper11 textureHelper = + TextureHelper11::MakeAndReference(resource, storage11->getANGLEFormat()); - return error; + gl::Box sourceBox(0, 0, 0, mWidth, mHeight, mDepth); + return copyWithoutConversion(gl::Offset(), sourceBox, textureHelper, subresourceIndex); } -gl::Error Image11::copy(const gl::Offset &destOffset, const gl::Box &sourceArea, ID3D11Resource *source, UINT sourceSubResource) +gl::Error Image11::copyFromFramebuffer(const gl::Offset &destOffset, + const gl::Rectangle &sourceArea, + const gl::Framebuffer *sourceFBO) { - D3D11_RESOURCE_DIMENSION dim; - source->GetType(&dim); + const gl::FramebufferAttachment *srcAttachment = sourceFBO->getReadColorbuffer(); + ASSERT(srcAttachment); - DXGI_FORMAT format = DXGI_FORMAT_UNKNOWN; - gl::Extents extents; - UINT sampleCount = 0; - - ID3D11Texture2D *source2D = NULL; - - if (dim == D3D11_RESOURCE_DIMENSION_TEXTURE2D) - { - D3D11_TEXTURE2D_DESC textureDesc2D; - source2D = d3d11::DynamicCastComObject(source); - ASSERT(source2D); - source2D->GetDesc(&textureDesc2D); - - format = textureDesc2D.Format; - extents = gl::Extents(textureDesc2D.Width, textureDesc2D.Height, 1); - sampleCount = textureDesc2D.SampleDesc.Count; - } - else if (dim == D3D11_RESOURCE_DIMENSION_TEXTURE3D) - { - D3D11_TEXTURE3D_DESC textureDesc3D; - ID3D11Texture3D *source3D = d3d11::DynamicCastComObject(source); - ASSERT(source3D); - source3D->GetDesc(&textureDesc3D); - - format = textureDesc3D.Format; - extents = gl::Extents(textureDesc3D.Width, textureDesc3D.Height, textureDesc3D.Depth); - sampleCount = 1; - } - else - { - UNREACHABLE(); - } + const auto &d3d11Format = d3d11::GetTextureFormatInfo(srcAttachment->getInternalFormat(), + mRenderer->getRenderer11DeviceCaps()); - if (format == mDXGIFormat) + if (d3d11Format.formatSet->texFormat == mDXGIFormat) { - // No conversion needed-- use copyback fastpath - ID3D11Resource *stagingTexture = NULL; - unsigned int stagingSubresourceIndex = 0; - gl::Error error = getStagingTexture(&stagingTexture, &stagingSubresourceIndex); + RenderTargetD3D *renderTarget = nullptr; + gl::Error error = srcAttachment->getRenderTarget(&renderTarget); if (error.isError()) { return error; } - ID3D11Device *device = mRenderer->getDevice(); - ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); + RenderTarget11 *rt11 = GetAs(renderTarget); + ASSERT(rt11->getTexture()); - UINT subresourceAfterResolve = sourceSubResource; + TextureHelper11 textureHelper = + TextureHelper11::MakeAndReference(rt11->getTexture(), rt11->getANGLEFormat()); + unsigned int sourceSubResource = rt11->getSubresourceIndex(); - ID3D11Resource *srcTex = NULL; + gl::Box sourceBox(sourceArea.x, sourceArea.y, 0, sourceArea.width, sourceArea.height, 1); + return copyWithoutConversion(destOffset, sourceBox, textureHelper, sourceSubResource); + } - bool needResolve = (dim == D3D11_RESOURCE_DIMENSION_TEXTURE2D && sampleCount > 1); + // This format requires conversion, so we must copy the texture to staging and manually convert + // via readPixels + D3D11_MAPPED_SUBRESOURCE mappedImage; + gl::Error error = map(D3D11_MAP_WRITE, &mappedImage); + if (error.isError()) + { + return error; + } - if (needResolve) - { - D3D11_TEXTURE2D_DESC resolveDesc; - resolveDesc.Width = extents.width; - resolveDesc.Height = extents.height; - resolveDesc.MipLevels = 1; - resolveDesc.ArraySize = 1; - resolveDesc.Format = format; - resolveDesc.SampleDesc.Count = 1; - resolveDesc.SampleDesc.Quality = 0; - resolveDesc.Usage = D3D11_USAGE_DEFAULT; - resolveDesc.BindFlags = 0; - resolveDesc.CPUAccessFlags = 0; - resolveDesc.MiscFlags = 0; - - ID3D11Texture2D *srcTex2D = NULL; - HRESULT result = device->CreateTexture2D(&resolveDesc, NULL, &srcTex2D); - if (FAILED(result)) - { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to create resolve texture for Image11::copy, HRESULT: 0x%X.", result); - } - srcTex = srcTex2D; + // determine the offset coordinate into the destination buffer + const auto &dxgiFormatInfo = d3d11::GetDXGIFormatSizeInfo(mDXGIFormat); + GLsizei rowOffset = dxgiFormatInfo.pixelBytes * destOffset.x; - deviceContext->ResolveSubresource(srcTex, 0, source, sourceSubResource, format); - subresourceAfterResolve = 0; - } - else - { - srcTex = source; - } + uint8_t *dataOffset = static_cast(mappedImage.pData) + + mappedImage.RowPitch * destOffset.y + rowOffset + + destOffset.z * mappedImage.DepthPitch; - 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; + const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(mInternalFormat); - deviceContext->CopySubresourceRegion(stagingTexture, stagingSubresourceIndex, destOffset.x, destOffset.y, - destOffset.z, srcTex, subresourceAfterResolve, &srcBox); + error = mRenderer->readFromAttachment(*srcAttachment, sourceArea, formatInfo.format, + formatInfo.type, mappedImage.RowPitch, + gl::PixelPackState(), dataOffset); - if (needResolve) - { - SafeRelease(srcTex); - } - } - else + unmap(); + mDirty = true; + + return error; +} + +gl::Error Image11::copyWithoutConversion(const gl::Offset &destOffset, + const gl::Box &sourceArea, + const TextureHelper11 &textureHelper, + UINT sourceSubResource) +{ + // No conversion needed-- use copyback fastpath + ID3D11Resource *stagingTexture = nullptr; + unsigned int stagingSubresourceIndex = 0; + gl::Error error = getStagingTexture(&stagingTexture, &stagingSubresourceIndex); + if (error.isError()) { - // This format requires conversion, so we must copy the texture to staging and manually convert via readPixels - D3D11_MAPPED_SUBRESOURCE mappedImage; - gl::Error error = map(D3D11_MAP_WRITE, &mappedImage); - if (error.isError()) - { - return error; - } + return error; + } - // determine the offset coordinate into the destination buffer - const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(mDXGIFormat); - GLsizei rowOffset = dxgiFormatInfo.pixelBytes * destOffset.x; - uint8_t *dataOffset = static_cast(mappedImage.pData) + mappedImage.RowPitch * destOffset.y + rowOffset + destOffset.z * mappedImage.DepthPitch; + ID3D11Device *device = mRenderer->getDevice(); + ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); - const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(mInternalFormat); + UINT subresourceAfterResolve = sourceSubResource; - // Currently in ANGLE, the source data may only need to be converted if the source is the current framebuffer - // and OpenGL ES framebuffers must be 2D textures therefore we should not need to convert 3D textures between different formats. - ASSERT(dim == D3D11_RESOURCE_DIMENSION_TEXTURE2D); - ASSERT(sourceArea.z == 0 && sourceArea.depth == 1); - gl::Rectangle sourceRect(sourceArea.x, sourceArea.y, sourceArea.width, sourceArea.height); - error = mRenderer->readTextureData(source2D, sourceSubResource, sourceRect, formatInfo.format, formatInfo.type, mappedImage.RowPitch, gl::PixelPackState(), dataOffset); + ID3D11Resource *srcTex = nullptr; + const gl::Extents &extents = textureHelper.getExtents(); - unmap(); + bool needResolve = + (textureHelper.getTextureType() == GL_TEXTURE_2D && textureHelper.getSampleCount() > 1); - if (error.isError()) + if (needResolve) + { + 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; + + ID3D11Texture2D *srcTex2D = NULL; + HRESULT result = device->CreateTexture2D(&resolveDesc, NULL, &srcTex2D); + if (FAILED(result)) { - return error; + return gl::Error(GL_OUT_OF_MEMORY, + "Failed to create resolve texture for Image11::copy, HRESULT: 0x%X.", + result); } + srcTex = srcTex2D; + + deviceContext->ResolveSubresource(srcTex, 0, textureHelper.getTexture2D(), + sourceSubResource, textureHelper.getFormat()); + subresourceAfterResolve = 0; + } + else + { + srcTex = textureHelper.getResource(); } - mDirty = true; + 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; + + deviceContext->CopySubresourceRegion(stagingTexture, stagingSubresourceIndex, destOffset.x, + destOffset.y, destOffset.z, srcTex, + subresourceAfterResolve, &srcBox); + + if (needResolve) + { + SafeRelease(srcTex); + } + mDirty = true; return gl::Error(GL_NO_ERROR); } @@ -537,11 +527,11 @@ gl::Error Image11::createStagingTexture() desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE; desc.MiscFlags = 0; - if (d3d11::GetTextureFormatInfo(mInternalFormat, mFeatureLevel).dataInitializerFunction != NULL) + if (d3d11::GetTextureFormatInfo(mInternalFormat, mRenderer->getRenderer11DeviceCaps()).dataInitializerFunction != NULL) { std::vector initialData; - std::vector< std::vector > textureData; - d3d11::GenerateInitialTextureData(mInternalFormat, mFeatureLevel, width, height, mDepth, + std::vector> textureData; + d3d11::GenerateInitialTextureData(mInternalFormat, mRenderer->getRenderer11DeviceCaps(), width, height, mDepth, lodOffset + 1, &initialData, &textureData); result = device->CreateTexture3D(&desc, initialData.data(), &newTexture); @@ -577,11 +567,11 @@ gl::Error Image11::createStagingTexture() desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE; desc.MiscFlags = 0; - if (d3d11::GetTextureFormatInfo(mInternalFormat, mFeatureLevel).dataInitializerFunction != NULL) + if (d3d11::GetTextureFormatInfo(mInternalFormat, mRenderer->getRenderer11DeviceCaps()).dataInitializerFunction != NULL) { std::vector initialData; - std::vector< std::vector > textureData; - d3d11::GenerateInitialTextureData(mInternalFormat, mFeatureLevel, width, height, 1, + std::vector> textureData; + d3d11::GenerateInitialTextureData(mInternalFormat, mRenderer->getRenderer11DeviceCaps(), width, height, 1, lodOffset + 1, &initialData, &textureData); result = device->CreateTexture2D(&desc, initialData.data(), &newTexture); @@ -631,13 +621,13 @@ gl::Error Image11::map(D3D11_MAP mapType, D3D11_MAPPED_SUBRESOURCE *map) ASSERT(mStagingTexture); HRESULT result = deviceContext->Map(stagingTexture, subresourceIndex, mapType, 0, map); - // this can fail if the device is removed (from TDR) - if (d3d11::isDeviceLostError(result)) - { - mRenderer->notifyDeviceLost(); - } - else if (FAILED(result)) + if (FAILED(result)) { + // this can fail if the device is removed (from TDR) + if (d3d11::isDeviceLostError(result)) + { + mRenderer->notifyDeviceLost(); + } return gl::Error(GL_OUT_OF_MEMORY, "Failed to map staging texture, result: 0x%X.", result); } @@ -655,4 +645,4 @@ void Image11::unmap() } } -} +} // namespace rx diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/Image11.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/Image11.h index 8b475e9bd1ef..ce3500498ca8 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/Image11.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/Image11.h @@ -23,7 +23,9 @@ class Framebuffer; namespace rx { class Renderer11; +class TextureHelper11; class TextureStorage11; +struct Renderer11DeviceCaps; class Image11 : public ImageD3D { @@ -31,7 +33,9 @@ class Image11 : public ImageD3D Image11(Renderer11 *renderer); virtual ~Image11(); - static gl::Error generateMipmap(Image11 *dest, Image11 *src); + static gl::Error generateMipmap(Image11 *dest, + Image11 *src, + const Renderer11DeviceCaps &rendererCaps); virtual bool isDirty() const; @@ -44,9 +48,10 @@ class Image11 : public ImageD3D virtual gl::Error loadData(const gl::Box &area, const gl::PixelUnpackState &unpack, GLenum type, const void *input); virtual gl::Error loadCompressedData(const gl::Box &area, const void *input); - virtual gl::Error copy(const gl::Offset &destOffset, const gl::Rectangle &sourceArea, RenderTargetD3D *source); - virtual gl::Error copy(const gl::Offset &destOffset, const gl::Box &sourceArea, - const gl::ImageIndex &sourceIndex, TextureStorage *source); + gl::Error copyFromTexStorage(const gl::ImageIndex &imageIndex, TextureStorage *source) override; + gl::Error copyFromFramebuffer(const gl::Offset &destOffset, + const gl::Rectangle &sourceArea, + const gl::Framebuffer *source) override; gl::Error recoverFromAssociatedStorage(); bool isAssociatedStorageValid(TextureStorage11* textureStorage) const; @@ -57,15 +62,16 @@ class Image11 : public ImageD3D void unmap(); private: - gl::Error copyToStorageImpl(TextureStorage11 *storage11, const gl::ImageIndex &index, const gl::Box ®ion); - gl::Error copy(const gl::Offset &destOffset, const gl::Box &sourceArea, ID3D11Resource *source, UINT sourceSubResource); + gl::Error copyWithoutConversion(const gl::Offset &destOffset, + const gl::Box &sourceArea, + const TextureHelper11 &textureHelper, + UINT sourceSubResource); gl::Error getStagingTexture(ID3D11Resource **outStagingTexture, unsigned int *outSubresourceIndex); gl::Error createStagingTexture(); void releaseStagingTexture(); Renderer11 *mRenderer; - D3D_FEATURE_LEVEL mFeatureLevel; DXGI_FORMAT mDXGIFormat; ID3D11Resource *mStagingTexture; diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/InputLayoutCache.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/InputLayoutCache.cpp index 755d00cec3b4..02ae26de6468 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/InputLayoutCache.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/InputLayoutCache.cpp @@ -8,51 +8,178 @@ // D3D11 input layouts. #include "libANGLE/renderer/d3d/d3d11/InputLayoutCache.h" -#include "libANGLE/renderer/d3d/d3d11/VertexBuffer11.h" + +#include "common/BitSetIterator.h" +#include "common/utilities.h" +#include "libANGLE/Program.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/Buffer11.h" #include "libANGLE/renderer/d3d/d3d11/ShaderExecutable11.h" +#include "libANGLE/renderer/d3d/d3d11/VertexBuffer11.h" #include "libANGLE/renderer/d3d/d3d11/formatutils11.h" -#include "libANGLE/renderer/d3d/ProgramD3D.h" -#include "libANGLE/renderer/d3d/VertexDataManager.h" -#include "libANGLE/Program.h" -#include "libANGLE/VertexAttribute.h" - #include "third_party/murmurhash/MurmurHash3.h" namespace rx { -static void GetInputLayout(const TranslatedAttribute translatedAttributes[gl::MAX_VERTEX_ATTRIBS], - gl::VertexFormat inputLayout[gl::MAX_VERTEX_ATTRIBS]) +namespace +{ + +size_t GetReservedBufferCount(bool usesPointSpriteEmulation) { - for (unsigned int attributeIndex = 0; attributeIndex < gl::MAX_VERTEX_ATTRIBS; attributeIndex++) + return usesPointSpriteEmulation ? 1 : 0; +} + +gl::InputLayout GetInputLayout(const std::vector &translatedAttributes) +{ + gl::InputLayout inputLayout(translatedAttributes.size(), gl::VERTEX_FORMAT_INVALID); + + for (size_t attributeIndex = 0; attributeIndex < translatedAttributes.size(); ++attributeIndex) + { + const TranslatedAttribute *translatedAttribute = translatedAttributes[attributeIndex]; + inputLayout[attributeIndex] = gl::GetVertexFormatType( + *translatedAttribute->attribute, translatedAttribute->currentValueType); + } + return inputLayout; +} + +GLenum GetGLSLAttributeType(const std::vector &shaderAttributes, int index) +{ + // Count matrices differently + for (const sh::Attribute &attrib : shaderAttributes) { - const TranslatedAttribute &translatedAttribute = translatedAttributes[attributeIndex]; + if (attrib.location == -1) + { + continue; + } - if (translatedAttributes[attributeIndex].active) + GLenum transposedType = gl::TransposeMatrixType(attrib.type); + int rows = gl::VariableRowCount(transposedType); + + if (index >= attrib.location && index < attrib.location + rows) { - inputLayout[attributeIndex] = gl::VertexFormat(*translatedAttribute.attribute, - translatedAttribute.currentValueType); + return transposedType; } } + + UNREACHABLE(); + return GL_NONE; } -const unsigned int InputLayoutCache::kMaxInputLayouts = 1024; +const unsigned int kDefaultCacheSize = 1024; -InputLayoutCache::InputLayoutCache() : mInputLayoutMap(kMaxInputLayouts, hashInputLayout, compareInputLayouts) +struct PackedAttribute { - mCounter = 0; - mDevice = NULL; - mDeviceContext = NULL; - mCurrentIL = NULL; - for (unsigned int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++) + uint8_t attribType; + uint8_t semanticIndex; + uint8_t vertexFormatType; + uint8_t divisor; +}; + +Optional FindFirstNonInstanced( + const std::vector ¤tAttributes) +{ + for (size_t index = 0; index < currentAttributes.size(); ++index) { - mCurrentBuffers[i] = NULL; - mCurrentVertexStrides[i] = static_cast(-1); - mCurrentVertexOffsets[i] = static_cast(-1); + if (currentAttributes[index]->divisor == 0) + { + return Optional(index); + } + } + + return Optional::Invalid(); +} + +void SortAttributesByLayout(const gl::Program *program, + const std::vector &vertexArrayAttribs, + const std::vector ¤tValueAttribs, + AttribIndexArray *sortedD3DSemanticsOut, + std::vector *sortedAttributesOut) +{ + sortedAttributesOut->clear(); + + const auto &locationToSemantic = + GetImplAs(program)->getAttribLocationToD3DSemantics(); + + for (auto locationIndex : angle::IterateBitSet(program->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]; + } + } +} + +} // anonymous namespace + +void InputLayoutCache::PackedAttributeLayout::addAttributeData( + GLenum glType, + UINT semanticIndex, + gl::VertexFormatType vertexFormatType, + 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(vertexFormatType); + packedAttrib.divisor = static_cast(divisor); + + ASSERT(static_cast(packedAttrib.attribType) == attribType); + ASSERT(static_cast(packedAttrib.semanticIndex) == semanticIndex); + ASSERT(static_cast(packedAttrib.vertexFormatType) == vertexFormatType); + ASSERT(static_cast(packedAttrib.divisor) == divisor); + + static_assert(sizeof(uint32_t) == sizeof(PackedAttribute), "PackedAttributes must be 32-bits exactly."); + + attributeData[numAttributes++] = gl::bitCast(packedAttrib); +} + +bool InputLayoutCache::PackedAttributeLayout::operator<(const PackedAttributeLayout &other) const +{ + if (numAttributes != other.numAttributes) + { + return numAttributes < other.numAttributes; } - mPointSpriteVertexBuffer = NULL; - mPointSpriteIndexBuffer = NULL; + + if (flags != other.flags) + { + return flags < other.flags; + } + + return memcmp(attributeData, other.attributeData, sizeof(uint32_t) * numAttributes) < 0; +} + +InputLayoutCache::InputLayoutCache() + : mCurrentIL(nullptr), + mPointSpriteVertexBuffer(nullptr), + mPointSpriteIndexBuffer(nullptr), + mCacheSize(kDefaultCacheSize), + mDevice(nullptr), + mDeviceContext(nullptr) +{ + mCurrentBuffers.fill(nullptr); + mCurrentVertexStrides.fill(std::numeric_limits::max()); + mCurrentVertexOffsets.fill(std::numeric_limits::max()); + mCurrentAttributes.reserve(gl::MAX_VERTEX_ATTRIBS); } InputLayoutCache::~InputLayoutCache() @@ -70,11 +197,11 @@ void InputLayoutCache::initialize(ID3D11Device *device, ID3D11DeviceContext *con void InputLayoutCache::clear() { - for (InputLayoutMap::iterator i = mInputLayoutMap.begin(); i != mInputLayoutMap.end(); i++) + for (auto &layout : mLayoutMap) { - SafeRelease(i->second.inputLayout); + SafeRelease(layout.second); } - mInputLayoutMap.clear(); + mLayoutMap.clear(); SafeRelease(mPointSpriteVertexBuffer); SafeRelease(mPointSpriteIndexBuffer); markDirty(); @@ -82,243 +209,133 @@ void InputLayoutCache::clear() void InputLayoutCache::markDirty() { - mCurrentIL = NULL; + mCurrentIL = nullptr; for (unsigned int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++) { - mCurrentBuffers[i] = NULL; + mCurrentBuffers[i] = nullptr; mCurrentVertexStrides[i] = static_cast(-1); mCurrentVertexOffsets[i] = static_cast(-1); } } -gl::Error InputLayoutCache::applyVertexBuffers(TranslatedAttribute attributes[gl::MAX_VERTEX_ATTRIBS], - GLenum mode, gl::Program *program) +gl::Error InputLayoutCache::applyVertexBuffers( + const gl::State &state, + const std::vector &vertexArrayAttribs, + const std::vector ¤tValueAttribs, + GLenum mode, + GLint start, + TranslatedIndexData *indexInfo, + GLsizei numIndicesPerInstance) { + ASSERT(mDevice && mDeviceContext); + + gl::Program *program = state.getProgram(); ProgramD3D *programD3D = GetImplAs(program); - int sortedSemanticIndices[gl::MAX_VERTEX_ATTRIBS]; - programD3D->sortAttributesByLayout(attributes, sortedSemanticIndices); bool programUsesInstancedPointSprites = programD3D->usesPointSize() && programD3D->usesInstancedPointSpriteEmulation(); bool instancedPointSpritesActive = programUsesInstancedPointSprites && (mode == GL_POINTS); - if (!mDevice || !mDeviceContext) - { - return gl::Error(GL_OUT_OF_MEMORY, "Internal input layout cache is not initialized."); - } - - InputLayoutKey ilKey = { 0 }; + AttribIndexArray sortedSemanticIndices; + SortAttributesByLayout(program, vertexArrayAttribs, currentValueAttribs, &sortedSemanticIndices, + &mCurrentAttributes); - static const char* semanticName = "TEXCOORD"; - - unsigned int firstIndexedElement = gl::MAX_VERTEX_ATTRIBS; - unsigned int firstInstancedElement = gl::MAX_VERTEX_ATTRIBS; - unsigned int nextAvailableInputSlot = 0; - - for (unsigned int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++) + // If we are using FL 9_3, make sure the first attribute is not instanced + if (mFeatureLevel <= D3D_FEATURE_LEVEL_9_3 && !mCurrentAttributes.empty()) { - if (attributes[i].active) + if (mCurrentAttributes[0]->divisor > 0) { - D3D11_INPUT_CLASSIFICATION inputClass = attributes[i].divisor > 0 ? D3D11_INPUT_PER_INSTANCE_DATA : D3D11_INPUT_PER_VERTEX_DATA; - // If rendering points and instanced pointsprite emulation is being used, the inputClass is required to be configured as per instance data - inputClass = instancedPointSpritesActive ? D3D11_INPUT_PER_INSTANCE_DATA : inputClass; - - gl::VertexFormat vertexFormat(*attributes[i].attribute, attributes[i].currentValueType); - const d3d11::VertexFormat &vertexFormatInfo = d3d11::GetVertexFormatInfo(vertexFormat, mFeatureLevel); - - // Record the type of the associated vertex shader vector in our key - // This will prevent mismatched vertex shaders from using the same input layout - GLint attributeSize; - program->getActiveAttribute(ilKey.elementCount, 0, NULL, &attributeSize, &ilKey.elements[ilKey.elementCount].glslElementType, NULL); - - ilKey.elements[ilKey.elementCount].desc.SemanticName = semanticName; - ilKey.elements[ilKey.elementCount].desc.SemanticIndex = sortedSemanticIndices[i]; - ilKey.elements[ilKey.elementCount].desc.Format = vertexFormatInfo.nativeFormat; - ilKey.elements[ilKey.elementCount].desc.InputSlot = i; - ilKey.elements[ilKey.elementCount].desc.AlignedByteOffset = 0; - ilKey.elements[ilKey.elementCount].desc.InputSlotClass = inputClass; - ilKey.elements[ilKey.elementCount].desc.InstanceDataStepRate = instancedPointSpritesActive ? 1 : attributes[i].divisor; - - if (inputClass == D3D11_INPUT_PER_VERTEX_DATA && firstIndexedElement == gl::MAX_VERTEX_ATTRIBS) + Optional firstNonInstancedIndex = FindFirstNonInstanced(mCurrentAttributes); + if (firstNonInstancedIndex.valid()) { - firstIndexedElement = ilKey.elementCount; + size_t index = firstNonInstancedIndex.value(); + std::swap(mCurrentAttributes[0], mCurrentAttributes[index]); + std::swap(sortedSemanticIndices[0], sortedSemanticIndices[index]); } - else if (inputClass == D3D11_INPUT_PER_INSTANCE_DATA && firstInstancedElement == gl::MAX_VERTEX_ATTRIBS) - { - firstInstancedElement = ilKey.elementCount; - } - - ilKey.elementCount++; - nextAvailableInputSlot = i + 1; } } - // 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) - { - ilKey.elements[ilKey.elementCount].desc.SemanticName = "SPRITEPOSITION"; - ilKey.elements[ilKey.elementCount].desc.SemanticIndex = 0; - ilKey.elements[ilKey.elementCount].desc.Format = DXGI_FORMAT_R32G32B32_FLOAT; - ilKey.elements[ilKey.elementCount].desc.InputSlot = nextAvailableInputSlot; - ilKey.elements[ilKey.elementCount].desc.AlignedByteOffset = 0; - ilKey.elements[ilKey.elementCount].desc.InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA; - ilKey.elements[ilKey.elementCount].desc.InstanceDataStepRate = 0; - - // The new elements are D3D11_INPUT_PER_VERTEX_DATA data so the indexed element - // tracking must be applied. This ensures that the instancing specific - // buffer swapping logic continues to work. - if (firstIndexedElement == gl::MAX_VERTEX_ATTRIBS) - { - firstIndexedElement = ilKey.elementCount; - } - - ilKey.elementCount++; - - ilKey.elements[ilKey.elementCount].desc.SemanticName = "SPRITETEXCOORD"; - ilKey.elements[ilKey.elementCount].desc.SemanticIndex = 0; - ilKey.elements[ilKey.elementCount].desc.Format = DXGI_FORMAT_R32G32_FLOAT; - ilKey.elements[ilKey.elementCount].desc.InputSlot = nextAvailableInputSlot; - ilKey.elements[ilKey.elementCount].desc.AlignedByteOffset = sizeof(float) * 3; - ilKey.elements[ilKey.elementCount].desc.InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA; - ilKey.elements[ilKey.elementCount].desc.InstanceDataStepRate = 0; + ANGLE_TRY(updateInputLayout(state, mode, sortedSemanticIndices, numIndicesPerInstance)); - ilKey.elementCount++; - } + bool dirtyBuffers = false; + size_t minDiff = gl::MAX_VERTEX_ATTRIBS; + size_t maxDiff = 0; - // 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. - ASSERT(!(mFeatureLevel <= D3D_FEATURE_LEVEL_9_3 && firstIndexedElement == gl::MAX_VERTEX_ATTRIBS)); - bool moveFirstIndexedIntoSlotZero = mFeatureLevel <= D3D_FEATURE_LEVEL_9_3 && firstInstancedElement == 0 && firstIndexedElement != gl::MAX_VERTEX_ATTRIBS; + // Note that if we use instance emulation, we reserve the first buffer slot. + size_t reservedBuffers = GetReservedBufferCount(programUsesInstancedPointSprites); - if (moveFirstIndexedIntoSlotZero) + for (size_t attribIndex = 0; attribIndex < (gl::MAX_VERTEX_ATTRIBS - reservedBuffers); + ++attribIndex) { - ilKey.elements[firstInstancedElement].desc.InputSlot = ilKey.elements[firstIndexedElement].desc.InputSlot; - ilKey.elements[firstIndexedElement].desc.InputSlot = 0; + ID3D11Buffer *buffer = nullptr; + UINT vertexStride = 0; + UINT vertexOffset = 0; - // Instanced PointSprite emulation uses multiple layout entries across a single vertex buffer. - // If an index swap is performed, we need to ensure that all elements get the proper InputSlot. - if (programUsesInstancedPointSprites) + if (attribIndex < mCurrentAttributes.size()) { - ilKey.elements[firstIndexedElement + 1].desc.InputSlot = 0; - } - } - - ID3D11InputLayout *inputLayout = NULL; - - InputLayoutMap::iterator keyIter = mInputLayoutMap.find(ilKey); - if (keyIter != mInputLayoutMap.end()) - { - inputLayout = keyIter->second.inputLayout; - keyIter->second.lastUsedTime = mCounter++; - } - else - { - gl::VertexFormat shaderInputLayout[gl::MAX_VERTEX_ATTRIBS]; - GetInputLayout(attributes, shaderInputLayout); - - ShaderExecutableD3D *shader = NULL; - gl::Error error = programD3D->getVertexExecutableForInputLayout(shaderInputLayout, &shader, nullptr); - if (error.isError()) - { - return error; - } - - ShaderExecutableD3D *shader11 = GetAs(shader); - - D3D11_INPUT_ELEMENT_DESC descs[gl::MAX_VERTEX_ATTRIBS]; - for (unsigned int j = 0; j < ilKey.elementCount; ++j) - { - descs[j] = ilKey.elements[j].desc; - } - - HRESULT result = mDevice->CreateInputLayout(descs, ilKey.elementCount, shader11->getFunction(), shader11->getLength(), &inputLayout); - if (FAILED(result)) - { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal input layout, HRESULT: 0x%08x", result); - } - - if (mInputLayoutMap.size() >= kMaxInputLayouts) - { - TRACE("Overflowed the limit of %u input layouts, removing the least recently used " - "to make room.", kMaxInputLayouts); - - InputLayoutMap::iterator leastRecentlyUsed = mInputLayoutMap.begin(); - for (InputLayoutMap::iterator i = mInputLayoutMap.begin(); i != mInputLayoutMap.end(); i++) + const auto &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) { - if (i->second.lastUsedTime < leastRecentlyUsed->second.lastUsedTime) + ASSERT(attrib.vertexBuffer.get()); + buffer = GetAs(attrib.vertexBuffer.get())->getBuffer(); + } + else if (instancedPointSpritesActive && (indexInfo != nullptr)) + { + if (indexInfo->srcIndexData.srcBuffer != nullptr) { - leastRecentlyUsed = i; + const uint8_t *bufferData = nullptr; + ANGLE_TRY(indexInfo->srcIndexData.srcBuffer->getData(&bufferData)); + ASSERT(bufferData != nullptr); + + ptrdiff_t offset = + reinterpret_cast(indexInfo->srcIndexData.srcIndices); + indexInfo->srcIndexData.srcBuffer = nullptr; + indexInfo->srcIndexData.srcIndices = bufferData + offset; } - } - SafeRelease(leastRecentlyUsed->second.inputLayout); - mInputLayoutMap.erase(leastRecentlyUsed); - } - - InputLayoutCounterPair inputCounterPair; - inputCounterPair.inputLayout = inputLayout; - inputCounterPair.lastUsedTime = mCounter++; - - mInputLayoutMap.insert(std::make_pair(ilKey, inputCounterPair)); - } - - if (inputLayout != mCurrentIL) - { - mDeviceContext->IASetInputLayout(inputLayout); - mCurrentIL = inputLayout; - } - - bool dirtyBuffers = false; - size_t minDiff = gl::MAX_VERTEX_ATTRIBS; - size_t maxDiff = 0; - unsigned int nextAvailableIndex = 0; - for (unsigned int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++) - { - ID3D11Buffer *buffer = NULL; - - if (attributes[i].active) - { - VertexBuffer11 *vertexBuffer = GetAs(attributes[i].vertexBuffer); - Buffer11 *bufferStorage = attributes[i].storage ? GetAs(attributes[i].storage) : NULL; + ANGLE_TRY_RESULT(bufferStorage->getEmulatedIndexedBuffer(&indexInfo->srcIndexData, + attrib, start), + buffer); + } + else + { + ANGLE_TRY_RESULT( + bufferStorage->getBuffer(BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK), buffer); + } - buffer = bufferStorage ? bufferStorage->getBuffer(BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK) - : vertexBuffer->getBuffer(); + vertexStride = attrib.stride; + ANGLE_TRY_RESULT(attrib.computeOffset(start), vertexOffset); } - UINT vertexStride = attributes[i].stride; - UINT vertexOffset = attributes[i].offset; + size_t bufferIndex = reservedBuffers + attribIndex; - if (buffer != mCurrentBuffers[i] || vertexStride != mCurrentVertexStrides[i] || - vertexOffset != mCurrentVertexOffsets[i]) + if (buffer != mCurrentBuffers[bufferIndex] || + vertexStride != mCurrentVertexStrides[bufferIndex] || + vertexOffset != mCurrentVertexOffsets[bufferIndex]) { dirtyBuffers = true; - minDiff = std::min(minDiff, static_cast(i)); - maxDiff = std::max(maxDiff, static_cast(i)); + minDiff = std::min(minDiff, bufferIndex); + maxDiff = std::max(maxDiff, bufferIndex); - mCurrentBuffers[i] = buffer; - mCurrentVertexStrides[i] = vertexStride; - mCurrentVertexOffsets[i] = vertexOffset; - - // If a non null ID3D11Buffer is being assigned to mCurrentBuffers, - // then the next available index needs to be tracked to ensure - // that any instanced pointsprite emulation buffers will be properly packed. - if (buffer) - { - nextAvailableIndex = i + 1; - } + mCurrentBuffers[bufferIndex] = buffer; + mCurrentVertexStrides[bufferIndex] = vertexStride; + mCurrentVertexOffsets[bufferIndex] = vertexOffset; } } - // 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. - if (instancedPointSpritesActive) + // 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) { HRESULT result = S_OK; const UINT pointSpriteVertexStride = sizeof(float) * 5; @@ -352,9 +369,16 @@ gl::Error InputLayoutCache::applyVertexBuffers(TranslatedAttribute attributes[gl } } - mCurrentBuffers[nextAvailableIndex] = mPointSpriteVertexBuffer; - mCurrentVertexStrides[nextAvailableIndex] = pointSpriteVertexStride; - mCurrentVertexOffsets[nextAvailableIndex] = 0; + mCurrentBuffers[0] = 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. + mCurrentVertexStrides[0] = instancedPointSpritesActive ? pointSpriteVertexStride : 0; + mCurrentVertexOffsets[0] = 0; + + // Update maxDiff to include the additional point sprite vertex buffer + // to ensure that IASetVertexBuffers uses the correct buffer count. + minDiff = 0; + maxDiff = std::max(maxDiff, static_cast(0)); if (!mPointSpriteIndexBuffer) { @@ -381,50 +405,246 @@ gl::Error InputLayoutCache::applyVertexBuffers(TranslatedAttribute attributes[gl } } - // 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. - mDeviceContext->IASetIndexBuffer(mPointSpriteIndexBuffer, DXGI_FORMAT_R16_UINT, 0); - } - - if (moveFirstIndexedIntoSlotZero) - { - // In this case, we swapped the slots of the first instanced element and the first indexed element, to ensure - // that the first slot contains non-instanced data (required by Feature Level 9_3). - // We must also swap the corresponding buffers sent to IASetVertexBuffers so that the correct data is sent to each slot. - std::swap(mCurrentBuffers[firstIndexedElement], mCurrentBuffers[firstInstancedElement]); - std::swap(mCurrentVertexStrides[firstIndexedElement], mCurrentVertexStrides[firstInstancedElement]); - std::swap(mCurrentVertexOffsets[firstIndexedElement], mCurrentVertexOffsets[firstInstancedElement]); + 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. + mDeviceContext->IASetIndexBuffer(mPointSpriteIndexBuffer, DXGI_FORMAT_R16_UINT, 0); + } } if (dirtyBuffers) { ASSERT(minDiff <= maxDiff && maxDiff < gl::MAX_VERTEX_ATTRIBS); - mDeviceContext->IASetVertexBuffers(minDiff, maxDiff - minDiff + 1, mCurrentBuffers + minDiff, - mCurrentVertexStrides + minDiff, mCurrentVertexOffsets + minDiff); + mDeviceContext->IASetVertexBuffers( + static_cast(minDiff), static_cast(maxDiff - minDiff + 1), + &mCurrentBuffers[minDiff], &mCurrentVertexStrides[minDiff], + &mCurrentVertexOffsets[minDiff]); } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -std::size_t InputLayoutCache::hashInputLayout(const InputLayoutKey &inputLayout) +gl::Error InputLayoutCache::updateVertexOffsetsForPointSpritesEmulation(GLint startVertex, + GLsizei emulatedInstanceId) { - static const unsigned int seed = 0xDEADBEEF; + 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_RESULT(attrib.computeOffset(startVertex), offset); + mCurrentVertexOffsets[bufferIndex] = + offset + (attrib.stride * (emulatedInstanceId / attrib.divisor)); + } + } - std::size_t hash = 0; - MurmurHash3_x86_32(inputLayout.begin(), static_cast(inputLayout.end() - inputLayout.begin()), seed, &hash); - return hash; + mDeviceContext->IASetVertexBuffers(0, gl::MAX_VERTEX_ATTRIBS, mCurrentBuffers.data(), + mCurrentVertexStrides.data(), mCurrentVertexOffsets.data()); + + return gl::NoError(); } -bool InputLayoutCache::compareInputLayouts(const InputLayoutKey &a, const InputLayoutKey &b) +gl::Error InputLayoutCache::updateInputLayout(const gl::State &state, + GLenum mode, + const AttribIndexArray &sortedSemanticIndices, + GLsizei numIndicesPerInstance) { - if (a.elementCount != b.elementCount) + 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_POINTS); + + if (programUsesInstancedPointSprites) { - return false; + layout.flags |= PackedAttributeLayout::FLAG_USES_INSTANCED_SPRITES; } - return std::equal(a.begin(), a.end(), b.begin()); + if (instancedPointSpritesActive) + { + layout.flags |= PackedAttributeLayout::FLAG_INSTANCED_SPRITES_ACTIVE; + } + + if (numIndicesPerInstance > 0) + { + layout.flags |= PackedAttributeLayout::FLAG_INSTANCED_RENDERING_ACTIVE; + } + + const auto &attribs = state.getVertexArray()->getVertexAttributes(); + const auto &locationToSemantic = programD3D->getAttribLocationToD3DSemantics(); + + for (unsigned long attribIndex : angle::IterateBitSet(program->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]; + int d3dSemantic = locationToSemantic[attribIndex]; + + const auto ¤tValue = state.getVertexAttribCurrentValue(attribIndex); + gl::VertexFormatType vertexFormatType = gl::GetVertexFormatType(attrib, currentValue.Type); + + layout.addAttributeData(glslElementType, d3dSemantic, vertexFormatType, attrib.divisor); + } + + ID3D11InputLayout *inputLayout = nullptr; + if (layout.numAttributes > 0 || layout.flags != 0) + { + auto layoutMapIt = mLayoutMap.find(layout); + if (layoutMapIt != mLayoutMap.end()) + { + inputLayout = layoutMapIt->second; + } + else + { + ANGLE_TRY(createInputLayout(sortedSemanticIndices, mode, program, numIndicesPerInstance, + &inputLayout)); + if (mLayoutMap.size() >= mCacheSize) + { + TRACE("Overflowed the limit of %u input layouts, purging half the cache.", + mCacheSize); + + // Randomly release every second element + auto it = mLayoutMap.begin(); + while (it != mLayoutMap.end()) + { + it++; + if (it != mLayoutMap.end()) + { + // c++11 erase allows us to easily delete the current iterator. + SafeRelease(it->second); + it = mLayoutMap.erase(it); + } + } + } + + mLayoutMap[layout] = inputLayout; + } + } + + if (inputLayout != mCurrentIL) + { + mDeviceContext->IASetInputLayout(inputLayout); + mCurrentIL = inputLayout; + } + + return gl::NoError(); } +gl::Error InputLayoutCache::createInputLayout(const AttribIndexArray &sortedSemanticIndices, + GLenum mode, + gl::Program *program, + GLsizei numIndicesPerInstance, + ID3D11InputLayout **inputLayoutOut) +{ + ProgramD3D *programD3D = GetImplAs(program); + + bool programUsesInstancedPointSprites = + programD3D->usesPointSize() && programD3D->usesInstancedPointSpriteEmulation(); + + unsigned int inputElementCount = 0; + std::array inputElements; + + for (size_t attribIndex = 0; attribIndex < mCurrentAttributes.size(); ++attribIndex) + { + const auto &attrib = *mCurrentAttributes[attribIndex]; + const int sortedIndex = sortedSemanticIndices[attribIndex]; + + D3D11_INPUT_CLASSIFICATION inputClass = + attrib.divisor > 0 ? D3D11_INPUT_PER_INSTANCE_DATA : D3D11_INPUT_PER_VERTEX_DATA; + + const auto &vertexFormatType = + gl::GetVertexFormatType(*attrib.attribute, attrib.currentValueType); + const auto &vertexFormatInfo = d3d11::GetVertexFormatInfo(vertexFormatType, mFeatureLevel); + + 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. + 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_POINTS) + { + inputElements[elementIndex].InputSlotClass = D3D11_INPUT_PER_INSTANCE_DATA; + inputElements[elementIndex].InstanceDataStepRate = 1; + if (numIndicesPerInstance > 0 && mCurrentAttributes[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++; + } + + const gl::InputLayout &shaderInputLayout = GetInputLayout(mCurrentAttributes); + + ShaderExecutableD3D *shader = nullptr; + ANGLE_TRY(programD3D->getVertexExecutableForInputLayout(shaderInputLayout, &shader, nullptr)); + + ShaderExecutableD3D *shader11 = GetAs(shader); + + HRESULT result = + mDevice->CreateInputLayout(inputElements.data(), inputElementCount, shader11->getFunction(), + shader11->getLength(), inputLayoutOut); + if (FAILED(result)) + { + return gl::Error(GL_OUT_OF_MEMORY, + "Failed to create internal input layout, HRESULT: 0x%08x", result); + } + + return gl::NoError(); } + +} // namespace rx diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/InputLayoutCache.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/InputLayoutCache.h index 2c94c57595d1..62a1020f5036 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/InputLayoutCache.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/InputLayoutCache.h @@ -10,14 +10,18 @@ #ifndef LIBANGLE_RENDERER_D3D_D3D11_INPUTLAYOUTCACHE_H_ #define LIBANGLE_RENDERER_D3D_D3D11_INPUTLAYOUTCACHE_H_ -#include "libANGLE/Constants.h" -#include "libANGLE/Error.h" -#include "common/angleutils.h" - #include #include -#include + +#include +#include + +#include "common/angleutils.h" +#include "libANGLE/Constants.h" +#include "libANGLE/Error.h" +#include "libANGLE/formatutils.h" +#include "libANGLE/renderer/d3d/RendererD3D.h" namespace gl { @@ -27,6 +31,9 @@ class Program; namespace rx { struct TranslatedAttribute; +struct TranslatedIndexData; +struct SourceIndexData; +class ProgramD3D; class InputLayoutCache : angle::NonCopyable { @@ -38,66 +45,76 @@ class InputLayoutCache : angle::NonCopyable void clear(); void markDirty(); - gl::Error applyVertexBuffers(TranslatedAttribute attributes[gl::MAX_VERTEX_ATTRIBS], - GLenum mode, gl::Program *program); + gl::Error applyVertexBuffers(const gl::State &state, + const std::vector &vertexArrayAttribs, + const std::vector ¤tValueAttribs, + GLenum mode, + GLint start, + TranslatedIndexData *indexInfo, + GLsizei numIndicesPerInstance); - private: - struct InputLayoutElement - { - D3D11_INPUT_ELEMENT_DESC desc; - GLenum glslElementType; - }; + gl::Error updateVertexOffsetsForPointSpritesEmulation(GLint startVertex, + GLsizei emulatedInstanceId); - struct InputLayoutKey - { - unsigned int elementCount; - InputLayoutElement elements[gl::MAX_VERTEX_ATTRIBS]; + // Useful for testing + void setCacheSize(unsigned int cacheSize) { mCacheSize = cacheSize; } - const char *begin() const + private: + struct PackedAttributeLayout + { + PackedAttributeLayout() + : numAttributes(0), + flags(0) { - return reinterpret_cast(&elementCount); } - const char *end() const + void addAttributeData(GLenum glType, + UINT semanticIndex, + gl::VertexFormatType vertexFormatType, + unsigned int divisor); + + bool operator<(const PackedAttributeLayout &other) const; + + enum Flags { - return reinterpret_cast(&elements[elementCount]); - } + FLAG_USES_INSTANCED_SPRITES = 0x1, + FLAG_INSTANCED_SPRITES_ACTIVE = 0x2, + FLAG_INSTANCED_RENDERING_ACTIVE = 0x4, + }; + + size_t numAttributes; + unsigned int flags; + uint32_t attributeData[gl::MAX_VERTEX_ATTRIBS]; }; - struct InputLayoutCounterPair - { - ID3D11InputLayout *inputLayout; - unsigned long long lastUsedTime; - }; + gl::Error updateInputLayout(const gl::State &state, + GLenum mode, + const AttribIndexArray &sortedSemanticIndices, + GLsizei numIndicesPerInstance); + gl::Error createInputLayout(const AttribIndexArray &sortedSemanticIndices, + GLenum mode, + gl::Program *program, + GLsizei numIndicesPerInstance, + ID3D11InputLayout **inputLayoutOut); + + std::map mLayoutMap; ID3D11InputLayout *mCurrentIL; - ID3D11Buffer *mCurrentBuffers[gl::MAX_VERTEX_ATTRIBS]; - UINT mCurrentVertexStrides[gl::MAX_VERTEX_ATTRIBS]; - UINT mCurrentVertexOffsets[gl::MAX_VERTEX_ATTRIBS]; + std::array mCurrentBuffers; + std::array mCurrentVertexStrides; + std::array mCurrentVertexOffsets; + std::vector mCurrentAttributes; ID3D11Buffer *mPointSpriteVertexBuffer; ID3D11Buffer *mPointSpriteIndexBuffer; - static std::size_t hashInputLayout(const InputLayoutKey &inputLayout); - static bool compareInputLayouts(const InputLayoutKey &a, const InputLayoutKey &b); - - typedef std::size_t (*InputLayoutHashFunction)(const InputLayoutKey &); - typedef bool (*InputLayoutEqualityFunction)(const InputLayoutKey &, const InputLayoutKey &); - typedef std::unordered_map InputLayoutMap; - InputLayoutMap mInputLayoutMap; - - static const unsigned int kMaxInputLayouts; - - unsigned long long mCounter; + unsigned int mCacheSize; ID3D11Device *mDevice; ID3D11DeviceContext *mDeviceContext; D3D_FEATURE_LEVEL mFeatureLevel; }; -} +} // namespace rx #endif // LIBANGLE_RENDERER_D3D_D3D11_INPUTLAYOUTCACHE_H_ diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/NativeWindow.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/NativeWindow.h index ce50c320dd7a..f28ce4f82759 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/NativeWindow.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/NativeWindow.h @@ -16,6 +16,7 @@ #include "common/platform.h" #include +#include "libANGLE/Config.h" // DXGISwapChain and DXGIFactory are typedef'd to specific required // types. The HWND NativeWindow implementation requires IDXGISwapChain @@ -43,14 +44,21 @@ typedef IDXGISwapChain DXGISwapChain; typedef IDXGIFactory DXGIFactory; #endif +typedef interface IDCompositionDevice IDCompositionDevice; +typedef interface IDCompositionTarget IDCompositionTarget; +typedef interface IDCompositionVisual IDCompositionVisual; + namespace rx { class NativeWindow { public: - explicit NativeWindow(EGLNativeWindowType window); + explicit NativeWindow(EGLNativeWindowType window, + const egl::Config *config, + bool directComposition); + ~NativeWindow(); bool initialize(); bool getClientRect(LPRECT rect); bool isIconic(); @@ -62,9 +70,16 @@ class NativeWindow inline EGLNativeWindowType getNativeWindow() const { return mWindow; } + void commitChange(); + private: EGLNativeWindowType mWindow; + bool mDirectComposition; + IDCompositionDevice *mDevice; + IDCompositionTarget *mCompositionTarget; + IDCompositionVisual *mVisual; + const egl::Config *mConfig; #if defined(ANGLE_ENABLE_WINDOWS_STORE) std::shared_ptr mImpl; #endif diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/PixelTransfer11.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/PixelTransfer11.cpp index fcaecad5bc8b..f73b8aa61225 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/PixelTransfer11.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/PixelTransfer11.cpp @@ -10,23 +10,25 @@ // #include "libANGLE/renderer/d3d/d3d11/PixelTransfer11.h" + +#include "libANGLE/Buffer.h" +#include "libANGLE/Context.h" +#include "libANGLE/formatutils.h" +#include "libANGLE/renderer/d3d/d3d11/Buffer11.h" +#include "libANGLE/renderer/d3d/d3d11/formatutils11.h" #include "libANGLE/renderer/d3d/d3d11/Renderer11.h" #include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h" -#include "libANGLE/renderer/d3d/d3d11/formatutils11.h" -#include "libANGLE/renderer/d3d/d3d11/Buffer11.h" -#include "libANGLE/renderer/d3d/d3d11/TextureStorage11.h" #include "libANGLE/renderer/d3d/d3d11/RenderTarget11.h" -#include "libANGLE/formatutils.h" +#include "libANGLE/renderer/d3d/d3d11/texture_format_table.h" +#include "libANGLE/renderer/d3d/d3d11/TextureStorage11.h" #include "libANGLE/Texture.h" -#include "libANGLE/Buffer.h" -#include "libANGLE/Context.h" // Precompiled shaders -#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/buffertotexture11_vs.h" #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 { @@ -62,7 +64,7 @@ gl::Error PixelTransfer11::loadResources() { if (mResourcesLoaded) { - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } HRESULT result = S_OK; @@ -139,17 +141,13 @@ gl::Error PixelTransfer11::loadResources() return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal buffer to texture geometry shader."); } - gl::Error error = buildShaderMap(); - if (error.isError()) - { - return error; - } + ANGLE_TRY(buildShaderMap()); StructZero(&mParamsData); mResourcesLoaded = true; - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } void PixelTransfer11::setBufferToTextureCopyParams(const gl::Box &destArea, const gl::Extents &destSize, GLenum internalFormat, @@ -178,11 +176,7 @@ void PixelTransfer11::setBufferToTextureCopyParams(const gl::Box &destArea, cons gl::Error PixelTransfer11::copyBufferToTexture(const gl::PixelUnpackState &unpack, unsigned int offset, RenderTargetD3D *destRenderTarget, GLenum destinationFormat, GLenum sourcePixelsType, const gl::Box &destArea) { - gl::Error error = loadResources(); - if (error.isError()) - { - return error; - } + ANGLE_TRY(loadResources()); gl::Extents destSize = destRenderTarget->getExtents(); @@ -202,31 +196,33 @@ gl::Error PixelTransfer11::copyBufferToTexture(const gl::PixelUnpackState &unpac GLenum unsizedFormat = gl::GetInternalFormatInfo(destinationFormat).format; GLenum sourceFormat = gl::GetSizedInternalFormat(unsizedFormat, sourcePixelsType); - const d3d11::TextureFormat &sourceFormatInfo = d3d11::GetTextureFormatInfo(sourceFormat, mRenderer->getFeatureLevel()); - DXGI_FORMAT srvFormat = sourceFormatInfo.srvFormat; + const d3d11::TextureFormat &sourceFormatInfo = d3d11::GetTextureFormatInfo(sourceFormat, mRenderer->getRenderer11DeviceCaps()); + DXGI_FORMAT srvFormat = sourceFormatInfo.formatSet->srvFormat; ASSERT(srvFormat != DXGI_FORMAT_UNKNOWN); Buffer11 *bufferStorage11 = GetAs(sourceBuffer.getImplementation()); - ID3D11ShaderResourceView *bufferSRV = bufferStorage11->getSRV(srvFormat); - ASSERT(bufferSRV != NULL); + ID3D11ShaderResourceView *bufferSRV = nullptr; + ANGLE_TRY_RESULT(bufferStorage11->getSRV(srvFormat), bufferSRV); + ASSERT(bufferSRV != nullptr); ID3D11RenderTargetView *textureRTV = GetAs(destRenderTarget)->getRenderTargetView(); - ASSERT(textureRTV != NULL); + ASSERT(textureRTV != nullptr); CopyShaderParams shaderParams; setBufferToTextureCopyParams(destArea, destSize, sourceFormat, unpack, offset, &shaderParams); ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); - ID3D11Buffer *nullBuffer = NULL; + ID3D11Buffer *nullBuffer = nullptr; UINT zero = 0; // Are we doing a 2D or 3D copy? ID3D11GeometryShader *geometryShader = ((destSize.depth > 1) ? mBufferToTextureGS : NULL); + auto stateManager = mRenderer->getStateManager(); deviceContext->VSSetShader(mBufferToTextureVS, NULL, 0); deviceContext->GSSetShader(geometryShader, NULL, 0); deviceContext->PSSetShader(pixelShader, NULL, 0); - mRenderer->setShaderResource(gl::SAMPLER_PIXEL, 0, bufferSRV); + stateManager->setShaderResource(gl::SAMPLER_PIXEL, 0, bufferSRV); deviceContext->IASetInputLayout(NULL); deviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_POINTLIST); @@ -235,7 +231,7 @@ gl::Error PixelTransfer11::copyBufferToTexture(const gl::PixelUnpackState &unpac deviceContext->OMSetDepthStencilState(mCopyDepthStencilState, 0xFFFFFFFF); deviceContext->RSSetState(mCopyRasterizerState); - mRenderer->setOneTimeRenderTarget(textureRTV); + stateManager->setOneTimeRenderTarget(textureRTV, nullptr); if (!StructEquals(mParamsData, shaderParams)) { @@ -259,12 +255,12 @@ gl::Error PixelTransfer11::copyBufferToTexture(const gl::PixelUnpackState &unpac deviceContext->Draw(numPixels, 0); // Unbind textures and render targets and vertex buffer - mRenderer->setShaderResource(gl::SAMPLER_PIXEL, 0, NULL); + stateManager->setShaderResource(gl::SAMPLER_PIXEL, 0, NULL); deviceContext->VSSetConstantBuffers(0, 1, &nullBuffer); mRenderer->markAllStateDirty(); - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } gl::Error PixelTransfer11::buildShaderMap() @@ -284,7 +280,7 @@ gl::Error PixelTransfer11::buildShaderMap() } } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } ID3D11PixelShader *PixelTransfer11::findBufferToTexturePS(GLenum internalFormat) const @@ -299,4 +295,4 @@ ID3D11PixelShader *PixelTransfer11::findBufferToTexturePS(GLenum internalFormat) return (shaderMapIt == mBufferToTexturePSMap.end() ? NULL : shaderMapIt->second); } -} +} // namespace rx diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/Query11.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/Query11.cpp index e0101902efc5..dad5f8ca72c9 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/Query11.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/Query11.cpp @@ -13,102 +13,248 @@ #include +namespace +{ + +GLuint64 MergeQueryResults(GLenum type, GLuint64 currentResult, GLuint64 newResult) +{ + switch (type) + { + case GL_ANY_SAMPLES_PASSED: + case GL_ANY_SAMPLES_PASSED_CONSERVATIVE: + return (currentResult == GL_TRUE || newResult == GL_TRUE) ? GL_TRUE : GL_FALSE; + + case GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN: + return currentResult + newResult; + + case GL_TIME_ELAPSED_EXT: + return currentResult + newResult; + + case GL_TIMESTAMP_EXT: + return newResult; + + default: + UNREACHABLE(); + return 0; + } +} + +} // anonymous namespace + namespace rx { +Query11::QueryState::QueryState() + : query(nullptr), beginTimestamp(nullptr), endTimestamp(nullptr), finished(false) +{ +} + +Query11::QueryState::~QueryState() +{ + SafeRelease(beginTimestamp); + SafeRelease(endTimestamp); + SafeRelease(query); +} + Query11::Query11(Renderer11 *renderer, GLenum type) - : QueryImpl(type), - mResult(0), - mQueryFinished(false), - mRenderer(renderer), - mQuery(NULL) + : QueryImpl(type), mResult(0), mResultSum(0), mRenderer(renderer) { + mActiveQuery = std::unique_ptr(new QueryState()); } Query11::~Query11() { - SafeRelease(mQuery); + mRenderer->getStateManager()->onDeleteQueryObject(this); } gl::Error Query11::begin() { - if (mQuery == NULL) - { - D3D11_QUERY_DESC queryDesc; - queryDesc.Query = gl_d3d11::ConvertQueryType(getType()); - queryDesc.MiscFlags = 0; + mResultSum = 0; + mRenderer->getStateManager()->onBeginQuery(this); + return resume(); +} - HRESULT result = mRenderer->getDevice()->CreateQuery(&queryDesc, &mQuery); - if (FAILED(result)) - { - return gl::Error(GL_OUT_OF_MEMORY, "Internal query creation failed, result: 0x%X.", result); - } - } +gl::Error Query11::end() +{ + return pause(); +} - mRenderer->getDeviceContext()->Begin(mQuery); +gl::Error Query11::queryCounter() +{ + // This doesn't do anything for D3D11 as we don't support timestamps + ASSERT(getType() == GL_TIMESTAMP_EXT); + mResultSum = 0; + mPendingQueries.push_back(std::unique_ptr(new QueryState())); return gl::Error(GL_NO_ERROR); } -gl::Error Query11::end() +template +gl::Error Query11::getResultBase(T *params) { - ASSERT(mQuery); - mRenderer->getDeviceContext()->End(mQuery); + ASSERT(mActiveQuery->query == nullptr); + + gl::Error error = flush(true); + if (error.isError()) + { + return error; + } - mQueryFinished = false; - mResult = GL_FALSE; + ASSERT(mPendingQueries.empty()); + *params = static_cast(mResultSum); return gl::Error(GL_NO_ERROR); } +gl::Error Query11::getResult(GLint *params) +{ + return getResultBase(params); +} + gl::Error Query11::getResult(GLuint *params) { - while (!mQueryFinished) + return getResultBase(params); +} + +gl::Error Query11::getResult(GLint64 *params) +{ + return getResultBase(params); +} + +gl::Error Query11::getResult(GLuint64 *params) +{ + return getResultBase(params); +} + +gl::Error Query11::isResultAvailable(bool *available) +{ + gl::Error error = flush(false); + if (error.isError()) + { + return error; + } + + *available = mPendingQueries.empty(); + return gl::Error(GL_NO_ERROR); +} + +gl::Error Query11::pause() +{ + if (mActiveQuery->query != nullptr) { - gl::Error error = testQuery(); + ID3D11DeviceContext *context = mRenderer->getDeviceContext(); + + // If we are doing time elapsed query the end timestamp + if (getType() == GL_TIME_ELAPSED_EXT) + { + context->End(mActiveQuery->endTimestamp); + } + + context->End(mActiveQuery->query); + + mPendingQueries.push_back(std::move(mActiveQuery)); + mActiveQuery = std::unique_ptr(new QueryState()); + } + + return flush(false); +} + +gl::Error Query11::resume() +{ + if (mActiveQuery->query == nullptr) + { + gl::Error error = flush(false); if (error.isError()) { return error; } - if (!mQueryFinished) + D3D11_QUERY_DESC queryDesc; + queryDesc.Query = gl_d3d11::ConvertQueryType(getType()); + queryDesc.MiscFlags = 0; + + ID3D11Device *device = mRenderer->getDevice(); + + HRESULT result = device->CreateQuery(&queryDesc, &mActiveQuery->query); + if (FAILED(result)) { - ScheduleYield(); + return gl::Error(GL_OUT_OF_MEMORY, "Internal query creation failed, result: 0x%X.", + result); + } + + // If we are doing time elapsed we also need a query to actually query the timestamp + if (getType() == GL_TIME_ELAPSED_EXT) + { + D3D11_QUERY_DESC desc; + desc.Query = D3D11_QUERY_TIMESTAMP; + desc.MiscFlags = 0; + result = device->CreateQuery(&desc, &mActiveQuery->beginTimestamp); + if (FAILED(result)) + { + return gl::Error(GL_OUT_OF_MEMORY, "Internal query creation failed, result: 0x%X.", + result); + } + result = device->CreateQuery(&desc, &mActiveQuery->endTimestamp); + if (FAILED(result)) + { + return gl::Error(GL_OUT_OF_MEMORY, "Internal query creation failed, result: 0x%X.", + result); + } } - } - ASSERT(mQueryFinished); - *params = mResult; + ID3D11DeviceContext *context = mRenderer->getDeviceContext(); + + context->Begin(mActiveQuery->query); + + // If we are doing time elapsed, query the begin timestamp + if (getType() == GL_TIME_ELAPSED_EXT) + { + context->End(mActiveQuery->beginTimestamp); + } + } return gl::Error(GL_NO_ERROR); } -gl::Error Query11::isResultAvailable(GLuint *available) +gl::Error Query11::flush(bool force) { - gl::Error error = testQuery(); - if (error.isError()) + while (!mPendingQueries.empty()) { - return error; - } + QueryState *query = mPendingQueries.front().get(); - *available = (mQueryFinished ? GL_TRUE : GL_FALSE); + do + { + gl::Error error = testQuery(query); + if (error.isError()) + { + return error; + } + if (!query->finished && !force) + { + return gl::Error(GL_NO_ERROR); + } + } while (!query->finished); + + mResultSum = MergeQueryResults(getType(), mResultSum, mResult); + mPendingQueries.pop_front(); + } return gl::Error(GL_NO_ERROR); } -gl::Error Query11::testQuery() +gl::Error Query11::testQuery(QueryState *queryState) { - if (!mQueryFinished) + if (!queryState->finished) { - ASSERT(mQuery); - ID3D11DeviceContext *context = mRenderer->getDeviceContext(); switch (getType()) { case GL_ANY_SAMPLES_PASSED_EXT: case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT: { + ASSERT(queryState->query); UINT64 numPixels = 0; - HRESULT result = context->GetData(mQuery, &numPixels, sizeof(numPixels), 0); + HRESULT result = + context->GetData(queryState->query, &numPixels, sizeof(numPixels), 0); if (FAILED(result)) { return gl::Error(GL_OUT_OF_MEMORY, "Failed to get the data of an internal query, result: 0x%X.", result); @@ -116,7 +262,7 @@ gl::Error Query11::testQuery() if (result == S_OK) { - mQueryFinished = true; + queryState->finished = true; mResult = (numPixels > 0) ? GL_TRUE : GL_FALSE; } } @@ -124,8 +270,9 @@ gl::Error Query11::testQuery() case GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN: { + ASSERT(queryState->query); D3D11_QUERY_DATA_SO_STATISTICS soStats = { 0 }; - HRESULT result = context->GetData(mQuery, &soStats, sizeof(soStats), 0); + HRESULT result = context->GetData(queryState->query, &soStats, sizeof(soStats), 0); if (FAILED(result)) { return gl::Error(GL_OUT_OF_MEMORY, "Failed to get the data of an internal query, result: 0x%X.", result); @@ -133,18 +280,90 @@ gl::Error Query11::testQuery() if (result == S_OK) { - mQueryFinished = true; - mResult = static_cast(soStats.NumPrimitivesWritten); + queryState->finished = true; + mResult = static_cast(soStats.NumPrimitivesWritten); } } break; + case GL_TIME_ELAPSED_EXT: + { + ASSERT(queryState->query); + ASSERT(queryState->beginTimestamp); + ASSERT(queryState->endTimestamp); + D3D11_QUERY_DATA_TIMESTAMP_DISJOINT timeStats = {0}; + HRESULT result = + context->GetData(queryState->query, &timeStats, sizeof(timeStats), 0); + if (FAILED(result)) + { + return gl::Error(GL_OUT_OF_MEMORY, + "Failed to get the data of an internal query, result: 0x%X.", + result); + } + + if (result == S_OK) + { + UINT64 beginTime = 0; + HRESULT beginRes = + context->GetData(queryState->beginTimestamp, &beginTime, sizeof(UINT64), 0); + if (FAILED(beginRes)) + { + return gl::Error( + GL_OUT_OF_MEMORY, + "Failed to get the data of an internal query, result: 0x%X.", beginRes); + } + UINT64 endTime = 0; + HRESULT endRes = + context->GetData(queryState->endTimestamp, &endTime, sizeof(UINT64), 0); + if (FAILED(endRes)) + { + return gl::Error( + GL_OUT_OF_MEMORY, + "Failed to get the data of an internal query, result: 0x%X.", endRes); + } + + 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"); + if (rx::IsUnsignedMultiplicationSafe(endTime - beginTime, 1000000000ull)) + { + mResult = ((endTime - beginTime) * 1000000000ull) / timeStats.Frequency; + } + 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_TIMESTAMP_EXT: + { + // 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 == nullptr); + mResult = 0; + queryState->finished = true; + } + break; + default: UNREACHABLE(); break; } - if (!mQueryFinished && mRenderer->testDeviceLost()) + if (!queryState->finished && mRenderer->testDeviceLost()) { mRenderer->notifyDeviceLost(); return gl::Error(GL_OUT_OF_MEMORY, "Failed to test get query result, device is lost."); diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/Query11.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/Query11.h index bd53fed250bf..706f805df11d 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/Query11.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/Query11.h @@ -9,6 +9,8 @@ #ifndef LIBANGLE_RENDERER_D3D_D3D11_QUERY11_H_ #define LIBANGLE_RENDERER_D3D_D3D11_QUERY11_H_ +#include + #include "libANGLE/renderer/QueryImpl.h" namespace rx @@ -19,22 +21,45 @@ class Query11 : public QueryImpl { public: Query11(Renderer11 *renderer, GLenum type); - virtual ~Query11(); + ~Query11() override; + + gl::Error begin() override; + gl::Error end() override; + gl::Error queryCounter() override; + gl::Error getResult(GLint *params) override; + gl::Error getResult(GLuint *params) override; + gl::Error getResult(GLint64 *params) override; + gl::Error getResult(GLuint64 *params) override; + gl::Error isResultAvailable(bool *available) override; - virtual gl::Error begin(); - virtual gl::Error end(); - virtual gl::Error getResult(GLuint *params); - virtual gl::Error isResultAvailable(GLuint *available); + gl::Error pause(); + gl::Error resume(); private: - gl::Error testQuery(); + struct QueryState final : public angle::NonCopyable + { + QueryState(); + ~QueryState(); + + ID3D11Query *query; + ID3D11Query *beginTimestamp; + ID3D11Query *endTimestamp; + bool finished; + }; - GLuint mResult; + gl::Error flush(bool force); + gl::Error testQuery(QueryState *queryState); - bool mQueryFinished; + template + gl::Error getResultBase(T *params); + + GLuint64 mResult; + GLuint64 mResultSum; Renderer11 *mRenderer; - ID3D11Query *mQuery; + + std::unique_ptr mActiveQuery; + std::deque> mPendingQueries; }; } diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/RenderStateCache.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/RenderStateCache.cpp index a4d883748877..2ee25cfb6c20 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/RenderStateCache.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/RenderStateCache.cpp @@ -21,6 +21,7 @@ namespace rx { +using namespace gl_d3d11; template static void ClearStateMap(mapType &map) @@ -42,12 +43,12 @@ const unsigned int RenderStateCache::kMaxSamplerStates = 4096; RenderStateCache::RenderStateCache(Renderer11 *renderer) : mRenderer(renderer), - mDevice(NULL), mCounter(0), mBlendStateCache(kMaxBlendStates, hashBlendState, compareBlendStates), mRasterizerStateCache(kMaxRasterizerStates, hashRasterizerState, compareRasterizerStates), mDepthStencilStateCache(kMaxDepthStencilStates, hashDepthStencilState, compareDepthStencilStates), - mSamplerStateCache(kMaxSamplerStates, hashSamplerState, compareSamplerStates) + mSamplerStateCache(kMaxSamplerStates, hashSamplerState, compareSamplerStates), + mDevice(NULL) { } @@ -95,9 +96,9 @@ gl::Error RenderStateCache::getBlendState(const gl::Framebuffer *framebuffer, co bool mrt = false; const FramebufferD3D *framebufferD3D = GetImplAs(framebuffer); - const gl::AttachmentList &colorbuffers = framebufferD3D->getColorAttachmentsForRender(mRenderer->getWorkarounds()); + const gl::AttachmentList &colorbuffers = framebufferD3D->getColorAttachmentsForRender(); - BlendStateKey key = { 0 }; + BlendStateKey key = {}; key.blendState = blendState; for (size_t colorAttachment = 0; colorAttachment < colorbuffers.size(); ++colorAttachment) { @@ -209,7 +210,7 @@ gl::Error RenderStateCache::getRasterizerState(const gl::RasterizerState &raster return gl::Error(GL_OUT_OF_MEMORY, "Internal error, RenderStateCache is not initialized."); } - RasterizerStateKey key = { 0 }; + RasterizerStateKey key = {}; key.rasterizerState = rasterState; key.scissorEnabled = scissorEnabled; @@ -297,14 +298,31 @@ bool RenderStateCache::compareDepthStencilStates(const gl::DepthStencilState &a, return memcmp(&a, &b, sizeof(gl::DepthStencilState)) == 0; } -gl::Error RenderStateCache::getDepthStencilState(const gl::DepthStencilState &dsState, ID3D11DepthStencilState **outDSState) +gl::Error RenderStateCache::getDepthStencilState(const gl::DepthStencilState &originalState, + bool disableDepth, + bool disableStencil, + ID3D11DepthStencilState **outDSState) { if (!mDevice) { return gl::Error(GL_OUT_OF_MEMORY, "Internal error, RenderStateCache is not initialized."); } - DepthStencilStateMap::iterator keyIter = mDepthStencilStateCache.find(dsState); + gl::DepthStencilState glState = originalState; + if (disableDepth) + { + glState.depthTest = false; + glState.depthMask = false; + } + + if (disableStencil) + { + glState.stencilWritemask = 0; + glState.stencilBackWritemask = 0; + glState.stencilTest = false; + } + + auto keyIter = mDepthStencilStateCache.find(glState); if (keyIter != mDepthStencilStateCache.end()) { DepthStencilStateCounterPair &state = keyIter->second; @@ -312,53 +330,55 @@ gl::Error RenderStateCache::getDepthStencilState(const gl::DepthStencilState &ds *outDSState = state.first; return gl::Error(GL_NO_ERROR); } - else + + if (mDepthStencilStateCache.size() >= kMaxDepthStencilStates) { - if (mDepthStencilStateCache.size() >= kMaxDepthStencilStates) - { - TRACE("Overflowed the limit of %u depth stencil states, removing the least recently used " - "to make room.", kMaxDepthStencilStates); + TRACE( + "Overflowed the limit of %u depth stencil states, removing the least recently used " + "to make room.", + kMaxDepthStencilStates); - DepthStencilStateMap::iterator leastRecentlyUsed = mDepthStencilStateCache.begin(); - for (DepthStencilStateMap::iterator i = mDepthStencilStateCache.begin(); i != mDepthStencilStateCache.end(); i++) + auto leastRecentlyUsed = mDepthStencilStateCache.begin(); + for (auto i = mDepthStencilStateCache.begin(); i != mDepthStencilStateCache.end(); i++) + { + if (i->second.second < leastRecentlyUsed->second.second) { - if (i->second.second < leastRecentlyUsed->second.second) - { - leastRecentlyUsed = i; - } + leastRecentlyUsed = i; } - SafeRelease(leastRecentlyUsed->second.first); - mDepthStencilStateCache.erase(leastRecentlyUsed); } + SafeRelease(leastRecentlyUsed->second.first); + mDepthStencilStateCache.erase(leastRecentlyUsed); + } - D3D11_DEPTH_STENCIL_DESC dsDesc = { 0 }; - dsDesc.DepthEnable = dsState.depthTest ? TRUE : FALSE; - dsDesc.DepthWriteMask = gl_d3d11::ConvertDepthMask(dsState.depthMask); - dsDesc.DepthFunc = gl_d3d11::ConvertComparison(dsState.depthFunc); - dsDesc.StencilEnable = dsState.stencilTest ? TRUE : FALSE; - dsDesc.StencilReadMask = gl_d3d11::ConvertStencilMask(dsState.stencilMask); - dsDesc.StencilWriteMask = gl_d3d11::ConvertStencilMask(dsState.stencilWritemask); - dsDesc.FrontFace.StencilFailOp = gl_d3d11::ConvertStencilOp(dsState.stencilFail); - dsDesc.FrontFace.StencilDepthFailOp = gl_d3d11::ConvertStencilOp(dsState.stencilPassDepthFail); - dsDesc.FrontFace.StencilPassOp = gl_d3d11::ConvertStencilOp(dsState.stencilPassDepthPass); - dsDesc.FrontFace.StencilFunc = gl_d3d11::ConvertComparison(dsState.stencilFunc); - dsDesc.BackFace.StencilFailOp = gl_d3d11::ConvertStencilOp(dsState.stencilBackFail); - dsDesc.BackFace.StencilDepthFailOp = gl_d3d11::ConvertStencilOp(dsState.stencilBackPassDepthFail); - dsDesc.BackFace.StencilPassOp = gl_d3d11::ConvertStencilOp(dsState.stencilBackPassDepthPass); - dsDesc.BackFace.StencilFunc = gl_d3d11::ConvertComparison(dsState.stencilBackFunc); - - ID3D11DepthStencilState *dx11DepthStencilState = NULL; - HRESULT result = mDevice->CreateDepthStencilState(&dsDesc, &dx11DepthStencilState); - if (FAILED(result) || !dx11DepthStencilState) - { - return gl::Error(GL_OUT_OF_MEMORY, "Unable to create a ID3D11DepthStencilState, HRESULT: 0x%X.", result); - } + D3D11_DEPTH_STENCIL_DESC dsDesc = {0}; + 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); + + ID3D11DepthStencilState *dx11DepthStencilState = NULL; + HRESULT result = mDevice->CreateDepthStencilState(&dsDesc, &dx11DepthStencilState); + if (FAILED(result) || !dx11DepthStencilState) + { + return gl::Error(GL_OUT_OF_MEMORY, + "Unable to create a ID3D11DepthStencilState, HRESULT: 0x%X.", result); + } - mDepthStencilStateCache.insert(std::make_pair(dsState, std::make_pair(dx11DepthStencilState, mCounter++))); + mDepthStencilStateCache.insert( + std::make_pair(glState, std::make_pair(dx11DepthStencilState, mCounter++))); - *outDSState = dx11DepthStencilState; - return gl::Error(GL_NO_ERROR); - } + *outDSState = dx11DepthStencilState; + return gl::Error(GL_NO_ERROR); } std::size_t RenderStateCache::hashSamplerState(const gl::SamplerState &samplerState) @@ -425,7 +445,7 @@ gl::Error RenderStateCache::getSamplerState(const gl::SamplerState &samplerState samplerDesc.MinLOD = samplerState.minLod; samplerDesc.MaxLOD = samplerState.maxLod; - if (mRenderer->getFeatureLevel() <= D3D_FEATURE_LEVEL_9_3) + if (mRenderer->getRenderer11DeviceCaps().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. diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/RenderStateCache.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/RenderStateCache.h index 0099b94a04de..82cb13903cf1 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/RenderStateCache.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/RenderStateCache.h @@ -36,7 +36,10 @@ class RenderStateCache : angle::NonCopyable gl::Error getBlendState(const gl::Framebuffer *framebuffer, const gl::BlendState &blendState, ID3D11BlendState **outBlendState); gl::Error getRasterizerState(const gl::RasterizerState &rasterState, bool scissorEnabled, ID3D11RasterizerState **outRasterizerState); - gl::Error getDepthStencilState(const gl::DepthStencilState &dsState, ID3D11DepthStencilState **outDSState); + gl::Error getDepthStencilState(const gl::DepthStencilState &dsState, + bool disableDepth, + bool disableStencil, + ID3D11DepthStencilState **outDSState); gl::Error getSamplerState(const gl::SamplerState &samplerState, ID3D11SamplerState **outSamplerState); private: diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/RenderTarget11.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/RenderTarget11.cpp index ba9eab348acc..d25cdf3d64a0 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/RenderTarget11.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/RenderTarget11.cpp @@ -8,10 +8,12 @@ // retained by Renderbuffers. #include "libANGLE/renderer/d3d/d3d11/RenderTarget11.h" + +#include "libANGLE/renderer/d3d/d3d11/formatutils11.h" #include "libANGLE/renderer/d3d/d3d11/Renderer11.h" #include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h" #include "libANGLE/renderer/d3d/d3d11/SwapChain11.h" -#include "libANGLE/renderer/d3d/d3d11/formatutils11.h" +#include "libANGLE/renderer/d3d/d3d11/texture_format_table.h" namespace rx { @@ -176,19 +178,55 @@ static unsigned int getDSVSubresourceIndex(ID3D11Resource *resource, ID3D11Depth return D3D11CalcSubresource(mipSlice, arraySlice, mipLevels); } -TextureRenderTarget11::TextureRenderTarget11(ID3D11RenderTargetView *rtv, ID3D11Resource *resource, ID3D11ShaderResourceView *srv, - GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLsizei samples) - : mWidth(width), +RenderTarget11::RenderTarget11(d3d11::ANGLEFormat angleFormat) : mANGLEFormat(angleFormat) +{ +} + +RenderTarget11::~RenderTarget11() +{ + signalDirty(); +} + +void RenderTarget11::addDirtyCallback(const NotificationCallback *callback) +{ + mDirtyCallbacks.add(callback); +} + +void RenderTarget11::removeDirtyCallback(const NotificationCallback *callback) +{ + mDirtyCallbacks.remove(callback); +} + +void RenderTarget11::signalDirty() +{ + mDirtyCallbacks.signal(); + + // Clear the signal list. We can't do this in the callback because it mutates the iterator. + mDirtyCallbacks.clear(); +} + +TextureRenderTarget11::TextureRenderTarget11(ID3D11RenderTargetView *rtv, + ID3D11Resource *resource, + ID3D11ShaderResourceView *srv, + ID3D11ShaderResourceView *blitSRV, + GLenum internalFormat, + d3d11::ANGLEFormat angleFormat, + GLsizei width, + GLsizei height, + GLsizei depth, + GLsizei samples) + : RenderTarget11(angleFormat), + mWidth(width), mHeight(height), mDepth(depth), mInternalFormat(internalFormat), - mDXGIFormat(DXGI_FORMAT_UNKNOWN), mSamples(samples), mSubresourceIndex(0), mTexture(resource), mRenderTarget(rtv), mDepthStencil(NULL), - mShaderResource(srv) + mShaderResource(srv), + mBlitShaderResource(blitSRV) { if (mTexture) { @@ -205,29 +243,39 @@ TextureRenderTarget11::TextureRenderTarget11(ID3D11RenderTargetView *rtv, ID3D11 mShaderResource->AddRef(); } + if (mBlitShaderResource) + { + mBlitShaderResource->AddRef(); + } + if (mRenderTarget && mTexture) { mSubresourceIndex = getRTVSubresourceIndex(mTexture, mRenderTarget); - - D3D11_RENDER_TARGET_VIEW_DESC desc; - mRenderTarget->GetDesc(&desc); - mDXGIFormat = desc.Format; } + ASSERT(mANGLEFormat != d3d11::ANGLE_FORMAT_NONE || mWidth == 0 || mHeight == 0); } -TextureRenderTarget11::TextureRenderTarget11(ID3D11DepthStencilView *dsv, ID3D11Resource *resource, ID3D11ShaderResourceView *srv, - GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLsizei samples) - : mWidth(width), +TextureRenderTarget11::TextureRenderTarget11(ID3D11DepthStencilView *dsv, + ID3D11Resource *resource, + ID3D11ShaderResourceView *srv, + GLenum internalFormat, + d3d11::ANGLEFormat angleFormat, + GLsizei width, + GLsizei height, + GLsizei depth, + GLsizei samples) + : RenderTarget11(angleFormat), + mWidth(width), mHeight(height), mDepth(depth), mInternalFormat(internalFormat), - mDXGIFormat(DXGI_FORMAT_UNKNOWN), mSamples(samples), mSubresourceIndex(0), mTexture(resource), mRenderTarget(NULL), mDepthStencil(dsv), - mShaderResource(srv) + mShaderResource(srv), + mBlitShaderResource(nullptr) { if (mTexture) { @@ -247,11 +295,8 @@ TextureRenderTarget11::TextureRenderTarget11(ID3D11DepthStencilView *dsv, ID3D11 if (mDepthStencil && mTexture) { mSubresourceIndex = getDSVSubresourceIndex(mTexture, mDepthStencil); - - D3D11_DEPTH_STENCIL_VIEW_DESC desc; - mDepthStencil->GetDesc(&desc); - mDXGIFormat = desc.Format; } + ASSERT(mANGLEFormat != d3d11::ANGLE_FORMAT_NONE || mWidth == 0 || mHeight == 0); } TextureRenderTarget11::~TextureRenderTarget11() @@ -260,6 +305,7 @@ TextureRenderTarget11::~TextureRenderTarget11() SafeRelease(mRenderTarget); SafeRelease(mDepthStencil); SafeRelease(mShaderResource); + SafeRelease(mBlitShaderResource); } ID3D11Resource *TextureRenderTarget11::getTexture() const @@ -282,6 +328,11 @@ ID3D11ShaderResourceView *TextureRenderTarget11::getShaderResourceView() const return mShaderResource; } +ID3D11ShaderResourceView *TextureRenderTarget11::getBlitShaderResourceView() const +{ + return mBlitShaderResource; +} + GLsizei TextureRenderTarget11::getWidth() const { return mWidth; @@ -312,17 +363,19 @@ unsigned int TextureRenderTarget11::getSubresourceIndex() const return mSubresourceIndex; } -DXGI_FORMAT TextureRenderTarget11::getDXGIFormat() const -{ - return mDXGIFormat; -} - -SurfaceRenderTarget11::SurfaceRenderTarget11(SwapChain11 *swapChain, Renderer11 *renderer, bool depth) - : mSwapChain(swapChain), +SurfaceRenderTarget11::SurfaceRenderTarget11(SwapChain11 *swapChain, + Renderer11 *renderer, + bool depth) + : RenderTarget11(d3d11::ANGLE_FORMAT_NONE), // format will be determined in constructor body + mSwapChain(swapChain), mRenderer(renderer), mDepth(depth) { ASSERT(mSwapChain); + + mANGLEFormat = d3d11::GetTextureFormatInfo(getInternalFormatInternal(), + mRenderer->getRenderer11DeviceCaps()) + .formatSet->format; } SurfaceRenderTarget11::~SurfaceRenderTarget11() @@ -346,7 +399,12 @@ GLsizei SurfaceRenderTarget11::getDepth() const GLenum SurfaceRenderTarget11::getInternalFormat() const { - return (mDepth ? mSwapChain->GetDepthBufferInternalFormat() : mSwapChain->GetBackBufferInternalFormat()); + return getInternalFormatInternal(); +} + +GLenum SurfaceRenderTarget11::getInternalFormatInternal() const +{ + return (mDepth ? mSwapChain->GetDepthBufferInternalFormat() : mSwapChain->GetRenderTargetInternalFormat()); } GLsizei SurfaceRenderTarget11::getSamples() const @@ -372,17 +430,19 @@ ID3D11DepthStencilView *SurfaceRenderTarget11::getDepthStencilView() const ID3D11ShaderResourceView *SurfaceRenderTarget11::getShaderResourceView() const { - return (mDepth ? mSwapChain->getDepthStencilShaderResource() : mSwapChain->getRenderTargetShaderResource()); + return (mDepth ? mSwapChain->getDepthStencilShaderResource() + : mSwapChain->getRenderTargetShaderResource()); } -unsigned int SurfaceRenderTarget11::getSubresourceIndex() const +ID3D11ShaderResourceView *SurfaceRenderTarget11::getBlitShaderResourceView() const { - return 0; + // The SurfaceRenderTargetView format should always be such that the normal SRV works for blits. + return getShaderResourceView(); } -DXGI_FORMAT SurfaceRenderTarget11::getDXGIFormat() const +unsigned int SurfaceRenderTarget11::getSubresourceIndex() const { - return d3d11::GetTextureFormatInfo(getInternalFormat(), mRenderer->getFeatureLevel()).texFormat; + return 0; } } diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/RenderTarget11.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/RenderTarget11.h index 169836eed6a0..aa470cc2c853 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/RenderTarget11.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/RenderTarget11.h @@ -11,6 +11,9 @@ #define LIBANGLE_RENDERER_D3D_D3D11_RENDERTARGET11_H_ #include "libANGLE/renderer/d3d/RenderTargetD3D.h" +#include "libANGLE/renderer/d3d/d3d11/texture_format_table.h" + +#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h" namespace rx { @@ -20,30 +23,51 @@ class Renderer11; class RenderTarget11 : public RenderTargetD3D { public: - RenderTarget11() { } - virtual ~RenderTarget11() { } + RenderTarget11(d3d11::ANGLEFormat angleFormat); + virtual ~RenderTarget11(); virtual ID3D11Resource *getTexture() const = 0; virtual ID3D11RenderTargetView *getRenderTargetView() const = 0; virtual ID3D11DepthStencilView *getDepthStencilView() const = 0; virtual ID3D11ShaderResourceView *getShaderResourceView() const = 0; + virtual ID3D11ShaderResourceView *getBlitShaderResourceView() const = 0; virtual unsigned int getSubresourceIndex() const = 0; - virtual DXGI_FORMAT getDXGIFormat() const = 0; + void addDirtyCallback(const NotificationCallback *callback); + void removeDirtyCallback(const NotificationCallback *callback); + void signalDirty() override; - private: - D3D_FEATURE_LEVEL mFeatureLevel; + d3d11::ANGLEFormat getANGLEFormat() const { return mANGLEFormat; } + + protected: + NotificationSet mDirtyCallbacks; + d3d11::ANGLEFormat mANGLEFormat; }; class TextureRenderTarget11 : public RenderTarget11 { public: // TextureRenderTarget11 takes ownership of any D3D11 resources it is given and will AddRef them - TextureRenderTarget11(ID3D11RenderTargetView *rtv, ID3D11Resource *resource, ID3D11ShaderResourceView *srv, - GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLsizei samples); - TextureRenderTarget11(ID3D11DepthStencilView *dsv, ID3D11Resource *resource, ID3D11ShaderResourceView *srv, - GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLsizei samples); + TextureRenderTarget11(ID3D11RenderTargetView *rtv, + ID3D11Resource *resource, + ID3D11ShaderResourceView *srv, + ID3D11ShaderResourceView *blitSRV, + GLenum internalFormat, + d3d11::ANGLEFormat angleFormat, + GLsizei width, + GLsizei height, + GLsizei depth, + GLsizei samples); + TextureRenderTarget11(ID3D11DepthStencilView *dsv, + ID3D11Resource *resource, + ID3D11ShaderResourceView *srv, + GLenum internalFormat, + d3d11::ANGLEFormat angleFormat, + GLsizei width, + GLsizei height, + GLsizei depth, + GLsizei samples); virtual ~TextureRenderTarget11(); GLsizei getWidth() const override; @@ -56,17 +80,15 @@ class TextureRenderTarget11 : public RenderTarget11 ID3D11RenderTargetView *getRenderTargetView() const override; ID3D11DepthStencilView *getDepthStencilView() const override; ID3D11ShaderResourceView *getShaderResourceView() const override; + ID3D11ShaderResourceView *getBlitShaderResourceView() const override; unsigned int getSubresourceIndex() const override; - DXGI_FORMAT getDXGIFormat() const override; - private: GLsizei mWidth; GLsizei mHeight; GLsizei mDepth; GLenum mInternalFormat; - DXGI_FORMAT mDXGIFormat; GLsizei mSamples; unsigned int mSubresourceIndex; @@ -74,6 +96,10 @@ class TextureRenderTarget11 : public RenderTarget11 ID3D11RenderTargetView *mRenderTarget; ID3D11DepthStencilView *mDepthStencil; ID3D11ShaderResourceView *mShaderResource; + + // Shader resource view to use with internal blit shaders. Not set for depth/stencil render + // targets. + ID3D11ShaderResourceView *mBlitShaderResource; }; class SurfaceRenderTarget11 : public RenderTarget11 @@ -92,12 +118,15 @@ class SurfaceRenderTarget11 : public RenderTarget11 ID3D11RenderTargetView *getRenderTargetView() const override; ID3D11DepthStencilView *getDepthStencilView() const override; ID3D11ShaderResourceView *getShaderResourceView() const override; + ID3D11ShaderResourceView *getBlitShaderResourceView() const override; unsigned int getSubresourceIndex() const override; - DXGI_FORMAT getDXGIFormat() const override; - private: + // The internal versions of the functions are needed so that they can be safely called + // from the constructor. + GLenum getInternalFormatInternal() const; + SwapChain11 *mSwapChain; Renderer11 *mRenderer; bool mDepth; diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp index f207793562fa..26326e5f041b 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp @@ -8,50 +8,63 @@ #include "libANGLE/renderer/d3d/d3d11/Renderer11.h" -#include #include +#include +#include -#include "common/utilities.h" #include "common/tls.h" +#include "common/utilities.h" #include "libANGLE/Buffer.h" #include "libANGLE/Display.h" +#include "libANGLE/formatutils.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/Program.h" #include "libANGLE/renderer/d3d/CompilerD3D.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/TransformFeedbackD3D.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/dxgi_support_table.h" #include "libANGLE/renderer/d3d/d3d11/Fence11.h" +#include "libANGLE/renderer/d3d/d3d11/formatutils11.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/Query11.h" +#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h" #include "libANGLE/renderer/d3d/d3d11/RenderTarget11.h" #include "libANGLE/renderer/d3d/d3d11/ShaderExecutable11.h" +#include "libANGLE/renderer/d3d/d3d11/Stream11.h" #include "libANGLE/renderer/d3d/d3d11/SwapChain11.h" +#include "libANGLE/renderer/d3d/d3d11/texture_format_table.h" #include "libANGLE/renderer/d3d/d3d11/TextureStorage11.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/CompilerD3D.h" +#include "libANGLE/renderer/d3d/DeviceD3D.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/TransformFeedbackD3D.h" +#include "libANGLE/renderer/d3d/VertexDataManager.h" +#include "libANGLE/State.h" +#include "libANGLE/Surface.h" #include "third_party/trace_event/trace_event.h" +// Include the D3D9 debug annotator header for use by the desktop D3D11 renderer +// because the D3D11 interface method ID3DUserDefinedAnnotation::GetStatus +// doesn't work with the Graphics Diagnostics tools in Visual Studio 2013. +#ifdef ANGLE_ENABLE_D3D9 +#include "libANGLE/renderer/d3d/d3d9/DebugAnnotator9.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 @@ -75,113 +88,311 @@ enum MAX_TEXTURE_IMAGE_UNITS_VTF_SM4 = 16 }; -// dirtyPointer is a special value that will make the comparison with any valid pointer fail and force the renderer to re-apply the state. -static const uintptr_t DirtyPointer = static_cast(-1); +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::roundUp(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 +} -static bool ImageIndexConflictsWithSRV(const gl::ImageIndex &index, D3D11_SHADER_RESOURCE_VIEW_DESC desc) +enum ANGLEFeatureLevel { - unsigned mipLevel = index.mipIndex; - unsigned layerIndex = index.layerIndex; - GLenum type = index.type; + 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 +}; - switch (desc.ViewDimension) +ANGLEFeatureLevel GetANGLEFeatureLevel(D3D_FEATURE_LEVEL d3dFeatureLevel) +{ + switch (d3dFeatureLevel) { - case D3D11_SRV_DIMENSION_TEXTURE2D: - { - unsigned maxSrvMip = desc.Texture2D.MipLevels + desc.Texture2D.MostDetailedMip; - maxSrvMip = (desc.Texture2D.MipLevels == -1) ? INT_MAX : maxSrvMip; + 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; + // Note: we don't ever request a 11_1 device, because this gives + // an E_INVALIDARG error on systems that don't have the platform update. + case D3D_FEATURE_LEVEL_11_1: return ANGLE_FEATURE_LEVEL_11_1; + default: return ANGLE_FEATURE_LEVEL_INVALID; + } +} - unsigned mipMin = index.mipIndex; - unsigned mipMax = (layerIndex == -1) ? INT_MAX : layerIndex; +void SetLineLoopIndices(GLuint *dest, size_t count) +{ + for (size_t i = 0; i < count; i++) + { + dest[i] = static_cast(i); + } + dest[count] = 0; +} - return type == GL_TEXTURE_2D && RangeUI(mipMin, mipMax).intersects(RangeUI(desc.Texture2D.MostDetailedMip, maxSrvMip)); - } +template +void CopyLineLoopIndices(const GLvoid *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]); +} - case D3D11_SRV_DIMENSION_TEXTURE2DARRAY: - { - unsigned maxSrvMip = desc.Texture2DArray.MipLevels + desc.Texture2DArray.MostDetailedMip; - maxSrvMip = (desc.Texture2DArray.MipLevels == -1) ? INT_MAX : maxSrvMip; +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; + } +} - unsigned maxSlice = desc.Texture2DArray.FirstArraySlice + desc.Texture2DArray.ArraySize; +template +void CopyLineLoopIndicesWithRestart(const GLvoid *indices, + size_t count, + GLenum indexType, + std::vector *bufferOut) +{ + GLuint restartIndex = gl::GetPrimitiveRestartIndex(indexType); + GLuint d3dRestartIndex = static_cast(d3d11::GetPrimitiveRestartIndex()); + const T *srcPtr = static_cast(indices); + Optional currentLoopStart; - // Cube maps can be mapped to Texture2DArray SRVs - return (type == GL_TEXTURE_2D_ARRAY || gl::IsCubeMapTextureTarget(type)) && - desc.Texture2DArray.MostDetailedMip <= mipLevel && mipLevel < maxSrvMip && - desc.Texture2DArray.FirstArraySlice <= layerIndex && layerIndex < maxSlice; - } + bufferOut->clear(); - case D3D11_SRV_DIMENSION_TEXTURECUBE: - { - unsigned maxSrvMip = desc.TextureCube.MipLevels + desc.TextureCube.MostDetailedMip; - maxSrvMip = (desc.TextureCube.MipLevels == -1) ? INT_MAX : maxSrvMip; + for (size_t indexIdx = 0; indexIdx < count; ++indexIdx) + { + GLuint value = static_cast(srcPtr[indexIdx]); - return gl::IsCubeMapTextureTarget(type) && - desc.TextureCube.MostDetailedMip <= mipLevel && mipLevel < maxSrvMip; + if (value == restartIndex) + { + if (currentLoopStart.valid()) + { + bufferOut->push_back(currentLoopStart.value()); + bufferOut->push_back(d3dRestartIndex); + currentLoopStart.reset(); + } } - - case D3D11_SRV_DIMENSION_TEXTURE3D: + else { - unsigned maxSrvMip = desc.Texture3D.MipLevels + desc.Texture3D.MostDetailedMip; - maxSrvMip = (desc.Texture3D.MipLevels == -1) ? INT_MAX : maxSrvMip; - - return type == GL_TEXTURE_3D && - desc.Texture3D.MostDetailedMip <= mipLevel && mipLevel < maxSrvMip; + bufferOut->push_back(value); + if (!currentLoopStart.valid()) + { + currentLoopStart = value; + } } - default: - // We only handle the cases corresponding to valid image indexes - UNIMPLEMENTED(); } - return false; + if (currentLoopStart.valid()) + { + bufferOut->push_back(currentLoopStart.value()); + } } -// Does *not* increment the resource ref count!! -ID3D11Resource *GetViewResource(ID3D11View *view) +void GetLineLoopIndices(const GLvoid *indices, + GLenum indexType, + GLuint count, + bool usePrimitiveRestartFixedIndex, + std::vector *bufferOut) { - ID3D11Resource *resource = NULL; - ASSERT(view); - view->GetResource(&resource); - resource->Release(); - return resource; + if (indexType != GL_NONE && usePrimitiveRestartFixedIndex) + { + switch (indexType) + { + case GL_UNSIGNED_BYTE: + CopyLineLoopIndicesWithRestart(indices, count, indexType, bufferOut); + break; + case GL_UNSIGNED_SHORT: + CopyLineLoopIndicesWithRestart(indices, count, indexType, bufferOut); + break; + case GL_UNSIGNED_INT: + CopyLineLoopIndicesWithRestart(indices, count, indexType, bufferOut); + 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_NONE: + SetLineLoopIndices(&(*bufferOut)[0], count); + break; + case GL_UNSIGNED_BYTE: + CopyLineLoopIndices(indices, &(*bufferOut)[0], count); + break; + case GL_UNSIGNED_SHORT: + CopyLineLoopIndices(indices, &(*bufferOut)[0], count); + break; + case GL_UNSIGNED_INT: + CopyLineLoopIndices(indices, &(*bufferOut)[0], count); + break; + default: + UNREACHABLE(); + break; + } } -void CalculateConstantBufferParams(GLintptr offset, GLsizeiptr size, UINT *outFirstConstant, UINT *outNumConstants) +template +void CopyTriangleFanIndices(const GLvoid *indices, GLuint *destPtr, size_t numTris) { - // The offset must be aligned to 256 bytes (should have been enforced by glBindBufferRange). - ASSERT(offset % 256 == 0); + const T *srcPtr = static_cast(indices); - // firstConstant and numConstants are expressed in constants of 16-bytes. Furthermore they must be a multiple of 16 constants. - *outFirstConstant = static_cast(offset / 16); + 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]); + } +} - // 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::roundUp(size, static_cast(256)) / 16); +template +void CopyTriangleFanIndicesWithRestart(const GLvoid *indices, + GLuint indexCount, + GLenum indexType, + std::vector *bufferOut) +{ + GLuint restartIndex = gl::GetPrimitiveRestartIndex(indexType); + GLuint d3dRestartIndex = gl::GetPrimitiveRestartIndex(GL_UNSIGNED_INT); + const T *srcPtr = static_cast(indices); + Optional vertexA; + Optional vertexB; - // 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 + 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; + } + } + } } -egl::Error GenerateD3D11CreateDeviceErr(HRESULT errorCode) +void GetTriFanIndices(const GLvoid *indices, + GLenum indexType, + GLuint count, + bool usePrimitiveRestartFixedIndex, + std::vector *bufferOut) { - return egl::Error(EGL_NOT_INITIALIZED, errorCode, "Could not create D3D11 device."); + if (indexType != GL_NONE && usePrimitiveRestartFixedIndex) + { + switch (indexType) + { + case GL_UNSIGNED_BYTE: + CopyTriangleFanIndicesWithRestart(indices, count, indexType, bufferOut); + break; + case GL_UNSIGNED_SHORT: + CopyTriangleFanIndicesWithRestart(indices, count, indexType, bufferOut); + break; + case GL_UNSIGNED_INT: + 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_NONE: + SetTriangleFanIndices(&(*bufferOut)[0], numTris); + break; + case GL_UNSIGNED_BYTE: + CopyTriangleFanIndices(indices, &(*bufferOut)[0], numTris); + break; + case GL_UNSIGNED_SHORT: + CopyTriangleFanIndices(indices, &(*bufferOut)[0], numTris); + break; + case GL_UNSIGNED_INT: + CopyTriangleFanIndices(indices, &(*bufferOut)[0], numTris); + break; + default: + UNREACHABLE(); + break; + } } +int GetWrapBits(GLenum wrap) +{ + switch (wrap) + { + case GL_CLAMP_TO_EDGE: + return 0x1; + case GL_REPEAT: + return 0x2; + case GL_MIRRORED_REPEAT: + return 0x3; + default: + UNREACHABLE(); + return 0; + } } +} // anonymous namespace + Renderer11::Renderer11(egl::Display *display) : RendererD3D(display), mStateCache(this), + mStateManager(this), + mLastHistogramUpdateTime(ANGLEPlatformCurrent()->monotonicallyIncreasingTime()), mDebug(nullptr) { - // Initialize global annotator - gl::InitializeDebugAnnotations(&mAnnotator); - mVertexDataManager = NULL; mIndexDataManager = NULL; mLineLoopIB = NULL; mTriangleFanIB = NULL; + mAppliedIBChanged = false; mBlit = NULL; mPixelTransfer = NULL; @@ -192,10 +403,18 @@ Renderer11::Renderer11(egl::Display *display) mSyncQuery = NULL; - mSupportsConstantBufferOffsets = false; + mRenderer11DeviceCaps.supportsClearView = false; + mRenderer11DeviceCaps.supportsConstantBufferOffsets = false; + mRenderer11DeviceCaps.supportsDXGI1_2 = false; + mRenderer11DeviceCaps.B5G6R5support = 0; + mRenderer11DeviceCaps.B4G4R4A4support = 0; + mRenderer11DeviceCaps.B5G5R5A1support = 0; mD3d11Module = NULL; mDxgiModule = NULL; + mDCompModule = NULL; + mCreatedWithDeviceEXT = false; + mEGLDevice = nullptr; mDevice = NULL; mDeviceContext = NULL; @@ -212,66 +431,88 @@ Renderer11::Renderer11(egl::Display *display) mAppliedNumXFBBindings = static_cast(-1); - const auto &attributes = mDisplay->getAttributeMap(); - - EGLint requestedMajorVersion = attributes.get(EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE, EGL_DONT_CARE); - EGLint requestedMinorVersion = attributes.get(EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE, EGL_DONT_CARE); + ZeroMemory(&mAdapterDescription, sizeof(mAdapterDescription)); - if (requestedMajorVersion == EGL_DONT_CARE || requestedMajorVersion >= 11) + if (mDisplay->getPlatform() == EGL_PLATFORM_ANGLE_ANGLE) { - if (requestedMinorVersion == EGL_DONT_CARE || requestedMinorVersion >= 0) + const auto &attributes = mDisplay->getAttributeMap(); + + 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) { - mAvailableFeatureLevels.push_back(D3D_FEATURE_LEVEL_11_0); + 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) + if (requestedMajorVersion == EGL_DONT_CARE || requestedMajorVersion >= 10) { - mAvailableFeatureLevels.push_back(D3D_FEATURE_LEVEL_10_1); + 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 (requestedMinorVersion == EGL_DONT_CARE || requestedMinorVersion >= 0) + + if (requestedMajorVersion == 9 && requestedMinorVersion == 3) { - mAvailableFeatureLevels.push_back(D3D_FEATURE_LEVEL_10_0); + mAvailableFeatureLevels.push_back(D3D_FEATURE_LEVEL_9_3); } - } - 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; - EGLint requestedDeviceType = 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: - mDriverType = D3D_DRIVER_TYPE_HARDWARE; - break; + case EGL_PLATFORM_ANGLE_DEVICE_TYPE_WARP_ANGLE: + mRequestedDriverType = D3D_DRIVER_TYPE_WARP; + break; - case EGL_PLATFORM_ANGLE_DEVICE_TYPE_WARP_ANGLE: - mDriverType = D3D_DRIVER_TYPE_WARP; - break; + case EGL_PLATFORM_ANGLE_DEVICE_TYPE_REFERENCE_ANGLE: + mRequestedDriverType = D3D_DRIVER_TYPE_REFERENCE; + break; - case EGL_PLATFORM_ANGLE_DEVICE_TYPE_REFERENCE_ANGLE: - mDriverType = D3D_DRIVER_TYPE_REFERENCE; - break; + case EGL_PLATFORM_ANGLE_DEVICE_TYPE_NULL_ANGLE: + mRequestedDriverType = D3D_DRIVER_TYPE_NULL; + break; - case EGL_PLATFORM_ANGLE_DEVICE_TYPE_NULL_ANGLE: - mDriverType = D3D_DRIVER_TYPE_NULL; - break; + default: + UNREACHABLE(); + } - default: - UNREACHABLE(); + 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); + } + else if (display->getPlatform() == EGL_PLATFORM_DEVICE_EXT) + { + mEGLDevice = GetImplAs(display->getDevice()); + ASSERT(mEGLDevice != 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; + mPresentPathFastEnabled = false; } + + initializeDebugAnnotator(); } Renderer11::~Renderer11() { release(); - - gl::UninitializeDebugAnnotations(); } #ifndef __d3d11_1_h__ @@ -280,118 +521,49 @@ Renderer11::~Renderer11() egl::Error Renderer11::initialize() { - if (!mCompiler.initialize()) + HRESULT result = S_OK; + + egl::Error error = initializeD3DDevice(); + if (error.isError()) { - return egl::Error(EGL_NOT_INITIALIZED, - D3D11_INIT_COMPILER_ERROR, - "Failed to initialize compiler."); + return error; } #if !defined(ANGLE_ENABLE_WINDOWS_STORE) - PFN_D3D11_CREATE_DEVICE D3D11CreateDevice = nullptr; - { - TRACE_EVENT0("gpu.angle", "Renderer11::initialize (Load DLLs)"); - mDxgiModule = LoadLibrary(TEXT("dxgi.dll")); - mD3d11Module = LoadLibrary(TEXT("d3d11.dll")); - - if (mD3d11Module == nullptr || mDxgiModule == nullptr) +#if !ANGLE_SKIP_DXGI_1_2_CHECK + { + 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) { - return egl::Error(EGL_NOT_INITIALIZED, - D3D11_INIT_MISSING_DEP, - "Could not load D3D11 or DXGI library."); + DWORD currentProcessId = GetCurrentProcessId(); + DWORD wndProcessId; + GetWindowThreadProcessId(hwnd, &wndProcessId); + requireDXGI1_2 = (currentProcessId != wndProcessId); } - - // create the D3D11 device - ASSERT(mDevice == nullptr); - D3D11CreateDevice = reinterpret_cast(GetProcAddress(mD3d11Module, "D3D11CreateDevice")); - - if (D3D11CreateDevice == nullptr) + else { - return egl::Error(EGL_NOT_INITIALIZED, - D3D11_INIT_MISSING_DEP, - "Could not retrieve D3D11CreateDevice address."); + requireDXGI1_2 = true; } - } -#endif - - HRESULT result = S_OK; -#ifdef _DEBUG - { - TRACE_EVENT0("gpu.angle", "D3D11CreateDevice (Debug)"); - result = D3D11CreateDevice(NULL, - mDriverType, - NULL, - D3D11_CREATE_DEVICE_DEBUG, - mAvailableFeatureLevels.data(), - mAvailableFeatureLevels.size(), - D3D11_SDK_VERSION, - &mDevice, - &mFeatureLevel, - &mDeviceContext); - } - - if (!mDevice || FAILED(result)) - { - ERR("Failed creating Debug D3D11 device - falling back to release runtime.\n"); - } - if (!mDevice || FAILED(result)) -#endif - { - double createDeviceBegin = ANGLEPlatformCurrent()->currentTime(); - - TRACE_EVENT0("gpu.angle", "D3D11CreateDevice"); - result = D3D11CreateDevice(NULL, - mDriverType, - NULL, - 0, - mAvailableFeatureLevels.data(), - mAvailableFeatureLevels.size(), - D3D11_SDK_VERSION, - &mDevice, - &mFeatureLevel, - &mDeviceContext); - - // Cleanup done by destructor - if (FAILED(result)) + if (requireDXGI1_2) { - // Most likely error codes, see - // https://msdn.microsoft.com/en-us/library/windows/desktop/ff476082%28v=vs.85%29.aspx - // And https://msdn.microsoft.com/en-us/library/windows/desktop/ff476174(v=vs.85).aspx - switch (result) + IDXGIDevice2 *dxgiDevice2 = NULL; + result = mDevice->QueryInterface(__uuidof(IDXGIDevice2), (void**)&dxgiDevice2); + if (FAILED(result)) { - case E_INVALIDARG: - return GenerateD3D11CreateDeviceErr(D3D11_INIT_CREATEDEVICE_INVALIDARG); - case E_FAIL: - return GenerateD3D11CreateDeviceErr(D3D11_INIT_CREATEDEVICE_FAIL); - case E_NOTIMPL: - return GenerateD3D11CreateDeviceErr(D3D11_INIT_CREATEDEVICE_NOTIMPL); - case E_OUTOFMEMORY: - return GenerateD3D11CreateDeviceErr(D3D11_INIT_CREATEDEVICE_OUTOFMEMORY); - case DXGI_ERROR_INVALID_CALL: - return GenerateD3D11CreateDeviceErr(D3D11_INIT_CREATEDEVICE_INVALIDCALL); - case DXGI_ERROR_SDK_COMPONENT_MISSING: - return GenerateD3D11CreateDeviceErr(D3D11_INIT_CREATEDEVICE_COMPONENTMISSING); - case DXGI_ERROR_WAS_STILL_DRAWING: - return GenerateD3D11CreateDeviceErr(D3D11_INIT_CREATEDEVICE_WASSTILLDRAWING); - case DXGI_ERROR_NOT_CURRENTLY_AVAILABLE: - return GenerateD3D11CreateDeviceErr(D3D11_INIT_CREATEDEVICE_NOTAVAILABLE); - case DXGI_ERROR_DEVICE_HUNG: - return GenerateD3D11CreateDeviceErr(D3D11_INIT_CREATEDEVICE_DEVICEHUNG); - default: - return GenerateD3D11CreateDeviceErr(D3D11_INIT_CREATEDEVICE_ERROR); + return egl::Error(EGL_NOT_INITIALIZED, + D3D11_INIT_INCOMPATIBLE_DXGI, + "DXGI 1.2 required to present to HWNDs owned by another process."); } + SafeRelease(dxgiDevice2); } - - if (!mDevice) - { - return GenerateD3D11CreateDeviceErr(D3D11_INIT_CREATEDEVICE_NULL); - } - - double createDeviceSec = ANGLEPlatformCurrent()->currentTime() - createDeviceBegin; - int createDeviceMS = static_cast(createDeviceSec * 1000); - ANGLE_HISTOGRAM_TIMES("GPU.ANGLE.D3D11CreateDeviceMS", createDeviceMS); } +#endif +#endif { TRACE_EVENT0("gpu.angle", "Renderer11::initialize (ComQueries)"); @@ -425,29 +597,38 @@ egl::Error Renderer11::initialize() // 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 (mFeatureLevel <= D3D_FEATURE_LEVEL_9_3 && dxgiAdapter2 != NULL) - { - DXGI_ADAPTER_DESC2 adapterDesc2 = { 0 }; - dxgiAdapter2->GetDesc2(&adapterDesc2); - - // 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; + if (mRenderer11DeviceCaps.featureLevel <= D3D_FEATURE_LEVEL_9_3 && dxgiAdapter2 != NULL) + { + 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 { - mDxgiAdapter->GetDesc(&mAdapterDescription); + result = mDxgiAdapter->GetDesc(&mAdapterDescription); } SafeRelease(dxgiAdapter2); + if (FAILED(result)) + { + return egl::Error(EGL_NOT_INITIALIZED, + D3D11_INIT_OTHER_ERROR, + "Could not read DXGI adaptor description."); + } + memset(mDescription, 0, sizeof(mDescription)); wcstombs(mDescription, mAdapterDescription.Description, sizeof(mDescription) - 1); @@ -475,8 +656,8 @@ egl::Error Renderer11::initialize() D3D11_MESSAGE_ID_DEVICE_DRAW_RENDERTARGETVIEW_NOT_SET }; - D3D11_INFO_QUEUE_FILTER filter = { 0 }; - filter.DenyList.NumIDs = ArraySize(hideMessages); + D3D11_INFO_QUEUE_FILTER filter = {}; + filter.DenyList.NumIDs = static_cast(ArraySize(hideMessages)); filter.DenyList.pIDList = hideMessages; infoQueue->AddStorageFilterEntries(&filter); @@ -494,13 +675,120 @@ egl::Error Renderer11::initialize() return egl::Error(EGL_SUCCESS); } +egl::Error Renderer11::initializeD3DDevice() +{ + HRESULT result = S_OK; + + if (!mCreatedWithDeviceEXT) + { +#if !defined(ANGLE_ENABLE_WINDOWS_STORE) + PFN_D3D11_CREATE_DEVICE D3D11CreateDevice = nullptr; + { + SCOPED_ANGLE_HISTOGRAM_TIMER("GPU.ANGLE.Renderer11InitializeDLLsMS"); + TRACE_EVENT0("gpu.angle", "Renderer11::initialize (Load DLLs)"); + mDxgiModule = LoadLibrary(TEXT("dxgi.dll")); + mD3d11Module = LoadLibrary(TEXT("d3d11.dll")); + mDCompModule = LoadLibrary(TEXT("dcomp.dll")); + + if (mD3d11Module == nullptr || mDxgiModule == nullptr) + { + return egl::Error(EGL_NOT_INITIALIZED, D3D11_INIT_MISSING_DEP, + "Could not load D3D11 or DXGI library."); + } + + // create the D3D11 device + ASSERT(mDevice == nullptr); + D3D11CreateDevice = reinterpret_cast( + GetProcAddress(mD3d11Module, "D3D11CreateDevice")); + + if (D3D11CreateDevice == nullptr) + { + return egl::Error(EGL_NOT_INITIALIZED, D3D11_INIT_MISSING_DEP, + "Could not retrieve D3D11CreateDevice address."); + } + } +#endif + +#ifdef _DEBUG + { + TRACE_EVENT0("gpu.angle", "D3D11CreateDevice (Debug)"); + result = D3D11CreateDevice(nullptr, mRequestedDriverType, nullptr, + D3D11_CREATE_DEVICE_DEBUG, mAvailableFeatureLevels.data(), + static_cast(mAvailableFeatureLevels.size()), + D3D11_SDK_VERSION, &mDevice, + &(mRenderer11DeviceCaps.featureLevel), &mDeviceContext); + } + + if (!mDevice || FAILED(result)) + { + ERR("Failed creating Debug D3D11 device - falling back to release runtime.\n"); + } + + if (!mDevice || FAILED(result)) +#endif + { + SCOPED_ANGLE_HISTOGRAM_TIMER("GPU.ANGLE.D3D11CreateDeviceMS"); + TRACE_EVENT0("gpu.angle", "D3D11CreateDevice"); + + result = D3D11CreateDevice( + nullptr, mRequestedDriverType, nullptr, 0, mAvailableFeatureLevels.data(), + static_cast(mAvailableFeatureLevels.size()), D3D11_SDK_VERSION, + &mDevice, &(mRenderer11DeviceCaps.featureLevel), &mDeviceContext); + + // Cleanup done by destructor + if (!mDevice || FAILED(result)) + { + ANGLE_HISTOGRAM_SPARSE_SLOWLY("GPU.ANGLE.D3D11CreateDeviceError", + static_cast(result)); + return egl::Error(EGL_NOT_INITIALIZED, D3D11_INIT_CREATEDEVICE_ERROR, + "Could not create D3D11 device."); + } + } + } + else + { + // We should use the inputted D3D11 device instead + void *device = nullptr; + egl::Error error = mEGLDevice->getDevice(&device); + if (error.isError()) + { + return error; + } + + ID3D11Device *d3dDevice = reinterpret_cast(device); + if (FAILED(d3dDevice->GetDeviceRemovedReason())) + { + return egl::Error(EGL_NOT_INITIALIZED, "Inputted D3D11 device has been lost."); + } + + if (d3dDevice->GetFeatureLevel() < D3D_FEATURE_LEVEL_9_3) + { + return egl::Error(EGL_NOT_INITIALIZED, + "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(); + } + + d3d11::SetDebugName(mDeviceContext, "DeviceContext"); + + return egl::Error(EGL_SUCCESS); +} + // 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. void Renderer11::initializeDevice() { + SCOPED_ANGLE_HISTOGRAM_TIMER("GPU.ANGLE.Renderer11InitializeDeviceMS"); TRACE_EVENT0("gpu.angle", "Renderer11::initializeDevice"); + populateRenderer11DeviceCaps(); + mStateCache.initialize(mDevice); mInputLayoutCache.initialize(mDevice, mDeviceContext); @@ -518,7 +806,8 @@ void Renderer11::initializeDevice() // 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 = attributes.get(EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE, EGL_FALSE); + EGLint enableAutoTrim = static_cast( + attributes.get(EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE, EGL_FALSE)); if (enableAutoTrim == EGL_TRUE) { @@ -531,32 +820,97 @@ void Renderer11::initializeDevice() const gl::Caps &rendererCaps = getRendererCaps(); - if (getDeviceContext1IfSupported()) - { - D3D11_FEATURE_DATA_D3D11_OPTIONS d3d11Options; - mDevice->CheckFeatureSupport(D3D11_FEATURE_D3D11_OPTIONS, &d3d11Options, sizeof(D3D11_FEATURE_DATA_D3D11_OPTIONS)); - mSupportsConstantBufferOffsets = (d3d11Options.ConstantBufferOffsetting != FALSE); - } + mStateManager.initialize(rendererCaps); mForceSetVertexSamplerStates.resize(rendererCaps.maxVertexTextureImageUnits); mCurVertexSamplerStates.resize(rendererCaps.maxVertexTextureImageUnits); + mSamplerMetadataVS.initData(rendererCaps.maxVertexTextureImageUnits); mForceSetPixelSamplerStates.resize(rendererCaps.maxTextureImageUnits); mCurPixelSamplerStates.resize(rendererCaps.maxTextureImageUnits); + mSamplerMetadataPS.initData(rendererCaps.maxTextureImageUnits); - mCurVertexSRVs.resize(rendererCaps.maxVertexTextureImageUnits); - mCurPixelSRVs.resize(rendererCaps.maxTextureImageUnits); + mStateManager.initialize(rendererCaps); markAllStateDirty(); + + // 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); +} + +void Renderer11::populateRenderer11DeviceCaps() +{ + HRESULT hr = S_OK; + + 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); + } + } + + hr = mDevice->CheckFormatSupport(DXGI_FORMAT_B5G6R5_UNORM, &(mRenderer11DeviceCaps.B5G6R5support)); + if (FAILED(hr)) + { + mRenderer11DeviceCaps.B5G6R5support = 0; + } + + hr = mDevice->CheckFormatSupport(DXGI_FORMAT_B4G4R4A4_UNORM, &(mRenderer11DeviceCaps.B4G4R4A4support)); + if (FAILED(hr)) + { + mRenderer11DeviceCaps.B4G4R4A4support = 0; + } + + hr = mDevice->CheckFormatSupport(DXGI_FORMAT_B5G5R5A1_UNORM, &(mRenderer11DeviceCaps.B5G5R5A1support)); + if (FAILED(hr)) + { + mRenderer11DeviceCaps.B5G5R5A1support = 0; + } + + IDXGIAdapter2 *dxgiAdapter2 = d3d11::DynamicCastComObject(mDxgiAdapter); + mRenderer11DeviceCaps.supportsDXGI1_2 = (dxgiAdapter2 != nullptr); + SafeRelease(dxgiAdapter2); } egl::ConfigSet Renderer11::generateConfigs() const { - static const GLenum colorBufferFormats[] = + 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 (!mPresentPathFastEnabled) { - GL_BGRA8_EXT, - GL_RGBA8_OES, - }; + // 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[] = { @@ -568,64 +922,87 @@ egl::ConfigSet Renderer11::generateConfigs() const const gl::Caps &rendererCaps = getRendererCaps(); const gl::TextureCapsMap &rendererTextureCaps = getRendererTextureCaps(); + const EGLint optimalSurfaceOrientation = + mPresentPathFastEnabled ? 0 : EGL_SURFACE_ORIENTATION_INVERT_Y_ANGLE; + egl::ConfigSet configs; - for (size_t formatIndex = 0; formatIndex < ArraySize(colorBufferFormats); formatIndex++) + for (GLenum colorBufferInternalFormat : colorBufferFormats) { - GLenum colorBufferInternalFormat = colorBufferFormats[formatIndex]; const gl::TextureCaps &colorBufferFormatCaps = rendererTextureCaps.get(colorBufferInternalFormat); - if (colorBufferFormatCaps.renderable) + if (!colorBufferFormatCaps.renderable) + { + continue; + } + + for (GLenum depthStencilBufferInternalFormat : depthStencilBufferFormats) { - for (size_t depthStencilIndex = 0; depthStencilIndex < ArraySize(depthStencilBufferFormats); depthStencilIndex++) + const gl::TextureCaps &depthStencilBufferFormatCaps = + rendererTextureCaps.get(depthStencilBufferInternalFormat); + if (!depthStencilBufferFormatCaps.renderable && + depthStencilBufferInternalFormat != GL_NONE) { - GLenum depthStencilBufferInternalFormat = depthStencilBufferFormats[depthStencilIndex]; - const gl::TextureCaps &depthStencilBufferFormatCaps = rendererTextureCaps.get(depthStencilBufferInternalFormat); - if (depthStencilBufferFormatCaps.renderable || depthStencilBufferInternalFormat == GL_NONE) - { - const gl::InternalFormat &colorBufferFormatInfo = gl::GetInternalFormatInfo(colorBufferInternalFormat); - const gl::InternalFormat &depthStencilBufferFormatInfo = gl::GetInternalFormatInfo(depthStencilBufferInternalFormat); - - 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; - config.configCaveat = EGL_NONE; - config.configID = static_cast(configs.size() + 1); - // Can only support a conformant ES2 with feature level greater than 10.0. - config.conformant = (mFeatureLevel >= D3D_FEATURE_LEVEL_10_0) ? (EGL_OPENGL_ES2_BIT | EGL_OPENGL_ES3_BIT_KHR) : EGL_NONE; - 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.0 - config.renderableType = EGL_OPENGL_ES2_BIT | ((mFeatureLevel >= D3D_FEATURE_LEVEL_10_0) ? EGL_OPENGL_ES3_BIT_KHR : 0); - 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; - - configs.add(config); - } + continue; + } + + const gl::InternalFormat &colorBufferFormatInfo = + gl::GetInternalFormatInfo(colorBufferInternalFormat); + const gl::InternalFormat &depthStencilBufferFormatInfo = + gl::GetInternalFormatInfo(depthStencilBufferInternalFormat); + + 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; + config.configCaveat = EGL_NONE; + config.configID = static_cast(configs.size() + 1); + // Can only support a conformant ES2 with feature level greater than 10.0. + config.conformant = (mRenderer11DeviceCaps.featureLevel >= D3D_FEATURE_LEVEL_10_0) + ? (EGL_OPENGL_ES2_BIT | EGL_OPENGL_ES3_BIT_KHR) + : 0; + + // PresentPathFast may not be conformant + if (mPresentPathFastEnabled) + { + config.conformant = 0; } + + 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.0 + config.renderableType = + EGL_OPENGL_ES2_BIT | ((mRenderer11DeviceCaps.featureLevel >= D3D_FEATURE_LEVEL_10_0) + ? EGL_OPENGL_ES3_BIT_KHR + : 0); + 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.optimalOrientation = optimalSurfaceOrientation; + + configs.add(config); } } @@ -633,6 +1010,44 @@ egl::ConfigSet Renderer11::generateConfigs() const return configs; } +void Renderer11::generateDisplayExtensions(egl::DisplayExtensions *outExtensions) const +{ + outExtensions->createContextRobustness = true; + + if (getShareHandleSupport()) + { + outExtensions->d3dShareHandleClientBuffer = true; + outExtensions->surfaceD3DTexture2DShareHandle = 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->createContext = true; + + outExtensions->deviceQuery = true; + + outExtensions->createContextNoError = true; + + outExtensions->image = true; + outExtensions->imageBase = true; + outExtensions->glTexture2DImage = true; + outExtensions->glTextureCubemapImage = true; + outExtensions->glRenderbufferImage = true; + + outExtensions->stream = true; + + outExtensions->flexibleSurfaceCompatibility = true; + outExtensions->directComposition = !!mDCompModule; +} + gl::Error Renderer11::flush() { mDeviceContext->Flush(); @@ -682,38 +1097,26 @@ gl::Error Renderer11::finish() return gl::Error(GL_NO_ERROR); } -bool Renderer11::shouldCreateChildWindowForSurface(EGLNativeWindowType window) const +SwapChainD3D *Renderer11::createSwapChain(NativeWindow nativeWindow, + HANDLE shareHandle, + GLenum backBufferFormat, + GLenum depthBufferFormat, + EGLint orientation) { -#if !defined(ANGLE_ENABLE_WINDOWS_STORE) - // 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. - DWORD currentProcessId = GetCurrentProcessId(); - DWORD wndProcessId; - GetWindowThreadProcessId(window, &wndProcessId); - if (currentProcessId == wndProcessId) - { - // Window is from this process, can always create a swap chain for it - return false; - } - - IDXGIDevice2 *dxgiDevice2 = d3d11::DynamicCastComObject(mDevice); - if (dxgiDevice2 != nullptr) - { - // DXGI 1.2 is available, can create a swap chain for this cross-process window - SafeRelease(dxgiDevice2); - return false; - } - - // DXGI 1.2 is not available, need to create a child window. - return true; -#else - return false; -#endif + return new SwapChain11(this, nativeWindow, shareHandle, backBufferFormat, depthBufferFormat, + orientation); } -SwapChainD3D *Renderer11::createSwapChain(NativeWindow nativeWindow, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat) +CompilerImpl *Renderer11::createCompiler() { - return new SwapChain11(this, nativeWindow, shareHandle, backBufferFormat, depthBufferFormat); + if (mRenderer11DeviceCaps.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); + } } void *Renderer11::getD3DDevice() @@ -738,10 +1141,10 @@ gl::Error Renderer11::generateSwizzle(gl::Texture *texture) if (texStorage) { TextureStorage11 *storage11 = GetAs(texStorage); - error = storage11->generateSwizzles(texture->getSamplerState().swizzleRed, - texture->getSamplerState().swizzleGreen, - texture->getSamplerState().swizzleBlue, - texture->getSamplerState().swizzleAlpha); + const gl::TextureState &textureState = texture->getTextureState(); + error = + storage11->generateSwizzles(textureState.swizzleRed, textureState.swizzleGreen, + textureState.swizzleBlue, textureState.swizzleAlpha); if (error.isError()) { return error; @@ -752,11 +1155,13 @@ gl::Error Renderer11::generateSwizzle(gl::Texture *texture) return gl::Error(GL_NO_ERROR); } -gl::Error Renderer11::setSamplerState(gl::SamplerType type, int index, gl::Texture *texture, const gl::SamplerState &samplerStateParam) +gl::Error Renderer11::setSamplerState(gl::SamplerType type, + int index, + gl::Texture *texture, + const gl::SamplerState &samplerState) { // Make sure to add the level offset for our tiny compressed texture workaround TextureD3D *textureD3D = GetImplAs(texture); - gl::SamplerState samplerStateInternal = samplerStateParam; TextureStorage *storage = nullptr; gl::Error error = textureD3D->getNativeTexture(&storage); @@ -768,16 +1173,20 @@ gl::Error Renderer11::setSamplerState(gl::SamplerType type, int index, gl::Textu // Storage should exist, texture should be complete ASSERT(storage); - samplerStateInternal.baseLevel += storage->getTopLevel(); + // 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. + SamplerMetadataD3D11 *metadata = nullptr; if (type == gl::SAMPLER_PIXEL) { ASSERT(static_cast(index) < getRendererCaps().maxTextureImageUnits); - if (mForceSetPixelSamplerStates[index] || memcmp(&samplerStateInternal, &mCurPixelSamplerStates[index], sizeof(gl::SamplerState)) != 0) + if (mForceSetPixelSamplerStates[index] || + memcmp(&samplerState, &mCurPixelSamplerStates[index], sizeof(gl::SamplerState)) != 0) { ID3D11SamplerState *dxSamplerState = NULL; - error = mStateCache.getSamplerState(samplerStateInternal, &dxSamplerState); + error = mStateCache.getSamplerState(samplerState, &dxSamplerState); if (error.isError()) { return error; @@ -786,19 +1195,22 @@ gl::Error Renderer11::setSamplerState(gl::SamplerType type, int index, gl::Textu ASSERT(dxSamplerState != NULL); mDeviceContext->PSSetSamplers(index, 1, &dxSamplerState); - mCurPixelSamplerStates[index] = samplerStateInternal; + mCurPixelSamplerStates[index] = samplerState; } mForceSetPixelSamplerStates[index] = false; + + metadata = &mSamplerMetadataPS; } else if (type == gl::SAMPLER_VERTEX) { ASSERT(static_cast(index) < getRendererCaps().maxVertexTextureImageUnits); - if (mForceSetVertexSamplerStates[index] || memcmp(&samplerStateInternal, &mCurVertexSamplerStates[index], sizeof(gl::SamplerState)) != 0) + if (mForceSetVertexSamplerStates[index] || + memcmp(&samplerState, &mCurVertexSamplerStates[index], sizeof(gl::SamplerState)) != 0) { ID3D11SamplerState *dxSamplerState = NULL; - error = mStateCache.getSamplerState(samplerStateInternal, &dxSamplerState); + error = mStateCache.getSamplerState(samplerState, &dxSamplerState); if (error.isError()) { return error; @@ -807,13 +1219,18 @@ gl::Error Renderer11::setSamplerState(gl::SamplerType type, int index, gl::Textu ASSERT(dxSamplerState != NULL); mDeviceContext->VSSetSamplers(index, 1, &dxSamplerState); - mCurVertexSamplerStates[index] = samplerStateInternal; + mCurVertexSamplerStates[index] = samplerState; } mForceSetVertexSamplerStates[index] = false; + + metadata = &mSamplerMetadataVS; } else UNREACHABLE(); + ASSERT(metadata != nullptr); + metadata->update(index, *texture); + return gl::Error(GL_NO_ERROR); } @@ -838,10 +1255,10 @@ gl::Error Renderer11::setTexture(gl::SamplerType type, int index, gl::Texture *t TextureStorage11 *storage11 = GetAs(texStorage); // Make sure to add the level offset for our tiny compressed texture workaround - gl::SamplerState samplerState = texture->getSamplerState(); - samplerState.baseLevel += storage11->getTopLevel(); + gl::TextureState textureState = texture->getTextureState(); + textureState.baseLevel += storage11->getTopLevel(); - error = storage11->getSRV(samplerState, &textureSRV); + error = storage11->getSRV(textureState, &textureSRV); if (error.isError()) { return error; @@ -857,16 +1274,16 @@ gl::Error Renderer11::setTexture(gl::SamplerType type, int index, gl::Texture *t ASSERT((type == gl::SAMPLER_PIXEL && static_cast(index) < getRendererCaps().maxTextureImageUnits) || (type == gl::SAMPLER_VERTEX && static_cast(index) < getRendererCaps().maxVertexTextureImageUnits)); - setShaderResource(type, index, textureSRV); + mStateManager.setShaderResource(type, index, textureSRV); return gl::Error(GL_NO_ERROR); } gl::Error Renderer11::setUniformBuffers(const gl::Data &data, - const GLint vertexUniformBuffers[], - const GLint fragmentUniformBuffers[]) + const std::vector &vertexUniformBuffers, + const std::vector &fragmentUniformBuffers) { - for (unsigned int uniformBufferIndex = 0; uniformBufferIndex < data.caps->maxVertexUniformBlocks; uniformBufferIndex++) + for (size_t uniformBufferIndex = 0; uniformBufferIndex < vertexUniformBuffers.size(); uniformBufferIndex++) { GLint binding = vertexUniformBuffers[uniformBufferIndex]; @@ -875,22 +1292,34 @@ gl::Error Renderer11::setUniformBuffers(const gl::Data &data, continue; } - gl::Buffer *uniformBuffer = data.state->getIndexedUniformBuffer(binding); - GLintptr uniformBufferOffset = data.state->getIndexedUniformBufferOffset(binding); - GLsizeiptr uniformBufferSize = data.state->getIndexedUniformBufferSize(binding); + const OffsetBindingPointer &uniformBuffer = + data.state->getIndexedUniformBuffer(binding); + GLintptr uniformBufferOffset = uniformBuffer.getOffset(); + GLsizeiptr uniformBufferSize = uniformBuffer.getSize(); - if (uniformBuffer) + if (uniformBuffer.get() != nullptr) { - Buffer11 *bufferStorage = GetImplAs(uniformBuffer); + Buffer11 *bufferStorage = GetImplAs(uniformBuffer.get()); ID3D11Buffer *constantBuffer; - if (mSupportsConstantBufferOffsets) + if (mRenderer11DeviceCaps.supportsConstantBufferOffsets) { - constantBuffer = bufferStorage->getBuffer(BUFFER_USAGE_UNIFORM); + auto bufferOrError = bufferStorage->getBuffer(BUFFER_USAGE_UNIFORM); + if (bufferOrError.isError()) + { + return bufferOrError.getError(); + } + constantBuffer = bufferOrError.getResult(); } else { - constantBuffer = bufferStorage->getConstantBufferRange(uniformBufferOffset, uniformBufferSize); + auto bufferOrError = + bufferStorage->getConstantBufferRange(uniformBufferOffset, uniformBufferSize); + if (bufferOrError.isError()) + { + return bufferOrError.getError(); + } + constantBuffer = bufferOrError.getResult(); } if (!constantBuffer) @@ -902,17 +1331,21 @@ gl::Error Renderer11::setUniformBuffers(const gl::Data &data, mCurrentConstantBufferVSOffset[uniformBufferIndex] != uniformBufferOffset || mCurrentConstantBufferVSSize[uniformBufferIndex] != uniformBufferSize) { - if (mSupportsConstantBufferOffsets && uniformBufferSize != 0) + if (mRenderer11DeviceCaps.supportsConstantBufferOffsets && uniformBufferSize != 0) { UINT firstConstant = 0, numConstants = 0; CalculateConstantBufferParams(uniformBufferOffset, uniformBufferSize, &firstConstant, &numConstants); - mDeviceContext1->VSSetConstantBuffers1(getReservedVertexUniformBuffers() + uniformBufferIndex, - 1, &constantBuffer, &firstConstant, &numConstants); + mDeviceContext1->VSSetConstantBuffers1( + getReservedVertexUniformBuffers() + + static_cast(uniformBufferIndex), + 1, &constantBuffer, &firstConstant, &numConstants); } else { - mDeviceContext->VSSetConstantBuffers(getReservedVertexUniformBuffers() + uniformBufferIndex, - 1, &constantBuffer); + mDeviceContext->VSSetConstantBuffers( + getReservedVertexUniformBuffers() + + static_cast(uniformBufferIndex), + 1, &constantBuffer); } mCurrentConstantBufferVS[uniformBufferIndex] = bufferStorage->getSerial(); @@ -922,7 +1355,7 @@ gl::Error Renderer11::setUniformBuffers(const gl::Data &data, } } - for (unsigned int uniformBufferIndex = 0; uniformBufferIndex < data.caps->maxFragmentUniformBlocks; uniformBufferIndex++) + for (size_t uniformBufferIndex = 0; uniformBufferIndex < fragmentUniformBuffers.size(); uniformBufferIndex++) { GLint binding = fragmentUniformBuffers[uniformBufferIndex]; @@ -931,22 +1364,34 @@ gl::Error Renderer11::setUniformBuffers(const gl::Data &data, continue; } - gl::Buffer *uniformBuffer = data.state->getIndexedUniformBuffer(binding); - GLintptr uniformBufferOffset = data.state->getIndexedUniformBufferOffset(binding); - GLsizeiptr uniformBufferSize = data.state->getIndexedUniformBufferSize(binding); + const OffsetBindingPointer &uniformBuffer = + data.state->getIndexedUniformBuffer(binding); + GLintptr uniformBufferOffset = uniformBuffer.getOffset(); + GLsizeiptr uniformBufferSize = uniformBuffer.getSize(); - if (uniformBuffer) + if (uniformBuffer.get() != nullptr) { - Buffer11 *bufferStorage = GetImplAs(uniformBuffer); + Buffer11 *bufferStorage = GetImplAs(uniformBuffer.get()); ID3D11Buffer *constantBuffer; - if (mSupportsConstantBufferOffsets) + if (mRenderer11DeviceCaps.supportsConstantBufferOffsets) { - constantBuffer = bufferStorage->getBuffer(BUFFER_USAGE_UNIFORM); + auto bufferOrError = bufferStorage->getBuffer(BUFFER_USAGE_UNIFORM); + if (bufferOrError.isError()) + { + return bufferOrError.getError(); + } + constantBuffer = bufferOrError.getResult(); } else { - constantBuffer = bufferStorage->getConstantBufferRange(uniformBufferOffset, uniformBufferSize); + auto bufferOrError = + bufferStorage->getConstantBufferRange(uniformBufferOffset, uniformBufferSize); + if (bufferOrError.isError()) + { + return bufferOrError.getError(); + } + constantBuffer = bufferOrError.getResult(); } if (!constantBuffer) @@ -958,252 +1403,87 @@ gl::Error Renderer11::setUniformBuffers(const gl::Data &data, mCurrentConstantBufferPSOffset[uniformBufferIndex] != uniformBufferOffset || mCurrentConstantBufferPSSize[uniformBufferIndex] != uniformBufferSize) { - if (mSupportsConstantBufferOffsets && uniformBufferSize != 0) + if (mRenderer11DeviceCaps.supportsConstantBufferOffsets && uniformBufferSize != 0) { UINT firstConstant = 0, numConstants = 0; CalculateConstantBufferParams(uniformBufferOffset, uniformBufferSize, &firstConstant, &numConstants); - mDeviceContext1->PSSetConstantBuffers1(getReservedFragmentUniformBuffers() + uniformBufferIndex, - 1, &constantBuffer, &firstConstant, &numConstants); - } - else - { - mDeviceContext->PSSetConstantBuffers(getReservedFragmentUniformBuffers() + uniformBufferIndex, - 1, &constantBuffer); - } - - mCurrentConstantBufferPS[uniformBufferIndex] = bufferStorage->getSerial(); - mCurrentConstantBufferPSOffset[uniformBufferIndex] = uniformBufferOffset; - mCurrentConstantBufferPSSize[uniformBufferIndex] = uniformBufferSize; - } - } - } - - return gl::Error(GL_NO_ERROR); -} - -gl::Error Renderer11::setRasterizerState(const gl::RasterizerState &rasterState) -{ - if (mForceSetRasterState || memcmp(&rasterState, &mCurRasterState, sizeof(gl::RasterizerState)) != 0) - { - ID3D11RasterizerState *dxRasterState = NULL; - gl::Error error = mStateCache.getRasterizerState(rasterState, mScissorEnabled, &dxRasterState); - if (error.isError()) - { - return error; - } - - mDeviceContext->RSSetState(dxRasterState); - - mCurRasterState = rasterState; - } - - mForceSetRasterState = false; - - return gl::Error(GL_NO_ERROR); -} - -gl::Error Renderer11::setBlendState(const gl::Framebuffer *framebuffer, const gl::BlendState &blendState, const gl::ColorF &blendColor, - unsigned int sampleMask) -{ - if (mForceSetBlendState || - memcmp(&blendState, &mCurBlendState, sizeof(gl::BlendState)) != 0 || - memcmp(&blendColor, &mCurBlendColor, sizeof(gl::ColorF)) != 0 || - sampleMask != mCurSampleMask) - { - ID3D11BlendState *dxBlendState = NULL; - gl::Error error = mStateCache.getBlendState(framebuffer, blendState, &dxBlendState); - if (error.isError()) - { - return error; - } - - ASSERT(dxBlendState != NULL); + mDeviceContext1->PSSetConstantBuffers1( + getReservedFragmentUniformBuffers() + + static_cast(uniformBufferIndex), + 1, &constantBuffer, &firstConstant, &numConstants); + } + else + { + mDeviceContext->PSSetConstantBuffers( + getReservedFragmentUniformBuffers() + + static_cast(uniformBufferIndex), + 1, &constantBuffer); + } - float blendColors[4] = {0.0f}; - 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) - { - blendColors[0] = blendColor.red; - blendColors[1] = blendColor.green; - blendColors[2] = blendColor.blue; - blendColors[3] = blendColor.alpha; - } - else - { - blendColors[0] = blendColor.alpha; - blendColors[1] = blendColor.alpha; - blendColors[2] = blendColor.alpha; - blendColors[3] = blendColor.alpha; + mCurrentConstantBufferPS[uniformBufferIndex] = bufferStorage->getSerial(); + mCurrentConstantBufferPSOffset[uniformBufferIndex] = uniformBufferOffset; + mCurrentConstantBufferPSSize[uniformBufferIndex] = uniformBufferSize; + } } - - mDeviceContext->OMSetBlendState(dxBlendState, blendColors, sampleMask); - - mCurBlendState = blendState; - mCurBlendColor = blendColor; - mCurSampleMask = sampleMask; } - mForceSetBlendState = false; - return gl::Error(GL_NO_ERROR); } -gl::Error Renderer11::setDepthStencilState(const gl::DepthStencilState &depthStencilState, int stencilRef, - int stencilBackRef, bool frontFaceCCW) +gl::Error Renderer11::updateState(const gl::Data &data, GLenum drawMode) { - if (mForceSetDepthStencilState || - memcmp(&depthStencilState, &mCurDepthStencilState, sizeof(gl::DepthStencilState)) != 0 || - stencilRef != mCurStencilRef || stencilBackRef != mCurStencilBackRef) + // Applies the render target surface, depth stencil surface, viewport rectangle and + // scissor rectangle to the renderer + const gl::Framebuffer *framebufferObject = data.state->getDrawFramebuffer(); + ASSERT(framebufferObject && framebufferObject->checkStatus(data) == GL_FRAMEBUFFER_COMPLETE); + gl::Error error = applyRenderTarget(framebufferObject); + if (error.isError()) { - ASSERT(depthStencilState.stencilWritemask == depthStencilState.stencilBackWritemask); - ASSERT(stencilRef == stencilBackRef); - ASSERT(depthStencilState.stencilMask == depthStencilState.stencilBackMask); + return error; + } - ID3D11DepthStencilState *dxDepthStencilState = NULL; - gl::Error error = mStateCache.getDepthStencilState(depthStencilState, &dxDepthStencilState); - if (error.isError()) - { - return error; - } + // Set the present path state + const bool presentPathFastActive = + UsePresentPathFast(this, framebufferObject->getFirstColorbuffer()); + mStateManager.updatePresentPath(presentPathFastActive, + framebufferObject->getFirstColorbuffer()); - ASSERT(dxDepthStencilState); + // Setting viewport state + mStateManager.setViewport(data.caps, data.state->getViewport(), data.state->getNearPlane(), + data.state->getFarPlane()); - // 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 = std::min(stencilRef, 0xFFu); + // Setting scissor state + mStateManager.setScissorRectangle(data.state->getScissor(), data.state->isScissorTestEnabled()); - mDeviceContext->OMSetDepthStencilState(dxDepthStencilState, dxStencilRef); + // Applying rasterizer state to D3D11 device + int samples = framebufferObject->getSamples(data); + gl::RasterizerState rasterizer = data.state->getRasterizerState(); + rasterizer.pointDrawMode = (drawMode == GL_POINTS); + rasterizer.multiSample = (samples != 0); - mCurDepthStencilState = depthStencilState; - mCurStencilRef = stencilRef; - mCurStencilBackRef = stencilBackRef; + error = mStateManager.setRasterizerState(rasterizer); + if (error.isError()) + { + return error; } - mForceSetDepthStencilState = false; - - return gl::Error(GL_NO_ERROR); -} - -void Renderer11::setScissorRectangle(const gl::Rectangle &scissor, bool enabled) -{ - if (mForceSetScissor || memcmp(&scissor, &mCurScissor, sizeof(gl::Rectangle)) != 0 || - enabled != mScissorEnabled) + // Setting blend state + unsigned int mask = GetBlendSampleMask(data, samples); + error = mStateManager.setBlendState(framebufferObject, data.state->getBlendState(), + data.state->getBlendColor(), mask); + if (error.isError()) { - if (enabled) - { - D3D11_RECT rect; - rect.left = std::max(0, scissor.x); - rect.top = std::max(0, scissor.y); - rect.right = scissor.x + std::max(0, scissor.width); - rect.bottom = scissor.y + std::max(0, scissor.height); - - mDeviceContext->RSSetScissorRects(1, &rect); - } - - if (enabled != mScissorEnabled) - { - mForceSetRasterState = true; - } - - mCurScissor = scissor; - mScissorEnabled = enabled; + return error; } - mForceSetScissor = false; + // Setting depth stencil state + error = mStateManager.setDepthStencilState(*data.state); + return error; } -void Renderer11::setViewport(const gl::Rectangle &viewport, float zNear, float zFar, GLenum drawMode, GLenum frontFace, - bool ignoreViewport) +void Renderer11::syncState(const gl::State &state, const gl::State::DirtyBits &bitmask) { - gl::Rectangle actualViewport = viewport; - float actualZNear = gl::clamp01(zNear); - float actualZFar = gl::clamp01(zFar); - if (ignoreViewport) - { - actualViewport.x = 0; - actualViewport.y = 0; - actualViewport.width = mRenderTargetDesc.width; - actualViewport.height = mRenderTargetDesc.height; - actualZNear = 0.0f; - actualZFar = 1.0f; - } - - bool viewportChanged = mForceSetViewport || memcmp(&actualViewport, &mCurViewport, sizeof(gl::Rectangle)) != 0 || - actualZNear != mCurNear || actualZFar != mCurFar; - - if (viewportChanged) - { - const gl::Caps& caps = getRendererCaps(); - - int dxMaxViewportBoundsX = static_cast(caps.maxViewportWidth); - int dxMaxViewportBoundsY = static_cast(caps.maxViewportHeight); - int dxMinViewportBoundsX = -dxMaxViewportBoundsX; - int dxMinViewportBoundsY = -dxMaxViewportBoundsY; - - if (mFeatureLevel <= D3D_FEATURE_LEVEL_9_3) - { - // Feature Level 9 viewports shouldn't exceed the dimensions of the rendertarget. - dxMaxViewportBoundsX = mRenderTargetDesc.width; - dxMaxViewportBoundsY = mRenderTargetDesc.height; - dxMinViewportBoundsX = 0; - dxMinViewportBoundsY = 0; - } - - int dxViewportTopLeftX = gl::clamp(actualViewport.x, dxMinViewportBoundsX, dxMaxViewportBoundsX); - int dxViewportTopLeftY = gl::clamp(actualViewport.y, dxMinViewportBoundsY, dxMaxViewportBoundsY); - int dxViewportWidth = gl::clamp(actualViewport.width, 0, dxMaxViewportBoundsX - dxViewportTopLeftX); - int dxViewportHeight = gl::clamp(actualViewport.height, 0, dxMaxViewportBoundsY - dxViewportTopLeftY); - - D3D11_VIEWPORT dxViewport; - dxViewport.TopLeftX = static_cast(dxViewportTopLeftX); - dxViewport.TopLeftY = static_cast(dxViewportTopLeftY); - dxViewport.Width = static_cast(dxViewportWidth); - dxViewport.Height = static_cast(dxViewportHeight); - dxViewport.MinDepth = actualZNear; - dxViewport.MaxDepth = actualZFar; - - mDeviceContext->RSSetViewports(1, &dxViewport); - - mCurViewport = actualViewport; - mCurNear = actualZNear; - mCurFar = actualZFar; - - // On Feature Level 9_*, we must emulate large and/or negative viewports in the shaders using viewAdjust (like the D3D9 renderer). - if (mFeatureLevel <= D3D_FEATURE_LEVEL_9_3) - { - mVertexConstants.viewAdjust[0] = static_cast((actualViewport.width - dxViewportWidth) + 2 * (actualViewport.x - dxViewportTopLeftX)) / dxViewport.Width; - mVertexConstants.viewAdjust[1] = static_cast((actualViewport.height - dxViewportHeight) + 2 * (actualViewport.y - dxViewportTopLeftY)) / dxViewport.Height; - mVertexConstants.viewAdjust[2] = static_cast(actualViewport.width) / dxViewport.Width; - mVertexConstants.viewAdjust[3] = static_cast(actualViewport.height) / dxViewport.Height; - } - - mPixelConstants.viewCoords[0] = actualViewport.width * 0.5f; - mPixelConstants.viewCoords[1] = actualViewport.height * 0.5f; - mPixelConstants.viewCoords[2] = actualViewport.x + (actualViewport.width * 0.5f); - mPixelConstants.viewCoords[3] = actualViewport.y + (actualViewport.height * 0.5f); - - // Instanced pointsprite emulation requires ViewCoords to be defined in the - // the vertex shader. - mVertexConstants.viewCoords[0] = mPixelConstants.viewCoords[0]; - mVertexConstants.viewCoords[1] = mPixelConstants.viewCoords[1]; - mVertexConstants.viewCoords[2] = mPixelConstants.viewCoords[2]; - mVertexConstants.viewCoords[3] = mPixelConstants.viewCoords[3]; - - mPixelConstants.depthFront[0] = (actualZFar - actualZNear) * 0.5f; - mPixelConstants.depthFront[1] = (actualZNear + actualZFar) * 0.5f; - - mVertexConstants.depthRange[0] = actualZNear; - mVertexConstants.depthRange[1] = actualZFar; - mVertexConstants.depthRange[2] = actualZFar - actualZNear; - - mPixelConstants.depthRange[0] = actualZNear; - mPixelConstants.depthRange[1] = actualZFar; - mPixelConstants.depthRange[2] = actualZFar - actualZNear; - } - - mForceSetViewport = false; + mStateManager.syncState(state, bitmask); } bool Renderer11::applyPrimitiveType(GLenum mode, GLsizei count, bool usesPointSize) @@ -1244,174 +1524,74 @@ bool Renderer11::applyPrimitiveType(GLenum mode, GLsizei count, bool usesPointSi return count >= minCount; } -void Renderer11::unsetConflictingSRVs(gl::SamplerType samplerType, uintptr_t resource, const gl::ImageIndex &index) +gl::Error Renderer11::applyRenderTarget(const gl::Framebuffer *framebuffer) { - auto ¤tSRVs = (samplerType == gl::SAMPLER_VERTEX ? mCurVertexSRVs : mCurPixelSRVs); - - for (size_t resourceIndex = 0; resourceIndex < currentSRVs.size(); ++resourceIndex) - { - auto &record = currentSRVs[resourceIndex]; - - if (record.srv && record.resource == resource && ImageIndexConflictsWithSRV(index, record.desc)) - { - setShaderResource(samplerType, static_cast(resourceIndex), NULL); - } - } + return mStateManager.syncFramebuffer(framebuffer); } -gl::Error Renderer11::applyRenderTarget(const gl::Framebuffer *framebuffer) +gl::Error Renderer11::applyVertexBuffer(const gl::State &state, + GLenum mode, + GLint first, + GLsizei count, + GLsizei instances, + TranslatedIndexData *indexInfo) { - // Get the color render buffer and serial - // Also extract the render target dimensions and view - unsigned int renderTargetWidth = 0; - unsigned int renderTargetHeight = 0; - DXGI_FORMAT renderTargetFormat = DXGI_FORMAT_UNKNOWN; - ID3D11RenderTargetView* framebufferRTVs[gl::IMPLEMENTATION_MAX_DRAW_BUFFERS] = {NULL}; - bool missingColorRenderTarget = true; - - const FramebufferD3D *framebufferD3D = GetImplAs(framebuffer); - const gl::AttachmentList &colorbuffers = framebufferD3D->getColorAttachmentsForRender(getWorkarounds()); + const auto &vertexArray = state.getVertexArray(); + auto *vertexArray11 = GetImplAs(vertexArray); - for (size_t colorAttachment = 0; colorAttachment < colorbuffers.size(); ++colorAttachment) + gl::Error error = vertexArray11->updateDirtyAndDynamicAttribs(mVertexDataManager, state, first, + count, instances); + if (error.isError()) { - const gl::FramebufferAttachment *colorbuffer = colorbuffers[colorAttachment]; - - if (colorbuffer) - { - // the draw buffer must be either "none", "back" for the default buffer or the same index as this color (in order) - - // 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 (colorbuffer->getWidth() == 0 || colorbuffer->getHeight() == 0) - { - return gl::Error(GL_NO_ERROR); - } - - // Extract the render target dimensions and view - RenderTarget11 *renderTarget = NULL; - gl::Error error = colorbuffer->getRenderTarget(&renderTarget); - if (error.isError()) - { - return error; - } - ASSERT(renderTarget); - - framebufferRTVs[colorAttachment] = renderTarget->getRenderTargetView(); - ASSERT(framebufferRTVs[colorAttachment]); - - if (missingColorRenderTarget) - { - renderTargetWidth = renderTarget->getWidth(); - renderTargetHeight = renderTarget->getHeight(); - renderTargetFormat = renderTarget->getDXGIFormat(); - missingColorRenderTarget = false; - } - - // Unbind render target SRVs from the shader here to prevent D3D11 warnings. - if (colorbuffer->type() == GL_TEXTURE) - { - uintptr_t rtResource = reinterpret_cast(GetViewResource(framebufferRTVs[colorAttachment])); - const gl::ImageIndex &index = colorbuffer->getTextureImageIndex(); - // The index doesn't need to be corrected for the small compressed texture workaround - // because a rendertarget is never compressed. - unsetConflictingSRVs(gl::SAMPLER_VERTEX, rtResource, index); - unsetConflictingSRVs(gl::SAMPLER_PIXEL, rtResource, index); - } - } + return error; } - // Get the depth stencil buffers - ID3D11DepthStencilView* framebufferDSV = NULL; - const gl::FramebufferAttachment *depthStencil = framebuffer->getDepthOrStencilbuffer(); - if (depthStencil) + error = mStateManager.updateCurrentValueAttribs(state, mVertexDataManager); + if (error.isError()) { - RenderTarget11 *depthStencilRenderTarget = NULL; - gl::Error error = depthStencil->getRenderTarget(&depthStencilRenderTarget); - if (error.isError()) - { - SafeRelease(framebufferRTVs); - return error; - } - ASSERT(depthStencilRenderTarget); - - framebufferDSV = depthStencilRenderTarget->getDepthStencilView(); - ASSERT(framebufferDSV); - - // If there is no render buffer, the width, height and format values come from - // the depth stencil - if (missingColorRenderTarget) - { - renderTargetWidth = depthStencilRenderTarget->getWidth(); - renderTargetHeight = depthStencilRenderTarget->getHeight(); - renderTargetFormat = depthStencilRenderTarget->getDXGIFormat(); - } - - // Unbind render target SRVs from the shader here to prevent D3D11 warnings. - if (depthStencil->type() == GL_TEXTURE) - { - uintptr_t depthStencilResource = reinterpret_cast(GetViewResource(framebufferDSV)); - const gl::ImageIndex &index = depthStencil->getTextureImageIndex(); - // The index doesn't need to be corrected for the small compressed texture workaround - // because a rendertarget is never compressed. - unsetConflictingSRVs(gl::SAMPLER_VERTEX, depthStencilResource, index); - unsetConflictingSRVs(gl::SAMPLER_PIXEL, depthStencilResource, index); - } + return error; } - // Apply the render target and depth stencil - if (!mRenderTargetDescInitialized || !mDepthStencilInitialized || - memcmp(framebufferRTVs, mAppliedRTVs, sizeof(framebufferRTVs)) != 0 || - reinterpret_cast(framebufferDSV) != mAppliedDSV) + // If index information is passed, mark it with the current changed status. + if (indexInfo) { - mDeviceContext->OMSetRenderTargets(getRendererCaps().maxDrawBuffers, framebufferRTVs, framebufferDSV); - - mRenderTargetDesc.width = renderTargetWidth; - mRenderTargetDesc.height = renderTargetHeight; - mRenderTargetDesc.format = renderTargetFormat; - mForceSetViewport = true; - mForceSetScissor = true; - mForceSetBlendState = true; - - if (!mDepthStencilInitialized) - { - mForceSetRasterState = true; - } - - for (size_t rtIndex = 0; rtIndex < ArraySize(framebufferRTVs); rtIndex++) - { - mAppliedRTVs[rtIndex] = reinterpret_cast(framebufferRTVs[rtIndex]); - } - mAppliedDSV = reinterpret_cast(framebufferDSV); - mRenderTargetDescInitialized = true; - mDepthStencilInitialized = true; + indexInfo->srcIndexData.srcIndicesChanged = mAppliedIBChanged; } - const Framebuffer11 *framebuffer11 = GetImplAs(framebuffer); - gl::Error error = framebuffer11->invalidateSwizzles(); - if (error.isError()) + GLsizei numIndicesPerInstance = 0; + if (instances > 0) { - return error; + numIndicesPerInstance = count; } + const auto &vertexArrayAttribs = vertexArray11->getTranslatedAttribs(); + const auto ¤tValueAttribs = mStateManager.getCurrentValueAttribs(); + ANGLE_TRY(mInputLayoutCache.applyVertexBuffers(state, vertexArrayAttribs, currentValueAttribs, + mode, first, indexInfo, numIndicesPerInstance)); - return gl::Error(GL_NO_ERROR); -} - -gl::Error Renderer11::applyVertexBuffer(const gl::State &state, GLenum mode, GLint first, GLsizei count, GLsizei instances) -{ - TranslatedAttribute attributes[gl::MAX_VERTEX_ATTRIBS]; - gl::Error error = mVertexDataManager->prepareVertexData(state, first, count, attributes, instances); - if (error.isError()) - { - return error; - } + // InputLayoutCache::applyVertexBuffers calls through to the Bufer11 to get the native vertex + // buffer (ID3D11Buffer *). Because we allocate these buffers lazily, this will trigger + // allocation. This in turn will signal that the buffer is dirty. Since we just resolved the + // dirty-ness in VertexArray11::updateDirtyAndDynamicAttribs, this can make us do a needless + // update on the second draw call. + // Hence we clear the flags here, after we've applied vertex data, since we know everything + // is clean. This is a bit of a hack. + vertexArray11->clearDirtyAndPromoteDynamicAttribs(state, count); - return mInputLayoutCache.applyVertexBuffers(attributes, mode, state.getProgram()); + return gl::NoError(); } -gl::Error Renderer11::applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementArrayBuffer, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo) +gl::Error Renderer11::applyIndexBuffer(const gl::Data &data, + const GLvoid *indices, + GLsizei count, + GLenum mode, + GLenum type, + TranslatedIndexData *indexInfo) { - gl::Error error = mIndexDataManager->prepareIndexData(type, count, elementArrayBuffer, indices, indexInfo); + gl::VertexArray *vao = data.state->getVertexArray(); + gl::Buffer *elementArrayBuffer = vao->getElementArrayBuffer().get(); + gl::Error error = + mIndexDataManager->prepareIndexData(type, count, elementArrayBuffer, indices, indexInfo, + data.state->isPrimitiveRestartEnabled()); if (error.isError()) { return error; @@ -1423,7 +1603,12 @@ gl::Error Renderer11::applyIndexBuffer(const GLvoid *indices, gl::Buffer *elemen if (indexInfo->storage) { Buffer11 *storage = GetAs(indexInfo->storage); - buffer = storage->getBuffer(BUFFER_USAGE_INDEX); + auto indexOrError = storage->getBuffer(BUFFER_USAGE_INDEX); + if (indexOrError.isError()) + { + return indexOrError.getError(); + } + buffer = indexOrError.getResult(); } else { @@ -1431,6 +1616,7 @@ gl::Error Renderer11::applyIndexBuffer(const GLvoid *indices, gl::Buffer *elemen buffer = indexBuffer->getBuffer(); } + mAppliedIBChanged = false; if (buffer != mAppliedIB || bufferFormat != mAppliedIBFormat || indexInfo->startOffset != mAppliedIBOffset) { mDeviceContext->IASetIndexBuffer(buffer, bufferFormat, indexInfo->startOffset); @@ -1438,12 +1624,13 @@ gl::Error Renderer11::applyIndexBuffer(const GLvoid *indices, gl::Buffer *elemen mAppliedIB = buffer; mAppliedIBFormat = bufferFormat; mAppliedIBOffset = indexInfo->startOffset; + mAppliedIBChanged = true; } return gl::Error(GL_NO_ERROR); } -void Renderer11::applyTransformFeedbackBuffers(const gl::State &state) +gl::Error Renderer11::applyTransformFeedbackBuffers(const gl::State &state) { size_t numXFBBindings = 0; bool requiresUpdate = false; @@ -1458,11 +1645,16 @@ void Renderer11::applyTransformFeedbackBuffers(const gl::State &state) { const OffsetBindingPointer &binding = transformFeedback->getIndexedBuffer(i); - ID3D11Buffer *d3dBuffer = NULL; + ID3D11Buffer *d3dBuffer = nullptr; if (binding.get() != nullptr) { Buffer11 *storage = GetImplAs(binding.get()); - d3dBuffer = storage->getBuffer(BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK); + auto bufferOrError = storage->getBuffer(BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK); + if (bufferOrError.isError()) + { + return bufferOrError.getError(); + } + d3dBuffer = bufferOrError.getResult(); } // TODO: mAppliedTFBuffers and friends should also be kept in a vector. @@ -1482,7 +1674,12 @@ void Renderer11::applyTransformFeedbackBuffers(const gl::State &state) if (binding.get() != nullptr) { Buffer11 *storage = GetImplAs(binding.get()); - ID3D11Buffer *d3dBuffer = storage->getBuffer(BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK); + auto bufferOrError = storage->getBuffer(BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK); + if (bufferOrError.isError()) + { + return bufferOrError.getError(); + } + ID3D11Buffer *d3dBuffer = bufferOrError.getResult(); mCurrentD3DOffsets[i] = (mAppliedTFBuffers[i] != d3dBuffer || mAppliedTFOffsets[i] != binding.getOffset()) ? static_cast(binding.getOffset()) : -1; @@ -1490,7 +1687,7 @@ void Renderer11::applyTransformFeedbackBuffers(const gl::State &state) } else { - mAppliedTFBuffers[i] = NULL; + mAppliedTFBuffers[i] = nullptr; mCurrentD3DOffsets[i] = 0; } mAppliedTFOffsets[i] = binding.getOffset(); @@ -1498,21 +1695,28 @@ void Renderer11::applyTransformFeedbackBuffers(const gl::State &state) mAppliedNumXFBBindings = numXFBBindings; - mDeviceContext->SOSetTargets(numXFBBindings, mAppliedTFBuffers, mCurrentD3DOffsets); + mDeviceContext->SOSetTargets(static_cast(numXFBBindings), mAppliedTFBuffers, + mCurrentD3DOffsets); } + + return gl::Error(GL_NO_ERROR); } -gl::Error Renderer11::drawArrays(const gl::Data &data, GLenum mode, GLsizei count, GLsizei instances, bool usesPointSize) +gl::Error Renderer11::drawArraysImpl(const gl::Data &data, + GLenum mode, + GLint startVertex, + GLsizei count, + GLsizei instances) { - bool useInstancedPointSpriteEmulation = usesPointSize && getWorkarounds().useInstancedPointSpriteEmulation; - if (mode == GL_POINTS && data.state->isTransformFeedbackActiveUnpaused()) - { - // Since point sprites are generated with a geometry shader, too many vertices will - // be written if transform feedback is active. To work around this, draw only the points - // with the stream out shader and no pixel shader to feed the stream out buffers and then - // draw again with the point sprite geometry shader to rasterize the point sprites. + ProgramD3D *programD3D = GetImplAs(data.state->getProgram()); - mDeviceContext->PSSetShader(NULL, NULL, 0); + if (programD3D->usesGeometryShader(mode) && data.state->isTransformFeedbackActiveUnpaused()) + { + // 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. + mDeviceContext->PSSetShader(nullptr, nullptr, 0); if (instances > 0) { @@ -1523,98 +1727,194 @@ gl::Error Renderer11::drawArrays(const gl::Data &data, GLenum mode, GLsizei coun mDeviceContext->Draw(count, 0); } - ProgramD3D *programD3D = GetImplAs(data.state->getProgram()); - - rx::ShaderExecutableD3D *pixelExe = NULL; + rx::ShaderExecutableD3D *pixelExe = nullptr; gl::Error error = programD3D->getPixelExecutableForFramebuffer(data.state->getDrawFramebuffer(), &pixelExe); if (error.isError()) { return error; } - // Skip this step if we're doing rasterizer discard. - if (pixelExe && !data.state->getRasterizerState().rasterizerDiscard && usesPointSize) + // Skip the draw call if rasterizer discard is enabled (or no fragment shader). + if (!pixelExe || data.state->getRasterizerState().rasterizerDiscard) { - ID3D11PixelShader *pixelShader = GetAs(pixelExe)->getPixelShader(); - ASSERT(reinterpret_cast(pixelShader) == mAppliedPixelShader); - mDeviceContext->PSSetShader(pixelShader, NULL, 0); + return gl::Error(GL_NO_ERROR); + } - // Retrieve the point sprite geometry shader - rx::ShaderExecutableD3D *geometryExe = programD3D->getGeometryExecutable(); - ID3D11GeometryShader *geometryShader = (geometryExe ? GetAs(geometryExe)->getGeometryShader() : NULL); - mAppliedGeometryShader = reinterpret_cast(geometryShader); - ASSERT(geometryShader); - mDeviceContext->GSSetShader(geometryShader, NULL, 0); + ID3D11PixelShader *pixelShader = GetAs(pixelExe)->getPixelShader(); + ASSERT(reinterpret_cast(pixelShader) == mAppliedPixelShader); + mDeviceContext->PSSetShader(pixelShader, NULL, 0); - if (instances > 0) - { - mDeviceContext->DrawInstanced(count, instances, 0, 0); - } - else - { - mDeviceContext->Draw(count, 0); - } + // Retrieve the geometry shader. + rx::ShaderExecutableD3D *geometryExe = nullptr; + error = + programD3D->getGeometryExecutableForPrimitiveType(data, mode, &geometryExe, nullptr); + if (error.isError()) + { + return error; } + ID3D11GeometryShader *geometryShader = + (geometryExe ? GetAs(geometryExe)->getGeometryShader() : NULL); + mAppliedGeometryShader = reinterpret_cast(geometryShader); + ASSERT(geometryShader); + mDeviceContext->GSSetShader(geometryShader, NULL, 0); + + if (instances > 0) + { + mDeviceContext->DrawInstanced(count, instances, 0, 0); + } + else + { + mDeviceContext->Draw(count, 0); + } return gl::Error(GL_NO_ERROR); } - else if (mode == GL_LINE_LOOP) - { - return drawLineLoop(count, GL_NONE, NULL, 0, NULL); - } - else if (mode == GL_TRIANGLE_FAN) + + if (mode == GL_LINE_LOOP) { - return drawTriangleFan(count, GL_NONE, NULL, 0, NULL, instances); + return drawLineLoop(data, count, GL_NONE, nullptr, nullptr, instances); } - else if (instances > 0) + + if (mode == GL_TRIANGLE_FAN) { - mDeviceContext->DrawInstanced(count, instances, 0, 0); - return gl::Error(GL_NO_ERROR); + return drawTriangleFan(data, count, GL_NONE, nullptr, 0, instances); } - else + + bool useInstancedPointSpriteEmulation = + programD3D->usesPointSize() && getWorkarounds().useInstancedPointSpriteEmulation; + + if (instances > 0) { - // If gl_PointSize is used and GL_POINTS is specified, then it is expected to render pointsprites. - // If instanced pointsprite emulation is being used the topology is expexted to be - // D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST and DrawIndexedInstanced must be used. if (mode == GL_POINTS && useInstancedPointSpriteEmulation) { - mDeviceContext->DrawIndexedInstanced(6, count, 0, 0, 0); + // 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 < instances; i++) + { + gl::Error error = + mInputLayoutCache.updateVertexOffsetsForPointSpritesEmulation(startVertex, i); + if (error.isError()) + { + return error; + } + + mDeviceContext->DrawIndexedInstanced(6, count, 0, 0, 0); + } } else { - mDeviceContext->Draw(count, 0); + mDeviceContext->DrawInstanced(count, instances, 0, 0); } return gl::Error(GL_NO_ERROR); } + + // 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 (mode == GL_POINTS && useInstancedPointSpriteEmulation) + { + mDeviceContext->DrawIndexedInstanced(6, count, 0, 0, 0); + } + else + { + mDeviceContext->Draw(count, 0); + } + return gl::Error(GL_NO_ERROR); } -gl::Error Renderer11::drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, - gl::Buffer *elementArrayBuffer, const TranslatedIndexData &indexInfo, GLsizei instances) +gl::Error Renderer11::drawElementsImpl(const gl::Data &data, + const TranslatedIndexData &indexInfo, + GLenum mode, + GLsizei count, + GLenum type, + const GLvoid *indices, + GLsizei instances) { int minIndex = static_cast(indexInfo.indexRange.start); if (mode == GL_LINE_LOOP) { - return drawLineLoop(count, type, indices, minIndex, elementArrayBuffer); + return drawLineLoop(data, count, type, indices, &indexInfo, instances); } - else if (mode == GL_TRIANGLE_FAN) + + if (mode == GL_TRIANGLE_FAN) { - return drawTriangleFan(count, type, indices, minIndex, elementArrayBuffer, instances); + return drawTriangleFan(data, count, type, indices, minIndex, instances); } - else if (instances > 0) + + const ProgramD3D *programD3D = GetImplAs(data.state->getProgram()); + if (instances > 0) { - mDeviceContext->DrawIndexedInstanced(count, instances, 0, -minIndex, 0); + if (mode == GL_POINTS && programD3D->usesInstancedPointSpriteEmulation()) + { + // 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. + GLsizei elementsToRender = static_cast(indexInfo.indexRange.vertexCount()); + + // Each instance being rendered requires the inputlayout cache to reapply buffers and + // offsets. + for (GLsizei i = 0; i < instances; i++) + { + gl::Error error = + mInputLayoutCache.updateVertexOffsetsForPointSpritesEmulation(minIndex, i); + if (error.isError()) + { + return error; + } + + mDeviceContext->DrawIndexedInstanced(6, elementsToRender, 0, 0, 0); + } + } + else + { + mDeviceContext->DrawIndexedInstanced(count, instances, 0, -minIndex, 0); + } return gl::Error(GL_NO_ERROR); } + + // 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 (mode == GL_POINTS && programD3D->usesInstancedPointSpriteEmulation()) + { + // 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. + mDeviceContext->DrawIndexedInstanced(6, count, 0, 0, 0); + } else { mDeviceContext->DrawIndexed(count, 0, -minIndex); - return gl::Error(GL_NO_ERROR); } + return gl::Error(GL_NO_ERROR); } -gl::Error Renderer11::drawLineLoop(GLsizei count, GLenum type, const GLvoid *indices, int minIndex, gl::Buffer *elementArrayBuffer) +gl::Error Renderer11::drawLineLoop(const gl::Data &data, + GLsizei count, + GLenum type, + const GLvoid *indexPointer, + const TranslatedIndexData *indexInfo, + int instances) { + gl::VertexArray *vao = data.state->getVertexArray(); + gl::Buffer *elementArrayBuffer = vao->getElementArrayBuffer().get(); + + const GLvoid *indices = indexPointer; + // Get the raw indices for an indexed draw if (type != GL_NONE && elementArrayBuffer) { @@ -1650,7 +1950,11 @@ gl::Error Renderer11::drawLineLoop(GLsizei count, GLenum type, const GLvoid *ind return gl::Error(GL_OUT_OF_MEMORY, "Failed to create a 32-bit looping index buffer for GL_LINE_LOOP, too many indices required."); } - const unsigned int spaceNeeded = (static_cast(count) + 1) * sizeof(unsigned int); + GetLineLoopIndices(indices, type, static_cast(count), + data.state->isPrimitiveRestartEnabled(), &mScratchIndexDataBuffer); + + unsigned int spaceNeeded = + static_cast(sizeof(GLuint) * mScratchIndexDataBuffer.size()); gl::Error error = mLineLoopIB->reserveBufferSpace(spaceNeeded, GL_UNSIGNED_INT); if (error.isError()) { @@ -1665,41 +1969,9 @@ gl::Error Renderer11::drawLineLoop(GLsizei count, GLenum type, const GLvoid *ind return error; } - unsigned int *data = reinterpret_cast(mappedMemory); - unsigned int indexBufferOffset = offset; - - switch (type) - { - case GL_NONE: // Non-indexed draw - for (int i = 0; i < count; i++) - { - data[i] = i; - } - data[count] = 0; - break; - case GL_UNSIGNED_BYTE: - for (int i = 0; i < count; i++) - { - data[i] = static_cast(indices)[i]; - } - data[count] = static_cast(indices)[0]; - break; - case GL_UNSIGNED_SHORT: - for (int i = 0; i < count; i++) - { - data[i] = static_cast(indices)[i]; - } - data[count] = static_cast(indices)[0]; - break; - case GL_UNSIGNED_INT: - for (int i = 0; i < count; i++) - { - data[i] = static_cast(indices)[i]; - } - data[count] = static_cast(indices)[0]; - break; - default: UNREACHABLE(); - } + // Copy over the converted index data. + memcpy(mappedMemory, &mScratchIndexDataBuffer[0], + sizeof(GLuint) * mScratchIndexDataBuffer.size()); error = mLineLoopIB->unmapBuffer(); if (error.isError()) @@ -1711,21 +1983,42 @@ gl::Error Renderer11::drawLineLoop(GLsizei count, GLenum type, const GLvoid *ind ID3D11Buffer *d3dIndexBuffer = indexBuffer->getBuffer(); DXGI_FORMAT indexFormat = indexBuffer->getIndexFormat(); - if (mAppliedIB != d3dIndexBuffer || mAppliedIBFormat != indexFormat || mAppliedIBOffset != indexBufferOffset) + if (mAppliedIB != d3dIndexBuffer || mAppliedIBFormat != indexFormat || + mAppliedIBOffset != offset) { - mDeviceContext->IASetIndexBuffer(d3dIndexBuffer, indexFormat, indexBufferOffset); + mDeviceContext->IASetIndexBuffer(d3dIndexBuffer, indexFormat, offset); mAppliedIB = d3dIndexBuffer; mAppliedIBFormat = indexFormat; - mAppliedIBOffset = indexBufferOffset; + mAppliedIBOffset = offset; } - mDeviceContext->DrawIndexed(count + 1, 0, -minIndex); + INT baseVertexLocation = (indexInfo ? -static_cast(indexInfo->indexRange.start) : 0); + UINT indexCount = static_cast(mScratchIndexDataBuffer.size()); + + if (instances > 0) + { + mDeviceContext->DrawIndexedInstanced(indexCount, instances, 0, baseVertexLocation, 0); + } + else + { + mDeviceContext->DrawIndexed(indexCount, 0, baseVertexLocation); + } return gl::Error(GL_NO_ERROR); } -gl::Error Renderer11::drawTriangleFan(GLsizei count, GLenum type, const GLvoid *indices, int minIndex, gl::Buffer *elementArrayBuffer, int instances) +gl::Error Renderer11::drawTriangleFan(const gl::Data &data, + GLsizei count, + GLenum type, + const GLvoid *indices, + int minIndex, + int instances) { + gl::VertexArray *vao = data.state->getVertexArray(); + gl::Buffer *elementArrayBuffer = vao->getElementArrayBuffer().get(); + + const GLvoid *indexPointer = indices; + // Get the raw indices for an indexed draw if (type != GL_NONE && elementArrayBuffer) { @@ -1739,7 +2032,7 @@ gl::Error Renderer11::drawTriangleFan(GLsizei count, GLenum type, const GLvoid * return error; } - indices = bufferData + offset; + indexPointer = bufferData + offset; } if (!mTriangleFanIB) @@ -1756,21 +2049,25 @@ gl::Error Renderer11::drawTriangleFan(GLsizei count, GLenum type, const GLvoid * // Checked by Renderer11::applyPrimitiveType ASSERT(count >= 3); - const unsigned int numTris = count - 2; + const GLuint numTris = count - 2; if (numTris > (std::numeric_limits::max() / (sizeof(unsigned int) * 3))) { return gl::Error(GL_OUT_OF_MEMORY, "Failed to create a scratch index buffer for GL_TRIANGLE_FAN, too many indices required."); } - const unsigned int spaceNeeded = (numTris * 3) * sizeof(unsigned int); + GetTriFanIndices(indexPointer, type, count, data.state->isPrimitiveRestartEnabled(), + &mScratchIndexDataBuffer); + + const unsigned int spaceNeeded = + static_cast(mScratchIndexDataBuffer.size() * sizeof(unsigned int)); gl::Error error = mTriangleFanIB->reserveBufferSpace(spaceNeeded, GL_UNSIGNED_INT); if (error.isError()) { return error; } - void* mappedMemory = NULL; + void *mappedMemory = nullptr; unsigned int offset; error = mTriangleFanIB->mapBuffer(spaceNeeded, &mappedMemory, &offset); if (error.isError()) @@ -1778,45 +2075,7 @@ gl::Error Renderer11::drawTriangleFan(GLsizei count, GLenum type, const GLvoid * return error; } - unsigned int *data = reinterpret_cast(mappedMemory); - unsigned int indexBufferOffset = offset; - - switch (type) - { - case GL_NONE: // Non-indexed draw - for (unsigned int i = 0; i < numTris; i++) - { - data[i*3 + 0] = 0; - data[i*3 + 1] = i + 1; - data[i*3 + 2] = i + 2; - } - break; - case GL_UNSIGNED_BYTE: - for (unsigned int i = 0; i < numTris; i++) - { - data[i*3 + 0] = static_cast(indices)[0]; - data[i*3 + 1] = static_cast(indices)[i + 1]; - data[i*3 + 2] = static_cast(indices)[i + 2]; - } - break; - case GL_UNSIGNED_SHORT: - for (unsigned int i = 0; i < numTris; i++) - { - data[i*3 + 0] = static_cast(indices)[0]; - data[i*3 + 1] = static_cast(indices)[i + 1]; - data[i*3 + 2] = static_cast(indices)[i + 2]; - } - break; - case GL_UNSIGNED_INT: - for (unsigned int i = 0; i < numTris; i++) - { - data[i*3 + 0] = static_cast(indices)[0]; - data[i*3 + 1] = static_cast(indices)[i + 1]; - data[i*3 + 2] = static_cast(indices)[i + 2]; - } - break; - default: UNREACHABLE(); - } + memcpy(mappedMemory, &mScratchIndexDataBuffer[0], spaceNeeded); error = mTriangleFanIB->unmapBuffer(); if (error.isError()) @@ -1828,30 +2087,33 @@ gl::Error Renderer11::drawTriangleFan(GLsizei count, GLenum type, const GLvoid * ID3D11Buffer *d3dIndexBuffer = indexBuffer->getBuffer(); DXGI_FORMAT indexFormat = indexBuffer->getIndexFormat(); - if (mAppliedIB != d3dIndexBuffer || mAppliedIBFormat != indexFormat || mAppliedIBOffset != indexBufferOffset) + if (mAppliedIB != d3dIndexBuffer || mAppliedIBFormat != indexFormat || + mAppliedIBOffset != offset) { - mDeviceContext->IASetIndexBuffer(d3dIndexBuffer, indexFormat, indexBufferOffset); + mDeviceContext->IASetIndexBuffer(d3dIndexBuffer, indexFormat, offset); mAppliedIB = d3dIndexBuffer; mAppliedIBFormat = indexFormat; - mAppliedIBOffset = indexBufferOffset; + mAppliedIBOffset = offset; } + UINT indexCount = static_cast(mScratchIndexDataBuffer.size()); + if (instances > 0) { - mDeviceContext->DrawIndexedInstanced(numTris * 3, instances, 0, -minIndex, 0); + mDeviceContext->DrawIndexedInstanced(indexCount, instances, 0, -minIndex, 0); } else { - mDeviceContext->DrawIndexed(numTris * 3, 0, -minIndex); + mDeviceContext->DrawIndexed(indexCount, 0, -minIndex); } return gl::Error(GL_NO_ERROR); } -gl::Error Renderer11::applyShaders(gl::Program *program, const gl::VertexFormat inputLayout[], const gl::Framebuffer *framebuffer, - bool rasterizerDiscard, bool transformFeedbackActive) +gl::Error Renderer11::applyShadersImpl(const gl::Data &data, GLenum drawMode) { - ProgramD3D *programD3D = GetImplAs(program); + ProgramD3D *programD3D = GetImplAs(data.state->getProgram()); + const auto &inputLayout = programD3D->getCachedInputLayout(); ShaderExecutableD3D *vertexExe = NULL; gl::Error error = programD3D->getVertexExecutableForInputLayout(inputLayout, &vertexExe, nullptr); @@ -1860,30 +2122,39 @@ gl::Error Renderer11::applyShaders(gl::Program *program, const gl::VertexFormat return error; } + const gl::Framebuffer *drawFramebuffer = data.state->getDrawFramebuffer(); ShaderExecutableD3D *pixelExe = NULL; - error = programD3D->getPixelExecutableForFramebuffer(framebuffer, &pixelExe); + error = programD3D->getPixelExecutableForFramebuffer(drawFramebuffer, &pixelExe); if (error.isError()) { return error; } - ShaderExecutableD3D *geometryExe = programD3D->getGeometryExecutable(); + ShaderExecutableD3D *geometryExe = nullptr; + error = + programD3D->getGeometryExecutableForPrimitiveType(data, drawMode, &geometryExe, nullptr); + if (error.isError()) + { + return error; + } ID3D11VertexShader *vertexShader = (vertexExe ? GetAs(vertexExe)->getVertexShader() : NULL); ID3D11PixelShader *pixelShader = NULL; // Skip pixel shader if we're doing rasterizer discard. + bool rasterizerDiscard = data.state->getRasterizerState().rasterizerDiscard; if (!rasterizerDiscard) { pixelShader = (pixelExe ? GetAs(pixelExe)->getPixelShader() : NULL); } ID3D11GeometryShader *geometryShader = NULL; + bool transformFeedbackActive = data.state->isTransformFeedbackActiveUnpaused(); if (transformFeedbackActive) { geometryShader = (vertexExe ? GetAs(vertexExe)->getStreamOutShader() : NULL); } - else if (mCurRasterState.pointDrawMode) + else { geometryShader = (geometryExe ? GetAs(geometryExe)->getGeometryShader() : NULL); } @@ -1919,7 +2190,9 @@ gl::Error Renderer11::applyShaders(gl::Program *program, const gl::VertexFormat return gl::Error(GL_NO_ERROR); } -gl::Error Renderer11::applyUniforms(const ProgramImpl &program, const std::vector &uniformArray) +gl::Error Renderer11::applyUniforms(const ProgramD3D &programD3D, + GLenum drawMode, + const std::vector &uniformArray) { unsigned int totalRegisterCountVS = 0; unsigned int totalRegisterCountPS = 0; @@ -1927,26 +2200,25 @@ gl::Error Renderer11::applyUniforms(const ProgramImpl &program, const std::vecto bool vertexUniformsDirty = false; bool pixelUniformsDirty = false; - for (size_t uniformIndex = 0; uniformIndex < uniformArray.size(); uniformIndex++) + for (const D3DUniform *uniform : uniformArray) { - const gl::LinkedUniform &uniform = *uniformArray[uniformIndex]; - - if (uniform.isReferencedByVertexShader() && !uniform.isSampler()) + if (uniform->isReferencedByVertexShader() && !uniform->isSampler()) { - totalRegisterCountVS += uniform.registerCount; - vertexUniformsDirty = (vertexUniformsDirty || uniform.dirty); + totalRegisterCountVS += uniform->registerCount; + vertexUniformsDirty = (vertexUniformsDirty || uniform->dirty); } - if (uniform.isReferencedByFragmentShader() && !uniform.isSampler()) + if (uniform->isReferencedByFragmentShader() && !uniform->isSampler()) { - totalRegisterCountPS += uniform.registerCount; - pixelUniformsDirty = (pixelUniformsDirty || uniform.dirty); + totalRegisterCountPS += uniform->registerCount; + pixelUniformsDirty = (pixelUniformsDirty || uniform->dirty); } } - const ProgramD3D *programD3D = GetAs(&program); - const UniformStorage11 *vertexUniformStorage = GetAs(&programD3D->getVertexUniformStorage()); - const UniformStorage11 *fragmentUniformStorage = GetAs(&programD3D->getFragmentUniformStorage()); + const UniformStorage11 *vertexUniformStorage = + GetAs(&programD3D.getVertexUniformStorage()); + const UniformStorage11 *fragmentUniformStorage = + GetAs(&programD3D.getFragmentUniformStorage()); ASSERT(vertexUniformStorage); ASSERT(fragmentUniformStorage); @@ -1974,26 +2246,26 @@ gl::Error Renderer11::applyUniforms(const ProgramImpl &program, const std::vecto mapPS = (float(*)[4])map.pData; } - for (size_t uniformIndex = 0; uniformIndex < uniformArray.size(); uniformIndex++) + for (const D3DUniform *uniform : uniformArray) { - gl::LinkedUniform *uniform = uniformArray[uniformIndex]; + if (uniform->isSampler()) + continue; - if (!uniform->isSampler()) - { - unsigned int componentCount = (4 - uniform->registerElement); + unsigned int componentCount = (4 - uniform->registerElement); - // we assume that uniforms from structs are arranged in struct order in our uniforms list. otherwise we would - // overwrite previously written regions of memory. + // we assume that uniforms from structs are arranged in struct order in our uniforms list. + // otherwise we would overwrite previously written regions of memory. - if (uniform->isReferencedByVertexShader() && mapVS) - { - memcpy(&mapVS[uniform->vsRegisterIndex][uniform->registerElement], uniform->data, uniform->registerCount * sizeof(float) * componentCount); - } + if (uniform->isReferencedByVertexShader() && mapVS) + { + memcpy(&mapVS[uniform->vsRegisterIndex][uniform->registerElement], uniform->data, + uniform->registerCount * sizeof(float) * componentCount); + } - if (uniform->isReferencedByFragmentShader() && mapPS) - { - memcpy(&mapPS[uniform->psRegisterIndex][uniform->registerElement], uniform->data, uniform->registerCount * sizeof(float) * componentCount); - } + if (uniform->isReferencedByFragmentShader() && mapPS) + { + memcpy(&mapPS[uniform->psRegisterIndex][uniform->registerElement], uniform->data, + uniform->registerCount * sizeof(float) * componentCount); } } @@ -2009,69 +2281,71 @@ gl::Error Renderer11::applyUniforms(const ProgramImpl &program, const std::vecto if (mCurrentVertexConstantBuffer != vertexConstantBuffer) { - mDeviceContext->VSSetConstantBuffers(0, 1, &vertexConstantBuffer); + mDeviceContext->VSSetConstantBuffers( + d3d11::RESERVED_CONSTANT_BUFFER_SLOT_DEFAULT_UNIFORM_BLOCK, 1, &vertexConstantBuffer); mCurrentVertexConstantBuffer = vertexConstantBuffer; } if (mCurrentPixelConstantBuffer != pixelConstantBuffer) { - mDeviceContext->PSSetConstantBuffers(0, 1, &pixelConstantBuffer); + mDeviceContext->PSSetConstantBuffers( + d3d11::RESERVED_CONSTANT_BUFFER_SLOT_DEFAULT_UNIFORM_BLOCK, 1, &pixelConstantBuffer); mCurrentPixelConstantBuffer = pixelConstantBuffer; } - // Driver uniforms if (!mDriverConstantBufferVS) { D3D11_BUFFER_DESC constantBufferDescription = {0}; - constantBufferDescription.ByteWidth = sizeof(dx_VertexConstants); - constantBufferDescription.Usage = D3D11_USAGE_DEFAULT; - constantBufferDescription.BindFlags = D3D11_BIND_CONSTANT_BUFFER; - constantBufferDescription.CPUAccessFlags = 0; - constantBufferDescription.MiscFlags = 0; - constantBufferDescription.StructureByteStride = 0; - - HRESULT result = mDevice->CreateBuffer(&constantBufferDescription, NULL, &mDriverConstantBufferVS); - UNUSED_ASSERTION_VARIABLE(result); + d3d11::InitConstantBufferDesc( + &constantBufferDescription, + sizeof(dx_VertexConstants11) + mSamplerMetadataVS.sizeBytes()); + HRESULT result = + mDevice->CreateBuffer(&constantBufferDescription, nullptr, &mDriverConstantBufferVS); ASSERT(SUCCEEDED(result)); - - mDeviceContext->VSSetConstantBuffers(1, 1, &mDriverConstantBufferVS); + if (FAILED(result)) + { + return gl::Error(GL_OUT_OF_MEMORY, "Failed to create vertex shader constant buffer, result: 0x%X.", result); + } + mDeviceContext->VSSetConstantBuffers(d3d11::RESERVED_CONSTANT_BUFFER_SLOT_DRIVER, 1, + &mDriverConstantBufferVS); } - if (!mDriverConstantBufferPS) { D3D11_BUFFER_DESC constantBufferDescription = {0}; - constantBufferDescription.ByteWidth = sizeof(dx_PixelConstants); - constantBufferDescription.Usage = D3D11_USAGE_DEFAULT; - constantBufferDescription.BindFlags = D3D11_BIND_CONSTANT_BUFFER; - constantBufferDescription.CPUAccessFlags = 0; - constantBufferDescription.MiscFlags = 0; - constantBufferDescription.StructureByteStride = 0; - - HRESULT result = mDevice->CreateBuffer(&constantBufferDescription, NULL, &mDriverConstantBufferPS); - UNUSED_ASSERTION_VARIABLE(result); + d3d11::InitConstantBufferDesc(&constantBufferDescription, + sizeof(dx_PixelConstants11) + mSamplerMetadataPS.sizeBytes()); + HRESULT result = + mDevice->CreateBuffer(&constantBufferDescription, nullptr, &mDriverConstantBufferPS); ASSERT(SUCCEEDED(result)); - - mDeviceContext->PSSetConstantBuffers(1, 1, &mDriverConstantBufferPS); + if (FAILED(result)) + { + return gl::Error(GL_OUT_OF_MEMORY, "Failed to create pixel shader constant buffer, result: 0x%X.", result); + } + mDeviceContext->PSSetConstantBuffers(d3d11::RESERVED_CONSTANT_BUFFER_SLOT_DRIVER, 1, + &mDriverConstantBufferPS); } - if (memcmp(&mVertexConstants, &mAppliedVertexConstants, sizeof(dx_VertexConstants)) != 0) - { - mDeviceContext->UpdateSubresource(mDriverConstantBufferVS, 0, NULL, &mVertexConstants, 16, 0); - memcpy(&mAppliedVertexConstants, &mVertexConstants, sizeof(dx_VertexConstants)); - } + // 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. + const dx_VertexConstants11 &vertexConstants = mStateManager.getVertexConstants(); + size_t samplerMetadataReferencedBytesVS = sizeof(SamplerMetadataD3D11::dx_SamplerMetadata) * + programD3D.getUsedSamplerRange(gl::SAMPLER_VERTEX); + applyDriverConstantsIfNeeded(&mAppliedVertexConstants, vertexConstants, &mSamplerMetadataVS, + samplerMetadataReferencedBytesVS, mDriverConstantBufferVS); - if (memcmp(&mPixelConstants, &mAppliedPixelConstants, sizeof(dx_PixelConstants)) != 0) - { - mDeviceContext->UpdateSubresource(mDriverConstantBufferPS, 0, NULL, &mPixelConstants, 16, 0); - memcpy(&mAppliedPixelConstants, &mPixelConstants, sizeof(dx_PixelConstants)); - } + const dx_PixelConstants11 &pixelConstants = mStateManager.getPixelConstants(); + size_t samplerMetadataReferencedBytesPS = sizeof(SamplerMetadataD3D11::dx_SamplerMetadata) * + programD3D.getUsedSamplerRange(gl::SAMPLER_PIXEL); + applyDriverConstantsIfNeeded(&mAppliedPixelConstants, pixelConstants, &mSamplerMetadataPS, + samplerMetadataReferencedBytesPS, mDriverConstantBufferPS); // GSSetConstantBuffers triggers device removal on 9_3, so we should only call it if necessary - if (programD3D->usesGeometryShader()) + if (programD3D.usesGeometryShader(drawMode)) { // needed for the point sprite geometry shader if (mCurrentGeometryConstantBuffer != mDriverConstantBufferPS) { + ASSERT(mDriverConstantBufferPS != nullptr); mDeviceContext->GSSetConstantBuffers(0, 1, &mDriverConstantBufferPS); mCurrentGeometryConstantBuffer = mDriverConstantBufferPS; } @@ -2080,49 +2354,175 @@ gl::Error Renderer11::applyUniforms(const ProgramImpl &program, const std::vecto return gl::Error(GL_NO_ERROR); } -void Renderer11::markAllStateDirty() +// SamplerMetadataD3D11 implementation + +Renderer11::SamplerMetadataD3D11::SamplerMetadataD3D11() : mDirty(true) { - TRACE_EVENT0("gpu.angle", "Renderer11::markAllStateDirty"); +} + +Renderer11::SamplerMetadataD3D11::~SamplerMetadataD3D11() +{ +} + +void Renderer11::SamplerMetadataD3D11::initData(unsigned int samplerCount) +{ + mSamplerMetadata.resize(samplerCount); +} + +void Renderer11::SamplerMetadataD3D11::update(unsigned int samplerIndex, const gl::Texture &texture) +{ + unsigned int baseLevel = texture.getBaseLevel(); + GLenum internalFormat = texture.getInternalFormat(texture.getTarget(), texture.getBaseLevel()); + if (mSamplerMetadata[samplerIndex].baseLevel != static_cast(baseLevel)) + { + mSamplerMetadata[samplerIndex].baseLevel = static_cast(baseLevel); + mDirty = 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 (internalFormat) + { + 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 (mSamplerMetadata[samplerIndex].internalFormatBits != internalFormatBits) + { + mSamplerMetadata[samplerIndex].internalFormatBits = internalFormatBits; + mDirty = true; + } + // Pack the wrap values into one integer so we can fit all the metadata in one 4-integer + // vector. + GLenum wrapS = texture.getWrapS(); + GLenum wrapT = texture.getWrapT(); + GLenum wrapR = texture.getWrapR(); + int wrapModes = GetWrapBits(wrapS) | (GetWrapBits(wrapT) << 2) | (GetWrapBits(wrapR) << 4); + if (mSamplerMetadata[samplerIndex].wrapModes != wrapModes) + { + mSamplerMetadata[samplerIndex].wrapModes = wrapModes; + mDirty = true; + } + } +} + +const Renderer11::SamplerMetadataD3D11::dx_SamplerMetadata * +Renderer11::SamplerMetadataD3D11::getData() const +{ + return mSamplerMetadata.data(); +} - for (size_t rtIndex = 0; rtIndex < ArraySize(mAppliedRTVs); rtIndex++) +size_t Renderer11::SamplerMetadataD3D11::sizeBytes() const +{ + return sizeof(SamplerMetadataD3D11::dx_SamplerMetadata) * mSamplerMetadata.size(); +} + +template +void Renderer11::applyDriverConstantsIfNeeded(TShaderConstants *appliedConstants, + const TShaderConstants &constants, + SamplerMetadataD3D11 *samplerMetadata, + size_t samplerMetadataReferencedBytes, + ID3D11Buffer *driverConstantBuffer) +{ + ASSERT(driverConstantBuffer != nullptr); + if (memcmp(appliedConstants, &constants, sizeof(TShaderConstants)) != 0 || + samplerMetadata->isDirty()) { - mAppliedRTVs[rtIndex] = DirtyPointer; + memcpy(appliedConstants, &constants, sizeof(TShaderConstants)); + + D3D11_MAPPED_SUBRESOURCE mapping = {0}; + HRESULT result = + mDeviceContext->Map(driverConstantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapping); + ASSERT(SUCCEEDED(result)); + UNUSED_ASSERTION_VARIABLE(result); + memcpy(mapping.pData, appliedConstants, sizeof(TShaderConstants)); + // Previous buffer contents were discarded, so we need to refresh also the area of the + // buffer that isn't used by this program. + memcpy(&reinterpret_cast(mapping.pData)[sizeof(TShaderConstants)], + samplerMetadata->getData(), samplerMetadata->sizeBytes()); + mDeviceContext->Unmap(driverConstantBuffer, 0); + + samplerMetadata->markClean(); } - mAppliedDSV = DirtyPointer; - mDepthStencilInitialized = false; - mRenderTargetDescInitialized = false; +} + +template void Renderer11::applyDriverConstantsIfNeeded( + dx_VertexConstants11 *appliedConstants, + const dx_VertexConstants11 &constants, + SamplerMetadataD3D11 *samplerMetadata, + size_t samplerMetadataReferencedBytes, + ID3D11Buffer *driverConstantBuffer); +template void Renderer11::applyDriverConstantsIfNeeded( + dx_PixelConstants11 *appliedConstants, + const dx_PixelConstants11 &constants, + SamplerMetadataD3D11 *samplerMetadata, + size_t samplerMetadataReferencedBytes, + ID3D11Buffer *driverConstantBuffer); - // We reset the current SRV data because it might not be in sync with D3D's state - // anymore. For example when a currently used SRV is used as an RTV, D3D silently - // remove it from its state. - memset(mCurVertexSRVs.data(), 0, sizeof(SRVRecord) * mCurVertexSRVs.size()); - memset(mCurPixelSRVs.data(), 0, sizeof(SRVRecord) * mCurPixelSRVs.size()); +void Renderer11::markAllStateDirty() +{ + TRACE_EVENT0("gpu.angle", "Renderer11::markAllStateDirty"); - ASSERT(mForceSetVertexSamplerStates.size() == mCurVertexSRVs.size()); for (size_t vsamplerId = 0; vsamplerId < mForceSetVertexSamplerStates.size(); ++vsamplerId) { mForceSetVertexSamplerStates[vsamplerId] = true; } - ASSERT(mForceSetPixelSamplerStates.size() == mCurPixelSRVs.size()); for (size_t fsamplerId = 0; fsamplerId < mForceSetPixelSamplerStates.size(); ++fsamplerId) { mForceSetPixelSamplerStates[fsamplerId] = true; } - mForceSetBlendState = true; - mForceSetRasterState = true; - mForceSetDepthStencilState = true; - mForceSetScissor = true; - mForceSetViewport = true; + mStateManager.invalidateEverything(); mAppliedIB = NULL; mAppliedIBFormat = DXGI_FORMAT_UNKNOWN; mAppliedIBOffset = 0; - mAppliedVertexShader = DirtyPointer; - mAppliedGeometryShader = DirtyPointer; - mAppliedPixelShader = DirtyPointer; + mAppliedVertexShader = angle::DirtyPointer; + mAppliedGeometryShader = angle::DirtyPointer; + mAppliedPixelShader = angle::DirtyPointer; mAppliedNumXFBBindings = static_cast(-1); @@ -2132,8 +2532,8 @@ void Renderer11::markAllStateDirty() mAppliedTFOffsets[i] = 0; } - memset(&mAppliedVertexConstants, 0, sizeof(dx_VertexConstants)); - memset(&mAppliedPixelConstants, 0, sizeof(dx_PixelConstants)); + memset(&mAppliedVertexConstants, 0, sizeof(dx_VertexConstants11)); + memset(&mAppliedPixelConstants, 0, sizeof(dx_PixelConstants11)); mInputLayoutCache.markDirty(); @@ -2156,6 +2556,7 @@ void Renderer11::markAllStateDirty() void Renderer11::releaseDeviceResources() { + mStateManager.deinitialize(); mStateCache.clear(); mInputLayoutCache.clear(); @@ -2215,20 +2616,16 @@ bool Renderer11::testDeviceResettable() D3D_FEATURE_LEVEL dummyFeatureLevel; ID3D11DeviceContext* dummyContext; - HRESULT result = D3D11CreateDevice(NULL, - mDriverType, - NULL, + ASSERT(mRequestedDriverType != D3D_DRIVER_TYPE_UNKNOWN); + HRESULT result = D3D11CreateDevice( + NULL, mRequestedDriverType, NULL, #if defined(_DEBUG) - D3D11_CREATE_DEVICE_DEBUG, + D3D11_CREATE_DEVICE_DEBUG, #else - 0, + 0, #endif - mAvailableFeatureLevels.data(), - mAvailableFeatureLevels.size(), - D3D11_SDK_VERSION, - &dummyDevice, - &dummyFeatureLevel, - &dummyContext); + mAvailableFeatureLevels.data(), static_cast(mAvailableFeatureLevels.size()), + D3D11_SDK_VERSION, &dummyDevice, &dummyFeatureLevel, &dummyContext); if (!mDevice || FAILED(result)) { @@ -2247,6 +2644,13 @@ void Renderer11::release() releaseDeviceResources(); + if (!mCreatedWithDeviceEXT) + { + // Only delete the device if the Renderer11 owns it + // Otherwise we should keep it around in case we try to reinitialize the renderer later + SafeDelete(mEGLDevice); + } + SafeRelease(mDxgiFactory); SafeRelease(mDxgiAdapter); @@ -2274,7 +2678,15 @@ void Renderer11::release() mDxgiModule = NULL; } + if (mDCompModule) + { + FreeLibrary(mDCompModule); + mDCompModule = NULL; + } + mCompiler.release(); + + mSupportsShareHandles.reset(); } bool Renderer11::resetDevice() @@ -2294,11 +2706,6 @@ bool Renderer11::resetDevice() return true; } -VendorID Renderer11::getVendorId() const -{ - return static_cast(mAdapterDescription.VendorId); -} - std::string Renderer11::getRendererDescription() const { std::ostringstream rendererString; @@ -2312,24 +2719,29 @@ std::string Renderer11::getRendererDescription() const return rendererString.str(); } -GUID Renderer11::getAdapterIdentifier() const +DeviceIdentifier Renderer11::getAdapterIdentifier() const { - // Use the adapter LUID as our adapter ID - // This number is local to a machine is only guaranteed to be unique between restarts - static_assert(sizeof(LUID) <= sizeof(GUID), "Size of GUID must be at least as large as LUID."); - GUID adapterId = {0}; - memcpy(&adapterId, &mAdapterDescription.AdapterLuid, sizeof(LUID)); - return adapterId; + // Don't use the AdapterLuid here, since that doesn't persist across reboot. + DeviceIdentifier deviceIdentifier = { 0 }; + 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 { - return 0; // Driver uniforms are stored in a separate constant buffer + // Driver uniforms are stored in a separate constant buffer + return d3d11_gl::GetReservedVertexUniformVectors(mRenderer11DeviceCaps.featureLevel); } unsigned int Renderer11::getReservedFragmentUniformVectors() const { - return 0; // Driver uniforms are stored in a separate constant buffer + // Driver uniforms are stored in a separate constant buffer + return d3d11_gl::GetReservedFragmentUniformVectors(mRenderer11DeviceCaps.featureLevel); } unsigned int Renderer11::getReservedVertexUniformBuffers() const @@ -2344,45 +2756,100 @@ unsigned int Renderer11::getReservedFragmentUniformBuffers() const return 2; } +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 (!getRendererExtensions().textureFormatBGRA8888) { + mSupportsShareHandles = false; return false; } // PIX doesn't seem to support using share handles, so disable them. if (gl::DebugAnnotationsActive()) { + 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 (mFeatureLevel <= D3D_FEATURE_LEVEL_9_3) + if (mRenderer11DeviceCaps.featureLevel <= D3D_FEATURE_LEVEL_9_3) { + mSupportsShareHandles = false; return false; } - // Also disable on non-hardware drivers, since sharing doesn't work cross-driver. - if (mDriverType != D3D_DRIVER_TYPE_HARDWARE) + // 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; } - return true; -} + if (deviceType == d3d11::ANGLE_D3D11_DEVICE_TYPE_SOFTWARE_REF_OR_NULL) + { + // Software/Reference/NULL devices don't support share handles + mSupportsShareHandles = false; + return false; + } -bool Renderer11::getPostSubBufferSupport() const -{ - // D3D11 does not support present with dirty rectangles until D3D11.1 and DXGI 1.2. - return false; + if (deviceType == d3d11::ANGLE_D3D11_DEVICE_TYPE_WARP) + { +#ifndef ANGLE_ENABLE_WINDOWS_STORE + if (!IsWindows8OrGreater()) + { + // WARP on Windows 7 doesn't support shared handles + mSupportsShareHandles = false; + return false; + } +#endif // ANGLE_ENABLE_WINDOWS_STORE + + // 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 (mFeatureLevel) + switch (mRenderer11DeviceCaps.featureLevel) { 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 @@ -2394,7 +2861,7 @@ int Renderer11::getMajorShaderModel() const int Renderer11::getMinorShaderModel() const { - switch (mFeatureLevel) + switch (mRenderer11DeviceCaps.featureLevel) { 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 @@ -2406,7 +2873,7 @@ int Renderer11::getMinorShaderModel() const std::string Renderer11::getShaderModelSuffix() const { - switch (mFeatureLevel) + switch (mRenderer11DeviceCaps.featureLevel) { case D3D_FEATURE_LEVEL_11_0: return ""; case D3D_FEATURE_LEVEL_10_1: return ""; @@ -2416,6 +2883,17 @@ std::string Renderer11::getShaderModelSuffix() const } } +const WorkaroundsD3D &RendererD3D::getWorkarounds() const +{ + if (!mWorkaroundsInitialized) + { + mWorkarounds = generateWorkarounds(); + mWorkaroundsInitialized = true; + } + + return mWorkarounds; +} + gl::Error Renderer11::copyImage2D(const gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, const gl::Offset &destOffset, TextureStorage *storage, GLint level) { @@ -2430,7 +2908,7 @@ gl::Error Renderer11::copyImage2D(const gl::Framebuffer *framebuffer, const gl:: } ASSERT(sourceRenderTarget); - ID3D11ShaderResourceView *source = sourceRenderTarget->getShaderResourceView(); + ID3D11ShaderResourceView *source = sourceRenderTarget->getBlitShaderResourceView(); ASSERT(source); TextureStorage11_2D *storage11 = GetAs(storage); @@ -2451,12 +2929,20 @@ gl::Error Renderer11::copyImage2D(const gl::Framebuffer *framebuffer, const gl:: 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, colorbuffer); + 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 - mBlit->copyTexture(source, sourceArea, sourceSize, dest, destArea, destSize, NULL, destFormat, GL_NEAREST); + error = mBlit->copyTexture(source, sourceArea, sourceSize, dest, destArea, destSize, NULL, + destFormat, GL_NEAREST, false); if (error.isError()) { return error; @@ -2481,7 +2967,7 @@ gl::Error Renderer11::copyImageCube(const gl::Framebuffer *framebuffer, const gl } ASSERT(sourceRenderTarget); - ID3D11ShaderResourceView *source = sourceRenderTarget->getShaderResourceView(); + ID3D11ShaderResourceView *source = sourceRenderTarget->getBlitShaderResourceView(); ASSERT(source); TextureStorage11_Cube *storage11 = GetAs(storage); @@ -2502,12 +2988,20 @@ gl::Error Renderer11::copyImageCube(const gl::Framebuffer *framebuffer, const gl 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, colorbuffer); + 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 - error = mBlit->copyTexture(source, sourceArea, sourceSize, dest, destArea, destSize, NULL, destFormat, GL_NEAREST); + error = mBlit->copyTexture(source, sourceArea, sourceSize, dest, destArea, destSize, NULL, + destFormat, GL_NEAREST, false); if (error.isError()) { return error; @@ -2532,7 +3026,7 @@ gl::Error Renderer11::copyImage3D(const gl::Framebuffer *framebuffer, const gl:: } ASSERT(sourceRenderTarget); - ID3D11ShaderResourceView *source = sourceRenderTarget->getShaderResourceView(); + ID3D11ShaderResourceView *source = sourceRenderTarget->getBlitShaderResourceView(); ASSERT(source); TextureStorage11_3D *storage11 = GetAs(storage); @@ -2558,7 +3052,8 @@ gl::Error Renderer11::copyImage3D(const gl::Framebuffer *framebuffer, const gl:: // Use nearest filtering because source and destination are the same size for the direct // copy - error = mBlit->copyTexture(source, sourceArea, sourceSize, dest, destArea, destSize, NULL, destFormat, GL_NEAREST); + error = mBlit->copyTexture(source, sourceArea, sourceSize, dest, destArea, destSize, NULL, + destFormat, GL_NEAREST, false); if (error.isError()) { return error; @@ -2583,7 +3078,7 @@ gl::Error Renderer11::copyImage2DArray(const gl::Framebuffer *framebuffer, const } ASSERT(sourceRenderTarget); - ID3D11ShaderResourceView *source = sourceRenderTarget->getShaderResourceView(); + ID3D11ShaderResourceView *source = sourceRenderTarget->getBlitShaderResourceView(); ASSERT(source); TextureStorage11_2DArray *storage11 = GetAs(storage); @@ -2609,7 +3104,8 @@ gl::Error Renderer11::copyImage2DArray(const gl::Framebuffer *framebuffer, const // Use nearest filtering because source and destination are the same size for the direct // copy - error = mBlit->copyTexture(source, sourceArea, sourceSize, dest, destArea, destSize, NULL, destFormat, GL_NEAREST); + error = mBlit->copyTexture(source, sourceArea, sourceSize, dest, destArea, destSize, NULL, + destFormat, GL_NEAREST, false); if (error.isError()) { return error; @@ -2620,31 +3116,9 @@ gl::Error Renderer11::copyImage2DArray(const gl::Framebuffer *framebuffer, const return gl::Error(GL_NO_ERROR); } -void Renderer11::unapplyRenderTargets() -{ - setOneTimeRenderTarget(NULL); -} - -// When finished with this rendertarget, markAllStateDirty must be called. -void Renderer11::setOneTimeRenderTarget(ID3D11RenderTargetView *renderTargetView) -{ - ID3D11RenderTargetView *rtvArray[gl::IMPLEMENTATION_MAX_DRAW_BUFFERS] = {NULL}; - - rtvArray[0] = renderTargetView; - - mDeviceContext->OMSetRenderTargets(getRendererCaps().maxDrawBuffers, rtvArray, NULL); - - // Do not preserve the serial for this one-time-use render target - for (size_t rtIndex = 0; rtIndex < ArraySize(mAppliedRTVs); rtIndex++) - { - mAppliedRTVs[rtIndex] = DirtyPointer; - } - mAppliedDSV = DirtyPointer; -} - gl::Error Renderer11::createRenderTarget(int width, int height, GLenum format, GLsizei samples, RenderTargetD3D **outRT) { - const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(format, mFeatureLevel); + const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(format, mRenderer11DeviceCaps); const gl::TextureCaps &textureCaps = getRendererTextureCaps().get(format); GLuint supportedSamples = textureCaps.getNearestSamples(samples); @@ -2657,7 +3131,7 @@ gl::Error Renderer11::createRenderTarget(int width, int height, GLenum format, G desc.Height = height; desc.MipLevels = 1; desc.ArraySize = 1; - desc.Format = formatInfo.texFormat; + desc.Format = formatInfo.formatSet->texFormat; desc.SampleDesc.Count = (supportedSamples == 0) ? 1 : supportedSamples; desc.SampleDesc.Quality = 0; desc.Usage = D3D11_USAGE_DEFAULT; @@ -2668,14 +3142,15 @@ gl::Error Renderer11::createRenderTarget(int width, int height, GLenum format, G // 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); - if (formatInfo.srvFormat != DXGI_FORMAT_UNKNOWN) + bindRTV = (formatInfo.formatSet->rtvFormat != DXGI_FORMAT_UNKNOWN); + bindDSV = (formatInfo.formatSet->dsvFormat != DXGI_FORMAT_UNKNOWN); + if (formatInfo.formatSet->srvFormat != DXGI_FORMAT_UNKNOWN) { // Multisample targets flagged for binding as depth stencil cannot also be // flagged for binding as SRV, so make certain not to add the SRV flag for // these targets. - bindSRV = !(formatInfo.dsvFormat != DXGI_FORMAT_UNKNOWN && desc.SampleDesc.Count > 1); + bindSRV = !(formatInfo.formatSet->dsvFormat != DXGI_FORMAT_UNKNOWN && + desc.SampleDesc.Count > 1); } desc.BindFlags = (bindRTV ? D3D11_BIND_RENDER_TARGET : 0) | @@ -2693,11 +3168,12 @@ gl::Error Renderer11::createRenderTarget(int width, int height, GLenum format, G return gl::Error(GL_OUT_OF_MEMORY, "Failed to create render target texture, result: 0x%X.", result); } - ID3D11ShaderResourceView *srv = NULL; + ID3D11ShaderResourceView *srv = nullptr; + ID3D11ShaderResourceView *blitSRV = nullptr; if (bindSRV) { D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; - srvDesc.Format = formatInfo.srvFormat; + srvDesc.Format = formatInfo.formatSet->srvFormat; srvDesc.ViewDimension = (supportedSamples == 0) ? D3D11_SRV_DIMENSION_TEXTURE2D : D3D11_SRV_DIMENSION_TEXTURE2DMS; srvDesc.Texture2D.MostDetailedMip = 0; srvDesc.Texture2D.MipLevels = 1; @@ -2709,12 +3185,40 @@ gl::Error Renderer11::createRenderTarget(int width, int height, GLenum format, G SafeRelease(texture); return gl::Error(GL_OUT_OF_MEMORY, "Failed to create render target shader resource view, result: 0x%X.", result); } + + if (formatInfo.formatSet->blitSRVFormat != formatInfo.formatSet->srvFormat) + { + D3D11_SHADER_RESOURCE_VIEW_DESC blitSRVDesc; + blitSRVDesc.Format = formatInfo.formatSet->blitSRVFormat; + blitSRVDesc.ViewDimension = (supportedSamples == 0) + ? D3D11_SRV_DIMENSION_TEXTURE2D + : D3D11_SRV_DIMENSION_TEXTURE2DMS; + blitSRVDesc.Texture2D.MostDetailedMip = 0; + blitSRVDesc.Texture2D.MipLevels = 1; + + result = mDevice->CreateShaderResourceView(texture, &blitSRVDesc, &blitSRV); + if (FAILED(result)) + { + ASSERT(result == E_OUTOFMEMORY); + SafeRelease(texture); + SafeRelease(srv); + return gl::Error(GL_OUT_OF_MEMORY, + "Failed to create render target shader resource view for " + "blits, result: 0x%X.", + result); + } + } + else + { + blitSRV = srv; + srv->AddRef(); + } } if (bindDSV) { D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc; - dsvDesc.Format = formatInfo.dsvFormat; + dsvDesc.Format = formatInfo.formatSet->dsvFormat; dsvDesc.ViewDimension = (supportedSamples == 0) ? D3D11_DSV_DIMENSION_TEXTURE2D : D3D11_DSV_DIMENSION_TEXTURE2DMS; dsvDesc.Texture2D.MipSlice = 0; dsvDesc.Flags = 0; @@ -2726,17 +3230,20 @@ gl::Error Renderer11::createRenderTarget(int width, int height, GLenum format, G ASSERT(result == E_OUTOFMEMORY); SafeRelease(texture); SafeRelease(srv); + SafeRelease(blitSRV); return gl::Error(GL_OUT_OF_MEMORY, "Failed to create render target depth stencil view, result: 0x%X.", result); } - *outRT = new TextureRenderTarget11(dsv, texture, srv, format, width, height, 1, supportedSamples); + *outRT = + new TextureRenderTarget11(dsv, texture, srv, format, formatInfo.formatSet->format, + width, height, 1, supportedSamples); SafeRelease(dsv); } else if (bindRTV) { D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; - rtvDesc.Format = formatInfo.rtvFormat; + rtvDesc.Format = formatInfo.formatSet->rtvFormat; rtvDesc.ViewDimension = (supportedSamples == 0) ? D3D11_RTV_DIMENSION_TEXTURE2D : D3D11_RTV_DIMENSION_TEXTURE2DMS; rtvDesc.Texture2D.MipSlice = 0; @@ -2747,6 +3254,7 @@ gl::Error Renderer11::createRenderTarget(int width, int height, GLenum format, G ASSERT(result == E_OUTOFMEMORY); SafeRelease(texture); SafeRelease(srv); + SafeRelease(blitSRV); return gl::Error(GL_OUT_OF_MEMORY, "Failed to create render target render target view, result: 0x%X.", result); } @@ -2756,7 +3264,9 @@ gl::Error Renderer11::createRenderTarget(int width, int height, GLenum format, G mDeviceContext->ClearRenderTargetView(rtv, clearValues); } - *outRT = new TextureRenderTarget11(rtv, texture, srv, format, width, height, 1, supportedSamples); + *outRT = new TextureRenderTarget11(rtv, texture, srv, blitSRV, format, + formatInfo.formatSet->format, width, height, 1, + supportedSamples); SafeRelease(rtv); } @@ -2767,18 +3277,38 @@ gl::Error Renderer11::createRenderTarget(int width, int height, GLenum format, G SafeRelease(texture); SafeRelease(srv); + SafeRelease(blitSRV); } else { - *outRT = new TextureRenderTarget11(reinterpret_cast(NULL), NULL, NULL, format, width, height, 1, supportedSamples); + *outRT = new TextureRenderTarget11(static_cast(nullptr), nullptr, + nullptr, nullptr, format, d3d11::ANGLE_FORMAT_NONE, + width, height, 1, supportedSamples); } return gl::Error(GL_NO_ERROR); } -FramebufferImpl *Renderer11::createDefaultFramebuffer(const gl::Framebuffer::Data &data) +gl::Error Renderer11::createRenderTargetCopy(RenderTargetD3D *source, RenderTargetD3D **outRT) { - return createFramebuffer(data); + ASSERT(source != nullptr); + + RenderTargetD3D *newRT = nullptr; + gl::Error error = createRenderTarget(source->getWidth(), source->getHeight(), + source->getInternalFormat(), source->getSamples(), &newRT); + if (error.isError()) + { + return error; + } + + RenderTarget11 *source11 = GetAs(source); + RenderTarget11 *dest11 = GetAs(newRT); + + mDeviceContext->CopySubresourceRegion(dest11->getTexture(), dest11->getSubresourceIndex(), 0, 0, + 0, source11->getTexture(), + source11->getSubresourceIndex(), nullptr); + *outRT = newRT; + return gl::Error(GL_NO_ERROR); } FramebufferImpl *Renderer11::createFramebuffer(const gl::Framebuffer::Data &data) @@ -2786,24 +3316,22 @@ FramebufferImpl *Renderer11::createFramebuffer(const gl::Framebuffer::Data &data return new Framebuffer11(data, this); } -CompilerImpl *Renderer11::createCompiler(const gl::Data &data) -{ - return new CompilerD3D(data, SH_HLSL11_OUTPUT); -} - -ShaderImpl *Renderer11::createShader(GLenum type) +ShaderImpl *Renderer11::createShader(const gl::Shader::Data &data) { - return new ShaderD3D(type); + return new ShaderD3D(data); } -ProgramImpl *Renderer11::createProgram() +ProgramImpl *Renderer11::createProgram(const gl::Program::Data &data) { - return new ProgramD3D(this); + return new ProgramD3D(data, this); } -gl::Error Renderer11::loadExecutable(const void *function, size_t length, ShaderType type, - const std::vector &transformFeedbackVaryings, - bool separatedOutputBuffers, ShaderExecutableD3D **outExecutable) +gl::Error Renderer11::loadExecutable(const void *function, + size_t length, + ShaderType type, + const std::vector &streamOutVaryings, + bool separatedOutputBuffers, + ShaderExecutableD3D **outExecutable) { switch (type) { @@ -2819,29 +3347,28 @@ gl::Error Renderer11::loadExecutable(const void *function, size_t length, Shader return gl::Error(GL_OUT_OF_MEMORY, "Failed to create vertex shader, result: 0x%X.", result); } - if (transformFeedbackVaryings.size() > 0) + if (!streamOutVaryings.empty()) { std::vector soDeclaration; - for (size_t i = 0; i < transformFeedbackVaryings.size(); i++) + soDeclaration.reserve(streamOutVaryings.size()); + + for (const auto &streamOutVarying : streamOutVaryings) { - const gl::LinkedVarying &varying = transformFeedbackVaryings[i]; - GLenum transposedType = gl::TransposeMatrixType(varying.type); - - for (size_t j = 0; j < varying.semanticIndexCount; j++) - { - D3D11_SO_DECLARATION_ENTRY entry = { 0 }; - entry.Stream = 0; - entry.SemanticName = varying.semanticName.c_str(); - entry.SemanticIndex = varying.semanticIndex + j; - entry.StartComponent = 0; - entry.ComponentCount = static_cast(gl::VariableColumnCount(transposedType)); - entry.OutputSlot = static_cast((separatedOutputBuffers ? i : 0)); - soDeclaration.push_back(entry); - } + D3D11_SO_DECLARATION_ENTRY entry = {0}; + 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); } - result = mDevice->CreateGeometryShaderWithStreamOutput(function, length, soDeclaration.data(), soDeclaration.size(), - NULL, 0, 0, NULL, &streamOutShader); + result = mDevice->CreateGeometryShaderWithStreamOutput( + function, static_cast(length), soDeclaration.data(), + static_cast(soDeclaration.size()), NULL, 0, 0, NULL, + &streamOutShader); ASSERT(SUCCEEDED(result)); if (FAILED(result)) { @@ -2888,9 +3415,12 @@ gl::Error Renderer11::loadExecutable(const void *function, size_t length, Shader return gl::Error(GL_NO_ERROR); } -gl::Error Renderer11::compileToExecutable(gl::InfoLog &infoLog, const std::string &shaderHLSL, ShaderType type, - const std::vector &transformFeedbackVaryings, - bool separatedOutputBuffers, const D3DCompilerWorkarounds &workarounds, +gl::Error Renderer11::compileToExecutable(gl::InfoLog &infoLog, + const std::string &shaderHLSL, + ShaderType type, + const std::vector &streamOutVaryings, + bool separatedOutputBuffers, + const D3DCompilerWorkarounds &workarounds, ShaderExecutableD3D **outExectuable) { const char *profileType = NULL; @@ -2933,6 +3463,15 @@ gl::Error Renderer11::compileToExecutable(gl::InfoLog &infoLog, const std::strin 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} }; ID3DBlob *binary = NULL; @@ -2952,7 +3491,7 @@ gl::Error Renderer11::compileToExecutable(gl::InfoLog &infoLog, const std::strin } error = loadExecutable(binary->GetBufferPointer(), binary->GetBufferSize(), type, - transformFeedbackVaryings, separatedOutputBuffers, outExectuable); + streamOutVaryings, separatedOutputBuffers, outExectuable); SafeRelease(binary); if (error.isError()) @@ -2985,12 +3524,14 @@ IndexBuffer *Renderer11::createIndexBuffer() BufferImpl *Renderer11::createBuffer() { - return new Buffer11(this); + Buffer11 *buffer = new Buffer11(this); + mAliveBuffers.insert(buffer); + return buffer; } -VertexArrayImpl *Renderer11::createVertexArray() +VertexArrayImpl *Renderer11::createVertexArray(const gl::VertexArray::Data &data) { - return new VertexArray11(this); + return new VertexArray11(data); } QueryImpl *Renderer11::createQuery(GLenum type) @@ -3013,13 +3554,17 @@ TransformFeedbackImpl* Renderer11::createTransformFeedback() return new TransformFeedbackD3D(); } +StreamImpl *Renderer11::createStream(const egl::AttributeMap &attribs) +{ + return new Stream11(this); +} + bool Renderer11::supportsFastCopyBufferToTexture(GLenum internalFormat) const { ASSERT(getRendererExtensions().pixelBufferObject); const gl::InternalFormat &internalFormatInfo = gl::GetInternalFormatInfo(internalFormat); - const d3d11::TextureFormat &d3d11FormatInfo = d3d11::GetTextureFormatInfo(internalFormat, mFeatureLevel); - const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(d3d11FormatInfo.texFormat); + const d3d11::TextureFormat &d3d11FormatInfo = d3d11::GetTextureFormatInfo(internalFormat, mRenderer11DeviceCaps); // sRGB formats do not work with D3D11 buffer SRVs if (internalFormatInfo.colorEncoding == GL_SRGB) @@ -3028,7 +3573,7 @@ bool Renderer11::supportsFastCopyBufferToTexture(GLenum internalFormat) const } // We cannot support direct copies to non-color-renderable formats - if (d3d11FormatInfo.rtvFormat == DXGI_FORMAT_UNKNOWN) + if (d3d11FormatInfo.formatSet->rtvFormat == DXGI_FORMAT_UNKNOWN) { return false; } @@ -3040,7 +3585,7 @@ bool Renderer11::supportsFastCopyBufferToTexture(GLenum internalFormat) const } // We don't support formats which we can't represent without conversion - if (dxgiFormatInfo.internalFormat != internalFormat) + if (d3d11FormatInfo.formatSet->glInternalFormat != internalFormat) { return false; } @@ -3064,10 +3609,11 @@ gl::Error Renderer11::generateMipmap(ImageD3D *dest, ImageD3D *src) { Image11 *dest11 = GetAs(dest); Image11 *src11 = GetAs(src); - return Image11::generateMipmap(dest11, src11); + return Image11::generateMipmap(dest11, src11, mRenderer11DeviceCaps); } -gl::Error Renderer11::generateMipmapsUsingD3D(TextureStorage *storage, const gl::SamplerState &samplerState) +gl::Error Renderer11::generateMipmapsUsingD3D(TextureStorage *storage, + const gl::TextureState &textureState) { TextureStorage11 *storage11 = GetAs(storage); @@ -3075,7 +3621,7 @@ gl::Error Renderer11::generateMipmapsUsingD3D(TextureStorage *storage, const gl: ASSERT(storage11->supportsNativeMipmapFunction()); ID3D11ShaderResourceView *srv; - gl::Error error = storage11->getSRVLevels(samplerState.baseLevel, samplerState.maxLevel, &srv); + gl::Error error = storage11->getSRVLevels(textureState.baseLevel, textureState.maxLevel, &srv); if (error.isError()) { return error; @@ -3092,6 +3638,11 @@ TextureStorage *Renderer11::createTextureStorage2D(SwapChainD3D *swapChain) return new TextureStorage11_2D(this, swapChain11); } +TextureStorage *Renderer11::createTextureStorageEGLImage(EGLImageD3D *eglImage) +{ + return new TextureStorage11_EGLImage(this, eglImage); +} + TextureStorage *Renderer11::createTextureStorage2D(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, int levels, bool hintLevelZeroOnly) { return new TextureStorage11_2D(this, internalformat, renderTarget, width, height, levels, hintLevelZeroOnly); @@ -3133,28 +3684,54 @@ RenderbufferImpl *Renderer11::createRenderbuffer() return renderbuffer; } -gl::Error Renderer11::readTextureData(ID3D11Texture2D *texture, unsigned int subResource, const gl::Rectangle &area, GLenum format, - GLenum type, GLuint outputPitch, const gl::PixelPackState &pack, uint8_t *pixels) +gl::Error Renderer11::readFromAttachment(const gl::FramebufferAttachment &srcAttachment, + const gl::Rectangle &sourceArea, + GLenum format, + GLenum type, + GLuint outputPitch, + const gl::PixelPackState &pack, + uint8_t *pixelsOut) { - ASSERT(area.width >= 0); - ASSERT(area.height >= 0); + ASSERT(sourceArea.width >= 0); + ASSERT(sourceArea.height >= 0); - D3D11_TEXTURE2D_DESC textureDesc; - texture->GetDesc(&textureDesc); + const bool invertTexture = UsePresentPathFast(this, &srcAttachment); + + RenderTargetD3D *renderTarget = nullptr; + gl::Error error = srcAttachment.getRenderTarget(&renderTarget); + if (error.isError()) + { + return error; + } + + RenderTarget11 *rt11 = GetAs(renderTarget); + ASSERT(rt11->getTexture()); + + TextureHelper11 textureHelper = + TextureHelper11::MakeAndReference(rt11->getTexture(), rt11->getANGLEFormat()); + unsigned int sourceSubResource = rt11->getSubresourceIndex(); + + const gl::Extents &texSize = textureHelper.getExtents(); + + gl::Rectangle actualArea = sourceArea; + if (invertTexture) + { + actualArea.y = texSize.height - actualArea.y - actualArea.height; + } // 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(area.x, 0, static_cast(textureDesc.Width)); - safeArea.y = gl::clamp(area.y, 0, static_cast(textureDesc.Height)); - safeArea.width = gl::clamp(area.width + std::min(area.x, 0), 0, - static_cast(textureDesc.Width) - safeArea.x); - safeArea.height = gl::clamp(area.height + std::min(area.y, 0), 0, - static_cast(textureDesc.Height) - safeArea.y); + 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 <= static_cast(textureDesc.Width)); - ASSERT(safeArea.y + safeArea.height <= static_cast(textureDesc.Height)); + ASSERT(safeArea.x + safeArea.width <= texSize.width); + ASSERT(safeArea.y + safeArea.height <= texSize.height); if (safeArea.width == 0 || safeArea.height == 0) { @@ -3162,35 +3739,30 @@ gl::Error Renderer11::readTextureData(ID3D11Texture2D *texture, unsigned int sub return gl::Error(GL_NO_ERROR); } - D3D11_TEXTURE2D_DESC stagingDesc; - stagingDesc.Width = safeArea.width; - stagingDesc.Height = safeArea.height; - stagingDesc.MipLevels = 1; - stagingDesc.ArraySize = 1; - stagingDesc.Format = textureDesc.Format; - 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; - - ID3D11Texture2D* stagingTex = NULL; - HRESULT result = mDevice->CreateTexture2D(&stagingDesc, NULL, &stagingTex); - if (FAILED(result)) + gl::Extents safeSize(safeArea.width, safeArea.height, 1); + auto errorOrResult = + CreateStagingTexture(textureHelper.getTextureType(), textureHelper.getFormat(), + textureHelper.getANGLEFormat(), safeSize, mDevice); + if (errorOrResult.isError()) { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal staging texture for ReadPixels, HRESULT: 0x%X.", result); + return errorOrResult.getError(); } - ID3D11Texture2D* srcTex = NULL; - if (textureDesc.SampleDesc.Count > 1) + TextureHelper11 stagingHelper(errorOrResult.getResult()); + 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.getTextureType() == GL_TEXTURE_2D && textureHelper.getSampleCount() > 1) { D3D11_TEXTURE2D_DESC resolveDesc; - resolveDesc.Width = textureDesc.Width; - resolveDesc.Height = textureDesc.Height; + resolveDesc.Width = static_cast(texSize.width); + resolveDesc.Height = static_cast(texSize.height); resolveDesc.MipLevels = 1; resolveDesc.ArraySize = 1; - resolveDesc.Format = textureDesc.Format; + resolveDesc.Format = textureHelper.getFormat(); resolveDesc.SampleDesc.Count = 1; resolveDesc.SampleDesc.Quality = 0; resolveDesc.Usage = D3D11_USAGE_DEFAULT; @@ -3198,20 +3770,23 @@ gl::Error Renderer11::readTextureData(ID3D11Texture2D *texture, unsigned int sub resolveDesc.CPUAccessFlags = 0; resolveDesc.MiscFlags = 0; - result = mDevice->CreateTexture2D(&resolveDesc, NULL, &srcTex); + ID3D11Texture2D *resolveTex2D = nullptr; + HRESULT result = mDevice->CreateTexture2D(&resolveDesc, nullptr, &resolveTex2D); if (FAILED(result)) { - SafeRelease(stagingTex); - return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal resolve texture for ReadPixels, HRESULT: 0x%X.", result); + return gl::Error(GL_OUT_OF_MEMORY, + "Renderer11::readTextureData failed to create internal resolve " + "texture for ReadPixels, HRESULT: 0x%X.", + result); } - mDeviceContext->ResolveSubresource(srcTex, 0, texture, subResource, textureDesc.Format); - subResource = 0; - } - else - { - srcTex = texture; - srcTex->AddRef(); + mDeviceContext->ResolveSubresource(resolveTex2D, 0, textureHelper.getTexture2D(), + sourceSubResource, textureHelper.getFormat()); + resolvedTextureHelper = + TextureHelper11::MakeAndReference(resolveTex2D, textureHelper.getANGLEFormat()); + + sourceSubResource = 0; + srcTexture = &resolvedTextureHelper; } D3D11_BOX srcBox; @@ -3219,28 +3794,52 @@ gl::Error Renderer11::readTextureData(ID3D11Texture2D *texture, unsigned int sub srcBox.right = static_cast(safeArea.x + safeArea.width); srcBox.top = static_cast(safeArea.y); srcBox.bottom = static_cast(safeArea.y + safeArea.height); - srcBox.front = 0; - srcBox.back = 1; - mDeviceContext->CopySubresourceRegion(stagingTex, 0, 0, 0, 0, srcTex, subResource, &srcBox); + // Select the correct layer from a 3D attachment + srcBox.front = 0; + if (textureHelper.getTextureType() == GL_TEXTURE_3D) + { + srcBox.front = static_cast(srcAttachment.layer()); + } + srcBox.back = srcBox.front + 1; + + mDeviceContext->CopySubresourceRegion(stagingHelper.getResource(), 0, 0, 0, 0, + srcTexture->getResource(), sourceSubResource, &srcBox); - SafeRelease(srcTex); + if (invertTexture) + { + gl::PixelPackState invertTexturePack; - PackPixelsParams packParams(safeArea, format, type, outputPitch, pack, 0); - gl::Error error = packPixels(stagingTex, packParams, pixels); + // Create a new PixelPackState with reversed row order. Note that we can't just assign + // 'invertTexturePack' to be 'pack' (or memcpy) since that breaks the ref counting/object + // tracking in the 'pixelBuffer' members, causing leaks. Instead we must use + // pixelBuffer.set() twice, which performs the addRef/release correctly + invertTexturePack.alignment = pack.alignment; + invertTexturePack.pixelBuffer.set(pack.pixelBuffer.get()); + invertTexturePack.reverseRowOrder = !pack.reverseRowOrder; - SafeRelease(stagingTex); + PackPixelsParams packParams(safeArea, format, type, outputPitch, invertTexturePack, 0); + error = packPixels(stagingHelper, packParams, pixelsOut); - return error; + invertTexturePack.pixelBuffer.set(nullptr); + + return error; + } + else + { + PackPixelsParams packParams(safeArea, format, type, outputPitch, pack, 0); + return packPixels(stagingHelper, packParams, pixelsOut); + } } -gl::Error Renderer11::packPixels(ID3D11Texture2D *readTexture, const PackPixelsParams ¶ms, uint8_t *pixelsOut) +gl::Error Renderer11::packPixels(const TextureHelper11 &textureHelper, + const PackPixelsParams ¶ms, + uint8_t *pixelsOut) { - D3D11_TEXTURE2D_DESC textureDesc; - readTexture->GetDesc(&textureDesc); + ID3D11Resource *readResource = textureHelper.getResource(); D3D11_MAPPED_SUBRESOURCE mapping; - HRESULT hr = mDeviceContext->Map(readTexture, 0, D3D11_MAP_READ, 0, &mapping); + HRESULT hr = mDeviceContext->Map(readResource, 0, D3D11_MAP_READ, 0, &mapping); if (FAILED(hr)) { ASSERT(hr == E_OUTOFMEMORY); @@ -3260,8 +3859,9 @@ gl::Error Renderer11::packPixels(ID3D11Texture2D *readTexture, const PackPixelsP inputPitch = static_cast(mapping.RowPitch); } - const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(textureDesc.Format); - const gl::InternalFormat &sourceFormatInfo = gl::GetInternalFormatInfo(dxgiFormatInfo.internalFormat); + const auto &angleFormatInfo = d3d11::GetANGLEFormatSet(textureHelper.getANGLEFormat()); + const gl::InternalFormat &sourceFormatInfo = + gl::GetInternalFormatInfo(angleFormatInfo.glInternalFormat); if (sourceFormatInfo.format == params.format && sourceFormatInfo.type == params.type) { uint8_t *dest = pixelsOut + params.offset; @@ -3272,9 +3872,10 @@ gl::Error Renderer11::packPixels(ID3D11Texture2D *readTexture, const PackPixelsP } else { - const d3d11::DXGIFormat &sourceDXGIFormatInfo = d3d11::GetDXGIFormatInfo(textureDesc.Format); - ColorCopyFunction fastCopyFunc = sourceDXGIFormatInfo.getFastCopyFunction(params.format, params.type); - + const d3d11::DXGIFormat &dxgiFormatInfo = + d3d11::GetDXGIFormatInfo(textureHelper.getFormat()); + ColorCopyFunction fastCopyFunc = + dxgiFormatInfo.getFastCopyFunction(params.format, params.type); GLenum sizedDestInternalFormat = gl::GetSizedInternalFormat(params.format, params.type); const gl::InternalFormat &destFormatInfo = gl::GetInternalFormatInfo(sizedDestInternalFormat); @@ -3294,7 +3895,7 @@ gl::Error Renderer11::packPixels(ID3D11Texture2D *readTexture, const PackPixelsP } else { - ColorReadFunction colorReadFunction = sourceDXGIFormatInfo.colorReadFunction; + ColorReadFunction colorReadFunction = angleFormatInfo.colorReadFunction; ColorWriteFunction colorWriteFunction = GetColorWriteFunction(params.format, params.type); uint8_t temp[16]; // Maximum size of any Color type used. @@ -3319,14 +3920,20 @@ gl::Error Renderer11::packPixels(ID3D11Texture2D *readTexture, const PackPixelsP } } - mDeviceContext->Unmap(readTexture, 0); + mDeviceContext->Unmap(readResource, 0); return gl::Error(GL_NO_ERROR); } -gl::Error Renderer11::blitRenderbufferRect(const gl::Rectangle &readRect, const gl::Rectangle &drawRect, RenderTargetD3D *readRenderTarget, - RenderTargetD3D *drawRenderTarget, GLenum filter, const gl::Rectangle *scissor, - bool colorBlit, bool depthBlit, bool stencilBlit) +gl::Error Renderer11::blitRenderbufferRect(const gl::Rectangle &readRectIn, + const gl::Rectangle &drawRectIn, + 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 @@ -3378,7 +3985,12 @@ gl::Error Renderer11::blitRenderbufferRect(const gl::Rectangle &readRect, const readTexture = readRenderTarget11->getTexture(); readTexture->AddRef(); readSubresource = readRenderTarget11->getSubresourceIndex(); - readSRV = readRenderTarget11->getShaderResourceView(); + readSRV = readRenderTarget11->getBlitShaderResourceView(); + if (readSRV == nullptr) + { + ASSERT(depthBlit || stencilBlit); + readSRV = readRenderTarget11->getShaderResourceView(); + } readSRV->AddRef(); } @@ -3392,13 +4004,96 @@ gl::Error Renderer11::blitRenderbufferRect(const gl::Rectangle &readRect, const gl::Extents readSize(readRenderTarget->getWidth(), readRenderTarget->getHeight(), 1); 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. + gl::Rectangle readRect = readRectIn; + gl::Rectangle drawRect = drawRectIn; + auto readToDrawX = [&drawRectIn, &readRectIn](int readOffset) + { + double readToDrawScale = + static_cast(drawRectIn.width) / static_cast(readRectIn.width); + return static_cast(round(static_cast(readOffset) * readToDrawScale)); + }; + if (readRect.x < 0) + { + int readOffset = -readRect.x; + readRect.x += readOffset; + readRect.width -= readOffset; + + int drawOffset = readToDrawX(readOffset); + drawRect.x += drawOffset; + drawRect.width -= drawOffset; + } + + auto readToDrawY = [&drawRectIn, &readRectIn](int readOffset) + { + double readToDrawScale = + static_cast(drawRectIn.height) / static_cast(readRectIn.height); + return static_cast(round(static_cast(readOffset) * readToDrawScale)); + }; + if (readRect.y < 0) + { + int readOffset = -readRect.y; + readRect.y += readOffset; + readRect.height -= readOffset; + + int drawOffset = readToDrawY(readOffset); + drawRect.y += drawOffset; + drawRect.height -= drawOffset; + } + + if (readRect.x1() < 0) + { + int readOffset = -readRect.x1(); + readRect.width += readOffset; + + int drawOffset = readToDrawX(readOffset); + drawRect.width += drawOffset; + } + + if (readRect.y1() < 0) + { + int readOffset = -readRect.y1(); + readRect.height += readOffset; + + int drawOffset = readToDrawY(readOffset); + drawRect.height += drawOffset; + } + bool scissorNeeded = scissor && gl::ClipRectangle(drawRect, *scissor, NULL); - bool wholeBufferCopy = !scissorNeeded && - 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; + const auto &destFormatInfo = gl::GetInternalFormatInfo(drawRenderTarget->getInternalFormat()); + const auto &srcFormatInfo = gl::GetInternalFormatInfo(readRenderTarget->getInternalFormat()); + const auto &formatSet = d3d11::GetANGLEFormatSet(drawRenderTarget11->getANGLEFormat()); + const DXGI_FORMAT drawDXGIFormat = colorBlit ? formatSet.rtvFormat : formatSet.dsvFormat; + const auto &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(drawDXGIFormat); + + // 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) && + (dxgiFormatInfo.redBits > 0); + colorMask.green = (srcFormatInfo.greenBits > 0) && (destFormatInfo.greenBits == 0) && + (dxgiFormatInfo.greenBits > 0); + colorMask.blue = (srcFormatInfo.blueBits > 0) && (destFormatInfo.blueBits == 0) && + (dxgiFormatInfo.blueBits > 0); + colorMask.alpha = (srcFormatInfo.alphaBits > 0) && (destFormatInfo.alphaBits == 0) && + (dxgiFormatInfo.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; @@ -3409,14 +4104,13 @@ gl::Error Renderer11::blitRenderbufferRect(const gl::Rectangle &readRect, const drawRect.x < 0 || drawRect.x + drawRect.width > drawSize.width || drawRect.y < 0 || drawRect.y + drawRect.height > drawSize.height; - const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(drawRenderTarget11->getDXGIFormat()); bool partialDSBlit = (dxgiFormatInfo.depthBits > 0 && depthBlit) != (dxgiFormatInfo.stencilBits > 0 && stencilBlit); gl::Error result(GL_NO_ERROR); - if (readRenderTarget11->getDXGIFormat() == drawRenderTarget11->getDXGIFormat() && + if (readRenderTarget11->getANGLEFormat() == drawRenderTarget11->getANGLEFormat() && !stretchRequired && !outOfBounds && !flipRequired && !partialDSBlit && - (!(depthBlit || stencilBlit) || wholeBufferCopy)) + !colorMaskingNeeded && (!(depthBlit || stencilBlit) || wholeBufferCopy)) { UINT dstX = drawRect.x; UINT dstY = drawRect.y; @@ -3486,9 +4180,10 @@ gl::Error Renderer11::blitRenderbufferRect(const gl::Rectangle &readRect, const } else { - GLenum format = gl::GetInternalFormatInfo(drawRenderTarget->getInternalFormat()).format; + // We don't currently support masking off any other channel than alpha + bool maskOffAlpha = colorMaskingNeeded && colorMask.alpha; result = mBlit->copyTexture(readSRV, readArea, readSize, drawRTV, drawArea, drawSize, - scissor, format, filter); + scissor, destFormatInfo.format, filter, maskOffAlpha); } } @@ -3500,9 +4195,49 @@ gl::Error Renderer11::blitRenderbufferRect(const gl::Rectangle &readRect, const bool Renderer11::isES3Capable() const { - return (d3d11_gl::GetMaximumClientVersion(mFeatureLevel) > 2); + return (d3d11_gl::GetMaximumClientVersion(mRenderer11DeviceCaps.featureLevel) > 2); }; +void Renderer11::onSwap() +{ + // Send histogram updates every half hour + const double kHistogramUpdateInterval = 30 * 60; + + const double currentTime = ANGLEPlatformCurrent()->monotonicallyIncreasingTime(); + 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 (auto &buffer : mAliveBuffers) + { + sizeSum += buffer->getTotalCPUBufferMemoryBytes(); + } + const int kOneMegaByte = 1024 * 1024; + ANGLE_HISTOGRAM_MEMORY_MB("GPU.ANGLE.Buffer11CPUMemoryMB", + static_cast(sizeSum) / kOneMegaByte); + } +} + +void Renderer11::onBufferDelete(const Buffer11 *deleted) +{ + mAliveBuffers.erase(deleted); +} + +void Renderer11::onMakeCurrent(const gl::Data &data) +{ + mStateManager.onMakeCurrent(data); +} + ID3D11Texture2D *Renderer11::resolveMultisampledTexture(ID3D11Texture2D *source, unsigned int subresource) { D3D11_TEXTURE2D_DESC textureDesc; @@ -3561,54 +4296,101 @@ bool Renderer11::getLUID(LUID *adapterLuid) const return true; } -VertexConversionType Renderer11::getVertexConversionType(const gl::VertexFormat &vertexFormat) const +VertexConversionType Renderer11::getVertexConversionType(gl::VertexFormatType vertexFormatType) const +{ + return d3d11::GetVertexFormatInfo(vertexFormatType, mRenderer11DeviceCaps.featureLevel).conversionType; +} + +GLenum Renderer11::getVertexComponentType(gl::VertexFormatType vertexFormatType) const { - return d3d11::GetVertexFormatInfo(vertexFormat, mFeatureLevel).conversionType; + return d3d11::GetDXGIFormatInfo(d3d11::GetVertexFormatInfo(vertexFormatType, mRenderer11DeviceCaps.featureLevel).nativeFormat).componentType; } -GLenum Renderer11::getVertexComponentType(const gl::VertexFormat &vertexFormat) const +gl::ErrorOrResult Renderer11::getVertexSpaceRequired( + const gl::VertexAttribute &attrib, + GLsizei count, + GLsizei instances) const { - return d3d11::GetDXGIFormatInfo(d3d11::GetVertexFormatInfo(vertexFormat, mFeatureLevel).nativeFormat).componentType; + if (!attrib.enabled) + { + return 16u; + } + + unsigned int elementCount = 0; + if (instances == 0 || attrib.divisor == 0) + { + elementCount = count; + } + else + { + // Round up to divisor, if possible + elementCount = UnsignedCeilDivide(static_cast(instances), attrib.divisor); + } + + gl::VertexFormatType formatType = gl::GetVertexFormatType(attrib); + const D3D_FEATURE_LEVEL featureLevel = mRenderer11DeviceCaps.featureLevel; + const d3d11::VertexFormat &vertexFormatInfo = + d3d11::GetVertexFormatInfo(formatType, featureLevel); + const d3d11::DXGIFormatSize &dxgiFormatInfo = + d3d11::GetDXGIFormatSizeInfo(vertexFormatInfo.nativeFormat); + unsigned int elementSize = dxgiFormatInfo.pixelBytes; + if (elementSize > std::numeric_limits::max() / elementCount) + { + return gl::Error(GL_OUT_OF_MEMORY, "New vertex buffer size would result in an overflow."); + } + + return elementSize * elementCount; } -void Renderer11::generateCaps(gl::Caps *outCaps, gl::TextureCapsMap *outTextureCaps, gl::Extensions *outExtensions) const +void Renderer11::generateCaps(gl::Caps *outCaps, gl::TextureCapsMap *outTextureCaps, + gl::Extensions *outExtensions, gl::Limitations *outLimitations) const { - d3d11_gl::GenerateCaps(mDevice, mDeviceContext, outCaps, outTextureCaps, outExtensions); + d3d11_gl::GenerateCaps(mDevice, mDeviceContext, mRenderer11DeviceCaps, outCaps, outTextureCaps, + outExtensions, outLimitations); } -Workarounds Renderer11::generateWorkarounds() const +WorkaroundsD3D Renderer11::generateWorkarounds() const { - return d3d11::GenerateWorkarounds(mFeatureLevel); + return d3d11::GenerateWorkarounds(mRenderer11DeviceCaps.featureLevel); } -void Renderer11::setShaderResource(gl::SamplerType shaderType, UINT resourceSlot, ID3D11ShaderResourceView *srv) +void Renderer11::createAnnotator() { - auto ¤tSRVs = (shaderType == gl::SAMPLER_VERTEX ? mCurVertexSRVs : mCurPixelSRVs); + // The D3D11 renderer must choose the D3D9 debug annotator because the D3D11 interface + // method ID3DUserDefinedAnnotation::GetStatus on desktop builds doesn't work with the Graphics + // Diagnostics tools in Visual Studio 2013. + // The D3D9 annotator works properly for both D3D11 and D3D9. + // Incorrect status reporting can cause ANGLE to log unnecessary debug events. +#ifdef ANGLE_ENABLE_D3D9 + mAnnotator = new DebugAnnotator9(); +#else + mAnnotator = new DebugAnnotator11(); +#endif +} - ASSERT(static_cast(resourceSlot) < currentSRVs.size()); - auto &record = currentSRVs[resourceSlot]; +gl::Error Renderer11::clearTextures(gl::SamplerType samplerType, size_t rangeStart, size_t rangeEnd) +{ + return mStateManager.clearTextures(samplerType, rangeStart, rangeEnd); +} - if (record.srv != reinterpret_cast(srv)) +egl::Error Renderer11::getEGLDevice(DeviceImpl **device) +{ + if (mEGLDevice == nullptr) { - if (shaderType == gl::SAMPLER_VERTEX) - { - mDeviceContext->VSSetShaderResources(resourceSlot, 1, &srv); - } - else - { - mDeviceContext->PSSetShaderResources(resourceSlot, 1, &srv); - } + ASSERT(mDevice != nullptr); + mEGLDevice = new DeviceD3D(); + egl::Error error = mEGLDevice->initialize(reinterpret_cast(mDevice), + EGL_D3D11_DEVICE_ANGLE, EGL_FALSE); - record.srv = reinterpret_cast(srv); - if (srv) - { - record.resource = reinterpret_cast(GetViewResource(srv)); - srv->GetDesc(&record.desc); - } - else + if (error.isError()) { - record.resource = 0; + SafeDelete(mEGLDevice); + return error; } } + + *device = static_cast(mEGLDevice); + return egl::Error(EGL_SUCCESS); } -} + +} // namespace rx diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/Renderer11.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/Renderer11.h index cbbcd7ef57ac..fda7118a2913 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/Renderer11.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/Renderer11.h @@ -14,11 +14,14 @@ #include "libANGLE/AttributeMap.h" #include "libANGLE/angletypes.h" #include "libANGLE/renderer/d3d/HLSLCompiler.h" +#include "libANGLE/renderer/d3d/ProgramD3D.h" #include "libANGLE/renderer/d3d/RendererD3D.h" #include "libANGLE/renderer/d3d/RenderTargetD3D.h" #include "libANGLE/renderer/d3d/d3d11/DebugAnnotator11.h" #include "libANGLE/renderer/d3d/d3d11/InputLayoutCache.h" +#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h" #include "libANGLE/renderer/d3d/d3d11/RenderStateCache.h" +#include "libANGLE/renderer/d3d/d3d11/StateManager11.h" namespace gl { @@ -33,12 +36,24 @@ class VertexDataManager; class IndexDataManager; class StreamingIndexBufferInterface; class Blit11; +class Buffer11; class Clear11; class PixelTransfer11; class RenderTarget11; class Trim11; struct PackPixelsParams; +struct 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 + UINT B5G6R5support; // Bitfield of D3D11_FORMAT_SUPPORT values for DXGI_FORMAT_B5G6R5_UNORM + UINT B4G4R4A4support; // Bitfield of D3D11_FORMAT_SUPPORT values for DXGI_FORMAT_B4G4R4A4_UNORM + UINT B5G5R5A1support; // Bitfield of D3D11_FORMAT_SUPPORT values for DXGI_FORMAT_B5G5R5A1_UNORM +}; + enum { MAX_VERTEX_UNIFORM_VECTORS_D3D11 = 1024, @@ -93,61 +108,61 @@ class Renderer11 : public RendererD3D virtual bool resetDevice(); egl::ConfigSet generateConfigs() const override; + void generateDisplayExtensions(egl::DisplayExtensions *outExtensions) const override; gl::Error flush() override; gl::Error finish() override; - bool shouldCreateChildWindowForSurface(EGLNativeWindowType window) const override; - virtual SwapChainD3D *createSwapChain(NativeWindow nativeWindow, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat); + SwapChainD3D *createSwapChain(NativeWindow nativeWindow, + HANDLE shareHandle, + GLenum backBufferFormat, + GLenum depthBufferFormat, + EGLint orientation) override; + + CompilerImpl *createCompiler() override; virtual gl::Error generateSwizzle(gl::Texture *texture); virtual gl::Error setSamplerState(gl::SamplerType type, int index, gl::Texture *texture, const gl::SamplerState &sampler); virtual gl::Error setTexture(gl::SamplerType type, int index, gl::Texture *texture); gl::Error setUniformBuffers(const gl::Data &data, - const GLint vertexUniformBuffers[], - const GLint fragmentUniformBuffers[]) override; - - virtual gl::Error setRasterizerState(const gl::RasterizerState &rasterState); - gl::Error setBlendState(const gl::Framebuffer *framebuffer, const gl::BlendState &blendState, const gl::ColorF &blendColor, - unsigned int sampleMask) override; - virtual gl::Error setDepthStencilState(const gl::DepthStencilState &depthStencilState, int stencilRef, - int stencilBackRef, bool frontFaceCCW); + const std::vector &vertexUniformBuffers, + const std::vector &fragmentUniformBuffers) override; - virtual void setScissorRectangle(const gl::Rectangle &scissor, bool enabled); - virtual void setViewport(const gl::Rectangle &viewport, float zNear, float zFar, GLenum drawMode, GLenum frontFace, - bool ignoreViewport); + gl::Error updateState(const gl::Data &data, GLenum drawMode) override; virtual bool applyPrimitiveType(GLenum mode, GLsizei count, bool usesPointSize); gl::Error applyRenderTarget(const gl::Framebuffer *frameBuffer) override; - virtual gl::Error applyShaders(gl::Program *program, const gl::VertexFormat inputLayout[], const gl::Framebuffer *framebuffer, - bool rasterizerDiscard, bool transformFeedbackActive); - - virtual gl::Error applyUniforms(const ProgramImpl &program, const std::vector &uniformArray); - virtual gl::Error applyVertexBuffer(const gl::State &state, GLenum mode, GLint first, GLsizei count, GLsizei instances); - virtual gl::Error applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementArrayBuffer, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo); - void applyTransformFeedbackBuffers(const gl::State &state) override; - - gl::Error drawArrays(const gl::Data &data, GLenum mode, GLsizei count, GLsizei instances, bool usesPointSize) override; - virtual gl::Error drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, - gl::Buffer *elementArrayBuffer, const TranslatedIndexData &indexInfo, GLsizei instances); - - virtual void markAllStateDirty(); + gl::Error applyUniforms(const ProgramD3D &programD3D, + GLenum drawMode, + const std::vector &uniformArray) override; + virtual gl::Error applyVertexBuffer(const gl::State &state, + GLenum mode, + GLint first, + GLsizei count, + GLsizei instances, + TranslatedIndexData *indexInfo); + gl::Error applyIndexBuffer(const gl::Data &data, + const GLvoid *indices, + GLsizei count, + GLenum mode, + GLenum type, + TranslatedIndexData *indexInfo) override; + gl::Error applyTransformFeedbackBuffers(const gl::State &state) override; // lost device bool testDeviceLost() override; bool testDeviceResettable() override; - VendorID getVendorId() const override; std::string getRendererDescription() const override; - GUID getAdapterIdentifier() const override; + DeviceIdentifier getAdapterIdentifier() const override; virtual unsigned int getReservedVertexUniformVectors() const; virtual unsigned int getReservedFragmentUniformVectors() const; virtual unsigned int getReservedVertexUniformBuffers() const; virtual unsigned int getReservedFragmentUniformBuffers() const; - virtual bool getShareHandleSupport() const; - virtual bool getPostSubBufferSupport() const; + + bool getShareHandleSupport() const; virtual int getMajorShaderModel() const; int getMinorShaderModel() const override; @@ -165,31 +180,38 @@ class Renderer11 : public RendererD3D // RenderTarget creation virtual gl::Error createRenderTarget(int width, int height, GLenum format, GLsizei samples, RenderTargetD3D **outRT); + gl::Error createRenderTargetCopy(RenderTargetD3D *source, RenderTargetD3D **outRT) override; // Framebuffer creation - FramebufferImpl *createDefaultFramebuffer(const gl::Framebuffer::Data &data) override; FramebufferImpl *createFramebuffer(const gl::Framebuffer::Data &data) override; // Shader creation - virtual CompilerImpl *createCompiler(const gl::Data &data); - virtual ShaderImpl *createShader(GLenum type); - virtual ProgramImpl *createProgram(); + ShaderImpl *createShader(const gl::Shader::Data &data) override; + ProgramImpl *createProgram(const gl::Program::Data &data) override; // Shader operations - virtual gl::Error loadExecutable(const void *function, size_t length, ShaderType type, - const std::vector &transformFeedbackVaryings, - bool separatedOutputBuffers, ShaderExecutableD3D **outExecutable); - virtual gl::Error compileToExecutable(gl::InfoLog &infoLog, const std::string &shaderHLSL, ShaderType type, - const std::vector &transformFeedbackVaryings, - bool separatedOutputBuffers, const D3DCompilerWorkarounds &workarounds, - ShaderExecutableD3D **outExectuable); - virtual UniformStorageD3D *createUniformStorage(size_t storageSize); + gl::Error loadExecutable(const void *function, + size_t length, + ShaderType type, + const std::vector &streamOutVaryings, + bool separatedOutputBuffers, + ShaderExecutableD3D **outExecutable) override; + gl::Error compileToExecutable(gl::InfoLog &infoLog, + const std::string &shaderHLSL, + ShaderType type, + const std::vector &streamOutVaryings, + bool separatedOutputBuffers, + const D3DCompilerWorkarounds &workarounds, + ShaderExecutableD3D **outExectuable) override; + UniformStorageD3D *createUniformStorage(size_t storageSize) override; // Image operations virtual ImageD3D *createImage(); gl::Error generateMipmap(ImageD3D *dest, ImageD3D *source) override; - gl::Error generateMipmapsUsingD3D(TextureStorage *storage, const gl::SamplerState &samplerState) override; + gl::Error generateMipmapsUsingD3D(TextureStorage *storage, + const gl::TextureState &textureState) override; virtual TextureStorage *createTextureStorage2D(SwapChainD3D *swapChain); + TextureStorage *createTextureStorageEGLImage(EGLImageD3D *eglImage) override; virtual TextureStorage *createTextureStorage2D(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, int levels, bool hintLevelZeroOnly); virtual TextureStorage *createTextureStorageCube(GLenum internalformat, bool renderTarget, int size, int levels, bool hintLevelZeroOnly); virtual TextureStorage *createTextureStorage3D(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, GLsizei depth, int levels); @@ -207,7 +229,7 @@ class Renderer11 : public RendererD3D virtual IndexBuffer *createIndexBuffer(); // Vertex Array creation - virtual VertexArrayImpl *createVertexArray(); + VertexArrayImpl *createVertexArray(const gl::VertexArray::Data &data) override; // Query and Fence creation virtual QueryImpl *createQuery(GLenum type); @@ -217,6 +239,9 @@ class Renderer11 : public RendererD3D // Transform Feedback creation virtual TransformFeedbackImpl* createTransformFeedback(); + // Stream Creation + StreamImpl *createStream(const egl::AttributeMap &attribs) override; + // D3D11-renderer specific methods ID3D11Device *getDevice() { return mDevice; } void *getD3DDevice() override; @@ -224,6 +249,8 @@ class Renderer11 : public RendererD3D ID3D11DeviceContext1 *getDeviceContext1IfSupported() { return mDeviceContext1; }; DXGIFactory *getDxgiFactory() { return mDxgiFactory; }; + RenderStateCache &getStateCache() { return mStateCache; } + Blit11 *getBlitter() { return mBlit; } Clear11 *getClearer() { return mClear; } @@ -232,64 +259,143 @@ class Renderer11 : public RendererD3D virtual gl::Error fastCopyBufferToTexture(const gl::PixelUnpackState &unpack, unsigned int offset, RenderTargetD3D *destRenderTarget, GLenum destinationFormat, GLenum sourcePixelsType, const gl::Box &destArea); - void unapplyRenderTargets(); - void setOneTimeRenderTarget(ID3D11RenderTargetView *renderTargetView); - gl::Error packPixels(ID3D11Texture2D *readTexture, const PackPixelsParams ¶ms, uint8_t *pixelsOut); + void markAllStateDirty(); + gl::Error packPixels(const TextureHelper11 &textureHelper, + const PackPixelsParams ¶ms, + uint8_t *pixelsOut); bool getLUID(LUID *adapterLuid) const override; - virtual VertexConversionType getVertexConversionType(const gl::VertexFormat &vertexFormat) const; - virtual GLenum getVertexComponentType(const gl::VertexFormat &vertexFormat) const; - - gl::Error readTextureData(ID3D11Texture2D *texture, unsigned int subResource, const gl::Rectangle &area, GLenum format, - GLenum type, GLuint outputPitch, const gl::PixelPackState &pack, uint8_t *pixels); - - void setShaderResource(gl::SamplerType shaderType, UINT resourceSlot, ID3D11ShaderResourceView *srv); + VertexConversionType getVertexConversionType(gl::VertexFormatType vertexFormatType) const override; + GLenum getVertexComponentType(gl::VertexFormatType vertexFormatType) const override; + gl::ErrorOrResult getVertexSpaceRequired(const gl::VertexAttribute &attrib, + GLsizei count, + GLsizei instances) const override; + + gl::Error readFromAttachment(const gl::FramebufferAttachment &srcAttachment, + const gl::Rectangle &sourceArea, + GLenum format, + GLenum type, + GLuint outputPitch, + const gl::PixelPackState &pack, + uint8_t *pixels); gl::Error blitRenderbufferRect(const gl::Rectangle &readRect, const gl::Rectangle &drawRect, RenderTargetD3D *readRenderTarget, RenderTargetD3D *drawRenderTarget, GLenum filter, const gl::Rectangle *scissor, bool colorBlit, bool depthBlit, bool stencilBlit); bool isES3Capable() const; - D3D_FEATURE_LEVEL getFeatureLevel() const { return mFeatureLevel; }; + const Renderer11DeviceCaps &getRenderer11DeviceCaps() { return mRenderer11DeviceCaps; }; RendererClass getRendererClass() const override { return RENDERER_D3D11; } + InputLayoutCache *getInputLayoutCache() { return &mInputLayoutCache; } + StateManager11 *getStateManager() { return &mStateManager; } - private: - void generateCaps(gl::Caps *outCaps, gl::TextureCapsMap *outTextureCaps, gl::Extensions *outExtensions) const override; - Workarounds generateWorkarounds() const override; + void onSwap(); + void onBufferDelete(const Buffer11 *deleted); + void onMakeCurrent(const gl::Data &data) override; + + egl::Error getEGLDevice(DeviceImpl **device) override; - gl::Error drawLineLoop(GLsizei count, GLenum type, const GLvoid *indices, int minIndex, gl::Buffer *elementArrayBuffer); - gl::Error drawTriangleFan(GLsizei count, GLenum type, const GLvoid *indices, int minIndex, gl::Buffer *elementArrayBuffer, int instances); + protected: + void createAnnotator() override; + gl::Error clearTextures(gl::SamplerType samplerType, size_t rangeStart, size_t rangeEnd) override; + gl::Error applyShadersImpl(const gl::Data &data, GLenum drawMode) override; + + void syncState(const gl::State &state, const gl::State::DirtyBits &bitmask) override; + + private: + gl::Error drawArraysImpl(const gl::Data &data, + GLenum mode, + GLint startVertex, + GLsizei count, + GLsizei instances) override; + gl::Error drawElementsImpl(const gl::Data &data, + const TranslatedIndexData &indexInfo, + GLenum mode, + GLsizei count, + GLenum type, + const GLvoid *indices, + GLsizei instances) override; + + void generateCaps(gl::Caps *outCaps, gl::TextureCapsMap *outTextureCaps, + gl::Extensions *outExtensions, + gl::Limitations *outLimitations) const override; + + WorkaroundsD3D generateWorkarounds() const override; + + gl::Error drawLineLoop(const gl::Data &data, + GLsizei count, + GLenum type, + const GLvoid *indices, + const TranslatedIndexData *indexInfo, + int instances); + gl::Error drawTriangleFan(const gl::Data &data, + GLsizei count, + GLenum type, + const GLvoid *indices, + int minIndex, + int instances); ID3D11Texture2D *resolveMultisampledTexture(ID3D11Texture2D *source, unsigned int subresource); - void unsetConflictingSRVs(gl::SamplerType shaderType, uintptr_t resource, const gl::ImageIndex &index); + + void populateRenderer11DeviceCaps(); + + void updateHistograms(); + + class SamplerMetadataD3D11 final : angle::NonCopyable + { + public: + SamplerMetadataD3D11(); + ~SamplerMetadataD3D11(); + + struct dx_SamplerMetadata + { + int baseLevel; + int internalFormatBits; + int wrapModes; + int padding; // This just pads the struct to 16 bytes + }; + static_assert(sizeof(dx_SamplerMetadata) == 16u, + "Sampler metadata struct must be one 4-vec / 16 bytes."); + + void initData(unsigned int samplerCount); + void update(unsigned int samplerIndex, const gl::Texture &texture); + + const dx_SamplerMetadata *getData() const; + size_t sizeBytes() const; + bool isDirty() const { return mDirty; } + void markClean() { mDirty = false; } + + private: + std::vector mSamplerMetadata; + bool mDirty; + }; + + template + void applyDriverConstantsIfNeeded(TShaderConstants *appliedConstants, + const TShaderConstants &constants, + SamplerMetadataD3D11 *samplerMetadata, + size_t samplerMetadataReferencedBytes, + ID3D11Buffer *driverConstantBuffer); HMODULE mD3d11Module; HMODULE mDxgiModule; + HMODULE mDCompModule; std::vector mAvailableFeatureLevels; - D3D_DRIVER_TYPE mDriverType; + D3D_DRIVER_TYPE mRequestedDriverType; + bool mCreatedWithDeviceEXT; + DeviceD3D *mEGLDevice; HLSLCompiler mCompiler; + egl::Error initializeD3DDevice(); void initializeDevice(); void releaseDeviceResources(); void release(); - RenderStateCache mStateCache; - - // current render target states - uintptr_t mAppliedRTVs[gl::IMPLEMENTATION_MAX_DRAW_BUFFERS]; - uintptr_t mAppliedDSV; - bool mDepthStencilInitialized; - bool mRenderTargetDescInitialized; + d3d11::ANGLED3D11DeviceType getDeviceType() const; - struct RenderTargetDesc - { - size_t width; - size_t height; - DXGI_FORMAT format; - }; - RenderTargetDesc mRenderTargetDesc; + RenderStateCache mStateCache; // Currently applied sampler states std::vector mForceSetVertexSamplerStates; @@ -298,42 +404,7 @@ class Renderer11 : public RendererD3D std::vector mForceSetPixelSamplerStates; std::vector mCurPixelSamplerStates; - // Currently applied textures - struct SRVRecord - { - uintptr_t srv; - uintptr_t resource; - D3D11_SHADER_RESOURCE_VIEW_DESC desc; - }; - std::vector mCurVertexSRVs; - std::vector mCurPixelSRVs; - - // Currently applied blend state - bool mForceSetBlendState; - gl::BlendState mCurBlendState; - gl::ColorF mCurBlendColor; - unsigned int mCurSampleMask; - - // Currently applied rasterizer state - bool mForceSetRasterState; - gl::RasterizerState mCurRasterState; - - // Currently applied depth stencil state - bool mForceSetDepthStencilState; - gl::DepthStencilState mCurDepthStencilState; - int mCurStencilRef; - int mCurStencilBackRef; - - // Currently applied scissor rectangle - bool mForceSetScissor; - bool mScissorEnabled; - gl::Rectangle mCurScissor; - - // Currently applied viewport - bool mForceSetViewport; - gl::Rectangle mCurViewport; - float mCurNear; - float mCurFar; + StateManager11 mStateManager; // Currently applied primitive topology D3D11_PRIMITIVE_TOPOLOGY mCurrentPrimitiveTopology; @@ -342,6 +413,7 @@ class Renderer11 : public RendererD3D ID3D11Buffer *mAppliedIB; DXGI_FORMAT mAppliedIBFormat; unsigned int mAppliedIBOffset; + bool mAppliedIBChanged; // Currently applied transform feedback buffers size_t mAppliedNumXFBBindings; @@ -359,17 +431,17 @@ class Renderer11 : public RendererD3D uintptr_t mAppliedGeometryShader; uintptr_t mAppliedPixelShader; - dx_VertexConstants mVertexConstants; - dx_VertexConstants mAppliedVertexConstants; + dx_VertexConstants11 mAppliedVertexConstants; ID3D11Buffer *mDriverConstantBufferVS; + SamplerMetadataD3D11 mSamplerMetadataVS; ID3D11Buffer *mCurrentVertexConstantBuffer; unsigned int mCurrentConstantBufferVS[gl::IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS]; GLintptr mCurrentConstantBufferVSOffset[gl::IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS]; GLsizeiptr mCurrentConstantBufferVSSize[gl::IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS]; - dx_PixelConstants mPixelConstants; - dx_PixelConstants mAppliedPixelConstants; + dx_PixelConstants11 mAppliedPixelConstants; ID3D11Buffer *mDriverConstantBufferPS; + SamplerMetadataD3D11 mSamplerMetadataPS; ID3D11Buffer *mCurrentPixelConstantBuffer; unsigned int mCurrentConstantBufferPS[gl::IMPLEMENTATION_MAX_FRAGMENT_SHADER_UNIFORM_BUFFERS]; GLintptr mCurrentConstantBufferPSOffset[gl::IMPLEMENTATION_MAX_FRAGMENT_SHADER_UNIFORM_BUFFERS]; @@ -398,11 +470,13 @@ class Renderer11 : public RendererD3D // Sync query ID3D11Query *mSyncQuery; - // Constant buffer offset support - bool mSupportsConstantBufferOffsets; + // Created objects state tracking + std::set mAliveBuffers; + + double mLastHistogramUpdateTime; ID3D11Device *mDevice; - D3D_FEATURE_LEVEL mFeatureLevel; + Renderer11DeviceCaps mRenderer11DeviceCaps; ID3D11DeviceContext *mDeviceContext; ID3D11DeviceContext1 *mDeviceContext1; IDXGIAdapter *mDxgiAdapter; @@ -411,7 +485,9 @@ class Renderer11 : public RendererD3D DXGIFactory *mDxgiFactory; ID3D11Debug *mDebug; - DebugAnnotator11 mAnnotator; + std::vector mScratchIndexDataBuffer; + + mutable Optional mSupportsShareHandles; }; } diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/ShaderExecutable11.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/ShaderExecutable11.cpp index 9f1fcc6d86d1..4da51afe49f8 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/ShaderExecutable11.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/ShaderExecutable11.cpp @@ -77,7 +77,7 @@ UniformStorage11::UniformStorage11(Renderer11 *renderer, size_t initialSize) if (initialSize > 0) { D3D11_BUFFER_DESC constantBufferDescription = {0}; - constantBufferDescription.ByteWidth = initialSize; + constantBufferDescription.ByteWidth = static_cast(initialSize); constantBufferDescription.Usage = D3D11_USAGE_DYNAMIC; constantBufferDescription.BindFlags = D3D11_BIND_CONSTANT_BUFFER; constantBufferDescription.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/StateManager11.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/StateManager11.cpp new file mode 100644 index 000000000000..c3b3e5ea5a8a --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/StateManager11.cpp @@ -0,0 +1,1136 @@ +// +// Copyright (c) 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/BitSetIterator.h" +#include "common/utilities.h" +#include "libANGLE/Query.h" +#include "libANGLE/renderer/d3d/d3d11/Framebuffer11.h" +#include "libANGLE/renderer/d3d/d3d11/Renderer11.h" +#include "libANGLE/renderer/d3d/d3d11/RenderTarget11.h" + +namespace rx +{ + +namespace +{ +bool ImageIndexConflictsWithSRV(const gl::ImageIndex &index, D3D11_SHADER_RESOURCE_VIEW_DESC desc) +{ + unsigned mipLevel = index.mipIndex; + unsigned layerIndex = index.layerIndex; + GLenum type = index.type; + + switch (desc.ViewDimension) + { + case D3D11_SRV_DIMENSION_TEXTURE2D: + { + unsigned maxSrvMip = desc.Texture2D.MipLevels + desc.Texture2D.MostDetailedMip; + maxSrvMip = (desc.Texture2D.MipLevels == -1) ? INT_MAX : maxSrvMip; + + unsigned mipMin = index.mipIndex; + unsigned mipMax = (layerIndex == -1) ? INT_MAX : layerIndex; + + return type == GL_TEXTURE_2D && + gl::RangeUI(mipMin, mipMax) + .intersects(gl::RangeUI(desc.Texture2D.MostDetailedMip, maxSrvMip)); + } + + case D3D11_SRV_DIMENSION_TEXTURE2DARRAY: + { + unsigned maxSrvMip = + desc.Texture2DArray.MipLevels + desc.Texture2DArray.MostDetailedMip; + maxSrvMip = (desc.Texture2DArray.MipLevels == -1) ? INT_MAX : maxSrvMip; + + unsigned maxSlice = desc.Texture2DArray.FirstArraySlice + desc.Texture2DArray.ArraySize; + + // Cube maps can be mapped to Texture2DArray SRVs + return (type == GL_TEXTURE_2D_ARRAY || gl::IsCubeMapTextureTarget(type)) && + desc.Texture2DArray.MostDetailedMip <= mipLevel && mipLevel < maxSrvMip && + desc.Texture2DArray.FirstArraySlice <= layerIndex && layerIndex < maxSlice; + } + + case D3D11_SRV_DIMENSION_TEXTURECUBE: + { + unsigned maxSrvMip = desc.TextureCube.MipLevels + desc.TextureCube.MostDetailedMip; + maxSrvMip = (desc.TextureCube.MipLevels == -1) ? INT_MAX : maxSrvMip; + + return gl::IsCubeMapTextureTarget(type) && + desc.TextureCube.MostDetailedMip <= mipLevel && mipLevel < maxSrvMip; + } + + case D3D11_SRV_DIMENSION_TEXTURE3D: + { + unsigned maxSrvMip = desc.Texture3D.MipLevels + desc.Texture3D.MostDetailedMip; + maxSrvMip = (desc.Texture3D.MipLevels == -1) ? INT_MAX : maxSrvMip; + + return type == GL_TEXTURE_3D && desc.Texture3D.MostDetailedMip <= mipLevel && + mipLevel < maxSrvMip; + } + default: + // We only handle the cases corresponding to valid image indexes + UNIMPLEMENTED(); + } + + return false; +} + +// Does *not* increment the resource ref count!! +ID3D11Resource *GetViewResource(ID3D11View *view) +{ + ID3D11Resource *resource = NULL; + ASSERT(view); + view->GetResource(&resource); + resource->Release(); + return resource; +} + +} // anonymous namespace + +void StateManager11::SRVCache::update(size_t resourceIndex, ID3D11ShaderResourceView *srv) +{ + ASSERT(resourceIndex < mCurrentSRVs.size()); + SRVRecord *record = &mCurrentSRVs[resourceIndex]; + + record->srv = reinterpret_cast(srv); + if (srv) + { + record->resource = reinterpret_cast(GetViewResource(srv)); + srv->GetDesc(&record->desc); + mHighestUsedSRV = std::max(resourceIndex + 1, mHighestUsedSRV); + } + else + { + record->resource = 0; + + if (resourceIndex + 1 == mHighestUsedSRV) + { + do + { + --mHighestUsedSRV; + } while (mHighestUsedSRV > 0 && mCurrentSRVs[mHighestUsedSRV].srv == 0); + } + } +} + +void StateManager11::SRVCache::clear() +{ + if (mCurrentSRVs.empty()) + { + return; + } + + memset(&mCurrentSRVs[0], 0, sizeof(SRVRecord) * mCurrentSRVs.size()); + mHighestUsedSRV = 0; +} + +static const GLenum QueryTypes[] = {GL_ANY_SAMPLES_PASSED, GL_ANY_SAMPLES_PASSED_CONSERVATIVE, + GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, GL_TIME_ELAPSED_EXT}; + +StateManager11::StateManager11(Renderer11 *renderer) + : mRenderer(renderer), + mBlendStateIsDirty(false), + mCurBlendColor(0, 0, 0, 0), + mCurSampleMask(0), + mDepthStencilStateIsDirty(false), + mCurStencilRef(0), + mCurStencilBackRef(0), + mCurStencilSize(0), + mRasterizerStateIsDirty(false), + mScissorStateIsDirty(false), + mCurScissorEnabled(false), + mCurScissorRect(), + mViewportStateIsDirty(false), + mCurViewport(), + mCurNear(0.0f), + mCurFar(0.0f), + mViewportBounds(), + mRenderTargetIsDirty(false), + mDirtyCurrentValueAttribs(), + mCurrentValueAttribs() +{ + mCurBlendState.blend = false; + mCurBlendState.sourceBlendRGB = GL_ONE; + mCurBlendState.destBlendRGB = GL_ZERO; + mCurBlendState.sourceBlendAlpha = GL_ONE; + mCurBlendState.destBlendAlpha = GL_ZERO; + mCurBlendState.blendEquationRGB = GL_FUNC_ADD; + mCurBlendState.blendEquationAlpha = GL_FUNC_ADD; + mCurBlendState.colorMaskRed = true; + mCurBlendState.colorMaskBlue = true; + mCurBlendState.colorMaskGreen = true; + mCurBlendState.colorMaskAlpha = true; + mCurBlendState.sampleAlphaToCoverage = false; + mCurBlendState.dither = false; + + 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_BACK; + mCurRasterState.frontFace = GL_CCW; + mCurRasterState.polygonOffsetFill = false; + mCurRasterState.polygonOffsetFactor = 0.0f; + mCurRasterState.polygonOffsetUnits = 0.0f; + mCurRasterState.pointDrawMode = false; + mCurRasterState.multiSample = false; + + // Initially all current value attributes must be updated on first use. + mDirtyCurrentValueAttribs.flip(); +} + +StateManager11::~StateManager11() +{ +} + +void StateManager11::updateStencilSizeIfChanged(bool depthStencilInitialized, + unsigned int stencilSize) +{ + if (!depthStencilInitialized || stencilSize != mCurStencilSize) + { + mCurStencilSize = stencilSize; + mDepthStencilStateIsDirty = true; + } +} + +void StateManager11::setViewportBounds(const int width, const int height) +{ + if (mRenderer->getRenderer11DeviceCaps().featureLevel <= D3D_FEATURE_LEVEL_9_3 && + (mViewportBounds.width != width || mViewportBounds.height != height)) + { + mViewportBounds = gl::Extents(width, height, 1); + mViewportStateIsDirty = true; + } +} + +void StateManager11::updatePresentPath(bool presentPathFastActive, + const gl::FramebufferAttachment *framebufferAttachment) +{ + const int colorBufferHeight = + framebufferAttachment ? framebufferAttachment->getSize().height : 0; + + if ((mCurPresentPathFastEnabled != presentPathFastActive) || + (presentPathFastActive && (colorBufferHeight != mCurPresentPathFastColorBufferHeight))) + { + mCurPresentPathFastEnabled = presentPathFastActive; + mCurPresentPathFastColorBufferHeight = colorBufferHeight; + mViewportStateIsDirty = true; // Viewport may need to be vertically inverted + mScissorStateIsDirty = true; // Scissor rect may need to be vertically inverted + mRasterizerStateIsDirty = true; // Cull Mode may need to be inverted + } +} + +void StateManager11::syncState(const gl::State &state, const gl::State::DirtyBits &dirtyBits) +{ + if (!dirtyBits.any()) + { + return; + } + + for (auto dirtyBit : angle::IterateBitSet(dirtyBits)) + { + switch (dirtyBit) + { + case gl::State::DIRTY_BIT_BLEND_EQUATIONS: + { + const gl::BlendState &blendState = state.getBlendState(); + if (blendState.blendEquationRGB != mCurBlendState.blendEquationRGB || + blendState.blendEquationAlpha != mCurBlendState.blendEquationAlpha) + { + mBlendStateIsDirty = true; + } + 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) + { + mBlendStateIsDirty = true; + } + break; + } + case gl::State::DIRTY_BIT_BLEND_ENABLED: + if (state.getBlendState().blend != mCurBlendState.blend) + { + mBlendStateIsDirty = true; + } + break; + case gl::State::DIRTY_BIT_SAMPLE_ALPHA_TO_COVERAGE_ENABLED: + if (state.getBlendState().sampleAlphaToCoverage != + mCurBlendState.sampleAlphaToCoverage) + { + mBlendStateIsDirty = true; + } + break; + case gl::State::DIRTY_BIT_DITHER_ENABLED: + if (state.getBlendState().dither != mCurBlendState.dither) + { + mBlendStateIsDirty = true; + } + 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) + { + mBlendStateIsDirty = true; + } + break; + } + case gl::State::DIRTY_BIT_BLEND_COLOR: + if (state.getBlendColor() != mCurBlendColor) + { + mBlendStateIsDirty = true; + } + break; + case gl::State::DIRTY_BIT_DEPTH_MASK: + if (state.getDepthStencilState().depthMask != mCurDepthStencilState.depthMask) + { + mDepthStencilStateIsDirty = true; + } + break; + case gl::State::DIRTY_BIT_DEPTH_TEST_ENABLED: + if (state.getDepthStencilState().depthTest != mCurDepthStencilState.depthTest) + { + mDepthStencilStateIsDirty = true; + } + break; + case gl::State::DIRTY_BIT_DEPTH_FUNC: + if (state.getDepthStencilState().depthFunc != mCurDepthStencilState.depthFunc) + { + mDepthStencilStateIsDirty = true; + } + break; + case gl::State::DIRTY_BIT_STENCIL_TEST_ENABLED: + if (state.getDepthStencilState().stencilTest != mCurDepthStencilState.stencilTest) + { + mDepthStencilStateIsDirty = true; + } + break; + case gl::State::DIRTY_BIT_STENCIL_FUNCS_FRONT: + { + const gl::DepthStencilState &depthStencil = state.getDepthStencilState(); + if (depthStencil.stencilFunc != mCurDepthStencilState.stencilFunc || + depthStencil.stencilMask != mCurDepthStencilState.stencilMask || + state.getStencilRef() != mCurStencilRef) + { + mDepthStencilStateIsDirty = true; + } + break; + } + case gl::State::DIRTY_BIT_STENCIL_FUNCS_BACK: + { + const gl::DepthStencilState &depthStencil = state.getDepthStencilState(); + if (depthStencil.stencilBackFunc != mCurDepthStencilState.stencilBackFunc || + depthStencil.stencilBackMask != mCurDepthStencilState.stencilBackMask || + state.getStencilBackRef() != mCurStencilBackRef) + { + mDepthStencilStateIsDirty = true; + } + break; + } + case gl::State::DIRTY_BIT_STENCIL_WRITEMASK_FRONT: + if (state.getDepthStencilState().stencilWritemask != + mCurDepthStencilState.stencilWritemask) + { + mDepthStencilStateIsDirty = true; + } + break; + case gl::State::DIRTY_BIT_STENCIL_WRITEMASK_BACK: + if (state.getDepthStencilState().stencilBackWritemask != + mCurDepthStencilState.stencilBackWritemask) + { + mDepthStencilStateIsDirty = true; + } + break; + case gl::State::DIRTY_BIT_STENCIL_OPS_FRONT: + { + const gl::DepthStencilState &depthStencil = state.getDepthStencilState(); + if (depthStencil.stencilFail != mCurDepthStencilState.stencilFail || + depthStencil.stencilPassDepthFail != + mCurDepthStencilState.stencilPassDepthFail || + depthStencil.stencilPassDepthPass != mCurDepthStencilState.stencilPassDepthPass) + { + mDepthStencilStateIsDirty = true; + } + break; + } + case gl::State::DIRTY_BIT_STENCIL_OPS_BACK: + { + const gl::DepthStencilState &depthStencil = state.getDepthStencilState(); + if (depthStencil.stencilBackFail != mCurDepthStencilState.stencilBackFail || + depthStencil.stencilBackPassDepthFail != + mCurDepthStencilState.stencilBackPassDepthFail || + depthStencil.stencilBackPassDepthPass != + mCurDepthStencilState.stencilBackPassDepthPass) + { + mDepthStencilStateIsDirty = true; + } + break; + } + case gl::State::DIRTY_BIT_CULL_FACE_ENABLED: + if (state.getRasterizerState().cullFace != mCurRasterState.cullFace) + { + mRasterizerStateIsDirty = true; + } + break; + case gl::State::DIRTY_BIT_CULL_FACE: + if (state.getRasterizerState().cullMode != mCurRasterState.cullMode) + { + mRasterizerStateIsDirty = true; + } + break; + case gl::State::DIRTY_BIT_FRONT_FACE: + if (state.getRasterizerState().frontFace != mCurRasterState.frontFace) + { + mRasterizerStateIsDirty = true; + } + break; + case gl::State::DIRTY_BIT_POLYGON_OFFSET_FILL_ENABLED: + if (state.getRasterizerState().polygonOffsetFill != + mCurRasterState.polygonOffsetFill) + { + mRasterizerStateIsDirty = true; + } + break; + case gl::State::DIRTY_BIT_POLYGON_OFFSET: + { + const gl::RasterizerState &rasterState = state.getRasterizerState(); + if (rasterState.polygonOffsetFactor != mCurRasterState.polygonOffsetFactor || + rasterState.polygonOffsetUnits != mCurRasterState.polygonOffsetUnits) + { + mRasterizerStateIsDirty = true; + } + break; + } + case gl::State::DIRTY_BIT_RASTERIZER_DISCARD_ENABLED: + if (state.getRasterizerState().rasterizerDiscard != + mCurRasterState.rasterizerDiscard) + { + mRasterizerStateIsDirty = true; + } + break; + case gl::State::DIRTY_BIT_SCISSOR: + if (state.getScissor() != mCurScissorRect) + { + mScissorStateIsDirty = true; + } + break; + case gl::State::DIRTY_BIT_SCISSOR_TEST_ENABLED: + if (state.isScissorTestEnabled() != mCurScissorEnabled) + { + mScissorStateIsDirty = true; + // Rasterizer state update needs mCurScissorsEnabled and updates when it changes + mRasterizerStateIsDirty = true; + } + break; + case gl::State::DIRTY_BIT_DEPTH_RANGE: + if (state.getNearPlane() != mCurNear || state.getFarPlane() != mCurFar) + { + mViewportStateIsDirty = true; + } + break; + case gl::State::DIRTY_BIT_VIEWPORT: + if (state.getViewport() != mCurViewport) + { + mViewportStateIsDirty = true; + } + break; + case gl::State::DIRTY_BIT_DRAW_FRAMEBUFFER_BINDING: + mRenderTargetIsDirty = true; + break; + default: + if (dirtyBit >= gl::State::DIRTY_BIT_CURRENT_VALUE_0 && + dirtyBit < gl::State::DIRTY_BIT_CURRENT_VALUE_MAX) + { + size_t attribIndex = + static_cast(dirtyBit - gl::State::DIRTY_BIT_CURRENT_VALUE_0); + mDirtyCurrentValueAttribs.set(attribIndex); + } + break; + } + } +} + +gl::Error StateManager11::setBlendState(const gl::Framebuffer *framebuffer, + const gl::BlendState &blendState, + const gl::ColorF &blendColor, + unsigned int sampleMask) +{ + if (!mBlendStateIsDirty && sampleMask == mCurSampleMask) + { + return gl::Error(GL_NO_ERROR); + } + + ID3D11BlendState *dxBlendState = nullptr; + gl::Error error = + mRenderer->getStateCache().getBlendState(framebuffer, blendState, &dxBlendState); + if (error.isError()) + { + return error; + } + + ASSERT(dxBlendState != nullptr); + + float blendColors[4] = {0.0f}; + 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) + { + blendColors[0] = blendColor.red; + blendColors[1] = blendColor.green; + blendColors[2] = blendColor.blue; + blendColors[3] = blendColor.alpha; + } + else + { + blendColors[0] = blendColor.alpha; + blendColors[1] = blendColor.alpha; + blendColors[2] = blendColor.alpha; + blendColors[3] = blendColor.alpha; + } + + mRenderer->getDeviceContext()->OMSetBlendState(dxBlendState, blendColors, sampleMask); + + mCurBlendState = blendState; + mCurBlendColor = blendColor; + mCurSampleMask = sampleMask; + + mBlendStateIsDirty = false; + + return error; +} + +gl::Error StateManager11::setDepthStencilState(const gl::State &glState) +{ + const auto &fbo = *glState.getDrawFramebuffer(); + + // 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()); + + // CurDisableDepth/Stencil are reset automatically after we call forceSetDepthStencilState. + if (!mDepthStencilStateIsDirty && mCurDisableDepth.valid() && + disableDepth == mCurDisableDepth.value() && mCurDisableStencil.valid() && + disableStencil == mCurDisableStencil.value()) + { + return gl::Error(GL_NO_ERROR); + } + + const auto &depthStencilState = glState.getDepthStencilState(); + int stencilRef = glState.getStencilRef(); + int stencilBackRef = glState.getStencilBackRef(); + + // get the maximum size of the stencil ref + unsigned int maxStencil = 0; + if (depthStencilState.stencilTest && mCurStencilSize > 0) + { + maxStencil = (1 << mCurStencilSize) - 1; + } + ASSERT((depthStencilState.stencilWritemask & maxStencil) == + (depthStencilState.stencilBackWritemask & maxStencil)); + ASSERT(stencilRef == stencilBackRef); + ASSERT((depthStencilState.stencilMask & maxStencil) == + (depthStencilState.stencilBackMask & maxStencil)); + + ID3D11DepthStencilState *dxDepthStencilState = NULL; + gl::Error error = mRenderer->getStateCache().getDepthStencilState( + depthStencilState, disableDepth, disableStencil, &dxDepthStencilState); + if (error.isError()) + { + return error; + } + + ASSERT(dxDepthStencilState); + + // 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 = std::min(stencilRef, 0xFFu); + + mRenderer->getDeviceContext()->OMSetDepthStencilState(dxDepthStencilState, dxStencilRef); + + mCurDepthStencilState = depthStencilState; + mCurStencilRef = stencilRef; + mCurStencilBackRef = stencilBackRef; + mCurDisableDepth = disableDepth; + mCurDisableStencil = disableStencil; + + mDepthStencilStateIsDirty = false; + + return gl::Error(GL_NO_ERROR); +} + +gl::Error StateManager11::setRasterizerState(const gl::RasterizerState &rasterState) +{ + // TODO: Remove pointDrawMode and multiSample from gl::RasterizerState. + if (!mRasterizerStateIsDirty && rasterState.pointDrawMode == mCurRasterState.pointDrawMode && + rasterState.multiSample == mCurRasterState.multiSample) + { + return gl::Error(GL_NO_ERROR); + } + + ID3D11RasterizerState *dxRasterState = nullptr; + gl::Error error(GL_NO_ERROR); + + 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; + } + + error = mRenderer->getStateCache().getRasterizerState(modifiedRasterState, + mCurScissorEnabled, &dxRasterState); + } + else + { + error = mRenderer->getStateCache().getRasterizerState(rasterState, mCurScissorEnabled, + &dxRasterState); + } + + if (error.isError()) + { + return error; + } + + mRenderer->getDeviceContext()->RSSetState(dxRasterState); + + mCurRasterState = rasterState; + mRasterizerStateIsDirty = false; + + return error; +} + +void StateManager11::setScissorRectangle(const gl::Rectangle &scissor, bool enabled) +{ + if (!mScissorStateIsDirty) + return; + + int modifiedScissorY = scissor.y; + if (mCurPresentPathFastEnabled) + { + modifiedScissorY = mCurPresentPathFastColorBufferHeight - scissor.height - scissor.y; + } + + if (enabled) + { + D3D11_RECT rect; + rect.left = std::max(0, scissor.x); + rect.top = std::max(0, modifiedScissorY); + rect.right = scissor.x + std::max(0, scissor.width); + rect.bottom = modifiedScissorY + std::max(0, scissor.height); + + mRenderer->getDeviceContext()->RSSetScissorRects(1, &rect); + } + + mCurScissorRect = scissor; + mCurScissorEnabled = enabled; + mScissorStateIsDirty = false; +} + +void StateManager11::setViewport(const gl::Caps *caps, + const gl::Rectangle &viewport, + float zNear, + float zFar) +{ + if (!mViewportStateIsDirty) + return; + + float actualZNear = gl::clamp01(zNear); + float actualZFar = gl::clamp01(zFar); + + int dxMaxViewportBoundsX = static_cast(caps->maxViewportWidth); + int dxMaxViewportBoundsY = static_cast(caps->maxViewportHeight); + int dxMinViewportBoundsX = -dxMaxViewportBoundsX; + int dxMinViewportBoundsY = -dxMaxViewportBoundsY; + + if (mRenderer->getRenderer11DeviceCaps().featureLevel <= D3D_FEATURE_LEVEL_9_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; + } + + int dxViewportTopLeftX = gl::clamp(viewport.x, dxMinViewportBoundsX, dxMaxViewportBoundsX); + int dxViewportTopLeftY = gl::clamp(viewport.y, dxMinViewportBoundsY, dxMaxViewportBoundsY); + int dxViewportWidth = gl::clamp(viewport.width, 0, dxMaxViewportBoundsX - dxViewportTopLeftX); + int dxViewportHeight = gl::clamp(viewport.height, 0, dxMaxViewportBoundsY - dxViewportTopLeftY); + + D3D11_VIEWPORT dxViewport; + dxViewport.TopLeftX = static_cast(dxViewportTopLeftX); + + if (mCurPresentPathFastEnabled) + { + // 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); + } + + 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; + + // On Feature Level 9_*, we must emulate large and/or negative viewports in the shaders + // using viewAdjust (like the D3D9 renderer). + if (mRenderer->getRenderer11DeviceCaps().featureLevel <= D3D_FEATURE_LEVEL_9_3) + { + mVertexConstants.viewAdjust[0] = static_cast((viewport.width - dxViewportWidth) + + 2 * (viewport.x - dxViewportTopLeftX)) / + dxViewport.Width; + mVertexConstants.viewAdjust[1] = static_cast((viewport.height - dxViewportHeight) + + 2 * (viewport.y - dxViewportTopLeftY)) / + dxViewport.Height; + mVertexConstants.viewAdjust[2] = static_cast(viewport.width) / dxViewport.Width; + mVertexConstants.viewAdjust[3] = static_cast(viewport.height) / dxViewport.Height; + } + + mPixelConstants.viewCoords[0] = viewport.width * 0.5f; + mPixelConstants.viewCoords[1] = viewport.height * 0.5f; + mPixelConstants.viewCoords[2] = viewport.x + (viewport.width * 0.5f); + mPixelConstants.viewCoords[3] = viewport.y + (viewport.height * 0.5f); + + // Instanced pointsprite emulation requires ViewCoords to be defined in the + // the vertex shader. + mVertexConstants.viewCoords[0] = mPixelConstants.viewCoords[0]; + mVertexConstants.viewCoords[1] = mPixelConstants.viewCoords[1]; + mVertexConstants.viewCoords[2] = mPixelConstants.viewCoords[2]; + mVertexConstants.viewCoords[3] = mPixelConstants.viewCoords[3]; + + mPixelConstants.depthFront[0] = (actualZFar - actualZNear) * 0.5f; + mPixelConstants.depthFront[1] = (actualZNear + actualZFar) * 0.5f; + + mVertexConstants.depthRange[0] = actualZNear; + mVertexConstants.depthRange[1] = actualZFar; + mVertexConstants.depthRange[2] = actualZFar - actualZNear; + + mPixelConstants.depthRange[0] = actualZNear; + mPixelConstants.depthRange[1] = actualZFar; + mPixelConstants.depthRange[2] = actualZFar - actualZNear; + + mPixelConstants.viewScale[0] = 1.0f; + mPixelConstants.viewScale[1] = mCurPresentPathFastEnabled ? 1.0f : -1.0f; + mPixelConstants.viewScale[2] = 1.0f; + mPixelConstants.viewScale[3] = 1.0f; + + mVertexConstants.viewScale[0] = mPixelConstants.viewScale[0]; + mVertexConstants.viewScale[1] = mPixelConstants.viewScale[1]; + mVertexConstants.viewScale[2] = mPixelConstants.viewScale[2]; + mVertexConstants.viewScale[3] = mPixelConstants.viewScale[3]; + + mViewportStateIsDirty = false; +} + +void StateManager11::invalidateRenderTarget() +{ + mRenderTargetIsDirty = true; +} + +void StateManager11::invalidateBoundViews() +{ + mCurVertexSRVs.clear(); + mCurPixelSRVs.clear(); + + invalidateRenderTarget(); +} + +void StateManager11::invalidateEverything() +{ + mBlendStateIsDirty = true; + mDepthStencilStateIsDirty = true; + mRasterizerStateIsDirty = true; + mScissorStateIsDirty = true; + mViewportStateIsDirty = true; + + // We reset the current SRV data because it might not be in sync with D3D's state + // anymore. For example when a currently used SRV is used as an RTV, D3D silently + // remove it from its state. + invalidateBoundViews(); +} + +void StateManager11::setOneTimeRenderTarget(ID3D11RenderTargetView *renderTarget, + ID3D11DepthStencilView *depthStencil) +{ + mRenderer->getDeviceContext()->OMSetRenderTargets(1, &renderTarget, depthStencil); + mRenderTargetIsDirty = true; +} + +void StateManager11::setOneTimeRenderTargets( + const std::vector &renderTargets, + ID3D11DepthStencilView *depthStencil) +{ + UINT count = static_cast(renderTargets.size()); + auto renderTargetPointer = (!renderTargets.empty() ? renderTargets.data() : nullptr); + + mRenderer->getDeviceContext()->OMSetRenderTargets(count, renderTargetPointer, depthStencil); + mRenderTargetIsDirty = true; +} + +void StateManager11::onBeginQuery(Query11 *query) +{ + mCurrentQueries.insert(query); +} + +void StateManager11::onDeleteQueryObject(Query11 *query) +{ + mCurrentQueries.erase(query); +} + +gl::Error StateManager11::onMakeCurrent(const gl::Data &data) +{ + const gl::State &state = *data.state; + + for (Query11 *query : mCurrentQueries) + { + query->pause(); + } + mCurrentQueries.clear(); + + for (GLenum queryType : QueryTypes) + { + gl::Query *query = state.getActiveQuery(queryType); + if (query != nullptr) + { + Query11 *query11 = GetImplAs(query); + query11->resume(); + mCurrentQueries.insert(query11); + } + } + + return gl::Error(GL_NO_ERROR); +} + +void StateManager11::setShaderResource(gl::SamplerType shaderType, + UINT resourceSlot, + ID3D11ShaderResourceView *srv) +{ + auto ¤tSRVs = (shaderType == gl::SAMPLER_VERTEX ? mCurVertexSRVs : mCurPixelSRVs); + + ASSERT(static_cast(resourceSlot) < currentSRVs.size()); + const SRVRecord &record = currentSRVs[resourceSlot]; + + if (record.srv != reinterpret_cast(srv)) + { + auto deviceContext = mRenderer->getDeviceContext(); + if (shaderType == gl::SAMPLER_VERTEX) + { + deviceContext->VSSetShaderResources(resourceSlot, 1, &srv); + } + else + { + deviceContext->PSSetShaderResources(resourceSlot, 1, &srv); + } + + currentSRVs.update(resourceSlot, srv); + } +} + +gl::Error StateManager11::clearTextures(gl::SamplerType samplerType, + size_t rangeStart, + size_t rangeEnd) +{ + if (rangeStart == rangeEnd) + { + return gl::Error(GL_NO_ERROR); + } + + auto ¤tSRVs = (samplerType == gl::SAMPLER_VERTEX ? mCurVertexSRVs : mCurPixelSRVs); + + gl::Range clearRange(rangeStart, rangeStart); + clearRange.extend(std::min(rangeEnd, currentSRVs.highestUsed())); + + if (clearRange.empty()) + { + return gl::Error(GL_NO_ERROR); + } + + auto deviceContext = mRenderer->getDeviceContext(); + if (samplerType == gl::SAMPLER_VERTEX) + { + deviceContext->VSSetShaderResources(static_cast(rangeStart), + static_cast(rangeEnd - rangeStart), + &mNullSRVs[0]); + } + else + { + deviceContext->PSSetShaderResources(static_cast(rangeStart), + static_cast(rangeEnd - rangeStart), + &mNullSRVs[0]); + } + + for (size_t samplerIndex = rangeStart; samplerIndex < rangeEnd; ++samplerIndex) + { + currentSRVs.update(samplerIndex, nullptr); + } + + return gl::Error(GL_NO_ERROR); +} + +void StateManager11::unsetConflictingSRVs(gl::SamplerType samplerType, + uintptr_t resource, + const gl::ImageIndex &index) +{ + auto ¤tSRVs = (samplerType == gl::SAMPLER_VERTEX ? mCurVertexSRVs : mCurPixelSRVs); + + for (size_t resourceIndex = 0; resourceIndex < currentSRVs.size(); ++resourceIndex) + { + auto &record = currentSRVs[resourceIndex]; + + if (record.srv && record.resource == resource && + ImageIndexConflictsWithSRV(index, record.desc)) + { + setShaderResource(samplerType, static_cast(resourceIndex), NULL); + } + } +} + +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::SAMPLER_VERTEX, resourcePtr, index); + unsetConflictingSRVs(gl::SAMPLER_PIXEL, resourcePtr, index); + } +} + +void StateManager11::initialize(const gl::Caps &caps) +{ + mCurVertexSRVs.initialize(caps.maxVertexTextureImageUnits); + mCurPixelSRVs.initialize(caps.maxTextureImageUnits); + + // Initialize cached NULL SRV block + mNullSRVs.resize(caps.maxTextureImageUnits, nullptr); + + mCurrentValueAttribs.resize(caps.maxVertexAttributes); +} + +void StateManager11::deinitialize() +{ + mCurrentValueAttribs.clear(); +} + +gl::Error StateManager11::syncFramebuffer(const gl::Framebuffer *framebuffer) +{ + const Framebuffer11 *framebuffer11 = GetImplAs(framebuffer); + gl::Error error = framebuffer11->invalidateSwizzles(); + if (error.isError()) + { + return error; + } + + if (framebuffer11->hasAnyInternalDirtyBit()) + { + ASSERT(framebuffer->id() != 0); + framebuffer11->syncInternalState(); + } + + if (!mRenderTargetIsDirty) + { + return gl::Error(GL_NO_ERROR); + } + + mRenderTargetIsDirty = false; + + // 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 (framebuffer->id() == 0) + { + ASSERT(!framebuffer11->hasAnyInternalDirtyBit()); + const gl::Extents &size = framebuffer->getFirstColorbuffer()->getSize(); + if (size.width == 0 || size.height == 0) + { + return gl::Error(GL_NO_ERROR); + } + } + + // Get the color render buffer and serial + // Also extract the render target dimensions and view + unsigned int renderTargetWidth = 0; + unsigned int renderTargetHeight = 0; + RTVArray framebufferRTVs; + bool missingColorRenderTarget = true; + + framebufferRTVs.fill(nullptr); + + const auto &colorRTs = framebuffer11->getCachedColorRenderTargets(); + + size_t appliedRTIndex = 0; + bool skipInactiveRTs = mRenderer->getWorkarounds().mrtPerfWorkaround; + const auto &drawStates = framebuffer->getDrawBufferStates(); + + 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)) + { + continue; + } + + if (renderTarget) + { + framebufferRTVs[appliedRTIndex] = renderTarget->getRenderTargetView(); + ASSERT(framebufferRTVs[appliedRTIndex]); + + if (missingColorRenderTarget) + { + renderTargetWidth = renderTarget->getWidth(); + renderTargetHeight = renderTarget->getHeight(); + missingColorRenderTarget = false; + } + } + + // Unset conflicting texture SRVs + const auto *attachment = framebuffer->getColorbuffer(rtIndex); + ASSERT(attachment); + unsetConflictingAttachmentResources(attachment, renderTarget->getTexture()); + + appliedRTIndex++; + } + + // Get the depth stencil buffers + ID3D11DepthStencilView *framebufferDSV = nullptr; + const auto *depthStencilRenderTarget = framebuffer11->getCachedDepthStencilRenderTarget(); + if (depthStencilRenderTarget) + { + framebufferDSV = depthStencilRenderTarget->getDepthStencilView(); + ASSERT(framebufferDSV); + + // If there is no render buffer, the width, height and format values come from + // the depth stencil + if (missingColorRenderTarget) + { + renderTargetWidth = depthStencilRenderTarget->getWidth(); + renderTargetHeight = depthStencilRenderTarget->getHeight(); + } + + // Unset conflicting texture SRVs + const auto *attachment = framebuffer->getDepthOrStencilbuffer(); + ASSERT(attachment); + unsetConflictingAttachmentResources(attachment, depthStencilRenderTarget->getTexture()); + } + + // TODO(jmadill): Use context caps? + UINT drawBuffers = mRenderer->getRendererCaps().maxDrawBuffers; + + // Apply the render target and depth stencil + mRenderer->getDeviceContext()->OMSetRenderTargets(drawBuffers, framebufferRTVs.data(), + framebufferDSV); + + // The D3D11 blend state is heavily dependent on the current render target. + mBlendStateIsDirty = true; + + setViewportBounds(renderTargetWidth, renderTargetHeight); + + return gl::Error(GL_NO_ERROR); +} + +gl::Error StateManager11::updateCurrentValueAttribs(const gl::State &state, + VertexDataManager *vertexDataManager) +{ + const auto &activeAttribsMask = state.getProgram()->getActiveAttribLocationsMask(); + const auto &dirtyActiveAttribs = (activeAttribsMask & mDirtyCurrentValueAttribs); + const auto &vertexAttributes = state.getVertexArray()->getVertexAttributes(); + + for (auto attribIndex : angle::IterateBitSet(dirtyActiveAttribs)) + { + if (vertexAttributes[attribIndex].enabled) + continue; + + mDirtyCurrentValueAttribs.reset(attribIndex); + + const auto ¤tValue = + state.getVertexAttribCurrentValue(static_cast(attribIndex)); + auto currentValueAttrib = &mCurrentValueAttribs[attribIndex]; + currentValueAttrib->currentValueType = currentValue.Type; + currentValueAttrib->attribute = &vertexAttributes[attribIndex]; + + gl::Error error = vertexDataManager->storeCurrentValue(currentValue, currentValueAttrib, + static_cast(attribIndex)); + if (error.isError()) + { + return error; + } + } + + return gl::Error(GL_NO_ERROR); +} + +const std::vector &StateManager11::getCurrentValueAttribs() const +{ + return mCurrentValueAttribs; +} + +} // namespace rx diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/StateManager11.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/StateManager11.h new file mode 100644 index 000000000000..c926ccde57e0 --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/StateManager11.h @@ -0,0 +1,202 @@ +// +// Copyright (c) 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/angletypes.h" +#include "libANGLE/Data.h" +#include "libANGLE/State.h" +#include "libANGLE/renderer/d3d/d3d11/RenderStateCache.h" +#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h" +#include "libANGLE/renderer/d3d/d3d11/Query11.h" +#include "libANGLE/renderer/d3d/RendererD3D.h" + +namespace rx +{ + +struct RenderTargetDesc; +struct Renderer11DeviceCaps; + +struct dx_VertexConstants11 +{ + float depthRange[4]; + float viewAdjust[4]; + float viewCoords[4]; + float viewScale[4]; +}; + +struct dx_PixelConstants11 +{ + float depthRange[4]; + float viewCoords[4]; + float depthFront[4]; + float viewScale[4]; +}; + +class StateManager11 final : angle::NonCopyable +{ + public: + StateManager11(Renderer11 *renderer); + ~StateManager11(); + + void initialize(const gl::Caps &caps); + void deinitialize(); + void syncState(const gl::State &state, const gl::State::DirtyBits &dirtyBits); + + gl::Error setBlendState(const gl::Framebuffer *framebuffer, + const gl::BlendState &blendState, + const gl::ColorF &blendColor, + unsigned int sampleMask); + + gl::Error setDepthStencilState(const gl::State &glState); + + gl::Error setRasterizerState(const gl::RasterizerState &rasterState); + + void setScissorRectangle(const gl::Rectangle &scissor, bool enabled); + + void setViewport(const gl::Caps *caps, const gl::Rectangle &viewport, float zNear, float zFar); + + void updatePresentPath(bool presentPathFastActive, + const gl::FramebufferAttachment *framebufferAttachment); + + const dx_VertexConstants11 &getVertexConstants() const { return mVertexConstants; } + const dx_PixelConstants11 &getPixelConstants() const { return mPixelConstants; } + + void updateStencilSizeIfChanged(bool depthStencilInitialized, unsigned int stencilSize); + + void setShaderResource(gl::SamplerType shaderType, + UINT resourceSlot, + ID3D11ShaderResourceView *srv); + gl::Error clearTextures(gl::SamplerType samplerType, size_t rangeStart, size_t rangeEnd); + + gl::Error syncFramebuffer(const gl::Framebuffer *framebuffer); + + void invalidateRenderTarget(); + void invalidateBoundViews(); + void invalidateEverything(); + + void setOneTimeRenderTarget(ID3D11RenderTargetView *renderTarget, + ID3D11DepthStencilView *depthStencil); + void setOneTimeRenderTargets(const std::vector &renderTargets, + ID3D11DepthStencilView *depthStencil); + + void onBeginQuery(Query11 *query); + void onDeleteQueryObject(Query11 *query); + gl::Error onMakeCurrent(const gl::Data &data); + + gl::Error updateCurrentValueAttribs(const gl::State &state, + VertexDataManager *vertexDataManager); + + const std::vector &getCurrentValueAttribs() const; + + private: + void setViewportBounds(const int width, const int height); + void unsetConflictingSRVs(gl::SamplerType shaderType, + uintptr_t resource, + const gl::ImageIndex &index); + void unsetConflictingAttachmentResources(const gl::FramebufferAttachment *attachment, + ID3D11Resource *resource); + + Renderer11 *mRenderer; + + // Blend State + bool mBlendStateIsDirty; + // TODO(dianx) temporary representation of a dirty bit. once we move enough states in, + // try experimenting with dirty bit instead of a bool + gl::BlendState mCurBlendState; + gl::ColorF mCurBlendColor; + unsigned int mCurSampleMask; + + // Currently applied depth stencil state + bool mDepthStencilStateIsDirty; + gl::DepthStencilState mCurDepthStencilState; + int mCurStencilRef; + int mCurStencilBackRef; + unsigned int mCurStencilSize; + Optional mCurDisableDepth; + Optional mCurDisableStencil; + + // Currently applied rasterizer state + bool mRasterizerStateIsDirty; + gl::RasterizerState mCurRasterState; + + // Currently applied scissor rectangle state + bool mScissorStateIsDirty; + bool mCurScissorEnabled; + gl::Rectangle mCurScissorRect; + + // Currently applied viewport state + bool mViewportStateIsDirty; + gl::Rectangle mCurViewport; + float mCurNear; + float mCurFar; + + // Things needed in viewport state + dx_VertexConstants11 mVertexConstants; + dx_PixelConstants11 mPixelConstants; + + // Render target variables + gl::Extents mViewportBounds; + + // EGL_ANGLE_experimental_present_path variables + bool mCurPresentPathFastEnabled; + int mCurPresentPathFastColorBufferHeight; + + // Current RenderTarget state + bool mRenderTargetIsDirty; + + // Queries that are currently active in this state + std::set mCurrentQueries; + + // Currently applied textures + struct SRVRecord + { + uintptr_t srv; + uintptr_t resource; + D3D11_SHADER_RESOURCE_VIEW_DESC desc; + }; + + // A cache of current SRVs that also tracks the highest 'used' (non-NULL) SRV + // We might want to investigate a more robust approach that is also fast when there's + // a large gap between used SRVs (e.g. if SRV 0 and 7 are non-NULL, this approach will + // waste time on SRVs 1-6.) + class SRVCache : angle::NonCopyable + { + public: + SRVCache() : mHighestUsedSRV(0) {} + + void initialize(size_t size) { mCurrentSRVs.resize(size); } + + size_t size() const { return mCurrentSRVs.size(); } + size_t highestUsed() const { return mHighestUsedSRV; } + + const SRVRecord &operator[](size_t index) const { return mCurrentSRVs[index]; } + void clear(); + void update(size_t resourceIndex, ID3D11ShaderResourceView *srv); + + private: + std::vector mCurrentSRVs; + size_t mHighestUsedSRV; + }; + + SRVCache mCurVertexSRVs; + SRVCache mCurPixelSRVs; + + // A block of NULL pointers, cached so we don't re-allocate every draw call + std::vector mNullSRVs; + + // Current translations of "Current-Value" data - owned by Context, not VertexArray. + gl::AttributesMask mDirtyCurrentValueAttribs; + std::vector mCurrentValueAttribs; +}; + +} // namespace rx +#endif // LIBANGLE_RENDERER_D3D11_STATEMANAGER11_H_ diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/Stream11.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/Stream11.cpp new file mode 100644 index 000000000000..9dba705d922a --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/Stream11.cpp @@ -0,0 +1,26 @@ +// +// Copyright (c) 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. +// + +// Stream11.cpp: Defines the rx::Stream11 class which implements rx::StreamImpl. + +#include "libANGLE/renderer/d3d/d3d11/Stream11.h" + +#include "common/utilities.h" +#include "libANGLE/renderer/d3d/d3d11/Renderer11.h" +#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h" + +namespace rx +{ + +Stream11::Stream11(Renderer11 *renderer) : mRenderer(renderer) +{ + UNUSED_VARIABLE(mRenderer); +} + +Stream11::~Stream11() +{ +} +} // namespace rx diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/Stream11.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/Stream11.h new file mode 100644 index 000000000000..5a971f5121e0 --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/Stream11.h @@ -0,0 +1,29 @@ +// +// Copyright (c) 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. +// + +// Stream11.h: Defines the rx::Stream11 class which implements rx::StreamImpl. + +#ifndef LIBANGLE_RENDERER_D3D_D3D11_STREAM11_H_ +#define LIBANGLE_RENDERER_D3D_D3D11_STREAM11_H_ + +#include "libANGLE/renderer/StreamImpl.h" + +namespace rx +{ +class Renderer11; + +class Stream11 : public StreamImpl +{ + public: + Stream11(Renderer11 *renderer); + ~Stream11() override; + + private: + Renderer11 *mRenderer; +}; +} // namespace rx + +#endif // LIBANGLE_RENDERER_D3D_D3D11_STREAM11_H_ diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp index b15cfb88eb61..4b308cc3a223 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp @@ -8,46 +8,79 @@ #include "libANGLE/renderer/d3d/d3d11/SwapChain11.h" +#include + #include "libANGLE/features.h" +#include "libANGLE/renderer/d3d/d3d11/formatutils11.h" #include "libANGLE/renderer/d3d/d3d11/NativeWindow.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 "third_party/trace_event/trace_event.h" // Precompiled shaders #include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthrough2d11vs.h" #include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2d11ps.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 { -SwapChain11::SwapChain11(Renderer11 *renderer, NativeWindow nativeWindow, HANDLE shareHandle, - GLenum backBufferFormat, GLenum depthBufferFormat) - : mRenderer(renderer), - SwapChainD3D(nativeWindow, shareHandle, backBufferFormat, depthBufferFormat), +namespace +{ +bool NeedsOffscreenTexture(Renderer11 *renderer, NativeWindow 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, + NativeWindow nativeWindow, + HANDLE shareHandle, + GLenum backBufferFormat, + GLenum depthBufferFormat, + EGLint orientation) + : SwapChainD3D(nativeWindow, shareHandle, backBufferFormat, depthBufferFormat), + mRenderer(renderer), + mWidth(-1), + mHeight(-1), + mOrientation(orientation), + mAppCreatedShareHandle(mShareHandle != nullptr), + mSwapInterval(0), + mPassThroughResourcesInit(false), + mFirstSwap(true), + mSwapChain(nullptr), + mSwapChain1(nullptr), + mKeyedMutex(nullptr), + mBackBufferTexture(nullptr), + mBackBufferRTView(nullptr), + mBackBufferSRView(nullptr), + mNeedsOffscreenTexture(NeedsOffscreenTexture(renderer, nativeWindow, orientation)), + mOffscreenTexture(nullptr), + mOffscreenRTView(nullptr), + mOffscreenSRView(nullptr), + mDepthStencilTexture(nullptr), + mDepthStencilDSView(nullptr), + mDepthStencilSRView(nullptr), + mQuadVB(nullptr), + mPassThroughSampler(nullptr), + mPassThroughIL(nullptr), + mPassThroughVS(nullptr), + mPassThroughPS(nullptr), + mPassThroughRS(nullptr), mColorRenderTarget(this, renderer, false), mDepthStencilRenderTarget(this, renderer, true) { - mSwapChain = NULL; - mBackBufferTexture = NULL; - mBackBufferRTView = NULL; - mOffscreenTexture = NULL; - mOffscreenRTView = NULL; - mOffscreenSRView = NULL; - mDepthStencilTexture = NULL; - mDepthStencilDSView = NULL; - mDepthStencilSRView = NULL; - mQuadVB = NULL; - mPassThroughSampler = NULL; - mPassThroughIL = NULL; - mPassThroughVS = NULL; - mPassThroughPS = NULL; - mWidth = -1; - mHeight = -1; - mSwapInterval = 0; - mAppCreatedShareHandle = mShareHandle != NULL; - mPassThroughResourcesInit = false; + // Sanity check that if present path fast is active then we're using the default orientation + ASSERT(!mRenderer->presentPathFastEnabled() || orientation == 0); } SwapChain11::~SwapChain11() @@ -57,9 +90,12 @@ SwapChain11::~SwapChain11() void SwapChain11::release() { + SafeRelease(mSwapChain1); SafeRelease(mSwapChain); + SafeRelease(mKeyedMutex); SafeRelease(mBackBufferTexture); SafeRelease(mBackBufferRTView); + SafeRelease(mBackBufferSRView); SafeRelease(mOffscreenTexture); SafeRelease(mOffscreenRTView); SafeRelease(mOffscreenSRView); @@ -71,6 +107,7 @@ void SwapChain11::release() SafeRelease(mPassThroughIL); SafeRelease(mPassThroughVS); SafeRelease(mPassThroughPS); + SafeRelease(mPassThroughRS); if (!mAppCreatedShareHandle) { @@ -78,18 +115,47 @@ void SwapChain11::release() } } -void SwapChain11::releaseOffscreenTexture() +void SwapChain11::releaseOffscreenColorBuffer() { SafeRelease(mOffscreenTexture); SafeRelease(mOffscreenRTView); SafeRelease(mOffscreenSRView); +} + +void SwapChain11::releaseOffscreenDepthBuffer() +{ SafeRelease(mDepthStencilTexture); SafeRelease(mDepthStencilDSView); SafeRelease(mDepthStencilSRView); } -EGLint SwapChain11::resetOffscreenTexture(int backbufferWidth, int backbufferHeight) +EGLint SwapChain11::resetOffscreenBuffers(int backbufferWidth, int backbufferHeight) { + if (mNeedsOffscreenTexture) + { + EGLint result = resetOffscreenColorBuffer(backbufferWidth, backbufferHeight); + if (result != EGL_SUCCESS) + { + return result; + } + } + + EGLint result = resetOffscreenDepthBuffer(backbufferWidth, backbufferHeight); + if (result != EGL_SUCCESS) + { + return result; + } + + mWidth = backbufferWidth; + mHeight = backbufferHeight; + + return EGL_SUCCESS; +} + +EGLint SwapChain11::resetOffscreenColorBuffer(int backbufferWidth, int backbufferHeight) +{ + ASSERT(mNeedsOffscreenTexture); + TRACE_EVENT0("gpu.angle", "SwapChain11::resetOffscreenTexture"); ID3D11Device *device = mRenderer->getDevice(); @@ -108,9 +174,9 @@ EGLint SwapChain11::resetOffscreenTexture(int backbufferWidth, int backbufferHei const int previousWidth = mWidth; const int previousHeight = mHeight; - releaseOffscreenTexture(); + releaseOffscreenColorBuffer(); - const d3d11::TextureFormat &backbufferFormatInfo = d3d11::GetTextureFormatInfo(mBackBufferFormat, mRenderer->getFeatureLevel()); + const d3d11::TextureFormat &backbufferFormatInfo = d3d11::GetTextureFormatInfo(mOffscreenRenderTargetFormat, mRenderer->getRenderer11DeviceCaps()); // If the app passed in a share handle, open the resource // See EGL_ANGLE_d3d_share_handle_client_buffer @@ -142,9 +208,8 @@ EGLint SwapChain11::resetOffscreenTexture(int backbufferWidth, int backbufferHei if (offscreenTextureDesc.Width != (UINT)backbufferWidth || offscreenTextureDesc.Height != (UINT)backbufferHeight || - offscreenTextureDesc.Format != backbufferFormatInfo.texFormat || - offscreenTextureDesc.MipLevels != 1 || - offscreenTextureDesc.ArraySize != 1) + offscreenTextureDesc.Format != backbufferFormatInfo.formatSet->texFormat || + offscreenTextureDesc.MipLevels != 1 || offscreenTextureDesc.ArraySize != 1) { ERR("Invalid texture parameters in the shared offscreen texture pbuffer"); release(); @@ -158,7 +223,7 @@ EGLint SwapChain11::resetOffscreenTexture(int backbufferWidth, int backbufferHei D3D11_TEXTURE2D_DESC offscreenTextureDesc = {0}; offscreenTextureDesc.Width = backbufferWidth; offscreenTextureDesc.Height = backbufferHeight; - offscreenTextureDesc.Format = backbufferFormatInfo.texFormat; + offscreenTextureDesc.Format = backbufferFormatInfo.formatSet->texFormat; offscreenTextureDesc.MipLevels = 1; offscreenTextureDesc.ArraySize = 1; offscreenTextureDesc.SampleDesc.Count = 1; @@ -166,7 +231,7 @@ EGLint SwapChain11::resetOffscreenTexture(int backbufferWidth, int backbufferHei offscreenTextureDesc.Usage = D3D11_USAGE_DEFAULT; offscreenTextureDesc.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE; offscreenTextureDesc.CPUAccessFlags = 0; - offscreenTextureDesc.MiscFlags = useSharedResource ? D3D11_RESOURCE_MISC_SHARED : 0; + offscreenTextureDesc.MiscFlags = useSharedResource ? ANGLE_RESOURCE_SHARE_TYPE : 0; HRESULT result = device->CreateTexture2D(&offscreenTextureDesc, NULL, &mOffscreenTexture); @@ -212,9 +277,11 @@ EGLint SwapChain11::resetOffscreenTexture(int backbufferWidth, int backbufferHei } } + // This may return null if the original texture was created without a keyed mutex. + mKeyedMutex = d3d11::DynamicCastComObject(mOffscreenTexture); D3D11_RENDER_TARGET_VIEW_DESC offscreenRTVDesc; - offscreenRTVDesc.Format = backbufferFormatInfo.rtvFormat; + offscreenRTVDesc.Format = backbufferFormatInfo.formatSet->rtvFormat; offscreenRTVDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D; offscreenRTVDesc.Texture2D.MipSlice = 0; @@ -223,7 +290,7 @@ EGLint SwapChain11::resetOffscreenTexture(int backbufferWidth, int backbufferHei d3d11::SetDebugName(mOffscreenRTView, "Offscreen back buffer render target"); D3D11_SHADER_RESOURCE_VIEW_DESC offscreenSRVDesc; - offscreenSRVDesc.Format = backbufferFormatInfo.srvFormat; + offscreenSRVDesc.Format = backbufferFormatInfo.formatSet->srvFormat; offscreenSRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; offscreenSRVDesc.Texture2D.MostDetailedMip = 0; offscreenSRVDesc.Texture2D.MipLevels = static_cast(-1); @@ -232,14 +299,45 @@ EGLint SwapChain11::resetOffscreenTexture(int backbufferWidth, int backbufferHei ASSERT(SUCCEEDED(result)); d3d11::SetDebugName(mOffscreenSRView, "Offscreen back buffer shader resource"); - const d3d11::TextureFormat &depthBufferFormatInfo = d3d11::GetTextureFormatInfo(mDepthBufferFormat, mRenderer->getFeatureLevel()); + if (previousOffscreenTexture != nullptr) + { + D3D11_BOX sourceBox = {0}; + 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, 0, 0, yoffset, 0, + previousOffscreenTexture, 0, &sourceBox); + + SafeRelease(previousOffscreenTexture); + + if (mSwapChain) + { + swapRect(0, 0, backbufferWidth, backbufferHeight); + } + } + + return EGL_SUCCESS; +} + +EGLint SwapChain11::resetOffscreenDepthBuffer(int backbufferWidth, int backbufferHeight) +{ + releaseOffscreenDepthBuffer(); if (mDepthBufferFormat != GL_NONE) { + const d3d11::TextureFormat &depthBufferFormatInfo = + d3d11::GetTextureFormatInfo(mDepthBufferFormat, mRenderer->getRenderer11DeviceCaps()); + D3D11_TEXTURE2D_DESC depthStencilTextureDesc; depthStencilTextureDesc.Width = backbufferWidth; depthStencilTextureDesc.Height = backbufferHeight; - depthStencilTextureDesc.Format = depthBufferFormatInfo.texFormat; + depthStencilTextureDesc.Format = depthBufferFormatInfo.formatSet->texFormat; depthStencilTextureDesc.MipLevels = 1; depthStencilTextureDesc.ArraySize = 1; depthStencilTextureDesc.SampleDesc.Count = 1; @@ -247,7 +345,7 @@ EGLint SwapChain11::resetOffscreenTexture(int backbufferWidth, int backbufferHei depthStencilTextureDesc.Usage = D3D11_USAGE_DEFAULT; depthStencilTextureDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL; - if (depthBufferFormatInfo.srvFormat != DXGI_FORMAT_UNKNOWN) + if (depthBufferFormatInfo.formatSet->srvFormat != DXGI_FORMAT_UNKNOWN) { depthStencilTextureDesc.BindFlags |= D3D11_BIND_SHADER_RESOURCE; } @@ -255,7 +353,9 @@ EGLint SwapChain11::resetOffscreenTexture(int backbufferWidth, int backbufferHei depthStencilTextureDesc.CPUAccessFlags = 0; depthStencilTextureDesc.MiscFlags = 0; - result = device->CreateTexture2D(&depthStencilTextureDesc, NULL, &mDepthStencilTexture); + ID3D11Device *device = mRenderer->getDevice(); + HRESULT result = + device->CreateTexture2D(&depthStencilTextureDesc, NULL, &mDepthStencilTexture); if (FAILED(result)) { ERR("Could not create depthstencil surface for new swap chain: 0x%08X", result); @@ -273,7 +373,7 @@ EGLint SwapChain11::resetOffscreenTexture(int backbufferWidth, int backbufferHei d3d11::SetDebugName(mDepthStencilTexture, "Offscreen depth stencil texture"); D3D11_DEPTH_STENCIL_VIEW_DESC depthStencilDesc; - depthStencilDesc.Format = depthBufferFormatInfo.dsvFormat; + depthStencilDesc.Format = depthBufferFormatInfo.formatSet->dsvFormat; depthStencilDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D; depthStencilDesc.Flags = 0; depthStencilDesc.Texture2D.MipSlice = 0; @@ -282,10 +382,10 @@ EGLint SwapChain11::resetOffscreenTexture(int backbufferWidth, int backbufferHei ASSERT(SUCCEEDED(result)); d3d11::SetDebugName(mDepthStencilDSView, "Offscreen depth stencil view"); - if (depthBufferFormatInfo.srvFormat != DXGI_FORMAT_UNKNOWN) + if (depthBufferFormatInfo.formatSet->srvFormat != DXGI_FORMAT_UNKNOWN) { D3D11_SHADER_RESOURCE_VIEW_DESC depthStencilSRVDesc; - depthStencilSRVDesc.Format = depthBufferFormatInfo.srvFormat; + depthStencilSRVDesc.Format = depthBufferFormatInfo.formatSet->srvFormat; depthStencilSRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; depthStencilSRVDesc.Texture2D.MostDetailedMip = 0; depthStencilSRVDesc.Texture2D.MipLevels = static_cast(-1); @@ -296,31 +396,6 @@ EGLint SwapChain11::resetOffscreenTexture(int backbufferWidth, int backbufferHei } } - mWidth = backbufferWidth; - mHeight = backbufferHeight; - - if (previousOffscreenTexture != NULL) - { - D3D11_BOX sourceBox = {0}; - sourceBox.left = 0; - sourceBox.right = std::min(previousWidth, mWidth); - sourceBox.top = std::max(previousHeight - mHeight, 0); - sourceBox.bottom = previousHeight; - sourceBox.front = 0; - sourceBox.back = 1; - - ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); - const int yoffset = std::max(mHeight - previousHeight, 0); - deviceContext->CopySubresourceRegion(mOffscreenTexture, 0, 0, yoffset, 0, previousOffscreenTexture, 0, &sourceBox); - - SafeRelease(previousOffscreenTexture); - - if (mSwapChain) - { - swapRect(0, 0, mWidth, mHeight); - } - } - return EGL_SUCCESS; } @@ -340,17 +415,30 @@ EGLint SwapChain11::resize(EGLint backbufferWidth, EGLint backbufferHeight) 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 && mBackBufferRTView); + ASSERT(mSwapChain && mBackBufferTexture && mBackBufferRTView && mBackBufferSRView); SafeRelease(mBackBufferTexture); SafeRelease(mBackBufferRTView); + SafeRelease(mBackBufferSRView); // Resize swap chain DXGI_SWAP_CHAIN_DESC desc; - mSwapChain->GetDesc(&desc); - const d3d11::TextureFormat &backbufferFormatInfo = d3d11::GetTextureFormatInfo(mBackBufferFormat, mRenderer->getFeatureLevel()); - HRESULT result = mSwapChain->ResizeBuffers(desc.BufferCount, backbufferWidth, backbufferHeight, backbufferFormatInfo.texFormat, 0); + HRESULT result = mSwapChain->GetDesc(&desc); + if (FAILED(result)) + { + ERR("Error reading swap chain description: 0x%08X", result); + release(); + return EGL_BAD_ALLOC; + } + + result = mSwapChain->ResizeBuffers(desc.BufferCount, backbufferWidth, backbufferHeight, getSwapChainNativeFormat(), 0); if (FAILED(result)) { @@ -372,20 +460,49 @@ EGLint SwapChain11::resize(EGLint backbufferWidth, EGLint backbufferHeight) if (SUCCEEDED(result)) { d3d11::SetDebugName(mBackBufferTexture, "Back buffer texture"); - } + result = device->CreateRenderTargetView(mBackBufferTexture, NULL, &mBackBufferRTView); + ASSERT(SUCCEEDED(result)); + if (SUCCEEDED(result)) + { + d3d11::SetDebugName(mBackBufferRTView, "Back buffer render target"); + } - result = device->CreateRenderTargetView(mBackBufferTexture, NULL, &mBackBufferRTView); - ASSERT(SUCCEEDED(result)); - if (SUCCEEDED(result)) - { - d3d11::SetDebugName(mBackBufferRTView, "Back buffer render target"); + result = device->CreateShaderResourceView(mBackBufferTexture, nullptr, &mBackBufferSRView); + ASSERT(SUCCEEDED(result)); + if (SUCCEEDED(result)) + { + d3d11::SetDebugName(mBackBufferSRView, "Back buffer shader resource"); + } } - return resetOffscreenTexture(backbufferWidth, backbufferHeight); + mFirstSwap = true; + + return resetOffscreenBuffers(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 + return (mOffscreenRenderTargetFormat == GL_BGRA8_EXT) ? DXGI_FORMAT_B8G8R8A8_UNORM : DXGI_FORMAT_R8G8B8A8_UNORM; } EGLint SwapChain11::reset(int backbufferWidth, int 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(backbufferWidth, backbufferHeight); + } + TRACE_EVENT0("gpu.angle", "SwapChain11::reset"); ID3D11Device *device = mRenderer->getDevice(); @@ -396,30 +513,22 @@ EGLint SwapChain11::reset(int backbufferWidth, int backbufferHeight, EGLint swap // 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); SafeRelease(mBackBufferTexture); SafeRelease(mBackBufferRTView); - 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; - } - // EGL allows creating a surface with 0x0 dimension, however, DXGI does not like 0x0 swapchains if (backbufferWidth < 1 || backbufferHeight < 1) { - releaseOffscreenTexture(); + releaseOffscreenColorBuffer(); return EGL_SUCCESS; } if (mNativeWindow.getNativeWindow()) { - const d3d11::TextureFormat &backbufferFormatInfo = d3d11::GetTextureFormatInfo(mBackBufferFormat, mRenderer->getFeatureLevel()); - HRESULT result = mNativeWindow.createSwapChain(device, mRenderer->getDxgiFactory(), - backbufferFormatInfo.texFormat, + getSwapChainNativeFormat(), backbufferWidth, backbufferHeight, &mSwapChain); if (FAILED(result)) @@ -437,6 +546,11 @@ EGLint SwapChain11::reset(int backbufferWidth, int backbufferHeight, EGLint swap } } + if (mRenderer->getRenderer11DeviceCaps().supportsDXGI1_2) + { + mSwapChain1 = d3d11::DynamicCastComObject(mSwapChain); + } + result = mSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&mBackBufferTexture); ASSERT(SUCCEEDED(result)); d3d11::SetDebugName(mBackBufferTexture, "Back buffer texture"); @@ -444,20 +558,24 @@ EGLint SwapChain11::reset(int backbufferWidth, int backbufferHeight, EGLint swap result = device->CreateRenderTargetView(mBackBufferTexture, NULL, &mBackBufferRTView); ASSERT(SUCCEEDED(result)); d3d11::SetDebugName(mBackBufferRTView, "Back buffer render target"); - } - // If we are resizing the swap chain, we don't wish to recreate all the static resources - if (!mPassThroughResourcesInit) - { - mPassThroughResourcesInit = true; - initPassThroughResources(); + result = device->CreateShaderResourceView(mBackBufferTexture, nullptr, &mBackBufferSRView); + ASSERT(SUCCEEDED(result)); + d3d11::SetDebugName(mBackBufferSRView, "Back buffer shader resource view"); } - return resetOffscreenTexture(backbufferWidth, backbufferHeight); + mFirstSwap = true; + + return resetOffscreenBuffers(backbufferWidth, backbufferHeight); } void SwapChain11::initPassThroughResources() { + if (mPassThroughResourcesInit) + { + return; + } + TRACE_EVENT0("gpu.angle", "SwapChain11::initPassThroughResources"); ID3D11Device *device = mRenderer->getDevice(); @@ -515,17 +633,58 @@ void SwapChain11::initPassThroughResources() result = device->CreatePixelShader(g_PS_PassthroughRGBA2D, sizeof(g_PS_PassthroughRGBA2D), NULL, &mPassThroughPS); ASSERT(SUCCEEDED(result)); d3d11::SetDebugName(mPassThroughPS, "Swap chain pass through pixel shader"); + + // 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; + result = device->CreateRasterizerState(&rasterizerDesc, &mPassThroughRS); + ASSERT(SUCCEEDED(result)); + d3d11::SetDebugName(mPassThroughRS, "Swap chain pass through rasterizer state"); + + mPassThroughResourcesInit = true; } // parameters should be validated/clamped by caller EGLint SwapChain11::swapRect(EGLint x, EGLint y, EGLint width, EGLint height) +{ + if (mNeedsOffscreenTexture) + { + EGLint result = copyOffscreenToBackbuffer(x, y, width, height); + if (result != EGL_SUCCESS) + { + return result; + } + } + + EGLint result = present(x, y, width, height); + if (result != EGL_SUCCESS) + { + return result; + } + + mRenderer->onSwap(); + + return EGL_SUCCESS; +} + +EGLint SwapChain11::copyOffscreenToBackbuffer(EGLint x, EGLint y, EGLint width, EGLint height) { if (!mSwapChain) { return EGL_SUCCESS; } - ID3D11Device *device = mRenderer->getDevice(); + initPassThroughResources(); + ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); // Set vertices @@ -549,6 +708,16 @@ EGLint SwapChain11::swapRect(EGLint x, EGLint y, EGLint width, EGLint height) 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); @@ -566,7 +735,7 @@ EGLint SwapChain11::swapRect(EGLint x, EGLint y, EGLint width, EGLint height) static const float blendFactor[4] = { 1.0f, 1.0f, 1.0f, 1.0f }; deviceContext->OMSetBlendState(NULL, blendFactor, 0xFFFFFFF); - deviceContext->RSSetState(NULL); + deviceContext->RSSetState(mPassThroughRS); // Apply shaders deviceContext->IASetInputLayout(mPassThroughIL); @@ -575,8 +744,10 @@ EGLint SwapChain11::swapRect(EGLint x, EGLint y, EGLint width, EGLint height) deviceContext->PSSetShader(mPassThroughPS, NULL, 0); deviceContext->GSSetShader(NULL, NULL, 0); + auto stateManager = mRenderer->getStateManager(); + // Apply render targets - mRenderer->setOneTimeRenderTarget(mBackBufferRTView); + stateManager->setOneTimeRenderTarget(mBackBufferRTView, nullptr); // Set the viewport D3D11_VIEWPORT viewport; @@ -589,23 +760,68 @@ EGLint SwapChain11::swapRect(EGLint x, EGLint y, EGLint width, EGLint height) deviceContext->RSSetViewports(1, &viewport); // Apply textures - mRenderer->setShaderResource(gl::SAMPLER_PIXEL, 0, mOffscreenSRView); + stateManager->setShaderResource(gl::SAMPLER_PIXEL, 0, mOffscreenSRView); deviceContext->PSSetSamplers(0, 1, &mPassThroughSampler); // Draw deviceContext->Draw(4, 0); + // Rendering to the swapchain is now complete. Now we can call Present(). + // Before that, we perform any cleanup on the D3D device. We do this before Present() to make sure the + // cleanup is caught under the current eglSwapBuffers() PIX/Graphics Diagnostics call rather than the next one. + stateManager->setShaderResource(gl::SAMPLER_PIXEL, 0, NULL); + + mRenderer->markAllStateDirty(); + + return EGL_SUCCESS; +} + +EGLint SwapChain11::present(EGLint x, EGLint y, EGLint width, EGLint height) +{ + if (!mSwapChain) + { + return EGL_SUCCESS; + } + + UINT swapInterval = mSwapInterval; #if ANGLE_VSYNC == ANGLE_DISABLED - result = mSwapChain->Present(0, 0); -#else - result = mSwapChain->Present(mSwapInterval, 0); + swapInterval = 0; #endif + HRESULT result = S_OK; + + // Use IDXGISwapChain1::Present1 with a dirty rect if DXGI 1.2 is available. + if (mSwapChain1 != nullptr) + { + 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. + mRenderer->getStateManager()->invalidateRenderTarget(); + if (result == DXGI_ERROR_DEVICE_REMOVED) { - HRESULT removedReason = device->GetDeviceRemovedReason(); - UNUSED_TRACE_VARIABLE(removedReason); - ERR("Present failed: the D3D11 device was removed: 0x%08X", removedReason); + ERR("Present failed: the D3D11 device was removed: 0x%08X", + mRenderer->getDevice()->GetDeviceRemovedReason()); return EGL_CONTEXT_LOST; } else if (result == DXGI_ERROR_DEVICE_RESET) @@ -618,28 +834,24 @@ EGLint SwapChain11::swapRect(EGLint x, EGLint y, EGLint width, EGLint height) ERR("Present failed with error code 0x%08X", result); } - // Unbind - mRenderer->setShaderResource(gl::SAMPLER_PIXEL, 0, NULL); - - mRenderer->unapplyRenderTargets(); - mRenderer->markAllStateDirty(); + mNativeWindow.commitChange(); return EGL_SUCCESS; } ID3D11Texture2D *SwapChain11::getOffscreenTexture() { - return mOffscreenTexture; + return mNeedsOffscreenTexture ? mOffscreenTexture : mBackBufferTexture; } ID3D11RenderTargetView *SwapChain11::getRenderTarget() { - return mOffscreenRTView; + return mNeedsOffscreenTexture ? mOffscreenRTView : mBackBufferRTView; } ID3D11ShaderResourceView *SwapChain11::getRenderTargetShaderResource() { - return mOffscreenSRView; + return mNeedsOffscreenTexture ? mOffscreenSRView : mBackBufferSRView; } ID3D11DepthStencilView *SwapChain11::getDepthStencil() diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/SwapChain11.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/SwapChain11.h index d5b27bb4860f..583e29c3c81a 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/SwapChain11.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/SwapChain11.h @@ -20,8 +20,12 @@ class Renderer11; class SwapChain11 : public SwapChainD3D { public: - SwapChain11(Renderer11 *renderer, NativeWindow nativeWindow, HANDLE shareHandle, - GLenum backBufferFormat, GLenum depthBufferFormat); + SwapChain11(Renderer11 *renderer, + NativeWindow nativeWindow, + HANDLE shareHandle, + GLenum backBufferFormat, + GLenum depthBufferFormat, + EGLint orientation); virtual ~SwapChain11(); EGLint resize(EGLint backbufferWidth, EGLint backbufferHeight); @@ -42,25 +46,41 @@ class SwapChain11 : public SwapChainD3D EGLint getWidth() const { return mWidth; } EGLint getHeight() const { return mHeight; } + void *getKeyedMutex() override { return mKeyedMutex; } private: void release(); void initPassThroughResources(); - void releaseOffscreenTexture(); - EGLint resetOffscreenTexture(int backbufferWidth, int backbufferHeight); + + void releaseOffscreenColorBuffer(); + void releaseOffscreenDepthBuffer(); + EGLint resetOffscreenBuffers(int backbufferWidth, int backbufferHeight); + EGLint resetOffscreenColorBuffer(int backbufferWidth, int backbufferHeight); + EGLint resetOffscreenDepthBuffer(int backbufferWidth, int backbufferHeight); + + DXGI_FORMAT getSwapChainNativeFormat() const; + + EGLint copyOffscreenToBackbuffer(EGLint x, EGLint y, EGLint width, EGLint height); + EGLint present(EGLint x, EGLint y, EGLint width, EGLint height); Renderer11 *mRenderer; - EGLint mHeight; EGLint mWidth; + EGLint mHeight; + const EGLint mOrientation; bool mAppCreatedShareHandle; unsigned int mSwapInterval; bool mPassThroughResourcesInit; + bool mFirstSwap; DXGISwapChain *mSwapChain; + IDXGISwapChain1 *mSwapChain1; + IDXGIKeyedMutex *mKeyedMutex; ID3D11Texture2D *mBackBufferTexture; ID3D11RenderTargetView *mBackBufferRTView; + ID3D11ShaderResourceView *mBackBufferSRView; + const bool mNeedsOffscreenTexture; ID3D11Texture2D *mOffscreenTexture; ID3D11RenderTargetView *mOffscreenRTView; ID3D11ShaderResourceView *mOffscreenSRView; @@ -74,6 +94,7 @@ class SwapChain11 : public SwapChainD3D ID3D11InputLayout *mPassThroughIL; ID3D11VertexShader *mPassThroughVS; ID3D11PixelShader *mPassThroughPS; + ID3D11RasterizerState *mPassThroughRS; SurfaceRenderTarget11 mColorRenderTarget; SurfaceRenderTarget11 mDepthStencilRenderTarget; diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/TextureStorage11.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/TextureStorage11.cpp index 8bbcbb2d4df9..05362c71d821 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/TextureStorage11.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/TextureStorage11.cpp @@ -5,7 +5,8 @@ // // 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. +// classes TextureStorage11_2D and TextureStorage11_Cube, which act as the interface to the D3D11 +// texture. #include "libANGLE/renderer/d3d/d3d11/TextureStorage11.h" @@ -13,36 +14,42 @@ #include "common/MemoryBuffer.h" #include "common/utilities.h" -#include "libANGLE/ImageIndex.h" #include "libANGLE/formatutils.h" -#include "libANGLE/renderer/d3d/TextureD3D.h" +#include "libANGLE/ImageIndex.h" #include "libANGLE/renderer/d3d/d3d11/Blit11.h" +#include "libANGLE/renderer/d3d/d3d11/formatutils11.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/SwapChain11.h" -#include "libANGLE/renderer/d3d/d3d11/formatutils11.h" #include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h" +#include "libANGLE/renderer/d3d/d3d11/RenderTarget11.h" +#include "libANGLE/renderer/d3d/d3d11/SwapChain11.h" +#include "libANGLE/renderer/d3d/d3d11/texture_format_table.h" +#include "libANGLE/renderer/d3d/EGLImageD3D.h" +#include "libANGLE/renderer/d3d/TextureD3D.h" namespace rx { TextureStorage11::SwizzleCacheValue::SwizzleCacheValue() - : swizzleRed(GL_NONE), swizzleGreen(GL_NONE), swizzleBlue(GL_NONE), swizzleAlpha(GL_NONE) + : swizzleRed(GL_INVALID_INDEX), + swizzleGreen(GL_INVALID_INDEX), + swizzleBlue(GL_INVALID_INDEX), + swizzleAlpha(GL_INVALID_INDEX) { } -TextureStorage11::SwizzleCacheValue::SwizzleCacheValue(GLenum red, GLenum green, GLenum blue, GLenum alpha) +TextureStorage11::SwizzleCacheValue::SwizzleCacheValue(GLenum red, + GLenum green, + GLenum blue, + GLenum alpha) : swizzleRed(red), swizzleGreen(green), swizzleBlue(blue), swizzleAlpha(alpha) { } bool TextureStorage11::SwizzleCacheValue::operator==(const SwizzleCacheValue &other) const { - return swizzleRed == other.swizzleRed && - swizzleGreen == other.swizzleGreen && - swizzleBlue == other.swizzleBlue && - swizzleAlpha == other.swizzleAlpha; + return swizzleRed == other.swizzleRed && swizzleGreen == other.swizzleGreen && + swizzleBlue == other.swizzleBlue && swizzleAlpha == other.swizzleAlpha; } bool TextureStorage11::SwizzleCacheValue::operator!=(const SwizzleCacheValue &other) const @@ -57,28 +64,25 @@ TextureStorage11::SRVKey::SRVKey(int baseLevel, int mipLevels, bool swizzle) bool TextureStorage11::SRVKey::operator<(const SRVKey &rhs) const { - return std::tie(baseLevel, mipLevels, swizzle) < std::tie(rhs.baseLevel, rhs.mipLevels, rhs.swizzle); + return std::tie(baseLevel, mipLevels, swizzle) < + std::tie(rhs.baseLevel, rhs.mipLevels, rhs.swizzle); } TextureStorage11::TextureStorage11(Renderer11 *renderer, UINT bindFlags, UINT miscFlags) : mRenderer(renderer), - mBindFlags(bindFlags), - mMiscFlags(miscFlags), mTopLevel(0), mMipLevels(0), mInternalFormat(GL_NONE), - mTextureFormat(DXGI_FORMAT_UNKNOWN), - mShaderResourceFormat(DXGI_FORMAT_UNKNOWN), - mRenderTargetFormat(DXGI_FORMAT_UNKNOWN), - mDepthStencilFormat(DXGI_FORMAT_UNKNOWN), + mTextureFormatSet(nullptr), + mSwizzleFormatSet(nullptr), mTextureWidth(0), mTextureHeight(0), - mTextureDepth(0) + mTextureDepth(0), + mBindFlags(bindFlags), + mMiscFlags(miscFlags) { - for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++) - { - mLevelSRVs[i] = nullptr; - } + mLevelSRVs.fill(nullptr); + mLevelBlitSRVs.fill(nullptr); } TextureStorage11::~TextureStorage11() @@ -86,6 +90,7 @@ TextureStorage11::~TextureStorage11() for (unsigned int level = 0; level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++) { SafeRelease(mLevelSRVs[level]); + SafeRelease(mLevelBlitSRVs[level]); } for (SRVCache::iterator i = mSrvCache.begin(); i != mSrvCache.end(); i++) @@ -95,20 +100,23 @@ TextureStorage11::~TextureStorage11() mSrvCache.clear(); } -DWORD TextureStorage11::GetTextureBindFlags(GLenum internalFormat, D3D_FEATURE_LEVEL featureLevel, bool renderTarget) +DWORD TextureStorage11::GetTextureBindFlags(GLenum internalFormat, + const Renderer11DeviceCaps &renderer11DeviceCaps, + bool renderTarget) { UINT bindFlags = 0; - const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(internalFormat, featureLevel); - if (formatInfo.srvFormat != DXGI_FORMAT_UNKNOWN) + const d3d11::TextureFormat &formatInfo = + d3d11::GetTextureFormatInfo(internalFormat, renderer11DeviceCaps); + if (formatInfo.formatSet->srvFormat != DXGI_FORMAT_UNKNOWN) { bindFlags |= D3D11_BIND_SHADER_RESOURCE; } - if (formatInfo.dsvFormat != DXGI_FORMAT_UNKNOWN) + if (formatInfo.formatSet->dsvFormat != DXGI_FORMAT_UNKNOWN) { bindFlags |= D3D11_BIND_DEPTH_STENCIL; } - if (formatInfo.rtvFormat != DXGI_FORMAT_UNKNOWN && renderTarget) + if (formatInfo.formatSet->rtvFormat != DXGI_FORMAT_UNKNOWN && renderTarget) { bindFlags |= D3D11_BIND_RENDER_TARGET; } @@ -116,16 +124,21 @@ DWORD TextureStorage11::GetTextureBindFlags(GLenum internalFormat, D3D_FEATURE_L return bindFlags; } -DWORD TextureStorage11::GetTextureMiscFlags(GLenum internalFormat, D3D_FEATURE_LEVEL featureLevel, bool renderTarget, int levels) +DWORD TextureStorage11::GetTextureMiscFlags(GLenum internalFormat, + const Renderer11DeviceCaps &renderer11DeviceCaps, + bool renderTarget, + int levels) { UINT miscFlags = 0; - const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(internalFormat, featureLevel); + const d3d11::TextureFormat &formatInfo = + d3d11::GetTextureFormatInfo(internalFormat, renderer11DeviceCaps); if (renderTarget && levels > 1) { - const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(formatInfo.srvFormat); + const d3d11::DXGIFormat &dxgiFormatInfo = + d3d11::GetDXGIFormatInfo(formatInfo.formatSet->texFormat); - if (dxgiFormatInfo.nativeMipmapSupport(featureLevel)) + if (dxgiFormatInfo.nativeMipmapSupport(renderer11DeviceCaps.featureLevel)) { miscFlags |= D3D11_RESOURCE_MISC_GENERATE_MIPS; } @@ -186,23 +199,25 @@ int TextureStorage11::getLevelDepth(int mipLevel) const UINT TextureStorage11::getSubresourceIndex(const gl::ImageIndex &index) const { - UINT mipSlice = static_cast(index.mipIndex + mTopLevel); - UINT arraySlice = static_cast(index.hasLayer() ? index.layerIndex : 0); + UINT mipSlice = static_cast(index.mipIndex + mTopLevel); + UINT arraySlice = static_cast(index.hasLayer() ? index.layerIndex : 0); UINT subresource = D3D11CalcSubresource(mipSlice, arraySlice, mMipLevels); ASSERT(subresource != std::numeric_limits::max()); return subresource; } -gl::Error TextureStorage11::getSRV(const gl::SamplerState &samplerState, ID3D11ShaderResourceView **outSRV) +gl::Error TextureStorage11::getSRV(const gl::TextureState &textureState, + ID3D11ShaderResourceView **outSRV) { - bool swizzleRequired = samplerState.swizzleRequired(); - bool mipmapping = gl::IsMipmapFiltered(samplerState); - unsigned int mipLevels = mipmapping ? (samplerState.maxLevel - samplerState.baseLevel + 1) : 1; + bool swizzleRequired = textureState.swizzleRequired(); + bool mipmapping = gl::IsMipmapFiltered(textureState.samplerState); + unsigned int mipLevels = mipmapping ? (textureState.maxLevel - textureState.baseLevel + 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 - samplerState.baseLevel); + // 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 - textureState.baseLevel); - if (mRenderer->getFeatureLevel() <= D3D_FEATURE_LEVEL_9_3) + if (mRenderer->getRenderer11DeviceCaps().featureLevel <= D3D_FEATURE_LEVEL_9_3) { ASSERT(!swizzleRequired); ASSERT(mipLevels == 1 || mipLevels == mMipLevels); @@ -220,10 +235,11 @@ gl::Error TextureStorage11::getSRV(const gl::SamplerState &samplerState, ID3D11S if (swizzleRequired) { - verifySwizzleExists(samplerState.swizzleRed, samplerState.swizzleGreen, samplerState.swizzleBlue, samplerState.swizzleAlpha); + verifySwizzleExists(textureState.swizzleRed, textureState.swizzleGreen, + textureState.swizzleBlue, textureState.swizzleAlpha); } - SRVKey key(samplerState.baseLevel, mipLevels, swizzleRequired); + SRVKey key(textureState.baseLevel, mipLevels, swizzleRequired); auto iter = mSrvCache.find(key); if (iter != mSrvCache.end()) { @@ -250,8 +266,9 @@ gl::Error TextureStorage11::getSRV(const gl::SamplerState &samplerState, ID3D11S } ID3D11ShaderResourceView *srv = nullptr; - DXGI_FORMAT format = (swizzleRequired ? mSwizzleShaderResourceFormat : mShaderResourceFormat); - gl::Error error = createSRV(samplerState.baseLevel, mipLevels, format, texture, &srv); + DXGI_FORMAT format = + (swizzleRequired ? mSwizzleFormatSet->srvFormat : mTextureFormatSet->srvFormat); + gl::Error error = createSRV(textureState.baseLevel, mipLevels, format, texture, &srv); if (error.isError()) { return error; @@ -263,39 +280,59 @@ gl::Error TextureStorage11::getSRV(const gl::SamplerState &samplerState, ID3D11S return gl::Error(GL_NO_ERROR); } -gl::Error TextureStorage11::getSRVLevel(int mipLevel, ID3D11ShaderResourceView **outSRV) +gl::Error TextureStorage11::getSRVLevel(int mipLevel, + bool blitSRV, + ID3D11ShaderResourceView **outSRV) { ASSERT(mipLevel >= 0 && mipLevel < getLevelCount()); - if (!mLevelSRVs[mipLevel]) + auto &levelSRVs = (blitSRV) ? mLevelBlitSRVs : mLevelSRVs; + auto &otherLevelSRVs = (blitSRV) ? mLevelSRVs : mLevelBlitSRVs; + + if (!levelSRVs[mipLevel]) { - ID3D11Resource *resource = NULL; - gl::Error error = getResource(&resource); - if (error.isError()) + // Only create a different SRV for blit if blit format is different from regular srv format + if (otherLevelSRVs[mipLevel] && + mTextureFormatSet->srvFormat == mTextureFormatSet->blitSRVFormat) { - return error; + levelSRVs[mipLevel] = otherLevelSRVs[mipLevel]; + levelSRVs[mipLevel]->AddRef(); } - - error = createSRV(mipLevel, 1, mShaderResourceFormat, resource, &mLevelSRVs[mipLevel]); - if (error.isError()) + else { - return error; + ID3D11Resource *resource = nullptr; + gl::Error error = getResource(&resource); + if (error.isError()) + { + return error; + } + + DXGI_FORMAT resourceFormat = + blitSRV ? mTextureFormatSet->blitSRVFormat : mTextureFormatSet->srvFormat; + error = createSRV(mipLevel, 1, resourceFormat, resource, &levelSRVs[mipLevel]); + if (error.isError()) + { + return error; + } } } - *outSRV = mLevelSRVs[mipLevel]; + *outSRV = levelSRVs[mipLevel]; return gl::Error(GL_NO_ERROR); } -gl::Error TextureStorage11::getSRVLevels(GLint baseLevel, GLint maxLevel, ID3D11ShaderResourceView **outSRV) +gl::Error TextureStorage11::getSRVLevels(GLint baseLevel, + GLint maxLevel, + ID3D11ShaderResourceView **outSRV) { 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) + // 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->getFeatureLevel() <= D3D_FEATURE_LEVEL_9_3) + if (mRenderer->getRenderer11DeviceCaps().featureLevel <= D3D_FEATURE_LEVEL_9_3) { ASSERT(mipLevels == 1 || mipLevels == mMipLevels); } @@ -326,19 +363,27 @@ gl::Error TextureStorage11::getSRVLevels(GLint baseLevel, GLint maxLevel, ID3D11 } ID3D11ShaderResourceView *srv = nullptr; - error = createSRV(baseLevel, mipLevels, mShaderResourceFormat, texture, &srv); + error = createSRV(baseLevel, mipLevels, mTextureFormatSet->srvFormat, texture, &srv); if (error.isError()) { return error; } mSrvCache[key] = srv; - *outSRV = srv; + *outSRV = srv; return gl::Error(GL_NO_ERROR); } -gl::Error TextureStorage11::generateSwizzles(GLenum swizzleRed, GLenum swizzleGreen, GLenum swizzleBlue, GLenum swizzleAlpha) +d3d11::ANGLEFormat TextureStorage11::getANGLEFormat() const +{ + return mTextureFormatSet->format; +} + +gl::Error TextureStorage11::generateSwizzles(GLenum swizzleRed, + GLenum swizzleGreen, + GLenum swizzleBlue, + GLenum swizzleAlpha) { SwizzleCacheValue swizzleTarget(swizzleRed, swizzleGreen, swizzleBlue, swizzleAlpha); for (int level = 0; level < getLevelCount(); level++) @@ -347,14 +392,15 @@ gl::Error TextureStorage11::generateSwizzles(GLenum swizzleRed, GLenum swizzleGr if (mSwizzleCache[level] != swizzleTarget) { // Need to re-render the swizzle for this level - ID3D11ShaderResourceView *sourceSRV = NULL; - gl::Error error = getSRVLevel(level, &sourceSRV); + ID3D11ShaderResourceView *sourceSRV = nullptr; + gl::Error error = getSRVLevel(level, true, &sourceSRV); + if (error.isError()) { return error; } - ID3D11RenderTargetView *destRTV = NULL; + ID3D11RenderTargetView *destRTV = nullptr; error = getSwizzleRenderTarget(level, &destRTV); if (error.isError()) { @@ -365,7 +411,8 @@ gl::Error TextureStorage11::generateSwizzles(GLenum swizzleRed, GLenum swizzleGr Blit11 *blitter = mRenderer->getBlitter(); - error = blitter->swizzleTexture(sourceSRV, destRTV, size, swizzleRed, swizzleGreen, swizzleBlue, swizzleAlpha); + error = blitter->swizzleTexture(sourceSRV, destRTV, size, swizzleRed, swizzleGreen, + swizzleBlue, swizzleAlpha); if (error.isError()) { return error; @@ -396,29 +443,28 @@ void TextureStorage11::invalidateSwizzleCache() } } -gl::Error TextureStorage11::updateSubresourceLevel(ID3D11Resource *srcTexture, unsigned int sourceSubresource, - const gl::ImageIndex &index, const gl::Box ©Area) +gl::Error TextureStorage11::updateSubresourceLevel(ID3D11Resource *srcTexture, + unsigned int sourceSubresource, + const gl::ImageIndex &index, + const gl::Box ©Area) { ASSERT(srcTexture); - GLint level = index.mipIndex; + const GLint level = index.mipIndex; invalidateSwizzleCacheLevel(level); gl::Extents texSize(getLevelWidth(level), getLevelHeight(level), getLevelDepth(level)); - bool fullCopy = copyArea.x == 0 && - copyArea.y == 0 && - copyArea.z == 0 && - copyArea.width == texSize.width && - copyArea.height == texSize.height && - copyArea.depth == texSize.depth; + bool fullCopy = copyArea.x == 0 && copyArea.y == 0 && copyArea.z == 0 && + copyArea.width == texSize.width && copyArea.height == texSize.height && + copyArea.depth == texSize.depth; - ID3D11Resource *dstTexture = NULL; + ID3D11Resource *dstTexture = nullptr; gl::Error error(GL_NO_ERROR); - // 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 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.mipIndex > 0 && mRenderer->getWorkarounds().zeroMaxLodWorkaround) { error = getMippedResource(&dstTexture); @@ -437,44 +483,49 @@ gl::Error TextureStorage11::updateSubresourceLevel(ID3D11Resource *srcTexture, u ASSERT(dstTexture); - const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(mTextureFormat); - if (!fullCopy && (dxgiFormatInfo.depthBits > 0 || dxgiFormatInfo.stencilBits > 0)) + const d3d11::DXGIFormatSize &dxgiFormatSizeInfo = + d3d11::GetDXGIFormatSizeInfo(mTextureFormatSet->texFormat); + if (!fullCopy && mTextureFormatSet->dsvFormat != DXGI_FORMAT_UNKNOWN) { // CopySubresourceRegion cannot copy partial depth stencils, use the blitter instead Blit11 *blitter = mRenderer->getBlitter(); return blitter->copyDepthStencil(srcTexture, sourceSubresource, copyArea, texSize, - dstTexture, dstSubresource, copyArea, texSize, - NULL); + dstTexture, dstSubresource, copyArea, texSize, nullptr); } else { D3D11_BOX srcBox; srcBox.left = copyArea.x; srcBox.top = copyArea.y; - srcBox.right = copyArea.x + roundUp(static_cast(copyArea.width), dxgiFormatInfo.blockWidth); - srcBox.bottom = copyArea.y + roundUp(static_cast(copyArea.height), dxgiFormatInfo.blockHeight); + 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; + srcBox.back = copyArea.z + copyArea.depth; ID3D11DeviceContext *context = mRenderer->getDeviceContext(); - context->CopySubresourceRegion(dstTexture, dstSubresource, copyArea.x, copyArea.y, copyArea.z, - srcTexture, sourceSubresource, fullCopy ? NULL : &srcBox); + context->CopySubresourceRegion(dstTexture, dstSubresource, copyArea.x, copyArea.y, + copyArea.z, srcTexture, sourceSubresource, + fullCopy ? nullptr : &srcBox); return gl::Error(GL_NO_ERROR); } } -gl::Error TextureStorage11::copySubresourceLevel(ID3D11Resource* dstTexture, unsigned int dstSubresource, - const gl::ImageIndex &index, const gl::Box ®ion) +gl::Error TextureStorage11::copySubresourceLevel(ID3D11Resource *dstTexture, + unsigned int dstSubresource, + const gl::ImageIndex &index, + const gl::Box ®ion) { ASSERT(dstTexture); - ID3D11Resource *srcTexture = NULL; + ID3D11Resource *srcTexture = nullptr; gl::Error error(GL_NO_ERROR); - // 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 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.mipIndex > 0 && mRenderer->getWorkarounds().zeroMaxLodWorkaround) { error = getMippedResource(&srcTexture); @@ -495,23 +546,23 @@ gl::Error TextureStorage11::copySubresourceLevel(ID3D11Resource* dstTexture, uns ID3D11DeviceContext *context = mRenderer->getDeviceContext(); - // D3D11 can't perform partial CopySubresourceRegion on depth/stencil textures, so pSrcBox should be NULL. + // D3D11 can't perform partial CopySubresourceRegion on depth/stencil textures, so pSrcBox + // should be nullptr. D3D11_BOX srcBox; - D3D11_BOX *pSrcBox = NULL; - if (mRenderer->getFeatureLevel() <= D3D_FEATURE_LEVEL_9_3) - { - // 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(d3d11::GetDXGIFormatInfo(mTextureFormat).depthBits == 0); - ASSERT(d3d11::GetDXGIFormatInfo(mTextureFormat).stencilBits == 0); - srcBox.left = region.x; - srcBox.right = region.x + region.width; - srcBox.top = region.y; + D3D11_BOX *pSrcBox = nullptr; + if (mRenderer->getRenderer11DeviceCaps().featureLevel <= D3D_FEATURE_LEVEL_9_3) + { + // 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(mTextureFormatSet->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; + srcBox.front = region.z; + srcBox.back = region.z + region.depth; + pSrcBox = &srcBox; } context->CopySubresourceRegion(dstTexture, dstSubresource, region.x, region.y, region.z, @@ -520,28 +571,30 @@ gl::Error TextureStorage11::copySubresourceLevel(ID3D11Resource* dstTexture, uns return gl::Error(GL_NO_ERROR); } -gl::Error TextureStorage11::generateMipmap(const gl::ImageIndex &sourceIndex, const gl::ImageIndex &destIndex) +gl::Error TextureStorage11::generateMipmap(const gl::ImageIndex &sourceIndex, + const gl::ImageIndex &destIndex) { ASSERT(sourceIndex.layerIndex == destIndex.layerIndex); invalidateSwizzleCacheLevel(destIndex.mipIndex); - RenderTargetD3D *source = NULL; + RenderTargetD3D *source = nullptr; gl::Error error = getRenderTarget(sourceIndex, &source); if (error.isError()) { return error; } - RenderTargetD3D *dest = NULL; + RenderTargetD3D *dest = nullptr; error = getRenderTarget(destIndex, &dest); if (error.isError()) { return error; } - ID3D11ShaderResourceView *sourceSRV = GetAs(source)->getShaderResourceView(); - ID3D11RenderTargetView *destRTV = GetAs(dest)->getRenderTargetView(); + ID3D11ShaderResourceView *sourceSRV = + GetAs(source)->getBlitShaderResourceView(); + ID3D11RenderTargetView *destRTV = GetAs(dest)->getRenderTargetView(); gl::Box sourceArea(0, 0, 0, source->getWidth(), source->getHeight(), source->getDepth()); gl::Extents sourceSize(source->getWidth(), source->getHeight(), source->getDepth()); @@ -550,11 +603,15 @@ gl::Error TextureStorage11::generateMipmap(const gl::ImageIndex &sourceIndex, co gl::Extents destSize(dest->getWidth(), dest->getHeight(), dest->getDepth()); Blit11 *blitter = mRenderer->getBlitter(); - return blitter->copyTexture(sourceSRV, sourceArea, sourceSize, destRTV, destArea, destSize, NULL, - gl::GetInternalFormatInfo(source->getInternalFormat()).format, GL_LINEAR); + return blitter->copyTexture( + sourceSRV, sourceArea, sourceSize, destRTV, destArea, destSize, nullptr, + gl::GetInternalFormatInfo(source->getInternalFormat()).format, GL_LINEAR, false); } -void TextureStorage11::verifySwizzleExists(GLenum swizzleRed, GLenum swizzleGreen, GLenum swizzleBlue, GLenum swizzleAlpha) +void TextureStorage11::verifySwizzleExists(GLenum swizzleRed, + GLenum swizzleGreen, + GLenum swizzleBlue, + GLenum swizzleAlpha) { SwizzleCacheValue swizzleTarget(swizzleRed, swizzleGreen, swizzleBlue, swizzleAlpha); for (unsigned int level = 0; level < mMipLevels; level++) @@ -563,19 +620,44 @@ void TextureStorage11::verifySwizzleExists(GLenum swizzleRed, GLenum swizzleGree } } +void TextureStorage11::clearSRVCache() +{ + invalidateSwizzleCache(); + + auto iter = mSrvCache.begin(); + while (iter != mSrvCache.end()) + { + if (!iter->first.swizzle) + { + SafeRelease(iter->second); + iter = mSrvCache.erase(iter); + } + else + { + iter++; + } + } + + for (size_t level = 0; level < mLevelSRVs.size(); level++) + { + SafeRelease(mLevelSRVs[level]); + SafeRelease(mLevelBlitSRVs[level]); + } +} + gl::Error TextureStorage11::copyToStorage(TextureStorage *destStorage) { ASSERT(destStorage); - ID3D11Resource *sourceResouce = NULL; + ID3D11Resource *sourceResouce = nullptr; gl::Error error = getResource(&sourceResouce); if (error.isError()) { return error; } - TextureStorage11 *dest11 = GetAs(destStorage); - ID3D11Resource *destResource = NULL; + TextureStorage11 *dest11 = GetAs(destStorage); + ID3D11Resource *destResource = nullptr; error = dest11->getResource(&destResource); if (error.isError()) { @@ -590,12 +672,16 @@ gl::Error TextureStorage11::copyToStorage(TextureStorage *destStorage) return gl::Error(GL_NO_ERROR); } -gl::Error TextureStorage11::setData(const gl::ImageIndex &index, ImageD3D *image, const gl::Box *destBox, GLenum type, - const gl::PixelUnpackState &unpack, const uint8_t *pixelData) +gl::Error TextureStorage11::setData(const gl::ImageIndex &index, + ImageD3D *image, + const gl::Box *destBox, + GLenum type, + const gl::PixelUnpackState &unpack, + const uint8_t *pixelData) { ASSERT(!image->isDirty()); - ID3D11Resource *resource = NULL; + ID3D11Resource *resource = nullptr; gl::Error error = getResource(&resource); if (error.isError()) { @@ -605,10 +691,12 @@ gl::Error TextureStorage11::setData(const gl::ImageIndex &index, ImageD3D *image UINT destSubresource = getSubresourceIndex(index); - const gl::InternalFormat &internalFormatInfo = gl::GetInternalFormatInfo(image->getInternalFormat()); + const gl::InternalFormat &internalFormatInfo = + gl::GetInternalFormatInfo(image->getInternalFormat()); - gl::Box levelBox(0, 0, 0, getLevelWidth(index.mipIndex), getLevelHeight(index.mipIndex), getLevelDepth(index.mipIndex)); - bool fullUpdate = (destBox == NULL || *destBox == levelBox); + gl::Box levelBox(0, 0, 0, getLevelWidth(index.mipIndex), getLevelHeight(index.mipIndex), + getLevelDepth(index.mipIndex)); + bool fullUpdate = (destBox == nullptr || *destBox == levelBox); ASSERT(internalFormatInfo.depthBits == 0 || fullUpdate); // TODO(jmadill): Handle compressed formats @@ -617,33 +705,50 @@ gl::Error TextureStorage11::setData(const gl::ImageIndex &index, ImageD3D *image // with compressed formats in the calling logic. ASSERT(!internalFormatInfo.compressed); - int width = destBox ? destBox->width : static_cast(image->getWidth()); - int height = destBox ? destBox->height : static_cast(image->getHeight()); - int depth = destBox ? destBox->depth : static_cast(image->getDepth()); - UINT srcRowPitch = internalFormatInfo.computeRowPitch(type, width, unpack.alignment, unpack.rowLength); - UINT srcDepthPitch = internalFormatInfo.computeDepthPitch(type, width, height, unpack.alignment, unpack.rowLength); + 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()); + const UINT srcRowPitch = + internalFormatInfo.computeRowPitch(type, width, unpack.alignment, unpack.rowLength); + const UINT srcDepthPitch = internalFormatInfo.computeDepthPitch( + type, width, height, unpack.alignment, unpack.rowLength, unpack.imageHeight); + const GLsizei srcSkipBytes = internalFormatInfo.computeSkipPixels( + srcRowPitch, srcDepthPitch, unpack.skipImages, unpack.skipRows, unpack.skipPixels); - const d3d11::TextureFormat &d3d11Format = d3d11::GetTextureFormatInfo(image->getInternalFormat(), mRenderer->getFeatureLevel()); - const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(d3d11Format.texFormat); + const d3d11::TextureFormat &d3d11Format = d3d11::GetTextureFormatInfo( + image->getInternalFormat(), mRenderer->getRenderer11DeviceCaps()); + const d3d11::DXGIFormatSize &dxgiFormatInfo = + d3d11::GetDXGIFormatSizeInfo(d3d11Format.formatSet->texFormat); - size_t outputPixelSize = dxgiFormatInfo.pixelBytes; + const size_t outputPixelSize = dxgiFormatInfo.pixelBytes; - UINT bufferRowPitch = outputPixelSize * width; + UINT bufferRowPitch = static_cast(outputPixelSize) * width; UINT bufferDepthPitch = bufferRowPitch * height; - size_t neededSize = bufferDepthPitch * depth; - MemoryBuffer *conversionBuffer = NULL; - error = mRenderer->getScratchMemoryBuffer(neededSize, &conversionBuffer); - if (error.isError()) + const size_t neededSize = bufferDepthPitch * depth; + MemoryBuffer *conversionBuffer = nullptr; + const uint8_t *data = nullptr; + + d3d11::LoadImageFunctionInfo loadFunctionInfo = d3d11Format.loadFunctions.at(type); + if (loadFunctionInfo.requiresConversion) { - return error; - } + error = mRenderer->getScratchMemoryBuffer(neededSize, &conversionBuffer); + if (error.isError()) + { + return error; + } - // TODO: fast path - LoadImageFunction loadFunction = d3d11Format.loadFunctions.at(type); - loadFunction(width, height, depth, - pixelData, srcRowPitch, srcDepthPitch, - conversionBuffer->data(), bufferRowPitch, bufferDepthPitch); + 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(); @@ -652,21 +757,19 @@ gl::Error TextureStorage11::setData(const gl::ImageIndex &index, ImageD3D *image ASSERT(destBox); D3D11_BOX destD3DBox; - destD3DBox.left = destBox->x; - destD3DBox.right = destBox->x + destBox->width; - destD3DBox.top = destBox->y; + 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; + destD3DBox.front = destBox->z; + destD3DBox.back = destBox->z + destBox->depth; - immediateContext->UpdateSubresource(resource, destSubresource, - &destD3DBox, conversionBuffer->data(), + immediateContext->UpdateSubresource(resource, destSubresource, &destD3DBox, data, bufferRowPitch, bufferDepthPitch); } else { - immediateContext->UpdateSubresource(resource, destSubresource, - NULL, conversionBuffer->data(), + immediateContext->UpdateSubresource(resource, destSubresource, nullptr, data, bufferRowPitch, bufferDepthPitch); } @@ -676,107 +779,94 @@ gl::Error TextureStorage11::setData(const gl::ImageIndex &index, ImageD3D *image TextureStorage11_2D::TextureStorage11_2D(Renderer11 *renderer, SwapChain11 *swapchain) : TextureStorage11(renderer, D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE, 0), mTexture(swapchain->getOffscreenTexture()), - mSwizzleTexture(NULL), - mLevelZeroTexture(NULL), - mLevelZeroRenderTarget(NULL), - mUseLevelZeroTexture(false) + mLevelZeroTexture(nullptr), + mLevelZeroRenderTarget(nullptr), + mUseLevelZeroTexture(false), + mSwizzleTexture(nullptr) { mTexture->AddRef(); for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++) { - mAssociatedImages[i] = NULL; - mRenderTarget[i] = NULL; - mSwizzleRenderTargets[i] = NULL; + mAssociatedImages[i] = nullptr; + mRenderTarget[i] = nullptr; + mSwizzleRenderTargets[i] = nullptr; } D3D11_TEXTURE2D_DESC texDesc; mTexture->GetDesc(&texDesc); - mMipLevels = texDesc.MipLevels; - mTextureFormat = texDesc.Format; - mTextureWidth = texDesc.Width; + mMipLevels = texDesc.MipLevels; + mTextureWidth = texDesc.Width; mTextureHeight = texDesc.Height; - mTextureDepth = 1; - - mInternalFormat = swapchain->GetBackBufferInternalFormat(); - - ID3D11ShaderResourceView *srv = swapchain->getRenderTargetShaderResource(); - D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; - srv->GetDesc(&srvDesc); - mShaderResourceFormat = srvDesc.Format; - - ID3D11RenderTargetView* offscreenRTV = swapchain->getRenderTarget(); - D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; - offscreenRTV->GetDesc(&rtvDesc); - mRenderTargetFormat = rtvDesc.Format; - - const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(mTextureFormat); - const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(dxgiFormatInfo.internalFormat, mRenderer->getFeatureLevel()); - mSwizzleTextureFormat = formatInfo.swizzleTexFormat; - mSwizzleShaderResourceFormat = formatInfo.swizzleSRVFormat; - mSwizzleRenderTargetFormat = formatInfo.swizzleRTVFormat; - - mDepthStencilFormat = DXGI_FORMAT_UNKNOWN; - - initializeSerials(1, 1); -} - -TextureStorage11_2D::TextureStorage11_2D(Renderer11 *renderer, GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, int levels, bool hintLevelZeroOnly) - : TextureStorage11(renderer, - GetTextureBindFlags(internalformat, renderer->getFeatureLevel(), renderTarget), - GetTextureMiscFlags(internalformat, renderer->getFeatureLevel(), renderTarget, levels)), - mTexture(NULL), - mSwizzleTexture(NULL), - mLevelZeroTexture(NULL), - mLevelZeroRenderTarget(NULL), - mUseLevelZeroTexture(false) + mTextureDepth = 1; + mHasKeyedMutex = (texDesc.MiscFlags & D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX) != 0; + + mInternalFormat = swapchain->GetRenderTargetInternalFormat(); + + const auto &formatInfo = + d3d11::GetTextureFormatInfo(mInternalFormat, mRenderer->getRenderer11DeviceCaps()); + mTextureFormatSet = formatInfo.formatSet; + mSwizzleFormatSet = formatInfo.swizzleFormatSet; +} + +TextureStorage11_2D::TextureStorage11_2D(Renderer11 *renderer, + GLenum internalformat, + bool renderTarget, + GLsizei width, + GLsizei height, + int levels, + bool hintLevelZeroOnly) + : TextureStorage11( + renderer, + GetTextureBindFlags(internalformat, renderer->getRenderer11DeviceCaps(), renderTarget), + GetTextureMiscFlags(internalformat, + renderer->getRenderer11DeviceCaps(), + renderTarget, + levels)), + mTexture(nullptr), + mHasKeyedMutex(false), + mLevelZeroTexture(nullptr), + mLevelZeroRenderTarget(nullptr), + mUseLevelZeroTexture(hintLevelZeroOnly && levels > 1), + mSwizzleTexture(nullptr) { for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++) { - mAssociatedImages[i] = NULL; - mRenderTarget[i] = NULL; - mSwizzleRenderTargets[i] = NULL; + mAssociatedImages[i] = nullptr; + mRenderTarget[i] = nullptr; + mSwizzleRenderTargets[i] = nullptr; } mInternalFormat = internalformat; - const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(internalformat, renderer->getFeatureLevel()); - mTextureFormat = formatInfo.texFormat; - mShaderResourceFormat = formatInfo.srvFormat; - mDepthStencilFormat = formatInfo.dsvFormat; - mRenderTargetFormat = formatInfo.rtvFormat; - mSwizzleTextureFormat = formatInfo.swizzleTexFormat; - mSwizzleShaderResourceFormat = formatInfo.swizzleSRVFormat; - mSwizzleRenderTargetFormat = formatInfo.swizzleRTVFormat; - - d3d11::MakeValidSize(false, mTextureFormat, &width, &height, &mTopLevel); - mMipLevels = mTopLevel + levels; - mTextureWidth = width; - mTextureHeight = height; - mTextureDepth = 1; + const d3d11::TextureFormat &formatInfo = + d3d11::GetTextureFormatInfo(internalformat, renderer->getRenderer11DeviceCaps()); + mTextureFormatSet = formatInfo.formatSet; + mSwizzleFormatSet = formatInfo.swizzleFormatSet; - if (hintLevelZeroOnly && levels > 1) - { - //The LevelZeroOnly hint should only be true if the zero max LOD workaround is active. - ASSERT(mRenderer->getWorkarounds().zeroMaxLodWorkaround); - mUseLevelZeroTexture = true; - } + d3d11::MakeValidSize(false, mTextureFormatSet->texFormat, &width, &height, &mTopLevel); + mMipLevels = mTopLevel + levels; + mTextureWidth = width; + mTextureHeight = height; + mTextureDepth = 1; - initializeSerials(getLevelCount(), 1); + // The LevelZeroOnly hint should only be true if the zero max LOD workaround is active. + ASSERT(!mUseLevelZeroTexture || mRenderer->getWorkarounds().zeroMaxLodWorkaround); } TextureStorage11_2D::~TextureStorage11_2D() { for (unsigned i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++) { - if (mAssociatedImages[i] != NULL) + if (mAssociatedImages[i] != nullptr) { bool imageAssociationCorrect = mAssociatedImages[i]->isAssociatedStorageValid(this); ASSERT(imageAssociationCorrect); if (imageAssociationCorrect) { - // We must let the Images recover their data before we delete it from the TextureStorage. + // We must let the Images recover their data before we delete it from the + // TextureStorage. gl::Error error = mAssociatedImages[i]->recoverFromAssociatedStorage(); if (error.isError()) { @@ -797,19 +887,26 @@ TextureStorage11_2D::~TextureStorage11_2D() SafeDelete(mRenderTarget[i]); SafeRelease(mSwizzleRenderTargets[i]); } + + if (mHasKeyedMutex) + { + // If the keyed mutex is released that will unbind it and cause the state cache to become + // desynchronized. + mRenderer->getStateManager()->invalidateBoundViews(); + } } gl::Error TextureStorage11_2D::copyToStorage(TextureStorage *destStorage) { ASSERT(destStorage); - TextureStorage11_2D *dest11 = GetAs(destStorage); + TextureStorage11_2D *dest11 = GetAs(destStorage); + ID3D11DeviceContext *immediateContext = mRenderer->getDeviceContext(); if (mRenderer->getWorkarounds().zeroMaxLodWorkaround) { - ID3D11DeviceContext *immediateContext = mRenderer->getDeviceContext(); - - // If either mTexture or mLevelZeroTexture exist, then we need to copy them into the corresponding textures in destStorage. + // If either mTexture or mLevelZeroTexture exist, then we need to copy them into the + // corresponding textures in destStorage. if (mTexture) { gl::Error error = dest11->useLevelZeroWorkaroundTexture(false); @@ -818,7 +915,7 @@ gl::Error TextureStorage11_2D::copyToStorage(TextureStorage *destStorage) return error; } - ID3D11Resource *destResource = NULL; + ID3D11Resource *destResource = nullptr; error = dest11->getResource(&destResource); if (error.isError()) { @@ -836,7 +933,7 @@ gl::Error TextureStorage11_2D::copyToStorage(TextureStorage *destStorage) return error; } - ID3D11Resource *destResource = NULL; + ID3D11Resource *destResource = nullptr; error = dest11->getResource(&destResource); if (error.isError()) { @@ -845,34 +942,36 @@ gl::Error TextureStorage11_2D::copyToStorage(TextureStorage *destStorage) immediateContext->CopyResource(destResource, mLevelZeroTexture); } + + return gl::Error(GL_NO_ERROR); } else { - ID3D11Resource *sourceResouce = NULL; + ID3D11Resource *sourceResouce = nullptr; gl::Error error = getResource(&sourceResouce); if (error.isError()) { return error; } - ID3D11Resource *destResource = NULL; + ID3D11Resource *destResource = nullptr; error = dest11->getResource(&destResource); if (error.isError()) { return error; } - ID3D11DeviceContext *immediateContext = mRenderer->getDeviceContext(); immediateContext->CopyResource(destResource, sourceResouce); + dest11->invalidateSwizzleCache(); } - dest11->invalidateSwizzleCache(); - return gl::Error(GL_NO_ERROR); } gl::Error TextureStorage11_2D::useLevelZeroWorkaroundTexture(bool useLevelZeroTexture) { + bool lastSetting = mUseLevelZeroTexture; + if (useLevelZeroTexture && mMipLevels > 1) { if (!mUseLevelZeroTexture && mTexture) @@ -886,7 +985,7 @@ gl::Error TextureStorage11_2D::useLevelZeroWorkaroundTexture(bool useLevelZeroTe // Pull data back from the mipped texture if necessary. ASSERT(mLevelZeroTexture); ID3D11DeviceContext *context = mRenderer->getDeviceContext(); - context->CopySubresourceRegion(mLevelZeroTexture, 0, 0, 0, 0, mTexture, 0, NULL); + context->CopySubresourceRegion(mLevelZeroTexture, 0, 0, 0, 0, mTexture, 0, nullptr); } mUseLevelZeroTexture = true; @@ -904,18 +1003,34 @@ gl::Error TextureStorage11_2D::useLevelZeroWorkaroundTexture(bool useLevelZeroTe // Pull data back from the level zero texture if necessary. ASSERT(mTexture); ID3D11DeviceContext *context = mRenderer->getDeviceContext(); - context->CopySubresourceRegion(mTexture, 0, 0, 0, 0, mLevelZeroTexture, 0, NULL); + context->CopySubresourceRegion(mTexture, 0, 0, 0, 0, mLevelZeroTexture, 0, nullptr); } mUseLevelZeroTexture = false; } + if (lastSetting != mUseLevelZeroTexture) + { + // Mark everything as dirty to be conservative. + if (mLevelZeroRenderTarget) + { + mLevelZeroRenderTarget->signalDirty(); + } + for (auto *renderTarget : mRenderTarget) + { + if (renderTarget) + { + renderTarget->signalDirty(); + } + } + } + return gl::Error(GL_NO_ERROR); } -void TextureStorage11_2D::associateImage(Image11* image, const gl::ImageIndex &index) +void TextureStorage11_2D::associateImage(Image11 *image, const gl::ImageIndex &index) { - GLint level = index.mipIndex; + const GLint level = index.mipIndex; ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS); @@ -925,13 +1040,15 @@ void TextureStorage11_2D::associateImage(Image11* image, const gl::ImageIndex &i } } -bool TextureStorage11_2D::isAssociatedImageValid(const gl::ImageIndex &index, Image11* expectedImage) +bool TextureStorage11_2D::isAssociatedImageValid(const gl::ImageIndex &index, + Image11 *expectedImage) { - GLint level = index.mipIndex; + const GLint level = index.mipIndex; if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS) { - // This validation check should never return false. It means the Image/TextureStorage association is broken. + // This validation check should never return false. It means the Image/TextureStorage + // association is broken. bool retValue = (mAssociatedImages[level] == expectedImage); ASSERT(retValue); return retValue; @@ -941,9 +1058,9 @@ bool TextureStorage11_2D::isAssociatedImageValid(const gl::ImageIndex &index, Im } // disassociateImage allows an Image to end its association with a Storage. -void TextureStorage11_2D::disassociateImage(const gl::ImageIndex &index, Image11* expectedImage) +void TextureStorage11_2D::disassociateImage(const gl::ImageIndex &index, Image11 *expectedImage) { - GLint level = index.mipIndex; + const GLint level = index.mipIndex; ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS); @@ -953,31 +1070,34 @@ void TextureStorage11_2D::disassociateImage(const gl::ImageIndex &index, Image11 if (mAssociatedImages[level] == expectedImage) { - mAssociatedImages[level] = NULL; + mAssociatedImages[level] = nullptr; } } } -// releaseAssociatedImage prepares the Storage for a new Image association. It lets the old Image recover its data before ending the association. -gl::Error TextureStorage11_2D::releaseAssociatedImage(const gl::ImageIndex &index, Image11* incomingImage) +// releaseAssociatedImage prepares the Storage for a new Image association. It lets the old Image +// recover its data before ending the association. +gl::Error TextureStorage11_2D::releaseAssociatedImage(const gl::ImageIndex &index, + Image11 *incomingImage) { - GLint level = index.mipIndex; + const GLint level = index.mipIndex; 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] != NULL && mAssociatedImages[level] != incomingImage) + if (mAssociatedImages[level] != nullptr && mAssociatedImages[level] != incomingImage) { - // Ensure that the Image is still associated with this TextureStorage. This should be true. + // Ensure that the Image is still associated with this TextureStorage. This should be + // true. bool imageAssociationCorrect = mAssociatedImages[level]->isAssociatedStorageValid(this); ASSERT(imageAssociationCorrect); if (imageAssociationCorrect) { // Force the image to recover from storage before its data is overwritten. - // This will reset mAssociatedImages[level] to NULL too. + // This will reset mAssociatedImages[level] to nullptr too. gl::Error error = mAssociatedImages[level]->recoverFromAssociatedStorage(); if (error.isError()) { @@ -1034,43 +1154,49 @@ gl::Error TextureStorage11_2D::getMippedResource(ID3D11Resource **outResource) gl::Error TextureStorage11_2D::ensureTextureExists(int mipLevels) { // If mMipLevels = 1 then always use mTexture rather than mLevelZeroTexture. - bool useLevelZeroTexture = mRenderer->getWorkarounds().zeroMaxLodWorkaround ? (mipLevels == 1) && (mMipLevels > 1) : false; + bool useLevelZeroTexture = mRenderer->getWorkarounds().zeroMaxLodWorkaround + ? (mipLevels == 1) && (mMipLevels > 1) + : false; ID3D11Texture2D **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 == NULL && mTextureWidth > 0 && mTextureHeight > 0) + if (*outputTexture == nullptr && mTextureWidth > 0 && mTextureHeight > 0) { ASSERT(mipLevels > 0); ID3D11Device *device = mRenderer->getDevice(); D3D11_TEXTURE2D_DESC desc; - desc.Width = mTextureWidth; // Compressed texture size constraints? - desc.Height = mTextureHeight; - desc.MipLevels = mipLevels; - desc.ArraySize = 1; - desc.Format = mTextureFormat; - desc.SampleDesc.Count = 1; + desc.Width = mTextureWidth; // Compressed texture size constraints? + desc.Height = mTextureHeight; + desc.MipLevels = mipLevels; + desc.ArraySize = 1; + desc.Format = mTextureFormatSet->texFormat; + desc.SampleDesc.Count = 1; desc.SampleDesc.Quality = 0; - desc.Usage = D3D11_USAGE_DEFAULT; - desc.BindFlags = getBindFlags(); - desc.CPUAccessFlags = 0; - desc.MiscFlags = getMiscFlags(); + desc.Usage = D3D11_USAGE_DEFAULT; + desc.BindFlags = getBindFlags(); + desc.CPUAccessFlags = 0; + desc.MiscFlags = getMiscFlags(); - HRESULT result = device->CreateTexture2D(&desc, NULL, outputTexture); + HRESULT result = device->CreateTexture2D(&desc, nullptr, outputTexture); // this can happen from windows TDR if (d3d11::isDeviceLostError(result)) { mRenderer->notifyDeviceLost(); - return gl::Error(GL_OUT_OF_MEMORY, "Failed to create 2D texture storage, result: 0x%X.", result); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to create 2D texture storage, result: 0x%X.", + result); } else if (FAILED(result)) { ASSERT(result == E_OUTOFMEMORY); - return gl::Error(GL_OUT_OF_MEMORY, "Failed to create 2D texture storage, result: 0x%X.", result); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to create 2D texture storage, result: 0x%X.", + result); } + + d3d11::SetDebugName(*outputTexture, "TexStorage2D.Texture"); } return gl::Error(GL_NO_ERROR); @@ -1080,131 +1206,155 @@ gl::Error TextureStorage11_2D::getRenderTarget(const gl::ImageIndex &index, Rend { ASSERT(!index.hasLayer()); - int level = index.mipIndex; + const int level = index.mipIndex; ASSERT(level >= 0 && level < getLevelCount()); - // 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->getFeatureLevel() <= D3D_FEATURE_LEVEL_9_3 && level > 0)); - - if (!mRenderTarget[level]) + // 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]) { - ID3D11Resource *texture = NULL; - gl::Error error = getResource(&texture); - if (error.isError()) - { - return error; - } - - ID3D11ShaderResourceView *srv = NULL; - error = getSRVLevel(level, &srv); - if (error.isError()) - { - return error; - } - - if (mUseLevelZeroTexture) - { - if (!mLevelZeroRenderTarget) - { - ID3D11Device *device = mRenderer->getDevice(); - - D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; - rtvDesc.Format = mRenderTargetFormat; - rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D; - rtvDesc.Texture2D.MipSlice = mTopLevel + level; - - ID3D11RenderTargetView *rtv; - HRESULT result = device->CreateRenderTargetView(mLevelZeroTexture, &rtvDesc, &rtv); + *outRT = mRenderTarget[level]; + return gl::Error(GL_NO_ERROR); + } - if (result == E_OUTOFMEMORY) - { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal render target view for texture storage, result: 0x%X.", result); - } - ASSERT(SUCCEEDED(result)); + ID3D11Resource *texture = nullptr; + gl::Error error = getResource(&texture); + if (error.isError()) + { + return error; + } - mLevelZeroRenderTarget = new TextureRenderTarget11(rtv, mLevelZeroTexture, NULL, mInternalFormat, getLevelWidth(level), getLevelHeight(level), 1, 0); + ID3D11ShaderResourceView *srv = nullptr; + error = getSRVLevel(level, false, &srv); + if (error.isError()) + { + return error; + } - // RenderTarget will take ownership of these resources - SafeRelease(rtv); - } + ID3D11ShaderResourceView *blitSRV = nullptr; + error = getSRVLevel(level, true, &blitSRV); + if (error.isError()) + { + return error; + } - ASSERT(outRT); - *outRT = mLevelZeroRenderTarget; - return gl::Error(GL_NO_ERROR); - } + ID3D11Device *device = mRenderer->getDevice(); - if (mRenderTargetFormat != DXGI_FORMAT_UNKNOWN) + if (mUseLevelZeroTexture) + { + if (!mLevelZeroRenderTarget) { - ID3D11Device *device = mRenderer->getDevice(); - D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; - rtvDesc.Format = mRenderTargetFormat; - rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D; + rtvDesc.Format = mTextureFormatSet->rtvFormat; + rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D; rtvDesc.Texture2D.MipSlice = mTopLevel + level; ID3D11RenderTargetView *rtv; - HRESULT result = device->CreateRenderTargetView(texture, &rtvDesc, &rtv); + HRESULT result = device->CreateRenderTargetView(mLevelZeroTexture, &rtvDesc, &rtv); - ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result)); - if (FAILED(result)) + if (result == E_OUTOFMEMORY) { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal render target view for texture storage, result: 0x%X.", result); + return gl::Error(GL_OUT_OF_MEMORY, + "Failed to create internal render target view for texture " + "storage, result: 0x%X.", + result); } + ASSERT(SUCCEEDED(result)); - mRenderTarget[level] = new TextureRenderTarget11(rtv, texture, srv, mInternalFormat, getLevelWidth(level), getLevelHeight(level), 1, 0); + mLevelZeroRenderTarget = new TextureRenderTarget11( + rtv, mLevelZeroTexture, nullptr, nullptr, mInternalFormat, + mTextureFormatSet->format, getLevelWidth(level), getLevelHeight(level), 1, 0); // RenderTarget will take ownership of these resources SafeRelease(rtv); } - else if (mDepthStencilFormat != DXGI_FORMAT_UNKNOWN) - { - ID3D11Device *device = mRenderer->getDevice(); - - D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc; - dsvDesc.Format = mDepthStencilFormat; - dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D; - dsvDesc.Texture2D.MipSlice = mTopLevel + level; - dsvDesc.Flags = 0; - ID3D11DepthStencilView *dsv; - HRESULT result = device->CreateDepthStencilView(texture, &dsvDesc, &dsv); + *outRT = mLevelZeroRenderTarget; + return gl::Error(GL_NO_ERROR); + } - ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result)); - if (FAILED(result)) - { - return gl::Error(GL_OUT_OF_MEMORY,"Failed to create internal depth stencil view for texture storage, result: 0x%X.", result); - } + if (mTextureFormatSet->rtvFormat != DXGI_FORMAT_UNKNOWN) + { + D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; + rtvDesc.Format = mTextureFormatSet->rtvFormat; + rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D; + rtvDesc.Texture2D.MipSlice = mTopLevel + level; - mRenderTarget[level] = new TextureRenderTarget11(dsv, texture, srv, mInternalFormat, getLevelWidth(level), getLevelHeight(level), 1, 0); + ID3D11RenderTargetView *rtv; + HRESULT result = device->CreateRenderTargetView(texture, &rtvDesc, &rtv); - // RenderTarget will take ownership of these resources - SafeRelease(dsv); - } - else + ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result)); + if (FAILED(result)) { - UNREACHABLE(); + return gl::Error( + GL_OUT_OF_MEMORY, + "Failed to create internal render target view for texture storage, result: 0x%X.", + result); } + + mRenderTarget[level] = new TextureRenderTarget11( + rtv, texture, srv, blitSRV, mInternalFormat, mTextureFormatSet->format, + getLevelWidth(level), getLevelHeight(level), 1, 0); + + // RenderTarget will take ownership of these resources + SafeRelease(rtv); + + *outRT = mRenderTarget[level]; + return gl::Error(GL_NO_ERROR); } - ASSERT(outRT); + ASSERT(mTextureFormatSet->dsvFormat != DXGI_FORMAT_UNKNOWN); + + D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc; + dsvDesc.Format = mTextureFormatSet->dsvFormat; + dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D; + dsvDesc.Texture2D.MipSlice = mTopLevel + level; + dsvDesc.Flags = 0; + + ID3D11DepthStencilView *dsv; + HRESULT result = device->CreateDepthStencilView(texture, &dsvDesc, &dsv); + + ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result)); + if (FAILED(result)) + { + return gl::Error( + GL_OUT_OF_MEMORY, + "Failed to create internal depth stencil view for texture storage, result: 0x%X.", + result); + } + + mRenderTarget[level] = + new TextureRenderTarget11(dsv, texture, srv, mInternalFormat, mTextureFormatSet->format, + getLevelWidth(level), getLevelHeight(level), 1, 0); + + // RenderTarget will take ownership of these resources + SafeRelease(dsv); + *outRT = mRenderTarget[level]; return gl::Error(GL_NO_ERROR); } -gl::Error TextureStorage11_2D::createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture, +gl::Error TextureStorage11_2D::createSRV(int baseLevel, + int mipLevels, + DXGI_FORMAT format, + ID3D11Resource *texture, ID3D11ShaderResourceView **outSRV) const { ASSERT(outSRV); D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; - srvDesc.Format = format; - srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; + srvDesc.Format = format; + srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; srvDesc.Texture2D.MostDetailedMip = mTopLevel + baseLevel; - srvDesc.Texture2D.MipLevels = mipLevels; + srvDesc.Texture2D.MipLevels = mipLevels; ID3D11Resource *srvTexture = texture; @@ -1212,31 +1362,35 @@ gl::Error TextureStorage11_2D::createSRV(int baseLevel, int mipLevels, DXGI_FORM { ASSERT(mTopLevel == 0); ASSERT(baseLevel == 0); - // This code also assumes that the incoming texture equals either mLevelZeroTexture or mTexture. + // 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. - ASSERT(mLevelZeroTexture != NULL && texture == mLevelZeroTexture); + ASSERT(mLevelZeroTexture != nullptr && texture == mLevelZeroTexture); srvTexture = mLevelZeroTexture; } else { ASSERT(mipLevels == static_cast(mMipLevels)); - ASSERT(mTexture != NULL && texture == mTexture); + ASSERT(mTexture != nullptr && texture == mTexture); srvTexture = mTexture; } } ID3D11Device *device = mRenderer->getDevice(); - HRESULT result = device->CreateShaderResourceView(srvTexture, &srvDesc, outSRV); + HRESULT result = device->CreateShaderResourceView(srvTexture, &srvDesc, outSRV); ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result)); if (FAILED(result)) { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal texture storage SRV, result: 0x%X.", result); + return gl::Error(GL_OUT_OF_MEMORY, + "Failed to create internal texture storage SRV, result: 0x%X.", result); } + d3d11::SetDebugName(*outSRV, "TexStorage2D.SRV"); + return gl::Error(GL_NO_ERROR); } @@ -1249,25 +1403,28 @@ gl::Error TextureStorage11_2D::getSwizzleTexture(ID3D11Resource **outTexture) ID3D11Device *device = mRenderer->getDevice(); D3D11_TEXTURE2D_DESC desc; - desc.Width = mTextureWidth; - desc.Height = mTextureHeight; - desc.MipLevels = mMipLevels; - desc.ArraySize = 1; - desc.Format = mSwizzleTextureFormat; - desc.SampleDesc.Count = 1; + desc.Width = mTextureWidth; + desc.Height = mTextureHeight; + desc.MipLevels = mMipLevels; + desc.ArraySize = 1; + desc.Format = mSwizzleFormatSet->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; + desc.Usage = D3D11_USAGE_DEFAULT; + desc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET; + desc.CPUAccessFlags = 0; + desc.MiscFlags = 0; - HRESULT result = device->CreateTexture2D(&desc, NULL, &mSwizzleTexture); + HRESULT result = device->CreateTexture2D(&desc, nullptr, &mSwizzleTexture); ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result)); if (FAILED(result)) { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal swizzle texture, result: 0x%X.", result); + return gl::Error(GL_OUT_OF_MEMORY, + "Failed to create internal swizzle texture, result: 0x%X.", result); } + + d3d11::SetDebugName(mSwizzleTexture, "TexStorage2D.SwizzleTexture"); } *outTexture = mSwizzleTexture; @@ -1281,7 +1438,7 @@ gl::Error TextureStorage11_2D::getSwizzleRenderTarget(int mipLevel, ID3D11Render if (!mSwizzleRenderTargets[mipLevel]) { - ID3D11Resource *swizzleTexture = NULL; + ID3D11Resource *swizzleTexture = nullptr; gl::Error error = getSwizzleTexture(&swizzleTexture); if (error.isError()) { @@ -1291,16 +1448,19 @@ gl::Error TextureStorage11_2D::getSwizzleRenderTarget(int mipLevel, ID3D11Render ID3D11Device *device = mRenderer->getDevice(); D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; - rtvDesc.Format = mSwizzleRenderTargetFormat; - rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D; + rtvDesc.Format = mSwizzleFormatSet->rtvFormat; + rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D; rtvDesc.Texture2D.MipSlice = mTopLevel + mipLevel; - HRESULT result = device->CreateRenderTargetView(mSwizzleTexture, &rtvDesc, &mSwizzleRenderTargets[mipLevel]); + HRESULT result = device->CreateRenderTargetView(mSwizzleTexture, &rtvDesc, + &mSwizzleRenderTargets[mipLevel]); ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result)); if (FAILED(result)) { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal swizzle render target view, result: 0x%X.", result); + return gl::Error(GL_OUT_OF_MEMORY, + "Failed to create internal swizzle render target view, result: 0x%X.", + result); } } @@ -1308,60 +1468,349 @@ gl::Error TextureStorage11_2D::getSwizzleRenderTarget(int mipLevel, ID3D11Render return gl::Error(GL_NO_ERROR); } -TextureStorage11_Cube::TextureStorage11_Cube(Renderer11 *renderer, GLenum internalformat, bool renderTarget, int size, int levels, bool hintLevelZeroOnly) - : TextureStorage11(renderer, - GetTextureBindFlags(internalformat, renderer->getFeatureLevel(), renderTarget), - GetTextureMiscFlags(internalformat, renderer->getFeatureLevel(), renderTarget, levels)) +TextureStorage11_EGLImage::TextureStorage11_EGLImage(Renderer11 *renderer, EGLImageD3D *eglImage) + : TextureStorage11(renderer, D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE, 0), + mImage(eglImage), + mCurrentRenderTarget(0), + mSwizzleTexture(nullptr), + mSwizzleRenderTargets(gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS, nullptr) +{ + RenderTargetD3D *renderTargetD3D = nullptr; + mImage->getRenderTarget(&renderTargetD3D); + RenderTarget11 *renderTarget11 = GetAs(renderTargetD3D); + mCurrentRenderTarget = reinterpret_cast(renderTarget11); + + mMipLevels = 1; + mTextureFormatSet = &d3d11::GetANGLEFormatSet(renderTarget11->getANGLEFormat()); + mSwizzleFormatSet = &d3d11::GetANGLEFormatSet(mTextureFormatSet->swizzleFormat); + mTextureWidth = renderTarget11->getWidth(); + mTextureHeight = renderTarget11->getHeight(); + mTextureDepth = 1; + mInternalFormat = renderTarget11->getInternalFormat(); +} + +TextureStorage11_EGLImage::~TextureStorage11_EGLImage() +{ + SafeRelease(mSwizzleTexture); + for (size_t i = 0; i < mSwizzleRenderTargets.size(); i++) + { + SafeRelease(mSwizzleRenderTargets[i]); + } +} + +gl::Error TextureStorage11_EGLImage::getResource(ID3D11Resource **outResource) +{ + gl::Error error = checkForUpdatedRenderTarget(); + if (error.isError()) + { + return error; + } + + RenderTarget11 *renderTarget11 = nullptr; + error = getImageRenderTarget(&renderTarget11); + if (error.isError()) + { + return error; + } + + *outResource = renderTarget11->getTexture(); + return gl::Error(GL_NO_ERROR); +} + +gl::Error TextureStorage11_EGLImage::getSRV(const gl::TextureState &textureState, + ID3D11ShaderResourceView **outSRV) { - mTexture = NULL; - mSwizzleTexture = NULL; + gl::Error error = checkForUpdatedRenderTarget(); + if (error.isError()) + { + return error; + } + + return TextureStorage11::getSRV(textureState, outSRV); +} + +gl::Error TextureStorage11_EGLImage::getMippedResource(ID3D11Resource **) +{ + // This shouldn't be called unless the zero max LOD workaround is active. + // EGL images are unavailable in this configuration. + UNREACHABLE(); + return gl::Error(GL_INVALID_OPERATION); +} + +gl::Error TextureStorage11_EGLImage::getRenderTarget(const gl::ImageIndex &index, + RenderTargetD3D **outRT) +{ + ASSERT(!index.hasLayer()); + ASSERT(index.mipIndex == 0); + UNUSED_ASSERTION_VARIABLE(index); + + gl::Error error = checkForUpdatedRenderTarget(); + if (error.isError()) + { + return error; + } + + return mImage->getRenderTarget(outRT); +} + +gl::Error TextureStorage11_EGLImage::copyToStorage(TextureStorage *destStorage) +{ + ID3D11Resource *sourceResouce = nullptr; + gl::Error error = getResource(&sourceResouce); + if (error.isError()) + { + return error; + } + + ASSERT(destStorage); + TextureStorage11_2D *dest11 = GetAs(destStorage); + ID3D11Resource *destResource = nullptr; + error = dest11->getResource(&destResource); + if (error.isError()) + { + return error; + } + ID3D11DeviceContext *immediateContext = mRenderer->getDeviceContext(); + immediateContext->CopyResource(destResource, sourceResouce); + + dest11->invalidateSwizzleCache(); + + return gl::Error(GL_NO_ERROR); +} + +void TextureStorage11_EGLImage::associateImage(Image11 *, const gl::ImageIndex &) +{ +} + +void TextureStorage11_EGLImage::disassociateImage(const gl::ImageIndex &, Image11 *) +{ +} + +bool TextureStorage11_EGLImage::isAssociatedImageValid(const gl::ImageIndex &, Image11 *) +{ + return false; +} + +gl::Error TextureStorage11_EGLImage::releaseAssociatedImage(const gl::ImageIndex &, Image11 *) +{ + return gl::Error(GL_NO_ERROR); +} + +gl::Error TextureStorage11_EGLImage::useLevelZeroWorkaroundTexture(bool) +{ + UNREACHABLE(); + return gl::Error(GL_INVALID_OPERATION); +} + +gl::Error TextureStorage11_EGLImage::getSwizzleTexture(ID3D11Resource **outTexture) +{ + ASSERT(outTexture); + + if (!mSwizzleTexture) + { + ID3D11Device *device = mRenderer->getDevice(); + + D3D11_TEXTURE2D_DESC desc; + desc.Width = mTextureWidth; + desc.Height = mTextureHeight; + desc.MipLevels = mMipLevels; + desc.ArraySize = 1; + desc.Format = mSwizzleFormatSet->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; + + HRESULT result = device->CreateTexture2D(&desc, nullptr, &mSwizzleTexture); + + ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result)); + if (FAILED(result)) + { + return gl::Error(GL_OUT_OF_MEMORY, + "Failed to create internal swizzle texture, result: 0x%X.", result); + } + + d3d11::SetDebugName(mSwizzleTexture, "TexStorageEGLImage.SwizzleTexture"); + } + + *outTexture = mSwizzleTexture; + return gl::Error(GL_NO_ERROR); +} + +gl::Error TextureStorage11_EGLImage::getSwizzleRenderTarget(int mipLevel, + ID3D11RenderTargetView **outRTV) +{ + ASSERT(mipLevel >= 0 && mipLevel < getLevelCount()); + ASSERT(outRTV); + + if (!mSwizzleRenderTargets[mipLevel]) + { + ID3D11Resource *swizzleTexture = nullptr; + gl::Error error = getSwizzleTexture(&swizzleTexture); + if (error.isError()) + { + return error; + } + + ID3D11Device *device = mRenderer->getDevice(); + + D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; + rtvDesc.Format = mSwizzleFormatSet->rtvFormat; + rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D; + rtvDesc.Texture2D.MipSlice = mTopLevel + mipLevel; + + HRESULT result = device->CreateRenderTargetView(mSwizzleTexture, &rtvDesc, + &mSwizzleRenderTargets[mipLevel]); + + ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result)); + if (FAILED(result)) + { + return gl::Error(GL_OUT_OF_MEMORY, + "Failed to create internal swizzle render target view, result: 0x%X.", + result); + } + } + + *outRTV = mSwizzleRenderTargets[mipLevel]; + return gl::Error(GL_NO_ERROR); +} + +gl::Error TextureStorage11_EGLImage::checkForUpdatedRenderTarget() +{ + RenderTarget11 *renderTarget11 = nullptr; + gl::Error error = getImageRenderTarget(&renderTarget11); + if (error.isError()) + { + return error; + } + + if (mCurrentRenderTarget != reinterpret_cast(renderTarget11)) + { + clearSRVCache(); + mCurrentRenderTarget = reinterpret_cast(renderTarget11); + } + + return gl::Error(GL_NO_ERROR); +} + +gl::Error TextureStorage11_EGLImage::createSRV(int baseLevel, + int mipLevels, + DXGI_FORMAT format, + ID3D11Resource *texture, + ID3D11ShaderResourceView **outSRV) const +{ + 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; + + ID3D11Device *device = mRenderer->getDevice(); + HRESULT result = device->CreateShaderResourceView(texture, &srvDesc, outSRV); + + ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result)); + if (FAILED(result)) + { + return gl::Error(GL_OUT_OF_MEMORY, + "Failed to create internal texture storage SRV, result: 0x%X.", + result); + } + + d3d11::SetDebugName(*outSRV, "TexStorageEGLImage.SRV"); + } + else + { + RenderTarget11 *renderTarget = nullptr; + gl::Error error = getImageRenderTarget(&renderTarget); + if (error.isError()) + { + return error; + } + + ASSERT(texture == renderTarget->getTexture()); + + *outSRV = renderTarget->getShaderResourceView(); + (*outSRV)->AddRef(); + } + + return gl::Error(GL_NO_ERROR); +} + +gl::Error TextureStorage11_EGLImage::getImageRenderTarget(RenderTarget11 **outRT) const +{ + RenderTargetD3D *renderTargetD3D = nullptr; + gl::Error error = mImage->getRenderTarget(&renderTargetD3D); + if (error.isError()) + { + return error; + } + + *outRT = GetAs(renderTargetD3D); + return gl::Error(GL_NO_ERROR); +} + +TextureStorage11_Cube::TextureStorage11_Cube(Renderer11 *renderer, + GLenum internalformat, + bool renderTarget, + int size, + int levels, + bool hintLevelZeroOnly) + : TextureStorage11( + renderer, + GetTextureBindFlags(internalformat, renderer->getRenderer11DeviceCaps(), renderTarget), + GetTextureMiscFlags(internalformat, + renderer->getRenderer11DeviceCaps(), + renderTarget, + levels)), + mTexture(nullptr), + mLevelZeroTexture(nullptr), + mUseLevelZeroTexture(hintLevelZeroOnly && levels > 1), + mSwizzleTexture(nullptr) +{ for (unsigned int level = 0; level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++) { - mSwizzleRenderTargets[level] = NULL; + mSwizzleRenderTargets[level] = nullptr; for (unsigned int face = 0; face < CUBE_FACE_COUNT; face++) { - mAssociatedImages[face][level] = NULL; - mRenderTarget[face][level] = NULL; + mAssociatedImages[face][level] = nullptr; + mRenderTarget[face][level] = nullptr; } } - mLevelZeroTexture = NULL; - mUseLevelZeroTexture = false; - for (unsigned int face = 0; face < CUBE_FACE_COUNT; face++) { - mLevelZeroRenderTarget[face] = NULL; + mLevelZeroRenderTarget[face] = nullptr; } mInternalFormat = internalformat; - const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(internalformat, renderer->getFeatureLevel()); - mTextureFormat = formatInfo.texFormat; - mShaderResourceFormat = formatInfo.srvFormat; - mDepthStencilFormat = formatInfo.dsvFormat; - mRenderTargetFormat = formatInfo.rtvFormat; - mSwizzleTextureFormat = formatInfo.swizzleTexFormat; - mSwizzleShaderResourceFormat = formatInfo.swizzleSRVFormat; - mSwizzleRenderTargetFormat = formatInfo.swizzleRTVFormat; + const d3d11::TextureFormat &formatInfo = + d3d11::GetTextureFormatInfo(internalformat, renderer->getRenderer11DeviceCaps()); + mTextureFormatSet = formatInfo.formatSet; + mSwizzleFormatSet = formatInfo.swizzleFormatSet; // adjust size if needed for compressed textures int height = size; - d3d11::MakeValidSize(false, mTextureFormat, &size, &height, &mTopLevel); + d3d11::MakeValidSize(false, mTextureFormatSet->texFormat, &size, &height, &mTopLevel); - mMipLevels = mTopLevel + levels; - mTextureWidth = size; + mMipLevels = mTopLevel + levels; + mTextureWidth = size; mTextureHeight = size; - mTextureDepth = 1; + mTextureDepth = 1; - if (hintLevelZeroOnly && levels > 1) - { - //The LevelZeroOnly hint should only be true if the zero max LOD workaround is active. - ASSERT(mRenderer->getWorkarounds().zeroMaxLodWorkaround); - mUseLevelZeroTexture = true; - } - - initializeSerials(getLevelCount() * CUBE_FACE_COUNT, CUBE_FACE_COUNT); + // The LevelZeroOnly hint should only be true if the zero max LOD workaround is active. + ASSERT(!mUseLevelZeroTexture || mRenderer->getWorkarounds().zeroMaxLodWorkaround); } TextureStorage11_Cube::~TextureStorage11_Cube() @@ -1370,14 +1819,16 @@ TextureStorage11_Cube::~TextureStorage11_Cube() { for (unsigned int face = 0; face < CUBE_FACE_COUNT; face++) { - if (mAssociatedImages[face][level] != NULL) + if (mAssociatedImages[face][level] != nullptr) { - bool imageAssociationCorrect = mAssociatedImages[face][level]->isAssociatedStorageValid(this); + bool imageAssociationCorrect = + mAssociatedImages[face][level]->isAssociatedStorageValid(this); ASSERT(imageAssociationCorrect); if (imageAssociationCorrect) { - // We must let the Images recover their data before we delete it from the TextureStorage. + // We must let the Images recover their data before we delete it from the + // TextureStorage. mAssociatedImages[face][level]->recoverFromAssociatedStorage(); } } @@ -1405,17 +1856,18 @@ TextureStorage11_Cube::~TextureStorage11_Cube() UINT TextureStorage11_Cube::getSubresourceIndex(const gl::ImageIndex &index) const { - if (mRenderer->getWorkarounds().zeroMaxLodWorkaround && mUseLevelZeroTexture && index.mipIndex == 0) + if (mRenderer->getWorkarounds().zeroMaxLodWorkaround && mUseLevelZeroTexture && + index.mipIndex == 0) { - UINT arraySlice = static_cast(index.hasLayer() ? index.layerIndex : 0); + UINT arraySlice = static_cast(index.hasLayer() ? index.layerIndex : 0); UINT subresource = D3D11CalcSubresource(0, arraySlice, 1); ASSERT(subresource != std::numeric_limits::max()); return subresource; } else { - UINT mipSlice = static_cast(index.mipIndex + mTopLevel); - UINT arraySlice = static_cast(index.hasLayer() ? index.layerIndex : 0); + UINT mipSlice = static_cast(index.mipIndex + mTopLevel); + UINT arraySlice = static_cast(index.hasLayer() ? index.layerIndex : 0); UINT subresource = D3D11CalcSubresource(mipSlice, arraySlice, mMipLevels); ASSERT(subresource != std::numeric_limits::max()); return subresource; @@ -1432,7 +1884,8 @@ gl::Error TextureStorage11_Cube::copyToStorage(TextureStorage *destStorage) { ID3D11DeviceContext *immediateContext = mRenderer->getDeviceContext(); - // If either mTexture or mLevelZeroTexture exist, then we need to copy them into the corresponding textures in destStorage. + // If either mTexture or mLevelZeroTexture exist, then we need to copy them into the + // corresponding textures in destStorage. if (mTexture) { gl::Error error = dest11->useLevelZeroWorkaroundTexture(false); @@ -1441,7 +1894,7 @@ gl::Error TextureStorage11_Cube::copyToStorage(TextureStorage *destStorage) return error; } - ID3D11Resource *destResource = NULL; + ID3D11Resource *destResource = nullptr; error = dest11->getResource(&destResource); if (error.isError()) { @@ -1459,7 +1912,7 @@ gl::Error TextureStorage11_Cube::copyToStorage(TextureStorage *destStorage) return error; } - ID3D11Resource *destResource = NULL; + ID3D11Resource *destResource = nullptr; error = dest11->getResource(&destResource); if (error.isError()) { @@ -1471,14 +1924,14 @@ gl::Error TextureStorage11_Cube::copyToStorage(TextureStorage *destStorage) } else { - ID3D11Resource *sourceResouce = NULL; + ID3D11Resource *sourceResouce = nullptr; gl::Error error = getResource(&sourceResouce); if (error.isError()) { return error; } - ID3D11Resource *destResource = NULL; + ID3D11Resource *destResource = nullptr; error = dest11->getResource(&destResource); if (error.isError()) { @@ -1512,7 +1965,8 @@ gl::Error TextureStorage11_Cube::useLevelZeroWorkaroundTexture(bool useLevelZero for (int face = 0; face < 6; face++) { - context->CopySubresourceRegion(mLevelZeroTexture, D3D11CalcSubresource(0, face, 1), 0, 0, 0, mTexture, face * mMipLevels, NULL); + context->CopySubresourceRegion(mLevelZeroTexture, D3D11CalcSubresource(0, face, 1), + 0, 0, 0, mTexture, face * mMipLevels, nullptr); } } @@ -1534,7 +1988,8 @@ gl::Error TextureStorage11_Cube::useLevelZeroWorkaroundTexture(bool useLevelZero for (int face = 0; face < 6; face++) { - context->CopySubresourceRegion(mTexture, D3D11CalcSubresource(0, face, mMipLevels), 0, 0, 0, mLevelZeroTexture, face, NULL); + context->CopySubresourceRegion(mTexture, D3D11CalcSubresource(0, face, mMipLevels), + 0, 0, 0, mLevelZeroTexture, face, nullptr); } } @@ -1544,10 +1999,10 @@ gl::Error TextureStorage11_Cube::useLevelZeroWorkaroundTexture(bool useLevelZero return gl::Error(GL_NO_ERROR); } -void TextureStorage11_Cube::associateImage(Image11* image, const gl::ImageIndex &index) +void TextureStorage11_Cube::associateImage(Image11 *image, const gl::ImageIndex &index) { - GLint level = index.mipIndex; - GLint layerTarget = index.layerIndex; + const GLint level = index.mipIndex; + const GLint layerTarget = index.layerIndex; ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS); ASSERT(0 <= layerTarget && layerTarget < CUBE_FACE_COUNT); @@ -1561,16 +2016,18 @@ void TextureStorage11_Cube::associateImage(Image11* image, const gl::ImageIndex } } -bool TextureStorage11_Cube::isAssociatedImageValid(const gl::ImageIndex &index, Image11* expectedImage) +bool TextureStorage11_Cube::isAssociatedImageValid(const gl::ImageIndex &index, + Image11 *expectedImage) { - GLint level = index.mipIndex; - GLint layerTarget = index.layerIndex; + const GLint level = index.mipIndex; + const GLint layerTarget = index.layerIndex; if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS) { if (0 <= layerTarget && layerTarget < CUBE_FACE_COUNT) { - // This validation check should never return false. It means the Image/TextureStorage association is broken. + // This validation check should never return false. It means the Image/TextureStorage + // association is broken. bool retValue = (mAssociatedImages[layerTarget][level] == expectedImage); ASSERT(retValue); return retValue; @@ -1581,10 +2038,10 @@ bool TextureStorage11_Cube::isAssociatedImageValid(const gl::ImageIndex &index, } // disassociateImage allows an Image to end its association with a Storage. -void TextureStorage11_Cube::disassociateImage(const gl::ImageIndex &index, Image11* expectedImage) +void TextureStorage11_Cube::disassociateImage(const gl::ImageIndex &index, Image11 *expectedImage) { - GLint level = index.mipIndex; - GLint layerTarget = index.layerIndex; + const GLint level = index.mipIndex; + const GLint layerTarget = index.layerIndex; ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS); ASSERT(0 <= layerTarget && layerTarget < CUBE_FACE_COUNT); @@ -1597,17 +2054,19 @@ void TextureStorage11_Cube::disassociateImage(const gl::ImageIndex &index, Image if (mAssociatedImages[layerTarget][level] == expectedImage) { - mAssociatedImages[layerTarget][level] = NULL; + 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. -gl::Error TextureStorage11_Cube::releaseAssociatedImage(const gl::ImageIndex &index, Image11* incomingImage) +// releaseAssociatedImage prepares the Storage for a new Image association. It lets the old Image +// recover its data before ending the association. +gl::Error TextureStorage11_Cube::releaseAssociatedImage(const gl::ImageIndex &index, + Image11 *incomingImage) { - GLint level = index.mipIndex; - GLint layerTarget = index.layerIndex; + const GLint level = index.mipIndex; + const GLint layerTarget = index.layerIndex; ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS); ASSERT(0 <= layerTarget && layerTarget < CUBE_FACE_COUNT); @@ -1617,17 +2076,21 @@ gl::Error TextureStorage11_Cube::releaseAssociatedImage(const gl::ImageIndex &in if (0 <= layerTarget && layerTarget < CUBE_FACE_COUNT) { // No need to let the old Image recover its data, if it is also the incoming Image. - if (mAssociatedImages[layerTarget][level] != NULL && mAssociatedImages[layerTarget][level] != incomingImage) + if (mAssociatedImages[layerTarget][level] != nullptr && + mAssociatedImages[layerTarget][level] != incomingImage) { - // Ensure that the Image is still associated with this TextureStorage. This should be true. - bool imageAssociationCorrect = mAssociatedImages[layerTarget][level]->isAssociatedStorageValid(this); + // Ensure that the Image is still associated with this TextureStorage. This should + // be true. + bool imageAssociationCorrect = + mAssociatedImages[layerTarget][level]->isAssociatedStorageValid(this); ASSERT(imageAssociationCorrect); if (imageAssociationCorrect) { // Force the image to recover from storage before its data is overwritten. - // This will reset mAssociatedImages[level] to NULL too. - gl::Error error = mAssociatedImages[layerTarget][level]->recoverFromAssociatedStorage(); + // This will reset mAssociatedImages[level] to nullptr too. + gl::Error error = + mAssociatedImages[layerTarget][level]->recoverFromAssociatedStorage(); if (error.isError()) { return error; @@ -1684,52 +2147,95 @@ gl::Error TextureStorage11_Cube::getMippedResource(ID3D11Resource **outResource) gl::Error TextureStorage11_Cube::ensureTextureExists(int mipLevels) { // If mMipLevels = 1 then always use mTexture rather than mLevelZeroTexture. - bool useLevelZeroTexture = mRenderer->getWorkarounds().zeroMaxLodWorkaround ? (mipLevels == 1) && (mMipLevels > 1) : false; + bool useLevelZeroTexture = mRenderer->getWorkarounds().zeroMaxLodWorkaround + ? (mipLevels == 1) && (mMipLevels > 1) + : false; ID3D11Texture2D **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 == NULL && mTextureWidth > 0 && mTextureHeight > 0) + if (*outputTexture == nullptr && mTextureWidth > 0 && mTextureHeight > 0) { ASSERT(mMipLevels > 0); ID3D11Device *device = mRenderer->getDevice(); D3D11_TEXTURE2D_DESC desc; - desc.Width = mTextureWidth; - desc.Height = mTextureHeight; - desc.MipLevels = mipLevels; - desc.ArraySize = CUBE_FACE_COUNT; - desc.Format = mTextureFormat; - desc.SampleDesc.Count = 1; + desc.Width = mTextureWidth; + desc.Height = mTextureHeight; + desc.MipLevels = mipLevels; + desc.ArraySize = CUBE_FACE_COUNT; + desc.Format = mTextureFormatSet->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(); + desc.Usage = D3D11_USAGE_DEFAULT; + desc.BindFlags = getBindFlags(); + desc.CPUAccessFlags = 0; + desc.MiscFlags = D3D11_RESOURCE_MISC_TEXTURECUBE | getMiscFlags(); - HRESULT result = device->CreateTexture2D(&desc, NULL, outputTexture); + HRESULT result = device->CreateTexture2D(&desc, nullptr, outputTexture); // this can happen from windows TDR if (d3d11::isDeviceLostError(result)) { mRenderer->notifyDeviceLost(); - return gl::Error(GL_OUT_OF_MEMORY, "Failed to create cube texture storage, result: 0x%X.", result); + return gl::Error(GL_OUT_OF_MEMORY, + "Failed to create cube texture storage, result: 0x%X.", result); } else if (FAILED(result)) { ASSERT(result == E_OUTOFMEMORY); - return gl::Error(GL_OUT_OF_MEMORY, "Failed to create cube texture storage, result: 0x%X.", result); + return gl::Error(GL_OUT_OF_MEMORY, + "Failed to create cube texture storage, result: 0x%X.", result); } + + d3d11::SetDebugName(*outputTexture, "TexStorageCube.Texture"); + } + + return gl::Error(GL_NO_ERROR); +} + +gl::Error TextureStorage11_Cube::createRenderTargetSRV(ID3D11Resource *texture, + const gl::ImageIndex &index, + DXGI_FORMAT resourceFormat, + ID3D11ShaderResourceView **srv) const +{ + ID3D11Device *device = mRenderer->getDevice(); + D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; + srvDesc.Format = resourceFormat; + srvDesc.Texture2DArray.MostDetailedMip = mTopLevel + index.mipIndex; + srvDesc.Texture2DArray.MipLevels = 1; + srvDesc.Texture2DArray.FirstArraySlice = index.layerIndex; + srvDesc.Texture2DArray.ArraySize = 1; + + if (mRenderer->getRenderer11DeviceCaps().featureLevel <= D3D_FEATURE_LEVEL_9_3) + { + srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE; + } + else + { + // Will be used with Texture2D sampler, not TextureCube + srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY; } + HRESULT result = device->CreateShaderResourceView(texture, &srvDesc, srv); + + ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result)); + if (FAILED(result)) + { + return gl::Error( + GL_OUT_OF_MEMORY, + "Failed to create internal shader resource view for texture storage, result: 0x%X.", + result); + } return gl::Error(GL_NO_ERROR); } -gl::Error TextureStorage11_Cube::getRenderTarget(const gl::ImageIndex &index, RenderTargetD3D **outRT) +gl::Error TextureStorage11_Cube::getRenderTarget(const gl::ImageIndex &index, + RenderTargetD3D **outRT) { - int faceIndex = index.layerIndex; - int level = index.mipIndex; + const int faceIndex = index.layerIndex; + const int level = index.mipIndex; ASSERT(level >= 0 && level < getLevelCount()); ASSERT(faceIndex >= 0 && faceIndex < CUBE_FACE_COUNT); @@ -1739,7 +2245,7 @@ gl::Error TextureStorage11_Cube::getRenderTarget(const gl::ImageIndex &index, Re ID3D11Device *device = mRenderer->getDevice(); HRESULT result; - ID3D11Resource *texture = NULL; + ID3D11Resource *texture = nullptr; gl::Error error = getResource(&texture); if (error.isError()) { @@ -1751,22 +2257,27 @@ gl::Error TextureStorage11_Cube::getRenderTarget(const gl::ImageIndex &index, Re if (!mLevelZeroRenderTarget[faceIndex]) { D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; - rtvDesc.Format = mRenderTargetFormat; - rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY; - rtvDesc.Texture2DArray.MipSlice = mTopLevel + level; + rtvDesc.Format = mTextureFormatSet->rtvFormat; + rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY; + rtvDesc.Texture2DArray.MipSlice = mTopLevel + level; rtvDesc.Texture2DArray.FirstArraySlice = faceIndex; - rtvDesc.Texture2DArray.ArraySize = 1; + rtvDesc.Texture2DArray.ArraySize = 1; ID3D11RenderTargetView *rtv; result = device->CreateRenderTargetView(mLevelZeroTexture, &rtvDesc, &rtv); if (result == E_OUTOFMEMORY) { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal render target view for texture storage, result: 0x%X.", result); + return gl::Error(GL_OUT_OF_MEMORY, + "Failed to create internal render target view for texture " + "storage, result: 0x%X.", + result); } ASSERT(SUCCEEDED(result)); - mLevelZeroRenderTarget[faceIndex] = new TextureRenderTarget11(rtv, mLevelZeroTexture, NULL, mInternalFormat, getLevelWidth(level), getLevelHeight(level), 1, 0); + mLevelZeroRenderTarget[faceIndex] = new TextureRenderTarget11( + rtv, mLevelZeroTexture, nullptr, nullptr, mInternalFormat, + mTextureFormatSet->format, getLevelWidth(level), getLevelHeight(level), 1, 0); // RenderTarget will take ownership of these resources SafeRelease(rtv); @@ -1777,39 +2288,39 @@ gl::Error TextureStorage11_Cube::getRenderTarget(const gl::ImageIndex &index, Re return gl::Error(GL_NO_ERROR); } - D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; - srvDesc.Format = mShaderResourceFormat; - srvDesc.Texture2DArray.MostDetailedMip = mTopLevel + level; - srvDesc.Texture2DArray.MipLevels = 1; - srvDesc.Texture2DArray.FirstArraySlice = faceIndex; - srvDesc.Texture2DArray.ArraySize = 1; - - if (mRenderer->getFeatureLevel() <= D3D_FEATURE_LEVEL_9_3) + ID3D11ShaderResourceView *srv = nullptr; + error = createRenderTargetSRV(texture, index, mTextureFormatSet->srvFormat, &srv); + if (error.isError()) { - srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE; + return error; } - else + ID3D11ShaderResourceView *blitSRV = nullptr; + if (mTextureFormatSet->blitSRVFormat != mTextureFormatSet->srvFormat) { - srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY; // Will be used with Texture2D sampler, not TextureCube + error = + createRenderTargetSRV(texture, index, mTextureFormatSet->blitSRVFormat, &blitSRV); + if (error.isError()) + { + SafeRelease(srv); + return error; + } } - - ID3D11ShaderResourceView *srv; - result = device->CreateShaderResourceView(texture, &srvDesc, &srv); - - ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result)); - if (FAILED(result)) + else { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal shader resource view for texture storage, result: 0x%X.", result); + blitSRV = srv; + blitSRV->AddRef(); } - if (mRenderTargetFormat != DXGI_FORMAT_UNKNOWN) + d3d11::SetDebugName(srv, "TexStorageCube.RenderTargetSRV"); + + if (mTextureFormatSet->rtvFormat != DXGI_FORMAT_UNKNOWN) { D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; - rtvDesc.Format = mRenderTargetFormat; - rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY; - rtvDesc.Texture2DArray.MipSlice = mTopLevel + level; + rtvDesc.Format = mTextureFormatSet->rtvFormat; + rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY; + rtvDesc.Texture2DArray.MipSlice = mTopLevel + level; rtvDesc.Texture2DArray.FirstArraySlice = faceIndex; - rtvDesc.Texture2DArray.ArraySize = 1; + rtvDesc.Texture2DArray.ArraySize = 1; ID3D11RenderTargetView *rtv; result = device->CreateRenderTargetView(texture, &rtvDesc, &rtv); @@ -1818,24 +2329,33 @@ gl::Error TextureStorage11_Cube::getRenderTarget(const gl::ImageIndex &index, Re if (FAILED(result)) { SafeRelease(srv); - return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal render target view for texture storage, result: 0x%X.", result); + SafeRelease(blitSRV); + return gl::Error(GL_OUT_OF_MEMORY, + "Failed to create internal render target view for texture " + "storage, result: 0x%X.", + result); } - mRenderTarget[faceIndex][level] = new TextureRenderTarget11(rtv, texture, srv, mInternalFormat, getLevelWidth(level), getLevelHeight(level), 1, 0); + d3d11::SetDebugName(rtv, "TexStorageCube.RenderTargetRTV"); + + mRenderTarget[faceIndex][level] = new TextureRenderTarget11( + rtv, texture, srv, blitSRV, mInternalFormat, mTextureFormatSet->format, + getLevelWidth(level), getLevelHeight(level), 1, 0); // RenderTarget will take ownership of these resources SafeRelease(rtv); SafeRelease(srv); + SafeRelease(blitSRV); } - else if (mDepthStencilFormat != DXGI_FORMAT_UNKNOWN) + else if (mTextureFormatSet->dsvFormat != DXGI_FORMAT_UNKNOWN) { D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc; - dsvDesc.Format = mDepthStencilFormat; - dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DARRAY; - dsvDesc.Flags = 0; - dsvDesc.Texture2DArray.MipSlice = mTopLevel + level; + dsvDesc.Format = mTextureFormatSet->dsvFormat; + dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DARRAY; + dsvDesc.Flags = 0; + dsvDesc.Texture2DArray.MipSlice = mTopLevel + level; dsvDesc.Texture2DArray.FirstArraySlice = faceIndex; - dsvDesc.Texture2DArray.ArraySize = 1; + dsvDesc.Texture2DArray.ArraySize = 1; ID3D11DepthStencilView *dsv; result = device->CreateDepthStencilView(texture, &dsvDesc, &dsv); @@ -1844,14 +2364,23 @@ gl::Error TextureStorage11_Cube::getRenderTarget(const gl::ImageIndex &index, Re if (FAILED(result)) { SafeRelease(srv); - return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal depth stencil view for texture storage, result: 0x%X.", result); + SafeRelease(blitSRV); + return gl::Error(GL_OUT_OF_MEMORY, + "Failed to create internal depth stencil view for texture " + "storage, result: 0x%X.", + result); } - mRenderTarget[faceIndex][level] = new TextureRenderTarget11(dsv, texture, srv, mInternalFormat, getLevelWidth(level), getLevelHeight(level), 1, 0); + d3d11::SetDebugName(dsv, "TexStorageCube.RenderTargetDSV"); + + mRenderTarget[faceIndex][level] = new TextureRenderTarget11( + dsv, texture, srv, mInternalFormat, mTextureFormatSet->format, getLevelWidth(level), + getLevelHeight(level), 1, 0); // RenderTarget will take ownership of these resources SafeRelease(dsv); SafeRelease(srv); + SafeRelease(blitSRV); } else { @@ -1864,7 +2393,10 @@ gl::Error TextureStorage11_Cube::getRenderTarget(const gl::ImageIndex &index, Re return gl::Error(GL_NO_ERROR); } -gl::Error TextureStorage11_Cube::createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture, +gl::Error TextureStorage11_Cube::createSRV(int baseLevel, + int mipLevels, + DXGI_FORMAT format, + ID3D11Resource *texture, ID3D11ShaderResourceView **outSRV) const { ASSERT(outSRV); @@ -1872,20 +2404,21 @@ gl::Error TextureStorage11_Cube::createSRV(int baseLevel, int mipLevels, DXGI_FO 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 + // Unnormalized integer cube maps are not supported by DX11; we emulate them as an array of six + // 2D textures const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(format); if (dxgiFormatInfo.componentType == GL_INT || dxgiFormatInfo.componentType == GL_UNSIGNED_INT) { - srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY; + srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY; srvDesc.Texture2DArray.MostDetailedMip = mTopLevel + baseLevel; - srvDesc.Texture2DArray.MipLevels = 1; + srvDesc.Texture2DArray.MipLevels = mipLevels; srvDesc.Texture2DArray.FirstArraySlice = 0; - srvDesc.Texture2DArray.ArraySize = CUBE_FACE_COUNT; + srvDesc.Texture2DArray.ArraySize = CUBE_FACE_COUNT; } else { - srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE; - srvDesc.TextureCube.MipLevels = mipLevels; + srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE; + srvDesc.TextureCube.MipLevels = mipLevels; srvDesc.TextureCube.MostDetailedMip = mTopLevel + baseLevel; } @@ -1895,31 +2428,35 @@ gl::Error TextureStorage11_Cube::createSRV(int baseLevel, int mipLevels, DXGI_FO { ASSERT(mTopLevel == 0); ASSERT(baseLevel == 0); - // This code also assumes that the incoming texture equals either mLevelZeroTexture or mTexture. + // 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. - ASSERT(mLevelZeroTexture != NULL && texture == mLevelZeroTexture); + ASSERT(mLevelZeroTexture != nullptr && texture == mLevelZeroTexture); srvTexture = mLevelZeroTexture; } else { ASSERT(mipLevels == static_cast(mMipLevels)); - ASSERT(mTexture != NULL && texture == mTexture); + ASSERT(mTexture != nullptr && texture == mTexture); srvTexture = mTexture; } } ID3D11Device *device = mRenderer->getDevice(); - HRESULT result = device->CreateShaderResourceView(srvTexture, &srvDesc, outSRV); + HRESULT result = device->CreateShaderResourceView(srvTexture, &srvDesc, outSRV); ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result)); if (FAILED(result)) { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal texture storage SRV, result: 0x%X.", result); + return gl::Error(GL_OUT_OF_MEMORY, + "Failed to create internal texture storage SRV, result: 0x%X.", result); } + d3d11::SetDebugName(*outSRV, "TexStorageCube.SRV"); + return gl::Error(GL_NO_ERROR); } @@ -1932,39 +2469,43 @@ gl::Error TextureStorage11_Cube::getSwizzleTexture(ID3D11Resource **outTexture) ID3D11Device *device = mRenderer->getDevice(); D3D11_TEXTURE2D_DESC desc; - desc.Width = mTextureWidth; - desc.Height = mTextureHeight; - desc.MipLevels = mMipLevels; - desc.ArraySize = CUBE_FACE_COUNT; - desc.Format = mSwizzleTextureFormat; - desc.SampleDesc.Count = 1; + desc.Width = mTextureWidth; + desc.Height = mTextureHeight; + desc.MipLevels = mMipLevels; + desc.ArraySize = CUBE_FACE_COUNT; + desc.Format = mSwizzleFormatSet->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; + desc.Usage = D3D11_USAGE_DEFAULT; + desc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET; + desc.CPUAccessFlags = 0; + desc.MiscFlags = D3D11_RESOURCE_MISC_TEXTURECUBE; - HRESULT result = device->CreateTexture2D(&desc, NULL, &mSwizzleTexture); + HRESULT result = device->CreateTexture2D(&desc, nullptr, &mSwizzleTexture); ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result)); if (FAILED(result)) { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal swizzle texture, result: 0x%X.", result); + return gl::Error(GL_OUT_OF_MEMORY, + "Failed to create internal swizzle texture, result: 0x%X.", result); } + + d3d11::SetDebugName(*outTexture, "TexStorageCube.SwizzleTexture"); } *outTexture = mSwizzleTexture; return gl::Error(GL_NO_ERROR); } -gl::Error TextureStorage11_Cube::getSwizzleRenderTarget(int mipLevel, ID3D11RenderTargetView **outRTV) +gl::Error TextureStorage11_Cube::getSwizzleRenderTarget(int mipLevel, + ID3D11RenderTargetView **outRTV) { ASSERT(mipLevel >= 0 && mipLevel < getLevelCount()); ASSERT(outRTV); if (!mSwizzleRenderTargets[mipLevel]) { - ID3D11Resource *swizzleTexture = NULL; + ID3D11Resource *swizzleTexture = nullptr; gl::Error error = getSwizzleTexture(&swizzleTexture); if (error.isError()) { @@ -1974,18 +2515,21 @@ gl::Error TextureStorage11_Cube::getSwizzleRenderTarget(int mipLevel, ID3D11Rend ID3D11Device *device = mRenderer->getDevice(); D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; - rtvDesc.Format = mSwizzleRenderTargetFormat; - rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY; - rtvDesc.Texture2DArray.MipSlice = mTopLevel + mipLevel; + rtvDesc.Format = mSwizzleFormatSet->rtvFormat; + rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY; + rtvDesc.Texture2DArray.MipSlice = mTopLevel + mipLevel; rtvDesc.Texture2DArray.FirstArraySlice = 0; - rtvDesc.Texture2DArray.ArraySize = CUBE_FACE_COUNT; + rtvDesc.Texture2DArray.ArraySize = CUBE_FACE_COUNT; - HRESULT result = device->CreateRenderTargetView(mSwizzleTexture, &rtvDesc, &mSwizzleRenderTargets[mipLevel]); + HRESULT result = device->CreateRenderTargetView(mSwizzleTexture, &rtvDesc, + &mSwizzleRenderTargets[mipLevel]); ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result)); if (FAILED(result)) { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal swizzle render target view, result: 0x%X.", result); + return gl::Error(GL_OUT_OF_MEMORY, + "Failed to create internal swizzle render target view, result: 0x%X.", + result); } } @@ -1993,56 +2537,60 @@ gl::Error TextureStorage11_Cube::getSwizzleRenderTarget(int mipLevel, ID3D11Rend return gl::Error(GL_NO_ERROR); } -TextureStorage11_3D::TextureStorage11_3D(Renderer11 *renderer, GLenum internalformat, bool renderTarget, - GLsizei width, GLsizei height, GLsizei depth, int levels) - : TextureStorage11(renderer, - GetTextureBindFlags(internalformat, renderer->getFeatureLevel(), renderTarget), - GetTextureMiscFlags(internalformat, renderer->getFeatureLevel(), renderTarget, levels)) -{ - mTexture = NULL; - mSwizzleTexture = NULL; +TextureStorage11_3D::TextureStorage11_3D(Renderer11 *renderer, + GLenum internalformat, + bool renderTarget, + GLsizei width, + GLsizei height, + GLsizei depth, + int levels) + : TextureStorage11( + renderer, + GetTextureBindFlags(internalformat, renderer->getRenderer11DeviceCaps(), renderTarget), + GetTextureMiscFlags(internalformat, + renderer->getRenderer11DeviceCaps(), + renderTarget, + levels)) +{ + mTexture = nullptr; + mSwizzleTexture = nullptr; for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++) { - mAssociatedImages[i] = NULL; - mLevelRenderTargets[i] = NULL; - mSwizzleRenderTargets[i] = NULL; + mAssociatedImages[i] = nullptr; + mLevelRenderTargets[i] = nullptr; + mSwizzleRenderTargets[i] = nullptr; } mInternalFormat = internalformat; - const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(internalformat, renderer->getFeatureLevel()); - mTextureFormat = formatInfo.texFormat; - mShaderResourceFormat = formatInfo.srvFormat; - mDepthStencilFormat = formatInfo.dsvFormat; - mRenderTargetFormat = formatInfo.rtvFormat; - mSwizzleTextureFormat = formatInfo.swizzleTexFormat; - mSwizzleShaderResourceFormat = formatInfo.swizzleSRVFormat; - mSwizzleRenderTargetFormat = formatInfo.swizzleRTVFormat; + const d3d11::TextureFormat &formatInfo = + d3d11::GetTextureFormatInfo(internalformat, renderer->getRenderer11DeviceCaps()); + mTextureFormatSet = formatInfo.formatSet; + mSwizzleFormatSet = formatInfo.swizzleFormatSet; // adjust size if needed for compressed textures - d3d11::MakeValidSize(false, mTextureFormat, &width, &height, &mTopLevel); + d3d11::MakeValidSize(false, mTextureFormatSet->texFormat, &width, &height, &mTopLevel); - mMipLevels = mTopLevel + levels; - mTextureWidth = width; + mMipLevels = mTopLevel + levels; + mTextureWidth = width; mTextureHeight = height; - mTextureDepth = depth; - - initializeSerials(getLevelCount() * depth, depth); + mTextureDepth = depth; } TextureStorage11_3D::~TextureStorage11_3D() { for (unsigned i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++) { - if (mAssociatedImages[i] != NULL) + if (mAssociatedImages[i] != nullptr) { bool imageAssociationCorrect = mAssociatedImages[i]->isAssociatedStorageValid(this); ASSERT(imageAssociationCorrect); if (imageAssociationCorrect) { - // We must let the Images recover their data before we delete it from the TextureStorage. + // We must let the Images recover their data before we delete it from the + // TextureStorage. mAssociatedImages[i]->recoverFromAssociatedStorage(); } } @@ -2051,7 +2599,8 @@ TextureStorage11_3D::~TextureStorage11_3D() SafeRelease(mTexture); SafeRelease(mSwizzleTexture); - for (RenderTargetMap::iterator i = mLevelLayerRenderTargets.begin(); i != mLevelLayerRenderTargets.end(); i++) + for (RenderTargetMap::iterator i = mLevelLayerRenderTargets.begin(); + i != mLevelLayerRenderTargets.end(); i++) { SafeDelete(i->second); } @@ -2064,9 +2613,9 @@ TextureStorage11_3D::~TextureStorage11_3D() } } -void TextureStorage11_3D::associateImage(Image11* image, const gl::ImageIndex &index) +void TextureStorage11_3D::associateImage(Image11 *image, const gl::ImageIndex &index) { - GLint level = index.mipIndex; + const GLint level = index.mipIndex; ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS); @@ -2076,13 +2625,15 @@ void TextureStorage11_3D::associateImage(Image11* image, const gl::ImageIndex &i } } -bool TextureStorage11_3D::isAssociatedImageValid(const gl::ImageIndex &index, Image11* expectedImage) +bool TextureStorage11_3D::isAssociatedImageValid(const gl::ImageIndex &index, + Image11 *expectedImage) { - GLint level = index.mipIndex; + const GLint level = index.mipIndex; if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS) { - // This validation check should never return false. It means the Image/TextureStorage association is broken. + // This validation check should never return false. It means the Image/TextureStorage + // association is broken. bool retValue = (mAssociatedImages[level] == expectedImage); ASSERT(retValue); return retValue; @@ -2092,9 +2643,9 @@ bool TextureStorage11_3D::isAssociatedImageValid(const gl::ImageIndex &index, Im } // disassociateImage allows an Image to end its association with a Storage. -void TextureStorage11_3D::disassociateImage(const gl::ImageIndex &index, Image11* expectedImage) +void TextureStorage11_3D::disassociateImage(const gl::ImageIndex &index, Image11 *expectedImage) { - GLint level = index.mipIndex; + const GLint level = index.mipIndex; ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS); @@ -2104,31 +2655,34 @@ void TextureStorage11_3D::disassociateImage(const gl::ImageIndex &index, Image11 if (mAssociatedImages[level] == expectedImage) { - mAssociatedImages[level] = NULL; + mAssociatedImages[level] = nullptr; } } } -// releaseAssociatedImage prepares the Storage for a new Image association. It lets the old Image recover its data before ending the association. -gl::Error TextureStorage11_3D::releaseAssociatedImage(const gl::ImageIndex &index, Image11* incomingImage) +// releaseAssociatedImage prepares the Storage for a new Image association. It lets the old Image +// recover its data before ending the association. +gl::Error TextureStorage11_3D::releaseAssociatedImage(const gl::ImageIndex &index, + Image11 *incomingImage) { - GLint level = index.mipIndex; + const GLint level = index.mipIndex; 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] != NULL && mAssociatedImages[level] != incomingImage) + if (mAssociatedImages[level] != nullptr && mAssociatedImages[level] != incomingImage) { - // Ensure that the Image is still associated with this TextureStorage. This should be true. + // Ensure that the Image is still associated with this TextureStorage. This should be + // true. bool imageAssociationCorrect = mAssociatedImages[level]->isAssociatedStorageValid(this); ASSERT(imageAssociationCorrect); if (imageAssociationCorrect) { // Force the image to recover from storage before its data is overwritten. - // This will reset mAssociatedImages[level] to NULL too. + // This will reset mAssociatedImages[level] to nullptr too. gl::Error error = mAssociatedImages[level]->recoverFromAssociatedStorage(); if (error.isError()) { @@ -2143,87 +2697,104 @@ gl::Error TextureStorage11_3D::releaseAssociatedImage(const gl::ImageIndex &inde gl::Error TextureStorage11_3D::getResource(ID3D11Resource **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 == NULL && mTextureWidth > 0 && mTextureHeight > 0 && mTextureDepth > 0) + // 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 == nullptr && mTextureWidth > 0 && mTextureHeight > 0 && mTextureDepth > 0) { ASSERT(mMipLevels > 0); ID3D11Device *device = mRenderer->getDevice(); D3D11_TEXTURE3D_DESC desc; - desc.Width = mTextureWidth; - desc.Height = mTextureHeight; - desc.Depth = mTextureDepth; - desc.MipLevels = mMipLevels; - desc.Format = mTextureFormat; - desc.Usage = D3D11_USAGE_DEFAULT; - desc.BindFlags = getBindFlags(); + desc.Width = mTextureWidth; + desc.Height = mTextureHeight; + desc.Depth = mTextureDepth; + desc.MipLevels = mMipLevels; + desc.Format = mTextureFormatSet->texFormat; + desc.Usage = D3D11_USAGE_DEFAULT; + desc.BindFlags = getBindFlags(); desc.CPUAccessFlags = 0; - desc.MiscFlags = getMiscFlags(); + desc.MiscFlags = getMiscFlags(); - HRESULT result = device->CreateTexture3D(&desc, NULL, &mTexture); + HRESULT result = device->CreateTexture3D(&desc, nullptr, &mTexture); // this can happen from windows TDR if (d3d11::isDeviceLostError(result)) { mRenderer->notifyDeviceLost(); - return gl::Error(GL_OUT_OF_MEMORY, "Failed to create 3D texture storage, result: 0x%X.", result); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to create 3D texture storage, result: 0x%X.", + result); } else if (FAILED(result)) { ASSERT(result == E_OUTOFMEMORY); - return gl::Error(GL_OUT_OF_MEMORY, "Failed to create 3D texture storage, result: 0x%X.", result); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to create 3D texture storage, result: 0x%X.", + result); } + + d3d11::SetDebugName(mTexture, "TexStorage3D.Texture"); } *outResource = mTexture; return gl::Error(GL_NO_ERROR); } -gl::Error TextureStorage11_3D::createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture, +gl::Error TextureStorage11_3D::createSRV(int baseLevel, + int mipLevels, + DXGI_FORMAT format, + ID3D11Resource *texture, ID3D11ShaderResourceView **outSRV) const { ASSERT(outSRV); D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; - srvDesc.Format = format; - srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE3D; + srvDesc.Format = format; + srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE3D; srvDesc.Texture3D.MostDetailedMip = baseLevel; - srvDesc.Texture3D.MipLevels = mipLevels; + srvDesc.Texture3D.MipLevels = mipLevels; ID3D11Device *device = mRenderer->getDevice(); - HRESULT result = device->CreateShaderResourceView(texture, &srvDesc, outSRV); + HRESULT result = device->CreateShaderResourceView(texture, &srvDesc, outSRV); ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result)); if (FAILED(result)) { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal texture storage SRV, result: 0x%X.", result); + return gl::Error(GL_OUT_OF_MEMORY, + "Failed to create internal texture storage SRV, result: 0x%X.", result); } + d3d11::SetDebugName(*outSRV, "TexStorage3D.SRV"); + return gl::Error(GL_NO_ERROR); } gl::Error TextureStorage11_3D::getRenderTarget(const gl::ImageIndex &index, RenderTargetD3D **outRT) { - int mipLevel = index.mipIndex; + const int mipLevel = index.mipIndex; ASSERT(mipLevel >= 0 && mipLevel < getLevelCount()); - ASSERT(mRenderTargetFormat != DXGI_FORMAT_UNKNOWN); + ASSERT(mTextureFormatSet->rtvFormat != DXGI_FORMAT_UNKNOWN); if (!index.hasLayer()) { if (!mLevelRenderTargets[mipLevel]) { - ID3D11Resource *texture = NULL; + ID3D11Resource *texture = nullptr; gl::Error error = getResource(&texture); if (error.isError()) { return error; } - ID3D11ShaderResourceView *srv = NULL; - error = getSRVLevel(mipLevel, &srv); + ID3D11ShaderResourceView *srv = nullptr; + error = getSRVLevel(mipLevel, false, &srv); + if (error.isError()) + { + return error; + } + + ID3D11ShaderResourceView *blitSRV = nullptr; + error = getSRVLevel(mipLevel, true, &blitSRV); if (error.isError()) { return error; @@ -2232,11 +2803,11 @@ gl::Error TextureStorage11_3D::getRenderTarget(const gl::ImageIndex &index, Rend ID3D11Device *device = mRenderer->getDevice(); D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; - rtvDesc.Format = mRenderTargetFormat; - rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE3D; - rtvDesc.Texture3D.MipSlice = mTopLevel + mipLevel; + rtvDesc.Format = mTextureFormatSet->rtvFormat; + rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE3D; + rtvDesc.Texture3D.MipSlice = mTopLevel + mipLevel; rtvDesc.Texture3D.FirstWSlice = 0; - rtvDesc.Texture3D.WSize = static_cast(-1); + rtvDesc.Texture3D.WSize = static_cast(-1); ID3D11RenderTargetView *rtv; HRESULT result = device->CreateRenderTargetView(texture, &rtvDesc, &rtv); @@ -2245,10 +2816,18 @@ gl::Error TextureStorage11_3D::getRenderTarget(const gl::ImageIndex &index, Rend if (FAILED(result)) { SafeRelease(srv); - return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal render target view for texture storage, result: 0x%X.", result); + SafeRelease(blitSRV); + return gl::Error(GL_OUT_OF_MEMORY, + "Failed to create internal render target view for texture " + "storage, result: 0x%X.", + result); } - mLevelRenderTargets[mipLevel] = new TextureRenderTarget11(rtv, texture, srv, mInternalFormat, getLevelWidth(mipLevel), getLevelHeight(mipLevel), getLevelDepth(mipLevel), 0); + d3d11::SetDebugName(rtv, "TexStorage3D.RTV"); + + mLevelRenderTargets[mipLevel] = new TextureRenderTarget11( + rtv, texture, srv, blitSRV, mInternalFormat, mTextureFormatSet->format, + getLevelWidth(mipLevel), getLevelHeight(mipLevel), getLevelDepth(mipLevel), 0); // RenderTarget will take ownership of these resources SafeRelease(rtv); @@ -2260,7 +2839,7 @@ gl::Error TextureStorage11_3D::getRenderTarget(const gl::ImageIndex &index, Rend } else { - int layer = index.layerIndex; + const int layer = index.layerIndex; LevelLayerKey key(mipLevel, layer); if (mLevelLayerRenderTargets.find(key) == mLevelLayerRenderTargets.end()) @@ -2268,7 +2847,7 @@ gl::Error TextureStorage11_3D::getRenderTarget(const gl::ImageIndex &index, Rend ID3D11Device *device = mRenderer->getDevice(); HRESULT result; - ID3D11Resource *texture = NULL; + ID3D11Resource *texture = nullptr; gl::Error error = getResource(&texture); if (error.isError()) { @@ -2276,14 +2855,15 @@ gl::Error TextureStorage11_3D::getRenderTarget(const gl::ImageIndex &index, Rend } // TODO, what kind of SRV is expected here? - ID3D11ShaderResourceView *srv = NULL; + ID3D11ShaderResourceView *srv = nullptr; + ID3D11ShaderResourceView *blitSRV = nullptr; D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; - rtvDesc.Format = mRenderTargetFormat; - rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE3D; - rtvDesc.Texture3D.MipSlice = mTopLevel + mipLevel; + rtvDesc.Format = mTextureFormatSet->rtvFormat; + rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE3D; + rtvDesc.Texture3D.MipSlice = mTopLevel + mipLevel; rtvDesc.Texture3D.FirstWSlice = layer; - rtvDesc.Texture3D.WSize = 1; + rtvDesc.Texture3D.WSize = 1; ID3D11RenderTargetView *rtv; result = device->CreateRenderTargetView(texture, &rtvDesc, &rtv); @@ -2291,11 +2871,20 @@ gl::Error TextureStorage11_3D::getRenderTarget(const gl::ImageIndex &index, Rend ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result)); if (FAILED(result)) { - SafeRelease(srv); return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal render target view for texture storage, result: 0x%X.", result); + SafeRelease(srv); + SafeRelease(blitSRV); + return gl::Error(GL_OUT_OF_MEMORY, + "Failed to create internal render target view for texture " + "storage, result: 0x%X.", + result); } ASSERT(SUCCEEDED(result)); - mLevelLayerRenderTargets[key] = new TextureRenderTarget11(rtv, texture, srv, mInternalFormat, getLevelWidth(mipLevel), getLevelHeight(mipLevel), 1, 0); + d3d11::SetDebugName(rtv, "TexStorage3D.LayerRTV"); + + mLevelLayerRenderTargets[key] = new TextureRenderTarget11( + rtv, texture, srv, blitSRV, mInternalFormat, mTextureFormatSet->format, + getLevelWidth(mipLevel), getLevelHeight(mipLevel), 1, 0); // RenderTarget will take ownership of these resources SafeRelease(rtv); @@ -2316,23 +2905,26 @@ gl::Error TextureStorage11_3D::getSwizzleTexture(ID3D11Resource **outTexture) ID3D11Device *device = mRenderer->getDevice(); D3D11_TEXTURE3D_DESC desc; - desc.Width = mTextureWidth; - desc.Height = mTextureHeight; - desc.Depth = mTextureDepth; - desc.MipLevels = mMipLevels; - desc.Format = mSwizzleTextureFormat; - desc.Usage = D3D11_USAGE_DEFAULT; - desc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET; + desc.Width = mTextureWidth; + desc.Height = mTextureHeight; + desc.Depth = mTextureDepth; + desc.MipLevels = mMipLevels; + desc.Format = mSwizzleFormatSet->texFormat; + desc.Usage = D3D11_USAGE_DEFAULT; + desc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET; desc.CPUAccessFlags = 0; - desc.MiscFlags = 0; + desc.MiscFlags = 0; - HRESULT result = device->CreateTexture3D(&desc, NULL, &mSwizzleTexture); + HRESULT result = device->CreateTexture3D(&desc, nullptr, &mSwizzleTexture); ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result)); if (FAILED(result)) { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal swizzle texture, result: 0x%X.", result); + return gl::Error(GL_OUT_OF_MEMORY, + "Failed to create internal swizzle texture, result: 0x%X.", result); } + + d3d11::SetDebugName(mSwizzleTexture, "TexStorage3D.SwizzleTexture"); } *outTexture = mSwizzleTexture; @@ -2346,7 +2938,7 @@ gl::Error TextureStorage11_3D::getSwizzleRenderTarget(int mipLevel, ID3D11Render if (!mSwizzleRenderTargets[mipLevel]) { - ID3D11Resource *swizzleTexture = NULL; + ID3D11Resource *swizzleTexture = nullptr; gl::Error error = getSwizzleTexture(&swizzleTexture); if (error.isError()) { @@ -2356,59 +2948,67 @@ gl::Error TextureStorage11_3D::getSwizzleRenderTarget(int mipLevel, ID3D11Render ID3D11Device *device = mRenderer->getDevice(); D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; - rtvDesc.Format = mSwizzleRenderTargetFormat; - rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE3D; - rtvDesc.Texture3D.MipSlice = mTopLevel + mipLevel; + rtvDesc.Format = mSwizzleFormatSet->rtvFormat; + rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE3D; + rtvDesc.Texture3D.MipSlice = mTopLevel + mipLevel; rtvDesc.Texture3D.FirstWSlice = 0; - rtvDesc.Texture3D.WSize = static_cast(-1); + rtvDesc.Texture3D.WSize = static_cast(-1); - HRESULT result = device->CreateRenderTargetView(mSwizzleTexture, &rtvDesc, &mSwizzleRenderTargets[mipLevel]); + HRESULT result = device->CreateRenderTargetView(mSwizzleTexture, &rtvDesc, + &mSwizzleRenderTargets[mipLevel]); ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result)); if (FAILED(result)) { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal swizzle render target view, result: 0x%X.", result); + return gl::Error(GL_OUT_OF_MEMORY, + "Failed to create internal swizzle render target view, result: 0x%X.", + result); } + + d3d11::SetDebugName(mSwizzleTexture, "TexStorage3D.SwizzleRTV"); } *outRTV = mSwizzleRenderTargets[mipLevel]; return gl::Error(GL_NO_ERROR); } -TextureStorage11_2DArray::TextureStorage11_2DArray(Renderer11 *renderer, GLenum internalformat, bool renderTarget, - GLsizei width, GLsizei height, GLsizei depth, int levels) - : TextureStorage11(renderer, - GetTextureBindFlags(internalformat, renderer->getFeatureLevel(), renderTarget), - GetTextureMiscFlags(internalformat, renderer->getFeatureLevel(), renderTarget, levels)) -{ - mTexture = NULL; - mSwizzleTexture = NULL; +TextureStorage11_2DArray::TextureStorage11_2DArray(Renderer11 *renderer, + GLenum internalformat, + bool renderTarget, + GLsizei width, + GLsizei height, + GLsizei depth, + int levels) + : TextureStorage11( + renderer, + GetTextureBindFlags(internalformat, renderer->getRenderer11DeviceCaps(), renderTarget), + GetTextureMiscFlags(internalformat, + renderer->getRenderer11DeviceCaps(), + renderTarget, + levels)) +{ + mTexture = nullptr; + mSwizzleTexture = nullptr; for (unsigned int level = 0; level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++) { - mSwizzleRenderTargets[level] = NULL; + mSwizzleRenderTargets[level] = nullptr; } mInternalFormat = internalformat; - const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(internalformat, renderer->getFeatureLevel()); - mTextureFormat = formatInfo.texFormat; - mShaderResourceFormat = formatInfo.srvFormat; - mDepthStencilFormat = formatInfo.dsvFormat; - mRenderTargetFormat = formatInfo.rtvFormat; - mSwizzleTextureFormat = formatInfo.swizzleTexFormat; - mSwizzleShaderResourceFormat = formatInfo.swizzleSRVFormat; - mSwizzleRenderTargetFormat = formatInfo.swizzleRTVFormat; + const d3d11::TextureFormat &formatInfo = + d3d11::GetTextureFormatInfo(internalformat, renderer->getRenderer11DeviceCaps()); + mTextureFormatSet = formatInfo.formatSet; + mSwizzleFormatSet = formatInfo.swizzleFormatSet; // adjust size if needed for compressed textures - d3d11::MakeValidSize(false, mTextureFormat, &width, &height, &mTopLevel); + d3d11::MakeValidSize(false, mTextureFormatSet->texFormat, &width, &height, &mTopLevel); - mMipLevels = mTopLevel + levels; - mTextureWidth = width; + mMipLevels = mTopLevel + levels; + mTextureWidth = width; mTextureHeight = height; - mTextureDepth = depth; - - initializeSerials(getLevelCount() * depth, depth); + mTextureDepth = depth; } TextureStorage11_2DArray::~TextureStorage11_2DArray() @@ -2422,7 +3022,8 @@ TextureStorage11_2DArray::~TextureStorage11_2DArray() if (imageAssociationCorrect) { - // We must let the Images recover their data before we delete it from the TextureStorage. + // We must let the Images recover their data before we delete it from the + // TextureStorage. i->second->recoverFromAssociatedStorage(); } } @@ -2444,10 +3045,10 @@ TextureStorage11_2DArray::~TextureStorage11_2DArray() mRenderTargets.clear(); } -void TextureStorage11_2DArray::associateImage(Image11* image, const gl::ImageIndex &index) +void TextureStorage11_2DArray::associateImage(Image11 *image, const gl::ImageIndex &index) { - GLint level = index.mipIndex; - GLint layerTarget = index.layerIndex; + const GLint level = index.mipIndex; + const GLint layerTarget = index.layerIndex; ASSERT(0 <= level && level < getLevelCount()); @@ -2458,56 +3059,64 @@ void TextureStorage11_2DArray::associateImage(Image11* image, const gl::ImageInd } } -bool TextureStorage11_2DArray::isAssociatedImageValid(const gl::ImageIndex &index, Image11* expectedImage) +bool TextureStorage11_2DArray::isAssociatedImageValid(const gl::ImageIndex &index, + Image11 *expectedImage) { - GLint level = index.mipIndex; - GLint layerTarget = index.layerIndex; + const GLint level = index.mipIndex; + const GLint layerTarget = index.layerIndex; LevelLayerKey key(level, layerTarget); - // 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)); + // 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); return retValue; } // disassociateImage allows an Image to end its association with a Storage. -void TextureStorage11_2DArray::disassociateImage(const gl::ImageIndex &index, Image11* expectedImage) +void TextureStorage11_2DArray::disassociateImage(const gl::ImageIndex &index, + Image11 *expectedImage) { - GLint level = index.mipIndex; - GLint layerTarget = index.layerIndex; + const GLint level = index.mipIndex; + const GLint layerTarget = index.layerIndex; LevelLayerKey key(level, layerTarget); - bool imageAssociationCorrect = (mAssociatedImages.find(key) != mAssociatedImages.end() && (mAssociatedImages[key] == expectedImage)); + bool imageAssociationCorrect = (mAssociatedImages.find(key) != mAssociatedImages.end() && + (mAssociatedImages[key] == expectedImage)); ASSERT(imageAssociationCorrect); if (imageAssociationCorrect) { - mAssociatedImages[key] = NULL; + mAssociatedImages[key] = nullptr; } } -// releaseAssociatedImage prepares the Storage for a new Image association. It lets the old Image recover its data before ending the association. -gl::Error TextureStorage11_2DArray::releaseAssociatedImage(const gl::ImageIndex &index, Image11* incomingImage) +// releaseAssociatedImage prepares the Storage for a new Image association. It lets the old Image +// recover its data before ending the association. +gl::Error TextureStorage11_2DArray::releaseAssociatedImage(const gl::ImageIndex &index, + Image11 *incomingImage) { - GLint level = index.mipIndex; - GLint layerTarget = index.layerIndex; + const GLint level = index.mipIndex; + const GLint layerTarget = index.layerIndex; LevelLayerKey key(level, layerTarget); if (mAssociatedImages.find(key) != mAssociatedImages.end()) { - if (mAssociatedImages[key] != NULL && mAssociatedImages[key] != incomingImage) + if (mAssociatedImages[key] != nullptr && mAssociatedImages[key] != incomingImage) { - // Ensure that the Image is still associated with this TextureStorage. This should be true. + // Ensure that the Image is still associated with this TextureStorage. This should be + // true. bool imageAssociationCorrect = mAssociatedImages[key]->isAssociatedStorageValid(this); ASSERT(imageAssociationCorrect); if (imageAssociationCorrect) { // Force the image to recover from storage before its data is overwritten. - // This will reset mAssociatedImages[level] to NULL too. + // This will reset mAssociatedImages[level] to nullptr too. gl::Error error = mAssociatedImages[key]->recoverFromAssociatedStorage(); if (error.isError()) { @@ -2524,73 +3133,112 @@ gl::Error TextureStorage11_2DArray::getResource(ID3D11Resource **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 == NULL && mTextureWidth > 0 && mTextureHeight > 0 && mTextureDepth > 0) + if (mTexture == nullptr && mTextureWidth > 0 && mTextureHeight > 0 && mTextureDepth > 0) { ASSERT(mMipLevels > 0); ID3D11Device *device = mRenderer->getDevice(); D3D11_TEXTURE2D_DESC desc; - desc.Width = mTextureWidth; - desc.Height = mTextureHeight; - desc.MipLevels = mMipLevels; - desc.ArraySize = mTextureDepth; - desc.Format = mTextureFormat; - desc.SampleDesc.Count = 1; + desc.Width = mTextureWidth; + desc.Height = mTextureHeight; + desc.MipLevels = mMipLevels; + desc.ArraySize = mTextureDepth; + desc.Format = mTextureFormatSet->texFormat; + desc.SampleDesc.Count = 1; desc.SampleDesc.Quality = 0; - desc.Usage = D3D11_USAGE_DEFAULT; - desc.BindFlags = getBindFlags(); - desc.CPUAccessFlags = 0; - desc.MiscFlags = getMiscFlags(); + desc.Usage = D3D11_USAGE_DEFAULT; + desc.BindFlags = getBindFlags(); + desc.CPUAccessFlags = 0; + desc.MiscFlags = getMiscFlags(); - HRESULT result = device->CreateTexture2D(&desc, NULL, &mTexture); + HRESULT result = device->CreateTexture2D(&desc, nullptr, &mTexture); // this can happen from windows TDR if (d3d11::isDeviceLostError(result)) { mRenderer->notifyDeviceLost(); - return gl::Error(GL_OUT_OF_MEMORY, "Failed to create 2D array texture storage, result: 0x%X.", result); + return gl::Error(GL_OUT_OF_MEMORY, + "Failed to create 2D array texture storage, result: 0x%X.", result); } else if (FAILED(result)) { ASSERT(result == E_OUTOFMEMORY); - return gl::Error(GL_OUT_OF_MEMORY, "Failed to create 2D array texture storage, result: 0x%X.", result); + return gl::Error(GL_OUT_OF_MEMORY, + "Failed to create 2D array texture storage, result: 0x%X.", result); } + + d3d11::SetDebugName(mTexture, "TexStorage2DArray.Texture"); } *outResource = mTexture; return gl::Error(GL_NO_ERROR); } -gl::Error TextureStorage11_2DArray::createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture, +gl::Error TextureStorage11_2DArray::createSRV(int baseLevel, + int mipLevels, + DXGI_FORMAT format, + ID3D11Resource *texture, ID3D11ShaderResourceView **outSRV) const { D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; - srvDesc.Format = format; - srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY; + srvDesc.Format = format; + srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY; srvDesc.Texture2DArray.MostDetailedMip = mTopLevel + baseLevel; - srvDesc.Texture2DArray.MipLevels = mipLevels; + srvDesc.Texture2DArray.MipLevels = mipLevels; srvDesc.Texture2DArray.FirstArraySlice = 0; - srvDesc.Texture2DArray.ArraySize = mTextureDepth; + srvDesc.Texture2DArray.ArraySize = mTextureDepth; + + ID3D11Device *device = mRenderer->getDevice(); + HRESULT result = device->CreateShaderResourceView(texture, &srvDesc, outSRV); + + ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result)); + if (FAILED(result)) + { + return gl::Error(GL_OUT_OF_MEMORY, + "Failed to create internal texture storage SRV, result: 0x%X.", result); + } + + d3d11::SetDebugName(*outSRV, "TexStorage2DArray.SRV"); + + return gl::Error(GL_NO_ERROR); +} +gl::Error TextureStorage11_2DArray::createRenderTargetSRV(ID3D11Resource *texture, + const gl::ImageIndex &index, + DXGI_FORMAT resourceFormat, + ID3D11ShaderResourceView **srv) const +{ ID3D11Device *device = mRenderer->getDevice(); - HRESULT result = device->CreateShaderResourceView(texture, &srvDesc, outSRV); + D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; + srvDesc.Format = resourceFormat; + srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY; + srvDesc.Texture2DArray.MostDetailedMip = mTopLevel + index.mipIndex; + srvDesc.Texture2DArray.MipLevels = 1; + srvDesc.Texture2DArray.FirstArraySlice = index.layerIndex; + srvDesc.Texture2DArray.ArraySize = 1; + + HRESULT result = device->CreateShaderResourceView(texture, &srvDesc, srv); ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result)); if (FAILED(result)) { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal texture storage SRV, result: 0x%X.", result); + return gl::Error( + GL_OUT_OF_MEMORY, + "Failed to create internal shader resource view for texture storage, result: 0x%X.", + result); } return gl::Error(GL_NO_ERROR); } -gl::Error TextureStorage11_2DArray::getRenderTarget(const gl::ImageIndex &index, RenderTargetD3D **outRT) +gl::Error TextureStorage11_2DArray::getRenderTarget(const gl::ImageIndex &index, + RenderTargetD3D **outRT) { ASSERT(index.hasLayer()); - int mipLevel = index.mipIndex; - int layer = index.layerIndex; + const int mipLevel = index.mipIndex; + const int layer = index.layerIndex; ASSERT(mipLevel >= 0 && mipLevel < getLevelCount()); @@ -2600,38 +3248,45 @@ gl::Error TextureStorage11_2DArray::getRenderTarget(const gl::ImageIndex &index, ID3D11Device *device = mRenderer->getDevice(); HRESULT result; - ID3D11Resource *texture = NULL; + ID3D11Resource *texture = nullptr; gl::Error error = getResource(&texture); if (error.isError()) { return error; } - - D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; - srvDesc.Format = mShaderResourceFormat; - srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY; - srvDesc.Texture2DArray.MostDetailedMip = mTopLevel + mipLevel; - srvDesc.Texture2DArray.MipLevels = 1; - srvDesc.Texture2DArray.FirstArraySlice = layer; - srvDesc.Texture2DArray.ArraySize = 1; - ID3D11ShaderResourceView *srv; - result = device->CreateShaderResourceView(texture, &srvDesc, &srv); - - ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result)); - if (FAILED(result)) + error = createRenderTargetSRV(texture, index, mTextureFormatSet->srvFormat, &srv); + if (error.isError()) { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal shader resource view for texture storage, result: 0x%X.", result); + return error; } + ID3D11ShaderResourceView *blitSRV; + if (mTextureFormatSet->blitSRVFormat != mTextureFormatSet->srvFormat) + { + error = + createRenderTargetSRV(texture, index, mTextureFormatSet->blitSRVFormat, &blitSRV); + if (error.isError()) + { + SafeRelease(srv); + return error; + } + } + else + { + blitSRV = srv; + blitSRV->AddRef(); + } + + d3d11::SetDebugName(srv, "TexStorage2DArray.RenderTargetSRV"); - if (mRenderTargetFormat != DXGI_FORMAT_UNKNOWN) + if (mTextureFormatSet->rtvFormat != DXGI_FORMAT_UNKNOWN) { D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; - rtvDesc.Format = mRenderTargetFormat; - rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY; - rtvDesc.Texture2DArray.MipSlice = mTopLevel + mipLevel; + rtvDesc.Format = mTextureFormatSet->rtvFormat; + rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY; + rtvDesc.Texture2DArray.MipSlice = mTopLevel + mipLevel; rtvDesc.Texture2DArray.FirstArraySlice = layer; - rtvDesc.Texture2DArray.ArraySize = 1; + rtvDesc.Texture2DArray.ArraySize = 1; ID3D11RenderTargetView *rtv; result = device->CreateRenderTargetView(texture, &rtvDesc, &rtv); @@ -2640,18 +3295,58 @@ gl::Error TextureStorage11_2DArray::getRenderTarget(const gl::ImageIndex &index, if (FAILED(result)) { SafeRelease(srv); - return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal render target view for texture storage, result: 0x%X.", result); + SafeRelease(blitSRV); + return gl::Error(GL_OUT_OF_MEMORY, + "Failed to create internal render target view for texture " + "storage, result: 0x%X.", + result); } - mRenderTargets[key] = new TextureRenderTarget11(rtv, texture, srv, mInternalFormat, getLevelWidth(mipLevel), getLevelHeight(mipLevel), 1, 0); + d3d11::SetDebugName(rtv, "TexStorage2DArray.RenderTargetRTV"); + + mRenderTargets[key] = new TextureRenderTarget11( + rtv, texture, srv, blitSRV, mInternalFormat, mTextureFormatSet->format, + getLevelWidth(mipLevel), getLevelHeight(mipLevel), 1, 0); // RenderTarget will take ownership of these resources SafeRelease(rtv); SafeRelease(srv); + SafeRelease(blitSRV); } else { - UNREACHABLE(); + ASSERT(mTextureFormatSet->dsvFormat != DXGI_FORMAT_UNKNOWN); + + D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc; + dsvDesc.Format = mTextureFormatSet->dsvFormat; + dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DARRAY; + dsvDesc.Texture2DArray.MipSlice = mTopLevel + mipLevel; + dsvDesc.Texture2DArray.FirstArraySlice = layer; + dsvDesc.Texture2DArray.ArraySize = 1; + dsvDesc.Flags = 0; + + ID3D11DepthStencilView *dsv; + result = device->CreateDepthStencilView(texture, &dsvDesc, &dsv); + + ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result)); + if (FAILED(result)) + { + SafeRelease(srv); + SafeRelease(blitSRV); + return gl::Error(GL_OUT_OF_MEMORY, + "Failed to create TexStorage2DArray DSV. Result: 0x%X.", result); + } + + d3d11::SetDebugName(dsv, "TexStorage2DArray.RenderTargetDSV"); + + mRenderTargets[key] = new TextureRenderTarget11( + dsv, texture, srv, mInternalFormat, mTextureFormatSet->format, + getLevelWidth(mipLevel), getLevelHeight(mipLevel), 1, 0); + + // RenderTarget will take ownership of these resources + SafeRelease(dsv); + SafeRelease(srv); + SafeRelease(blitSRV); } } @@ -2667,39 +3362,43 @@ gl::Error TextureStorage11_2DArray::getSwizzleTexture(ID3D11Resource **outTextur ID3D11Device *device = mRenderer->getDevice(); D3D11_TEXTURE2D_DESC desc; - desc.Width = mTextureWidth; - desc.Height = mTextureHeight; - desc.MipLevels = mMipLevels; - desc.ArraySize = mTextureDepth; - desc.Format = mSwizzleTextureFormat; - desc.SampleDesc.Count = 1; + desc.Width = mTextureWidth; + desc.Height = mTextureHeight; + desc.MipLevels = mMipLevels; + desc.ArraySize = mTextureDepth; + desc.Format = mSwizzleFormatSet->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; + desc.Usage = D3D11_USAGE_DEFAULT; + desc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET; + desc.CPUAccessFlags = 0; + desc.MiscFlags = 0; - HRESULT result = device->CreateTexture2D(&desc, NULL, &mSwizzleTexture); + HRESULT result = device->CreateTexture2D(&desc, nullptr, &mSwizzleTexture); ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result)); if (FAILED(result)) { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal swizzle texture, result: 0x%X.", result); + return gl::Error(GL_OUT_OF_MEMORY, + "Failed to create internal swizzle texture, result: 0x%X.", result); } + + d3d11::SetDebugName(*outTexture, "TexStorage2DArray.SwizzleTexture"); } *outTexture = mSwizzleTexture; return gl::Error(GL_NO_ERROR); } -gl::Error TextureStorage11_2DArray::getSwizzleRenderTarget(int mipLevel, ID3D11RenderTargetView **outRTV) +gl::Error TextureStorage11_2DArray::getSwizzleRenderTarget(int mipLevel, + ID3D11RenderTargetView **outRTV) { ASSERT(mipLevel >= 0 && mipLevel < getLevelCount()); ASSERT(outRTV); if (!mSwizzleRenderTargets[mipLevel]) { - ID3D11Resource *swizzleTexture = NULL; + ID3D11Resource *swizzleTexture = nullptr; gl::Error error = getSwizzleTexture(&swizzleTexture); if (error.isError()) { @@ -2709,23 +3408,25 @@ gl::Error TextureStorage11_2DArray::getSwizzleRenderTarget(int mipLevel, ID3D11R ID3D11Device *device = mRenderer->getDevice(); D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; - rtvDesc.Format = mSwizzleRenderTargetFormat; - rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY; - rtvDesc.Texture2DArray.MipSlice = mTopLevel + mipLevel; + rtvDesc.Format = mSwizzleFormatSet->rtvFormat; + rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY; + rtvDesc.Texture2DArray.MipSlice = mTopLevel + mipLevel; rtvDesc.Texture2DArray.FirstArraySlice = 0; - rtvDesc.Texture2DArray.ArraySize = mTextureDepth; + rtvDesc.Texture2DArray.ArraySize = mTextureDepth; - HRESULT result = device->CreateRenderTargetView(mSwizzleTexture, &rtvDesc, &mSwizzleRenderTargets[mipLevel]); + HRESULT result = device->CreateRenderTargetView(mSwizzleTexture, &rtvDesc, + &mSwizzleRenderTargets[mipLevel]); ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result)); if (FAILED(result)) { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal swizzle render target view, result: 0x%X.", result); + return gl::Error(GL_OUT_OF_MEMORY, + "Failed to create internal swizzle render target view, result: 0x%X.", + result); } } *outRTV = mSwizzleRenderTargets[mipLevel]; return gl::Error(GL_NO_ERROR); } - -} +} // namespace rx diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/TextureStorage11.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/TextureStorage11.h index e9b200c1b844..6275f032a10f 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/TextureStorage11.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/TextureStorage11.h @@ -13,7 +13,9 @@ #include "libANGLE/Texture.h" #include "libANGLE/Error.h" #include "libANGLE/renderer/d3d/TextureStorage.h" +#include "libANGLE/renderer/d3d/d3d11/texture_format_table.h" +#include #include namespace gl @@ -23,25 +25,28 @@ struct ImageIndex; namespace rx { +class EGLImageD3D; class RenderTargetD3D; class RenderTarget11; class Renderer11; class SwapChain11; class Image11; +struct Renderer11DeviceCaps; class TextureStorage11 : public TextureStorage { public: virtual ~TextureStorage11(); - static DWORD GetTextureBindFlags(GLenum internalFormat, D3D_FEATURE_LEVEL featureLevel, bool renderTarget); - static DWORD GetTextureMiscFlags(GLenum internalFormat, D3D_FEATURE_LEVEL featureLevel, bool renderTarget, int levels); + static DWORD GetTextureBindFlags(GLenum internalFormat, const Renderer11DeviceCaps &renderer11DeviceCaps, bool renderTarget); + static DWORD GetTextureMiscFlags(GLenum internalFormat, const Renderer11DeviceCaps &renderer11DeviceCaps, bool renderTarget, int levels); UINT getBindFlags() const; UINT getMiscFlags() const; virtual gl::Error getResource(ID3D11Resource **outResource) = 0; - virtual gl::Error getSRV(const gl::SamplerState &samplerState, ID3D11ShaderResourceView **outSRV); + virtual gl::Error getSRV(const gl::TextureState &textureState, + ID3D11ShaderResourceView **outSRV); virtual gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTargetD3D **outRT) = 0; virtual gl::Error generateMipmap(const gl::ImageIndex &sourceIndex, const gl::ImageIndex &destIndex); @@ -74,6 +79,8 @@ class TextureStorage11 : public TextureStorage gl::Error getSRVLevels(GLint baseLevel, GLint maxLevel, ID3D11ShaderResourceView **outSRV); + d3d11::ANGLEFormat getANGLEFormat() const; + protected: TextureStorage11(Renderer11 *renderer, UINT bindFlags, UINT miscFlags); int getLevelWidth(int mipLevel) const; @@ -85,25 +92,23 @@ class TextureStorage11 : public TextureStorage virtual gl::Error getSwizzleTexture(ID3D11Resource **outTexture) = 0; virtual gl::Error getSwizzleRenderTarget(int mipLevel, ID3D11RenderTargetView **outRTV) = 0; - gl::Error getSRVLevel(int mipLevel, ID3D11ShaderResourceView **outSRV); + gl::Error getSRVLevel(int mipLevel, bool blitSRV, ID3D11ShaderResourceView **outSRV); virtual gl::Error createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture, ID3D11ShaderResourceView **outSRV) const = 0; void verifySwizzleExists(GLenum swizzleRed, GLenum swizzleGreen, GLenum swizzleBlue, GLenum swizzleAlpha); + // Clear all cached non-swizzle SRVs and invalidate the swizzle cache. + void clearSRVCache(); + Renderer11 *mRenderer; int mTopLevel; unsigned int mMipLevels; GLenum mInternalFormat; - DXGI_FORMAT mTextureFormat; - DXGI_FORMAT mShaderResourceFormat; - DXGI_FORMAT mRenderTargetFormat; - DXGI_FORMAT mDepthStencilFormat; - DXGI_FORMAT mSwizzleTextureFormat; - DXGI_FORMAT mSwizzleShaderResourceFormat; - DXGI_FORMAT mSwizzleRenderTargetFormat; + const d3d11::ANGLEFormatSet *mTextureFormatSet; + const d3d11::ANGLEFormatSet *mSwizzleFormatSet; unsigned int mTextureWidth; unsigned int mTextureHeight; unsigned int mTextureDepth; @@ -140,7 +145,8 @@ class TextureStorage11 : public TextureStorage typedef std::map SRVCache; SRVCache mSrvCache; - ID3D11ShaderResourceView *mLevelSRVs[gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS]; + std::array mLevelSRVs; + std::array mLevelBlitSRVs; }; class TextureStorage11_2D : public TextureStorage11 @@ -175,6 +181,7 @@ class TextureStorage11_2D : public TextureStorage11 ID3D11Texture2D *mTexture; RenderTarget11 *mRenderTarget[gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS]; + 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). @@ -196,6 +203,52 @@ class TextureStorage11_2D : public TextureStorage11 Image11 *mAssociatedImages[gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS]; }; +class TextureStorage11_EGLImage final : public TextureStorage11 +{ + public: + TextureStorage11_EGLImage(Renderer11 *renderer, EGLImageD3D *eglImage); + ~TextureStorage11_EGLImage() override; + + gl::Error getResource(ID3D11Resource **outResource) override; + gl::Error getSRV(const gl::TextureState &textureState, + ID3D11ShaderResourceView **outSRV) override; + gl::Error getMippedResource(ID3D11Resource **outResource) override; + gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTargetD3D **outRT) override; + + gl::Error copyToStorage(TextureStorage *destStorage) override; + + void associateImage(Image11 *image, const gl::ImageIndex &index) override; + void disassociateImage(const gl::ImageIndex &index, Image11 *expectedImage) override; + bool isAssociatedImageValid(const gl::ImageIndex &index, Image11 *expectedImage) override; + gl::Error releaseAssociatedImage(const gl::ImageIndex &index, Image11 *incomingImage) override; + + gl::Error useLevelZeroWorkaroundTexture(bool useLevelZeroTexture) override; + + protected: + gl::Error getSwizzleTexture(ID3D11Resource **outTexture) override; + gl::Error getSwizzleRenderTarget(int mipLevel, ID3D11RenderTargetView **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. + gl::Error checkForUpdatedRenderTarget(); + + gl::Error createSRV(int baseLevel, + int mipLevels, + DXGI_FORMAT format, + ID3D11Resource *texture, + ID3D11ShaderResourceView **outSRV) const override; + + gl::Error getImageRenderTarget(RenderTarget11 **outRT) const; + + EGLImageD3D *mImage; + uintptr_t mCurrentRenderTarget; + + // Swizzle-related variables + ID3D11Texture2D *mSwizzleTexture; + std::vector mSwizzleRenderTargets; +}; + class TextureStorage11_Cube : public TextureStorage11 { public: @@ -226,6 +279,10 @@ class TextureStorage11_Cube : public TextureStorage11 private: virtual gl::Error createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture, ID3D11ShaderResourceView **outSRV) const; + gl::Error createRenderTargetSRV(ID3D11Resource *texture, + const gl::ImageIndex &index, + DXGI_FORMAT resourceFormat, + ID3D11ShaderResourceView **srv) const; static const size_t CUBE_FACE_COUNT = 6; @@ -303,6 +360,10 @@ class TextureStorage11_2DArray : public TextureStorage11 private: virtual gl::Error createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture, ID3D11ShaderResourceView **outSRV) const; + gl::Error createRenderTargetSRV(ID3D11Resource *texture, + const gl::ImageIndex &index, + DXGI_FORMAT resourceFormat, + ID3D11ShaderResourceView **srv) const; typedef std::pair LevelLayerKey; typedef std::map RenderTargetMap; diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/Trim11.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/Trim11.h index f232ad7e8e5b..4741e8160194 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/Trim11.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/Trim11.h @@ -31,7 +31,9 @@ class Trim11 : angle::NonCopyable private: Renderer11 *mRenderer; +#if defined (ANGLE_ENABLE_WINDOWS_STORE) EventRegistrationToken mApplicationSuspendedEventToken; +#endif void trim(); bool registerForRendererTrimRequest(); diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/VertexArray11.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/VertexArray11.cpp new file mode 100644 index 000000000000..7bb27214be70 --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/VertexArray11.cpp @@ -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. +// +// VertexArray11: +// Implementation of rx::VertexArray11. +// + +#include "libANGLE/renderer/d3d/d3d11/VertexArray11.h" + +#include "common/BitSetIterator.h" +#include "libANGLE/renderer/d3d/d3d11/Buffer11.h" + +namespace rx +{ + +namespace +{ +size_t GetAttribIndex(unsigned long dirtyBit) +{ + if (dirtyBit >= gl::VertexArray::DIRTY_BIT_ATTRIB_0_ENABLED && + dirtyBit < gl::VertexArray::DIRTY_BIT_ATTRIB_MAX_ENABLED) + { + return dirtyBit - gl::VertexArray::DIRTY_BIT_ATTRIB_0_ENABLED; + } + + if (dirtyBit >= gl::VertexArray::DIRTY_BIT_ATTRIB_0_POINTER && + dirtyBit < gl::VertexArray::DIRTY_BIT_ATTRIB_MAX_POINTER) + { + return dirtyBit - gl::VertexArray::DIRTY_BIT_ATTRIB_0_POINTER; + } + + ASSERT(dirtyBit >= gl::VertexArray::DIRTY_BIT_ATTRIB_0_DIVISOR && + dirtyBit < gl::VertexArray::DIRTY_BIT_ATTRIB_MAX_DIVISOR); + return static_cast(dirtyBit) - gl::VertexArray::DIRTY_BIT_ATTRIB_0_DIVISOR; +} +} // anonymous namespace + +VertexArray11::VertexArray11(const gl::VertexArray::Data &data) + : VertexArrayImpl(data), + mAttributeStorageTypes(data.getVertexAttributes().size(), VertexStorageType::CURRENT_VALUE), + mTranslatedAttribs(data.getVertexAttributes().size()), + mCurrentBuffers(data.getVertexAttributes().size()) +{ + for (size_t attribIndex = 0; attribIndex < mCurrentBuffers.size(); ++attribIndex) + { + auto callback = [this, attribIndex]() + { + this->markBufferDataDirty(attribIndex); + }; + mOnBufferDataDirty.push_back(callback); + } +} + +VertexArray11::~VertexArray11() +{ + for (size_t attribIndex = 0; attribIndex < mCurrentBuffers.size(); ++attribIndex) + { + if (mCurrentBuffers[attribIndex].get()) + { + unlinkBuffer(attribIndex, mAttributeStorageTypes[attribIndex]); + mCurrentBuffers[attribIndex].set(nullptr); + } + } +} + +void VertexArray11::syncState(const gl::VertexArray::DirtyBits &dirtyBits) +{ + for (auto dirtyBit : angle::IterateBitSet(dirtyBits)) + { + if (dirtyBit == gl::VertexArray::DIRTY_BIT_ELEMENT_ARRAY_BUFFER) + continue; + + size_t attribIndex = GetAttribIndex(dirtyBit); + mAttribsToUpdate.set(attribIndex); + } +} + +void VertexArray11::updateVertexAttribStorage(size_t attribIndex) +{ + const auto &attrib = mData.getVertexAttribute(attribIndex); + + // Note: having an unchanged storage type doesn't mean the attribute is clean. + auto oldStorageType = mAttributeStorageTypes[attribIndex]; + auto newStorageType = ClassifyAttributeStorage(attrib); + + mAttributeStorageTypes[attribIndex] = newStorageType; + + if (newStorageType == VertexStorageType::DYNAMIC) + { + if (oldStorageType != VertexStorageType::DYNAMIC) + { + // Sync dynamic attribs in a different set. + mAttribsToTranslate.reset(attribIndex); + mDynamicAttribsMask.set(attribIndex); + } + } + else + { + mAttribsToTranslate.set(attribIndex); + + if (oldStorageType == VertexStorageType::DYNAMIC) + { + ASSERT(mDynamicAttribsMask[attribIndex]); + mDynamicAttribsMask.reset(attribIndex); + } + } + + gl::Buffer *oldBufferGL = mCurrentBuffers[attribIndex].get(); + gl::Buffer *newBufferGL = attrib.buffer.get(); + Buffer11 *oldBuffer11 = oldBufferGL ? GetImplAs(oldBufferGL) : nullptr; + Buffer11 *newBuffer11 = newBufferGL ? GetImplAs(newBufferGL) : nullptr; + + if (oldBuffer11 != newBuffer11 || oldStorageType != newStorageType) + { + // Note that for static callbacks, promotion to a static buffer from a dynamic buffer means + // we need to tag dynamic buffers with static callbacks. + if (oldBuffer11 != nullptr) + { + unlinkBuffer(attribIndex, oldStorageType); + } + if (newBuffer11 != nullptr) + { + if (newStorageType == VertexStorageType::DIRECT) + { + newBuffer11->addDirectBufferDirtyCallback(&mOnBufferDataDirty[attribIndex]); + } + else if (newStorageType == VertexStorageType::STATIC || + newStorageType == VertexStorageType::DYNAMIC) + { + newBuffer11->addStaticBufferDirtyCallback(&mOnBufferDataDirty[attribIndex]); + } + } + mCurrentBuffers[attribIndex] = attrib.buffer; + } +} + +gl::Error VertexArray11::updateDirtyAndDynamicAttribs(VertexDataManager *vertexDataManager, + const gl::State &state, + GLint start, + GLsizei count, + GLsizei instances) +{ + const gl::Program *program = state.getProgram(); + const auto &activeLocations = program->getActiveAttribLocationsMask(); + + if (mAttribsToUpdate.any()) + { + // Skip attrib locations the program doesn't use. + const auto &activeToUpdate = (mAttribsToUpdate & activeLocations); + + for (auto toUpdateIndex : angle::IterateBitSet(activeToUpdate)) + { + mAttribsToUpdate.reset(toUpdateIndex); + updateVertexAttribStorage(toUpdateIndex); + } + } + + const auto &attribs = mData.getVertexAttributes(); + + if (mAttribsToTranslate.any()) + { + // Skip attrib locations the program doesn't use, saving for the next frame. + const auto &dirtyActiveAttribs = (mAttribsToTranslate & activeLocations); + + for (auto dirtyAttribIndex : angle::IterateBitSet(dirtyActiveAttribs)) + { + mAttribsToTranslate.reset(dirtyAttribIndex); + + auto *translatedAttrib = &mTranslatedAttribs[dirtyAttribIndex]; + const auto ¤tValue = + state.getVertexAttribCurrentValue(static_cast(dirtyAttribIndex)); + + // Record basic attrib info + translatedAttrib->attribute = &attribs[dirtyAttribIndex]; + translatedAttrib->currentValueType = currentValue.Type; + translatedAttrib->divisor = translatedAttrib->attribute->divisor; + + switch (mAttributeStorageTypes[dirtyAttribIndex]) + { + case VertexStorageType::DIRECT: + VertexDataManager::StoreDirectAttrib(translatedAttrib); + break; + case VertexStorageType::STATIC: + { + auto error = + VertexDataManager::StoreStaticAttrib(translatedAttrib, count, instances); + if (error.isError()) + { + return error; + } + break; + } + case VertexStorageType::CURRENT_VALUE: + // Current value attribs are managed by the StateManager11. + break; + default: + UNREACHABLE(); + break; + } + } + } + + if (mDynamicAttribsMask.any()) + { + auto activeDynamicAttribs = (mDynamicAttribsMask & activeLocations); + + for (auto dynamicAttribIndex : angle::IterateBitSet(activeDynamicAttribs)) + { + auto *dynamicAttrib = &mTranslatedAttribs[dynamicAttribIndex]; + const auto ¤tValue = + state.getVertexAttribCurrentValue(static_cast(dynamicAttribIndex)); + + // Record basic attrib info + dynamicAttrib->attribute = &attribs[dynamicAttribIndex]; + dynamicAttrib->currentValueType = currentValue.Type; + dynamicAttrib->divisor = dynamicAttrib->attribute->divisor; + } + + return vertexDataManager->storeDynamicAttribs(&mTranslatedAttribs, activeDynamicAttribs, + start, count, instances); + } + + return gl::Error(GL_NO_ERROR); +} + +const std::vector &VertexArray11::getTranslatedAttribs() const +{ + return mTranslatedAttribs; +} + +void VertexArray11::markBufferDataDirty(size_t attribIndex) +{ + ASSERT(mAttributeStorageTypes[attribIndex] != VertexStorageType::CURRENT_VALUE); + + // This can change a buffer's storage, we'll need to re-check. + mAttribsToUpdate.set(attribIndex); +} + +void VertexArray11::clearDirtyAndPromoteDynamicAttribs(const gl::State &state, GLsizei count) +{ + const gl::Program *program = state.getProgram(); + const auto &activeLocations = program->getActiveAttribLocationsMask(); + mAttribsToUpdate &= ~activeLocations; + + // Promote to static after we clear the dirty attributes, otherwise we can lose dirtyness. + auto activeDynamicAttribs = (mDynamicAttribsMask & activeLocations); + VertexDataManager::PromoteDynamicAttribs(mTranslatedAttribs, activeDynamicAttribs, count); +} + +void VertexArray11::unlinkBuffer(size_t attribIndex, VertexStorageType storageType) +{ + Buffer11 *buffer = GetImplAs(mCurrentBuffers[attribIndex].get()); + if (storageType == VertexStorageType::DIRECT) + { + buffer->removeDirectBufferDirtyCallback(&mOnBufferDataDirty[attribIndex]); + } + else if (storageType == VertexStorageType::STATIC || storageType == VertexStorageType::DYNAMIC) + { + buffer->removeStaticBufferDirtyCallback(&mOnBufferDataDirty[attribIndex]); + } +} + +} // namespace rx diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/VertexArray11.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/VertexArray11.h index 78aad7d106ef..f2b4c1380c22 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/VertexArray11.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/VertexArray11.h @@ -19,22 +19,42 @@ class Renderer11; class VertexArray11 : public VertexArrayImpl { public: - VertexArray11(Renderer11 *renderer) - : VertexArrayImpl(), - mRenderer(renderer) - { - } - virtual ~VertexArray11() { } - - virtual void setElementArrayBuffer(const gl::Buffer *buffer) { } - virtual void setAttribute(size_t idx, const gl::VertexAttribute &attr) { } - virtual void setAttributeDivisor(size_t idx, GLuint divisor) { } - virtual void enableAttribute(size_t idx, bool enabledState) { } + VertexArray11(const gl::VertexArray::Data &data); + ~VertexArray11() override; + + void syncState(const gl::VertexArray::DirtyBits &dirtyBits) override; + gl::Error updateDirtyAndDynamicAttribs(VertexDataManager *vertexDataManager, + const gl::State &state, + GLint start, + GLsizei count, + GLsizei instances); + void clearDirtyAndPromoteDynamicAttribs(const gl::State &state, GLsizei count); + + const std::vector &getTranslatedAttribs() const; private: - Renderer11 *mRenderer; + void updateVertexAttribStorage(size_t attribIndex); + void markBufferDataDirty(size_t attribIndex); + void unlinkBuffer(size_t attribIndex, VertexStorageType storageType); + + std::vector mAttributeStorageTypes; + std::vector mTranslatedAttribs; + + // The mask of attributes marked as dynamic. + gl::AttributesMask mDynamicAttribsMask; + + // A mask of attributes that need to be re-evaluated. + gl::AttributesMask mAttribsToUpdate; + + // A set of attributes we know are dirty, and need to be re-translated. + gl::AttributesMask mAttribsToTranslate; + + // We need to keep a safe pointer to the Buffer so we can attach the correct dirty callbacks. + std::vector> mCurrentBuffers; + + std::vector mOnBufferDataDirty; }; -} +} // namespace rx #endif // LIBANGLE_RENDERER_D3D_D3D11_VERTEXARRAY11_H_ diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/VertexBuffer11.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/VertexBuffer11.cpp index 4f1fb00b7d72..8e2d119d2271 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/VertexBuffer11.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/VertexBuffer11.cpp @@ -10,6 +10,7 @@ #include "libANGLE/Buffer.h" #include "libANGLE/VertexAttribute.h" +#include "libANGLE/formatutils.h" #include "libANGLE/renderer/d3d/d3d11/Buffer11.h" #include "libANGLE/renderer/d3d/d3d11/formatutils11.h" #include "libANGLE/renderer/d3d/d3d11/Renderer11.h" @@ -103,16 +104,20 @@ void VertexBuffer11::hintUnmapResource() } } -gl::Error VertexBuffer11::storeVertexAttributes(const gl::VertexAttribute &attrib, const gl::VertexAttribCurrentValueData ¤tValue, - GLint start, GLsizei count, GLsizei instances, unsigned int offset) +gl::Error VertexBuffer11::storeVertexAttributes(const gl::VertexAttribute &attrib, + GLenum currentValueType, + GLint start, + GLsizei count, + GLsizei instances, + unsigned int offset, + const uint8_t *sourceData) { if (!mBuffer) { return gl::Error(GL_OUT_OF_MEMORY, "Internal vertex buffer is not initialized."); } - gl::Buffer *buffer = attrib.buffer.get(); - int inputStride = ComputeVertexAttributeStride(attrib); + int inputStride = static_cast(ComputeVertexAttributeStride(attrib)); // This will map the resource if it isn't already mapped. gl::Error error = mapResource(); @@ -123,86 +128,22 @@ gl::Error VertexBuffer11::storeVertexAttributes(const gl::VertexAttribute &attri uint8_t *output = mMappedResourceData + offset; - const uint8_t *input = NULL; - if (attrib.enabled) - { - if (buffer) - { - BufferD3D *storage = GetImplAs(buffer); - error = storage->getData(&input); - if (error.isError()) - { - return error; - } - input += static_cast(attrib.offset); - } - else - { - input = static_cast(attrib.pointer); - } - } - else - { - input = reinterpret_cast(currentValue.FloatValues); - } + const uint8_t *input = sourceData; if (instances == 0 || attrib.divisor == 0) { input += inputStride * start; } - gl::VertexFormat vertexFormat(attrib, currentValue.Type); - const d3d11::VertexFormat &vertexFormatInfo = d3d11::GetVertexFormatInfo(vertexFormat, mRenderer->getFeatureLevel()); + gl::VertexFormatType vertexFormatType = gl::GetVertexFormatType(attrib, currentValueType); + const D3D_FEATURE_LEVEL featureLevel = mRenderer->getRenderer11DeviceCaps().featureLevel; + const d3d11::VertexFormat &vertexFormatInfo = d3d11::GetVertexFormatInfo(vertexFormatType, featureLevel); ASSERT(vertexFormatInfo.copyFunction != NULL); vertexFormatInfo.copyFunction(input, inputStride, count, output); return gl::Error(GL_NO_ERROR); } -gl::Error VertexBuffer11::getSpaceRequired(const gl::VertexAttribute &attrib, GLsizei count, - GLsizei instances, unsigned int *outSpaceRequired) const -{ - unsigned int elementCount = 0; - if (attrib.enabled) - { - if (instances == 0 || attrib.divisor == 0) - { - elementCount = count; - } - else - { - // Round up to divisor, if possible - elementCount = UnsignedCeilDivide(static_cast(instances), attrib.divisor); - } - - gl::VertexFormat vertexFormat(attrib); - const d3d11::VertexFormat &vertexFormatInfo = d3d11::GetVertexFormatInfo(vertexFormat, mRenderer->getFeatureLevel()); - const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(vertexFormatInfo.nativeFormat); - unsigned int elementSize = dxgiFormatInfo.pixelBytes; - if (elementSize <= std::numeric_limits::max() / elementCount) - { - if (outSpaceRequired) - { - *outSpaceRequired = elementSize * elementCount; - } - return gl::Error(GL_NO_ERROR); - } - else - { - return gl::Error(GL_OUT_OF_MEMORY, "New vertex buffer size would result in an overflow."); - } - } - else - { - const unsigned int elementSize = 4; - if (outSpaceRequired) - { - *outSpaceRequired = elementSize * 4; - } - return gl::Error(GL_NO_ERROR); - } -} - unsigned int VertexBuffer11::getBufferSize() const { return mBufferSize; @@ -246,4 +187,4 @@ ID3D11Buffer *VertexBuffer11::getBuffer() const return mBuffer; } -} +} // namespace rx diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/VertexBuffer11.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/VertexBuffer11.h index 3cc18876286b..e8339db4917a 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/VertexBuffer11.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/VertexBuffer11.h @@ -21,25 +21,27 @@ class VertexBuffer11 : public VertexBuffer { public: explicit VertexBuffer11(Renderer11 *const renderer); - virtual ~VertexBuffer11(); - virtual gl::Error initialize(unsigned int size, bool dynamicUsage); + gl::Error initialize(unsigned int size, bool dynamicUsage) override; - virtual gl::Error storeVertexAttributes(const gl::VertexAttribute &attrib, const gl::VertexAttribCurrentValueData ¤tValue, - GLint start, GLsizei count, GLsizei instances, unsigned int offset); + gl::Error storeVertexAttributes(const gl::VertexAttribute &attrib, + GLenum currentValueType, + GLint start, + GLsizei count, + GLsizei instances, + unsigned int offset, + const uint8_t *sourceData) override; - virtual gl::Error getSpaceRequired(const gl::VertexAttribute &attrib, GLsizei count, GLsizei instances, - unsigned int *outSpaceRequired) const; + unsigned int getBufferSize() const override; + gl::Error setBufferSize(unsigned int size) override; + gl::Error discard() override; - virtual unsigned int getBufferSize() const; - virtual gl::Error setBufferSize(unsigned int size); - virtual gl::Error discard(); - - virtual void hintUnmapResource(); + void hintUnmapResource() override; ID3D11Buffer *getBuffer() const; private: + ~VertexBuffer11() override; gl::Error mapResource(); Renderer11 *const mRenderer; @@ -51,6 +53,6 @@ class VertexBuffer11 : public VertexBuffer uint8_t *mMappedResourceData; }; -} +} // namespace rx #endif // LIBANGLE_RENDERER_D3D_D3D11_VERTEXBUFFER11_H_ diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/copyvertex.inl b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/copyvertex.inl index 1ec21dee55c8..7c5c157c6fa7 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/copyvertex.inl +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/copyvertex.inl @@ -15,33 +15,42 @@ inline void CopyNativeVertexData(const uint8_t *input, size_t stride, size_t cou if (attribSize == stride && inputComponentCount == outputComponentCount) { memcpy(output, input, count * attribSize); + return; } - else - { - const T defaultAlphaValue = gl::bitCast(alphaDefaultValueBits); - const size_t lastNonAlphaOutputComponent = std::min(outputComponentCount, 3); + if (inputComponentCount == outputComponentCount) + { for (size_t i = 0; i < count; i++) { const T *offsetInput = reinterpret_cast(input + (i * stride)); T *offsetOutput = reinterpret_cast(output) + i * outputComponentCount; - for (size_t j = 0; j < inputComponentCount; j++) - { - offsetOutput[j] = offsetInput[j]; - } + memcpy(offsetOutput, offsetInput, attribSize); + } + return; + } - for (size_t j = inputComponentCount; j < lastNonAlphaOutputComponent; j++) - { - // Set the remaining G/B channels to 0. - offsetOutput[j] = 0; - } + const T defaultAlphaValue = gl::bitCast(alphaDefaultValueBits); + const size_t lastNonAlphaOutputComponent = std::min(outputComponentCount, 3); - if (inputComponentCount < outputComponentCount && outputComponentCount == 4) - { - // Set the remaining alpha channel to the defaultAlphaValue. - offsetOutput[3] = defaultAlphaValue; - } + for (size_t i = 0; i < count; i++) + { + const T *offsetInput = reinterpret_cast(input + (i * stride)); + 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; } } } diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/dxgi_support_data.json b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/dxgi_support_data.json new file mode 100644 index 000000000000..e81b4deea541 --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/dxgi_support_data.json @@ -0,0 +1,1164 @@ +[ + { + "DXGI_FORMAT_UNKNOWN": + { + "texture2D": "never", + "texture3D": "never", + "textureCube": "never", + "shaderSample": "never", + "renderTarget": "never", + "multisampleRT": "never", + "depthStencil": "never" + }, + "DXGI_FORMAT_R32G32B32A32_TYPELESS": + { + "texture2D": "always", + "texture3D": "always", + "textureCube": "always", + "shaderSample": "never", + "renderTarget": "never", + "multisampleRT": "never", + "depthStencil": "never" + }, + "DXGI_FORMAT_R32G32B32A32_FLOAT": + { + "texture2D": "always", + "texture3D": "always", + "textureCube": "always", + "shaderSample": "10_0check10_1always", + "renderTarget": "always", + "multisampleRT": "check", + "depthStencil": "never" + }, + "DXGI_FORMAT_R32G32B32A32_UINT": + { + "texture2D": "always", + "texture3D": "always", + "textureCube": "always", + "shaderSample": "never", + "renderTarget": "always", + "multisampleRT": "check", + "depthStencil": "never" + }, + "DXGI_FORMAT_R32G32B32A32_SINT": + { + "texture2D": "always", + "texture3D": "always", + "textureCube": "always", + "shaderSample": "never", + "renderTarget": "always", + "multisampleRT": "check", + "depthStencil": "never" + }, + "DXGI_FORMAT_R32G32B32_TYPELESS": + { + "texture2D": "always", + "texture3D": "always", + "textureCube": "always", + "shaderSample": "never", + "renderTarget": "never", + "multisampleRT": "never", + "depthStencil": "never" + }, + "DXGI_FORMAT_R32G32B32_FLOAT": + { + "texture2D": "always", + "texture3D": "always", + "textureCube": "always", + "shaderSample": "11_0check", + "renderTarget": "check", + "multisampleRT": "check", + "depthStencil": "never" + }, + "DXGI_FORMAT_R32G32B32_UINT": + { + "texture2D": "always", + "texture3D": "always", + "textureCube": "always", + "shaderSample": "never", + "renderTarget": "check", + "multisampleRT": "check", + "depthStencil": "never" + }, + "DXGI_FORMAT_R32G32B32_SINT": + { + "texture2D": "always", + "texture3D": "always", + "textureCube": "always", + "shaderSample": "never", + "renderTarget": "check", + "multisampleRT": "check", + "depthStencil": "never" + }, + "DXGI_FORMAT_R16G16B16A16_TYPELESS": + { + "texture2D": "always", + "texture3D": "always", + "textureCube": "always", + "shaderSample": "never", + "renderTarget": "never", + "multisampleRT": "never", + "depthStencil": "never" + }, + "DXGI_FORMAT_R16G16B16A16_FLOAT": + { + "texture2D": "always", + "texture3D": "always", + "textureCube": "always", + "shaderSample": "10_0", + "renderTarget": "always", + "multisampleRT": "check", + "depthStencil": "never" + }, + "DXGI_FORMAT_R16G16B16A16_UNORM": + { + "texture2D": "always", + "texture3D": "always", + "textureCube": "always", + "shaderSample": "10_0", + "renderTarget": "always", + "multisampleRT": "check", + "depthStencil": "never" + }, + "DXGI_FORMAT_R16G16B16A16_UINT": + { + "texture2D": "always", + "texture3D": "always", + "textureCube": "always", + "shaderSample": "never", + "renderTarget": "always", + "multisampleRT": "check", + "depthStencil": "never" + }, + "DXGI_FORMAT_R16G16B16A16_SNORM": + { + "texture2D": "always", + "texture3D": "always", + "textureCube": "always", + "shaderSample": "10_0", + "renderTarget": "always", + "multisampleRT": "check", + "depthStencil": "never" + }, + "DXGI_FORMAT_R16G16B16A16_SINT": + { + "texture2D": "always", + "texture3D": "always", + "textureCube": "always", + "shaderSample": "never", + "renderTarget": "always", + "multisampleRT": "check", + "depthStencil": "never" + }, + "DXGI_FORMAT_R32G32_TYPELESS": + { + "texture2D": "always", + "texture3D": "always", + "textureCube": "always", + "shaderSample": "never", + "renderTarget": "never", + "multisampleRT": "never", + "depthStencil": "never" + }, + "DXGI_FORMAT_R32G32_FLOAT": + { + "texture2D": "always", + "texture3D": "always", + "textureCube": "always", + "shaderSample": "10_0check10_1always", + "renderTarget": "always", + "multisampleRT": "check", + "depthStencil": "never" + }, + "DXGI_FORMAT_R32G32_UINT": + { + "texture2D": "always", + "texture3D": "always", + "textureCube": "always", + "shaderSample": "never", + "renderTarget": "always", + "multisampleRT": "check", + "depthStencil": "never" + }, + "DXGI_FORMAT_R32G32_SINT": + { + "texture2D": "always", + "texture3D": "always", + "textureCube": "always", + "shaderSample": "never", + "renderTarget": "always", + "multisampleRT": "check", + "depthStencil": "never" + }, + "DXGI_FORMAT_R32G8X24_TYPELESS": + { + "texture2D": "always", + "texture3D": "never", + "textureCube": "always", + "shaderSample": "never", + "renderTarget": "never", + "multisampleRT": "never", + "depthStencil": "never" + }, + "DXGI_FORMAT_D32_FLOAT_S8X24_UINT": + { + "texture2D": "always", + "texture3D": "never", + "textureCube": "always", + "shaderSample": "never", + "renderTarget": "never", + "multisampleRT": "check", + "depthStencil": "always" + }, + "DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS": + { + "texture2D": "always", + "texture3D": "never", + "textureCube": "always", + "shaderSample": "10_0check10_1always", + "renderTarget": "never", + "multisampleRT": "never", + "depthStencil": "never" + }, + "DXGI_FORMAT_X32_TYPELESS_G8X24_UINT": + { + "texture2D": "always", + "texture3D": "never", + "textureCube": "always", + "shaderSample": "never", + "renderTarget": "never", + "multisampleRT": "never", + "depthStencil": "never" + }, + "DXGI_FORMAT_R10G10B10A2_TYPELESS": + { + "texture2D": "always", + "texture3D": "always", + "textureCube": "always", + "shaderSample": "never", + "renderTarget": "never", + "multisampleRT": "never", + "depthStencil": "never" + }, + "DXGI_FORMAT_R10G10B10A2_UNORM": + { + "texture2D": "always", + "texture3D": "always", + "textureCube": "always", + "shaderSample": "10_0", + "renderTarget": "always", + "multisampleRT": "check", + "depthStencil": "never" + }, + "DXGI_FORMAT_R10G10B10A2_UINT": + { + "texture2D": "always", + "texture3D": "always", + "textureCube": "always", + "shaderSample": "never", + "renderTarget": "always", + "multisampleRT": "check", + "depthStencil": "never" + }, + "DXGI_FORMAT_R11G11B10_FLOAT": + { + "texture2D": "always", + "texture3D": "always", + "textureCube": "always", + "shaderSample": "10_0", + "renderTarget": "always", + "multisampleRT": "check", + "depthStencil": "never" + }, + "DXGI_FORMAT_R8G8B8A8_TYPELESS": + { + "texture2D": "always", + "texture3D": "always", + "textureCube": "always", + "shaderSample": "never", + "renderTarget": "never", + "multisampleRT": "never", + "depthStencil": "never" + }, + "DXGI_FORMAT_R8G8B8A8_UNORM": + { + "texture2D": "always", + "texture3D": "always", + "textureCube": "always", + "shaderSample": "10_0", + "renderTarget": "always", + "multisampleRT": "check", + "depthStencil": "never" + }, + "DXGI_FORMAT_R8G8B8A8_UNORM_SRGB": + { + "texture2D": "always", + "texture3D": "always", + "textureCube": "always", + "shaderSample": "10_0", + "renderTarget": "always", + "multisampleRT": "check", + "depthStencil": "never" + }, + "DXGI_FORMAT_R8G8B8A8_UINT": + { + "texture2D": "always", + "texture3D": "always", + "textureCube": "always", + "shaderSample": "never", + "renderTarget": "always", + "multisampleRT": "check", + "depthStencil": "never" + }, + "DXGI_FORMAT_R8G8B8A8_SNORM": + { + "texture2D": "always", + "texture3D": "always", + "textureCube": "always", + "shaderSample": "10_0", + "renderTarget": "always", + "multisampleRT": "check", + "depthStencil": "never" + }, + "DXGI_FORMAT_R8G8B8A8_SINT": + { + "texture2D": "always", + "texture3D": "always", + "textureCube": "always", + "shaderSample": "never", + "renderTarget": "always", + "multisampleRT": "check", + "depthStencil": "never" + }, + "DXGI_FORMAT_R16G16_TYPELESS": + { + "texture2D": "always", + "texture3D": "always", + "textureCube": "always", + "shaderSample": "never", + "renderTarget": "never", + "multisampleRT": "never", + "depthStencil": "never" + }, + "DXGI_FORMAT_R16G16_FLOAT": + { + "texture2D": "always", + "texture3D": "always", + "textureCube": "always", + "shaderSample": "10_0", + "renderTarget": "always", + "multisampleRT": "check", + "depthStencil": "never" + }, + "DXGI_FORMAT_R16G16_UNORM": + { + "texture2D": "always", + "texture3D": "always", + "textureCube": "always", + "shaderSample": "10_0", + "renderTarget": "always", + "multisampleRT": "check", + "depthStencil": "never" + }, + "DXGI_FORMAT_R16G16_UINT": + { + "texture2D": "always", + "texture3D": "always", + "textureCube": "always", + "shaderSample": "never", + "renderTarget": "always", + "multisampleRT": "check", + "depthStencil": "never" + }, + "DXGI_FORMAT_R16G16_SNORM": + { + "texture2D": "always", + "texture3D": "always", + "textureCube": "always", + "shaderSample": "10_0", + "renderTarget": "always", + "multisampleRT": "check", + "depthStencil": "never" + }, + "DXGI_FORMAT_R16G16_SINT": + { + "texture2D": "always", + "texture3D": "always", + "textureCube": "always", + "shaderSample": "never", + "renderTarget": "always", + "multisampleRT": "check", + "depthStencil": "never" + }, + "DXGI_FORMAT_R32_TYPELESS": + { + "texture2D": "always", + "texture3D": "always", + "textureCube": "always", + "shaderSample": "never", + "renderTarget": "never", + "multisampleRT": "never", + "depthStencil": "never" + }, + "DXGI_FORMAT_D32_FLOAT": + { + "texture2D": "always", + "texture3D": "never", + "textureCube": "always", + "shaderSample": "never", + "renderTarget": "never", + "multisampleRT": "check", + "depthStencil": "always" + }, + "DXGI_FORMAT_R32_FLOAT": + { + "texture2D": "always", + "texture3D": "always", + "textureCube": "always", + "shaderSample": "10_0check10_1always", + "renderTarget": "always", + "multisampleRT": "check", + "depthStencil": "never" + }, + "DXGI_FORMAT_R32_UINT": + { + "texture2D": "always", + "texture3D": "always", + "textureCube": "always", + "shaderSample": "never", + "renderTarget": "always", + "multisampleRT": "check", + "depthStencil": "never" + }, + "DXGI_FORMAT_R32_SINT": + { + "texture2D": "always", + "texture3D": "always", + "textureCube": "always", + "shaderSample": "never", + "renderTarget": "always", + "multisampleRT": "check", + "depthStencil": "never" + }, + "DXGI_FORMAT_R24G8_TYPELESS": + { + "texture2D": "always", + "texture3D": "never", + "textureCube": "always", + "shaderSample": "never", + "renderTarget": "never", + "multisampleRT": "never", + "depthStencil": "never" + }, + "DXGI_FORMAT_D24_UNORM_S8_UINT": + { + "texture2D": "always", + "texture3D": "never", + "textureCube": "always", + "shaderSample": "never", + "renderTarget": "never", + "multisampleRT": "check", + "depthStencil": "always" + }, + "DXGI_FORMAT_R24_UNORM_X8_TYPELESS": + { + "texture2D": "always", + "texture3D": "never", + "textureCube": "always", + "shaderSample": "10_0check10_1always", + "renderTarget": "never", + "multisampleRT": "never", + "depthStencil": "never" + }, + "DXGI_FORMAT_X24_TYPELESS_G8_UINT": + { + "texture2D": "always", + "texture3D": "never", + "textureCube": "always", + "shaderSample": "never", + "renderTarget": "never", + "multisampleRT": "never", + "depthStencil": "never" + }, + "DXGI_FORMAT_R8G8_TYPELESS": + { + "texture2D": "always", + "texture3D": "always", + "textureCube": "always", + "shaderSample": "never", + "renderTarget": "never", + "multisampleRT": "never", + "depthStencil": "never" + }, + "DXGI_FORMAT_R8G8_UNORM": + { + "texture2D": "always", + "texture3D": "always", + "textureCube": "always", + "shaderSample": "10_0", + "renderTarget": "always", + "multisampleRT": "check", + "depthStencil": "never" + }, + "DXGI_FORMAT_R8G8_UINT": + { + "texture2D": "always", + "texture3D": "always", + "textureCube": "always", + "shaderSample": "never", + "renderTarget": "always", + "multisampleRT": "check", + "depthStencil": "never" + }, + "DXGI_FORMAT_R8G8_SNORM": + { + "texture2D": "always", + "texture3D": "always", + "textureCube": "always", + "shaderSample": "10_0", + "renderTarget": "always", + "multisampleRT": "check", + "depthStencil": "never" + }, + "DXGI_FORMAT_R8G8_SINT": + { + "texture2D": "always", + "texture3D": "always", + "textureCube": "always", + "shaderSample": "never", + "renderTarget": "always", + "multisampleRT": "check", + "depthStencil": "never" + }, + "DXGI_FORMAT_R16_TYPELESS": + { + "texture2D": "always", + "texture3D": "always", + "textureCube": "always", + "shaderSample": "never", + "renderTarget": "never", + "multisampleRT": "never", + "depthStencil": "never" + }, + "DXGI_FORMAT_R16_FLOAT": + { + "texture2D": "always", + "texture3D": "always", + "textureCube": "always", + "shaderSample": "10_0", + "renderTarget": "always", + "multisampleRT": "check", + "depthStencil": "never" + }, + "DXGI_FORMAT_D16_UNORM": + { + "texture2D": "always", + "texture3D": "never", + "textureCube": "always", + "shaderSample": "never", + "renderTarget": "never", + "multisampleRT": "check", + "depthStencil": "always" + }, + "DXGI_FORMAT_R16_UNORM": + { + "texture2D": "always", + "texture3D": "always", + "textureCube": "always", + "shaderSample": "10_0", + "renderTarget": "always", + "multisampleRT": "check", + "depthStencil": "never" + }, + "DXGI_FORMAT_R16_UINT": + { + "texture2D": "always", + "texture3D": "always", + "textureCube": "always", + "shaderSample": "never", + "renderTarget": "always", + "multisampleRT": "check", + "depthStencil": "never" + }, + "DXGI_FORMAT_R16_SNORM": + { + "texture2D": "always", + "texture3D": "always", + "textureCube": "always", + "shaderSample": "10_0", + "renderTarget": "always", + "multisampleRT": "check", + "depthStencil": "never" + }, + "DXGI_FORMAT_R16_SINT": + { + "texture2D": "always", + "texture3D": "always", + "textureCube": "always", + "shaderSample": "never", + "renderTarget": "always", + "multisampleRT": "check", + "depthStencil": "never" + }, + "DXGI_FORMAT_R8_TYPELESS": + { + "texture2D": "always", + "texture3D": "always", + "textureCube": "always", + "shaderSample": "never", + "renderTarget": "never", + "multisampleRT": "never", + "depthStencil": "never" + }, + "DXGI_FORMAT_R8_UNORM": + { + "texture2D": "always", + "texture3D": "always", + "textureCube": "always", + "shaderSample": "10_0", + "renderTarget": "always", + "multisampleRT": "check", + "depthStencil": "never" + }, + "DXGI_FORMAT_R8_UINT": + { + "texture2D": "always", + "texture3D": "always", + "textureCube": "always", + "shaderSample": "never", + "renderTarget": "always", + "multisampleRT": "check", + "depthStencil": "never" + }, + "DXGI_FORMAT_R8_SNORM": + { + "texture2D": "always", + "texture3D": "always", + "textureCube": "always", + "shaderSample": "10_0", + "renderTarget": "always", + "multisampleRT": "check", + "depthStencil": "never" + }, + "DXGI_FORMAT_R8_SINT": + { + "texture2D": "always", + "texture3D": "always", + "textureCube": "always", + "shaderSample": "never", + "renderTarget": "always", + "multisampleRT": "check", + "depthStencil": "never" + }, + "DXGI_FORMAT_A8_UNORM": + { + "texture2D": "always", + "texture3D": "always", + "textureCube": "always", + "shaderSample": "10_0", + "renderTarget": "always", + "multisampleRT": "check", + "depthStencil": "never" + }, + "DXGI_FORMAT_R1_UNORM": + { + "texture2D": "always", + "texture3D": "11_0", + "textureCube": "11_0", + "shaderSample": "never", + "renderTarget": "never", + "multisampleRT": "never", + "depthStencil": "never" + }, + "DXGI_FORMAT_R9G9B9E5_SHAREDEXP": + { + "texture2D": "always", + "texture3D": "always", + "textureCube": "always", + "shaderSample": "10_0", + "renderTarget": "never", + "multisampleRT": "never", + "depthStencil": "never" + }, + "DXGI_FORMAT_R8G8_B8G8_UNORM": + { + "texture2D": "always", + "texture3D": "always", + "textureCube": "always", + "shaderSample": "10_0", + "renderTarget": "never", + "multisampleRT": "never", + "depthStencil": "never" + }, + "DXGI_FORMAT_G8R8_G8B8_UNORM": + { + "texture2D": "always", + "texture3D": "always", + "textureCube": "always", + "shaderSample": "10_0", + "renderTarget": "never", + "multisampleRT": "never", + "depthStencil": "never" + }, + "DXGI_FORMAT_BC1_TYPELESS": + { + "texture2D": "always", + "texture3D": "always", + "textureCube": "always", + "shaderSample": "never", + "renderTarget": "never", + "multisampleRT": "never", + "depthStencil": "never" + }, + "DXGI_FORMAT_BC1_UNORM": + { + "texture2D": "always", + "texture3D": "always", + "textureCube": "always", + "shaderSample": "10_0", + "renderTarget": "never", + "multisampleRT": "never", + "depthStencil": "never" + }, + "DXGI_FORMAT_BC1_UNORM_SRGB": + { + "texture2D": "always", + "texture3D": "always", + "textureCube": "always", + "shaderSample": "10_0", + "renderTarget": "never", + "multisampleRT": "never", + "depthStencil": "never" + }, + "DXGI_FORMAT_BC2_TYPELESS": + { + "texture2D": "always", + "texture3D": "always", + "textureCube": "always", + "shaderSample": "never", + "renderTarget": "never", + "multisampleRT": "never", + "depthStencil": "never" + }, + "DXGI_FORMAT_BC2_UNORM": + { + "texture2D": "always", + "texture3D": "always", + "textureCube": "always", + "shaderSample": "10_0", + "renderTarget": "never", + "multisampleRT": "never", + "depthStencil": "never" + }, + "DXGI_FORMAT_BC2_UNORM_SRGB": + { + "texture2D": "always", + "texture3D": "always", + "textureCube": "always", + "shaderSample": "10_0", + "renderTarget": "never", + "multisampleRT": "never", + "depthStencil": "never" + }, + "DXGI_FORMAT_BC3_TYPELESS": + { + "texture2D": "always", + "texture3D": "always", + "textureCube": "always", + "shaderSample": "never", + "renderTarget": "never", + "multisampleRT": "never", + "depthStencil": "never" + }, + "DXGI_FORMAT_BC3_UNORM": + { + "texture2D": "always", + "texture3D": "always", + "textureCube": "always", + "shaderSample": "10_0", + "renderTarget": "never", + "multisampleRT": "never", + "depthStencil": "never" + }, + "DXGI_FORMAT_BC3_UNORM_SRGB": + { + "texture2D": "always", + "texture3D": "always", + "textureCube": "always", + "shaderSample": "10_0", + "renderTarget": "never", + "multisampleRT": "never", + "depthStencil": "never" + }, + "DXGI_FORMAT_BC4_TYPELESS": + { + "texture2D": "always", + "texture3D": "always", + "textureCube": "always", + "shaderSample": "never", + "renderTarget": "never", + "multisampleRT": "never", + "depthStencil": "never" + }, + "DXGI_FORMAT_BC4_UNORM": + { + "texture2D": "always", + "texture3D": "always", + "textureCube": "always", + "shaderSample": "10_0", + "renderTarget": "never", + "multisampleRT": "never", + "depthStencil": "never" + }, + "DXGI_FORMAT_BC4_SNORM": + { + "texture2D": "always", + "texture3D": "always", + "textureCube": "always", + "shaderSample": "10_0", + "renderTarget": "never", + "multisampleRT": "never", + "depthStencil": "never" + }, + "DXGI_FORMAT_BC5_TYPELESS": + { + "texture2D": "always", + "texture3D": "always", + "textureCube": "always", + "shaderSample": "never", + "renderTarget": "never", + "multisampleRT": "never", + "depthStencil": "never" + }, + "DXGI_FORMAT_BC5_UNORM": + { + "texture2D": "always", + "texture3D": "always", + "textureCube": "always", + "shaderSample": "10_0", + "renderTarget": "never", + "multisampleRT": "never", + "depthStencil": "never" + }, + "DXGI_FORMAT_BC5_SNORM": + { + "texture2D": "always", + "texture3D": "always", + "textureCube": "always", + "shaderSample": "10_0", + "renderTarget": "never", + "multisampleRT": "never", + "depthStencil": "never" + }, + "DXGI_FORMAT_B5G6R5_UNORM": + { + "texture2D": "dxgi1_2", + "texture3D": "dxgi1_2", + "textureCube": "dxgi1_2", + "shaderSample": "dxgi1_2", + "renderTarget": "dxgi1_2", + "multisampleRT": "check", + "depthStencil": "never" + }, + "DXGI_FORMAT_B5G5R5A1_UNORM": + { + "texture2D": "dxgi1_2", + "texture3D": "dxgi1_2", + "textureCube": "dxgi1_2", + "shaderSample": "dxgi1_2", + "renderTarget": "check", + "multisampleRT": "check", + "depthStencil": "never" + }, + "DXGI_FORMAT_B8G8R8A8_UNORM": + { + "texture2D": "check", + "texture3D": "check", + "textureCube": "check", + "shaderSample": "10_0check11_0always", + "renderTarget": "10_0check11_0always", + "multisampleRT": "check", + "depthStencil": "never" + }, + "DXGI_FORMAT_B8G8R8X8_UNORM": + { + "texture2D": "check", + "texture3D": "check", + "textureCube": "check", + "shaderSample": "10_0check11_0always", + "renderTarget": "11_0", + "multisampleRT": "check", + "depthStencil": "never" + }, + "DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM": + { + "texture2D": "check", + "texture3D": "check", + "textureCube": "never", + "shaderSample": "never", + "renderTarget": "never", + "multisampleRT": "never", + "depthStencil": "never" + }, + "DXGI_FORMAT_B8G8R8A8_TYPELESS": + { + "texture2D": "check", + "texture3D": "check", + "textureCube": "check", + "shaderSample": "never", + "renderTarget": "never", + "multisampleRT": "never", + "depthStencil": "never" + }, + "DXGI_FORMAT_B8G8R8A8_UNORM_SRGB": + { + "texture2D": "check", + "texture3D": "check", + "textureCube": "check", + "shaderSample": "10_0check11_0always", + "renderTarget": "11_0", + "multisampleRT": "check", + "depthStencil": "never" + }, + "DXGI_FORMAT_B8G8R8X8_TYPELESS": + { + "texture2D": "check", + "texture3D": "check", + "textureCube": "check", + "shaderSample": "never", + "renderTarget": "never", + "multisampleRT": "never", + "depthStencil": "never" + }, + "DXGI_FORMAT_B8G8R8X8_UNORM_SRGB": + { + "texture2D": "check", + "texture3D": "check", + "textureCube": "check", + "shaderSample": "10_0check11_0always", + "renderTarget": "11_0", + "multisampleRT": "check", + "depthStencil": "never" + }, + "DXGI_FORMAT_BC6H_TYPELESS": + { + "texture2D": "11_0", + "texture3D": "11_0", + "textureCube": "11_0", + "shaderSample": "never", + "renderTarget": "never", + "multisampleRT": "never", + "depthStencil": "never" + }, + "DXGI_FORMAT_BC6H_UF16": + { + "texture2D": "11_0", + "texture3D": "11_0", + "textureCube": "11_0", + "shaderSample": "11_0", + "renderTarget": "never", + "multisampleRT": "never", + "depthStencil": "never" + }, + "DXGI_FORMAT_BC6H_SF16": + { + "texture2D": "11_0", + "texture3D": "11_0", + "textureCube": "11_0", + "shaderSample": "11_0", + "renderTarget": "never", + "multisampleRT": "never", + "depthStencil": "never" + }, + "DXGI_FORMAT_BC7_TYPELESS": + { + "texture2D": "11_0", + "texture3D": "11_0", + "textureCube": "11_0", + "shaderSample": "never", + "renderTarget": "never", + "multisampleRT": "never", + "depthStencil": "never" + }, + "DXGI_FORMAT_BC7_UNORM": + { + "texture2D": "11_0", + "texture3D": "11_0", + "textureCube": "11_0", + "shaderSample": "11_0", + "renderTarget": "never", + "multisampleRT": "never", + "depthStencil": "never" + }, + "DXGI_FORMAT_BC7_UNORM_SRGB": + { + "texture2D": "11_0", + "texture3D": "11_0", + "textureCube": "11_0", + "shaderSample": "11_0", + "renderTarget": "never", + "multisampleRT": "never", + "depthStencil": "never" + }, + "DXGI_FORMAT_AYUV": + { + "texture2D": "11_1", + "texture3D": "never", + "textureCube": "never", + "shaderSample": "11_1", + "renderTarget": "11_1", + "multisampleRT": "check", + "depthStencil": "never" + }, + "DXGI_FORMAT_Y410": + { + "texture2D": "11_1", + "texture3D": "never", + "textureCube": "never", + "shaderSample": "11_1", + "renderTarget": "never", + "multisampleRT": "never", + "depthStencil": "never" + }, + "DXGI_FORMAT_Y416": + { + "texture2D": "11_1", + "texture3D": "never", + "textureCube": "never", + "shaderSample": "11_1", + "renderTarget": "never", + "multisampleRT": "never", + "depthStencil": "never" + }, + "DXGI_FORMAT_NV12": + { + "texture2D": "11_1", + "texture3D": "never", + "textureCube": "never", + "shaderSample": "11_1", + "renderTarget": "11_1", + "multisampleRT": "check", + "depthStencil": "never" + }, + "DXGI_FORMAT_P010": + { + "texture2D": "11_1", + "texture3D": "never", + "textureCube": "never", + "shaderSample": "11_1", + "renderTarget": "11_1", + "multisampleRT": "check", + "depthStencil": "never" + }, + "DXGI_FORMAT_P016": + { + "texture2D": "11_1", + "texture3D": "never", + "textureCube": "never", + "shaderSample": "11_1", + "renderTarget": "11_1", + "multisampleRT": "check", + "depthStencil": "never" + }, + "DXGI_FORMAT_420_OPAQUE": + { + "texture2D": "11_1", + "texture3D": "never", + "textureCube": "never", + "shaderSample": "never", + "renderTarget": "never", + "multisampleRT": "never", + "depthStencil": "never" + }, + "DXGI_FORMAT_YUY2": + { + "texture2D": "11_1", + "texture3D": "never", + "textureCube": "never", + "shaderSample": "11_1", + "renderTarget": "never", + "multisampleRT": "never", + "depthStencil": "never" + }, + "DXGI_FORMAT_Y210": + { + "texture2D": "11_1", + "texture3D": "never", + "textureCube": "never", + "shaderSample": "11_1", + "renderTarget": "never", + "multisampleRT": "never", + "depthStencil": "never" + }, + "DXGI_FORMAT_Y216": + { + "texture2D": "11_1", + "texture3D": "never", + "textureCube": "never", + "shaderSample": "11_1", + "renderTarget": "never", + "multisampleRT": "never", + "depthStencil": "never" + }, + "DXGI_FORMAT_NV11": + { + "texture2D": "11_1", + "texture3D": "never", + "textureCube": "never", + "shaderSample": "11_1", + "renderTarget": "11_1", + "multisampleRT": "check", + "depthStencil": "never" + }, + "DXGI_FORMAT_AI44": + { + "texture2D": "11_1", + "texture3D": "never", + "textureCube": "never", + "shaderSample": "never", + "renderTarget": "never", + "multisampleRT": "never", + "depthStencil": "never" + }, + "DXGI_FORMAT_IA44": + { + "texture2D": "11_1", + "texture3D": "never", + "textureCube": "never", + "shaderSample": "never", + "renderTarget": "never", + "multisampleRT": "never", + "depthStencil": "never" + }, + "DXGI_FORMAT_P8": + { + "texture2D": "11_1", + "texture3D": "never", + "textureCube": "never", + "shaderSample": "never", + "renderTarget": "never", + "multisampleRT": "never", + "depthStencil": "never" + }, + "DXGI_FORMAT_A8P8": + { + "texture2D": "11_1", + "texture3D": "never", + "textureCube": "never", + "shaderSample": "never", + "renderTarget": "never", + "multisampleRT": "never", + "depthStencil": "never" + }, + "DXGI_FORMAT_B4G4R4A4_UNORM": + { + "texture2D": "dxgi1_2", + "texture3D": "dxgi1_2", + "textureCube": "dxgi1_2", + "shaderSample": "dxgi1_2", + "renderTarget": "check", + "multisampleRT": "check", + "depthStencil": "never" + } + } +] diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/dxgi_support_table.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/dxgi_support_table.cpp new file mode 100644 index 000000000000..cbc36445e678 --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/dxgi_support_table.cpp @@ -0,0 +1,1846 @@ +// 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/d3d/d3d11/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 + +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; + static const DXGISupport defaultSupport(0, 0, AllSupportFlags); + return defaultSupport; +} + +const DXGISupport &GetDXGISupport_10_0(DXGI_FORMAT dxgiFormat) +{ + switch (dxgiFormat) + { + case DXGI_FORMAT_420_OPAQUE: + { + static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_A8P8: + { + static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | 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_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_AI44: + { + static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_AYUV: + { + static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_RT | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_B4G4R4A4_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | 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_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_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_B8G8R8A8_TYPELESS: + { + static const DXGISupport info(0, F_DS | F_MS | F_RT | F_SAMPLE, F_2D | F_3D | F_CUBE); + return info; + } + case DXGI_FORMAT_B8G8R8A8_UNORM: + { + static const DXGISupport info(0, 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(0, 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_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_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_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_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_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_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_BC2_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | 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_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_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_BC3_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | 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_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_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_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_BC4_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | 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_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_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_BC5_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | 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_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_BC6H_SF16: + { + static const DXGISupport info(0, F_DS | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_BC6H_TYPELESS: + { + static const DXGISupport info(0, F_DS | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_BC6H_UF16: + { + static const DXGISupport info(0, F_DS | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_BC7_TYPELESS: + { + static const DXGISupport info(0, F_DS | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_BC7_UNORM: + { + static const DXGISupport info(0, F_DS | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_BC7_UNORM_SRGB: + { + static const DXGISupport info(0, F_DS | 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_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_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_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_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_IA44: + { + static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_NV11: + { + static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_RT | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_NV12: + { + static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_RT | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_P010: + { + static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_RT | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_P016: + { + static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_RT | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_P8: + { + static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | 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_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_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R10G10B10A2_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | 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_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_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_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_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R16G16B16A16_SNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | 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_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_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R16G16B16A16_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | 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_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_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_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_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R16G16_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | 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_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_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R16_SNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | 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_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_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R16_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R1_UNORM: + { + static const DXGISupport info(F_2D, F_DS | 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_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_MS | F_RT, F_SAMPLE); + return info; + } + case DXGI_FORMAT_R32G32B32A32_FLOAT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | 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_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R32G32B32A32_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | 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_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R32G32B32_FLOAT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS, F_MS | F_RT); + return info; + } + case DXGI_FORMAT_R32G32B32_SINT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | 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_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_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 | F_SAMPLE); + return info; + } + case DXGI_FORMAT_R32G32_SINT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R32G32_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | 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_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R32G8X24_TYPELESS: + { + static const DXGISupport info(F_2D | F_CUBE, F_3D | F_DS | 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_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_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_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R32_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | 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_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_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_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_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R8G8B8A8_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | 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_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_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_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R8G8_SNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | 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_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_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R8G8_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | 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_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R8_SNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | 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_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_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R8_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | 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_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_UNKNOWN: + { + static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | 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_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_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_Y210: + { + static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_Y216: + { + static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_Y410: + { + static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_Y416: + { + static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_YUY2: + { + static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + + default: + UNREACHABLE(); + return GetDefaultSupport(); + } +} + +const DXGISupport &GetDXGISupport_10_1(DXGI_FORMAT dxgiFormat) +{ + switch (dxgiFormat) + { + case DXGI_FORMAT_420_OPAQUE: + { + static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_A8P8: + { + static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | 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_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_AI44: + { + static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_AYUV: + { + static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_RT | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_B4G4R4A4_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | 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_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_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_B8G8R8A8_TYPELESS: + { + static const DXGISupport info(0, F_DS | F_MS | F_RT | F_SAMPLE, F_2D | F_3D | F_CUBE); + return info; + } + case DXGI_FORMAT_B8G8R8A8_UNORM: + { + static const DXGISupport info(0, 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(0, 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_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_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_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_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_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_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_BC2_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | 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_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_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_BC3_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | 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_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_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_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_BC4_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | 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_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_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_BC5_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | 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_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_BC6H_SF16: + { + static const DXGISupport info(0, F_DS | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_BC6H_TYPELESS: + { + static const DXGISupport info(0, F_DS | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_BC6H_UF16: + { + static const DXGISupport info(0, F_DS | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_BC7_TYPELESS: + { + static const DXGISupport info(0, F_DS | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_BC7_UNORM: + { + static const DXGISupport info(0, F_DS | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_BC7_UNORM_SRGB: + { + static const DXGISupport info(0, F_DS | 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_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_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_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_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_IA44: + { + static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_NV11: + { + static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_RT | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_NV12: + { + static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_RT | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_P010: + { + static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_RT | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_P016: + { + static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_RT | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_P8: + { + static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | 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_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_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R10G10B10A2_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | 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_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_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_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_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R16G16B16A16_SNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | 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_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_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R16G16B16A16_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | 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_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_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_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_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R16G16_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | 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_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_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R16_SNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | 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_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_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R16_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R1_UNORM: + { + static const DXGISupport info(F_2D, F_DS | 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_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_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_R32G32B32A32_FLOAT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | 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_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R32G32B32A32_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | 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_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R32G32B32_FLOAT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS, F_MS | F_RT); + return info; + } + case DXGI_FORMAT_R32G32B32_SINT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | 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_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_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_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_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R32G32_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | 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_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R32G8X24_TYPELESS: + { + static const DXGISupport info(F_2D | F_CUBE, F_3D | F_DS | 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_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_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_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R32_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | 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_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_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_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_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R8G8B8A8_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | 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_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_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_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R8G8_SNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | 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_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_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R8G8_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | 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_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R8_SNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | 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_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_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R8_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | 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_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_UNKNOWN: + { + static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | 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_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_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_Y210: + { + static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_Y216: + { + static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_Y410: + { + static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_Y416: + { + static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_YUY2: + { + static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + + default: + UNREACHABLE(); + return GetDefaultSupport(); + } +} + +const DXGISupport &GetDXGISupport_11_0(DXGI_FORMAT dxgiFormat) +{ + switch (dxgiFormat) + { + case DXGI_FORMAT_420_OPAQUE: + { + static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_A8P8: + { + static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | 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_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_AI44: + { + static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_AYUV: + { + static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_RT | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_B4G4R4A4_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | 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_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_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_B8G8R8A8_TYPELESS: + { + static const DXGISupport info(0, F_DS | F_MS | F_RT | F_SAMPLE, F_2D | F_3D | F_CUBE); + return info; + } + case DXGI_FORMAT_B8G8R8A8_UNORM: + { + static const DXGISupport info(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_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_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_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_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_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_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_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_BC2_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | 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_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_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_BC3_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | 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_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_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_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_BC4_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | 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_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_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_BC5_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | 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_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_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_BC6H_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | 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_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_BC7_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | 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_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_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_D16_UNORM: + { + static const DXGISupport info(F_2D | F_CUBE | F_DS, F_3D | 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_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_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_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_IA44: + { + static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_NV11: + { + static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_RT | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_NV12: + { + static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_RT | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_P010: + { + static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_RT | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_P016: + { + static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_RT | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_P8: + { + static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | 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_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_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R10G10B10A2_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | 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_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_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_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_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R16G16B16A16_SNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | 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_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_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R16G16B16A16_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | 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_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_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_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_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R16G16_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | 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_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_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R16_SNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | 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_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_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R16_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | 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_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_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_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_R32G32B32A32_FLOAT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | 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_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R32G32B32A32_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | 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_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R32G32B32_FLOAT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS, F_MS | F_RT); + return info; + } + case DXGI_FORMAT_R32G32B32_SINT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | 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_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_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_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_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R32G32_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | 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_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R32G8X24_TYPELESS: + { + static const DXGISupport info(F_2D | F_CUBE, F_3D | F_DS | 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_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_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_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R32_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | 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_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_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_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_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R8G8B8A8_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | 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_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_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_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R8G8_SNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | 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_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_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R8G8_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | 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_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R8_SNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | 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_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_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R8_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | 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_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_UNKNOWN: + { + static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | 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_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_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_Y210: + { + static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_Y216: + { + static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_Y410: + { + static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_Y416: + { + static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_YUY2: + { + static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + + default: + UNREACHABLE(); + return GetDefaultSupport(); + } +} + +} + +#undef F_2D +#undef F_3D +#undef F_CUBE +#undef F_SAMPLE +#undef F_RT +#undef F_MS +#undef F_DS + +const DXGISupport &GetDXGISupport(DXGI_FORMAT dxgiFormat, D3D_FEATURE_LEVEL featureLevel) +{ + switch (featureLevel) + { + 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); + default: + return GetDefaultSupport(); + } +} + +} // namespace d3d11 + +} // namespace rx diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/dxgi_support_table.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/dxgi_support_table.h new file mode 100644 index 000000000000..1d8d68565e6c --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/dxgi_support_table.h @@ -0,0 +1,44 @@ +// +// 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 "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 diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/formatutils11.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/formatutils11.cpp index f3909f11801a..7a94835b0705 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/formatutils11.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/formatutils11.cpp @@ -10,11 +10,13 @@ #include "libANGLE/renderer/d3d/d3d11/formatutils11.h" #include "libANGLE/formatutils.h" -#include "libANGLE/renderer/Renderer.h" #include "libANGLE/renderer/d3d/copyimage.h" +#include "libANGLE/renderer/d3d/d3d11/copyvertex.h" +#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h" +#include "libANGLE/renderer/d3d/d3d11/Renderer11.h" #include "libANGLE/renderer/d3d/generatemip.h" #include "libANGLE/renderer/d3d/loadimage.h" -#include "libANGLE/renderer/d3d/d3d11/copyvertex.h" +#include "libANGLE/renderer/Renderer.h" namespace rx { @@ -22,86 +24,6 @@ namespace rx namespace d3d11 { -typedef std::map DXGIToESFormatMap; - -inline void AddDXGIToESEntry(DXGIToESFormatMap *map, DXGI_FORMAT key, GLenum value) -{ - map->insert(std::make_pair(key, value)); -} - -static DXGIToESFormatMap BuildDXGIToESFormatMap() -{ - DXGIToESFormatMap map; - - AddDXGIToESEntry(&map, DXGI_FORMAT_UNKNOWN, GL_NONE); - - AddDXGIToESEntry(&map, DXGI_FORMAT_A8_UNORM, GL_ALPHA8_EXT); - AddDXGIToESEntry(&map, DXGI_FORMAT_R8_UNORM, GL_R8); - AddDXGIToESEntry(&map, DXGI_FORMAT_R8G8_UNORM, GL_RG8); - AddDXGIToESEntry(&map, DXGI_FORMAT_R8G8B8A8_UNORM, GL_RGBA8); - AddDXGIToESEntry(&map, DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, GL_SRGB8_ALPHA8); - AddDXGIToESEntry(&map, DXGI_FORMAT_B8G8R8A8_UNORM, GL_BGRA8_EXT); - - AddDXGIToESEntry(&map, DXGI_FORMAT_R8_SNORM, GL_R8_SNORM); - AddDXGIToESEntry(&map, DXGI_FORMAT_R8G8_SNORM, GL_RG8_SNORM); - AddDXGIToESEntry(&map, DXGI_FORMAT_R8G8B8A8_SNORM, GL_RGBA8_SNORM); - - AddDXGIToESEntry(&map, DXGI_FORMAT_R8_UINT, GL_R8UI); - AddDXGIToESEntry(&map, DXGI_FORMAT_R16_UINT, GL_R16UI); - AddDXGIToESEntry(&map, DXGI_FORMAT_R32_UINT, GL_R32UI); - AddDXGIToESEntry(&map, DXGI_FORMAT_R8G8_UINT, GL_RG8UI); - AddDXGIToESEntry(&map, DXGI_FORMAT_R16G16_UINT, GL_RG16UI); - AddDXGIToESEntry(&map, DXGI_FORMAT_R32G32_UINT, GL_RG32UI); - AddDXGIToESEntry(&map, DXGI_FORMAT_R32G32B32_UINT, GL_RGB32UI); - AddDXGIToESEntry(&map, DXGI_FORMAT_R8G8B8A8_UINT, GL_RGBA8UI); - AddDXGIToESEntry(&map, DXGI_FORMAT_R16G16B16A16_UINT, GL_RGBA16UI); - AddDXGIToESEntry(&map, DXGI_FORMAT_R32G32B32A32_UINT, GL_RGBA32UI); - - AddDXGIToESEntry(&map, DXGI_FORMAT_R8_SINT, GL_R8I); - AddDXGIToESEntry(&map, DXGI_FORMAT_R16_SINT, GL_R16I); - AddDXGIToESEntry(&map, DXGI_FORMAT_R32_SINT, GL_R32I); - AddDXGIToESEntry(&map, DXGI_FORMAT_R8G8_SINT, GL_RG8I); - AddDXGIToESEntry(&map, DXGI_FORMAT_R16G16_SINT, GL_RG16I); - AddDXGIToESEntry(&map, DXGI_FORMAT_R32G32_SINT, GL_RG32I); - AddDXGIToESEntry(&map, DXGI_FORMAT_R32G32B32_SINT, GL_RGB32I); - AddDXGIToESEntry(&map, DXGI_FORMAT_R8G8B8A8_SINT, GL_RGBA8I); - AddDXGIToESEntry(&map, DXGI_FORMAT_R16G16B16A16_SINT, GL_RGBA16I); - AddDXGIToESEntry(&map, DXGI_FORMAT_R32G32B32A32_SINT, GL_RGBA32I); - - AddDXGIToESEntry(&map, DXGI_FORMAT_R10G10B10A2_UNORM, GL_RGB10_A2); - AddDXGIToESEntry(&map, DXGI_FORMAT_R10G10B10A2_UINT, GL_RGB10_A2UI); - - AddDXGIToESEntry(&map, DXGI_FORMAT_R16_FLOAT, GL_R16F); - AddDXGIToESEntry(&map, DXGI_FORMAT_R16G16_FLOAT, GL_RG16F); - AddDXGIToESEntry(&map, DXGI_FORMAT_R16G16B16A16_FLOAT, GL_RGBA16F); - - AddDXGIToESEntry(&map, DXGI_FORMAT_R32_FLOAT, GL_R32F); - AddDXGIToESEntry(&map, DXGI_FORMAT_R32G32_FLOAT, GL_RG32F); - AddDXGIToESEntry(&map, DXGI_FORMAT_R32G32B32_FLOAT, GL_RGB32F); - AddDXGIToESEntry(&map, DXGI_FORMAT_R32G32B32A32_FLOAT, GL_RGBA32F); - - AddDXGIToESEntry(&map, DXGI_FORMAT_R9G9B9E5_SHAREDEXP, GL_RGB9_E5); - AddDXGIToESEntry(&map, DXGI_FORMAT_R11G11B10_FLOAT, GL_R11F_G11F_B10F); - - AddDXGIToESEntry(&map, DXGI_FORMAT_R16_TYPELESS, GL_DEPTH_COMPONENT16); - AddDXGIToESEntry(&map, DXGI_FORMAT_R16_UNORM, GL_DEPTH_COMPONENT16); - AddDXGIToESEntry(&map, DXGI_FORMAT_D16_UNORM, GL_DEPTH_COMPONENT16); - AddDXGIToESEntry(&map, DXGI_FORMAT_R24G8_TYPELESS, GL_DEPTH24_STENCIL8_OES); - AddDXGIToESEntry(&map, DXGI_FORMAT_R24_UNORM_X8_TYPELESS, GL_DEPTH24_STENCIL8_OES); - AddDXGIToESEntry(&map, DXGI_FORMAT_D24_UNORM_S8_UINT, GL_DEPTH24_STENCIL8_OES); - AddDXGIToESEntry(&map, DXGI_FORMAT_R32G8X24_TYPELESS, GL_DEPTH32F_STENCIL8); - AddDXGIToESEntry(&map, DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS, GL_DEPTH32F_STENCIL8); - AddDXGIToESEntry(&map, DXGI_FORMAT_D32_FLOAT_S8X24_UINT, GL_DEPTH32F_STENCIL8); - AddDXGIToESEntry(&map, DXGI_FORMAT_R32_TYPELESS, GL_DEPTH_COMPONENT32F); - AddDXGIToESEntry(&map, DXGI_FORMAT_D32_FLOAT, GL_DEPTH_COMPONENT32F); - - AddDXGIToESEntry(&map, DXGI_FORMAT_BC1_UNORM, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT); - AddDXGIToESEntry(&map, DXGI_FORMAT_BC2_UNORM, GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE); - AddDXGIToESEntry(&map, DXGI_FORMAT_BC3_UNORM, GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE); - - return map; -} - struct D3D11FastCopyFormat { GLenum destFormat; @@ -161,6 +83,7 @@ static ColorFormatInfoMap BuildColorFormatInfoMap() { ColorFormatInfoMap map; + // clang-format off // | DXGI format | R | G | B | A | S | InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_A8_UNORM, 0, 0, 0, 8, 0); InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R8_UNORM, 8, 0, 0, 0, 0); @@ -168,10 +91,16 @@ static ColorFormatInfoMap BuildColorFormatInfoMap() InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R8G8B8A8_UNORM, 8, 8, 8, 8, 0); InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, 8, 8, 8, 8, 0); InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_B8G8R8A8_UNORM, 8, 8, 8, 8, 0); + InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R16_UNORM, 16, 0, 0, 0, 0); + InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R16G16_UNORM, 16, 16, 0, 0, 0); + InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R16G16B16A16_UNORM, 16, 16, 16, 16, 0); InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R8_SNORM, 8, 0, 0, 0, 0); InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R8G8_SNORM, 8, 8, 0, 0, 0); InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R8G8B8A8_SNORM, 8, 8, 8, 8, 0); + InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R16_SNORM, 16, 0, 0, 0, 0); + InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R16G16_SNORM, 16, 16, 0, 0, 0); + InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R16G16B16A16_SNORM, 16, 16, 16, 16, 0); InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R8_UINT, 8, 0, 0, 0, 0); InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R16_UINT, 16, 0, 0, 0, 0); @@ -195,6 +124,7 @@ static ColorFormatInfoMap BuildColorFormatInfoMap() InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R16G16B16A16_SINT, 16, 16, 16, 16, 0); InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R32G32B32A32_SINT, 32, 32, 32, 32, 0); + InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R10G10B10A2_TYPELESS, 10, 10, 10, 2, 0); InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R10G10B10A2_UNORM, 10, 10, 10, 2, 0); InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R10G10B10A2_UINT, 10, 10, 10, 2, 0); @@ -210,28 +140,47 @@ static ColorFormatInfoMap BuildColorFormatInfoMap() InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R9G9B9E5_SHAREDEXP, 9, 9, 9, 0, 5); InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R11G11B10_FLOAT, 11, 11, 10, 0, 0); + InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_B5G6R5_UNORM, 5, 6, 5, 0, 0); + InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_B4G4R4A4_UNORM, 4, 4, 4, 4, 0); + InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_B5G5R5A1_UNORM, 5, 5, 5, 1, 0); + + InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R8_TYPELESS, 8, 0, 0, 0, 0); + InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R16_TYPELESS, 16, 0, 0, 0, 0); + InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R32_TYPELESS, 32, 0, 0, 0, 0); + InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R8G8_TYPELESS, 8, 8, 0, 0, 0); + InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R16G16_TYPELESS, 16, 16, 0, 0, 0); + InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R32G32_TYPELESS, 32, 32, 0, 0, 0); + InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R32G32B32_TYPELESS, 32, 32, 32, 0, 0); + InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R8G8B8A8_TYPELESS, 8, 8, 8, 8, 0); + InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R16G16B16A16_TYPELESS, 16, 16, 16, 16, 0); + InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R32G32B32A32_TYPELESS, 32, 32, 32, 32, 0); + + InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R24G8_TYPELESS, 24, 8, 0, 0, 0); + InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R24_UNORM_X8_TYPELESS, 24, 0, 0, 0, 0); + InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R32G8X24_TYPELESS, 32, 8, 0, 0, 0); + InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS, 32, 0, 0, 0, 0); + // clang-format on + return map; } struct DXGIDepthStencilInfo { unsigned int depthBits; - unsigned int depthOffset; unsigned int stencilBits; - unsigned int stencilOffset; }; typedef std::map DepthStencilInfoMap; typedef std::pair DepthStencilInfoPair; -static inline void InsertDXGIDepthStencilInfo(DepthStencilInfoMap *map, DXGI_FORMAT format, unsigned int depthBits, - unsigned int depthOffset, unsigned int stencilBits, unsigned int stencilOffset) +static inline void InsertDXGIDepthStencilInfo(DepthStencilInfoMap *map, + DXGI_FORMAT format, + unsigned int depthBits, + unsigned int stencilBits) { DXGIDepthStencilInfo info; info.depthBits = depthBits; - info.depthOffset = depthOffset; info.stencilBits = stencilBits; - info.stencilOffset = stencilOffset; map->insert(std::make_pair(format, info)); } @@ -240,21 +189,12 @@ static DepthStencilInfoMap BuildDepthStencilInfoMap() { DepthStencilInfoMap map; - InsertDXGIDepthStencilInfo(&map, DXGI_FORMAT_R16_TYPELESS, 16, 0, 0, 0); - InsertDXGIDepthStencilInfo(&map, DXGI_FORMAT_R16_UNORM, 16, 0, 0, 0); - InsertDXGIDepthStencilInfo(&map, DXGI_FORMAT_D16_UNORM, 16, 0, 0, 0); - - InsertDXGIDepthStencilInfo(&map, DXGI_FORMAT_R24G8_TYPELESS, 24, 0, 8, 24); - InsertDXGIDepthStencilInfo(&map, DXGI_FORMAT_R24_UNORM_X8_TYPELESS, 24, 0, 8, 24); - InsertDXGIDepthStencilInfo(&map, DXGI_FORMAT_D24_UNORM_S8_UINT, 24, 0, 8, 24); - - InsertDXGIDepthStencilInfo(&map, DXGI_FORMAT_R32_TYPELESS, 32, 0, 0, 0); - InsertDXGIDepthStencilInfo(&map, DXGI_FORMAT_R32_FLOAT, 32, 0, 0, 0); - InsertDXGIDepthStencilInfo(&map, DXGI_FORMAT_D32_FLOAT, 32, 0, 0, 0); - - InsertDXGIDepthStencilInfo(&map, DXGI_FORMAT_R32G8X24_TYPELESS, 32, 0, 8, 32); - InsertDXGIDepthStencilInfo(&map, DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS, 32, 0, 8, 32); - InsertDXGIDepthStencilInfo(&map, DXGI_FORMAT_D32_FLOAT_S8X24_UINT, 32, 0, 8, 32); + // clang-format off + InsertDXGIDepthStencilInfo(&map, DXGI_FORMAT_D16_UNORM, 16, 0); + InsertDXGIDepthStencilInfo(&map, DXGI_FORMAT_D24_UNORM_S8_UINT, 24, 8); + InsertDXGIDepthStencilInfo(&map, DXGI_FORMAT_D32_FLOAT, 32, 0); + InsertDXGIDepthStencilInfo(&map, DXGI_FORMAT_D32_FLOAT_S8X24_UINT, 32, 8); + // clang-format on return map; } @@ -262,22 +202,14 @@ static DepthStencilInfoMap BuildDepthStencilInfoMap() typedef std::map DXGIFormatInfoMap; DXGIFormat::DXGIFormat() - : pixelBytes(0), - blockWidth(0), - blockHeight(0), - redBits(0), + : redBits(0), greenBits(0), blueBits(0), alphaBits(0), sharedBits(0), depthBits(0), - depthOffset(0), stencilBits(0), - stencilOffset(0), - internalFormat(GL_NONE), componentType(GL_NONE), - mipGenerationFunction(NULL), - colorReadFunction(NULL), fastCopyFunctions(), nativeMipmapSupport(NULL) { @@ -300,24 +232,23 @@ ColorCopyFunction DXGIFormat::getFastCopyFunction(GLenum format, GLenum type) co return (iter != fastCopyFunctions.end()) ? iter->second : NULL; } -void AddDXGIFormat(DXGIFormatInfoMap *map, DXGI_FORMAT dxgiFormat, GLuint pixelBits, GLuint blockWidth, GLuint blockHeight, - GLenum componentType, MipGenerationFunction mipFunc, ColorReadFunction readFunc, NativeMipmapGenerationSupportFunction nativeMipmapSupport) +void AddDXGIFormat(DXGIFormatInfoMap *map, + DXGI_FORMAT dxgiFormat, + GLenum componentType, + NativeMipmapGenerationSupportFunction nativeMipmapSupport) { DXGIFormat info; - info.pixelBytes = pixelBits / 8; - info.blockWidth = blockWidth; - info.blockHeight = blockHeight; static const ColorFormatInfoMap colorInfoMap = BuildColorFormatInfoMap(); ColorFormatInfoMap::const_iterator colorInfoIter = colorInfoMap.find(dxgiFormat); if (colorInfoIter != colorInfoMap.end()) { const DXGIColorFormatInfo &colorInfo = colorInfoIter->second; - info.redBits = colorInfo.redBits; - info.greenBits = colorInfo.greenBits; - info.blueBits = colorInfo.blueBits; - info.alphaBits = colorInfo.alphaBits; - info.sharedBits = colorInfo.sharedBits; + info.redBits = static_cast(colorInfo.redBits); + info.greenBits = static_cast(colorInfo.greenBits); + info.blueBits = static_cast(colorInfo.blueBits); + info.alphaBits = static_cast(colorInfo.alphaBits); + info.sharedBits = static_cast(colorInfo.sharedBits); } static const DepthStencilInfoMap dsInfoMap = BuildDepthStencilInfoMap(); @@ -326,20 +257,11 @@ void AddDXGIFormat(DXGIFormatInfoMap *map, DXGI_FORMAT dxgiFormat, GLuint pixelB { const DXGIDepthStencilInfo &dsInfo = dsInfoIter->second; info.depthBits = dsInfo.depthBits; - info.depthOffset = dsInfo.depthOffset; info.stencilBits = dsInfo.stencilBits; - info.stencilOffset = dsInfo.stencilOffset; } - static const DXGIToESFormatMap dxgiToESMap = BuildDXGIToESFormatMap(); - DXGIToESFormatMap::const_iterator dxgiToESIter = dxgiToESMap.find(dxgiFormat); - info.internalFormat = (dxgiToESIter != dxgiToESMap.end()) ? dxgiToESIter->second : GL_NONE; - info.componentType = componentType; - info.mipGenerationFunction = mipFunc; - info.colorReadFunction = readFunc; - static const D3D11FastCopyMap fastCopyMap = BuildFastCopyMap(); std::pair fastCopyIter = fastCopyMap.equal_range(dxgiFormat); for (D3D11FastCopyMap::const_iterator i = fastCopyIter.first; i != fastCopyIter.second; i++) @@ -352,85 +274,104 @@ void AddDXGIFormat(DXGIFormatInfoMap *map, DXGI_FORMAT dxgiFormat, GLuint pixelB map->insert(std::make_pair(dxgiFormat, info)); } -// A map to determine the pixel size and mipmap generation function of a given DXGI format +// A map to determine the color read function and mipmap generation function of a given DXGI format static DXGIFormatInfoMap BuildDXGIFormatInfoMap() { DXGIFormatInfoMap map; - // | DXGI format |S |W |H |Component Type | Mip generation function | Color read function | Native mipmap function - AddDXGIFormat(&map, DXGI_FORMAT_UNKNOWN, 0, 0, 0, GL_NONE, NULL, NULL, NeverSupported); - - AddDXGIFormat(&map, DXGI_FORMAT_A8_UNORM, 8, 1, 1, GL_UNSIGNED_NORMALIZED, GenerateMip, ReadColor, RequiresFeatureLevel); - AddDXGIFormat(&map, DXGI_FORMAT_R8_UNORM, 8, 1, 1, GL_UNSIGNED_NORMALIZED, GenerateMip, ReadColor, RequiresFeatureLevel); - AddDXGIFormat(&map, DXGI_FORMAT_R8G8_UNORM, 16, 1, 1, GL_UNSIGNED_NORMALIZED, GenerateMip, ReadColor, RequiresFeatureLevel); - AddDXGIFormat(&map, DXGI_FORMAT_R8G8B8A8_UNORM, 32, 1, 1, GL_UNSIGNED_NORMALIZED, GenerateMip, ReadColor, RequiresFeatureLevel); - AddDXGIFormat(&map, DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, 32, 1, 1, GL_UNSIGNED_NORMALIZED, GenerateMip, ReadColor, RequiresFeatureLevel); - AddDXGIFormat(&map, DXGI_FORMAT_B8G8R8A8_UNORM, 32, 1, 1, GL_UNSIGNED_NORMALIZED, GenerateMip, ReadColor, RequiresFeatureLevel); - - AddDXGIFormat(&map, DXGI_FORMAT_R8_SNORM, 8, 1, 1, GL_SIGNED_NORMALIZED, GenerateMip, ReadColor , RequiresFeatureLevel); - AddDXGIFormat(&map, DXGI_FORMAT_R8G8_SNORM, 16, 1, 1, GL_SIGNED_NORMALIZED, GenerateMip, ReadColor , RequiresFeatureLevel); - AddDXGIFormat(&map, DXGI_FORMAT_R8G8B8A8_SNORM, 32, 1, 1, GL_SIGNED_NORMALIZED, GenerateMip, ReadColor, RequiresFeatureLevel); - - AddDXGIFormat(&map, DXGI_FORMAT_R8_UINT, 8, 1, 1, GL_UNSIGNED_INT, GenerateMip, ReadColor, NeverSupported); - AddDXGIFormat(&map, DXGI_FORMAT_R16_UINT, 16, 1, 1, GL_UNSIGNED_INT, GenerateMip, ReadColor, NeverSupported); - AddDXGIFormat(&map, DXGI_FORMAT_R32_UINT, 32, 1, 1, GL_UNSIGNED_INT, GenerateMip, ReadColor, NeverSupported); - AddDXGIFormat(&map, DXGI_FORMAT_R8G8_UINT, 16, 1, 1, GL_UNSIGNED_INT, GenerateMip, ReadColor, NeverSupported); - AddDXGIFormat(&map, DXGI_FORMAT_R16G16_UINT, 32, 1, 1, GL_UNSIGNED_INT, GenerateMip, ReadColor, NeverSupported); - AddDXGIFormat(&map, DXGI_FORMAT_R32G32_UINT, 64, 1, 1, GL_UNSIGNED_INT, GenerateMip, ReadColor, NeverSupported); - AddDXGIFormat(&map, DXGI_FORMAT_R32G32B32_UINT, 96, 1, 1, GL_UNSIGNED_INT, GenerateMip, ReadColor, NeverSupported); - AddDXGIFormat(&map, DXGI_FORMAT_R8G8B8A8_UINT, 32, 1, 1, GL_UNSIGNED_INT, GenerateMip, ReadColor, NeverSupported); - AddDXGIFormat(&map, DXGI_FORMAT_R16G16B16A16_UINT, 64, 1, 1, GL_UNSIGNED_INT, GenerateMip, ReadColor, NeverSupported); - AddDXGIFormat(&map, DXGI_FORMAT_R32G32B32A32_UINT, 128, 1, 1, GL_UNSIGNED_INT, GenerateMip, ReadColor, NeverSupported); - - AddDXGIFormat(&map, DXGI_FORMAT_R8_SINT, 8, 1, 1, GL_INT, GenerateMip, ReadColor, NeverSupported); - AddDXGIFormat(&map, DXGI_FORMAT_R16_SINT, 16, 1, 1, GL_INT, GenerateMip, ReadColor, NeverSupported); - AddDXGIFormat(&map, DXGI_FORMAT_R32_SINT, 32, 1, 1, GL_INT, GenerateMip, ReadColor, NeverSupported); - AddDXGIFormat(&map, DXGI_FORMAT_R8G8_SINT, 16, 1, 1, GL_INT, GenerateMip, ReadColor, NeverSupported); - AddDXGIFormat(&map, DXGI_FORMAT_R16G16_SINT, 32, 1, 1, GL_INT, GenerateMip, ReadColor, NeverSupported); - AddDXGIFormat(&map, DXGI_FORMAT_R32G32_SINT, 64, 1, 1, GL_INT, GenerateMip, ReadColor, NeverSupported); - AddDXGIFormat(&map, DXGI_FORMAT_R32G32B32_SINT, 96, 1, 1, GL_INT, GenerateMip, ReadColor, NeverSupported); - AddDXGIFormat(&map, DXGI_FORMAT_R8G8B8A8_SINT, 32, 1, 1, GL_INT, GenerateMip, ReadColor, NeverSupported); - AddDXGIFormat(&map, DXGI_FORMAT_R16G16B16A16_SINT, 64, 1, 1, GL_INT, GenerateMip, ReadColor, NeverSupported); - AddDXGIFormat(&map, DXGI_FORMAT_R32G32B32A32_SINT, 128, 1, 1, GL_INT, GenerateMip, ReadColor, NeverSupported); - - AddDXGIFormat(&map, DXGI_FORMAT_R10G10B10A2_UNORM, 32, 1, 1, GL_UNSIGNED_NORMALIZED, GenerateMip, ReadColor, RequiresFeatureLevel); - AddDXGIFormat(&map, DXGI_FORMAT_R10G10B10A2_UINT, 32, 1, 1, GL_UNSIGNED_INT, GenerateMip, ReadColor, NeverSupported); - - AddDXGIFormat(&map, DXGI_FORMAT_R16_FLOAT, 16, 1, 1, GL_FLOAT, GenerateMip, ReadColor, RequiresFeatureLevel); - AddDXGIFormat(&map, DXGI_FORMAT_R16G16_FLOAT, 32, 1, 1, GL_FLOAT, GenerateMip, ReadColor, RequiresFeatureLevel); - AddDXGIFormat(&map, DXGI_FORMAT_R16G16B16A16_FLOAT, 64, 1, 1, GL_FLOAT, GenerateMip, ReadColor, RequiresFeatureLevel); - - AddDXGIFormat(&map, DXGI_FORMAT_R32_FLOAT, 32, 1, 1, GL_FLOAT, GenerateMip, ReadColor, RequiresFeatureLevel); - AddDXGIFormat(&map, DXGI_FORMAT_R32G32_FLOAT, 64, 1, 1, GL_FLOAT, GenerateMip, ReadColor, RequiresFeatureLevel); - AddDXGIFormat(&map, DXGI_FORMAT_R32G32B32_FLOAT, 96, 1, 1, GL_FLOAT, NULL, NULL, NeverSupported); - AddDXGIFormat(&map, DXGI_FORMAT_R32G32B32A32_FLOAT, 128, 1, 1, GL_FLOAT, GenerateMip, ReadColor, RequiresFeatureLevel); - - AddDXGIFormat(&map, DXGI_FORMAT_R9G9B9E5_SHAREDEXP, 32, 1, 1, GL_FLOAT, GenerateMip, ReadColor, NeverSupported); - AddDXGIFormat(&map, DXGI_FORMAT_R11G11B10_FLOAT, 32, 1, 1, GL_FLOAT, GenerateMip, ReadColor, RequiresFeatureLevel); - - AddDXGIFormat(&map, DXGI_FORMAT_R16_TYPELESS, 16, 1, 1, GL_NONE, NULL, NULL, NeverSupported); - AddDXGIFormat(&map, DXGI_FORMAT_R16_UNORM, 16, 1, 1, GL_UNSIGNED_NORMALIZED, NULL, NULL, NeverSupported); - AddDXGIFormat(&map, DXGI_FORMAT_D16_UNORM, 16, 1, 1, GL_UNSIGNED_NORMALIZED, NULL, NULL, NeverSupported); - AddDXGIFormat(&map, DXGI_FORMAT_R24G8_TYPELESS, 32, 1, 1, GL_NONE, NULL, NULL, NeverSupported); - AddDXGIFormat(&map, DXGI_FORMAT_R24_UNORM_X8_TYPELESS, 32, 1, 1, GL_NONE, NULL, NULL, NeverSupported); - AddDXGIFormat(&map, DXGI_FORMAT_D24_UNORM_S8_UINT, 32, 1, 1, GL_UNSIGNED_INT, NULL, NULL, NeverSupported); - AddDXGIFormat(&map, DXGI_FORMAT_R32G8X24_TYPELESS, 64, 1, 1, GL_NONE, NULL, NULL, NeverSupported); - AddDXGIFormat(&map, DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS, 64, 1, 1, GL_NONE, NULL, NULL, NeverSupported); - AddDXGIFormat(&map, DXGI_FORMAT_D32_FLOAT_S8X24_UINT, 64, 1, 1, GL_UNSIGNED_INT, NULL, NULL, NeverSupported); - AddDXGIFormat(&map, DXGI_FORMAT_R32_TYPELESS, 32, 1, 1, GL_NONE, NULL, NULL, NeverSupported); - AddDXGIFormat(&map, DXGI_FORMAT_D32_FLOAT, 32, 1, 1, GL_FLOAT, NULL, NULL, NeverSupported); - - AddDXGIFormat(&map, DXGI_FORMAT_BC1_UNORM, 64, 4, 4, GL_UNSIGNED_NORMALIZED, NULL, NULL, NeverSupported); - AddDXGIFormat(&map, DXGI_FORMAT_BC2_UNORM, 128, 4, 4, GL_UNSIGNED_NORMALIZED, NULL, NULL, NeverSupported); - AddDXGIFormat(&map, DXGI_FORMAT_BC3_UNORM, 128, 4, 4, GL_UNSIGNED_NORMALIZED, NULL, NULL, NeverSupported); - - // Useful formats for vertex buffers - AddDXGIFormat(&map, DXGI_FORMAT_R16_UNORM, 16, 1, 1, GL_UNSIGNED_NORMALIZED, NULL, NULL, NeverSupported); - AddDXGIFormat(&map, DXGI_FORMAT_R16_SNORM, 16, 1, 1, GL_SIGNED_NORMALIZED, NULL, NULL, NeverSupported); - AddDXGIFormat(&map, DXGI_FORMAT_R16G16_UNORM, 32, 1, 1, GL_UNSIGNED_NORMALIZED, NULL, NULL, NeverSupported); - AddDXGIFormat(&map, DXGI_FORMAT_R16G16_SNORM, 32, 1, 1, GL_SIGNED_NORMALIZED, NULL, NULL, NeverSupported); - AddDXGIFormat(&map, DXGI_FORMAT_R16G16B16A16_UNORM, 64, 1, 1, GL_UNSIGNED_NORMALIZED, NULL, NULL, NeverSupported); - AddDXGIFormat(&map, DXGI_FORMAT_R16G16B16A16_SNORM, 64, 1, 1, GL_SIGNED_NORMALIZED, NULL, NULL, NeverSupported); + // clang-format off + // | DXGI format | Component Type | Color read function | Native mipmap function + AddDXGIFormat(&map, DXGI_FORMAT_UNKNOWN, GL_NONE, NeverSupported); + + AddDXGIFormat(&map, DXGI_FORMAT_A8_UNORM, GL_UNSIGNED_NORMALIZED, RequiresFeatureLevel); + AddDXGIFormat(&map, DXGI_FORMAT_R8_UNORM, GL_UNSIGNED_NORMALIZED, RequiresFeatureLevel); + AddDXGIFormat(&map, DXGI_FORMAT_R16_UNORM, GL_UNSIGNED_NORMALIZED, NeverSupported); + AddDXGIFormat(&map, DXGI_FORMAT_R8G8_UNORM, GL_UNSIGNED_NORMALIZED, RequiresFeatureLevel); + AddDXGIFormat(&map, DXGI_FORMAT_R16G16_UNORM, GL_UNSIGNED_NORMALIZED, NeverSupported); + AddDXGIFormat(&map, DXGI_FORMAT_R8G8B8A8_UNORM, GL_UNSIGNED_NORMALIZED, RequiresFeatureLevel); + AddDXGIFormat(&map, DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, GL_UNSIGNED_NORMALIZED, RequiresFeatureLevel); + AddDXGIFormat(&map, DXGI_FORMAT_B8G8R8A8_UNORM, GL_UNSIGNED_NORMALIZED, RequiresFeatureLevel); + AddDXGIFormat(&map, DXGI_FORMAT_R16G16B16A16_UNORM, GL_UNSIGNED_NORMALIZED, NeverSupported); + + AddDXGIFormat(&map, DXGI_FORMAT_R8_SNORM, GL_SIGNED_NORMALIZED, RequiresFeatureLevel); + AddDXGIFormat(&map, DXGI_FORMAT_R16_SNORM, GL_SIGNED_NORMALIZED, NeverSupported); + AddDXGIFormat(&map, DXGI_FORMAT_R8G8_SNORM, GL_SIGNED_NORMALIZED, RequiresFeatureLevel); + AddDXGIFormat(&map, DXGI_FORMAT_R16G16_SNORM, GL_SIGNED_NORMALIZED, NeverSupported); + AddDXGIFormat(&map, DXGI_FORMAT_R8G8B8A8_SNORM, GL_SIGNED_NORMALIZED, RequiresFeatureLevel); + AddDXGIFormat(&map, DXGI_FORMAT_R16G16B16A16_SNORM, GL_SIGNED_NORMALIZED, NeverSupported); + + AddDXGIFormat(&map, DXGI_FORMAT_R8_UINT, GL_UNSIGNED_INT, NeverSupported); + AddDXGIFormat(&map, DXGI_FORMAT_R16_UINT, GL_UNSIGNED_INT, NeverSupported); + AddDXGIFormat(&map, DXGI_FORMAT_R32_UINT, GL_UNSIGNED_INT, NeverSupported); + AddDXGIFormat(&map, DXGI_FORMAT_R8G8_UINT, GL_UNSIGNED_INT, NeverSupported); + AddDXGIFormat(&map, DXGI_FORMAT_R16G16_UINT, GL_UNSIGNED_INT, NeverSupported); + AddDXGIFormat(&map, DXGI_FORMAT_R32G32_UINT, GL_UNSIGNED_INT, NeverSupported); + AddDXGIFormat(&map, DXGI_FORMAT_R32G32B32_UINT, GL_UNSIGNED_INT, NeverSupported); + AddDXGIFormat(&map, DXGI_FORMAT_R8G8B8A8_UINT, GL_UNSIGNED_INT, NeverSupported); + AddDXGIFormat(&map, DXGI_FORMAT_R16G16B16A16_UINT, GL_UNSIGNED_INT, NeverSupported); + AddDXGIFormat(&map, DXGI_FORMAT_R32G32B32A32_UINT, GL_UNSIGNED_INT, NeverSupported); + + AddDXGIFormat(&map, DXGI_FORMAT_R8_SINT, GL_INT, NeverSupported); + AddDXGIFormat(&map, DXGI_FORMAT_R16_SINT, GL_INT, NeverSupported); + AddDXGIFormat(&map, DXGI_FORMAT_R32_SINT, GL_INT, NeverSupported); + AddDXGIFormat(&map, DXGI_FORMAT_R8G8_SINT, GL_INT, NeverSupported); + AddDXGIFormat(&map, DXGI_FORMAT_R16G16_SINT, GL_INT, NeverSupported); + AddDXGIFormat(&map, DXGI_FORMAT_R32G32_SINT, GL_INT, NeverSupported); + AddDXGIFormat(&map, DXGI_FORMAT_R32G32B32_SINT, GL_INT, NeverSupported); + AddDXGIFormat(&map, DXGI_FORMAT_R8G8B8A8_SINT, GL_INT, NeverSupported); + AddDXGIFormat(&map, DXGI_FORMAT_R16G16B16A16_SINT, GL_INT, NeverSupported); + AddDXGIFormat(&map, DXGI_FORMAT_R32G32B32A32_SINT, GL_INT, NeverSupported); + + AddDXGIFormat(&map, DXGI_FORMAT_R10G10B10A2_TYPELESS, GL_NONE, NeverSupported); + AddDXGIFormat(&map, DXGI_FORMAT_R10G10B10A2_UNORM, GL_UNSIGNED_NORMALIZED, RequiresFeatureLevel); + AddDXGIFormat(&map, DXGI_FORMAT_R10G10B10A2_UINT, GL_UNSIGNED_INT, NeverSupported); + + AddDXGIFormat(&map, DXGI_FORMAT_R16_FLOAT, GL_FLOAT, RequiresFeatureLevel); + AddDXGIFormat(&map, DXGI_FORMAT_R16G16_FLOAT, GL_FLOAT, RequiresFeatureLevel); + AddDXGIFormat(&map, DXGI_FORMAT_R16G16B16A16_FLOAT, GL_FLOAT, RequiresFeatureLevel); + + AddDXGIFormat(&map, DXGI_FORMAT_R32_FLOAT, GL_FLOAT, RequiresFeatureLevel); + AddDXGIFormat(&map, DXGI_FORMAT_R32G32_FLOAT, GL_FLOAT, RequiresFeatureLevel); + AddDXGIFormat(&map, DXGI_FORMAT_R32G32B32_FLOAT, GL_FLOAT, NeverSupported); + AddDXGIFormat(&map, DXGI_FORMAT_R32G32B32A32_FLOAT, GL_FLOAT, RequiresFeatureLevel); + + AddDXGIFormat(&map, DXGI_FORMAT_R9G9B9E5_SHAREDEXP, GL_FLOAT, NeverSupported); + AddDXGIFormat(&map, DXGI_FORMAT_R11G11B10_FLOAT, GL_FLOAT, RequiresFeatureLevel); + + AddDXGIFormat(&map, DXGI_FORMAT_R8_TYPELESS, GL_NONE, NeverSupported); + AddDXGIFormat(&map, DXGI_FORMAT_R16_TYPELESS, GL_NONE, NeverSupported); + AddDXGIFormat(&map, DXGI_FORMAT_R32_TYPELESS, GL_NONE, NeverSupported); + AddDXGIFormat(&map, DXGI_FORMAT_R8G8_TYPELESS, GL_NONE, NeverSupported); + AddDXGIFormat(&map, DXGI_FORMAT_R16G16_TYPELESS, GL_NONE, NeverSupported); + AddDXGIFormat(&map, DXGI_FORMAT_R32G32_TYPELESS, GL_NONE, NeverSupported); + AddDXGIFormat(&map, DXGI_FORMAT_R8G8_TYPELESS, GL_NONE, NeverSupported); + AddDXGIFormat(&map, DXGI_FORMAT_R16G16_TYPELESS, GL_NONE, NeverSupported); + AddDXGIFormat(&map, DXGI_FORMAT_R32G32_TYPELESS, GL_NONE, NeverSupported); + AddDXGIFormat(&map, DXGI_FORMAT_R32G32B32_TYPELESS, GL_NONE, NeverSupported); + AddDXGIFormat(&map, DXGI_FORMAT_R8G8B8A8_TYPELESS, GL_NONE, NeverSupported); + AddDXGIFormat(&map, DXGI_FORMAT_R16G16B16A16_TYPELESS, GL_NONE, NeverSupported); + AddDXGIFormat(&map, DXGI_FORMAT_R32G32B32A32_TYPELESS, GL_NONE, NeverSupported); + + AddDXGIFormat(&map, DXGI_FORMAT_R24G8_TYPELESS, GL_NONE, NeverSupported); + AddDXGIFormat(&map, DXGI_FORMAT_R24_UNORM_X8_TYPELESS, GL_NONE, NeverSupported); + AddDXGIFormat(&map, DXGI_FORMAT_R32G8X24_TYPELESS, GL_NONE, NeverSupported); + AddDXGIFormat(&map, DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS, GL_NONE, NeverSupported); + + AddDXGIFormat(&map, DXGI_FORMAT_D16_UNORM, GL_UNSIGNED_NORMALIZED, NeverSupported); + AddDXGIFormat(&map, DXGI_FORMAT_D24_UNORM_S8_UINT, GL_UNSIGNED_INT, NeverSupported); + AddDXGIFormat(&map, DXGI_FORMAT_D32_FLOAT_S8X24_UINT, GL_UNSIGNED_INT, NeverSupported); + AddDXGIFormat(&map, DXGI_FORMAT_D32_FLOAT, GL_FLOAT, NeverSupported); + + AddDXGIFormat(&map, DXGI_FORMAT_BC1_UNORM, GL_UNSIGNED_NORMALIZED, NeverSupported); + AddDXGIFormat(&map, DXGI_FORMAT_BC2_UNORM, GL_UNSIGNED_NORMALIZED, NeverSupported); + AddDXGIFormat(&map, DXGI_FORMAT_BC3_UNORM, GL_UNSIGNED_NORMALIZED, NeverSupported); + + // B5G6R5 in D3D11 is treated the same as R5G6B5 in D3D9, so reuse the R5G6B5 functions used by the D3D9 renderer. + // The same applies to B4G4R4A4 and B5G5R5A1 with A4R4G4B4 and A1R5G5B5 respectively. + AddDXGIFormat(&map, DXGI_FORMAT_B5G6R5_UNORM, GL_UNSIGNED_NORMALIZED, RequiresFeatureLevel); + AddDXGIFormat(&map, DXGI_FORMAT_B4G4R4A4_UNORM, GL_UNSIGNED_NORMALIZED, NeverSupported); + AddDXGIFormat(&map, DXGI_FORMAT_B5G5R5A1_UNORM, GL_UNSIGNED_NORMALIZED, NeverSupported); + // clang-format on return map; } @@ -450,613 +391,175 @@ const DXGIFormat &GetDXGIFormatInfo(DXGI_FORMAT format) } } -struct SwizzleSizeType -{ - size_t maxComponentSize; - GLenum componentType; - - SwizzleSizeType() - : maxComponentSize(0), componentType(GL_NONE) - { } - - SwizzleSizeType(size_t maxComponentSize, GLenum componentType) - : maxComponentSize(maxComponentSize), componentType(componentType) - { } - - bool operator<(const SwizzleSizeType& other) const - { - return (maxComponentSize != other.maxComponentSize) ? (maxComponentSize < other.maxComponentSize) - : (componentType < other.componentType); - } -}; - -struct SwizzleFormatInfo -{ - DXGI_FORMAT mTexFormat; - DXGI_FORMAT mSRVFormat; - DXGI_FORMAT mRTVFormat; - - SwizzleFormatInfo() - : mTexFormat(DXGI_FORMAT_UNKNOWN), mSRVFormat(DXGI_FORMAT_UNKNOWN), mRTVFormat(DXGI_FORMAT_UNKNOWN) - { } - - SwizzleFormatInfo(DXGI_FORMAT texFormat, DXGI_FORMAT srvFormat, DXGI_FORMAT rtvFormat) - : mTexFormat(texFormat), mSRVFormat(srvFormat), mRTVFormat(rtvFormat) - { } -}; - -typedef std::map SwizzleInfoMap; -typedef std::pair SwizzleInfoPair; - -static SwizzleInfoMap BuildSwizzleInfoMap() -{ - SwizzleInfoMap map; - - map.insert(SwizzleInfoPair(SwizzleSizeType( 8, GL_UNSIGNED_NORMALIZED), SwizzleFormatInfo(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM ))); - map.insert(SwizzleInfoPair(SwizzleSizeType(16, GL_UNSIGNED_NORMALIZED), SwizzleFormatInfo(DXGI_FORMAT_R16G16B16A16_UNORM, DXGI_FORMAT_R16G16B16A16_UNORM, DXGI_FORMAT_R16G16B16A16_UNORM))); - map.insert(SwizzleInfoPair(SwizzleSizeType(24, GL_UNSIGNED_NORMALIZED), SwizzleFormatInfo(DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT))); - map.insert(SwizzleInfoPair(SwizzleSizeType(32, GL_UNSIGNED_NORMALIZED), SwizzleFormatInfo(DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT))); - - map.insert(SwizzleInfoPair(SwizzleSizeType( 8, GL_SIGNED_NORMALIZED ), SwizzleFormatInfo(DXGI_FORMAT_R8G8B8A8_SNORM, DXGI_FORMAT_R8G8B8A8_SNORM, DXGI_FORMAT_R8G8B8A8_SNORM ))); - - map.insert(SwizzleInfoPair(SwizzleSizeType(16, GL_FLOAT ), SwizzleFormatInfo(DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R16G16B16A16_FLOAT))); - map.insert(SwizzleInfoPair(SwizzleSizeType(32, GL_FLOAT ), SwizzleFormatInfo(DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT))); - - map.insert(SwizzleInfoPair(SwizzleSizeType( 8, GL_UNSIGNED_INT ), SwizzleFormatInfo(DXGI_FORMAT_R8G8B8A8_UINT, DXGI_FORMAT_R8G8B8A8_UINT, DXGI_FORMAT_R8G8B8A8_UINT ))); - map.insert(SwizzleInfoPair(SwizzleSizeType(16, GL_UNSIGNED_INT ), SwizzleFormatInfo(DXGI_FORMAT_R16G16B16A16_UINT, DXGI_FORMAT_R16G16B16A16_UINT, DXGI_FORMAT_R16G16B16A16_UINT ))); - map.insert(SwizzleInfoPair(SwizzleSizeType(32, GL_UNSIGNED_INT ), SwizzleFormatInfo(DXGI_FORMAT_R32G32B32A32_UINT, DXGI_FORMAT_R32G32B32A32_UINT, DXGI_FORMAT_R32G32B32A32_UINT ))); - - map.insert(SwizzleInfoPair(SwizzleSizeType( 8, GL_INT ), SwizzleFormatInfo(DXGI_FORMAT_R8G8B8A8_SINT, DXGI_FORMAT_R8G8B8A8_SINT, DXGI_FORMAT_R8G8B8A8_SINT ))); - map.insert(SwizzleInfoPair(SwizzleSizeType(16, GL_INT ), SwizzleFormatInfo(DXGI_FORMAT_R16G16B16A16_SINT, DXGI_FORMAT_R16G16B16A16_SINT, DXGI_FORMAT_R16G16B16A16_SINT ))); - map.insert(SwizzleInfoPair(SwizzleSizeType(32, GL_INT ), SwizzleFormatInfo(DXGI_FORMAT_R32G32B32A32_SINT, DXGI_FORMAT_R32G32B32A32_SINT, DXGI_FORMAT_R32G32B32A32_SINT ))); - - return map; -} - -typedef std::pair InternalFormatInitializerPair; -typedef std::map InternalFormatInitializerMap; - -static InternalFormatInitializerMap BuildInternalFormatInitializerMap() -{ - InternalFormatInitializerMap map; - - map.insert(InternalFormatInitializerPair(GL_RGB8, Initialize4ComponentData )); - map.insert(InternalFormatInitializerPair(GL_RGB565, Initialize4ComponentData )); - map.insert(InternalFormatInitializerPair(GL_SRGB8, Initialize4ComponentData )); - map.insert(InternalFormatInitializerPair(GL_RGB16F, Initialize4ComponentData)); - map.insert(InternalFormatInitializerPair(GL_RGB32F, Initialize4ComponentData)); - map.insert(InternalFormatInitializerPair(GL_RGB8UI, Initialize4ComponentData )); - map.insert(InternalFormatInitializerPair(GL_RGB8I, Initialize4ComponentData )); - map.insert(InternalFormatInitializerPair(GL_RGB16UI, Initialize4ComponentData )); - map.insert(InternalFormatInitializerPair(GL_RGB16I, Initialize4ComponentData )); - map.insert(InternalFormatInitializerPair(GL_RGB32UI, Initialize4ComponentData )); - map.insert(InternalFormatInitializerPair(GL_RGB32I, Initialize4ComponentData )); - - return map; -} - -// ES3 image loading functions vary based on the internal format and data type given, -// this map type determines the loading function from the internal format and type supplied -// to glTex*Image*D and the destination DXGI_FORMAT. Source formats and types are taken from -// Tables 3.2 and 3.3 of the ES 3 spec. -typedef std::pair TypeLoadFunctionPair; -typedef std::map > D3D11LoadFunctionMap; - -static 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(); -} - -static 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(); -} - -// A helper function to insert data into the D3D11LoadFunctionMap with fewer characters. -static inline void InsertLoadFunction(D3D11LoadFunctionMap *map, GLenum internalFormat, GLenum type, - LoadImageFunction loadFunc) -{ - (*map)[internalFormat].push_back(TypeLoadFunctionPair(type, loadFunc)); -} - -D3D11LoadFunctionMap BuildD3D11_FL9_3_LoadFunctionMap() -{ - D3D11LoadFunctionMap map; - - // From GL_EXT_texture_storage. Also used by GL_ALPHA8 - // On feature level 9_3, A8_UNORM doesn't support mipmaps, so we must use RGBA8 instead - InsertLoadFunction(&map, GL_ALPHA8_EXT, GL_UNSIGNED_BYTE, LoadA8ToRGBA8); - - return map; -} - -D3D11LoadFunctionMap BuildD3D11_FL10_0Plus_LoadFunctionMap() -{ - D3D11LoadFunctionMap map; - - // From GL_EXT_texture_storage. Also used by GL_ALPHA8 - InsertLoadFunction(&map, GL_ALPHA8_EXT, GL_UNSIGNED_BYTE, LoadToNative); - - return map; -} - -D3D11LoadFunctionMap BuildBaseD3D11LoadFunctionMap() -{ - D3D11LoadFunctionMap map; - - // | Internal format | Type | Load function | - InsertLoadFunction(&map, GL_RGBA8, GL_UNSIGNED_BYTE, LoadToNative ); - InsertLoadFunction(&map, GL_RGB5_A1, GL_UNSIGNED_BYTE, LoadToNative ); - InsertLoadFunction(&map, GL_RGBA4, GL_UNSIGNED_BYTE, LoadToNative ); - InsertLoadFunction(&map, GL_SRGB8_ALPHA8, GL_UNSIGNED_BYTE, LoadToNative ); - InsertLoadFunction(&map, GL_RGBA8_SNORM, GL_BYTE, LoadToNative ); - InsertLoadFunction(&map, GL_RGBA4, GL_UNSIGNED_SHORT_4_4_4_4, LoadRGBA4ToRGBA8 ); - InsertLoadFunction(&map, GL_RGB10_A2, GL_UNSIGNED_INT_2_10_10_10_REV, LoadToNative ); - InsertLoadFunction(&map, GL_RGB5_A1, GL_UNSIGNED_SHORT_5_5_5_1, LoadRGB5A1ToRGBA8 ); - InsertLoadFunction(&map, GL_RGB5_A1, GL_UNSIGNED_INT_2_10_10_10_REV, LoadRGB10A2ToRGBA8 ); - InsertLoadFunction(&map, GL_RGBA16F, GL_HALF_FLOAT, LoadToNative ); - InsertLoadFunction(&map, GL_RGBA16F, GL_HALF_FLOAT_OES, LoadToNative ); - InsertLoadFunction(&map, GL_RGBA32F, GL_FLOAT, LoadToNative ); - InsertLoadFunction(&map, GL_RGBA16F, GL_FLOAT, Load32FTo16F<4> ); - InsertLoadFunction(&map, GL_RGBA8UI, GL_UNSIGNED_BYTE, LoadToNative ); - InsertLoadFunction(&map, GL_RGBA8I, GL_BYTE, LoadToNative ); - InsertLoadFunction(&map, GL_RGBA16UI, GL_UNSIGNED_SHORT, LoadToNative ); - InsertLoadFunction(&map, GL_RGBA16I, GL_SHORT, LoadToNative ); - InsertLoadFunction(&map, GL_RGBA32UI, GL_UNSIGNED_INT, LoadToNative ); - InsertLoadFunction(&map, GL_RGBA32I, GL_INT, LoadToNative ); - InsertLoadFunction(&map, GL_RGB10_A2UI, GL_UNSIGNED_INT_2_10_10_10_REV, LoadToNative ); - InsertLoadFunction(&map, GL_RGB8, GL_UNSIGNED_BYTE, LoadToNative3To4 ); - InsertLoadFunction(&map, GL_RGB565, GL_UNSIGNED_BYTE, LoadToNative3To4 ); - InsertLoadFunction(&map, GL_SRGB8, GL_UNSIGNED_BYTE, LoadToNative3To4 ); - InsertLoadFunction(&map, GL_RGB8_SNORM, GL_BYTE, LoadToNative3To4 ); - InsertLoadFunction(&map, GL_RGB565, GL_UNSIGNED_SHORT_5_6_5, LoadR5G6B5ToRGBA8 ); - InsertLoadFunction(&map, GL_R11F_G11F_B10F, GL_UNSIGNED_INT_10F_11F_11F_REV, LoadToNative ); - InsertLoadFunction(&map, GL_RGB9_E5, GL_UNSIGNED_INT_5_9_9_9_REV, LoadToNative ); - InsertLoadFunction(&map, GL_RGB16F, GL_HALF_FLOAT, LoadToNative3To4); - InsertLoadFunction(&map, GL_RGB16F, GL_HALF_FLOAT_OES, LoadToNative3To4); - InsertLoadFunction(&map, GL_R11F_G11F_B10F, GL_HALF_FLOAT, LoadRGB16FToRG11B10F ); - InsertLoadFunction(&map, GL_R11F_G11F_B10F, GL_HALF_FLOAT_OES, LoadRGB16FToRG11B10F ); - InsertLoadFunction(&map, GL_RGB9_E5, GL_HALF_FLOAT, LoadRGB16FToRGB9E5 ); - InsertLoadFunction(&map, GL_RGB9_E5, GL_HALF_FLOAT_OES, LoadRGB16FToRGB9E5 ); - InsertLoadFunction(&map, GL_RGB32F, GL_FLOAT, LoadToNative3To4); - InsertLoadFunction(&map, GL_RGB16F, GL_FLOAT, LoadRGB32FToRGBA16F ); - InsertLoadFunction(&map, GL_R11F_G11F_B10F, GL_FLOAT, LoadRGB32FToRG11B10F ); - InsertLoadFunction(&map, GL_RGB9_E5, GL_FLOAT, LoadRGB32FToRGB9E5 ); - InsertLoadFunction(&map, GL_RGB8UI, GL_UNSIGNED_BYTE, LoadToNative3To4 ); - InsertLoadFunction(&map, GL_RGB8I, GL_BYTE, LoadToNative3To4 ); - InsertLoadFunction(&map, GL_RGB16UI, GL_UNSIGNED_SHORT, LoadToNative3To4 ); - InsertLoadFunction(&map, GL_RGB16I, GL_SHORT, LoadToNative3To4 ); - InsertLoadFunction(&map, GL_RGB32UI, GL_UNSIGNED_INT, LoadToNative3To4 ); - InsertLoadFunction(&map, GL_RGB32I, GL_INT, LoadToNative3To4 ); - InsertLoadFunction(&map, GL_RG8, GL_UNSIGNED_BYTE, LoadToNative ); - InsertLoadFunction(&map, GL_RG8_SNORM, GL_BYTE, LoadToNative ); - InsertLoadFunction(&map, GL_RG16F, GL_HALF_FLOAT, LoadToNative ); - InsertLoadFunction(&map, GL_RG16F, GL_HALF_FLOAT_OES, LoadToNative ); - InsertLoadFunction(&map, GL_RG32F, GL_FLOAT, LoadToNative ); - InsertLoadFunction(&map, GL_RG16F, GL_FLOAT, Load32FTo16F<2> ); - InsertLoadFunction(&map, GL_RG8UI, GL_UNSIGNED_BYTE, LoadToNative ); - InsertLoadFunction(&map, GL_RG8I, GL_BYTE, LoadToNative ); - InsertLoadFunction(&map, GL_RG16UI, GL_UNSIGNED_SHORT, LoadToNative ); - InsertLoadFunction(&map, GL_RG16I, GL_SHORT, LoadToNative ); - InsertLoadFunction(&map, GL_RG32UI, GL_UNSIGNED_INT, LoadToNative ); - InsertLoadFunction(&map, GL_RG32I, GL_INT, LoadToNative ); - InsertLoadFunction(&map, GL_R8, GL_UNSIGNED_BYTE, LoadToNative ); - InsertLoadFunction(&map, GL_R8_SNORM, GL_BYTE, LoadToNative ); - InsertLoadFunction(&map, GL_R16F, GL_HALF_FLOAT, LoadToNative ); - InsertLoadFunction(&map, GL_R16F, GL_HALF_FLOAT_OES, LoadToNative ); - InsertLoadFunction(&map, GL_R32F, GL_FLOAT, LoadToNative ); - InsertLoadFunction(&map, GL_R16F, GL_FLOAT, Load32FTo16F<1> ); - InsertLoadFunction(&map, GL_R8UI, GL_UNSIGNED_BYTE, LoadToNative ); - InsertLoadFunction(&map, GL_R8I, GL_BYTE, LoadToNative ); - InsertLoadFunction(&map, GL_R16UI, GL_UNSIGNED_SHORT, LoadToNative ); - InsertLoadFunction(&map, GL_R16I, GL_SHORT, LoadToNative ); - InsertLoadFunction(&map, GL_R32UI, GL_UNSIGNED_INT, LoadToNative ); - InsertLoadFunction(&map, GL_R32I, GL_INT, LoadToNative ); - InsertLoadFunction(&map, GL_DEPTH_COMPONENT16, GL_UNSIGNED_SHORT, LoadToNative ); - InsertLoadFunction(&map, GL_DEPTH_COMPONENT24, GL_UNSIGNED_INT, LoadR32ToR24G8 ); - InsertLoadFunction(&map, GL_DEPTH_COMPONENT16, GL_UNSIGNED_INT, LoadR32ToR16 ); - InsertLoadFunction(&map, GL_DEPTH_COMPONENT32F, GL_FLOAT, LoadToNative ); - InsertLoadFunction(&map, GL_DEPTH24_STENCIL8, GL_UNSIGNED_INT_24_8, LoadR32ToR24G8 ); - InsertLoadFunction(&map, GL_DEPTH32F_STENCIL8, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, LoadToNative ); - - // Unsized formats - // Load functions are unreachable because they are converted to sized internal formats based on - // the format and type before loading takes place. - InsertLoadFunction(&map, GL_RGBA, GL_UNSIGNED_BYTE, UnreachableLoadFunction ); - InsertLoadFunction(&map, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, UnreachableLoadFunction ); - InsertLoadFunction(&map, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, UnreachableLoadFunction ); - InsertLoadFunction(&map, GL_RGB, GL_UNSIGNED_BYTE, UnreachableLoadFunction ); - InsertLoadFunction(&map, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, UnreachableLoadFunction ); - InsertLoadFunction(&map, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, UnreachableLoadFunction ); - InsertLoadFunction(&map, GL_LUMINANCE, GL_UNSIGNED_BYTE, UnreachableLoadFunction ); - InsertLoadFunction(&map, GL_ALPHA, GL_UNSIGNED_BYTE, UnreachableLoadFunction ); - - // From GL_OES_texture_float - InsertLoadFunction(&map, GL_LUMINANCE_ALPHA, GL_FLOAT, LoadLA32FToRGBA32F ); - InsertLoadFunction(&map, GL_LUMINANCE, GL_FLOAT, LoadL32FToRGBA32F ); - InsertLoadFunction(&map, GL_ALPHA, GL_FLOAT, LoadA32FToRGBA32F ); - - // From GL_OES_texture_half_float - InsertLoadFunction(&map, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT, LoadLA16FToRGBA16F ); - InsertLoadFunction(&map, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT_OES, LoadLA16FToRGBA16F ); - InsertLoadFunction(&map, GL_LUMINANCE, GL_HALF_FLOAT, LoadL16FToRGBA16F ); - InsertLoadFunction(&map, GL_LUMINANCE, GL_HALF_FLOAT_OES, LoadL16FToRGBA16F ); - InsertLoadFunction(&map, GL_ALPHA, GL_HALF_FLOAT, LoadA16FToRGBA16F ); - InsertLoadFunction(&map, GL_ALPHA, GL_HALF_FLOAT_OES, LoadA16FToRGBA16F ); - - // From GL_EXT_texture_storage - // GL_ALPHA8_EXT GL_UNSIGNED_BYTE is in the feature-level-specific load function maps, due to differences between 9_3 and 10_0+ - InsertLoadFunction(&map, GL_LUMINANCE8_EXT, GL_UNSIGNED_BYTE, LoadL8ToRGBA8 ); - InsertLoadFunction(&map, GL_LUMINANCE8_ALPHA8_EXT, GL_UNSIGNED_BYTE, LoadLA8ToRGBA8 ); - InsertLoadFunction(&map, GL_ALPHA32F_EXT, GL_FLOAT, LoadA32FToRGBA32F ); - InsertLoadFunction(&map, GL_LUMINANCE32F_EXT, GL_FLOAT, LoadL32FToRGBA32F ); - InsertLoadFunction(&map, GL_LUMINANCE_ALPHA32F_EXT, GL_FLOAT, LoadLA32FToRGBA32F ); - InsertLoadFunction(&map, GL_ALPHA16F_EXT, GL_HALF_FLOAT, LoadA16FToRGBA16F ); - InsertLoadFunction(&map, GL_ALPHA16F_EXT, GL_HALF_FLOAT_OES, LoadA16FToRGBA16F ); - InsertLoadFunction(&map, GL_LUMINANCE16F_EXT, GL_HALF_FLOAT, LoadL16FToRGBA16F ); - InsertLoadFunction(&map, GL_LUMINANCE16F_EXT, GL_HALF_FLOAT_OES, LoadL16FToRGBA16F ); - InsertLoadFunction(&map, GL_LUMINANCE_ALPHA16F_EXT, GL_HALF_FLOAT, LoadLA16FToRGBA16F ); - InsertLoadFunction(&map, GL_LUMINANCE_ALPHA16F_EXT, GL_HALF_FLOAT_OES, LoadLA16FToRGBA16F ); - - // From GL_ANGLE_depth_texture - InsertLoadFunction(&map, GL_DEPTH_COMPONENT32_OES, GL_UNSIGNED_INT, LoadR32ToR24G8 ); - - // From GL_EXT_texture_format_BGRA8888 - InsertLoadFunction(&map, GL_BGRA8_EXT, GL_UNSIGNED_BYTE, LoadToNative ); - InsertLoadFunction(&map, GL_BGRA4_ANGLEX, GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT, LoadRGBA4ToRGBA8 ); - InsertLoadFunction(&map, GL_BGRA4_ANGLEX, GL_UNSIGNED_BYTE, LoadToNative ); - InsertLoadFunction(&map, GL_BGR5_A1_ANGLEX, GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT, LoadRGB5A1ToRGBA8 ); - InsertLoadFunction(&map, GL_BGR5_A1_ANGLEX, GL_UNSIGNED_BYTE, LoadToNative ); - - // Compressed formats - // From ES 3.0.1 spec, table 3.16 - // | Internal format | Type | Load function | - InsertLoadFunction(&map, GL_COMPRESSED_R11_EAC, GL_UNSIGNED_BYTE, UnimplementedLoadFunction ); - InsertLoadFunction(&map, GL_COMPRESSED_R11_EAC, GL_UNSIGNED_BYTE, UnimplementedLoadFunction ); - InsertLoadFunction(&map, GL_COMPRESSED_SIGNED_R11_EAC, GL_UNSIGNED_BYTE, UnimplementedLoadFunction ); - InsertLoadFunction(&map, GL_COMPRESSED_RG11_EAC, GL_UNSIGNED_BYTE, UnimplementedLoadFunction ); - InsertLoadFunction(&map, GL_COMPRESSED_SIGNED_RG11_EAC, GL_UNSIGNED_BYTE, UnimplementedLoadFunction ); - InsertLoadFunction(&map, GL_COMPRESSED_RGB8_ETC2, GL_UNSIGNED_BYTE, UnimplementedLoadFunction ); - InsertLoadFunction(&map, GL_COMPRESSED_SRGB8_ETC2, GL_UNSIGNED_BYTE, UnimplementedLoadFunction ); - InsertLoadFunction(&map, GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2, GL_UNSIGNED_BYTE, UnimplementedLoadFunction ); - InsertLoadFunction(&map, GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, GL_UNSIGNED_BYTE, UnimplementedLoadFunction ); - InsertLoadFunction(&map, GL_COMPRESSED_RGBA8_ETC2_EAC, GL_UNSIGNED_BYTE, UnimplementedLoadFunction ); - InsertLoadFunction(&map, GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC, GL_UNSIGNED_BYTE, UnimplementedLoadFunction ); - - // From GL_EXT_texture_compression_dxt1 - InsertLoadFunction(&map, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, GL_UNSIGNED_BYTE, LoadCompressedToNative<4, 4, 8>); - InsertLoadFunction(&map, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_UNSIGNED_BYTE, LoadCompressedToNative<4, 4, 8>); - - // From GL_ANGLE_texture_compression_dxt3 - InsertLoadFunction(&map, GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, GL_UNSIGNED_BYTE, LoadCompressedToNative<4, 4, 16>); - - // From GL_ANGLE_texture_compression_dxt5 - InsertLoadFunction(&map, GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, GL_UNSIGNED_BYTE, LoadCompressedToNative<4, 4, 16>); - - return map; -} - -// For sized GL internal formats, there is only one corresponding D3D11 format. This map type allows -// querying for the DXGI texture formats to use for textures, SRVs, RTVs and DSVs given a GL internal -// format. -typedef std::map D3D11ES3FormatMap; - -TextureFormat::TextureFormat() - : texFormat(DXGI_FORMAT_UNKNOWN), - srvFormat(DXGI_FORMAT_UNKNOWN), - rtvFormat(DXGI_FORMAT_UNKNOWN), - dsvFormat(DXGI_FORMAT_UNKNOWN), - renderFormat(DXGI_FORMAT_UNKNOWN), - swizzleTexFormat(DXGI_FORMAT_UNKNOWN), - swizzleSRVFormat(DXGI_FORMAT_UNKNOWN), - swizzleRTVFormat(DXGI_FORMAT_UNKNOWN), - dataInitializerFunction(NULL), - loadFunctions() -{ -} - -static inline void InsertD3D11FormatInfoBase(D3D11ES3FormatMap *formatMap, const D3D11LoadFunctionMap &flLoadFunctions, GLenum internalFormat, DXGI_FORMAT texFormat, - DXGI_FORMAT srvFormat, DXGI_FORMAT rtvFormat, DXGI_FORMAT dsvFormat) -{ - TextureFormat info; - info.texFormat = texFormat; - info.srvFormat = srvFormat; - info.rtvFormat = rtvFormat; - info.dsvFormat = dsvFormat; - - // Given a GL internal format, the renderFormat is the DSV format if it is depth- or stencil-renderable, - // the RTV format if it is color-renderable, and the (nonrenderable) texture format otherwise. - if (dsvFormat != DXGI_FORMAT_UNKNOWN) - { - info.renderFormat = dsvFormat; - } - else if (rtvFormat != DXGI_FORMAT_UNKNOWN) - { - info.renderFormat = rtvFormat; - } - else if (texFormat != DXGI_FORMAT_UNKNOWN) - { - info.renderFormat = texFormat; - } - else - { - info.renderFormat = DXGI_FORMAT_UNKNOWN; - } - - // Compute the swizzle formats - const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalFormat); - if (internalFormat != GL_NONE && formatInfo.pixelBytes > 0) - { - if (formatInfo.componentCount != 4 || texFormat == DXGI_FORMAT_UNKNOWN || - srvFormat == DXGI_FORMAT_UNKNOWN || rtvFormat == DXGI_FORMAT_UNKNOWN) - { - // Get the maximum sized component - unsigned int maxBits = 1; - if (formatInfo.compressed) - { - unsigned int compressedBitsPerBlock = formatInfo.pixelBytes * 8; - unsigned int blockSize = formatInfo.compressedBlockWidth * formatInfo.compressedBlockHeight; - maxBits = std::max(compressedBitsPerBlock / blockSize, maxBits); - } - else - { - maxBits = std::max(maxBits, formatInfo.alphaBits); - maxBits = std::max(maxBits, formatInfo.redBits); - maxBits = std::max(maxBits, formatInfo.greenBits); - maxBits = std::max(maxBits, formatInfo.blueBits); - maxBits = std::max(maxBits, formatInfo.luminanceBits); - maxBits = std::max(maxBits, formatInfo.depthBits); - } - - maxBits = roundUp(maxBits, 8U); - - static const SwizzleInfoMap swizzleMap = BuildSwizzleInfoMap(); - SwizzleInfoMap::const_iterator swizzleIter = swizzleMap.find(SwizzleSizeType(maxBits, formatInfo.componentType)); - ASSERT(swizzleIter != swizzleMap.end()); - - const SwizzleFormatInfo &swizzleInfo = swizzleIter->second; - info.swizzleTexFormat = swizzleInfo.mTexFormat; - info.swizzleSRVFormat = swizzleInfo.mSRVFormat; - info.swizzleRTVFormat = swizzleInfo.mRTVFormat; - } - else - { - // The original texture format is suitable for swizzle operations - info.swizzleTexFormat = texFormat; - info.swizzleSRVFormat = srvFormat; - info.swizzleRTVFormat = rtvFormat; - } - } - else - { - // Not possible to swizzle with this texture format since it is either unsized or GL_NONE - info.swizzleTexFormat = DXGI_FORMAT_UNKNOWN; - info.swizzleSRVFormat = DXGI_FORMAT_UNKNOWN; - info.swizzleRTVFormat = DXGI_FORMAT_UNKNOWN; - } - - // Check if there is an initialization function for this texture format - static const InternalFormatInitializerMap initializerMap = BuildInternalFormatInitializerMap(); - InternalFormatInitializerMap::const_iterator initializerIter = initializerMap.find(internalFormat); - info.dataInitializerFunction = (initializerIter != initializerMap.end()) ? initializerIter->second : NULL; - - // Gather all the load functions for this internal format from the base list - static const D3D11LoadFunctionMap loadFunctions = BuildBaseD3D11LoadFunctionMap(); - D3D11LoadFunctionMap::const_iterator loadFunctionIter = loadFunctions.find(internalFormat); - if (loadFunctionIter != loadFunctions.end()) - { - const std::vector &loadFunctionVector = loadFunctionIter->second; - for (size_t i = 0; i < loadFunctionVector.size(); i++) - { - GLenum type = loadFunctionVector[i].first; - LoadImageFunction function = loadFunctionVector[i].second; - info.loadFunctions.insert(std::make_pair(type, function)); - } - } - - // Gather load functions for this internal format from the feature-level-specific list - D3D11LoadFunctionMap::const_iterator flLoadFunctionIter = flLoadFunctions.find(internalFormat); - if (flLoadFunctionIter != flLoadFunctions.end()) - { - const std::vector &flLoadFunctionVector = flLoadFunctionIter->second; - for (size_t i = 0; i < flLoadFunctionVector.size(); i++) - { - GLenum type = flLoadFunctionVector[i].first; - LoadImageFunction function = flLoadFunctionVector[i].second; - info.loadFunctions.insert(std::make_pair(type, function)); - } - } - - formatMap->insert(std::make_pair(internalFormat, info)); -} - -static inline void InsertD3D11_FL9_3_FormatInfo(D3D11ES3FormatMap *map, GLenum internalFormat, DXGI_FORMAT texFormat, - DXGI_FORMAT srvFormat, DXGI_FORMAT rtvFormat, DXGI_FORMAT dsvFormat) -{ - static const D3D11LoadFunctionMap flLoadFunctions = BuildD3D11_FL9_3_LoadFunctionMap(); - InsertD3D11FormatInfoBase(map, flLoadFunctions, internalFormat, texFormat, srvFormat, rtvFormat, dsvFormat); -} - -static inline void InsertD3D11FormatInfo(D3D11ES3FormatMap *map, GLenum internalFormat, DXGI_FORMAT texFormat, - DXGI_FORMAT srvFormat, DXGI_FORMAT rtvFormat, DXGI_FORMAT dsvFormat) -{ - static const D3D11LoadFunctionMap flLoadFunctions = BuildD3D11_FL10_0Plus_LoadFunctionMap(); - InsertD3D11FormatInfoBase(map, flLoadFunctions, internalFormat, texFormat, srvFormat, rtvFormat, dsvFormat); -} - -static D3D11ES3FormatMap BuildD3D11_FL9_3FormatOverrideMap() -{ - // D3D11 Feature Level 9_3 doesn't support as many texture formats as Feature Level 10_0+. - // In particular, it doesn't support: - // - mipmaps on DXGI_FORMAT_A8_NORM - // - *_TYPELESS formats - // - DXGI_FORMAT_D32_FLOAT_S8X24_UINT or DXGI_FORMAT_D32_FLOAT - - D3D11ES3FormatMap map; - - // | GL internal format | D3D11 texture format | D3D11 SRV format | D3D11 RTV format | D3D11 DSV format - InsertD3D11_FL9_3_FormatInfo(&map, GL_ALPHA, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN); - InsertD3D11_FL9_3_FormatInfo(&map, GL_ALPHA8_EXT, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN); - InsertD3D11_FL9_3_FormatInfo(&map, GL_DEPTH_COMPONENT16, DXGI_FORMAT_D16_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_D16_UNORM); - InsertD3D11_FL9_3_FormatInfo(&map, GL_DEPTH_COMPONENT24, DXGI_FORMAT_D24_UNORM_S8_UINT, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_D24_UNORM_S8_UINT); - InsertD3D11_FL9_3_FormatInfo(&map, GL_DEPTH_COMPONENT32F, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN); - InsertD3D11_FL9_3_FormatInfo(&map, GL_DEPTH24_STENCIL8, DXGI_FORMAT_D24_UNORM_S8_UINT, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_D24_UNORM_S8_UINT); - InsertD3D11_FL9_3_FormatInfo(&map, GL_DEPTH32F_STENCIL8, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN); - InsertD3D11_FL9_3_FormatInfo(&map, GL_STENCIL_INDEX8, DXGI_FORMAT_D24_UNORM_S8_UINT, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_D24_UNORM_S8_UINT); - - return map; -} - -static D3D11ES3FormatMap BuildD3D11FormatMap() +DXGIFormatSize::DXGIFormatSize(GLuint pixelBits, GLuint blockWidth, GLuint blockHeight) + : pixelBytes(pixelBits / 8), blockWidth(blockWidth), blockHeight(blockHeight) { - D3D11ES3FormatMap map; - - // | GL internal format | D3D11 texture format | D3D11 SRV format | D3D11 RTV format | D3D11 DSV format | - InsertD3D11FormatInfo(&map, GL_NONE, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN); - InsertD3D11FormatInfo(&map, GL_R8, DXGI_FORMAT_R8_UNORM, DXGI_FORMAT_R8_UNORM, DXGI_FORMAT_R8_UNORM, DXGI_FORMAT_UNKNOWN); - InsertD3D11FormatInfo(&map, GL_R8_SNORM, DXGI_FORMAT_R8_SNORM, DXGI_FORMAT_R8_SNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN); - InsertD3D11FormatInfo(&map, GL_RG8, DXGI_FORMAT_R8G8_UNORM, DXGI_FORMAT_R8G8_UNORM, DXGI_FORMAT_R8G8_UNORM, DXGI_FORMAT_UNKNOWN); - InsertD3D11FormatInfo(&map, GL_RG8_SNORM, DXGI_FORMAT_R8G8_SNORM, DXGI_FORMAT_R8G8_SNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN); - InsertD3D11FormatInfo(&map, GL_RGB8, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN); - InsertD3D11FormatInfo(&map, GL_RGB8_SNORM, DXGI_FORMAT_R8G8B8A8_SNORM, DXGI_FORMAT_R8G8B8A8_SNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN); - InsertD3D11FormatInfo(&map, GL_RGB565, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN); - InsertD3D11FormatInfo(&map, GL_RGBA4, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN); - InsertD3D11FormatInfo(&map, GL_RGB5_A1, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN); - InsertD3D11FormatInfo(&map, GL_RGBA8, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN); - InsertD3D11FormatInfo(&map, GL_RGBA8_SNORM, DXGI_FORMAT_R8G8B8A8_SNORM, DXGI_FORMAT_R8G8B8A8_SNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN); - InsertD3D11FormatInfo(&map, GL_RGB10_A2, DXGI_FORMAT_R10G10B10A2_UNORM, DXGI_FORMAT_R10G10B10A2_UNORM, DXGI_FORMAT_R10G10B10A2_UNORM, DXGI_FORMAT_UNKNOWN); - InsertD3D11FormatInfo(&map, GL_RGB10_A2UI, DXGI_FORMAT_R10G10B10A2_UINT, DXGI_FORMAT_R10G10B10A2_UINT, DXGI_FORMAT_R10G10B10A2_UINT, DXGI_FORMAT_UNKNOWN); - InsertD3D11FormatInfo(&map, GL_SRGB8, DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN); - InsertD3D11FormatInfo(&map, GL_SRGB8_ALPHA8, DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, DXGI_FORMAT_UNKNOWN); - InsertD3D11FormatInfo(&map, GL_R16F, DXGI_FORMAT_R16_FLOAT, DXGI_FORMAT_R16_FLOAT, DXGI_FORMAT_R16_FLOAT, DXGI_FORMAT_UNKNOWN); - InsertD3D11FormatInfo(&map, GL_RG16F, DXGI_FORMAT_R16G16_FLOAT, DXGI_FORMAT_R16G16_FLOAT, DXGI_FORMAT_R16G16_FLOAT, DXGI_FORMAT_UNKNOWN); - InsertD3D11FormatInfo(&map, GL_RGB16F, DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_UNKNOWN); - InsertD3D11FormatInfo(&map, GL_RGBA16F, DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_UNKNOWN); - InsertD3D11FormatInfo(&map, GL_R32F, DXGI_FORMAT_R32_FLOAT, DXGI_FORMAT_R32_FLOAT, DXGI_FORMAT_R32_FLOAT, DXGI_FORMAT_UNKNOWN); - InsertD3D11FormatInfo(&map, GL_RG32F, DXGI_FORMAT_R32G32_FLOAT, DXGI_FORMAT_R32G32_FLOAT, DXGI_FORMAT_R32G32_FLOAT, DXGI_FORMAT_UNKNOWN); - InsertD3D11FormatInfo(&map, GL_RGB32F, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_UNKNOWN); - InsertD3D11FormatInfo(&map, GL_RGBA32F, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_UNKNOWN); - InsertD3D11FormatInfo(&map, GL_R11F_G11F_B10F, DXGI_FORMAT_R11G11B10_FLOAT, DXGI_FORMAT_R11G11B10_FLOAT, DXGI_FORMAT_R11G11B10_FLOAT, DXGI_FORMAT_UNKNOWN); - InsertD3D11FormatInfo(&map, GL_RGB9_E5, DXGI_FORMAT_R9G9B9E5_SHAREDEXP, DXGI_FORMAT_R9G9B9E5_SHAREDEXP, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN); - InsertD3D11FormatInfo(&map, GL_R8I, DXGI_FORMAT_R8_SINT, DXGI_FORMAT_R8_SINT, DXGI_FORMAT_R8_SINT, DXGI_FORMAT_UNKNOWN); - InsertD3D11FormatInfo(&map, GL_R8UI, DXGI_FORMAT_R8_UINT, DXGI_FORMAT_R8_UINT, DXGI_FORMAT_R8_UINT, DXGI_FORMAT_UNKNOWN); - InsertD3D11FormatInfo(&map, GL_R16I, DXGI_FORMAT_R16_SINT, DXGI_FORMAT_R16_SINT, DXGI_FORMAT_R16_SINT, DXGI_FORMAT_UNKNOWN); - InsertD3D11FormatInfo(&map, GL_R16UI, DXGI_FORMAT_R16_UINT, DXGI_FORMAT_R16_UINT, DXGI_FORMAT_R16_UINT, DXGI_FORMAT_UNKNOWN); - InsertD3D11FormatInfo(&map, GL_R32I, DXGI_FORMAT_R32_SINT, DXGI_FORMAT_R32_SINT, DXGI_FORMAT_R32_SINT, DXGI_FORMAT_UNKNOWN); - InsertD3D11FormatInfo(&map, GL_R32UI, DXGI_FORMAT_R32_UINT, DXGI_FORMAT_R32_UINT, DXGI_FORMAT_R32_UINT, DXGI_FORMAT_UNKNOWN); - InsertD3D11FormatInfo(&map, GL_RG8I, DXGI_FORMAT_R8G8_SINT, DXGI_FORMAT_R8G8_SINT, DXGI_FORMAT_R8G8_SINT, DXGI_FORMAT_UNKNOWN); - InsertD3D11FormatInfo(&map, GL_RG8UI, DXGI_FORMAT_R8G8_UINT, DXGI_FORMAT_R8G8_UINT, DXGI_FORMAT_R8G8_UINT, DXGI_FORMAT_UNKNOWN); - InsertD3D11FormatInfo(&map, GL_RG16I, DXGI_FORMAT_R16G16_SINT, DXGI_FORMAT_R16G16_SINT, DXGI_FORMAT_R16G16_SINT, DXGI_FORMAT_UNKNOWN); - InsertD3D11FormatInfo(&map, GL_RG16UI, DXGI_FORMAT_R16G16_UINT, DXGI_FORMAT_R16G16_UINT, DXGI_FORMAT_R16G16_UINT, DXGI_FORMAT_UNKNOWN); - InsertD3D11FormatInfo(&map, GL_RG32I, DXGI_FORMAT_R32G32_SINT, DXGI_FORMAT_R32G32_SINT, DXGI_FORMAT_R32G32_SINT, DXGI_FORMAT_UNKNOWN); - InsertD3D11FormatInfo(&map, GL_RG32UI, DXGI_FORMAT_R32G32_UINT, DXGI_FORMAT_R32G32_UINT, DXGI_FORMAT_R32G32_UINT, DXGI_FORMAT_UNKNOWN); - InsertD3D11FormatInfo(&map, GL_RGB8I, DXGI_FORMAT_R8G8B8A8_SINT, DXGI_FORMAT_R8G8B8A8_SINT, DXGI_FORMAT_R8G8B8A8_SINT, DXGI_FORMAT_UNKNOWN); - InsertD3D11FormatInfo(&map, GL_RGB8UI, DXGI_FORMAT_R8G8B8A8_UINT, DXGI_FORMAT_R8G8B8A8_UINT, DXGI_FORMAT_R8G8B8A8_UINT, DXGI_FORMAT_UNKNOWN); - InsertD3D11FormatInfo(&map, GL_RGB16I, DXGI_FORMAT_R16G16B16A16_SINT, DXGI_FORMAT_R16G16B16A16_SINT, DXGI_FORMAT_R16G16B16A16_SINT, DXGI_FORMAT_UNKNOWN); - InsertD3D11FormatInfo(&map, GL_RGB16UI, DXGI_FORMAT_R16G16B16A16_UINT, DXGI_FORMAT_R16G16B16A16_UINT, DXGI_FORMAT_R16G16B16A16_UINT, DXGI_FORMAT_UNKNOWN); - InsertD3D11FormatInfo(&map, GL_RGB32I, DXGI_FORMAT_R32G32B32A32_SINT, DXGI_FORMAT_R32G32B32A32_SINT, DXGI_FORMAT_R32G32B32A32_SINT, DXGI_FORMAT_UNKNOWN); - InsertD3D11FormatInfo(&map, GL_RGB32UI, DXGI_FORMAT_R32G32B32A32_UINT, DXGI_FORMAT_R32G32B32A32_UINT, DXGI_FORMAT_R32G32B32A32_UINT, DXGI_FORMAT_UNKNOWN); - InsertD3D11FormatInfo(&map, GL_RGBA8I, DXGI_FORMAT_R8G8B8A8_SINT, DXGI_FORMAT_R8G8B8A8_SINT, DXGI_FORMAT_R8G8B8A8_SINT, DXGI_FORMAT_UNKNOWN); - InsertD3D11FormatInfo(&map, GL_RGBA8UI, DXGI_FORMAT_R8G8B8A8_UINT, DXGI_FORMAT_R8G8B8A8_UINT, DXGI_FORMAT_R8G8B8A8_UINT, DXGI_FORMAT_UNKNOWN); - InsertD3D11FormatInfo(&map, GL_RGBA16I, DXGI_FORMAT_R16G16B16A16_SINT, DXGI_FORMAT_R16G16B16A16_SINT, DXGI_FORMAT_R16G16B16A16_SINT, DXGI_FORMAT_UNKNOWN); - InsertD3D11FormatInfo(&map, GL_RGBA16UI, DXGI_FORMAT_R16G16B16A16_UINT, DXGI_FORMAT_R16G16B16A16_UINT, DXGI_FORMAT_R16G16B16A16_UINT, DXGI_FORMAT_UNKNOWN); - InsertD3D11FormatInfo(&map, GL_RGBA32I, DXGI_FORMAT_R32G32B32A32_SINT, DXGI_FORMAT_R32G32B32A32_SINT, DXGI_FORMAT_R32G32B32A32_SINT, DXGI_FORMAT_UNKNOWN); - InsertD3D11FormatInfo(&map, GL_RGBA32UI, DXGI_FORMAT_R32G32B32A32_UINT, DXGI_FORMAT_R32G32B32A32_UINT, DXGI_FORMAT_R32G32B32A32_UINT, DXGI_FORMAT_UNKNOWN); - - // Unsized formats, TODO: Are types of float and half float allowed for the unsized types? Would it change the DXGI format? - InsertD3D11FormatInfo(&map, GL_ALPHA, DXGI_FORMAT_A8_UNORM, DXGI_FORMAT_A8_UNORM, DXGI_FORMAT_A8_UNORM, DXGI_FORMAT_UNKNOWN); - InsertD3D11FormatInfo(&map, GL_LUMINANCE, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN); - InsertD3D11FormatInfo(&map, GL_LUMINANCE_ALPHA, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN); - InsertD3D11FormatInfo(&map, GL_RGB, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN); - InsertD3D11FormatInfo(&map, GL_RGBA, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN); - InsertD3D11FormatInfo(&map, GL_BGRA_EXT, DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_UNKNOWN); - - // From GL_EXT_texture_storage - // | GL internal format | D3D11 texture format | D3D11 SRV format | D3D11 RTV format | D3D11 DSV format | - InsertD3D11FormatInfo(&map, GL_ALPHA8_EXT, DXGI_FORMAT_A8_UNORM, DXGI_FORMAT_A8_UNORM, DXGI_FORMAT_A8_UNORM, DXGI_FORMAT_UNKNOWN ); - InsertD3D11FormatInfo(&map, GL_LUMINANCE8_EXT, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN ); - InsertD3D11FormatInfo(&map, GL_ALPHA32F_EXT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_UNKNOWN ); - InsertD3D11FormatInfo(&map, GL_LUMINANCE32F_EXT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_UNKNOWN ); - InsertD3D11FormatInfo(&map, GL_ALPHA16F_EXT, DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_UNKNOWN ); - InsertD3D11FormatInfo(&map, GL_LUMINANCE16F_EXT, DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_UNKNOWN ); - InsertD3D11FormatInfo(&map, GL_LUMINANCE8_ALPHA8_EXT, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN ); - InsertD3D11FormatInfo(&map, GL_LUMINANCE_ALPHA32F_EXT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_UNKNOWN ); - InsertD3D11FormatInfo(&map, GL_LUMINANCE_ALPHA16F_EXT, DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_UNKNOWN ); - InsertD3D11FormatInfo(&map, GL_BGRA8_EXT, DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_UNKNOWN ); - InsertD3D11FormatInfo(&map, GL_BGRA4_ANGLEX, DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_UNKNOWN ); - InsertD3D11FormatInfo(&map, GL_BGR5_A1_ANGLEX, DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_UNKNOWN ); - - // Depth stencil formats - InsertD3D11FormatInfo(&map, GL_DEPTH_COMPONENT16, DXGI_FORMAT_R16_TYPELESS, DXGI_FORMAT_R16_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_D16_UNORM ); - InsertD3D11FormatInfo(&map, GL_DEPTH_COMPONENT24, DXGI_FORMAT_R24G8_TYPELESS, DXGI_FORMAT_R24_UNORM_X8_TYPELESS, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_D24_UNORM_S8_UINT ); - InsertD3D11FormatInfo(&map, GL_DEPTH_COMPONENT32F, DXGI_FORMAT_R32_TYPELESS, DXGI_FORMAT_R32_FLOAT, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_D32_FLOAT ); - InsertD3D11FormatInfo(&map, GL_DEPTH24_STENCIL8, DXGI_FORMAT_R24G8_TYPELESS, DXGI_FORMAT_R24_UNORM_X8_TYPELESS, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_D24_UNORM_S8_UINT ); - InsertD3D11FormatInfo(&map, GL_DEPTH32F_STENCIL8, DXGI_FORMAT_R32G8X24_TYPELESS, DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_D32_FLOAT_S8X24_UINT); - InsertD3D11FormatInfo(&map, GL_STENCIL_INDEX8, DXGI_FORMAT_R24G8_TYPELESS, DXGI_FORMAT_X24_TYPELESS_G8_UINT, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_D24_UNORM_S8_UINT ); - - // From GL_ANGLE_depth_texture - // Since D3D11 doesn't have a D32_UNORM format, use D24S8 which has comparable precision and matches the ES3 format. - InsertD3D11FormatInfo(&map, GL_DEPTH_COMPONENT32_OES, DXGI_FORMAT_R24G8_TYPELESS, DXGI_FORMAT_R24_UNORM_X8_TYPELESS, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_D24_UNORM_S8_UINT); - - // Compressed formats, From ES 3.0.1 spec, table 3.16 - // | GL internal format | D3D11 texture format | D3D11 SRV format | D3D11 RTV format | D3D11 DSV format | - InsertD3D11FormatInfo(&map, GL_COMPRESSED_R11_EAC, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN); - InsertD3D11FormatInfo(&map, GL_COMPRESSED_SIGNED_R11_EAC, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN); - InsertD3D11FormatInfo(&map, GL_COMPRESSED_RG11_EAC, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN); - InsertD3D11FormatInfo(&map, GL_COMPRESSED_SIGNED_RG11_EAC, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN); - InsertD3D11FormatInfo(&map, GL_COMPRESSED_RGB8_ETC2, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN); - InsertD3D11FormatInfo(&map, GL_COMPRESSED_SRGB8_ETC2, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN); - InsertD3D11FormatInfo(&map, GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN); - InsertD3D11FormatInfo(&map, GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN); - InsertD3D11FormatInfo(&map, GL_COMPRESSED_RGBA8_ETC2_EAC, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN); - InsertD3D11FormatInfo(&map, GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN); - - // From GL_EXT_texture_compression_dxt1 - InsertD3D11FormatInfo(&map, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, DXGI_FORMAT_BC1_UNORM, DXGI_FORMAT_BC1_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN); - InsertD3D11FormatInfo(&map, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, DXGI_FORMAT_BC1_UNORM, DXGI_FORMAT_BC1_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN); - - // From GL_ANGLE_texture_compression_dxt3 - InsertD3D11FormatInfo(&map, GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, DXGI_FORMAT_BC2_UNORM, DXGI_FORMAT_BC2_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN); - - // From GL_ANGLE_texture_compression_dxt5 - InsertD3D11FormatInfo(&map, GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, DXGI_FORMAT_BC3_UNORM, DXGI_FORMAT_BC3_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN); - - return map; } -const TextureFormat &GetTextureFormatInfo(GLenum internalFormat, D3D_FEATURE_LEVEL featureLevel) +const DXGIFormatSize &GetDXGIFormatSizeInfo(DXGI_FORMAT format) { - static const D3D11ES3FormatMap formatMap = BuildD3D11FormatMap(); - static const D3D11ES3FormatMap formatMapFL9_3Override = BuildD3D11_FL9_3FormatOverrideMap(); - - if (featureLevel == D3D_FEATURE_LEVEL_9_3) - { - // First see if the internalFormat has a special map for FL9_3 - D3D11ES3FormatMap::const_iterator fl9_3Iter = formatMapFL9_3Override.find(internalFormat); - if (fl9_3Iter != formatMapFL9_3Override.end()) - { - return fl9_3Iter->second; - } - } - - D3D11ES3FormatMap::const_iterator iter = formatMap.find(internalFormat); - if (iter != formatMap.end()) + 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) { - return iter->second; - } - else - { - static const TextureFormat defaultInfo; - return defaultInfo; + 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; } } -typedef std::map D3D11VertexFormatInfoMap; -typedef std::pair D3D11VertexFormatPair; +typedef std::map D3D11VertexFormatInfoMap; +typedef std::pair D3D11VertexFormatPair; VertexFormat::VertexFormat() : conversionType(VERTEX_CONVERT_NONE), @@ -1065,30 +568,31 @@ VertexFormat::VertexFormat() { } -static void AddVertexFormatInfo(D3D11VertexFormatInfoMap *map, GLenum inputType, GLboolean normalized, GLuint componentCount, - VertexConversionType conversionType, DXGI_FORMAT nativeFormat, VertexCopyFunction copyFunction) +VertexFormat::VertexFormat(VertexConversionType conversionTypeIn, + DXGI_FORMAT nativeFormatIn, + VertexCopyFunction copyFunctionIn) + : conversionType(conversionTypeIn), + nativeFormat(nativeFormatIn), + copyFunction(copyFunctionIn) { - gl::VertexFormat inputFormat(inputType, normalized, componentCount, false); - - VertexFormat info; - info.conversionType = conversionType; - info.nativeFormat = nativeFormat; - info.copyFunction = copyFunction; - - map->insert(D3D11VertexFormatPair(inputFormat, info)); } -static void AddIntegerVertexFormatInfo(D3D11VertexFormatInfoMap *map, GLenum inputType, GLuint componentCount, - VertexConversionType conversionType, DXGI_FORMAT nativeFormat, VertexCopyFunction copyFunction) +static void AddVertexFormatInfo(D3D11VertexFormatInfoMap *map, + GLenum inputType, + GLboolean normalized, + GLuint componentCount, + VertexConversionType conversionType, + DXGI_FORMAT nativeFormat, + VertexCopyFunction copyFunction) { - gl::VertexFormat inputFormat(inputType, GL_FALSE, componentCount, true); + gl::VertexFormatType formatType = gl::GetVertexFormatType(inputType, normalized, componentCount, false); VertexFormat info; info.conversionType = conversionType; info.nativeFormat = nativeFormat; info.copyFunction = copyFunction; - map->insert(D3D11VertexFormatPair(inputFormat, info)); + map->insert(D3D11VertexFormatPair(formatType, info)); } static D3D11VertexFormatInfoMap BuildD3D11_FL9_3VertexFormatInfoOverrideMap() @@ -1153,187 +657,539 @@ static D3D11VertexFormatInfoMap BuildD3D11_FL9_3VertexFormatInfoOverrideMap() return map; } -static D3D11VertexFormatInfoMap BuildD3D11VertexFormatInfoMap() +const VertexFormat &GetVertexFormatInfo(gl::VertexFormatType vertexFormatType, D3D_FEATURE_LEVEL featureLevel) { - D3D11VertexFormatInfoMap map; + if (featureLevel == D3D_FEATURE_LEVEL_9_3) + { + static const D3D11VertexFormatInfoMap vertexFormatMapFL9_3Override = + BuildD3D11_FL9_3VertexFormatInfoOverrideMap(); - // TODO: column legend + // First see if the format has a special mapping for FL9_3 + auto iter = vertexFormatMapFL9_3Override.find(vertexFormatType); + if (iter != vertexFormatMapFL9_3Override.end()) + { + return iter->second; + } + } - // - // Float formats - // + switch (vertexFormatType) + { + // + // Float formats + // - // GL_BYTE -- un-normalized - AddVertexFormatInfo(&map, GL_BYTE, GL_FALSE, 1, VERTEX_CONVERT_GPU, DXGI_FORMAT_R8_SINT, &CopyNativeVertexData); - AddVertexFormatInfo(&map, GL_BYTE, GL_FALSE, 2, VERTEX_CONVERT_GPU, DXGI_FORMAT_R8G8_SINT, &CopyNativeVertexData); - AddVertexFormatInfo(&map, GL_BYTE, GL_FALSE, 3, VERTEX_CONVERT_BOTH, DXGI_FORMAT_R8G8B8A8_SINT, &CopyNativeVertexData); - AddVertexFormatInfo(&map, GL_BYTE, GL_FALSE, 4, VERTEX_CONVERT_GPU, DXGI_FORMAT_R8G8B8A8_SINT, &CopyNativeVertexData); + // GL_BYTE -- un-normalized + case gl::VERTEX_FORMAT_SBYTE1: + { + static const VertexFormat info(VERTEX_CONVERT_GPU, DXGI_FORMAT_R8_SINT, &CopyNativeVertexData); + return info; + } + case gl::VERTEX_FORMAT_SBYTE2: + { + static const VertexFormat info(VERTEX_CONVERT_GPU, DXGI_FORMAT_R8G8_SINT, &CopyNativeVertexData); + return info; + } + case gl::VERTEX_FORMAT_SBYTE3: + { + static const VertexFormat info(VERTEX_CONVERT_BOTH, DXGI_FORMAT_R8G8B8A8_SINT, &CopyNativeVertexData); + return info; + } + case gl::VERTEX_FORMAT_SBYTE4: + { + static const VertexFormat info(VERTEX_CONVERT_GPU, DXGI_FORMAT_R8G8B8A8_SINT, &CopyNativeVertexData); + return info; + } - // GL_BYTE -- normalized - AddVertexFormatInfo(&map, GL_BYTE, GL_TRUE, 1, VERTEX_CONVERT_NONE, DXGI_FORMAT_R8_SNORM, &CopyNativeVertexData); - AddVertexFormatInfo(&map, GL_BYTE, GL_TRUE, 2, VERTEX_CONVERT_NONE, DXGI_FORMAT_R8G8_SNORM, &CopyNativeVertexData); - AddVertexFormatInfo(&map, GL_BYTE, GL_TRUE, 3, VERTEX_CONVERT_CPU, DXGI_FORMAT_R8G8B8A8_SNORM, &CopyNativeVertexData); - AddVertexFormatInfo(&map, GL_BYTE, GL_TRUE, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R8G8B8A8_SNORM, &CopyNativeVertexData); + // GL_BYTE -- normalized + case gl::VERTEX_FORMAT_SBYTE1_NORM: + { + static const VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R8_SNORM, &CopyNativeVertexData); + return info; + } + case gl::VERTEX_FORMAT_SBYTE2_NORM: + { + static const VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R8G8_SNORM, &CopyNativeVertexData); + return info; + } + case gl::VERTEX_FORMAT_SBYTE3_NORM: + { + static const VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R8G8B8A8_SNORM, &CopyNativeVertexData); + return info; + } + case gl::VERTEX_FORMAT_SBYTE4_NORM: + { + static const VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R8G8B8A8_SNORM, &CopyNativeVertexData); + return info; + } - // GL_UNSIGNED_BYTE -- un-normalized - AddVertexFormatInfo(&map, GL_UNSIGNED_BYTE, GL_FALSE, 1, VERTEX_CONVERT_GPU, DXGI_FORMAT_R8_UINT, &CopyNativeVertexData); - AddVertexFormatInfo(&map, GL_UNSIGNED_BYTE, GL_FALSE, 2, VERTEX_CONVERT_GPU, DXGI_FORMAT_R8G8_UINT, &CopyNativeVertexData); - AddVertexFormatInfo(&map, GL_UNSIGNED_BYTE, GL_FALSE, 3, VERTEX_CONVERT_BOTH, DXGI_FORMAT_R8G8B8A8_UINT, &CopyNativeVertexData); - AddVertexFormatInfo(&map, GL_UNSIGNED_BYTE, GL_FALSE, 4, VERTEX_CONVERT_GPU, DXGI_FORMAT_R8G8B8A8_UINT, &CopyNativeVertexData); + // GL_UNSIGNED_BYTE -- un-normalized + case gl::VERTEX_FORMAT_UBYTE1: + { + static const VertexFormat info(VERTEX_CONVERT_GPU, DXGI_FORMAT_R8_UINT, &CopyNativeVertexData); + return info; + } + case gl::VERTEX_FORMAT_UBYTE2: + { + static const VertexFormat info(VERTEX_CONVERT_GPU, DXGI_FORMAT_R8G8_UINT, &CopyNativeVertexData); + return info; + } + case gl::VERTEX_FORMAT_UBYTE3: + { + static const VertexFormat info(VERTEX_CONVERT_BOTH, DXGI_FORMAT_R8G8B8A8_UINT, &CopyNativeVertexData); + return info; + } + case gl::VERTEX_FORMAT_UBYTE4: + { + static const VertexFormat info(VERTEX_CONVERT_GPU, DXGI_FORMAT_R8G8B8A8_UINT, &CopyNativeVertexData); + return info; + } - // GL_UNSIGNED_BYTE -- normalized - AddVertexFormatInfo(&map, GL_UNSIGNED_BYTE, GL_TRUE, 1, VERTEX_CONVERT_NONE, DXGI_FORMAT_R8_UNORM, &CopyNativeVertexData); - AddVertexFormatInfo(&map, GL_UNSIGNED_BYTE, GL_TRUE, 2, VERTEX_CONVERT_NONE, DXGI_FORMAT_R8G8_UNORM, &CopyNativeVertexData); - AddVertexFormatInfo(&map, GL_UNSIGNED_BYTE, GL_TRUE, 3, VERTEX_CONVERT_CPU, DXGI_FORMAT_R8G8B8A8_UNORM, &CopyNativeVertexData); - AddVertexFormatInfo(&map, GL_UNSIGNED_BYTE, GL_TRUE, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R8G8B8A8_UNORM, &CopyNativeVertexData); + // GL_UNSIGNED_BYTE -- normalized + case gl::VERTEX_FORMAT_UBYTE1_NORM: + { + static const VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R8_UNORM, &CopyNativeVertexData); + return info; + } + case gl::VERTEX_FORMAT_UBYTE2_NORM: + { + static const VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R8G8_UNORM, &CopyNativeVertexData); + return info; + } + case gl::VERTEX_FORMAT_UBYTE3_NORM: + { + static const VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R8G8B8A8_UNORM, &CopyNativeVertexData); + return info; + } + case gl::VERTEX_FORMAT_UBYTE4_NORM: + { + static const VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R8G8B8A8_UNORM, &CopyNativeVertexData); + return info; + } - // GL_SHORT -- un-normalized - AddVertexFormatInfo(&map, GL_SHORT, GL_FALSE, 1, VERTEX_CONVERT_GPU, DXGI_FORMAT_R16_SINT, &CopyNativeVertexData); - AddVertexFormatInfo(&map, GL_SHORT, GL_FALSE, 2, VERTEX_CONVERT_GPU, DXGI_FORMAT_R16G16_SINT, &CopyNativeVertexData); - AddVertexFormatInfo(&map, GL_SHORT, GL_FALSE, 3, VERTEX_CONVERT_BOTH, DXGI_FORMAT_R16G16B16A16_SINT, &CopyNativeVertexData); - AddVertexFormatInfo(&map, GL_SHORT, GL_FALSE, 4, VERTEX_CONVERT_GPU, DXGI_FORMAT_R16G16B16A16_SINT, &CopyNativeVertexData); + // GL_SHORT -- un-normalized + case gl::VERTEX_FORMAT_SSHORT1: + { + static const VertexFormat info(VERTEX_CONVERT_GPU, DXGI_FORMAT_R16_SINT, &CopyNativeVertexData); + return info; + } + case gl::VERTEX_FORMAT_SSHORT2: + { + static const VertexFormat info(VERTEX_CONVERT_GPU, DXGI_FORMAT_R16G16_SINT, &CopyNativeVertexData); + return info; + } + case gl::VERTEX_FORMAT_SSHORT3: + { + static const VertexFormat info(VERTEX_CONVERT_BOTH, DXGI_FORMAT_R16G16B16A16_SINT, &CopyNativeVertexData); + return info; + } + case gl::VERTEX_FORMAT_SSHORT4: + { + static const VertexFormat info(VERTEX_CONVERT_GPU, DXGI_FORMAT_R16G16B16A16_SINT, &CopyNativeVertexData); + return info; + } - // GL_SHORT -- normalized - AddVertexFormatInfo(&map, GL_SHORT, GL_TRUE, 1, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16_SNORM, &CopyNativeVertexData); - AddVertexFormatInfo(&map, GL_SHORT, GL_TRUE, 2, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16_SNORM, &CopyNativeVertexData); - AddVertexFormatInfo(&map, GL_SHORT, GL_TRUE, 3, VERTEX_CONVERT_CPU, DXGI_FORMAT_R16G16B16A16_SNORM, &CopyNativeVertexData); - AddVertexFormatInfo(&map, GL_SHORT, GL_TRUE, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16B16A16_SNORM, &CopyNativeVertexData); + // GL_SHORT -- normalized + case gl::VERTEX_FORMAT_SSHORT1_NORM: + { + static const VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R16_SNORM, &CopyNativeVertexData); + return info; + } + case gl::VERTEX_FORMAT_SSHORT2_NORM: + { + static const VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16_SNORM, &CopyNativeVertexData); + return info; + } + case gl::VERTEX_FORMAT_SSHORT3_NORM: + { + static const VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R16G16B16A16_SNORM, &CopyNativeVertexData); + return info; + } + case gl::VERTEX_FORMAT_SSHORT4_NORM: + { + static const VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16B16A16_SNORM, &CopyNativeVertexData); + return info; + } - // GL_UNSIGNED_SHORT -- un-normalized - AddVertexFormatInfo(&map, GL_UNSIGNED_SHORT, GL_FALSE, 1, VERTEX_CONVERT_GPU, DXGI_FORMAT_R16_UINT, &CopyNativeVertexData); - AddVertexFormatInfo(&map, GL_UNSIGNED_SHORT, GL_FALSE, 2, VERTEX_CONVERT_GPU, DXGI_FORMAT_R16G16_UINT, &CopyNativeVertexData); - AddVertexFormatInfo(&map, GL_UNSIGNED_SHORT, GL_FALSE, 3, VERTEX_CONVERT_BOTH, DXGI_FORMAT_R16G16B16A16_UINT, &CopyNativeVertexData); - AddVertexFormatInfo(&map, GL_UNSIGNED_SHORT, GL_FALSE, 4, VERTEX_CONVERT_GPU, DXGI_FORMAT_R16G16B16A16_UINT, &CopyNativeVertexData); + // GL_UNSIGNED_SHORT -- un-normalized + case gl::VERTEX_FORMAT_USHORT1: + { + static const VertexFormat info(VERTEX_CONVERT_GPU, DXGI_FORMAT_R16_UINT, &CopyNativeVertexData); + return info; + } + case gl::VERTEX_FORMAT_USHORT2: + { + static const VertexFormat info(VERTEX_CONVERT_GPU, DXGI_FORMAT_R16G16_UINT, &CopyNativeVertexData); + return info; + } + case gl::VERTEX_FORMAT_USHORT3: + { + static const VertexFormat info(VERTEX_CONVERT_BOTH, DXGI_FORMAT_R16G16B16A16_UINT, &CopyNativeVertexData); + return info; + } + case gl::VERTEX_FORMAT_USHORT4: + { + static const VertexFormat info(VERTEX_CONVERT_GPU, DXGI_FORMAT_R16G16B16A16_UINT, &CopyNativeVertexData); + return info; + } - // GL_UNSIGNED_SHORT -- normalized - AddVertexFormatInfo(&map, GL_UNSIGNED_SHORT, GL_TRUE, 1, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16_UNORM, &CopyNativeVertexData); - AddVertexFormatInfo(&map, GL_UNSIGNED_SHORT, GL_TRUE, 2, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16_UNORM, &CopyNativeVertexData); - AddVertexFormatInfo(&map, GL_UNSIGNED_SHORT, GL_TRUE, 3, VERTEX_CONVERT_CPU, DXGI_FORMAT_R16G16B16A16_UNORM, &CopyNativeVertexData); - AddVertexFormatInfo(&map, GL_UNSIGNED_SHORT, GL_TRUE, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16B16A16_UNORM, &CopyNativeVertexData); - - // GL_INT -- un-normalized - AddVertexFormatInfo(&map, GL_INT, GL_FALSE, 1, VERTEX_CONVERT_GPU, DXGI_FORMAT_R32_SINT, &CopyNativeVertexData); - AddVertexFormatInfo(&map, GL_INT, GL_FALSE, 2, VERTEX_CONVERT_GPU, DXGI_FORMAT_R32G32_SINT, &CopyNativeVertexData); - AddVertexFormatInfo(&map, GL_INT, GL_FALSE, 3, VERTEX_CONVERT_GPU, DXGI_FORMAT_R32G32B32_SINT, &CopyNativeVertexData); - AddVertexFormatInfo(&map, GL_INT, GL_FALSE, 4, VERTEX_CONVERT_GPU, DXGI_FORMAT_R32G32B32A32_SINT, &CopyNativeVertexData); - - // GL_INT -- normalized - AddVertexFormatInfo(&map, GL_INT, GL_TRUE, 1, VERTEX_CONVERT_CPU, DXGI_FORMAT_R32_FLOAT, &CopyTo32FVertexData); - AddVertexFormatInfo(&map, GL_INT, GL_TRUE, 2, VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32_FLOAT, &CopyTo32FVertexData); - AddVertexFormatInfo(&map, GL_INT, GL_TRUE, 3, VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32B32_FLOAT, &CopyTo32FVertexData); - AddVertexFormatInfo(&map, GL_INT, GL_TRUE, 4, VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32B32A32_FLOAT, &CopyTo32FVertexData); - - // GL_UNSIGNED_INT -- un-normalized - AddVertexFormatInfo(&map, GL_UNSIGNED_INT, GL_FALSE, 1, VERTEX_CONVERT_GPU, DXGI_FORMAT_R32_UINT, &CopyNativeVertexData); - AddVertexFormatInfo(&map, GL_UNSIGNED_INT, GL_FALSE, 2, VERTEX_CONVERT_GPU, DXGI_FORMAT_R32G32_UINT, &CopyNativeVertexData); - AddVertexFormatInfo(&map, GL_UNSIGNED_INT, GL_FALSE, 3, VERTEX_CONVERT_GPU, DXGI_FORMAT_R32G32B32_UINT, &CopyNativeVertexData); - AddVertexFormatInfo(&map, GL_UNSIGNED_INT, GL_FALSE, 4, VERTEX_CONVERT_GPU, DXGI_FORMAT_R32G32B32A32_UINT, &CopyNativeVertexData); - - // GL_UNSIGNED_INT -- normalized - AddVertexFormatInfo(&map, GL_UNSIGNED_INT, GL_TRUE, 1, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32_FLOAT, &CopyTo32FVertexData); - AddVertexFormatInfo(&map, GL_UNSIGNED_INT, GL_TRUE, 2, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32_FLOAT, &CopyTo32FVertexData); - AddVertexFormatInfo(&map, GL_UNSIGNED_INT, GL_TRUE, 3, VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32B32_FLOAT, &CopyTo32FVertexData); - AddVertexFormatInfo(&map, GL_UNSIGNED_INT, GL_TRUE, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32B32A32_FLOAT, &CopyTo32FVertexData); + // GL_UNSIGNED_SHORT -- normalized + case gl::VERTEX_FORMAT_USHORT1_NORM: + { + static const VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R16_UNORM, &CopyNativeVertexData); + return info; + } + case gl::VERTEX_FORMAT_USHORT2_NORM: + { + static const VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16_UNORM, &CopyNativeVertexData); + return info; + } + case gl::VERTEX_FORMAT_USHORT3_NORM: + { + static const VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R16G16B16A16_UNORM, &CopyNativeVertexData); + return info; + } + case gl::VERTEX_FORMAT_USHORT4_NORM: + { + static const VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16B16A16_UNORM, &CopyNativeVertexData); + return info; + } - // GL_FIXED - AddVertexFormatInfo(&map, GL_FIXED, GL_FALSE, 1, VERTEX_CONVERT_CPU, DXGI_FORMAT_R32_FLOAT, &Copy32FixedTo32FVertexData<1, 1>); - AddVertexFormatInfo(&map, GL_FIXED, GL_FALSE, 2, VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32_FLOAT, &Copy32FixedTo32FVertexData<2, 2>); - AddVertexFormatInfo(&map, GL_FIXED, GL_FALSE, 3, VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32B32_FLOAT, &Copy32FixedTo32FVertexData<3, 3>); - AddVertexFormatInfo(&map, GL_FIXED, GL_FALSE, 4, VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32B32A32_FLOAT, &Copy32FixedTo32FVertexData<4, 4>); + // GL_INT -- un-normalized + case gl::VERTEX_FORMAT_SINT1: + { + static const VertexFormat info(VERTEX_CONVERT_GPU, DXGI_FORMAT_R32_SINT, &CopyNativeVertexData); + return info; + } + case gl::VERTEX_FORMAT_SINT2: + { + static const VertexFormat info(VERTEX_CONVERT_GPU, DXGI_FORMAT_R32G32_SINT, &CopyNativeVertexData); + return info; + } + case gl::VERTEX_FORMAT_SINT3: + { + static const VertexFormat info(VERTEX_CONVERT_GPU, DXGI_FORMAT_R32G32B32_SINT, &CopyNativeVertexData); + return info; + } + case gl::VERTEX_FORMAT_SINT4: + { + static const VertexFormat info(VERTEX_CONVERT_GPU, DXGI_FORMAT_R32G32B32A32_SINT, &CopyNativeVertexData); + return info; + } - // GL_HALF_FLOAT - AddVertexFormatInfo(&map, GL_HALF_FLOAT, GL_FALSE, 1, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16_FLOAT, &CopyNativeVertexData); - AddVertexFormatInfo(&map, GL_HALF_FLOAT, GL_FALSE, 2, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16_FLOAT, &CopyNativeVertexData); - AddVertexFormatInfo(&map, GL_HALF_FLOAT, GL_FALSE, 3, VERTEX_CONVERT_CPU, DXGI_FORMAT_R16G16B16A16_FLOAT, &CopyNativeVertexData); - AddVertexFormatInfo(&map, GL_HALF_FLOAT, GL_FALSE, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16B16A16_FLOAT, &CopyNativeVertexData); + // GL_INT -- normalized + case gl::VERTEX_FORMAT_SINT1_NORM: + { + static const VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R32_FLOAT, &CopyTo32FVertexData); + return info; + } + case gl::VERTEX_FORMAT_SINT2_NORM: + { + static const VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32_FLOAT, &CopyTo32FVertexData); + return info; + } + case gl::VERTEX_FORMAT_SINT3_NORM: + { + static const VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32B32_FLOAT, &CopyTo32FVertexData); + return info; + } + case gl::VERTEX_FORMAT_SINT4_NORM: + { + static const VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32B32A32_FLOAT, &CopyTo32FVertexData); + return info; + } - // GL_FLOAT - AddVertexFormatInfo(&map, GL_FLOAT, GL_FALSE, 1, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32_FLOAT, &CopyNativeVertexData); - AddVertexFormatInfo(&map, GL_FLOAT, GL_FALSE, 2, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32_FLOAT, &CopyNativeVertexData); - AddVertexFormatInfo(&map, GL_FLOAT, GL_FALSE, 3, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32B32_FLOAT, &CopyNativeVertexData); - AddVertexFormatInfo(&map, GL_FLOAT, GL_FALSE, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32B32A32_FLOAT, &CopyNativeVertexData); - - // GL_INT_2_10_10_10_REV - AddVertexFormatInfo(&map, GL_INT_2_10_10_10_REV, GL_FALSE, 4, VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32B32A32_FLOAT, &CopyXYZ10W2ToXYZW32FVertexData); - AddVertexFormatInfo(&map, GL_INT_2_10_10_10_REV, GL_TRUE, 4, VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32B32A32_FLOAT, &CopyXYZ10W2ToXYZW32FVertexData); - - // GL_UNSIGNED_INT_2_10_10_10_REV - AddVertexFormatInfo(&map, GL_UNSIGNED_INT_2_10_10_10_REV, GL_FALSE, 4, VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32B32A32_FLOAT, &CopyXYZ10W2ToXYZW32FVertexData); - AddVertexFormatInfo(&map, GL_UNSIGNED_INT_2_10_10_10_REV, GL_TRUE, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R10G10B10A2_UNORM, &CopyNativeVertexData); - - // - // Integer Formats - // - - // GL_BYTE - AddIntegerVertexFormatInfo(&map, GL_BYTE, 1, VERTEX_CONVERT_NONE, DXGI_FORMAT_R8_SINT, &CopyNativeVertexData); - AddIntegerVertexFormatInfo(&map, GL_BYTE, 2, VERTEX_CONVERT_NONE, DXGI_FORMAT_R8G8_SINT, &CopyNativeVertexData); - AddIntegerVertexFormatInfo(&map, GL_BYTE, 3, VERTEX_CONVERT_CPU, DXGI_FORMAT_R8G8B8A8_SINT, &CopyNativeVertexData); - AddIntegerVertexFormatInfo(&map, GL_BYTE, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R8G8B8A8_SINT, &CopyNativeVertexData); - - // GL_UNSIGNED_BYTE - AddIntegerVertexFormatInfo(&map, GL_UNSIGNED_BYTE, 1, VERTEX_CONVERT_NONE, DXGI_FORMAT_R8_UINT, &CopyNativeVertexData); - AddIntegerVertexFormatInfo(&map, GL_UNSIGNED_BYTE, 2, VERTEX_CONVERT_NONE, DXGI_FORMAT_R8G8_UINT, &CopyNativeVertexData); - AddIntegerVertexFormatInfo(&map, GL_UNSIGNED_BYTE, 3, VERTEX_CONVERT_CPU, DXGI_FORMAT_R8G8B8A8_UINT, &CopyNativeVertexData); - AddIntegerVertexFormatInfo(&map, GL_UNSIGNED_BYTE, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R8G8B8A8_UINT, &CopyNativeVertexData); - - // GL_SHORT - AddIntegerVertexFormatInfo(&map, GL_SHORT, 1, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16_SINT, &CopyNativeVertexData); - AddIntegerVertexFormatInfo(&map, GL_SHORT, 2, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16_SINT, &CopyNativeVertexData); - AddIntegerVertexFormatInfo(&map, GL_SHORT, 3, VERTEX_CONVERT_CPU, DXGI_FORMAT_R16G16B16A16_SINT, &CopyNativeVertexData); - AddIntegerVertexFormatInfo(&map, GL_SHORT, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16B16A16_SINT, &CopyNativeVertexData); - - // GL_UNSIGNED_SHORT - AddIntegerVertexFormatInfo(&map, GL_UNSIGNED_SHORT, 1, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16_UINT, &CopyNativeVertexData); - AddIntegerVertexFormatInfo(&map, GL_UNSIGNED_SHORT, 2, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16_UINT, &CopyNativeVertexData); - AddIntegerVertexFormatInfo(&map, GL_UNSIGNED_SHORT, 3, VERTEX_CONVERT_CPU, DXGI_FORMAT_R16G16B16A16_UINT, &CopyNativeVertexData); - AddIntegerVertexFormatInfo(&map, GL_UNSIGNED_SHORT, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16B16A16_UINT, &CopyNativeVertexData); - - // GL_INT - AddIntegerVertexFormatInfo(&map, GL_INT, 1, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32_SINT, &CopyNativeVertexData); - AddIntegerVertexFormatInfo(&map, GL_INT, 2, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32_SINT, &CopyNativeVertexData); - AddIntegerVertexFormatInfo(&map, GL_INT, 3, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32B32_SINT, &CopyNativeVertexData); - AddIntegerVertexFormatInfo(&map, GL_INT, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32B32A32_SINT, &CopyNativeVertexData); - - // GL_UNSIGNED_INT - AddIntegerVertexFormatInfo(&map, GL_UNSIGNED_INT, 1, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32_SINT, &CopyNativeVertexData); - AddIntegerVertexFormatInfo(&map, GL_UNSIGNED_INT, 2, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32_SINT, &CopyNativeVertexData); - AddIntegerVertexFormatInfo(&map, GL_UNSIGNED_INT, 3, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32B32_SINT, &CopyNativeVertexData); - AddIntegerVertexFormatInfo(&map, GL_UNSIGNED_INT, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32B32A32_SINT, &CopyNativeVertexData); - - // GL_INT_2_10_10_10_REV - AddIntegerVertexFormatInfo(&map, GL_INT_2_10_10_10_REV, 4, VERTEX_CONVERT_CPU, DXGI_FORMAT_R16G16B16A16_SINT, &CopyXYZ10W2ToXYZW32FVertexData); - - // GL_UNSIGNED_INT_2_10_10_10_REV - AddIntegerVertexFormatInfo(&map, GL_UNSIGNED_INT_2_10_10_10_REV, 4, VERTEX_CONVERT_NONE, DXGI_FORMAT_R10G10B10A2_UINT, &CopyNativeVertexData); + // GL_UNSIGNED_INT -- un-normalized + case gl::VERTEX_FORMAT_UINT1: + { + static const VertexFormat info(VERTEX_CONVERT_GPU, DXGI_FORMAT_R32_UINT, &CopyNativeVertexData); + return info; + } + case gl::VERTEX_FORMAT_UINT2: + { + static const VertexFormat info(VERTEX_CONVERT_GPU, DXGI_FORMAT_R32G32_UINT, &CopyNativeVertexData); + return info; + } + case gl::VERTEX_FORMAT_UINT3: + { + static const VertexFormat info(VERTEX_CONVERT_GPU, DXGI_FORMAT_R32G32B32_UINT, &CopyNativeVertexData); + return info; + } + case gl::VERTEX_FORMAT_UINT4: + { + static const VertexFormat info(VERTEX_CONVERT_GPU, DXGI_FORMAT_R32G32B32A32_UINT, &CopyNativeVertexData); + return info; + } - return map; -} + // GL_UNSIGNED_INT -- normalized + case gl::VERTEX_FORMAT_UINT1_NORM: + { + static const VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R32_FLOAT, + &CopyTo32FVertexData); + return info; + } + case gl::VERTEX_FORMAT_UINT2_NORM: + { + static const VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32_FLOAT, + &CopyTo32FVertexData); + return info; + } + case gl::VERTEX_FORMAT_UINT3_NORM: + { + static const VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32B32_FLOAT, &CopyTo32FVertexData); + return info; + } + case gl::VERTEX_FORMAT_UINT4_NORM: + { + static const VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32B32A32_FLOAT, + &CopyTo32FVertexData); + return info; + } -const VertexFormat &GetVertexFormatInfo(const gl::VertexFormat &vertexFormat, D3D_FEATURE_LEVEL featureLevel) -{ - static const D3D11VertexFormatInfoMap vertexFormatMap = BuildD3D11VertexFormatInfoMap(); - static const D3D11VertexFormatInfoMap vertexFormatMapFL9_3Override = BuildD3D11_FL9_3VertexFormatInfoOverrideMap(); + // GL_FIXED + case gl::VERTEX_FORMAT_FIXED1: + { + static const VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R32_FLOAT, &Copy32FixedTo32FVertexData<1, 1>); + return info; + } + case gl::VERTEX_FORMAT_FIXED2: + { + static const VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32_FLOAT, &Copy32FixedTo32FVertexData<2, 2>); + return info; + } + case gl::VERTEX_FORMAT_FIXED3: + { + static const VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32B32_FLOAT, &Copy32FixedTo32FVertexData<3, 3>); + return info; + } + case gl::VERTEX_FORMAT_FIXED4: + { + static const VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32B32A32_FLOAT, &Copy32FixedTo32FVertexData<4, 4>); + return info; + } - if (featureLevel == D3D_FEATURE_LEVEL_9_3) - { - // First see if the format has a special mapping for FL9_3 - D3D11VertexFormatInfoMap::const_iterator iter = vertexFormatMapFL9_3Override.find(vertexFormat); - if (iter != vertexFormatMapFL9_3Override.end()) + // GL_HALF_FLOAT + case gl::VERTEX_FORMAT_HALF1: { - return iter->second; + static const VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R16_FLOAT, &CopyNativeVertexData); + return info; + } + case gl::VERTEX_FORMAT_HALF2: + { + static const VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16_FLOAT, &CopyNativeVertexData); + return info; + } + case gl::VERTEX_FORMAT_HALF3: + { + static const VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R16G16B16A16_FLOAT, &CopyNativeVertexData); + return info; + } + case gl::VERTEX_FORMAT_HALF4: + { + static const VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16B16A16_FLOAT, &CopyNativeVertexData); + return info; } - } - D3D11VertexFormatInfoMap::const_iterator iter = vertexFormatMap.find(vertexFormat); - if (iter != vertexFormatMap.end()) - { - return iter->second; - } - else - { - static const VertexFormat defaultInfo; - return defaultInfo; + // GL_FLOAT + case gl::VERTEX_FORMAT_FLOAT1: + { + static const VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R32_FLOAT, &CopyNativeVertexData); + return info; + } + case gl::VERTEX_FORMAT_FLOAT2: + { + static const VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32_FLOAT, &CopyNativeVertexData); + return info; + } + case gl::VERTEX_FORMAT_FLOAT3: + { + static const VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32B32_FLOAT, &CopyNativeVertexData); + return info; + } + case gl::VERTEX_FORMAT_FLOAT4: + { + static const VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32B32A32_FLOAT, &CopyNativeVertexData); + return info; + } + + // GL_INT_2_10_10_10_REV + case gl::VERTEX_FORMAT_SINT210: + { + static const VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32B32A32_FLOAT, &CopyXYZ10W2ToXYZW32FVertexData); + return info; + } + case gl::VERTEX_FORMAT_SINT210_NORM: + { + static const VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32B32A32_FLOAT, &CopyXYZ10W2ToXYZW32FVertexData); + return info; + } + + // GL_UNSIGNED_INT_2_10_10_10_REV + case gl::VERTEX_FORMAT_UINT210: + { + static const VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32B32A32_FLOAT, &CopyXYZ10W2ToXYZW32FVertexData); + return info; + } + case gl::VERTEX_FORMAT_UINT210_NORM: + { + static const VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R10G10B10A2_UNORM, &CopyNativeVertexData); + return info; + } + + // + // Integer Formats + // + + // GL_BYTE + case gl::VERTEX_FORMAT_SBYTE1_INT: + { + static const VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R8_SINT, &CopyNativeVertexData); + return info; + } + case gl::VERTEX_FORMAT_SBYTE2_INT: + { + static const VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R8G8_SINT, &CopyNativeVertexData); + return info; + } + case gl::VERTEX_FORMAT_SBYTE3_INT: + { + static const VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R8G8B8A8_SINT, &CopyNativeVertexData); + return info; + } + case gl::VERTEX_FORMAT_SBYTE4_INT: + { + static const VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R8G8B8A8_SINT, &CopyNativeVertexData); + return info; + } + + // GL_UNSIGNED_BYTE + case gl::VERTEX_FORMAT_UBYTE1_INT: + { + static const VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R8_UINT, &CopyNativeVertexData); + return info; + } + case gl::VERTEX_FORMAT_UBYTE2_INT: + { + static const VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R8G8_UINT, &CopyNativeVertexData); + return info; + } + case gl::VERTEX_FORMAT_UBYTE3_INT: + { + static const VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R8G8B8A8_UINT, &CopyNativeVertexData); + return info; + } + case gl::VERTEX_FORMAT_UBYTE4_INT: + { + static const VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R8G8B8A8_UINT, &CopyNativeVertexData); + return info; + } + + // GL_SHORT + case gl::VERTEX_FORMAT_SSHORT1_INT: + { + static const VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R16_SINT, &CopyNativeVertexData); + return info; + } + case gl::VERTEX_FORMAT_SSHORT2_INT: + { + static const VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16_SINT, &CopyNativeVertexData); + return info; + } + case gl::VERTEX_FORMAT_SSHORT3_INT: + { + static const VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R16G16B16A16_SINT, &CopyNativeVertexData); + return info; + } + case gl::VERTEX_FORMAT_SSHORT4_INT: + { + static const VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16B16A16_SINT, &CopyNativeVertexData); + return info; + } + + // GL_UNSIGNED_SHORT + case gl::VERTEX_FORMAT_USHORT1_INT: + { + static const VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R16_UINT, &CopyNativeVertexData); + return info; + } + case gl::VERTEX_FORMAT_USHORT2_INT: + { + static const VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16_UINT, &CopyNativeVertexData); + return info; + } + case gl::VERTEX_FORMAT_USHORT3_INT: + { + static const VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R16G16B16A16_UINT, &CopyNativeVertexData); + return info; + } + case gl::VERTEX_FORMAT_USHORT4_INT: + { + static const VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16B16A16_UINT, &CopyNativeVertexData); + return info; + } + + // GL_INT + case gl::VERTEX_FORMAT_SINT1_INT: + { + static const VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R32_SINT, &CopyNativeVertexData); + return info; + } + case gl::VERTEX_FORMAT_SINT2_INT: + { + static const VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32_SINT, &CopyNativeVertexData); + return info; + } + case gl::VERTEX_FORMAT_SINT3_INT: + { + static const VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32B32_SINT, &CopyNativeVertexData); + return info; + } + case gl::VERTEX_FORMAT_SINT4_INT: + { + static const VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32B32A32_SINT, &CopyNativeVertexData); + return info; + } + + // GL_UNSIGNED_INT + case gl::VERTEX_FORMAT_UINT1_INT: + { + static const VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R32_SINT, &CopyNativeVertexData); + return info; + } + case gl::VERTEX_FORMAT_UINT2_INT: + { + static const VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32_SINT, &CopyNativeVertexData); + return info; + } + case gl::VERTEX_FORMAT_UINT3_INT: + { + static const VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32B32_SINT, &CopyNativeVertexData); + return info; + } + case gl::VERTEX_FORMAT_UINT4_INT: + { + static const VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32B32A32_SINT, &CopyNativeVertexData); + return info; + } + + // GL_INT_2_10_10_10_REV + case gl::VERTEX_FORMAT_SINT210_INT: + { + static const VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R16G16B16A16_SINT, &CopyXYZ10W2ToXYZW32FVertexData); + return info; + } + + // GL_UNSIGNED_INT_2_10_10_10_REV + case gl::VERTEX_FORMAT_UINT210_INT: + { + static const VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R10G10B10A2_UINT, &CopyNativeVertexData); + return info; + } + + default: + { + static const VertexFormat info; + return info; + } } } diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/formatutils11.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/formatutils11.h index c411bfa8d786..4eee58e1ba45 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/formatutils11.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/formatutils11.h @@ -10,15 +10,16 @@ #ifndef LIBANGLE_RENDERER_D3D_D3D11_FORMATUTILS11_H_ #define LIBANGLE_RENDERER_D3D_D3D11_FORMATUTILS11_H_ -#include "libANGLE/renderer/d3d/formatutilsD3D.h" -#include "libANGLE/angletypes.h" +#include #include "common/platform.h" - -#include +#include "libANGLE/angletypes.h" +#include "libANGLE/formatutils.h" +#include "libANGLE/renderer/d3d/formatutilsD3D.h" namespace rx { +struct Renderer11DeviceCaps; namespace d3d11 { @@ -30,10 +31,6 @@ struct DXGIFormat { DXGIFormat(); - GLuint pixelBytes; - GLuint blockWidth; - GLuint blockHeight; - GLuint redBits; GLuint greenBits; GLuint blueBits; @@ -41,57 +38,49 @@ struct DXGIFormat GLuint sharedBits; GLuint depthBits; - GLuint depthOffset; GLuint stencilBits; - GLuint stencilOffset; - GLenum internalFormat; GLenum componentType; - MipGenerationFunction mipGenerationFunction; - ColorReadFunction colorReadFunction; - FastCopyFunctionMap fastCopyFunctions; NativeMipmapGenerationSupportFunction nativeMipmapSupport; ColorCopyFunction getFastCopyFunction(GLenum format, GLenum type) const; }; + +// This structure is problematic because a resource is associated with multiple DXGI formats. +// For example, 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. const DXGIFormat &GetDXGIFormatInfo(DXGI_FORMAT format); -struct TextureFormat +struct DXGIFormatSize { - TextureFormat(); - - DXGI_FORMAT texFormat; - DXGI_FORMAT srvFormat; - DXGI_FORMAT rtvFormat; - DXGI_FORMAT dsvFormat; - DXGI_FORMAT renderFormat; - - DXGI_FORMAT swizzleTexFormat; - DXGI_FORMAT swizzleSRVFormat; - DXGI_FORMAT swizzleRTVFormat; + DXGIFormatSize(GLuint pixelBits, GLuint blockWidth, GLuint blockHeight); - InitializeTextureDataFunction dataInitializerFunction; - - typedef std::map LoadFunctionMap; - LoadFunctionMap loadFunctions; + GLuint pixelBytes; + GLuint blockWidth; + GLuint blockHeight; }; -const TextureFormat &GetTextureFormatInfo(GLenum internalFormat, D3D_FEATURE_LEVEL featureLevel); +const DXGIFormatSize &GetDXGIFormatSizeInfo(DXGI_FORMAT format); struct VertexFormat { VertexFormat(); + VertexFormat(VertexConversionType conversionType, + DXGI_FORMAT nativeFormat, + VertexCopyFunction copyFunction); VertexConversionType conversionType; DXGI_FORMAT nativeFormat; VertexCopyFunction copyFunction; }; -const VertexFormat &GetVertexFormatInfo(const gl::VertexFormat &vertexFormat, D3D_FEATURE_LEVEL featureLevel); +const VertexFormat &GetVertexFormatInfo(gl::VertexFormatType vertexFormatType, + D3D_FEATURE_LEVEL featureLevel); -} +} // namespace d3d11 -} +} // namespace rx #endif // LIBANGLE_RENDERER_D3D_D3D11_FORMATUTILS11_H_ diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/gen_dxgi_support_tables.py b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/gen_dxgi_support_tables.py new file mode 100644 index 000000000000..21b22803b9d4 --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/gen_dxgi_support_tables.py @@ -0,0 +1,243 @@ +#!/usr/bin/python +# 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. +# +# gen_dxgi_support_tables.py: +# Code generation for the DXGI support tables. Determines which formats +# are natively support in D3D10+. +# +# MSDN links: +# 10_0: https://msdn.microsoft.com/en-us/library/windows/desktop/cc627090.aspx +# 10_1: https://msdn.microsoft.com/en-us/library/windows/desktop/cc627091.aspx +# 11_0: https://msdn.microsoft.com/en-us/library/windows/desktop/ff471325.aspx +# 11_1: https://msdn.microsoft.com/en-us/library/windows/desktop/hh404483.aspx + +import sys +import json + +macro_prefix = 'F_' + +template = """// 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/d3d/d3d11/dxgi_support_table.h" + +#include "common/debug.h" + +namespace rx +{{ + +namespace d3d11 +{{ + +#define {prefix}2D D3D11_FORMAT_SUPPORT_TEXTURE2D +#define {prefix}3D D3D11_FORMAT_SUPPORT_TEXTURE3D +#define {prefix}CUBE D3D11_FORMAT_SUPPORT_TEXTURECUBE +#define {prefix}SAMPLE D3D11_FORMAT_SUPPORT_SHADER_SAMPLE +#define {prefix}RT D3D11_FORMAT_SUPPORT_RENDER_TARGET +#define {prefix}MS D3D11_FORMAT_SUPPORT_MULTISAMPLE_RENDERTARGET +#define {prefix}DS D3D11_FORMAT_SUPPORT_DEPTH_STENCIL + +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; + static const DXGISupport defaultSupport(0, 0, AllSupportFlags); + return defaultSupport; +}} + +const DXGISupport &GetDXGISupport_10_0(DXGI_FORMAT dxgiFormat) +{{ + switch (dxgiFormat) + {{ +{table_data_10_0} + default: + UNREACHABLE(); + return GetDefaultSupport(); + }} +}} + +const DXGISupport &GetDXGISupport_10_1(DXGI_FORMAT dxgiFormat) +{{ + switch (dxgiFormat) + {{ +{table_data_10_1} + default: + UNREACHABLE(); + return GetDefaultSupport(); + }} +}} + +const DXGISupport &GetDXGISupport_11_0(DXGI_FORMAT dxgiFormat) +{{ + switch (dxgiFormat) + {{ +{table_data_11_0} + default: + UNREACHABLE(); + return GetDefaultSupport(); + }} +}} + +}} + +#undef {prefix}2D +#undef {prefix}3D +#undef {prefix}CUBE +#undef {prefix}SAMPLE +#undef {prefix}RT +#undef {prefix}MS +#undef {prefix}DS + +const DXGISupport &GetDXGISupport(DXGI_FORMAT dxgiFormat, D3D_FEATURE_LEVEL featureLevel) +{{ + switch (featureLevel) + {{ + 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); + default: + return GetDefaultSupport(); + }} +}} + +}} // namespace d3d11 + +}} // namespace rx +""" + +table_init = "" + +def do_format(format_data): + table_data = {'10_0': '', '10_1': '', '11_0': ''} + + json_flag_to_d3d = { + 'texture2D': macro_prefix + '2D', + 'texture3D': macro_prefix + '3D', + 'textureCube': macro_prefix + 'CUBE', + 'shaderSample': macro_prefix + 'SAMPLE', + 'renderTarget': macro_prefix + 'RT', + 'multisampleRT': macro_prefix + 'MS', + 'depthStencil': macro_prefix + 'DS' + } + + for format_name, format_support in sorted(format_data.iteritems()): + + always_supported = set() + never_supported = set() + optionally_supported = set() + fl_10_1_supported = set() + fl_11_0_supported = set() + fl_11_0_check = set() + fl_10_0_check_10_1_supported = set() + fl_10_0_check_11_0_supported = set() + + for json_flag, support in format_support.iteritems(): + + d3d_flag = [json_flag_to_d3d[json_flag]] + + if support == 'check': + optionally_supported.update(d3d_flag) + elif support == 'always': + always_supported.update(d3d_flag) + elif support == 'never': + never_supported.update(d3d_flag) + elif support == '10_0': + # TODO(jmadill): FL 9_3 handling + always_supported.update(d3d_flag) + elif support == '10_1': + fl_10_1_supported.update(d3d_flag) + elif support == '11_0': + fl_11_0_supported.update(d3d_flag) + elif support == '11_1': + # TODO(jmadill): D3D 11.1 handling + never_supported.update(d3d_flag) + elif support == 'dxgi1_2': + # TODO(jmadill): DXGI 1.2 handling. + always_supported.update(d3d_flag) + elif support == '10_0check10_1always': + fl_10_0_check_10_1_supported.update(d3d_flag) + elif support == '10_0check11_0always': + fl_10_0_check_11_0_supported.update(d3d_flag) + elif support == '11_0check': + fl_11_0_check.update(d3d_flag) + else: + print("Data specification error: " + support) + sys.exit(1) + + for feature_level in ['10_0', '10_1', '11_0']: + always_for_fl = always_supported + optional_for_fl = optionally_supported + if feature_level == '10_0': + optional_for_fl = fl_10_0_check_10_1_supported.union(optional_for_fl) + optional_for_fl = fl_10_0_check_11_0_supported.union(optional_for_fl) + if feature_level == '10_1': + always_for_fl = fl_10_1_supported.union(always_for_fl) + always_for_fl = fl_10_0_check_10_1_supported.union(always_for_fl) + optional_for_fl = fl_10_0_check_11_0_supported.union(optional_for_fl) + elif feature_level == '11_0': + always_for_fl = fl_10_0_check_10_1_supported.union(always_for_fl) + always_for_fl = fl_10_0_check_11_0_supported.union(always_for_fl) + always_for_fl = fl_10_1_supported.union(always_for_fl) + always_for_fl = fl_11_0_supported.union(always_for_fl) + + always = ' | '.join(sorted(always_for_fl)) + never = ' | '.join(sorted(never_supported)) + optional = ' | '.join(sorted(optional_for_fl)) + + if not always: always = '0' + if not never: never = '0' + if not optional: optional = '0' + + table_data[feature_level] += ' case ' + format_name + ':\n' + table_data[feature_level] += ' {\n' + table_data[feature_level] += ' static const DXGISupport info(' + always + ', ' + never + ', ' + optional + ');\n' + table_data[feature_level] += ' return info;\n' + table_data[feature_level] += ' }\n' + + return table_data + +def join_table_data(table_data_1, table_data_2): + return {'10_0': table_data_1['10_0'] + table_data_2['10_0'], + '10_1': table_data_1['10_1'] + table_data_2['10_1'], + '11_0': table_data_1['11_0'] + table_data_2['11_0']} + +with open('dxgi_support_data.json') as dxgi_file: + file_data = dxgi_file.read() + dxgi_file.close() + json_data = json.loads(file_data) + + table_data = {'10_0': '', '10_1': '', '11_0': ''} + + for format_data in json_data: + table_data = join_table_data(table_data, do_format(format_data)) + + out_data = template.format(prefix=macro_prefix, + table_data_10_0=table_data['10_0'], + table_data_10_1=table_data['10_1'], + table_data_11_0=table_data['11_0']) + + with open('dxgi_support_table.cpp', 'wt') as out_file: + out_file.write(out_data) + out_file.close() + diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/gen_load_functions_table.py b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/gen_load_functions_table.py new file mode 100644 index 000000000000..8807f9ff4126 --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/gen_load_functions_table.py @@ -0,0 +1,199 @@ +#!/usr/bin/python +# 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. +# +# gen_load_functions_table.py: +# Code generation for the load function tables used for texture formats +# + +import json + +template = """// GENERATED FILE - DO NOT EDIT. +// Generated by gen_load_functions_table.py using data from load_functions_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. +// +// load_functions_table: +// Contains the GetLoadFunctionsMap for texture_format_util.h +// + +#include "libANGLE/renderer/d3d/d3d11/load_functions_table.h" +#include "libANGLE/renderer/d3d/d3d11/formatutils11.h" +#include "libANGLE/renderer/d3d/d3d11/texture_format_table.h" +#include "libANGLE/renderer/d3d/loadimage.h" +#include "libANGLE/renderer/d3d/loadimage_etc.h" + +namespace rx +{{ + +namespace d3d11 +{{ + +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(); +}} + +}} // namespace + +// TODO we can replace these maps with more generated code +const std::map &GetLoadFunctionsMap(GLenum {internal_format}, + DXGI_FORMAT {dxgi_format}) +{{ + // clang-format off + switch ({internal_format}) + {{ +{data} + default: + {{ + static std::map emptyLoadFunctionsMap; + return emptyLoadFunctionsMap; + }} + }} + // clang-format on + +}} // GetLoadFunctionsMap + +}} // namespace d3d11 + +}} // namespace rx +""" + +internal_format_param = 'internalFormat' +dxgi_format_param = 'dxgiFormat' +dxgi_format_unknown = "DXGI_FORMAT_UNKNOWN" + +def get_function_maps_string(typestr, function, requiresConversion): + return ' loadMap[' + typestr + '] = LoadImageFunctionInfo(' + function + ', ' + requiresConversion + ');\n' + +def get_unknown_format_string(dxgi_to_type_map, dxgi_unknown_string): + if dxgi_unknown_string not in dxgi_to_type_map: + return '' + + table_data = '' + + for unknown_type_function in dxgi_to_type_map[dxgi_unknown_string]: + table_data += get_function_maps_string(unknown_type_function['type'], unknown_type_function['loadFunction'], 'true') + + return table_data + +# Making map from dxgi to type map for a particular internalFormat +def create_dxgi_to_type_map(dst, json_data, internal_format_str): + for type_item in sorted(json_data[internal_format_str].iteritems()): + for entry_in_type_item in type_item[1]: + dxgi_format_str = entry_in_type_item['dxgiFormat'] + + if dxgi_format_str not in dst: + dst[dxgi_format_str] = [] + + type_dxgi_load_function = entry_in_type_item.copy(); + type_dxgi_load_function['type'] = type_item[0] + dst[dxgi_format_str].append(type_dxgi_load_function) + +def get_load_function_map_snippet(insert_map_string): + load_function_map_snippet = '' + load_function_map_snippet += ' static const std::map loadFunctionsMap = []() {\n' + load_function_map_snippet += ' std::map loadMap;\n' + load_function_map_snippet += insert_map_string + load_function_map_snippet += ' return loadMap;\n' + load_function_map_snippet += ' }();\n\n' + load_function_map_snippet += ' return loadFunctionsMap;\n' + + return load_function_map_snippet + +def parse_json_into_switch_string(json_data): + table_data = '' + for internal_format_item in sorted(json_data.iteritems()): + internal_format_str = internal_format_item[0] + table_data += ' case ' + internal_format_str + ':\n' + table_data += ' {\n' + table_data += ' switch (' + dxgi_format_param + ')\n' + table_data += ' {\n' + + dxgi_to_type_map = {}; + create_dxgi_to_type_map(dxgi_to_type_map, json_data, internal_format_str) + + dxgi_unknown_str = get_unknown_format_string(dxgi_to_type_map, dxgi_format_unknown); + + for dxgi_format_item in sorted(dxgi_to_type_map.iteritems()): + dxgi_format_str = dxgi_format_item[0] + + # Main case statements + table_data += ' case ' + dxgi_format_str + ':\n' + table_data += ' {\n' + insert_map_string = '' + types_already_in_loadmap = set() + for type_function in sorted(dxgi_format_item[1]): + insert_map_string += get_function_maps_string(type_function['type'], type_function['loadFunction'], type_function['requiresConversion']) + types_already_in_loadmap.add(type_function['type']) + + # DXGI_FORMAT_UNKNOWN add ons + if dxgi_format_unknown in dxgi_to_type_map: + for unknown_type_function in dxgi_to_type_map[dxgi_format_unknown]: + # Check that it's not already in the loadmap so it doesn't override the value + if unknown_type_function['type'] not in types_already_in_loadmap: + insert_map_string += get_function_maps_string(unknown_type_function['type'], unknown_type_function['loadFunction'], 'true') + + table_data += get_load_function_map_snippet(insert_map_string) + table_data += ' }\n' + + table_data += ' default:\n' + + if dxgi_unknown_str: + table_data += ' {\n' + table_data += get_load_function_map_snippet(dxgi_unknown_str) + table_data += ' }\n' + else: + table_data += ' break;\n' + table_data += ' }\n' + table_data += ' }\n' + + return table_data + +with open('load_functions_data.json') as functions_json_file: + functions_data = functions_json_file.read(); + functions_json_file.close() + json_data = json.loads(functions_data) + + table_data = parse_json_into_switch_string(json_data) + output = template.format(internal_format = internal_format_param, + dxgi_format = dxgi_format_param, + data=table_data) + + with open('load_functions_table_autogen.cpp', 'wt') as out_file: + out_file.write(output) + out_file.close() diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/gen_texture_format_table.py b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/gen_texture_format_table.py new file mode 100644 index 000000000000..cded368d5cdf --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/gen_texture_format_table.py @@ -0,0 +1,525 @@ +#!/usr/bin/python +# 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. +# +# gen_texture_format_table.py: +# Code generation for texture format map +# + +import json +import math +import pprint +import re + +template_texture_format_table_autogen_h = """// GENERATED FILE - DO NOT EDIT. +// Generated by gen_texture_format_table.py using data from texture_format_data.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. +// + +namespace rx +{{ + +namespace d3d11 +{{ + +enum ANGLEFormat +{{ +{angle_format_enum} +}}; + +}} // namespace d3d11 + +}} // namespace rx +""" + +template_texture_format_table_autogen_cpp = """// 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 "libANGLE/renderer/d3d/d3d11/formatutils11.h" +#include "libANGLE/renderer/d3d/d3d11/load_functions_table.h" +#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h" +#include "libANGLE/renderer/d3d/copyimage.h" +#include "libANGLE/renderer/d3d/generatemip.h" +#include "libANGLE/renderer/d3d/loadimage.h" + +namespace rx +{{ + +namespace d3d11 +{{ + +namespace +{{ + +typedef bool (*FormatSupportFunction)(const Renderer11DeviceCaps &); + +bool OnlyFL10Plus(const Renderer11DeviceCaps &deviceCaps) +{{ + return (deviceCaps.featureLevel >= D3D_FEATURE_LEVEL_10_0); +}} + +bool OnlyFL9_3(const Renderer11DeviceCaps &deviceCaps) +{{ + return (deviceCaps.featureLevel == D3D_FEATURE_LEVEL_9_3); +}} + +template +bool SupportsFormat(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; + + if (d3d11_gl::GetMaximumClientVersion(deviceCaps.featureLevel) > 2) + {{ + mustSupport |= D3D11_FORMAT_SUPPORT_TEXTURE3D; + }} + + 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); + }} + else if (format == DXGI_FORMAT_B4G4R4A4_UNORM) + {{ + fullSupport = ((deviceCaps.B4G4R4A4support & mustSupport) == mustSupport); + }} + else if (format == DXGI_FORMAT_B5G5R5A1_UNORM) + {{ + fullSupport = ((deviceCaps.B5G5R5A1support & mustSupport) == mustSupport); + }} + else + {{ + UNREACHABLE(); + return false; + }} + + // This 'SupportsFormat' function is used by individual entries in the D3D11 Format Map below, + // which maps GL formats to DXGI formats. + if (requireSupport) + {{ + // 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; + }} + else + {{ + // This means that ANGLE would like to use the entry in the map if the inputted DXGI format + // *ISN'T* supported. + // This might be a fallback entry. e.g. for ANGLE to use DXGI_FORMAT_R8G8B8A8_UNORM if + // DXGI_FORMAT_B5G5R5A1 isn't supported. + // In this case, we should only return 'true' if the format *ISN'T* supported. + return !fullSupport; + }} +}} + +// End Format Support Functions +}} // namespace + +ANGLEFormatSet::ANGLEFormatSet() + : format(ANGLE_FORMAT_NONE), + glInternalFormat(GL_NONE), + texFormat(DXGI_FORMAT_UNKNOWN), + srvFormat(DXGI_FORMAT_UNKNOWN), + rtvFormat(DXGI_FORMAT_UNKNOWN), + dsvFormat(DXGI_FORMAT_UNKNOWN), + blitSRVFormat(DXGI_FORMAT_UNKNOWN), + swizzleFormat(ANGLE_FORMAT_NONE), + mipGenerationFunction(nullptr), + colorReadFunction(nullptr) +{{ +}} + +// For sized GL internal formats, there are several possible corresponding D3D11 formats depending +// on device capabilities. +// This function allows querying for the DXGI texture formats to use for textures, SRVs, RTVs and +// DSVs given a GL internal format. +TextureFormat::TextureFormat(GLenum internalFormat, + const ANGLEFormat angleFormat, + InitializeTextureDataFunction internalFormatInitializer) + : dataInitializerFunction(internalFormatInitializer) +{{ + formatSet = &GetANGLEFormatSet(angleFormat); + swizzleFormatSet = &GetANGLEFormatSet(formatSet->swizzleFormat); + + // Gather all the load functions for this internal format + loadFunctions = GetLoadFunctionsMap(internalFormat, formatSet->texFormat); + + ASSERT(loadFunctions.size() != 0 || internalFormat == GL_NONE); +}} + +ANGLEFormatSet::ANGLEFormatSet(ANGLEFormat format, + GLenum glInternalFormat, + DXGI_FORMAT texFormat, + DXGI_FORMAT srvFormat, + DXGI_FORMAT rtvFormat, + DXGI_FORMAT dsvFormat, + DXGI_FORMAT blitSRVFormat, + ANGLEFormat swizzleFormat, + MipGenerationFunction mipGenerationFunction, + ColorReadFunction colorReadFunction) + : format(format), + glInternalFormat(glInternalFormat), + texFormat(texFormat), + srvFormat(srvFormat), + rtvFormat(rtvFormat), + dsvFormat(dsvFormat), + blitSRVFormat(blitSRVFormat), + swizzleFormat(swizzleFormat), + mipGenerationFunction(mipGenerationFunction), + colorReadFunction(colorReadFunction) +{{ +}} + +const ANGLEFormatSet &GetANGLEFormatSet(ANGLEFormat angleFormat) +{{ + // clang-format off + switch (angleFormat) + {{ +{angle_format_info_cases} + default: + break; + }} + // clang-format on + + UNREACHABLE(); + static const ANGLEFormatSet defaultInfo; + return defaultInfo; +}} + +const TextureFormat &GetTextureFormatInfo(GLenum internalFormat, + const Renderer11DeviceCaps &renderer11DeviceCaps) +{{ + // clang-format off + switch (internalFormat) + {{ +{texture_format_info_cases} + default: + break; + }} + // clang-format on + + static const TextureFormat defaultInfo(GL_NONE, ANGLE_FORMAT_NONE, nullptr); + return defaultInfo; +}} // GetTextureFormatInfo + +}} // namespace d3d11 + +}} // namespace rx +""" + +# TODO(oetuaho): Expand this code so that it could generate the gl format info tables as well. +def gl_format_channels(internal_format): + if internal_format == 'GL_BGR5_A1_ANGLEX': + return 'bgra' + if internal_format == 'GL_R11F_G11F_B10F': + return 'rgb' + if internal_format == 'GL_RGB5_A1': + return 'rgba' + if internal_format.find('GL_RGB10_A2') == 0: + return 'rgba' + + channels_pattern = re.compile('GL_(COMPRESSED_)?(SIGNED_)?(ETC\d_)?([A-Z]+)') + match = re.search(channels_pattern, internal_format) + channels_string = match.group(4) + + if channels_string == 'ALPHA': + return 'a' + if channels_string == 'LUMINANCE': + if (internal_format.find('ALPHA') >= 0): + return 'la' + return 'l' + if channels_string == 'SRGB': + if (internal_format.find('ALPHA') >= 0): + return 'rgba' + return 'rgb' + if channels_string == 'DEPTH': + if (internal_format.find('STENCIL') >= 0): + return 'ds' + return 'd' + if channels_string == 'STENCIL': + return 's' + return channels_string.lower() + +def get_internal_format_initializer(internal_format, angle_format): + internal_format_initializer = 'nullptr' + gl_channels = gl_format_channels(internal_format) + gl_format_no_alpha = gl_channels == 'rgb' or gl_channels == 'l' + if gl_format_no_alpha and angle_format['channels'] == 'rgba': + if angle_format['texFormat'] == 'DXGI_FORMAT_BC1_UNORM': + # BC1 is a special case since the texture data determines whether each block has an alpha channel or not. + # This if statement is hit by COMPRESSED_RGB_S3TC_DXT1, which is a bit of a mess. + # TODO(oetuaho): Look into whether COMPRESSED_RGB_S3TC_DXT1 works right in general. + # Reference: https://www.opengl.org/registry/specs/EXT/texture_compression_s3tc.txt + pass + elif 'componentType' not in angle_format: + raise ValueError('warning: internal format initializer could not be generated and may be needed for ' + internal_format) + elif angle_format['componentType'] == 'uint' and angle_format['bits']['red'] == 8: + internal_format_initializer = 'Initialize4ComponentData' + elif angle_format['componentType'] == 'unorm' and angle_format['bits']['red'] == 8: + internal_format_initializer = 'Initialize4ComponentData' + elif angle_format['componentType'] == 'int' and angle_format['bits']['red'] == 8: + internal_format_initializer = 'Initialize4ComponentData' + elif angle_format['componentType'] == 'snorm' and angle_format['bits']['red'] == 8: + internal_format_initializer = 'Initialize4ComponentData' + elif angle_format['componentType'] == 'float' and angle_format['bits']['red'] == 16: + internal_format_initializer = 'Initialize4ComponentData' + elif angle_format['componentType'] == 'uint' and angle_format['bits']['red'] == 16: + internal_format_initializer = 'Initialize4ComponentData' + elif angle_format['componentType'] == 'int' and angle_format['bits']['red'] == 16: + internal_format_initializer = 'Initialize4ComponentData' + elif angle_format['componentType'] == 'float' and angle_format['bits']['red'] == 32: + internal_format_initializer = 'Initialize4ComponentData' + elif angle_format['componentType'] == 'int' and angle_format['bits']['red'] == 32: + internal_format_initializer = 'Initialize4ComponentData' + elif angle_format['componentType'] == 'uint' and angle_format['bits']['red'] == 32: + internal_format_initializer = 'Initialize4ComponentData' + else: + raise ValueError('warning: internal format initializer could not be generated and may be needed for ' + internal_format) + + return internal_format_initializer + +def get_swizzle_format_id(angle_format_id, angle_format): + if angle_format_id == 'ANGLE_FORMAT_NONE': + return 'ANGLE_FORMAT_NONE' + elif 'swizzleFormat' in angle_format: + # For some special formats like compressed formats that don't have a clearly defined number + # of bits per channel, swizzle format needs to be specified manually. + return angle_format['swizzleFormat'] + + if 'bits' not in angle_format: + raise ValueError('no bits information for determining swizzleformat for format: ' + angle_format_id) + + bits = angle_format['bits'] + max_component_bits = max(bits.itervalues()) + channels_different = not all([component_bits == bits.itervalues().next() for component_bits in bits.itervalues()]) + + # The format itself can be used for swizzles if it can be accessed as a render target and + # sampled and the bit count for all 4 channels is the same. + if "rtvFormat" in angle_format and "srvFormat" in angle_format and not channels_different and len(angle_format['channels']) == 4: + return angle_format_id + + b = int(math.ceil(float(max_component_bits) / 8) * 8) + + # Depth formats need special handling, since combined depth/stencil formats don't have a clearly + # defined component type. + if angle_format['channels'].find('d') >= 0: + if b == 24 or b == 32: + return 'ANGLE_FORMAT_R32G32B32A32_FLOAT' + if b == 16: + return 'ANGLE_FORMAT_R16G16B16A16_UNORM' + + if b == 24: + raise ValueError('unexpected 24-bit format when determining swizzleformat for format: ' + angle_format_id) + + if 'componentType' not in angle_format: + raise ValueError('no component type information for determining swizzleformat for format: ' + angle_format_id) + + component_type = angle_format['componentType'] + if component_type == 'uint': + return 'ANGLE_FORMAT_R{}G{}B{}A{}_UINT'.format(b, b, b, b) + elif component_type == 'int': + return 'ANGLE_FORMAT_R{}G{}B{}A{}_SINT'.format(b, b, b, b) + elif component_type == 'unorm': + return 'ANGLE_FORMAT_R{}G{}B{}A{}_UNORM'.format(b, b, b, b) + elif component_type == 'snorm': + return 'ANGLE_FORMAT_R{}G{}B{}A{}_SNORM'.format(b, b, b, b) + elif component_type == 'float': + return 'ANGLE_FORMAT_R{}G{}B{}A{}_FLOAT'.format(b, b, b, b) + else: + raise ValueError('could not determine swizzleformat based on componentType for format: ' + angle_format_id) + +def get_texture_format_item(idx, internal_format, requirements_fn, angle_format_id, angle_format): + table_data = ''; + + internal_format_initializer = get_internal_format_initializer(internal_format, angle_format) + + indent = ' ' + if requirements_fn != None: + if idx == 0: + table_data += ' if (' + requirements_fn + '(renderer11DeviceCaps))\n' + else: + table_data += ' else if (' + requirements_fn + '(renderer11DeviceCaps))\n' + table_data += ' {\n' + indent += ' ' + + table_data += indent + 'static const TextureFormat textureFormat(internalFormat,\n' + table_data += indent + ' ' + angle_format_id + ',\n' + table_data += indent + ' ' + internal_format_initializer + ');\n' + table_data += indent + 'return textureFormat;\n' + + if requirements_fn != None: + table_data += ' }\n' + + return table_data + +def parse_json_into_switch_texture_format_string(json_map, json_data): + table_data = '' + angle_format_map = {} + + for internal_format_item in sorted(json_map.iteritems()): + internal_format = internal_format_item[0] + table_data += ' case ' + internal_format + ':\n' + table_data += ' {\n' + + if isinstance(json_map[internal_format], basestring): + angle_format_id = json_map[internal_format] + table_data += get_texture_format_item(0, internal_format, None, angle_format_id, json_data[angle_format_id]) + else: + for idx, requirements_map in enumerate(sorted(json_map[internal_format].iteritems())): + angle_format_id = requirements_map[1] + table_data += get_texture_format_item(idx, internal_format, requirements_map[0], angle_format_id, json_data[angle_format_id]) + table_data += ' else\n' + table_data += ' {\n' + table_data += ' break;\n' + table_data += ' }\n' + + table_data += ' }\n' + + return table_data + +def get_channel_struct(angle_format): + if 'bits' not in angle_format: + return None + bits = angle_format['bits'] + if 'depth' in bits or 'stencil' in bits: + return None + + if 'channelStruct' in angle_format: + return angle_format['channelStruct'] + + struct_name = '' + for channel in angle_format['channels']: + if channel == 'r': + struct_name += 'R{}'.format(bits['red']) + if channel == 'g': + struct_name += 'G{}'.format(bits['green']) + if channel == 'b': + struct_name += 'B{}'.format(bits['blue']) + if channel == 'a': + struct_name += 'A{}'.format(bits['alpha']) + if angle_format['componentType'] == 'float': + struct_name += 'F' + if angle_format['componentType'] == 'int' or angle_format['componentType'] == 'snorm': + struct_name += 'S' + return struct_name + +def get_mip_generation_function(angle_format): + channel_struct = get_channel_struct(angle_format) + if channel_struct == None: + return 'nullptr' + return 'GenerateMip<' + channel_struct + '>' + +def get_color_read_function(angle_format): + channel_struct = get_channel_struct(angle_format) + if channel_struct == None: + return 'nullptr' + component_type_map = { + 'uint': 'GLuint', + 'int': 'GLint', + 'unorm': 'GLfloat', + 'snorm': 'GLfloat', + 'float': 'GLfloat' + } + return 'ReadColor<' + channel_struct + ', '+ component_type_map[angle_format['componentType']] + '>' + +def get_blit_srv_format(angle_format): + if 'channels' not in angle_format: + return 'DXGI_FORMAT_UNKNOWN' + if 'r' in angle_format['channels'] and angle_format['componentType'] in ['int', 'uint']: + return angle_format['rtvFormat'] + + return angle_format["srvFormat"] if "srvFormat" in angle_format else "DXGI_FORMAT_UNKNOWN" + +def parse_json_into_switch_angle_format_string(json_data): + table_data = '' + for angle_format_item in sorted(json_data.iteritems()): + table_data += ' case ' + angle_format_item[0] + ':\n' + angle_format = angle_format_item[1] + gl_internal_format = angle_format["glInternalFormat"] if "glInternalFormat" in angle_format else "GL_NONE" + tex_format = angle_format["texFormat"] if "texFormat" in angle_format else "DXGI_FORMAT_UNKNOWN" + srv_format = angle_format["srvFormat"] if "srvFormat" in angle_format else "DXGI_FORMAT_UNKNOWN" + rtv_format = angle_format["rtvFormat"] if "rtvFormat" in angle_format else "DXGI_FORMAT_UNKNOWN" + dsv_format = angle_format["dsvFormat"] if "dsvFormat" in angle_format else "DXGI_FORMAT_UNKNOWN" + blit_srv_format = get_blit_srv_format(angle_format) + swizzle_format = get_swizzle_format_id(angle_format_item[0], angle_format) + mip_generation_function = get_mip_generation_function(angle_format) + color_read_function = get_color_read_function(angle_format) + table_data += ' {\n' + table_data += ' static const ANGLEFormatSet formatInfo(' + angle_format_item[0] + ',\n' + table_data += ' ' + gl_internal_format + ',\n' + table_data += ' ' + tex_format + ',\n' + table_data += ' ' + srv_format + ',\n' + table_data += ' ' + rtv_format + ',\n' + table_data += ' ' + dsv_format + ',\n' + table_data += ' ' + blit_srv_format + ',\n' + table_data += ' ' + swizzle_format + ',\n' + table_data += ' ' + mip_generation_function + ',\n' + table_data += ' ' + color_read_function + ');\n' + table_data += ' return formatInfo;\n' + table_data += ' }\n' + return table_data + +def parse_json_into_angle_format_enum_string(json_data): + enum_data = '' + index = 0 + for angle_format_item in sorted(json_data.iteritems()): + if index > 0: + enum_data += ',\n' + enum_data += ' ' + angle_format_item[0] + index += 1 + return enum_data + +def reject_duplicate_keys(pairs): + found_keys = {} + for key, value in pairs: + if key in found_keys: + raise ValueError("duplicate key: %r" % (key,)) + else: + found_keys[key] = value + return found_keys + +with open('texture_format_map.json') as texture_format_map_file: + with open('texture_format_data.json') as texture_format_json_file: + texture_format_map = texture_format_map_file.read() + texture_format_data = texture_format_json_file.read() + texture_format_map_file.close() + texture_format_json_file.close() + json_map = json.loads(texture_format_map, object_pairs_hook=reject_duplicate_keys) + json_data = json.loads(texture_format_data, object_pairs_hook=reject_duplicate_keys) + + texture_format_cases = parse_json_into_switch_texture_format_string(json_map, json_data) + angle_format_cases = parse_json_into_switch_angle_format_string(json_data) + output_cpp = template_texture_format_table_autogen_cpp.format( + texture_format_info_cases=texture_format_cases, + angle_format_info_cases=angle_format_cases) + with open('texture_format_table_autogen.cpp', 'wt') as out_file: + out_file.write(output_cpp) + out_file.close() + + enum_data = parse_json_into_angle_format_enum_string(json_data) + output_h = template_texture_format_table_autogen_h.format(angle_format_enum=enum_data) + with open('texture_format_table_autogen.h', 'wt') as out_file: + out_file.write(output_h) + out_file.close() diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/load_functions_data.json b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/load_functions_data.json new file mode 100644 index 000000000000..c85393e06b96 --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/load_functions_data.json @@ -0,0 +1,1116 @@ +{ + "GL_RG8_SNORM": { + "GL_BYTE": [ + { + "loadFunction": "LoadToNative", + "dxgiFormat": "DXGI_FORMAT_R8G8_SNORM", + "requiresConversion": "false" + } + ] + }, + "GL_SRGB8": { + "GL_UNSIGNED_BYTE": [ + { + "loadFunction": "LoadToNative3To4", + "dxgiFormat": "DXGI_FORMAT_R8G8B8A8_UNORM_SRGB", + "requiresConversion": "true" + } + ] + }, + "GL_RGBA8I": { + "GL_BYTE": [ + { + "loadFunction": "LoadToNative", + "dxgiFormat": "DXGI_FORMAT_R8G8B8A8_SINT", + "requiresConversion": "false" + } + ] + }, + "GL_R8_SNORM": { + "GL_BYTE": [ + { + "loadFunction": "LoadToNative", + "dxgiFormat": "DXGI_FORMAT_R8_SNORM", + "requiresConversion": "false" + } + ] + }, + "GL_RGBA8_SNORM": { + "GL_BYTE": [ + { + "loadFunction": "LoadToNative", + "dxgiFormat": "DXGI_FORMAT_R8G8B8A8_SNORM", + "requiresConversion": "false" + } + ] + }, + "GL_R16I": { + "GL_SHORT": [ + { + "loadFunction": "LoadToNative", + "dxgiFormat": "DXGI_FORMAT_R16_SINT", + "requiresConversion": "false" + } + ] + }, + "GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC": { + "GL_UNSIGNED_BYTE": [ + { + "loadFunction": "LoadETC2SRGBA8ToSRGBA8", + "dxgiFormat": "DXGI_FORMAT_R8G8B8A8_UNORM_SRGB", + "requiresConversion": "true" + } + ] + }, + "GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2": { + "GL_UNSIGNED_BYTE": [ + { + "loadFunction": "LoadETC2RGB8A1ToRGBA8", + "dxgiFormat": "DXGI_FORMAT_R8G8B8A8_UNORM", + "requiresConversion": "true" + } + ] + }, + "GL_RGB32UI": { + "GL_UNSIGNED_INT": [ + { + "loadFunction": "LoadToNative3To4", + "dxgiFormat": "DXGI_FORMAT_R32G32B32A32_UINT", + "requiresConversion": "true" + } + ] + }, + "GL_ALPHA32F_EXT": { + "GL_FLOAT": [ + { + "loadFunction": "LoadA32FToRGBA32F", + "dxgiFormat": "DXGI_FORMAT_UNKNOWN", + "requiresConversion": "true" + } + ] + }, + "GL_R16UI": { + "GL_UNSIGNED_SHORT": [ + { + "loadFunction": "LoadToNative", + "dxgiFormat": "DXGI_FORMAT_R16_UINT", + "requiresConversion": "false" + } + ] + }, + "GL_RGB9_E5": { + "GL_HALF_FLOAT": [ + { + "loadFunction": "LoadRGB16FToRGB9E5", + "dxgiFormat": "DXGI_FORMAT_R9G9B9E5_SHAREDEXP", + "requiresConversion": "true" + } + ], + "GL_UNSIGNED_INT_5_9_9_9_REV": [ + { + "loadFunction": "LoadToNative", + "dxgiFormat": "DXGI_FORMAT_R9G9B9E5_SHAREDEXP", + "requiresConversion": "false" + } + ], + "GL_FLOAT": [ + { + "loadFunction": "LoadRGB32FToRGB9E5", + "dxgiFormat": "DXGI_FORMAT_R9G9B9E5_SHAREDEXP", + "requiresConversion": "true" + } + ], + "GL_HALF_FLOAT_OES": [ + { + "loadFunction": "LoadRGB16FToRGB9E5", + "dxgiFormat": "DXGI_FORMAT_R9G9B9E5_SHAREDEXP", + "requiresConversion": "true" + } + ] + }, + "GL_COMPRESSED_R11_EAC": { + "GL_UNSIGNED_BYTE": [ + { + "loadFunction": "LoadEACR11ToR8", + "dxgiFormat": "DXGI_FORMAT_R8_UNORM", + "requiresConversion": "true" + } + ] + }, + "GL_RGBA32UI": { + "GL_UNSIGNED_INT": [ + { + "loadFunction": "LoadToNative", + "dxgiFormat": "DXGI_FORMAT_R32G32B32A32_UINT", + "requiresConversion": "false" + } + ] + }, + "GL_RG8UI": { + "GL_UNSIGNED_BYTE": [ + { + "loadFunction": "LoadToNative", + "dxgiFormat": "DXGI_FORMAT_R8G8_UINT", + "requiresConversion": "false" + } + ] + }, + "GL_LUMINANCE32F_EXT": { + "GL_FLOAT": [ + { + "loadFunction": "LoadL32FToRGBA32F", + "dxgiFormat": "DXGI_FORMAT_UNKNOWN", + "requiresConversion": "true" + } + ] + }, + "GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2": { + "GL_UNSIGNED_BYTE": [ + { + "loadFunction": "LoadETC2SRGB8A1ToRGBA8", + "dxgiFormat": "DXGI_FORMAT_R8G8B8A8_UNORM_SRGB", + "requiresConversion": "true" + } + ] + }, + "GL_R16F": { + "GL_HALF_FLOAT": [ + { + "loadFunction": "LoadToNative", + "dxgiFormat": "DXGI_FORMAT_R16_FLOAT", + "requiresConversion": "false" + } + ], + "GL_FLOAT": [ + { + "loadFunction": "Load32FTo16F<1>", + "dxgiFormat": "DXGI_FORMAT_R16_FLOAT", + "requiresConversion": "true" + } + ], + "GL_HALF_FLOAT_OES": [ + { + "loadFunction": "LoadToNative", + "dxgiFormat": "DXGI_FORMAT_R16_FLOAT", + "requiresConversion": "false" + } + ] + }, + "GL_RGBA8UI": { + "GL_UNSIGNED_BYTE": [ + { + "loadFunction": "LoadToNative", + "dxgiFormat": "DXGI_FORMAT_R8G8B8A8_UINT", + "requiresConversion": "false" + } + ] + }, + "GL_BGRA4_ANGLEX": { + "GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT": [ + { + "loadFunction": "LoadRGBA4ToRGBA8", + "dxgiFormat": "DXGI_FORMAT_UNKNOWN", + "requiresConversion": "true" + } + ], + "GL_UNSIGNED_BYTE": [ + { + "loadFunction": "LoadToNative", + "dxgiFormat": "DXGI_FORMAT_UNKNOWN", + "requiresConversion": "false" + } + ] + }, + "GL_RGBA16F": { + "GL_HALF_FLOAT": [ + { + "loadFunction": "LoadToNative", + "dxgiFormat": "DXGI_FORMAT_R16G16B16A16_FLOAT", + "requiresConversion": "false" + } + ], + "GL_FLOAT": [ + { + "loadFunction": "Load32FTo16F<4>", + "dxgiFormat": "DXGI_FORMAT_R16G16B16A16_FLOAT", + "requiresConversion": "true" + } + ], + "GL_HALF_FLOAT_OES": [ + { + "loadFunction": "LoadToNative", + "dxgiFormat": "DXGI_FORMAT_R16G16B16A16_FLOAT", + "requiresConversion": "false" + } + ] + }, + "GL_LUMINANCE8_EXT": { + "GL_UNSIGNED_BYTE": [ + { + "loadFunction": "LoadL8ToRGBA8", + "dxgiFormat": "DXGI_FORMAT_UNKNOWN", + "requiresConversion": "true" + } + ] + }, + "GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE": { + "GL_UNSIGNED_BYTE": [ + { + "loadFunction": "LoadCompressedToNative<4,4,16>", + "dxgiFormat": "DXGI_FORMAT_UNKNOWN", + "requiresConversion": "true" + } + ] + }, + "GL_RGB": { + "GL_UNSIGNED_BYTE": [ + { + "loadFunction": "UnreachableLoadFunction", + "dxgiFormat": "DXGI_FORMAT_UNKNOWN", + "requiresConversion": "true" + } + ], + "GL_UNSIGNED_SHORT_5_6_5": [ + { + "loadFunction": "UnreachableLoadFunction", + "dxgiFormat": "DXGI_FORMAT_UNKNOWN", + "requiresConversion": "true" + } + ] + }, + "GL_RGB5_A1": { + "GL_UNSIGNED_INT_2_10_10_10_REV": [ + { + "loadFunction": "LoadRGB10A2ToRGBA8", + "dxgiFormat": "DXGI_FORMAT_R8G8B8A8_UNORM", + "requiresConversion": "true" + } + ], + "GL_UNSIGNED_BYTE": [ + { + "loadFunction": "LoadToNative", + "dxgiFormat": "DXGI_FORMAT_R8G8B8A8_UNORM", + "requiresConversion": "false" + } + ], + "GL_UNSIGNED_SHORT_5_5_5_1": [ + { + "loadFunction": "LoadRGB5A1ToRGBA8", + "dxgiFormat": "DXGI_FORMAT_R8G8B8A8_UNORM", + "requiresConversion": "true" + }, + { + "loadFunction": "LoadRGB5A1ToA1RGB5", + "dxgiFormat": "DXGI_FORMAT_B5G5R5A1_UNORM", + "requiresConversion": "true" + } + ] + }, + "GL_RGB16UI": { + "GL_UNSIGNED_SHORT": [ + { + "loadFunction": "LoadToNative3To4", + "dxgiFormat": "DXGI_FORMAT_R16G16B16A16_UINT", + "requiresConversion": "true" + } + ] + }, + "GL_BGRA_EXT": { + "GL_UNSIGNED_BYTE": [ + { + "loadFunction": "UnreachableLoadFunction", + "dxgiFormat": "DXGI_FORMAT_UNKNOWN", + "requiresConversion": "true" + } + ] + }, + "GL_COMPRESSED_RGB8_ETC2": { + "GL_UNSIGNED_BYTE": [ + { + "loadFunction": "LoadETC2RGB8ToRGBA8", + "dxgiFormat": "DXGI_FORMAT_R8G8B8A8_UNORM", + "requiresConversion": "true" + } + ] + }, + "GL_RGBA32F": { + "GL_FLOAT": [ + { + "loadFunction": "LoadToNative", + "dxgiFormat": "DXGI_FORMAT_R32G32B32A32_FLOAT", + "requiresConversion": "false" + } + ] + }, + "GL_RGBA32I": { + "GL_INT": [ + { + "loadFunction": "LoadToNative", + "dxgiFormat": "DXGI_FORMAT_R32G32B32A32_SINT", + "requiresConversion": "false" + } + ] + }, + "GL_LUMINANCE8_ALPHA8_EXT": { + "GL_UNSIGNED_BYTE": [ + { + "loadFunction": "LoadLA8ToRGBA8", + "dxgiFormat": "DXGI_FORMAT_UNKNOWN", + "requiresConversion": "true" + } + ] + }, + "GL_RG8": { + "GL_UNSIGNED_BYTE": [ + { + "loadFunction": "LoadToNative", + "dxgiFormat": "DXGI_FORMAT_R8G8_UNORM", + "requiresConversion": "false" + } + ] + }, + "GL_RGB10_A2": { + "GL_UNSIGNED_INT_2_10_10_10_REV": [ + { + "loadFunction": "LoadToNative", + "dxgiFormat": "DXGI_FORMAT_R10G10B10A2_UNORM", + "requiresConversion": "false" + } + ] + }, + "GL_COMPRESSED_SIGNED_RG11_EAC": { + "GL_UNSIGNED_BYTE": [ + { + "loadFunction": "LoadEACRG11SToRG8", + "dxgiFormat": "DXGI_FORMAT_R8G8_SNORM", + "requiresConversion": "true" + } + ] + }, + "GL_DEPTH_COMPONENT16": { + "GL_UNSIGNED_INT": [ + { + "loadFunction": "LoadR32ToR16", + "dxgiFormat": "DXGI_FORMAT_R16_TYPELESS", + "requiresConversion": "true" + } + ], + "GL_UNSIGNED_SHORT": [ + { + "loadFunction": "LoadToNative", + "dxgiFormat": "DXGI_FORMAT_R16_TYPELESS", + "requiresConversion": "false" + }, + { + "loadFunction": "LoadToNative", + "dxgiFormat": "DXGI_FORMAT_D16_UNORM", + "requiresConversion": "false" + } + ] + }, + "GL_RGB32I": { + "GL_INT": [ + { + "loadFunction": "LoadToNative3To4", + "dxgiFormat": "DXGI_FORMAT_R32G32B32A32_SINT", + "requiresConversion": "true" + } + ] + }, + "GL_R8": { + "GL_UNSIGNED_BYTE": [ + { + "loadFunction": "LoadToNative", + "dxgiFormat": "DXGI_FORMAT_R8_UNORM", + "requiresConversion": "false" + } + ] + }, + "GL_RGB32F": { + "GL_FLOAT": [ + { + "loadFunction": "LoadToNative3To4", + "dxgiFormat": "DXGI_FORMAT_R32G32B32A32_FLOAT", + "requiresConversion": "true" + } + ] + }, + "GL_R11F_G11F_B10F": { + "GL_UNSIGNED_INT_10F_11F_11F_REV": [ + { + "loadFunction": "LoadToNative", + "dxgiFormat": "DXGI_FORMAT_R11G11B10_FLOAT", + "requiresConversion": "false" + } + ], + "GL_HALF_FLOAT": [ + { + "loadFunction": "LoadRGB16FToRG11B10F", + "dxgiFormat": "DXGI_FORMAT_R11G11B10_FLOAT", + "requiresConversion": "true" + } + ], + "GL_FLOAT": [ + { + "loadFunction": "LoadRGB32FToRG11B10F", + "dxgiFormat": "DXGI_FORMAT_R11G11B10_FLOAT", + "requiresConversion": "true" + } + ], + "GL_HALF_FLOAT_OES": [ + { + "loadFunction": "LoadRGB16FToRG11B10F", + "dxgiFormat": "DXGI_FORMAT_R11G11B10_FLOAT", + "requiresConversion": "true" + } + ] + }, + "GL_RGB8": { + "GL_UNSIGNED_BYTE": [ + { + "loadFunction": "LoadToNative3To4", + "dxgiFormat": "DXGI_FORMAT_R8G8B8A8_UNORM", + "requiresConversion": "true" + } + ] + }, + "GL_LUMINANCE_ALPHA": { + "GL_HALF_FLOAT": [ + { + "loadFunction": "LoadLA16FToRGBA16F", + "dxgiFormat": "DXGI_FORMAT_R16G16B16A16_FLOAT", + "requiresConversion": "true" + } + ], + "GL_UNSIGNED_BYTE": [ + { + "loadFunction": "UnreachableLoadFunction", + "dxgiFormat": "DXGI_FORMAT_UNKNOWN", + "requiresConversion": "true" + } + ], + "GL_FLOAT": [ + { + "loadFunction": "LoadLA32FToRGBA32F", + "dxgiFormat": "DXGI_FORMAT_R32G32B32A32_FLOAT", + "requiresConversion": "true" + } + ], + "GL_HALF_FLOAT_OES": [ + { + "loadFunction": "LoadLA16FToRGBA16F", + "dxgiFormat": "DXGI_FORMAT_R16G16B16A16_FLOAT", + "requiresConversion": "true" + } + ] + }, + "GL_RGBA16I": { + "GL_SHORT": [ + { + "loadFunction": "LoadToNative", + "dxgiFormat": "DXGI_FORMAT_R16G16B16A16_SINT", + "requiresConversion": "false" + } + ] + }, + "GL_R8I": { + "GL_BYTE": [ + { + "loadFunction": "LoadToNative", + "dxgiFormat": "DXGI_FORMAT_R8_SINT", + "requiresConversion": "false" + } + ] + }, + "GL_RGB8_SNORM": { + "GL_BYTE": [ + { + "loadFunction": "LoadToNative3To4", + "dxgiFormat": "DXGI_FORMAT_R8G8B8A8_SNORM", + "requiresConversion": "true" + } + ] + }, + "GL_RG32F": { + "GL_FLOAT": [ + { + "loadFunction": "LoadToNative", + "dxgiFormat": "DXGI_FORMAT_R32G32_FLOAT", + "requiresConversion": "false" + } + ] + }, + "GL_DEPTH_COMPONENT32F": { + "GL_FLOAT": [ + { + "loadFunction": "LoadToNative", + "dxgiFormat": "DXGI_FORMAT_R32_TYPELESS", + "requiresConversion": "false" + }, + { + "loadFunction": "UnimplementedLoadFunction", + "dxgiFormat": "DXGI_FORMAT_UNKNOWN", + "requiresConversion": "true" + } + ] + }, + "GL_RG32I": { + "GL_INT": [ + { + "loadFunction": "LoadToNative", + "dxgiFormat": "DXGI_FORMAT_R32G32_SINT", + "requiresConversion": "false" + } + ] + }, + "GL_ALPHA8_EXT": { + "GL_UNSIGNED_BYTE": [ + { + "loadFunction": "LoadToNative", + "dxgiFormat": "DXGI_FORMAT_A8_UNORM", + "requiresConversion": "false" + }, + { + "loadFunction": "LoadA8ToRGBA8", + "dxgiFormat": "DXGI_FORMAT_R8G8B8A8_UNORM", + "requiresConversion": "true" + } + ] + }, + "GL_RG32UI": { + "GL_UNSIGNED_INT": [ + { + "loadFunction": "LoadToNative", + "dxgiFormat": "DXGI_FORMAT_R32G32_UINT", + "requiresConversion": "false" + } + ] + }, + "GL_RGBA16UI": { + "GL_UNSIGNED_SHORT": [ + { + "loadFunction": "LoadToNative", + "dxgiFormat": "DXGI_FORMAT_R16G16B16A16_UINT", + "requiresConversion": "false" + } + ] + }, + "GL_COMPRESSED_RGBA8_ETC2_EAC": { + "GL_UNSIGNED_BYTE": [ + { + "loadFunction": "LoadETC2RGBA8ToRGBA8", + "dxgiFormat": "DXGI_FORMAT_R8G8B8A8_UNORM", + "requiresConversion": "true" + } + ] + }, + "GL_RGB8I": { + "GL_BYTE": [ + { + "loadFunction": "LoadToNative3To4", + "dxgiFormat": "DXGI_FORMAT_R8G8B8A8_SINT", + "requiresConversion": "true" + } + ] + }, + "GL_COMPRESSED_SRGB8_ETC2": { + "GL_UNSIGNED_BYTE": [ + { + "loadFunction": "LoadETC2SRGB8ToRGBA8", + "dxgiFormat": "DXGI_FORMAT_R8G8B8A8_UNORM_SRGB", + "requiresConversion": "true" + } + ] + }, + "GL_DEPTH32F_STENCIL8": { + "GL_FLOAT_32_UNSIGNED_INT_24_8_REV": [ + { + "loadFunction": "LoadToNative", + "dxgiFormat": "DXGI_FORMAT_R32G8X24_TYPELESS", + "requiresConversion": "false" + }, + { + "loadFunction": "UnimplementedLoadFunction", + "dxgiFormat": "DXGI_FORMAT_UNKNOWN", + "requiresConversion": "true" + } + ] + }, + "GL_RG8I": { + "GL_BYTE": [ + { + "loadFunction": "LoadToNative", + "dxgiFormat": "DXGI_FORMAT_R8G8_SINT", + "requiresConversion": "false" + } + ] + }, + "GL_R32UI": { + "GL_UNSIGNED_INT": [ + { + "loadFunction": "LoadToNative", + "dxgiFormat": "DXGI_FORMAT_R32_UINT", + "requiresConversion": "false" + } + ] + }, + "GL_BGR5_A1_ANGLEX": { + "GL_UNSIGNED_BYTE": [ + { + "loadFunction": "LoadToNative", + "dxgiFormat": "DXGI_FORMAT_UNKNOWN", + "requiresConversion": "false" + } + ], + "GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT": [ + { + "loadFunction": "LoadRGB5A1ToRGBA8", + "dxgiFormat": "DXGI_FORMAT_UNKNOWN", + "requiresConversion": "true" + } + ] + }, + "GL_COMPRESSED_RG11_EAC": { + "GL_UNSIGNED_BYTE": [ + { + "loadFunction": "LoadEACRG11ToRG8", + "dxgiFormat": "DXGI_FORMAT_R8G8_UNORM", + "requiresConversion": "true" + } + ] + }, + "GL_SRGB8_ALPHA8": { + "GL_UNSIGNED_BYTE": [ + { + "loadFunction": "LoadToNative", + "dxgiFormat": "DXGI_FORMAT_R8G8B8A8_UNORM_SRGB", + "requiresConversion": "false" + } + ] + }, + "GL_LUMINANCE_ALPHA16F_EXT": { + "GL_HALF_FLOAT": [ + { + "loadFunction": "LoadLA16FToRGBA16F", + "dxgiFormat": "DXGI_FORMAT_UNKNOWN", + "requiresConversion": "true" + } + ], + "GL_HALF_FLOAT_OES": [ + { + "loadFunction": "LoadLA16FToRGBA16F", + "dxgiFormat": "DXGI_FORMAT_UNKNOWN", + "requiresConversion": "true" + } + ] + }, + "GL_RGBA": { + "GL_UNSIGNED_BYTE": [ + { + "loadFunction": "UnreachableLoadFunction", + "dxgiFormat": "DXGI_FORMAT_UNKNOWN", + "requiresConversion": "true" + } + ], + "GL_UNSIGNED_SHORT_4_4_4_4": [ + { + "loadFunction": "UnreachableLoadFunction", + "dxgiFormat": "DXGI_FORMAT_UNKNOWN", + "requiresConversion": "true" + } + ], + "GL_UNSIGNED_SHORT_5_5_5_1": [ + { + "loadFunction": "UnreachableLoadFunction", + "dxgiFormat": "DXGI_FORMAT_UNKNOWN", + "requiresConversion": "true" + } + ] + }, + "GL_DEPTH24_STENCIL8": { + "GL_UNSIGNED_INT_24_8": [ + { + "loadFunction": "LoadR32ToR24G8", + "dxgiFormat": "DXGI_FORMAT_R24G8_TYPELESS", + "requiresConversion": "true" + }, + { + "loadFunction": "LoadR32ToR24G8", + "dxgiFormat": "DXGI_FORMAT_D24_UNORM_S8_UINT", + "requiresConversion": "true" + } + ] + }, + "GL_RGB16I": { + "GL_SHORT": [ + { + "loadFunction": "LoadToNative3To4", + "dxgiFormat": "DXGI_FORMAT_R16G16B16A16_SINT", + "requiresConversion": "true" + } + ] + }, + "GL_R8UI": { + "GL_UNSIGNED_BYTE": [ + { + "loadFunction": "LoadToNative", + "dxgiFormat": "DXGI_FORMAT_R8_UINT", + "requiresConversion": "false" + } + ] + }, + "GL_ALPHA": { + "GL_HALF_FLOAT": [ + { + "loadFunction": "LoadA16FToRGBA16F", + "dxgiFormat": "DXGI_FORMAT_R16G16B16A16_FLOAT", + "requiresConversion": "true" + } + ], + "GL_UNSIGNED_BYTE": [ + { + "loadFunction": "UnreachableLoadFunction", + "dxgiFormat": "DXGI_FORMAT_UNKNOWN", + "requiresConversion": "true" + } + ], + "GL_FLOAT": [ + { + "loadFunction": "LoadA32FToRGBA32F", + "dxgiFormat": "DXGI_FORMAT_R32G32B32A32_FLOAT", + "requiresConversion": "true" + } + ], + "GL_HALF_FLOAT_OES": [ + { + "loadFunction": "LoadA16FToRGBA16F", + "dxgiFormat": "DXGI_FORMAT_R16G16B16A16_FLOAT", + "requiresConversion": "true" + } + ] + }, + "GL_RGB16F": { + "GL_HALF_FLOAT": [ + { + "loadFunction": "LoadToNative3To4", + "dxgiFormat": "DXGI_FORMAT_R16G16B16A16_FLOAT", + "requiresConversion": "true" + } + ], + "GL_FLOAT": [ + { + "loadFunction": "LoadRGB32FToRGBA16F", + "dxgiFormat": "DXGI_FORMAT_R16G16B16A16_FLOAT", + "requiresConversion": "true" + } + ], + "GL_HALF_FLOAT_OES": [ + { + "loadFunction": "LoadToNative3To4", + "dxgiFormat": "DXGI_FORMAT_R16G16B16A16_FLOAT", + "requiresConversion": "true" + } + ] + }, + "GL_COMPRESSED_SIGNED_R11_EAC": { + "GL_UNSIGNED_BYTE": [ + { + "loadFunction": "LoadEACR11SToR8", + "dxgiFormat": "DXGI_FORMAT_R8_SNORM", + "requiresConversion": "true" + } + ] + }, + "GL_COMPRESSED_RGB_S3TC_DXT1_EXT": { + "GL_UNSIGNED_BYTE": [ + { + "loadFunction": "LoadCompressedToNative<4,4,8>", + "dxgiFormat": "DXGI_FORMAT_UNKNOWN", + "requiresConversion": "true" + } + ] + }, + "GL_COMPRESSED_RGBA_S3TC_DXT1_EXT": { + "GL_UNSIGNED_BYTE": [ + { + "loadFunction": "LoadCompressedToNative<4,4,8>", + "dxgiFormat": "DXGI_FORMAT_UNKNOWN", + "requiresConversion": "true" + } + ] + }, + "GL_STENCIL_INDEX8": { + "DXGI_FORMAT_R24G8_TYPELESS": [ + { + "loadFunction": "UnimplementedLoadFunction", + "dxgiFormat": "DXGI_FORMAT_UNKNOWN", + "requiresConversion": "true" + } + ], + "DXGI_FORMAT_D24_UNORM_S8_UINT": [ + { + "loadFunction": "UnimplementedLoadFunction", + "dxgiFormat": "DXGI_FORMAT_UNKNOWN", + "requiresConversion": "true" + } + ] + }, + "GL_LUMINANCE_ALPHA32F_EXT": { + "GL_FLOAT": [ + { + "loadFunction": "LoadLA32FToRGBA32F", + "dxgiFormat": "DXGI_FORMAT_UNKNOWN", + "requiresConversion": "true" + } + ] + }, + "GL_RGB8UI": { + "GL_UNSIGNED_BYTE": [ + { + "loadFunction": "LoadToNative3To4", + "dxgiFormat": "DXGI_FORMAT_R8G8B8A8_UINT", + "requiresConversion": "true" + } + ] + }, + "GL_DEPTH_COMPONENT24": { + "GL_UNSIGNED_INT": [ + { + "loadFunction": "LoadR32ToR24G8", + "dxgiFormat": "DXGI_FORMAT_R24G8_TYPELESS", + "requiresConversion": "true" + }, + { + "loadFunction": "LoadR32ToR24G8", + "dxgiFormat": "DXGI_FORMAT_D24_UNORM_S8_UINT", + "requiresConversion": "true" + } + ] + }, + "GL_R32I": { + "GL_INT": [ + { + "loadFunction": "LoadToNative", + "dxgiFormat": "DXGI_FORMAT_R32_SINT", + "requiresConversion": "false" + } + ] + }, + "GL_DEPTH_COMPONENT32_OES": { + "GL_UNSIGNED_INT": [ + { + "loadFunction": "LoadR32ToR24G8", + "dxgiFormat": "DXGI_FORMAT_UNKNOWN", + "requiresConversion": "true" + } + ] + }, + "GL_R32F": { + "GL_FLOAT": [ + { + "loadFunction": "LoadToNative", + "dxgiFormat": "DXGI_FORMAT_R32_FLOAT", + "requiresConversion": "false" + } + ] + }, + "GL_RG16F": { + "GL_HALF_FLOAT": [ + { + "loadFunction": "LoadToNative", + "dxgiFormat": "DXGI_FORMAT_R16G16_FLOAT", + "requiresConversion": "false" + } + ], + "GL_FLOAT": [ + { + "loadFunction": "Load32FTo16F<2>", + "dxgiFormat": "DXGI_FORMAT_R16G16_FLOAT", + "requiresConversion": "true" + } + ], + "GL_HALF_FLOAT_OES": [ + { + "loadFunction": "LoadToNative", + "dxgiFormat": "DXGI_FORMAT_R16G16_FLOAT", + "requiresConversion": "false" + } + ] + }, + "GL_RGB565": { + "GL_UNSIGNED_BYTE": [ + { + "loadFunction": "LoadToNative3To4", + "dxgiFormat": "DXGI_FORMAT_R8G8B8A8_UNORM", + "requiresConversion": "true" + } + ], + "GL_UNSIGNED_SHORT_5_6_5": [ + { + "loadFunction": "LoadR5G6B5ToRGBA8", + "dxgiFormat": "DXGI_FORMAT_R8G8B8A8_UNORM", + "requiresConversion": "true" + }, + { + "loadFunction": "LoadToNative", + "dxgiFormat": "DXGI_FORMAT_B5G6R5_UNORM", + "requiresConversion": "false" + } + ] + }, + "GL_LUMINANCE16F_EXT": { + "GL_HALF_FLOAT": [ + { + "loadFunction": "LoadL16FToRGBA16F", + "dxgiFormat": "DXGI_FORMAT_UNKNOWN", + "requiresConversion": "true" + } + ], + "GL_HALF_FLOAT_OES": [ + { + "loadFunction": "LoadL16FToRGBA16F", + "dxgiFormat": "DXGI_FORMAT_UNKNOWN", + "requiresConversion": "true" + } + ] + }, + "GL_RG16UI": { + "GL_UNSIGNED_SHORT": [ + { + "loadFunction": "LoadToNative", + "dxgiFormat": "DXGI_FORMAT_R16G16_UINT", + "requiresConversion": "false" + } + ] + }, + "GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE": { + "GL_UNSIGNED_BYTE": [ + { + "loadFunction": "LoadCompressedToNative<4,4,16>", + "dxgiFormat": "DXGI_FORMAT_UNKNOWN", + "requiresConversion": "true" + } + ] + }, + "GL_RG16I": { + "GL_SHORT": [ + { + "loadFunction": "LoadToNative", + "dxgiFormat": "DXGI_FORMAT_R16G16_SINT", + "requiresConversion": "false" + } + ] + }, + "GL_BGRA8_EXT": { + "GL_UNSIGNED_BYTE": [ + { + "loadFunction": "LoadToNative", + "dxgiFormat": "DXGI_FORMAT_UNKNOWN", + "requiresConversion": "false" + } + ] + }, + "GL_ALPHA16F_EXT": { + "GL_HALF_FLOAT": [ + { + "loadFunction": "LoadA16FToRGBA16F", + "dxgiFormat": "DXGI_FORMAT_UNKNOWN", + "requiresConversion": "true" + } + ], + "GL_HALF_FLOAT_OES": [ + { + "loadFunction": "LoadA16FToRGBA16F", + "dxgiFormat": "DXGI_FORMAT_UNKNOWN", + "requiresConversion": "true" + } + ] + }, + "GL_RGBA4": { + "GL_UNSIGNED_BYTE": [ + { + "loadFunction": "LoadToNative", + "dxgiFormat": "DXGI_FORMAT_R8G8B8A8_UNORM", + "requiresConversion": "false" + } + ], + "GL_UNSIGNED_SHORT_4_4_4_4": [ + { + "loadFunction": "LoadRGBA4ToRGBA8", + "dxgiFormat": "DXGI_FORMAT_R8G8B8A8_UNORM", + "requiresConversion": "true" + }, + { + "loadFunction": "LoadRGBA4ToARGB4", + "dxgiFormat": "DXGI_FORMAT_B4G4R4A4_UNORM", + "requiresConversion": "true" + } + ] + }, + "GL_RGBA8": { + "GL_UNSIGNED_BYTE": [ + { + "loadFunction": "LoadToNative", + "dxgiFormat": "DXGI_FORMAT_R8G8B8A8_UNORM", + "requiresConversion": "false" + } + ] + }, + "GL_LUMINANCE": { + "GL_HALF_FLOAT": [ + { + "loadFunction": "LoadL16FToRGBA16F", + "dxgiFormat": "DXGI_FORMAT_R16G16B16A16_FLOAT", + "requiresConversion": "true" + } + ], + "GL_UNSIGNED_BYTE": [ + { + "loadFunction": "UnreachableLoadFunction", + "dxgiFormat": "DXGI_FORMAT_UNKNOWN", + "requiresConversion": "true" + } + ], + "GL_FLOAT": [ + { + "loadFunction": "LoadL32FToRGBA32F", + "dxgiFormat": "DXGI_FORMAT_R32G32B32A32_FLOAT", + "requiresConversion": "true" + } + ], + "GL_HALF_FLOAT_OES": [ + { + "loadFunction": "LoadL16FToRGBA16F", + "dxgiFormat": "DXGI_FORMAT_R16G16B16A16_FLOAT", + "requiresConversion": "true" + } + ] + }, + "GL_RGB10_A2UI": { + "GL_UNSIGNED_INT_2_10_10_10_REV": [ + { + "loadFunction": "LoadToNative", + "dxgiFormat": "DXGI_FORMAT_R10G10B10A2_UINT", + "requiresConversion": "false" + } + ] + }, + "GL_ETC1_RGB8_OES": { + "GL_UNSIGNED_BYTE": [ + { + "loadFunction": "LoadETC1RGB8ToRGBA8", + "dxgiFormat": "DXGI_FORMAT_R8G8B8A8_UNORM", + "requiresConversion": "true" + } + ] + }, + "GL_ETC1_RGB8_LOSSY_DECODE_ANGLE": { + "GL_UNSIGNED_BYTE": [ + { + "loadFunction": "LoadETC1RGB8ToBC1", + "dxgiFormat": "DXGI_FORMAT_BC1_UNORM", + "requiresConversion": "true" + } + ] + } +} \ No newline at end of file diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/load_functions_table.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/load_functions_table.h new file mode 100644 index 000000000000..b17062f68ddd --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/load_functions_table.h @@ -0,0 +1,31 @@ +// +// 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 dxgi format +// + +#ifndef LIBANGLE_RENDERER_D3D_D3D11_LOADFUNCTIONSTABLE_H_ +#define LIBANGLE_RENDERER_D3D_D3D11_LOADFUNCTIONSTABLE_H_ + +#include + +#include "libANGLE/renderer/d3d/d3d11/Renderer11.h" +#include "libANGLE/renderer/d3d/d3d11/texture_format_table.h" + +namespace rx +{ + +namespace d3d11 +{ + +const std::map &GetLoadFunctionsMap(GLenum internalFormat, + DXGI_FORMAT dxgiFormat); + +} // namespace d3d11 + +} // namespace rx + +#endif // LIBANGLE_RENDERER_D3D_D3D11_LOADFUNCTIONSTABLE_H_ diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/load_functions_table_autogen.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/load_functions_table_autogen.cpp new file mode 100644 index 000000000000..acb48b9573d9 --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/load_functions_table_autogen.cpp @@ -0,0 +1,2098 @@ +// GENERATED FILE - DO NOT EDIT. +// Generated by gen_load_functions_table.py using data from load_functions_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. +// +// load_functions_table: +// Contains the GetLoadFunctionsMap for texture_format_util.h +// + +#include "libANGLE/renderer/d3d/d3d11/load_functions_table.h" +#include "libANGLE/renderer/d3d/d3d11/formatutils11.h" +#include "libANGLE/renderer/d3d/d3d11/texture_format_table.h" +#include "libANGLE/renderer/d3d/loadimage.h" +#include "libANGLE/renderer/d3d/loadimage_etc.h" + +namespace rx +{ + +namespace d3d11 +{ + +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(); +} + +} // namespace + +// TODO we can replace these maps with more generated code +const std::map &GetLoadFunctionsMap(GLenum internalFormat, + DXGI_FORMAT dxgiFormat) +{ + // clang-format off + switch (internalFormat) + { + case GL_ALPHA: + { + switch (dxgiFormat) + { + case DXGI_FORMAT_R16G16B16A16_FLOAT: + { + static const std::map loadFunctionsMap = []() { + std::map loadMap; + loadMap[GL_HALF_FLOAT] = LoadImageFunctionInfo(LoadA16FToRGBA16F, true); + loadMap[GL_HALF_FLOAT_OES] = LoadImageFunctionInfo(LoadA16FToRGBA16F, true); + loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(UnreachableLoadFunction, true); + return loadMap; + }(); + + return loadFunctionsMap; + } + case DXGI_FORMAT_R32G32B32A32_FLOAT: + { + static const std::map loadFunctionsMap = []() { + std::map loadMap; + loadMap[GL_FLOAT] = LoadImageFunctionInfo(LoadA32FToRGBA32F, true); + loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(UnreachableLoadFunction, true); + return loadMap; + }(); + + return loadFunctionsMap; + } + case DXGI_FORMAT_UNKNOWN: + { + static const std::map loadFunctionsMap = []() { + std::map loadMap; + loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(UnreachableLoadFunction, true); + return loadMap; + }(); + + return loadFunctionsMap; + } + default: + { + static const std::map loadFunctionsMap = []() { + std::map loadMap; + loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(UnreachableLoadFunction, true); + return loadMap; + }(); + + return loadFunctionsMap; + } + } + } + case GL_ALPHA16F_EXT: + { + switch (dxgiFormat) + { + case DXGI_FORMAT_UNKNOWN: + { + static const std::map loadFunctionsMap = []() { + std::map loadMap; + loadMap[GL_HALF_FLOAT] = LoadImageFunctionInfo(LoadA16FToRGBA16F, true); + loadMap[GL_HALF_FLOAT_OES] = LoadImageFunctionInfo(LoadA16FToRGBA16F, true); + return loadMap; + }(); + + return loadFunctionsMap; + } + default: + { + static const std::map loadFunctionsMap = []() { + std::map loadMap; + loadMap[GL_HALF_FLOAT] = LoadImageFunctionInfo(LoadA16FToRGBA16F, true); + loadMap[GL_HALF_FLOAT_OES] = LoadImageFunctionInfo(LoadA16FToRGBA16F, true); + return loadMap; + }(); + + return loadFunctionsMap; + } + } + } + case GL_ALPHA32F_EXT: + { + switch (dxgiFormat) + { + case DXGI_FORMAT_UNKNOWN: + { + static const std::map loadFunctionsMap = []() { + std::map loadMap; + loadMap[GL_FLOAT] = LoadImageFunctionInfo(LoadA32FToRGBA32F, true); + return loadMap; + }(); + + return loadFunctionsMap; + } + default: + { + static const std::map loadFunctionsMap = []() { + std::map loadMap; + loadMap[GL_FLOAT] = LoadImageFunctionInfo(LoadA32FToRGBA32F, true); + return loadMap; + }(); + + return loadFunctionsMap; + } + } + } + case GL_ALPHA8_EXT: + { + switch (dxgiFormat) + { + case DXGI_FORMAT_A8_UNORM: + { + static const std::map loadFunctionsMap = []() { + std::map loadMap; + loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(LoadToNative, false); + return loadMap; + }(); + + return loadFunctionsMap; + } + case DXGI_FORMAT_R8G8B8A8_UNORM: + { + static const std::map loadFunctionsMap = []() { + std::map loadMap; + loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(LoadA8ToRGBA8, true); + return loadMap; + }(); + + return loadFunctionsMap; + } + default: + break; + } + } + case GL_BGR5_A1_ANGLEX: + { + switch (dxgiFormat) + { + case DXGI_FORMAT_UNKNOWN: + { + static const std::map loadFunctionsMap = []() { + std::map loadMap; + loadMap[GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT] = LoadImageFunctionInfo(LoadRGB5A1ToRGBA8, true); + loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(LoadToNative, false); + return loadMap; + }(); + + return loadFunctionsMap; + } + default: + { + static const std::map loadFunctionsMap = []() { + std::map loadMap; + loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(LoadToNative, true); + loadMap[GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT] = LoadImageFunctionInfo(LoadRGB5A1ToRGBA8, true); + return loadMap; + }(); + + return loadFunctionsMap; + } + } + } + case GL_BGRA4_ANGLEX: + { + switch (dxgiFormat) + { + case DXGI_FORMAT_UNKNOWN: + { + static const std::map loadFunctionsMap = []() { + std::map loadMap; + loadMap[GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT] = LoadImageFunctionInfo(LoadRGBA4ToRGBA8, true); + loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(LoadToNative, false); + return loadMap; + }(); + + return loadFunctionsMap; + } + default: + { + static const std::map loadFunctionsMap = []() { + std::map loadMap; + loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(LoadToNative, true); + loadMap[GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT] = LoadImageFunctionInfo(LoadRGBA4ToRGBA8, true); + return loadMap; + }(); + + return loadFunctionsMap; + } + } + } + case GL_BGRA8_EXT: + { + switch (dxgiFormat) + { + case DXGI_FORMAT_UNKNOWN: + { + static const std::map loadFunctionsMap = []() { + std::map loadMap; + loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(LoadToNative, false); + return loadMap; + }(); + + return loadFunctionsMap; + } + default: + { + static const std::map loadFunctionsMap = []() { + std::map loadMap; + loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(LoadToNative, true); + return loadMap; + }(); + + return loadFunctionsMap; + } + } + } + case GL_BGRA_EXT: + { + switch (dxgiFormat) + { + case DXGI_FORMAT_UNKNOWN: + { + static const std::map loadFunctionsMap = []() { + std::map loadMap; + loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(UnreachableLoadFunction, true); + return loadMap; + }(); + + return loadFunctionsMap; + } + default: + { + static const std::map loadFunctionsMap = []() { + std::map loadMap; + loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(UnreachableLoadFunction, true); + return loadMap; + }(); + + return loadFunctionsMap; + } + } + } + case GL_COMPRESSED_R11_EAC: + { + switch (dxgiFormat) + { + case DXGI_FORMAT_R8_UNORM: + { + static const std::map loadFunctionsMap = []() { + std::map loadMap; + loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(LoadEACR11ToR8, true); + return loadMap; + }(); + + return loadFunctionsMap; + } + default: + break; + } + } + case GL_COMPRESSED_RG11_EAC: + { + switch (dxgiFormat) + { + case DXGI_FORMAT_R8G8_UNORM: + { + static const std::map loadFunctionsMap = []() { + std::map loadMap; + loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(LoadEACRG11ToRG8, true); + return loadMap; + }(); + + return loadFunctionsMap; + } + default: + break; + } + } + case GL_COMPRESSED_RGB8_ETC2: + { + switch (dxgiFormat) + { + case DXGI_FORMAT_R8G8B8A8_UNORM: + { + static const std::map loadFunctionsMap = []() { + std::map loadMap; + loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(LoadETC2RGB8ToRGBA8, true); + return loadMap; + }(); + + return loadFunctionsMap; + } + default: + break; + } + } + case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2: + { + switch (dxgiFormat) + { + case DXGI_FORMAT_R8G8B8A8_UNORM: + { + static const std::map loadFunctionsMap = []() { + std::map loadMap; + loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(LoadETC2RGB8A1ToRGBA8, true); + return loadMap; + }(); + + return loadFunctionsMap; + } + default: + break; + } + } + case GL_COMPRESSED_RGBA8_ETC2_EAC: + { + switch (dxgiFormat) + { + case DXGI_FORMAT_R8G8B8A8_UNORM: + { + static const std::map loadFunctionsMap = []() { + std::map loadMap; + loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(LoadETC2RGBA8ToRGBA8, true); + return loadMap; + }(); + + return loadFunctionsMap; + } + default: + break; + } + } + case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: + { + switch (dxgiFormat) + { + case DXGI_FORMAT_UNKNOWN: + { + static const std::map loadFunctionsMap = []() { + std::map loadMap; + loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(LoadCompressedToNative<4,4,8>, true); + return loadMap; + }(); + + return loadFunctionsMap; + } + default: + { + static const std::map loadFunctionsMap = []() { + std::map loadMap; + loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(LoadCompressedToNative<4,4,8>, true); + return loadMap; + }(); + + return loadFunctionsMap; + } + } + } + case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE: + { + switch (dxgiFormat) + { + case DXGI_FORMAT_UNKNOWN: + { + static const std::map loadFunctionsMap = []() { + std::map loadMap; + loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(LoadCompressedToNative<4,4,16>, true); + return loadMap; + }(); + + return loadFunctionsMap; + } + default: + { + static const std::map loadFunctionsMap = []() { + std::map loadMap; + loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(LoadCompressedToNative<4,4,16>, true); + return loadMap; + }(); + + return loadFunctionsMap; + } + } + } + case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE: + { + switch (dxgiFormat) + { + case DXGI_FORMAT_UNKNOWN: + { + static const std::map loadFunctionsMap = []() { + std::map loadMap; + loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(LoadCompressedToNative<4,4,16>, true); + return loadMap; + }(); + + return loadFunctionsMap; + } + default: + { + static const std::map loadFunctionsMap = []() { + std::map loadMap; + loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(LoadCompressedToNative<4,4,16>, true); + return loadMap; + }(); + + return loadFunctionsMap; + } + } + } + case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: + { + switch (dxgiFormat) + { + case DXGI_FORMAT_UNKNOWN: + { + static const std::map loadFunctionsMap = []() { + std::map loadMap; + loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(LoadCompressedToNative<4,4,8>, true); + return loadMap; + }(); + + return loadFunctionsMap; + } + default: + { + static const std::map loadFunctionsMap = []() { + std::map loadMap; + loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(LoadCompressedToNative<4,4,8>, true); + return loadMap; + }(); + + return loadFunctionsMap; + } + } + } + case GL_COMPRESSED_SIGNED_R11_EAC: + { + switch (dxgiFormat) + { + case DXGI_FORMAT_R8_SNORM: + { + static const std::map loadFunctionsMap = []() { + std::map loadMap; + loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(LoadEACR11SToR8, true); + return loadMap; + }(); + + return loadFunctionsMap; + } + default: + break; + } + } + case GL_COMPRESSED_SIGNED_RG11_EAC: + { + switch (dxgiFormat) + { + case DXGI_FORMAT_R8G8_SNORM: + { + static const std::map loadFunctionsMap = []() { + std::map loadMap; + loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(LoadEACRG11SToRG8, true); + return loadMap; + }(); + + return loadFunctionsMap; + } + default: + break; + } + } + case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC: + { + switch (dxgiFormat) + { + case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: + { + static const std::map loadFunctionsMap = []() { + std::map loadMap; + loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(LoadETC2SRGBA8ToSRGBA8, true); + return loadMap; + }(); + + return loadFunctionsMap; + } + default: + break; + } + } + case GL_COMPRESSED_SRGB8_ETC2: + { + switch (dxgiFormat) + { + case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: + { + static const std::map loadFunctionsMap = []() { + std::map loadMap; + loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(LoadETC2SRGB8ToRGBA8, true); + return loadMap; + }(); + + return loadFunctionsMap; + } + default: + break; + } + } + case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2: + { + switch (dxgiFormat) + { + case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: + { + static const std::map loadFunctionsMap = []() { + std::map loadMap; + loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(LoadETC2SRGB8A1ToRGBA8, true); + return loadMap; + }(); + + return loadFunctionsMap; + } + default: + break; + } + } + case GL_DEPTH24_STENCIL8: + { + switch (dxgiFormat) + { + case DXGI_FORMAT_D24_UNORM_S8_UINT: + { + static const std::map loadFunctionsMap = []() { + std::map loadMap; + loadMap[GL_UNSIGNED_INT_24_8] = LoadImageFunctionInfo(LoadR32ToR24G8, true); + return loadMap; + }(); + + return loadFunctionsMap; + } + case DXGI_FORMAT_R24G8_TYPELESS: + { + static const std::map loadFunctionsMap = []() { + std::map loadMap; + loadMap[GL_UNSIGNED_INT_24_8] = LoadImageFunctionInfo(LoadR32ToR24G8, true); + return loadMap; + }(); + + return loadFunctionsMap; + } + default: + break; + } + } + case GL_DEPTH32F_STENCIL8: + { + switch (dxgiFormat) + { + case DXGI_FORMAT_R32G8X24_TYPELESS: + { + static const std::map loadFunctionsMap = []() { + std::map loadMap; + loadMap[GL_FLOAT_32_UNSIGNED_INT_24_8_REV] = LoadImageFunctionInfo(LoadToNative, false); + return loadMap; + }(); + + return loadFunctionsMap; + } + case DXGI_FORMAT_UNKNOWN: + { + static const std::map loadFunctionsMap = []() { + std::map loadMap; + loadMap[GL_FLOAT_32_UNSIGNED_INT_24_8_REV] = LoadImageFunctionInfo(UnimplementedLoadFunction, true); + return loadMap; + }(); + + return loadFunctionsMap; + } + default: + { + static const std::map loadFunctionsMap = []() { + std::map loadMap; + loadMap[GL_FLOAT_32_UNSIGNED_INT_24_8_REV] = LoadImageFunctionInfo(UnimplementedLoadFunction, true); + return loadMap; + }(); + + return loadFunctionsMap; + } + } + } + case GL_DEPTH_COMPONENT16: + { + switch (dxgiFormat) + { + case DXGI_FORMAT_D16_UNORM: + { + static const std::map loadFunctionsMap = []() { + std::map loadMap; + loadMap[GL_UNSIGNED_SHORT] = LoadImageFunctionInfo(LoadToNative, false); + return loadMap; + }(); + + return loadFunctionsMap; + } + case DXGI_FORMAT_R16_TYPELESS: + { + static const std::map loadFunctionsMap = []() { + std::map loadMap; + loadMap[GL_UNSIGNED_INT] = LoadImageFunctionInfo(LoadR32ToR16, true); + loadMap[GL_UNSIGNED_SHORT] = LoadImageFunctionInfo(LoadToNative, false); + return loadMap; + }(); + + return loadFunctionsMap; + } + default: + break; + } + } + case GL_DEPTH_COMPONENT24: + { + switch (dxgiFormat) + { + case DXGI_FORMAT_D24_UNORM_S8_UINT: + { + static const std::map loadFunctionsMap = []() { + std::map loadMap; + loadMap[GL_UNSIGNED_INT] = LoadImageFunctionInfo(LoadR32ToR24G8, true); + return loadMap; + }(); + + return loadFunctionsMap; + } + case DXGI_FORMAT_R24G8_TYPELESS: + { + static const std::map loadFunctionsMap = []() { + std::map loadMap; + loadMap[GL_UNSIGNED_INT] = LoadImageFunctionInfo(LoadR32ToR24G8, true); + return loadMap; + }(); + + return loadFunctionsMap; + } + default: + break; + } + } + case GL_DEPTH_COMPONENT32F: + { + switch (dxgiFormat) + { + case DXGI_FORMAT_R32_TYPELESS: + { + static const std::map loadFunctionsMap = []() { + std::map loadMap; + loadMap[GL_FLOAT] = LoadImageFunctionInfo(LoadToNative, false); + return loadMap; + }(); + + return loadFunctionsMap; + } + case DXGI_FORMAT_UNKNOWN: + { + static const std::map loadFunctionsMap = []() { + std::map loadMap; + loadMap[GL_FLOAT] = LoadImageFunctionInfo(UnimplementedLoadFunction, true); + return loadMap; + }(); + + return loadFunctionsMap; + } + default: + { + static const std::map loadFunctionsMap = []() { + std::map loadMap; + loadMap[GL_FLOAT] = LoadImageFunctionInfo(UnimplementedLoadFunction, true); + return loadMap; + }(); + + return loadFunctionsMap; + } + } + } + case GL_DEPTH_COMPONENT32_OES: + { + switch (dxgiFormat) + { + case DXGI_FORMAT_UNKNOWN: + { + static const std::map loadFunctionsMap = []() { + std::map loadMap; + loadMap[GL_UNSIGNED_INT] = LoadImageFunctionInfo(LoadR32ToR24G8, true); + return loadMap; + }(); + + return loadFunctionsMap; + } + default: + { + static const std::map loadFunctionsMap = []() { + std::map loadMap; + loadMap[GL_UNSIGNED_INT] = LoadImageFunctionInfo(LoadR32ToR24G8, true); + return loadMap; + }(); + + return loadFunctionsMap; + } + } + } + case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE: + { + switch (dxgiFormat) + { + case DXGI_FORMAT_BC1_UNORM: + { + static const std::map loadFunctionsMap = []() { + std::map loadMap; + loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(LoadETC1RGB8ToBC1, true); + return loadMap; + }(); + + return loadFunctionsMap; + } + default: + break; + } + } + case GL_ETC1_RGB8_OES: + { + switch (dxgiFormat) + { + case DXGI_FORMAT_R8G8B8A8_UNORM: + { + static const std::map loadFunctionsMap = []() { + std::map loadMap; + loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(LoadETC1RGB8ToRGBA8, true); + return loadMap; + }(); + + return loadFunctionsMap; + } + default: + break; + } + } + case GL_LUMINANCE: + { + switch (dxgiFormat) + { + case DXGI_FORMAT_R16G16B16A16_FLOAT: + { + static const std::map loadFunctionsMap = []() { + std::map loadMap; + loadMap[GL_HALF_FLOAT] = LoadImageFunctionInfo(LoadL16FToRGBA16F, true); + loadMap[GL_HALF_FLOAT_OES] = LoadImageFunctionInfo(LoadL16FToRGBA16F, true); + loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(UnreachableLoadFunction, true); + return loadMap; + }(); + + return loadFunctionsMap; + } + case DXGI_FORMAT_R32G32B32A32_FLOAT: + { + static const std::map loadFunctionsMap = []() { + std::map loadMap; + loadMap[GL_FLOAT] = LoadImageFunctionInfo(LoadL32FToRGBA32F, true); + loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(UnreachableLoadFunction, true); + return loadMap; + }(); + + return loadFunctionsMap; + } + case DXGI_FORMAT_UNKNOWN: + { + static const std::map loadFunctionsMap = []() { + std::map loadMap; + loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(UnreachableLoadFunction, true); + return loadMap; + }(); + + return loadFunctionsMap; + } + default: + { + static const std::map loadFunctionsMap = []() { + std::map loadMap; + loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(UnreachableLoadFunction, true); + return loadMap; + }(); + + return loadFunctionsMap; + } + } + } + case GL_LUMINANCE16F_EXT: + { + switch (dxgiFormat) + { + case DXGI_FORMAT_UNKNOWN: + { + static const std::map loadFunctionsMap = []() { + std::map loadMap; + loadMap[GL_HALF_FLOAT] = LoadImageFunctionInfo(LoadL16FToRGBA16F, true); + loadMap[GL_HALF_FLOAT_OES] = LoadImageFunctionInfo(LoadL16FToRGBA16F, true); + return loadMap; + }(); + + return loadFunctionsMap; + } + default: + { + static const std::map loadFunctionsMap = []() { + std::map loadMap; + loadMap[GL_HALF_FLOAT] = LoadImageFunctionInfo(LoadL16FToRGBA16F, true); + loadMap[GL_HALF_FLOAT_OES] = LoadImageFunctionInfo(LoadL16FToRGBA16F, true); + return loadMap; + }(); + + return loadFunctionsMap; + } + } + } + case GL_LUMINANCE32F_EXT: + { + switch (dxgiFormat) + { + case DXGI_FORMAT_UNKNOWN: + { + static const std::map loadFunctionsMap = []() { + std::map loadMap; + loadMap[GL_FLOAT] = LoadImageFunctionInfo(LoadL32FToRGBA32F, true); + return loadMap; + }(); + + return loadFunctionsMap; + } + default: + { + static const std::map loadFunctionsMap = []() { + std::map loadMap; + loadMap[GL_FLOAT] = LoadImageFunctionInfo(LoadL32FToRGBA32F, true); + return loadMap; + }(); + + return loadFunctionsMap; + } + } + } + case GL_LUMINANCE8_ALPHA8_EXT: + { + switch (dxgiFormat) + { + case DXGI_FORMAT_UNKNOWN: + { + static const std::map loadFunctionsMap = []() { + std::map loadMap; + loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(LoadLA8ToRGBA8, true); + return loadMap; + }(); + + return loadFunctionsMap; + } + default: + { + static const std::map loadFunctionsMap = []() { + std::map loadMap; + loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(LoadLA8ToRGBA8, true); + return loadMap; + }(); + + return loadFunctionsMap; + } + } + } + case GL_LUMINANCE8_EXT: + { + switch (dxgiFormat) + { + case DXGI_FORMAT_UNKNOWN: + { + static const std::map loadFunctionsMap = []() { + std::map loadMap; + loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(LoadL8ToRGBA8, true); + return loadMap; + }(); + + return loadFunctionsMap; + } + default: + { + static const std::map loadFunctionsMap = []() { + std::map loadMap; + loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(LoadL8ToRGBA8, true); + return loadMap; + }(); + + return loadFunctionsMap; + } + } + } + case GL_LUMINANCE_ALPHA: + { + switch (dxgiFormat) + { + case DXGI_FORMAT_R16G16B16A16_FLOAT: + { + static const std::map loadFunctionsMap = []() { + std::map loadMap; + loadMap[GL_HALF_FLOAT] = LoadImageFunctionInfo(LoadLA16FToRGBA16F, true); + loadMap[GL_HALF_FLOAT_OES] = LoadImageFunctionInfo(LoadLA16FToRGBA16F, true); + loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(UnreachableLoadFunction, true); + return loadMap; + }(); + + return loadFunctionsMap; + } + case DXGI_FORMAT_R32G32B32A32_FLOAT: + { + static const std::map loadFunctionsMap = []() { + std::map loadMap; + loadMap[GL_FLOAT] = LoadImageFunctionInfo(LoadLA32FToRGBA32F, true); + loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(UnreachableLoadFunction, true); + return loadMap; + }(); + + return loadFunctionsMap; + } + case DXGI_FORMAT_UNKNOWN: + { + static const std::map loadFunctionsMap = []() { + std::map loadMap; + loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(UnreachableLoadFunction, true); + return loadMap; + }(); + + return loadFunctionsMap; + } + default: + { + static const std::map loadFunctionsMap = []() { + std::map loadMap; + loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(UnreachableLoadFunction, true); + return loadMap; + }(); + + return loadFunctionsMap; + } + } + } + case GL_LUMINANCE_ALPHA16F_EXT: + { + switch (dxgiFormat) + { + case DXGI_FORMAT_UNKNOWN: + { + static const std::map loadFunctionsMap = []() { + std::map loadMap; + loadMap[GL_HALF_FLOAT] = LoadImageFunctionInfo(LoadLA16FToRGBA16F, true); + loadMap[GL_HALF_FLOAT_OES] = LoadImageFunctionInfo(LoadLA16FToRGBA16F, true); + return loadMap; + }(); + + return loadFunctionsMap; + } + default: + { + static const std::map loadFunctionsMap = []() { + std::map loadMap; + loadMap[GL_HALF_FLOAT] = LoadImageFunctionInfo(LoadLA16FToRGBA16F, true); + loadMap[GL_HALF_FLOAT_OES] = LoadImageFunctionInfo(LoadLA16FToRGBA16F, true); + return loadMap; + }(); + + return loadFunctionsMap; + } + } + } + case GL_LUMINANCE_ALPHA32F_EXT: + { + switch (dxgiFormat) + { + case DXGI_FORMAT_UNKNOWN: + { + static const std::map loadFunctionsMap = []() { + std::map loadMap; + loadMap[GL_FLOAT] = LoadImageFunctionInfo(LoadLA32FToRGBA32F, true); + return loadMap; + }(); + + return loadFunctionsMap; + } + default: + { + static const std::map loadFunctionsMap = []() { + std::map loadMap; + loadMap[GL_FLOAT] = LoadImageFunctionInfo(LoadLA32FToRGBA32F, true); + return loadMap; + }(); + + return loadFunctionsMap; + } + } + } + case GL_R11F_G11F_B10F: + { + switch (dxgiFormat) + { + case DXGI_FORMAT_R11G11B10_FLOAT: + { + static const std::map loadFunctionsMap = []() { + std::map loadMap; + loadMap[GL_HALF_FLOAT] = LoadImageFunctionInfo(LoadRGB16FToRG11B10F, true); + loadMap[GL_HALF_FLOAT_OES] = LoadImageFunctionInfo(LoadRGB16FToRG11B10F, true); + loadMap[GL_FLOAT] = LoadImageFunctionInfo(LoadRGB32FToRG11B10F, true); + loadMap[GL_UNSIGNED_INT_10F_11F_11F_REV] = LoadImageFunctionInfo(LoadToNative, false); + return loadMap; + }(); + + return loadFunctionsMap; + } + default: + break; + } + } + case GL_R16F: + { + switch (dxgiFormat) + { + case DXGI_FORMAT_R16_FLOAT: + { + static const std::map loadFunctionsMap = []() { + std::map loadMap; + loadMap[GL_FLOAT] = LoadImageFunctionInfo(Load32FTo16F<1>, true); + loadMap[GL_HALF_FLOAT] = LoadImageFunctionInfo(LoadToNative, false); + loadMap[GL_HALF_FLOAT_OES] = LoadImageFunctionInfo(LoadToNative, false); + return loadMap; + }(); + + return loadFunctionsMap; + } + default: + break; + } + } + case GL_R16I: + { + switch (dxgiFormat) + { + case DXGI_FORMAT_R16_SINT: + { + static const std::map loadFunctionsMap = []() { + std::map loadMap; + loadMap[GL_SHORT] = LoadImageFunctionInfo(LoadToNative, false); + return loadMap; + }(); + + return loadFunctionsMap; + } + default: + break; + } + } + case GL_R16UI: + { + switch (dxgiFormat) + { + case DXGI_FORMAT_R16_UINT: + { + static const std::map loadFunctionsMap = []() { + std::map loadMap; + loadMap[GL_UNSIGNED_SHORT] = LoadImageFunctionInfo(LoadToNative, false); + return loadMap; + }(); + + return loadFunctionsMap; + } + default: + break; + } + } + case GL_R32F: + { + switch (dxgiFormat) + { + case DXGI_FORMAT_R32_FLOAT: + { + static const std::map loadFunctionsMap = []() { + std::map loadMap; + loadMap[GL_FLOAT] = LoadImageFunctionInfo(LoadToNative, false); + return loadMap; + }(); + + return loadFunctionsMap; + } + default: + break; + } + } + case GL_R32I: + { + switch (dxgiFormat) + { + case DXGI_FORMAT_R32_SINT: + { + static const std::map loadFunctionsMap = []() { + std::map loadMap; + loadMap[GL_INT] = LoadImageFunctionInfo(LoadToNative, false); + return loadMap; + }(); + + return loadFunctionsMap; + } + default: + break; + } + } + case GL_R32UI: + { + switch (dxgiFormat) + { + case DXGI_FORMAT_R32_UINT: + { + static const std::map loadFunctionsMap = []() { + std::map loadMap; + loadMap[GL_UNSIGNED_INT] = LoadImageFunctionInfo(LoadToNative, false); + return loadMap; + }(); + + return loadFunctionsMap; + } + default: + break; + } + } + case GL_R8: + { + switch (dxgiFormat) + { + case DXGI_FORMAT_R8_UNORM: + { + static const std::map loadFunctionsMap = []() { + std::map loadMap; + loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(LoadToNative, false); + return loadMap; + }(); + + return loadFunctionsMap; + } + default: + break; + } + } + case GL_R8I: + { + switch (dxgiFormat) + { + case DXGI_FORMAT_R8_SINT: + { + static const std::map loadFunctionsMap = []() { + std::map loadMap; + loadMap[GL_BYTE] = LoadImageFunctionInfo(LoadToNative, false); + return loadMap; + }(); + + return loadFunctionsMap; + } + default: + break; + } + } + case GL_R8UI: + { + switch (dxgiFormat) + { + case DXGI_FORMAT_R8_UINT: + { + static const std::map loadFunctionsMap = []() { + std::map loadMap; + loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(LoadToNative, false); + return loadMap; + }(); + + return loadFunctionsMap; + } + default: + break; + } + } + case GL_R8_SNORM: + { + switch (dxgiFormat) + { + case DXGI_FORMAT_R8_SNORM: + { + static const std::map loadFunctionsMap = []() { + std::map loadMap; + loadMap[GL_BYTE] = LoadImageFunctionInfo(LoadToNative, false); + return loadMap; + }(); + + return loadFunctionsMap; + } + default: + break; + } + } + case GL_RG16F: + { + switch (dxgiFormat) + { + case DXGI_FORMAT_R16G16_FLOAT: + { + static const std::map loadFunctionsMap = []() { + std::map loadMap; + loadMap[GL_FLOAT] = LoadImageFunctionInfo(Load32FTo16F<2>, true); + loadMap[GL_HALF_FLOAT] = LoadImageFunctionInfo(LoadToNative, false); + loadMap[GL_HALF_FLOAT_OES] = LoadImageFunctionInfo(LoadToNative, false); + return loadMap; + }(); + + return loadFunctionsMap; + } + default: + break; + } + } + case GL_RG16I: + { + switch (dxgiFormat) + { + case DXGI_FORMAT_R16G16_SINT: + { + static const std::map loadFunctionsMap = []() { + std::map loadMap; + loadMap[GL_SHORT] = LoadImageFunctionInfo(LoadToNative, false); + return loadMap; + }(); + + return loadFunctionsMap; + } + default: + break; + } + } + case GL_RG16UI: + { + switch (dxgiFormat) + { + case DXGI_FORMAT_R16G16_UINT: + { + static const std::map loadFunctionsMap = []() { + std::map loadMap; + loadMap[GL_UNSIGNED_SHORT] = LoadImageFunctionInfo(LoadToNative, false); + return loadMap; + }(); + + return loadFunctionsMap; + } + default: + break; + } + } + case GL_RG32F: + { + switch (dxgiFormat) + { + case DXGI_FORMAT_R32G32_FLOAT: + { + static const std::map loadFunctionsMap = []() { + std::map loadMap; + loadMap[GL_FLOAT] = LoadImageFunctionInfo(LoadToNative, false); + return loadMap; + }(); + + return loadFunctionsMap; + } + default: + break; + } + } + case GL_RG32I: + { + switch (dxgiFormat) + { + case DXGI_FORMAT_R32G32_SINT: + { + static const std::map loadFunctionsMap = []() { + std::map loadMap; + loadMap[GL_INT] = LoadImageFunctionInfo(LoadToNative, false); + return loadMap; + }(); + + return loadFunctionsMap; + } + default: + break; + } + } + case GL_RG32UI: + { + switch (dxgiFormat) + { + case DXGI_FORMAT_R32G32_UINT: + { + static const std::map loadFunctionsMap = []() { + std::map loadMap; + loadMap[GL_UNSIGNED_INT] = LoadImageFunctionInfo(LoadToNative, false); + return loadMap; + }(); + + return loadFunctionsMap; + } + default: + break; + } + } + case GL_RG8: + { + switch (dxgiFormat) + { + case DXGI_FORMAT_R8G8_UNORM: + { + static const std::map loadFunctionsMap = []() { + std::map loadMap; + loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(LoadToNative, false); + return loadMap; + }(); + + return loadFunctionsMap; + } + default: + break; + } + } + case GL_RG8I: + { + switch (dxgiFormat) + { + case DXGI_FORMAT_R8G8_SINT: + { + static const std::map loadFunctionsMap = []() { + std::map loadMap; + loadMap[GL_BYTE] = LoadImageFunctionInfo(LoadToNative, false); + return loadMap; + }(); + + return loadFunctionsMap; + } + default: + break; + } + } + case GL_RG8UI: + { + switch (dxgiFormat) + { + case DXGI_FORMAT_R8G8_UINT: + { + static const std::map loadFunctionsMap = []() { + std::map loadMap; + loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(LoadToNative, false); + return loadMap; + }(); + + return loadFunctionsMap; + } + default: + break; + } + } + case GL_RG8_SNORM: + { + switch (dxgiFormat) + { + case DXGI_FORMAT_R8G8_SNORM: + { + static const std::map loadFunctionsMap = []() { + std::map loadMap; + loadMap[GL_BYTE] = LoadImageFunctionInfo(LoadToNative, false); + return loadMap; + }(); + + return loadFunctionsMap; + } + default: + break; + } + } + case GL_RGB: + { + switch (dxgiFormat) + { + case DXGI_FORMAT_UNKNOWN: + { + static const std::map loadFunctionsMap = []() { + std::map loadMap; + loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(UnreachableLoadFunction, true); + loadMap[GL_UNSIGNED_SHORT_5_6_5] = LoadImageFunctionInfo(UnreachableLoadFunction, true); + return loadMap; + }(); + + return loadFunctionsMap; + } + default: + { + static const std::map loadFunctionsMap = []() { + std::map loadMap; + loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(UnreachableLoadFunction, true); + loadMap[GL_UNSIGNED_SHORT_5_6_5] = LoadImageFunctionInfo(UnreachableLoadFunction, true); + return loadMap; + }(); + + return loadFunctionsMap; + } + } + } + case GL_RGB10_A2: + { + switch (dxgiFormat) + { + case DXGI_FORMAT_R10G10B10A2_UNORM: + { + static const std::map loadFunctionsMap = []() { + std::map loadMap; + loadMap[GL_UNSIGNED_INT_2_10_10_10_REV] = LoadImageFunctionInfo(LoadToNative, false); + return loadMap; + }(); + + return loadFunctionsMap; + } + default: + break; + } + } + case GL_RGB10_A2UI: + { + switch (dxgiFormat) + { + case DXGI_FORMAT_R10G10B10A2_UINT: + { + static const std::map loadFunctionsMap = []() { + std::map loadMap; + loadMap[GL_UNSIGNED_INT_2_10_10_10_REV] = LoadImageFunctionInfo(LoadToNative, false); + return loadMap; + }(); + + return loadFunctionsMap; + } + default: + break; + } + } + case GL_RGB16F: + { + switch (dxgiFormat) + { + case DXGI_FORMAT_R16G16B16A16_FLOAT: + { + static const std::map loadFunctionsMap = []() { + std::map loadMap; + loadMap[GL_FLOAT] = LoadImageFunctionInfo(LoadRGB32FToRGBA16F, true); + loadMap[GL_HALF_FLOAT] = LoadImageFunctionInfo(LoadToNative3To4, true); + loadMap[GL_HALF_FLOAT_OES] = LoadImageFunctionInfo(LoadToNative3To4, true); + return loadMap; + }(); + + return loadFunctionsMap; + } + default: + break; + } + } + case GL_RGB16I: + { + switch (dxgiFormat) + { + case DXGI_FORMAT_R16G16B16A16_SINT: + { + static const std::map loadFunctionsMap = []() { + std::map loadMap; + loadMap[GL_SHORT] = LoadImageFunctionInfo(LoadToNative3To4, true); + return loadMap; + }(); + + return loadFunctionsMap; + } + default: + break; + } + } + case GL_RGB16UI: + { + switch (dxgiFormat) + { + case DXGI_FORMAT_R16G16B16A16_UINT: + { + static const std::map loadFunctionsMap = []() { + std::map loadMap; + loadMap[GL_UNSIGNED_SHORT] = LoadImageFunctionInfo(LoadToNative3To4, true); + return loadMap; + }(); + + return loadFunctionsMap; + } + default: + break; + } + } + case GL_RGB32F: + { + switch (dxgiFormat) + { + case DXGI_FORMAT_R32G32B32A32_FLOAT: + { + static const std::map loadFunctionsMap = []() { + std::map loadMap; + loadMap[GL_FLOAT] = LoadImageFunctionInfo(LoadToNative3To4, true); + return loadMap; + }(); + + return loadFunctionsMap; + } + default: + break; + } + } + case GL_RGB32I: + { + switch (dxgiFormat) + { + case DXGI_FORMAT_R32G32B32A32_SINT: + { + static const std::map loadFunctionsMap = []() { + std::map loadMap; + loadMap[GL_INT] = LoadImageFunctionInfo(LoadToNative3To4, true); + return loadMap; + }(); + + return loadFunctionsMap; + } + default: + break; + } + } + case GL_RGB32UI: + { + switch (dxgiFormat) + { + case DXGI_FORMAT_R32G32B32A32_UINT: + { + static const std::map loadFunctionsMap = []() { + std::map loadMap; + loadMap[GL_UNSIGNED_INT] = LoadImageFunctionInfo(LoadToNative3To4, true); + return loadMap; + }(); + + return loadFunctionsMap; + } + default: + break; + } + } + case GL_RGB565: + { + switch (dxgiFormat) + { + case DXGI_FORMAT_B5G6R5_UNORM: + { + static const std::map loadFunctionsMap = []() { + std::map loadMap; + loadMap[GL_UNSIGNED_SHORT_5_6_5] = LoadImageFunctionInfo(LoadToNative, false); + return loadMap; + }(); + + return loadFunctionsMap; + } + case DXGI_FORMAT_R8G8B8A8_UNORM: + { + static const std::map loadFunctionsMap = []() { + std::map loadMap; + loadMap[GL_UNSIGNED_SHORT_5_6_5] = LoadImageFunctionInfo(LoadR5G6B5ToRGBA8, true); + loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(LoadToNative3To4, true); + return loadMap; + }(); + + return loadFunctionsMap; + } + default: + break; + } + } + case GL_RGB5_A1: + { + switch (dxgiFormat) + { + case DXGI_FORMAT_B5G5R5A1_UNORM: + { + static const std::map loadFunctionsMap = []() { + std::map loadMap; + loadMap[GL_UNSIGNED_SHORT_5_5_5_1] = LoadImageFunctionInfo(LoadRGB5A1ToA1RGB5, true); + return loadMap; + }(); + + return loadFunctionsMap; + } + case DXGI_FORMAT_R8G8B8A8_UNORM: + { + static const std::map loadFunctionsMap = []() { + std::map loadMap; + loadMap[GL_UNSIGNED_INT_2_10_10_10_REV] = LoadImageFunctionInfo(LoadRGB10A2ToRGBA8, true); + loadMap[GL_UNSIGNED_SHORT_5_5_5_1] = LoadImageFunctionInfo(LoadRGB5A1ToRGBA8, true); + loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(LoadToNative, false); + return loadMap; + }(); + + return loadFunctionsMap; + } + default: + break; + } + } + case GL_RGB8: + { + switch (dxgiFormat) + { + case DXGI_FORMAT_R8G8B8A8_UNORM: + { + static const std::map loadFunctionsMap = []() { + std::map loadMap; + loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(LoadToNative3To4, true); + return loadMap; + }(); + + return loadFunctionsMap; + } + default: + break; + } + } + case GL_RGB8I: + { + switch (dxgiFormat) + { + case DXGI_FORMAT_R8G8B8A8_SINT: + { + static const std::map loadFunctionsMap = []() { + std::map loadMap; + loadMap[GL_BYTE] = LoadImageFunctionInfo(LoadToNative3To4, true); + return loadMap; + }(); + + return loadFunctionsMap; + } + default: + break; + } + } + case GL_RGB8UI: + { + switch (dxgiFormat) + { + case DXGI_FORMAT_R8G8B8A8_UINT: + { + static const std::map loadFunctionsMap = []() { + std::map loadMap; + loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(LoadToNative3To4, true); + return loadMap; + }(); + + return loadFunctionsMap; + } + default: + break; + } + } + case GL_RGB8_SNORM: + { + switch (dxgiFormat) + { + case DXGI_FORMAT_R8G8B8A8_SNORM: + { + static const std::map loadFunctionsMap = []() { + std::map loadMap; + loadMap[GL_BYTE] = LoadImageFunctionInfo(LoadToNative3To4, true); + return loadMap; + }(); + + return loadFunctionsMap; + } + default: + break; + } + } + case GL_RGB9_E5: + { + switch (dxgiFormat) + { + case DXGI_FORMAT_R9G9B9E5_SHAREDEXP: + { + static const std::map loadFunctionsMap = []() { + std::map loadMap; + loadMap[GL_HALF_FLOAT] = LoadImageFunctionInfo(LoadRGB16FToRGB9E5, true); + loadMap[GL_HALF_FLOAT_OES] = LoadImageFunctionInfo(LoadRGB16FToRGB9E5, true); + loadMap[GL_FLOAT] = LoadImageFunctionInfo(LoadRGB32FToRGB9E5, true); + loadMap[GL_UNSIGNED_INT_5_9_9_9_REV] = LoadImageFunctionInfo(LoadToNative, false); + return loadMap; + }(); + + return loadFunctionsMap; + } + default: + break; + } + } + case GL_RGBA: + { + switch (dxgiFormat) + { + case DXGI_FORMAT_UNKNOWN: + { + static const std::map loadFunctionsMap = []() { + std::map loadMap; + loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(UnreachableLoadFunction, true); + loadMap[GL_UNSIGNED_SHORT_4_4_4_4] = LoadImageFunctionInfo(UnreachableLoadFunction, true); + loadMap[GL_UNSIGNED_SHORT_5_5_5_1] = LoadImageFunctionInfo(UnreachableLoadFunction, true); + return loadMap; + }(); + + return loadFunctionsMap; + } + default: + { + static const std::map loadFunctionsMap = []() { + std::map loadMap; + loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(UnreachableLoadFunction, true); + loadMap[GL_UNSIGNED_SHORT_4_4_4_4] = LoadImageFunctionInfo(UnreachableLoadFunction, true); + loadMap[GL_UNSIGNED_SHORT_5_5_5_1] = LoadImageFunctionInfo(UnreachableLoadFunction, true); + return loadMap; + }(); + + return loadFunctionsMap; + } + } + } + case GL_RGBA16F: + { + switch (dxgiFormat) + { + case DXGI_FORMAT_R16G16B16A16_FLOAT: + { + static const std::map loadFunctionsMap = []() { + std::map loadMap; + loadMap[GL_FLOAT] = LoadImageFunctionInfo(Load32FTo16F<4>, true); + loadMap[GL_HALF_FLOAT] = LoadImageFunctionInfo(LoadToNative, false); + loadMap[GL_HALF_FLOAT_OES] = LoadImageFunctionInfo(LoadToNative, false); + return loadMap; + }(); + + return loadFunctionsMap; + } + default: + break; + } + } + case GL_RGBA16I: + { + switch (dxgiFormat) + { + case DXGI_FORMAT_R16G16B16A16_SINT: + { + static const std::map loadFunctionsMap = []() { + std::map loadMap; + loadMap[GL_SHORT] = LoadImageFunctionInfo(LoadToNative, false); + return loadMap; + }(); + + return loadFunctionsMap; + } + default: + break; + } + } + case GL_RGBA16UI: + { + switch (dxgiFormat) + { + case DXGI_FORMAT_R16G16B16A16_UINT: + { + static const std::map loadFunctionsMap = []() { + std::map loadMap; + loadMap[GL_UNSIGNED_SHORT] = LoadImageFunctionInfo(LoadToNative, false); + return loadMap; + }(); + + return loadFunctionsMap; + } + default: + break; + } + } + case GL_RGBA32F: + { + switch (dxgiFormat) + { + case DXGI_FORMAT_R32G32B32A32_FLOAT: + { + static const std::map loadFunctionsMap = []() { + std::map loadMap; + loadMap[GL_FLOAT] = LoadImageFunctionInfo(LoadToNative, false); + return loadMap; + }(); + + return loadFunctionsMap; + } + default: + break; + } + } + case GL_RGBA32I: + { + switch (dxgiFormat) + { + case DXGI_FORMAT_R32G32B32A32_SINT: + { + static const std::map loadFunctionsMap = []() { + std::map loadMap; + loadMap[GL_INT] = LoadImageFunctionInfo(LoadToNative, false); + return loadMap; + }(); + + return loadFunctionsMap; + } + default: + break; + } + } + case GL_RGBA32UI: + { + switch (dxgiFormat) + { + case DXGI_FORMAT_R32G32B32A32_UINT: + { + static const std::map loadFunctionsMap = []() { + std::map loadMap; + loadMap[GL_UNSIGNED_INT] = LoadImageFunctionInfo(LoadToNative, false); + return loadMap; + }(); + + return loadFunctionsMap; + } + default: + break; + } + } + case GL_RGBA4: + { + switch (dxgiFormat) + { + case DXGI_FORMAT_B4G4R4A4_UNORM: + { + static const std::map loadFunctionsMap = []() { + std::map loadMap; + loadMap[GL_UNSIGNED_SHORT_4_4_4_4] = LoadImageFunctionInfo(LoadRGBA4ToARGB4, true); + return loadMap; + }(); + + return loadFunctionsMap; + } + case DXGI_FORMAT_R8G8B8A8_UNORM: + { + static const std::map loadFunctionsMap = []() { + std::map loadMap; + loadMap[GL_UNSIGNED_SHORT_4_4_4_4] = LoadImageFunctionInfo(LoadRGBA4ToRGBA8, true); + loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(LoadToNative, false); + return loadMap; + }(); + + return loadFunctionsMap; + } + default: + break; + } + } + case GL_RGBA8: + { + switch (dxgiFormat) + { + case DXGI_FORMAT_R8G8B8A8_UNORM: + { + static const std::map loadFunctionsMap = []() { + std::map loadMap; + loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(LoadToNative, false); + return loadMap; + }(); + + return loadFunctionsMap; + } + default: + break; + } + } + case GL_RGBA8I: + { + switch (dxgiFormat) + { + case DXGI_FORMAT_R8G8B8A8_SINT: + { + static const std::map loadFunctionsMap = []() { + std::map loadMap; + loadMap[GL_BYTE] = LoadImageFunctionInfo(LoadToNative, false); + return loadMap; + }(); + + return loadFunctionsMap; + } + default: + break; + } + } + case GL_RGBA8UI: + { + switch (dxgiFormat) + { + case DXGI_FORMAT_R8G8B8A8_UINT: + { + static const std::map loadFunctionsMap = []() { + std::map loadMap; + loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(LoadToNative, false); + return loadMap; + }(); + + return loadFunctionsMap; + } + default: + break; + } + } + case GL_RGBA8_SNORM: + { + switch (dxgiFormat) + { + case DXGI_FORMAT_R8G8B8A8_SNORM: + { + static const std::map loadFunctionsMap = []() { + std::map loadMap; + loadMap[GL_BYTE] = LoadImageFunctionInfo(LoadToNative, false); + return loadMap; + }(); + + return loadFunctionsMap; + } + default: + break; + } + } + case GL_SRGB8: + { + switch (dxgiFormat) + { + case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: + { + static const std::map loadFunctionsMap = []() { + std::map loadMap; + loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(LoadToNative3To4, true); + return loadMap; + }(); + + return loadFunctionsMap; + } + default: + break; + } + } + case GL_SRGB8_ALPHA8: + { + switch (dxgiFormat) + { + case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: + { + static const std::map loadFunctionsMap = []() { + std::map loadMap; + loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(LoadToNative, false); + return loadMap; + }(); + + return loadFunctionsMap; + } + default: + break; + } + } + case GL_STENCIL_INDEX8: + { + switch (dxgiFormat) + { + case DXGI_FORMAT_UNKNOWN: + { + static const std::map loadFunctionsMap = []() { + std::map loadMap; + loadMap[DXGI_FORMAT_D24_UNORM_S8_UINT] = LoadImageFunctionInfo(UnimplementedLoadFunction, true); + loadMap[DXGI_FORMAT_R24G8_TYPELESS] = LoadImageFunctionInfo(UnimplementedLoadFunction, true); + return loadMap; + }(); + + return loadFunctionsMap; + } + default: + { + static const std::map loadFunctionsMap = []() { + std::map loadMap; + loadMap[DXGI_FORMAT_D24_UNORM_S8_UINT] = LoadImageFunctionInfo(UnimplementedLoadFunction, true); + loadMap[DXGI_FORMAT_R24G8_TYPELESS] = LoadImageFunctionInfo(UnimplementedLoadFunction, true); + return loadMap; + }(); + + return loadFunctionsMap; + } + } + } + + default: + { + static std::map emptyLoadFunctionsMap; + return emptyLoadFunctionsMap; + } + } + // clang-format on + +} // GetLoadFunctionsMap + +} // namespace d3d11 + +} // namespace rx diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/renderer11_utils.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/renderer11_utils.cpp index 094067908026..89a574be6a32 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/renderer11_utils.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/renderer11_utils.cpp @@ -8,17 +8,20 @@ // specific to the D3D11 renderer. #include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h" + +#include + +#include "common/debug.h" +#include "libANGLE/formatutils.h" +#include "libANGLE/Framebuffer.h" +#include "libANGLE/Program.h" +#include "libANGLE/renderer/d3d/d3d11/dxgi_support_table.h" #include "libANGLE/renderer/d3d/d3d11/formatutils11.h" +#include "libANGLE/renderer/d3d/d3d11/Renderer11.h" #include "libANGLE/renderer/d3d/d3d11/RenderTarget11.h" +#include "libANGLE/renderer/d3d/d3d11/texture_format_table.h" #include "libANGLE/renderer/d3d/FramebufferD3D.h" -#include "libANGLE/renderer/Workarounds.h" -#include "libANGLE/formatutils.h" -#include "libANGLE/Program.h" -#include "libANGLE/Framebuffer.h" - -#include "common/debug.h" - -#include +#include "libANGLE/renderer/d3d/WorkaroundsD3D.h" namespace rx { @@ -218,16 +221,106 @@ D3D11_QUERY ConvertQueryType(GLenum queryType) case GL_ANY_SAMPLES_PASSED_EXT: case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT: return D3D11_QUERY_OCCLUSION; case GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN: return D3D11_QUERY_SO_STATISTICS; + case GL_TIME_ELAPSED_EXT: + // Two internal queries are also created for begin/end timestamps + return D3D11_QUERY_TIMESTAMP_DISJOINT; default: UNREACHABLE(); return D3D11_QUERY_EVENT; } } -} - +} // namespace gl_d3d11 namespace d3d11_gl { +namespace +{ + +// 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%x", dxgiFormat); + } + } + + return ((supportedBits & supportMask) == supportMask); + } + + private: + ID3D11Device *mDevice; + D3D_FEATURE_LEVEL mFeatureLevel; +}; + +} // 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 3; + + default: + UNREACHABLE(); + return 0; + } +} + GLint GetMaximumClientVersion(D3D_FEATURE_LEVEL featureLevel) { switch (featureLevel) @@ -245,52 +338,65 @@ GLint GetMaximumClientVersion(D3D_FEATURE_LEVEL featureLevel) } } -static gl::TextureCaps GenerateTextureFormatCaps(GLint maxClientVersion, GLenum internalFormat, ID3D11Device *device) +static gl::TextureCaps GenerateTextureFormatCaps(GLint maxClientVersion, GLenum internalFormat, ID3D11Device *device, const Renderer11DeviceCaps &renderer11DeviceCaps) { gl::TextureCaps textureCaps; - const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(internalFormat, device->GetFeatureLevel()); + DXGISupportHelper support(device, renderer11DeviceCaps.featureLevel); + const d3d11::TextureFormat &formatInfo = + d3d11::GetTextureFormatInfo(internalFormat, renderer11DeviceCaps); + + const gl::InternalFormat &internalFormatInfo = gl::GetInternalFormatInfo(internalFormat); - UINT formatSupport; - if (SUCCEEDED(device->CheckFormatSupport(formatInfo.texFormat, &formatSupport))) + UINT texSupportMask = D3D11_FORMAT_SUPPORT_TEXTURE2D; + if (internalFormatInfo.depthBits == 0 && internalFormatInfo.stencilBits == 0) { - const gl::InternalFormat &internalFormatInfo = gl::GetInternalFormatInfo(internalFormat); - if (internalFormatInfo.depthBits > 0 || internalFormatInfo.stencilBits > 0) - { - textureCaps.texturable = ((formatSupport & D3D11_FORMAT_SUPPORT_TEXTURE2D) != 0); - } - else + texSupportMask |= D3D11_FORMAT_SUPPORT_TEXTURECUBE; + if (maxClientVersion > 2) { - UINT formatSupportMask = D3D11_FORMAT_SUPPORT_TEXTURE2D | D3D11_FORMAT_SUPPORT_TEXTURECUBE; - if (maxClientVersion > 2) - { - formatSupportMask |= D3D11_FORMAT_SUPPORT_TEXTURE3D; - } - textureCaps.texturable = ((formatSupport & formatSupportMask) == formatSupportMask); + texSupportMask |= D3D11_FORMAT_SUPPORT_TEXTURE3D; } } - if (SUCCEEDED(device->CheckFormatSupport(formatInfo.renderFormat, &formatSupport)) && - ((formatSupport & D3D11_FORMAT_SUPPORT_MULTISAMPLE_RENDERTARGET) != 0)) + textureCaps.texturable = support.query(formatInfo.formatSet->texFormat, texSupportMask); + textureCaps.filterable = + support.query(formatInfo.formatSet->srvFormat, D3D11_FORMAT_SUPPORT_SHADER_SAMPLE); + textureCaps.renderable = + (support.query(formatInfo.formatSet->rtvFormat, D3D11_FORMAT_SUPPORT_RENDER_TARGET)) || + (support.query(formatInfo.formatSet->dsvFormat, D3D11_FORMAT_SUPPORT_DEPTH_STENCIL)); + + DXGI_FORMAT renderFormat = DXGI_FORMAT_UNKNOWN; + if (formatInfo.formatSet->dsvFormat != DXGI_FORMAT_UNKNOWN) { - for (size_t sampleCount = 1; sampleCount <= D3D11_MAX_MULTISAMPLE_SAMPLE_COUNT; sampleCount++) + renderFormat = formatInfo.formatSet->dsvFormat; + } + else if (formatInfo.formatSet->rtvFormat != DXGI_FORMAT_UNKNOWN) + { + renderFormat = formatInfo.formatSet->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(formatInfo.renderFormat, sampleCount, &qualityCount)) && - qualityCount > 0) + if (SUCCEEDED(device->CheckMultisampleQualityLevels(renderFormat, sampleCount, + &qualityCount))) { + // Assume we always support lower sample counts + if (qualityCount == 0) + { + break; + } textureCaps.sampleCounts.insert(sampleCount); } } } - textureCaps.filterable = SUCCEEDED(device->CheckFormatSupport(formatInfo.srvFormat, &formatSupport)) && - ((formatSupport & D3D11_FORMAT_SUPPORT_SHADER_SAMPLE)) != 0; - textureCaps.renderable = (SUCCEEDED(device->CheckFormatSupport(formatInfo.rtvFormat, &formatSupport)) && - ((formatSupport & D3D11_FORMAT_SUPPORT_RENDER_TARGET)) != 0) || - (SUCCEEDED(device->CheckFormatSupport(formatInfo.dsvFormat, &formatSupport)) && - ((formatSupport & D3D11_FORMAT_SUPPORT_DEPTH_STENCIL) != 0)); - return textureCaps; } @@ -654,27 +760,26 @@ static size_t GetMaximumVertexUniformVectors(D3D_FEATURE_LEVEL featureLevel) // 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; + case D3D_FEATURE_LEVEL_9_1: + return 255 - d3d11_gl::GetReservedVertexUniformVectors(featureLevel); default: UNREACHABLE(); return 0; } } -static size_t GetReservedVertexUniformBuffers() -{ - // Reserve one buffer for the application uniforms, and one for driver uniforms - return 2; -} - static size_t 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 - GetReservedVertexUniformBuffers(); + 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 - GetReservedVertexUniformBuffers(); + 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: @@ -770,27 +875,26 @@ static size_t GetMaximumPixelUniformVectors(D3D_FEATURE_LEVEL featureLevel) // 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; + case D3D_FEATURE_LEVEL_9_1: + return 32 - d3d11_gl::GetReservedFragmentUniformVectors(featureLevel); default: UNREACHABLE(); return 0; } } -static size_t GetReservedPixelUniformBuffers() -{ - // Reserve one buffer for the application uniforms, and one for driver uniforms - return 2; -} - static size_t 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 - GetReservedPixelUniformBuffers(); + 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 - GetReservedPixelUniformBuffers(); + 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: @@ -957,15 +1061,15 @@ static size_t GetMaximumStreamOutputSeparateComponents(D3D_FEATURE_LEVEL feature } } -void GenerateCaps(ID3D11Device *device, ID3D11DeviceContext *deviceContext, gl::Caps *caps, gl::TextureCapsMap *textureCapsMap, gl::Extensions *extensions) +void GenerateCaps(ID3D11Device *device, ID3D11DeviceContext *deviceContext, const Renderer11DeviceCaps &renderer11DeviceCaps, gl::Caps *caps, + gl::TextureCapsMap *textureCapsMap, gl::Extensions *extensions, gl::Limitations *limitations) { - D3D_FEATURE_LEVEL featureLevel = device->GetFeatureLevel(); - GLuint maxSamples = 0; + D3D_FEATURE_LEVEL featureLevel = renderer11DeviceCaps.featureLevel; const gl::FormatSet &allFormats = gl::GetAllSizedInternalFormats(); for (gl::FormatSet::const_iterator internalFormat = allFormats.begin(); internalFormat != allFormats.end(); ++internalFormat) { - gl::TextureCaps textureCaps = GenerateTextureFormatCaps(GetMaximumClientVersion(featureLevel), *internalFormat, device); + gl::TextureCaps textureCaps = GenerateTextureFormatCaps(GetMaximumClientVersion(featureLevel), *internalFormat, device, renderer11DeviceCaps); textureCapsMap->insert(*internalFormat, textureCaps); maxSamples = std::max(maxSamples, textureCaps.getMaxSamples()); @@ -977,11 +1081,12 @@ void GenerateCaps(ID3D11Device *device, ID3D11DeviceContext *deviceContext, gl:: } // GL core feature limits - caps->maxElementIndex = static_cast(std::numeric_limits::max()); - caps->max3DTextureSize = GetMaximum3DTextureSize(featureLevel); - caps->max2DTextureSize = GetMaximum2DTextureSize(featureLevel); - caps->maxCubeMapTextureSize = GetMaximumCubeMapTextureSize(featureLevel); - caps->maxArrayTextureLayers = GetMaximum2DTextureArraySize(featureLevel); + // Reserve MAX_UINT for D3D11's primitive restart. + caps->maxElementIndex = static_cast(std::numeric_limits::max() - 1); + caps->max3DTextureSize = static_cast(GetMaximum3DTextureSize(featureLevel)); + caps->max2DTextureSize = static_cast(GetMaximum2DTextureSize(featureLevel)); + caps->maxCubeMapTextureSize = static_cast(GetMaximumCubeMapTextureSize(featureLevel)); + caps->maxArrayTextureLayers = static_cast(GetMaximum2DTextureArraySize(featureLevel)); // Unimplemented, set to minimum required caps->maxLODBias = 2.0f; @@ -991,11 +1096,12 @@ void GenerateCaps(ID3D11Device *device, ID3D11DeviceContext *deviceContext, gl:: // 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); + caps->maxDrawBuffers = static_cast(GetMaximumSimultaneousRenderTargets(featureLevel)); + caps->maxColorAttachments = + static_cast(GetMaximumSimultaneousRenderTargets(featureLevel)); // D3D11 has the same limit for viewport width and height - caps->maxViewportWidth = GetMaximumViewportSize(featureLevel); + caps->maxViewportWidth = static_cast(GetMaximumViewportSize(featureLevel)); caps->maxViewportHeight = caps->maxViewportWidth; // Choose a reasonable maximum, enforced in the shader. @@ -1007,8 +1113,8 @@ void GenerateCaps(ID3D11Device *device, ID3D11DeviceContext *deviceContext, gl:: caps->maxAliasedLineWidth = 1.0f; // Primitive count limits - caps->maxElementsIndices = GetMaximumDrawIndexedIndexCount(featureLevel); - caps->maxElementsVertices = GetMaximumDrawVertexCount(featureLevel); + caps->maxElementsIndices = static_cast(GetMaximumDrawIndexedIndexCount(featureLevel)); + caps->maxElementsVertices = static_cast(GetMaximumDrawVertexCount(featureLevel)); // Program and shader binary formats (no supported shader binary formats) caps->programBinaryFormats.push_back(GL_PROGRAM_BINARY_ANGLE); @@ -1032,19 +1138,27 @@ void GenerateCaps(ID3D11Device *device, ID3D11DeviceContext *deviceContext, gl:: caps->maxServerWaitTimeout = 0; // Vertex shader limits - caps->maxVertexAttributes = GetMaximumVertexInputSlots(featureLevel); - caps->maxVertexUniformComponents = GetMaximumVertexUniformVectors(featureLevel) * 4; - caps->maxVertexUniformVectors = GetMaximumVertexUniformVectors(featureLevel); - caps->maxVertexUniformBlocks = GetMaximumVertexUniformBlocks(featureLevel); - caps->maxVertexOutputComponents = GetMaximumVertexOutputVectors(featureLevel) * 4; - caps->maxVertexTextureImageUnits = GetMaximumVertexTextureUnits(featureLevel); + caps->maxVertexAttributes = static_cast(GetMaximumVertexInputSlots(featureLevel)); + caps->maxVertexUniformComponents = + static_cast(GetMaximumVertexUniformVectors(featureLevel)) * 4; + caps->maxVertexUniformVectors = + static_cast(GetMaximumVertexUniformVectors(featureLevel)); + caps->maxVertexUniformBlocks = static_cast(GetMaximumVertexUniformBlocks(featureLevel)); + caps->maxVertexOutputComponents = + static_cast(GetMaximumVertexOutputVectors(featureLevel)) * 4; + caps->maxVertexTextureImageUnits = + static_cast(GetMaximumVertexTextureUnits(featureLevel)); // Fragment shader limits - caps->maxFragmentUniformComponents = GetMaximumPixelUniformVectors(featureLevel) * 4; - caps->maxFragmentUniformVectors = GetMaximumPixelUniformVectors(featureLevel); - caps->maxFragmentUniformBlocks = GetMaximumPixelUniformBlocks(featureLevel); - caps->maxFragmentInputComponents = GetMaximumPixelInputVectors(featureLevel) * 4; - caps->maxTextureImageUnits = GetMaximumPixelTextureUnits(featureLevel); + caps->maxFragmentUniformComponents = + static_cast(GetMaximumPixelUniformVectors(featureLevel)) * 4; + caps->maxFragmentUniformVectors = + static_cast(GetMaximumPixelUniformVectors(featureLevel)); + caps->maxFragmentUniformBlocks = + static_cast(GetMaximumPixelUniformBlocks(featureLevel)); + caps->maxFragmentInputComponents = + static_cast(GetMaximumPixelInputVectors(featureLevel)) * 4; + caps->maxTextureImageUnits = static_cast(GetMaximumPixelTextureUnits(featureLevel)); caps->minProgramTexelOffset = GetMinimumTexelOffset(featureLevel); caps->maxProgramTexelOffset = GetMaximumTexelOffset(featureLevel); @@ -1063,14 +1177,18 @@ void GenerateCaps(ID3D11Device *device, ID3D11DeviceContext *deviceContext, gl:: static_cast(caps->maxVertexUniformComponents); caps->maxCombinedFragmentUniformComponents = (static_cast(caps->maxFragmentUniformBlocks) * static_cast(caps->maxUniformBlockSize / 4)) + static_cast(caps->maxFragmentUniformComponents); - caps->maxVaryingComponents = GetMaximumVertexOutputVectors(featureLevel) * 4; - caps->maxVaryingVectors = GetMaximumVertexOutputVectors(featureLevel); + caps->maxVaryingComponents = + static_cast(GetMaximumVertexOutputVectors(featureLevel)) * 4; + caps->maxVaryingVectors = static_cast(GetMaximumVertexOutputVectors(featureLevel)); caps->maxCombinedTextureImageUnits = caps->maxVertexTextureImageUnits + caps->maxTextureImageUnits; // Transform feedback limits - caps->maxTransformFeedbackInterleavedComponents = GetMaximumStreamOutputInterleavedComponents(featureLevel); - caps->maxTransformFeedbackSeparateAttributes = GetMaximumStreamOutputBuffers(featureLevel); - caps->maxTransformFeedbackSeparateComponents = GetMaximumStreamOutputSeparateComponents(featureLevel); + caps->maxTransformFeedbackInterleavedComponents = + static_cast(GetMaximumStreamOutputInterleavedComponents(featureLevel)); + caps->maxTransformFeedbackSeparateAttributes = + static_cast(GetMaximumStreamOutputBuffers(featureLevel)); + caps->maxTransformFeedbackSeparateComponents = + static_cast(GetMaximumStreamOutputSeparateComponents(featureLevel)); // Multisample limits caps->maxSamples = maxSamples; @@ -1078,7 +1196,6 @@ void GenerateCaps(ID3D11Device *device, ID3D11DeviceContext *deviceContext, gl:: // GL extension support extensions->setTextureExtensionSupport(*textureCapsMap); extensions->elementIndexUint = true; - extensions->packedDepthStencil = true; extensions->getProgramBinary = true; extensions->rgb8rgba8 = true; extensions->readFormatBGRA = true; @@ -1093,6 +1210,10 @@ void GenerateCaps(ID3D11Device *device, ID3D11DeviceContext *deviceContext, gl:: extensions->occlusionQueryBoolean = GetOcclusionQuerySupport(featureLevel); extensions->fence = GetEventQuerySupport(featureLevel); extensions->timerQuery = false; // Unimplemented + extensions->disjointTimerQuery = true; + extensions->queryCounterBitsTimeElapsed = 64; + extensions->queryCounterBitsTimestamp = + 0; // Timestamps cannot be supported due to D3D11 limitations extensions->robustness = true; extensions->blendMinMax = true; extensions->framebufferBlit = GetFramebufferBlitSupport(featureLevel); @@ -1103,18 +1224,119 @@ void GenerateCaps(ID3D11Device *device, ID3D11DeviceContext *deviceContext, gl:: extensions->shaderTextureLOD = GetShaderTextureLODSupport(featureLevel); extensions->fragDepth = true; extensions->textureUsage = true; // This could be false since it has no effect in D3D11 + extensions->discardFramebuffer = true; extensions->translatedShaderSource = true; extensions->fboRenderMipmap = false; + extensions->debugMarker = true; + extensions->eglImage = true; + extensions->unpackSubimage = true; + extensions->packSubimage = true; + extensions->vertexArrayObject = true; + extensions->noError = true; + extensions->lossyETCDecode = true; + + // 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; + +#ifdef ANGLE_ENABLE_WINDOWS_STORE + // 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 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 DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(format); + const DXGIFormatSize &dxgiFormatInfo = d3d11::GetDXGIFormatSizeInfo(format); int upsampleCount = 0; // Don't expand the size of full textures that are at least (blockWidth x blockHeight) already. @@ -1131,14 +1353,20 @@ void MakeValidSize(bool isImage, DXGI_FORMAT format, GLsizei *requestWidth, GLsi *levelOffset = upsampleCount; } -void GenerateInitialTextureData(GLint internalFormat, D3D_FEATURE_LEVEL featureLevel, GLuint width, GLuint height, GLuint depth, - GLuint mipLevels, std::vector *outSubresourceData, - std::vector< std::vector > *outData) +void GenerateInitialTextureData(GLint internalFormat, + const Renderer11DeviceCaps &renderer11DeviceCaps, + GLuint width, + GLuint height, + GLuint depth, + GLuint mipLevels, + std::vector *outSubresourceData, + std::vector> *outData) { - const d3d11::TextureFormat &d3dFormatInfo = d3d11::GetTextureFormatInfo(internalFormat, featureLevel); + const d3d11::TextureFormat &d3dFormatInfo = d3d11::GetTextureFormatInfo(internalFormat, renderer11DeviceCaps); ASSERT(d3dFormatInfo.dataInitializerFunction != NULL); - const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(d3dFormatInfo.texFormat); + const d3d11::DXGIFormatSize &dxgiFormatInfo = + d3d11::GetDXGIFormatSizeInfo(d3dFormatInfo.formatSet->texFormat); outSubresourceData->resize(mipLevels); outData->resize(mipLevels); @@ -1161,6 +1389,11 @@ void GenerateInitialTextureData(GLint internalFormat, D3D_FEATURE_LEVEL featureL } } +UINT GetPrimitiveRestartIndex() +{ + return std::numeric_limits::max(); +} + void SetPositionTexCoordVertex(PositionTexCoordVertex* vertex, float x, float y, float u, float v) { vertex->x = x; @@ -1183,15 +1416,94 @@ void SetPositionLayerTexCoord3DVertex(PositionLayerTexCoord3DVertex* vertex, flo HRESULT SetDebugName(ID3D11DeviceChild *resource, const char *name) { #if defined(_DEBUG) - return resource->SetPrivateData(WKPDID_D3DDebugObjectName, strlen(name), name); + UINT existingDataSize = 0; + resource->GetPrivateData(WKPDID_D3DDebugObjectName, &existingDataSize, nullptr); + // Don't check the HRESULT- if it failed then that probably just means that no private data + // exists yet + + if (existingDataSize > 0) + { + // In some cases, ANGLE will try to apply two names to one object, which causes + // a D3D SDK Layers warning. This can occur if, for example, you 'create' two objects + // (e.g.Rasterizer States) with identical DESCs on the same device. D3D11 will optimize + // these calls and return the same object both times. + static const char *multipleNamesUsed = "Multiple names set by ANGLE"; + + // Remove the existing name + HRESULT hr = resource->SetPrivateData(WKPDID_D3DDebugObjectName, 0, nullptr); + if (FAILED(hr)) + { + return hr; + } + + // Apply the new name + return resource->SetPrivateData(WKPDID_D3DDebugObjectName, + static_cast(strlen(multipleNamesUsed)), + multipleNamesUsed); + } + else + { + return resource->SetPrivateData(WKPDID_D3DDebugObjectName, + static_cast(strlen(name)), name); + } #else return S_OK; #endif } -Workarounds GenerateWorkarounds(D3D_FEATURE_LEVEL featureLevel) +LazyInputLayout::LazyInputLayout(const D3D11_INPUT_ELEMENT_DESC *inputDesc, + size_t inputDescLen, + const BYTE *byteCode, + size_t byteCodeLen, + const char *debugName) + : mInputDesc(inputDescLen), + mByteCodeLen(byteCodeLen), + mByteCode(byteCode), + mDebugName(debugName) +{ + memcpy(&mInputDesc[0], inputDesc, sizeof(D3D11_INPUT_ELEMENT_DESC) * inputDescLen); +} + +ID3D11InputLayout *LazyInputLayout::resolve(ID3D11Device *device) +{ + checkAssociatedDevice(device); + + if (mResource == nullptr) + { + HRESULT result = + device->CreateInputLayout(&mInputDesc[0], static_cast(mInputDesc.size()), + mByteCode, mByteCodeLen, &mResource); + ASSERT(SUCCEEDED(result)); + UNUSED_ASSERTION_VARIABLE(result); + d3d11::SetDebugName(mResource, mDebugName); + } + + return mResource; +} + +LazyBlendState::LazyBlendState(const D3D11_BLEND_DESC &desc, const char *debugName) + : mDesc(desc), mDebugName(debugName) { - Workarounds workarounds; +} + +ID3D11BlendState *LazyBlendState::resolve(ID3D11Device *device) +{ + checkAssociatedDevice(device); + + if (mResource == nullptr) + { + HRESULT result = device->CreateBlendState(&mDesc, &mResource); + ASSERT(SUCCEEDED(result)); + UNUSED_ASSERTION_VARIABLE(result); + d3d11::SetDebugName(mResource, mDebugName); + } + + return mResource; +} + +WorkaroundsD3D GenerateWorkarounds(D3D_FEATURE_LEVEL featureLevel) +{ + WorkaroundsD3D workarounds; workarounds.mrtPerfWorkaround = true; workarounds.setDataFasterThanImageUpload = true; workarounds.zeroMaxLodWorkaround = (featureLevel <= D3D_FEATURE_LEVEL_9_3); @@ -1199,6 +1511,245 @@ Workarounds GenerateWorkarounds(D3D_FEATURE_LEVEL featureLevel) return workarounds; } +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::TextureHelper11() + : mTextureType(GL_NONE), + mFormat(DXGI_FORMAT_UNKNOWN), + mANGLEFormat(d3d11::ANGLE_FORMAT_NONE), + mSampleCount(0), + mTexture2D(nullptr), + mTexture3D(nullptr) +{ +} + +TextureHelper11::TextureHelper11(TextureHelper11 &&toCopy) + : mTextureType(toCopy.mTextureType), + mExtents(toCopy.mExtents), + mFormat(toCopy.mFormat), + mANGLEFormat(toCopy.mANGLEFormat), + mSampleCount(toCopy.mSampleCount), + mTexture2D(toCopy.mTexture2D), + mTexture3D(toCopy.mTexture3D) +{ + toCopy.reset(); +} + +// static +TextureHelper11 TextureHelper11::MakeAndReference(ID3D11Resource *genericResource, + d3d11::ANGLEFormat angleFormat) +{ + TextureHelper11 newHelper; + newHelper.mANGLEFormat = angleFormat; + newHelper.mTexture2D = d3d11::DynamicCastComObject(genericResource); + newHelper.mTexture3D = d3d11::DynamicCastComObject(genericResource); + newHelper.mTextureType = newHelper.mTexture2D ? GL_TEXTURE_2D : GL_TEXTURE_3D; + newHelper.initDesc(); + return newHelper; +} + +// static +TextureHelper11 TextureHelper11::MakeAndPossess2D(ID3D11Texture2D *texToOwn, + d3d11::ANGLEFormat angleFormat) +{ + TextureHelper11 newHelper; + newHelper.mANGLEFormat = angleFormat; + newHelper.mTexture2D = texToOwn; + newHelper.mTextureType = GL_TEXTURE_2D; + newHelper.initDesc(); + return newHelper; +} + +// static +TextureHelper11 TextureHelper11::MakeAndPossess3D(ID3D11Texture3D *texToOwn, + d3d11::ANGLEFormat angleFormat) +{ + TextureHelper11 newHelper; + newHelper.mANGLEFormat = angleFormat; + newHelper.mTexture3D = texToOwn; + newHelper.mTextureType = GL_TEXTURE_3D; + newHelper.initDesc(); + return newHelper; +} + +void TextureHelper11::initDesc() +{ + if (mTextureType == GL_TEXTURE_2D) + { + ASSERT(!mTexture3D); + D3D11_TEXTURE2D_DESC desc2D; + mTexture2D->GetDesc(&desc2D); + + mExtents.width = static_cast(desc2D.Width); + mExtents.height = static_cast(desc2D.Height); + mExtents.depth = 1; + mFormat = desc2D.Format; + mSampleCount = desc2D.SampleDesc.Count; + } + else + { + ASSERT(mTexture3D && mTextureType == GL_TEXTURE_3D); + D3D11_TEXTURE3D_DESC desc3D; + mTexture3D->GetDesc(&desc3D); + + mExtents.width = static_cast(desc3D.Width); + mExtents.height = static_cast(desc3D.Height); + mExtents.depth = static_cast(desc3D.Depth); + mFormat = desc3D.Format; + mSampleCount = 1; + } + ASSERT(mFormat == d3d11::GetANGLEFormatSet(mANGLEFormat).texFormat); +} + +TextureHelper11::~TextureHelper11() +{ + SafeRelease(mTexture2D); + SafeRelease(mTexture3D); +} + +ID3D11Resource *TextureHelper11::getResource() const +{ + return mTexture2D ? static_cast(mTexture2D) + : static_cast(mTexture3D); +} + +TextureHelper11 &TextureHelper11::operator=(TextureHelper11 &&texture) +{ + SafeRelease(mTexture2D); + SafeRelease(mTexture3D); + + mTextureType = texture.mTextureType; + mExtents = texture.mExtents; + mFormat = texture.mFormat; + mANGLEFormat = texture.mANGLEFormat; + mSampleCount = texture.mSampleCount; + mTexture2D = texture.mTexture2D; + mTexture3D = texture.mTexture3D; + texture.reset(); + return *this; +} + +void TextureHelper11::reset() +{ + mTextureType = GL_NONE; + mExtents = gl::Extents(); + mFormat = DXGI_FORMAT_UNKNOWN; + mSampleCount = 0; + mTexture2D = nullptr; + mTexture3D = nullptr; } +gl::ErrorOrResult CreateStagingTexture(GLenum textureType, + DXGI_FORMAT dxgiFormat, + d3d11::ANGLEFormat angleFormat, + const gl::Extents &size, + ID3D11Device *device) +{ + if (textureType == GL_TEXTURE_2D) + { + D3D11_TEXTURE2D_DESC stagingDesc; + stagingDesc.Width = size.width; + stagingDesc.Height = size.height; + stagingDesc.MipLevels = 1; + stagingDesc.ArraySize = 1; + stagingDesc.Format = dxgiFormat; + 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; + + ID3D11Texture2D *stagingTex = nullptr; + HRESULT result = device->CreateTexture2D(&stagingDesc, nullptr, &stagingTex); + if (FAILED(result)) + { + return gl::Error(GL_OUT_OF_MEMORY, "CreateStagingTextureFor failed, HRESULT: 0x%X.", + result); + } + + return TextureHelper11::MakeAndPossess2D(stagingTex, angleFormat); + } + ASSERT(textureType == GL_TEXTURE_3D); + + D3D11_TEXTURE3D_DESC stagingDesc; + stagingDesc.Width = size.width; + stagingDesc.Height = size.height; + stagingDesc.Depth = 1; + stagingDesc.MipLevels = 1; + stagingDesc.Format = dxgiFormat; + stagingDesc.Usage = D3D11_USAGE_STAGING; + stagingDesc.BindFlags = 0; + stagingDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; + stagingDesc.MiscFlags = 0; + + ID3D11Texture3D *stagingTex = nullptr; + HRESULT result = device->CreateTexture3D(&stagingDesc, nullptr, &stagingTex); + if (FAILED(result)) + { + return gl::Error(GL_OUT_OF_MEMORY, "CreateStagingTextureFor failed, HRESULT: 0x%X.", + result); + } + + return TextureHelper11::MakeAndPossess3D(stagingTex, angleFormat); } + +bool UsePresentPathFast(const Renderer11 *renderer, + const gl::FramebufferAttachment *framebufferAttachment) +{ + if (framebufferAttachment == nullptr) + { + return false; + } + + return (framebufferAttachment->type() == GL_FRAMEBUFFER_DEFAULT && + renderer->presentPathFastEnabled()); +} + +NotificationSet::NotificationSet() +{ +} + +NotificationSet::~NotificationSet() +{ +} + +void NotificationSet::add(const NotificationCallback *callback) +{ + ASSERT(mCallbacks.count(callback) == 0); + mCallbacks.insert(callback); +} + +void NotificationSet::remove(const NotificationCallback *callback) +{ + ASSERT(mCallbacks.count(callback) == 1); + mCallbacks.erase(callback); +} + +void NotificationSet::signal() const +{ + if (mCallbacks.empty()) + return; + + for (const auto *callback : mCallbacks) + { + (*callback)(); + } +} + +void NotificationSet::clear() +{ + mCallbacks.clear(); +} + +} // namespace rx diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/renderer11_utils.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/renderer11_utils.h index 335dd843296e..49718c60c18a 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/renderer11_utils.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/renderer11_utils.h @@ -10,11 +10,15 @@ #ifndef LIBANGLE_RENDERER_D3D_D3D11_RENDERER11_UTILS_H_ #define LIBANGLE_RENDERER_D3D_D3D11_RENDERER11_UTILS_H_ +#include +#include +#include + #include "libANGLE/angletypes.h" #include "libANGLE/Caps.h" #include "libANGLE/Error.h" - -#include +#include "libANGLE/renderer/d3d/d3d11/texture_format_table.h" +#include "libANGLE/renderer/d3d/RendererD3D.h" namespace gl { @@ -23,8 +27,13 @@ class FramebufferAttachment; namespace rx { +class Renderer11; class RenderTarget11; -struct Workarounds; +struct WorkaroundsD3D; +struct Renderer11DeviceCaps; + +using RenderTargetArray = std::array; +using RTVArray = std::array; namespace gl_d3d11 { @@ -45,24 +54,46 @@ D3D11_TEXTURE_ADDRESS_MODE ConvertTextureWrap(GLenum wrap); D3D11_QUERY ConvertQueryType(GLenum queryType); -} +} // namespace gl_d3d11 namespace d3d11_gl { +unsigned int GetReservedVertexUniformVectors(D3D_FEATURE_LEVEL featureLevel); + +unsigned int GetReservedFragmentUniformVectors(D3D_FEATURE_LEVEL featureLevel); + GLint GetMaximumClientVersion(D3D_FEATURE_LEVEL featureLevel); -void GenerateCaps(ID3D11Device *device, ID3D11DeviceContext *deviceContext, gl::Caps *caps, gl::TextureCapsMap *textureCapsMap, gl::Extensions *extensions); +void GenerateCaps(ID3D11Device *device, ID3D11DeviceContext *deviceContext, const Renderer11DeviceCaps &renderer11DeviceCaps, gl::Caps *caps, + gl::TextureCapsMap *textureCapsMap, gl::Extensions *extensions, gl::Limitations *limitations); -} +} // 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); -void GenerateInitialTextureData(GLint internalFormat, D3D_FEATURE_LEVEL featureLevel, GLuint width, GLuint height, GLuint depth, - GLuint mipLevels, std::vector *outSubresourceData, - std::vector< std::vector > *outData); +void GenerateInitialTextureData(GLint internalFormat, + const Renderer11DeviceCaps &renderer11DeviceCaps, + GLuint width, + GLuint height, + GLuint depth, + GLuint mipLevels, + std::vector *outSubresourceData, + std::vector> *outData); + +UINT GetPrimitiveRestartIndex(); struct PositionTexCoordVertex { @@ -133,56 +164,263 @@ inline bool isDeviceLostError(HRESULT errorCode) } } -template -inline ID3D11VertexShader *CompileVS(ID3D11Device *device, const BYTE (&byteCode)[N], const char *name) +inline ID3D11VertexShader *CompileVS(ID3D11Device *device, const BYTE *byteCode, size_t N, const char *name) { - ID3D11VertexShader *vs = NULL; - HRESULT result = device->CreateVertexShader(byteCode, N, NULL, &vs); - UNUSED_ASSERTION_VARIABLE(result); + ID3D11VertexShader *vs = nullptr; + HRESULT result = device->CreateVertexShader(byteCode, N, nullptr, &vs); ASSERT(SUCCEEDED(result)); - SetDebugName(vs, name); - return vs; + if (SUCCEEDED(result)) + { + SetDebugName(vs, name); + return vs; + } + return nullptr; } template -inline ID3D11GeometryShader *CompileGS(ID3D11Device *device, const BYTE (&byteCode)[N], const char *name) +ID3D11VertexShader *CompileVS(ID3D11Device *device, const BYTE (&byteCode)[N], const char *name) { - ID3D11GeometryShader *gs = NULL; - HRESULT result = device->CreateGeometryShader(byteCode, N, NULL, &gs); - UNUSED_ASSERTION_VARIABLE(result); + return CompileVS(device, byteCode, N, name); +} + +inline ID3D11GeometryShader *CompileGS(ID3D11Device *device, const BYTE *byteCode, size_t N, const char *name) +{ + ID3D11GeometryShader *gs = nullptr; + HRESULT result = device->CreateGeometryShader(byteCode, N, nullptr, &gs); ASSERT(SUCCEEDED(result)); - SetDebugName(gs, name); - return gs; + if (SUCCEEDED(result)) + { + SetDebugName(gs, name); + return gs; + } + return nullptr; } template -inline ID3D11PixelShader *CompilePS(ID3D11Device *device, const BYTE (&byteCode)[N], const char *name) +ID3D11GeometryShader *CompileGS(ID3D11Device *device, const BYTE (&byteCode)[N], const char *name) { - ID3D11PixelShader *ps = NULL; - HRESULT result = device->CreatePixelShader(byteCode, N, NULL, &ps); - UNUSED_ASSERTION_VARIABLE(result); + return CompileGS(device, byteCode, N, name); +} + +inline ID3D11PixelShader *CompilePS(ID3D11Device *device, const BYTE *byteCode, size_t N, const char *name) +{ + ID3D11PixelShader *ps = nullptr; + HRESULT result = device->CreatePixelShader(byteCode, N, nullptr, &ps); ASSERT(SUCCEEDED(result)); - SetDebugName(ps, name); - return ps; + if (SUCCEEDED(result)) + { + SetDebugName(ps, name); + return ps; + } + return nullptr; } -// Copy data to small D3D11 buffers, such as for small constant buffers, which use one struct to -// represent an entire buffer. -template -inline void SetBufferData(ID3D11DeviceContext *context, ID3D11Buffer *constantBuffer, const T &value) +template +ID3D11PixelShader *CompilePS(ID3D11Device *device, const BYTE (&byteCode)[N], const char *name) { - D3D11_MAPPED_SUBRESOURCE mappedResource; - context->Map(constantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource); + return CompilePS(device, byteCode, N, name); +} + +template +class LazyResource : public angle::NonCopyable +{ + public: + LazyResource() : mResource(nullptr), mAssociatedDevice(nullptr) {} + virtual ~LazyResource() { release(); } + + virtual ResourceType *resolve(ID3D11Device *device) = 0; + void release() { SafeRelease(mResource); } + + protected: + void checkAssociatedDevice(ID3D11Device *device); + + ResourceType *mResource; + ID3D11Device *mAssociatedDevice; +}; + +template +void LazyResource::checkAssociatedDevice(ID3D11Device *device) +{ + ASSERT(mAssociatedDevice == nullptr || device == mAssociatedDevice); + mAssociatedDevice = device; +} + +template +class LazyShader final : public LazyResource +{ + public: + // All parameters must be constexpr. Not supported in VS2013. + LazyShader(const BYTE *byteCode, + size_t byteCodeSize, + const char *name) + : mByteCode(byteCode), + mByteCodeSize(byteCodeSize), + mName(name) + { + } + + D3D11ShaderType *resolve(ID3D11Device *device) override; - memcpy(mappedResource.pData, &value, sizeof(T)); + private: + const BYTE *mByteCode; + size_t mByteCodeSize; + const char *mName; +}; - context->Unmap(constantBuffer, 0); +template <> +inline ID3D11VertexShader *LazyShader::resolve(ID3D11Device *device) +{ + checkAssociatedDevice(device); + if (mResource == nullptr) + { + mResource = CompileVS(device, mByteCode, mByteCodeSize, mName); + } + return mResource; } -Workarounds GenerateWorkarounds(D3D_FEATURE_LEVEL featureLevel); +template <> +inline ID3D11GeometryShader *LazyShader::resolve(ID3D11Device *device) +{ + checkAssociatedDevice(device); + if (mResource == nullptr) + { + mResource = CompileGS(device, mByteCode, mByteCodeSize, mName); + } + return mResource; +} +template <> +inline ID3D11PixelShader *LazyShader::resolve(ID3D11Device *device) +{ + checkAssociatedDevice(device); + if (mResource == nullptr) + { + mResource = CompilePS(device, mByteCode, mByteCodeSize, mName); + } + return mResource; } +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); + + ID3D11InputLayout *resolve(ID3D11Device *device) override; + + private: + std::vector mInputDesc; + size_t mByteCodeLen; + const BYTE *mByteCode; + const char *mDebugName; +}; + +class LazyBlendState final : public LazyResource +{ + public: + LazyBlendState(const D3D11_BLEND_DESC &desc, const char *debugName); + + ID3D11BlendState *resolve(ID3D11Device *device) 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); + } } +WorkaroundsD3D GenerateWorkarounds(D3D_FEATURE_LEVEL featureLevel); + +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); +} // namespace d3d11 + +// A helper class which wraps a 2D or 3D texture. +class TextureHelper11 : angle::NonCopyable +{ + public: + TextureHelper11(); + TextureHelper11(TextureHelper11 &&toCopy); + ~TextureHelper11(); + TextureHelper11 &operator=(TextureHelper11 &&texture); + + static TextureHelper11 MakeAndReference(ID3D11Resource *genericResource, + d3d11::ANGLEFormat angleFormat); + static TextureHelper11 MakeAndPossess2D(ID3D11Texture2D *texToOwn, + d3d11::ANGLEFormat angleFormat); + static TextureHelper11 MakeAndPossess3D(ID3D11Texture3D *texToOwn, + d3d11::ANGLEFormat angleFormat); + + GLenum getTextureType() const { return mTextureType; } + gl::Extents getExtents() const { return mExtents; } + DXGI_FORMAT getFormat() const { return mFormat; } + d3d11::ANGLEFormat getANGLEFormat() const { return mANGLEFormat; } + int getSampleCount() const { return mSampleCount; } + ID3D11Texture2D *getTexture2D() const { return mTexture2D; } + ID3D11Texture3D *getTexture3D() const { return mTexture3D; } + ID3D11Resource *getResource() const; + + private: + void reset(); + void initDesc(); + + GLenum mTextureType; + gl::Extents mExtents; + DXGI_FORMAT mFormat; + d3d11::ANGLEFormat mANGLEFormat; + int mSampleCount; + ID3D11Texture2D *mTexture2D; + ID3D11Texture3D *mTexture3D; +}; + +gl::ErrorOrResult CreateStagingTexture(GLenum textureType, + DXGI_FORMAT dxgiFormat, + d3d11::ANGLEFormat angleFormat, + const gl::Extents &size, + ID3D11Device *device); + +bool UsePresentPathFast(const Renderer11 *renderer, const gl::FramebufferAttachment *colorbuffer); + +using NotificationCallback = std::function; + +class NotificationSet final : angle::NonCopyable +{ + public: + NotificationSet(); + ~NotificationSet(); + + void add(const NotificationCallback *callback); + void remove(const NotificationCallback *callback); + void signal() const; + void clear(); + + private: + std::set mCallbacks; +}; + +} // namespace rx + #endif // LIBANGLE_RENDERER_D3D_D3D11_RENDERER11_UTILS_H_ diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/buffertotexture11_gs.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/buffertotexture11_gs.h index 2d38307091fd..71a2fec64cd1 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/buffertotexture11_gs.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/buffertotexture11_gs.h @@ -1,165 +1,165 @@ -#if 0 -// -// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 -// -// -// -// 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, 79, 166, - 191, 97, 16, 63, 142, 167, - 231, 92, 119, 74, 86, 7, - 58, 165, 1, 0, 0, 0, - 212, 2, 0, 0, 5, 0, - 0, 0, 52, 0, 0, 0, - 140, 0, 0, 0, 0, 1, - 0, 0, 136, 1, 0, 0, - 88, 2, 0, 0, 82, 68, - 69, 70, 80, 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, 54, 46, 51, - 46, 57, 54, 48, 48, 46, - 49, 54, 51, 56, 52, 0, - 171, 171, 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 -}; +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 +// +// +// +// 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, 79, 166, + 191, 97, 16, 63, 142, 167, + 231, 92, 119, 74, 86, 7, + 58, 165, 1, 0, 0, 0, + 212, 2, 0, 0, 5, 0, + 0, 0, 52, 0, 0, 0, + 140, 0, 0, 0, 0, 1, + 0, 0, 136, 1, 0, 0, + 88, 2, 0, 0, 82, 68, + 69, 70, 80, 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, 54, 46, 51, + 46, 57, 54, 48, 48, 46, + 49, 54, 51, 56, 52, 0, + 171, 171, 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/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/buffertotexture11_ps_4f.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/buffertotexture11_ps_4f.h index 65fa413d1c5c..cfc0c3faa251 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/buffertotexture11_ps_4f.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/buffertotexture11_ps_4f.h @@ -1,229 +1,229 @@ -#if 0 -// -// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 -// -// -// Buffer Definitions: -// -// cbuffer BufferCopyParams -// { -// -// uint FirstPixelOffset; // Offset: 0 Size: 4 [unused] -// uint PixelsPerRow; // Offset: 4 Size: 4 [unused] -// uint RowStride; // Offset: 8 Size: 4 [unused] -// uint RowsPerSlice; // Offset: 12 Size: 4 [unused] -// float2 PositionOffset; // Offset: 16 Size: 8 [unused] -// float2 PositionScale; // Offset: 24 Size: 8 [unused] -// int2 TexLocationOffset; // Offset: 32 Size: 8 [unused] -// int2 TexLocationScale; // Offset: 40 Size: 8 [unused] -// uint FirstSlice; // Offset: 48 Size: 4 [unused] -// -// } -// -// -// Resource Bindings: -// -// Name Type Format Dim Slot Elements -// ------------------------------ ---------- ------- ----------- ---- -------- -// Buffer4F texture float4 buf 0 1 -// BufferCopyParams cbuffer NA NA 0 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_constantbuffer cb0[1], immediateIndexed -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, 176, 15, - 76, 123, 100, 38, 152, 23, - 150, 99, 165, 184, 222, 157, - 235, 80, 1, 0, 0, 0, - 252, 3, 0, 0, 5, 0, - 0, 0, 52, 0, 0, 0, - 140, 2, 0, 0, 228, 2, - 0, 0, 24, 3, 0, 0, - 128, 3, 0, 0, 82, 68, - 69, 70, 80, 2, 0, 0, - 1, 0, 0, 0, 120, 0, - 0, 0, 2, 0, 0, 0, - 28, 0, 0, 0, 0, 4, - 255, 255, 0, 1, 0, 0, - 28, 2, 0, 0, 92, 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, - 101, 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, 52, 70, 0, 66, - 117, 102, 102, 101, 114, 67, - 111, 112, 121, 80, 97, 114, - 97, 109, 115, 0, 171, 171, - 101, 0, 0, 0, 9, 0, - 0, 0, 144, 0, 0, 0, - 64, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 104, 1, 0, 0, 0, 0, - 0, 0, 4, 0, 0, 0, - 0, 0, 0, 0, 124, 1, - 0, 0, 0, 0, 0, 0, - 140, 1, 0, 0, 4, 0, - 0, 0, 4, 0, 0, 0, - 0, 0, 0, 0, 124, 1, - 0, 0, 0, 0, 0, 0, - 153, 1, 0, 0, 8, 0, - 0, 0, 4, 0, 0, 0, - 0, 0, 0, 0, 124, 1, - 0, 0, 0, 0, 0, 0, - 163, 1, 0, 0, 12, 0, - 0, 0, 4, 0, 0, 0, - 0, 0, 0, 0, 124, 1, - 0, 0, 0, 0, 0, 0, - 176, 1, 0, 0, 16, 0, - 0, 0, 8, 0, 0, 0, - 0, 0, 0, 0, 192, 1, - 0, 0, 0, 0, 0, 0, - 208, 1, 0, 0, 24, 0, - 0, 0, 8, 0, 0, 0, - 0, 0, 0, 0, 192, 1, - 0, 0, 0, 0, 0, 0, - 222, 1, 0, 0, 32, 0, - 0, 0, 8, 0, 0, 0, - 0, 0, 0, 0, 240, 1, - 0, 0, 0, 0, 0, 0, - 0, 2, 0, 0, 40, 0, - 0, 0, 8, 0, 0, 0, - 0, 0, 0, 0, 240, 1, - 0, 0, 0, 0, 0, 0, - 17, 2, 0, 0, 48, 0, - 0, 0, 4, 0, 0, 0, - 0, 0, 0, 0, 124, 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, 54, - 46, 51, 46, 57, 54, 48, - 48, 46, 49, 54, 51, 56, - 52, 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, - 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, 96, 0, - 0, 0, 64, 0, 0, 0, - 24, 0, 0, 0, 89, 0, - 0, 4, 70, 142, 32, 0, - 0, 0, 0, 0, 1, 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 -}; +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 +// +// +// Buffer Definitions: +// +// cbuffer BufferCopyParams +// { +// +// uint FirstPixelOffset; // Offset: 0 Size: 4 [unused] +// uint PixelsPerRow; // Offset: 4 Size: 4 [unused] +// uint RowStride; // Offset: 8 Size: 4 [unused] +// uint RowsPerSlice; // Offset: 12 Size: 4 [unused] +// float2 PositionOffset; // Offset: 16 Size: 8 [unused] +// float2 PositionScale; // Offset: 24 Size: 8 [unused] +// int2 TexLocationOffset; // Offset: 32 Size: 8 [unused] +// int2 TexLocationScale; // Offset: 40 Size: 8 [unused] +// uint FirstSlice; // Offset: 48 Size: 4 [unused] +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim Slot Elements +// ------------------------------ ---------- ------- ----------- ---- -------- +// Buffer4F texture float4 buf 0 1 +// BufferCopyParams cbuffer NA NA 0 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_constantbuffer cb0[1], immediateIndexed +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, 176, 15, + 76, 123, 100, 38, 152, 23, + 150, 99, 165, 184, 222, 157, + 235, 80, 1, 0, 0, 0, + 252, 3, 0, 0, 5, 0, + 0, 0, 52, 0, 0, 0, + 140, 2, 0, 0, 228, 2, + 0, 0, 24, 3, 0, 0, + 128, 3, 0, 0, 82, 68, + 69, 70, 80, 2, 0, 0, + 1, 0, 0, 0, 120, 0, + 0, 0, 2, 0, 0, 0, + 28, 0, 0, 0, 0, 4, + 255, 255, 0, 1, 0, 0, + 28, 2, 0, 0, 92, 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, + 101, 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, 52, 70, 0, 66, + 117, 102, 102, 101, 114, 67, + 111, 112, 121, 80, 97, 114, + 97, 109, 115, 0, 171, 171, + 101, 0, 0, 0, 9, 0, + 0, 0, 144, 0, 0, 0, + 64, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 104, 1, 0, 0, 0, 0, + 0, 0, 4, 0, 0, 0, + 0, 0, 0, 0, 124, 1, + 0, 0, 0, 0, 0, 0, + 140, 1, 0, 0, 4, 0, + 0, 0, 4, 0, 0, 0, + 0, 0, 0, 0, 124, 1, + 0, 0, 0, 0, 0, 0, + 153, 1, 0, 0, 8, 0, + 0, 0, 4, 0, 0, 0, + 0, 0, 0, 0, 124, 1, + 0, 0, 0, 0, 0, 0, + 163, 1, 0, 0, 12, 0, + 0, 0, 4, 0, 0, 0, + 0, 0, 0, 0, 124, 1, + 0, 0, 0, 0, 0, 0, + 176, 1, 0, 0, 16, 0, + 0, 0, 8, 0, 0, 0, + 0, 0, 0, 0, 192, 1, + 0, 0, 0, 0, 0, 0, + 208, 1, 0, 0, 24, 0, + 0, 0, 8, 0, 0, 0, + 0, 0, 0, 0, 192, 1, + 0, 0, 0, 0, 0, 0, + 222, 1, 0, 0, 32, 0, + 0, 0, 8, 0, 0, 0, + 0, 0, 0, 0, 240, 1, + 0, 0, 0, 0, 0, 0, + 0, 2, 0, 0, 40, 0, + 0, 0, 8, 0, 0, 0, + 0, 0, 0, 0, 240, 1, + 0, 0, 0, 0, 0, 0, + 17, 2, 0, 0, 48, 0, + 0, 0, 4, 0, 0, 0, + 0, 0, 0, 0, 124, 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, 54, + 46, 51, 46, 57, 54, 48, + 48, 46, 49, 54, 51, 56, + 52, 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, + 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, 96, 0, + 0, 0, 64, 0, 0, 0, + 24, 0, 0, 0, 89, 0, + 0, 4, 70, 142, 32, 0, + 0, 0, 0, 0, 1, 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/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/buffertotexture11_ps_4i.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/buffertotexture11_ps_4i.h index 407c8e0bf681..ac952f6df2a1 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/buffertotexture11_ps_4i.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/buffertotexture11_ps_4i.h @@ -1,128 +1,128 @@ -#if 0 -// -// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 -// -// -// Resource Bindings: -// -// Name Type Format Dim Slot Elements -// ------------------------------ ---------- ------- ----------- ---- -------- -// Buffer4I texture sint4 buf 0 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, 154, 139, - 95, 210, 76, 52, 228, 55, - 1, 175, 60, 90, 13, 234, - 138, 3, 1, 0, 0, 0, - 20, 2, 0, 0, 5, 0, - 0, 0, 52, 0, 0, 0, - 180, 0, 0, 0, 12, 1, - 0, 0, 64, 1, 0, 0, - 152, 1, 0, 0, 82, 68, - 69, 70, 120, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 1, 0, 0, 0, - 28, 0, 0, 0, 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, 54, 46, 51, 46, - 57, 54, 48, 48, 46, 49, - 54, 51, 56, 52, 0, 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 -}; +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 +// +// +// Resource Bindings: +// +// Name Type Format Dim Slot Elements +// ------------------------------ ---------- ------- ----------- ---- -------- +// Buffer4I texture sint4 buf 0 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, 154, 139, + 95, 210, 76, 52, 228, 55, + 1, 175, 60, 90, 13, 234, + 138, 3, 1, 0, 0, 0, + 20, 2, 0, 0, 5, 0, + 0, 0, 52, 0, 0, 0, + 180, 0, 0, 0, 12, 1, + 0, 0, 64, 1, 0, 0, + 152, 1, 0, 0, 82, 68, + 69, 70, 120, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 28, 0, 0, 0, 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, 54, 46, 51, 46, + 57, 54, 48, 48, 46, 49, + 54, 51, 56, 52, 0, 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/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/buffertotexture11_ps_4ui.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/buffertotexture11_ps_4ui.h index d4f6c164037b..fe7d6b27ab0a 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/buffertotexture11_ps_4ui.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/buffertotexture11_ps_4ui.h @@ -1,128 +1,128 @@ -#if 0 -// -// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 -// -// -// Resource Bindings: -// -// Name Type Format Dim Slot Elements -// ------------------------------ ---------- ------- ----------- ---- -------- -// Buffer4UI texture uint4 buf 0 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, 25, 164, - 1, 224, 250, 219, 16, 200, - 83, 99, 38, 137, 116, 129, - 200, 39, 1, 0, 0, 0, - 20, 2, 0, 0, 5, 0, - 0, 0, 52, 0, 0, 0, - 180, 0, 0, 0, 12, 1, - 0, 0, 64, 1, 0, 0, - 152, 1, 0, 0, 82, 68, - 69, 70, 120, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 1, 0, 0, 0, - 28, 0, 0, 0, 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, 54, 46, 51, - 46, 57, 54, 48, 48, 46, - 49, 54, 51, 56, 52, 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, 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 -}; +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 +// +// +// Resource Bindings: +// +// Name Type Format Dim Slot Elements +// ------------------------------ ---------- ------- ----------- ---- -------- +// Buffer4UI texture uint4 buf 0 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, 25, 164, + 1, 224, 250, 219, 16, 200, + 83, 99, 38, 137, 116, 129, + 200, 39, 1, 0, 0, 0, + 20, 2, 0, 0, 5, 0, + 0, 0, 52, 0, 0, 0, + 180, 0, 0, 0, 12, 1, + 0, 0, 64, 1, 0, 0, + 152, 1, 0, 0, 82, 68, + 69, 70, 120, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 28, 0, 0, 0, 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, 54, 46, 51, + 46, 57, 54, 48, 48, 46, + 49, 54, 51, 56, 52, 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, 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/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/buffertotexture11_vs.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/buffertotexture11_vs.h index 02ee45cfefb6..ac72f4be9cf0 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/buffertotexture11_vs.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/buffertotexture11_vs.h @@ -1,311 +1,311 @@ -#if 0 -// -// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 -// -// -// 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 Slot Elements -// ------------------------------ ---------- ------- ----------- ---- -------- -// BufferCopyParams cbuffer NA NA 0 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, 39, 207, - 138, 15, 42, 195, 141, 208, - 2, 107, 135, 197, 122, 36, - 114, 227, 1, 0, 0, 0, - 152, 5, 0, 0, 5, 0, - 0, 0, 52, 0, 0, 0, - 100, 2, 0, 0, 152, 2, - 0, 0, 12, 3, 0, 0, - 28, 5, 0, 0, 82, 68, - 69, 70, 40, 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, 54, 46, 51, 46, 57, - 54, 48, 48, 46, 49, 54, - 51, 56, 52, 0, 171, 171, - 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 -}; +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 +// +// +// 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 Slot Elements +// ------------------------------ ---------- ------- ----------- ---- -------- +// BufferCopyParams cbuffer NA NA 0 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, 39, 207, + 138, 15, 42, 195, 141, 208, + 2, 107, 135, 197, 122, 36, + 114, 227, 1, 0, 0, 0, + 152, 5, 0, 0, 5, 0, + 0, 0, 52, 0, 0, 0, + 100, 2, 0, 0, 152, 2, + 0, 0, 12, 3, 0, 0, + 28, 5, 0, 0, 82, 68, + 69, 70, 40, 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, 54, 46, 51, 46, 57, + 54, 48, 48, 46, 49, 54, + 51, 56, 52, 0, 171, 171, + 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/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11_fl9ps.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11_fl9ps.h index 3d90ea3ac87d..f8115b727755 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11_fl9ps.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11_fl9ps.h @@ -1,176 +1,176 @@ -#if 0 -// -// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 -// -// -// -// Input signature: -// -// Name Index Mask Register SysValue Format Used -// -------------------- ----- ------ -------- -------- ------- ------ -// SV_POSITION 0 xyzw 0 POS float -// COLOR 0 xyzw 1 NONE float xyzw -// -// -// 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 -// -// -// Level9 shader bytecode: -// - ps_2_x - dcl t0 - mov oC0, t0 - mov oC1, t0 - mov oC2, t0 - mov oC3, t0 - -// approximately 4 instruction slots used -ps_4_0 -dcl_input_ps linear v1.xyzw -dcl_output o0.xyzw -dcl_output o1.xyzw -dcl_output o2.xyzw -dcl_output o3.xyzw -mov o0.xyzw, v1.xyzw -mov o1.xyzw, v1.xyzw -mov o2.xyzw, v1.xyzw -mov o3.xyzw, v1.xyzw -ret -// Approximately 5 instruction slots used -#endif - -const BYTE g_PS_ClearFloat_FL9[] = -{ - 68, 88, 66, 67, 36, 167, - 59, 21, 253, 46, 206, 132, - 254, 28, 18, 118, 51, 115, - 45, 31, 1, 0, 0, 0, - 236, 2, 0, 0, 6, 0, - 0, 0, 56, 0, 0, 0, - 168, 0, 0, 0, 72, 1, - 0, 0, 196, 1, 0, 0, - 28, 2, 0, 0, 112, 2, - 0, 0, 65, 111, 110, 57, - 104, 0, 0, 0, 104, 0, - 0, 0, 0, 2, 255, 255, - 68, 0, 0, 0, 36, 0, - 0, 0, 0, 0, 36, 0, - 0, 0, 36, 0, 0, 0, - 36, 0, 0, 0, 36, 0, - 0, 0, 36, 0, 1, 2, - 255, 255, 31, 0, 0, 2, - 0, 0, 0, 128, 0, 0, - 15, 176, 1, 0, 0, 2, - 0, 8, 15, 128, 0, 0, - 228, 176, 1, 0, 0, 2, - 1, 8, 15, 128, 0, 0, - 228, 176, 1, 0, 0, 2, - 2, 8, 15, 128, 0, 0, - 228, 176, 1, 0, 0, 2, - 3, 8, 15, 128, 0, 0, - 228, 176, 255, 255, 0, 0, - 83, 72, 68, 82, 152, 0, - 0, 0, 64, 0, 0, 0, - 38, 0, 0, 0, 98, 16, - 0, 3, 242, 16, 16, 0, - 1, 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, 54, 0, - 0, 5, 242, 32, 16, 0, - 0, 0, 0, 0, 70, 30, - 16, 0, 1, 0, 0, 0, - 54, 0, 0, 5, 242, 32, - 16, 0, 1, 0, 0, 0, - 70, 30, 16, 0, 1, 0, - 0, 0, 54, 0, 0, 5, - 242, 32, 16, 0, 2, 0, - 0, 0, 70, 30, 16, 0, - 1, 0, 0, 0, 54, 0, - 0, 5, 242, 32, 16, 0, - 3, 0, 0, 0, 70, 30, - 16, 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, - 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, 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, 82, 68, 69, 70, - 80, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 28, 0, - 0, 0, 0, 4, 255, 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, 54, 46, 51, 46, 57, - 54, 48, 48, 46, 49, 54, - 51, 56, 52, 0, 171, 171, - 73, 83, 71, 78, 76, 0, - 0, 0, 2, 0, 0, 0, - 8, 0, 0, 0, 56, 0, - 0, 0, 0, 0, 0, 0, - 1, 0, 0, 0, 3, 0, - 0, 0, 0, 0, 0, 0, - 15, 0, 0, 0, 68, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 3, 0, - 0, 0, 1, 0, 0, 0, - 15, 15, 0, 0, 83, 86, - 95, 80, 79, 83, 73, 84, - 73, 79, 78, 0, 67, 79, - 76, 79, 82, 0, 171, 171, - 79, 83, 71, 78, 116, 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, 104, 0, - 0, 0, 3, 0, 0, 0, - 0, 0, 0, 0, 3, 0, - 0, 0, 3, 0, 0, 0, - 15, 0, 0, 0, 83, 86, - 95, 84, 65, 82, 71, 69, - 84, 0, 171, 171 -}; +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// COLOR 0 xyzw 1 NONE float xyzw +// +// +// 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 +// +// +// Level9 shader bytecode: +// + ps_2_x + dcl t0 + mov oC0, t0 + mov oC1, t0 + mov oC2, t0 + mov oC3, t0 + +// approximately 4 instruction slots used +ps_4_0 +dcl_input_ps linear v1.xyzw +dcl_output o0.xyzw +dcl_output o1.xyzw +dcl_output o2.xyzw +dcl_output o3.xyzw +mov o0.xyzw, v1.xyzw +mov o1.xyzw, v1.xyzw +mov o2.xyzw, v1.xyzw +mov o3.xyzw, v1.xyzw +ret +// Approximately 5 instruction slots used +#endif + +const BYTE g_PS_ClearFloat_FL9[] = +{ + 68, 88, 66, 67, 36, 167, + 59, 21, 253, 46, 206, 132, + 254, 28, 18, 118, 51, 115, + 45, 31, 1, 0, 0, 0, + 236, 2, 0, 0, 6, 0, + 0, 0, 56, 0, 0, 0, + 168, 0, 0, 0, 72, 1, + 0, 0, 196, 1, 0, 0, + 28, 2, 0, 0, 112, 2, + 0, 0, 65, 111, 110, 57, + 104, 0, 0, 0, 104, 0, + 0, 0, 0, 2, 255, 255, + 68, 0, 0, 0, 36, 0, + 0, 0, 0, 0, 36, 0, + 0, 0, 36, 0, 0, 0, + 36, 0, 0, 0, 36, 0, + 0, 0, 36, 0, 1, 2, + 255, 255, 31, 0, 0, 2, + 0, 0, 0, 128, 0, 0, + 15, 176, 1, 0, 0, 2, + 0, 8, 15, 128, 0, 0, + 228, 176, 1, 0, 0, 2, + 1, 8, 15, 128, 0, 0, + 228, 176, 1, 0, 0, 2, + 2, 8, 15, 128, 0, 0, + 228, 176, 1, 0, 0, 2, + 3, 8, 15, 128, 0, 0, + 228, 176, 255, 255, 0, 0, + 83, 72, 68, 82, 152, 0, + 0, 0, 64, 0, 0, 0, + 38, 0, 0, 0, 98, 16, + 0, 3, 242, 16, 16, 0, + 1, 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, 54, 0, + 0, 5, 242, 32, 16, 0, + 0, 0, 0, 0, 70, 30, + 16, 0, 1, 0, 0, 0, + 54, 0, 0, 5, 242, 32, + 16, 0, 1, 0, 0, 0, + 70, 30, 16, 0, 1, 0, + 0, 0, 54, 0, 0, 5, + 242, 32, 16, 0, 2, 0, + 0, 0, 70, 30, 16, 0, + 1, 0, 0, 0, 54, 0, + 0, 5, 242, 32, 16, 0, + 3, 0, 0, 0, 70, 30, + 16, 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, + 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, 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, 82, 68, 69, 70, + 80, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 28, 0, + 0, 0, 0, 4, 255, 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, 54, 46, 51, 46, 57, + 54, 48, 48, 46, 49, 54, + 51, 56, 52, 0, 171, 171, + 73, 83, 71, 78, 76, 0, + 0, 0, 2, 0, 0, 0, + 8, 0, 0, 0, 56, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 3, 0, + 0, 0, 0, 0, 0, 0, + 15, 0, 0, 0, 68, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3, 0, + 0, 0, 1, 0, 0, 0, + 15, 15, 0, 0, 83, 86, + 95, 80, 79, 83, 73, 84, + 73, 79, 78, 0, 67, 79, + 76, 79, 82, 0, 171, 171, + 79, 83, 71, 78, 116, 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, 104, 0, + 0, 0, 3, 0, 0, 0, + 0, 0, 0, 0, 3, 0, + 0, 0, 3, 0, 0, 0, + 15, 0, 0, 0, 83, 86, + 95, 84, 65, 82, 71, 69, + 84, 0, 171, 171 +}; diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11ps.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11ps.h index 360db1cfe138..a32268783901 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11ps.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11ps.h @@ -1,195 +1,195 @@ -#if 0 -// -// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 -// -// -// -// Input signature: -// -// Name Index Mask Register SysValue Format Used -// -------------------- ----- ------ -------- -------- ------- ------ -// SV_POSITION 0 xyzw 0 POS float -// COLOR 0 xyzw 1 NONE float xyzw -// -// -// 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 -// -ps_4_0 -dcl_input_ps linear v1.xyzw -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 -mov o0.xyzw, v1.xyzw -mov o1.xyzw, v1.xyzw -mov o2.xyzw, v1.xyzw -mov o3.xyzw, v1.xyzw -mov o4.xyzw, v1.xyzw -mov o5.xyzw, v1.xyzw -mov o6.xyzw, v1.xyzw -mov o7.xyzw, v1.xyzw -ret -// Approximately 9 instruction slots used -#endif - -const BYTE g_PS_ClearFloat[] = -{ - 68, 88, 66, 67, 19, 30, - 102, 69, 166, 219, 165, 14, - 173, 41, 171, 133, 144, 58, - 14, 224, 1, 0, 0, 0, - 88, 3, 0, 0, 5, 0, - 0, 0, 52, 0, 0, 0, - 140, 0, 0, 0, 224, 0, - 0, 0, 188, 1, 0, 0, - 220, 2, 0, 0, 82, 68, - 69, 70, 80, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 28, 0, 0, 0, 0, 4, - 255, 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, 54, 46, 51, - 46, 57, 54, 48, 48, 46, - 49, 54, 51, 56, 52, 0, - 171, 171, 73, 83, 71, 78, - 76, 0, 0, 0, 2, 0, - 0, 0, 8, 0, 0, 0, - 56, 0, 0, 0, 0, 0, - 0, 0, 1, 0, 0, 0, - 3, 0, 0, 0, 0, 0, - 0, 0, 15, 0, 0, 0, - 68, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 3, 0, 0, 0, 1, 0, - 0, 0, 15, 15, 0, 0, - 83, 86, 95, 80, 79, 83, - 73, 84, 73, 79, 78, 0, - 67, 79, 76, 79, 82, 0, - 171, 171, 79, 83, 71, 78, - 212, 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, - 200, 0, 0, 0, 7, 0, - 0, 0, 0, 0, 0, 0, - 3, 0, 0, 0, 7, 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, 98, 16, - 0, 3, 242, 16, 16, 0, - 1, 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, 54, 0, - 0, 5, 242, 32, 16, 0, - 0, 0, 0, 0, 70, 30, - 16, 0, 1, 0, 0, 0, - 54, 0, 0, 5, 242, 32, - 16, 0, 1, 0, 0, 0, - 70, 30, 16, 0, 1, 0, - 0, 0, 54, 0, 0, 5, - 242, 32, 16, 0, 2, 0, - 0, 0, 70, 30, 16, 0, - 1, 0, 0, 0, 54, 0, - 0, 5, 242, 32, 16, 0, - 3, 0, 0, 0, 70, 30, - 16, 0, 1, 0, 0, 0, - 54, 0, 0, 5, 242, 32, - 16, 0, 4, 0, 0, 0, - 70, 30, 16, 0, 1, 0, - 0, 0, 54, 0, 0, 5, - 242, 32, 16, 0, 5, 0, - 0, 0, 70, 30, 16, 0, - 1, 0, 0, 0, 54, 0, - 0, 5, 242, 32, 16, 0, - 6, 0, 0, 0, 70, 30, - 16, 0, 1, 0, 0, 0, - 54, 0, 0, 5, 242, 32, - 16, 0, 7, 0, 0, 0, - 70, 30, 16, 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, 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, - 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 -}; +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// COLOR 0 xyzw 1 NONE float xyzw +// +// +// 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 +// +ps_4_0 +dcl_input_ps linear v1.xyzw +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 +mov o0.xyzw, v1.xyzw +mov o1.xyzw, v1.xyzw +mov o2.xyzw, v1.xyzw +mov o3.xyzw, v1.xyzw +mov o4.xyzw, v1.xyzw +mov o5.xyzw, v1.xyzw +mov o6.xyzw, v1.xyzw +mov o7.xyzw, v1.xyzw +ret +// Approximately 9 instruction slots used +#endif + +const BYTE g_PS_ClearFloat[] = +{ + 68, 88, 66, 67, 19, 30, + 102, 69, 166, 219, 165, 14, + 173, 41, 171, 133, 144, 58, + 14, 224, 1, 0, 0, 0, + 88, 3, 0, 0, 5, 0, + 0, 0, 52, 0, 0, 0, + 140, 0, 0, 0, 224, 0, + 0, 0, 188, 1, 0, 0, + 220, 2, 0, 0, 82, 68, + 69, 70, 80, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 28, 0, 0, 0, 0, 4, + 255, 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, 54, 46, 51, + 46, 57, 54, 48, 48, 46, + 49, 54, 51, 56, 52, 0, + 171, 171, 73, 83, 71, 78, + 76, 0, 0, 0, 2, 0, + 0, 0, 8, 0, 0, 0, + 56, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 3, 0, 0, 0, 0, 0, + 0, 0, 15, 0, 0, 0, + 68, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 3, 0, 0, 0, 1, 0, + 0, 0, 15, 15, 0, 0, + 83, 86, 95, 80, 79, 83, + 73, 84, 73, 79, 78, 0, + 67, 79, 76, 79, 82, 0, + 171, 171, 79, 83, 71, 78, + 212, 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, + 200, 0, 0, 0, 7, 0, + 0, 0, 0, 0, 0, 0, + 3, 0, 0, 0, 7, 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, 98, 16, + 0, 3, 242, 16, 16, 0, + 1, 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, 54, 0, + 0, 5, 242, 32, 16, 0, + 0, 0, 0, 0, 70, 30, + 16, 0, 1, 0, 0, 0, + 54, 0, 0, 5, 242, 32, + 16, 0, 1, 0, 0, 0, + 70, 30, 16, 0, 1, 0, + 0, 0, 54, 0, 0, 5, + 242, 32, 16, 0, 2, 0, + 0, 0, 70, 30, 16, 0, + 1, 0, 0, 0, 54, 0, + 0, 5, 242, 32, 16, 0, + 3, 0, 0, 0, 70, 30, + 16, 0, 1, 0, 0, 0, + 54, 0, 0, 5, 242, 32, + 16, 0, 4, 0, 0, 0, + 70, 30, 16, 0, 1, 0, + 0, 0, 54, 0, 0, 5, + 242, 32, 16, 0, 5, 0, + 0, 0, 70, 30, 16, 0, + 1, 0, 0, 0, 54, 0, + 0, 5, 242, 32, 16, 0, + 6, 0, 0, 0, 70, 30, + 16, 0, 1, 0, 0, 0, + 54, 0, 0, 5, 242, 32, + 16, 0, 7, 0, 0, 0, + 70, 30, 16, 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, 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, + 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/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11vs.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11vs.h index 8965918b2fe2..06d75b95edfa 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11vs.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11vs.h @@ -1,175 +1,175 @@ -#if 0 -// -// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 -// -// -// -// Input signature: -// -// Name Index Mask Register SysValue Format Used -// -------------------- ----- ------ -------- -------- ------- ------ -// POSITION 0 xyz 0 NONE float xyz -// COLOR 0 xyzw 1 NONE float xyzw -// -// -// Output signature: -// -// Name Index Mask Register SysValue Format Used -// -------------------- ----- ------ -------- -------- ------- ------ -// SV_POSITION 0 xyzw 0 POS float xyzw -// COLOR 0 xyzw 1 NONE float xyzw -// -// -// Runtime generated constant mappings: -// -// Target Reg Constant Description -// ---------- -------------------------------------------------- -// c0 Vertex Shader position offset -// -// -// Level9 shader bytecode: -// - vs_2_x - def c1, 1, 0, 0, 0 - dcl_texcoord v0 - dcl_texcoord1 v1 - add oPos.xy, v0, c0 - mad oPos.zw, v0.z, c1.xyxy, c1.xyyx - mov oT0, v1 - -// approximately 3 instruction slots used -vs_4_0 -dcl_input v0.xyz -dcl_input v1.xyzw -dcl_output_siv o0.xyzw, position -dcl_output o1.xyzw -mov o0.xyz, v0.xyzx -mov o0.w, l(1.000000) -mov o1.xyzw, v1.xyzw -ret -// Approximately 4 instruction slots used -#endif - -const BYTE g_VS_ClearFloat[] = -{ - 68, 88, 66, 67, 254, 253, - 200, 174, 22, 35, 97, 190, - 187, 200, 253, 161, 246, 45, - 67, 66, 1, 0, 0, 0, - 204, 2, 0, 0, 6, 0, - 0, 0, 56, 0, 0, 0, - 208, 0, 0, 0, 84, 1, - 0, 0, 208, 1, 0, 0, - 40, 2, 0, 0, 120, 2, - 0, 0, 65, 111, 110, 57, - 144, 0, 0, 0, 144, 0, - 0, 0, 0, 2, 254, 255, - 104, 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, 128, 63, - 0, 0, 0, 0, 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, 4, 0, - 0, 4, 0, 0, 12, 192, - 0, 0, 170, 144, 1, 0, - 68, 160, 1, 0, 20, 160, - 1, 0, 0, 2, 0, 0, - 15, 224, 1, 0, 228, 144, - 255, 255, 0, 0, 83, 72, - 68, 82, 124, 0, 0, 0, - 64, 0, 1, 0, 31, 0, - 0, 0, 95, 0, 0, 3, - 114, 16, 16, 0, 0, 0, - 0, 0, 95, 0, 0, 3, - 242, 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, 242, 32, - 16, 0, 1, 0, 0, 0, - 54, 0, 0, 5, 114, 32, - 16, 0, 0, 0, 0, 0, - 70, 18, 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, 54, 0, - 0, 5, 242, 32, 16, 0, - 1, 0, 0, 0, 70, 30, - 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, - 80, 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, 54, 46, 51, 46, 57, - 54, 48, 48, 46, 49, 54, - 51, 56, 52, 0, 171, 171, - 73, 83, 71, 78, 72, 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, - 7, 7, 0, 0, 65, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 3, 0, - 0, 0, 1, 0, 0, 0, - 15, 15, 0, 0, 80, 79, - 83, 73, 84, 73, 79, 78, - 0, 67, 79, 76, 79, 82, - 0, 171, 79, 83, 71, 78, - 76, 0, 0, 0, 2, 0, - 0, 0, 8, 0, 0, 0, - 56, 0, 0, 0, 0, 0, - 0, 0, 1, 0, 0, 0, - 3, 0, 0, 0, 0, 0, - 0, 0, 15, 0, 0, 0, - 68, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 3, 0, 0, 0, 1, 0, - 0, 0, 15, 0, 0, 0, - 83, 86, 95, 80, 79, 83, - 73, 84, 73, 79, 78, 0, - 67, 79, 76, 79, 82, 0, - 171, 171 -}; +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// POSITION 0 xyz 0 NONE float xyz +// COLOR 0 xyzw 1 NONE float xyzw +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float xyzw +// COLOR 0 xyzw 1 NONE float xyzw +// +// +// Runtime generated constant mappings: +// +// Target Reg Constant Description +// ---------- -------------------------------------------------- +// c0 Vertex Shader position offset +// +// +// Level9 shader bytecode: +// + vs_2_x + def c1, 1, 0, 0, 0 + dcl_texcoord v0 + dcl_texcoord1 v1 + add oPos.xy, v0, c0 + mad oPos.zw, v0.z, c1.xyxy, c1.xyyx + mov oT0, v1 + +// approximately 3 instruction slots used +vs_4_0 +dcl_input v0.xyz +dcl_input v1.xyzw +dcl_output_siv o0.xyzw, position +dcl_output o1.xyzw +mov o0.xyz, v0.xyzx +mov o0.w, l(1.000000) +mov o1.xyzw, v1.xyzw +ret +// Approximately 4 instruction slots used +#endif + +const BYTE g_VS_ClearFloat[] = +{ + 68, 88, 66, 67, 254, 253, + 200, 174, 22, 35, 97, 190, + 187, 200, 253, 161, 246, 45, + 67, 66, 1, 0, 0, 0, + 204, 2, 0, 0, 6, 0, + 0, 0, 56, 0, 0, 0, + 208, 0, 0, 0, 84, 1, + 0, 0, 208, 1, 0, 0, + 40, 2, 0, 0, 120, 2, + 0, 0, 65, 111, 110, 57, + 144, 0, 0, 0, 144, 0, + 0, 0, 0, 2, 254, 255, + 104, 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, 128, 63, + 0, 0, 0, 0, 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, 4, 0, + 0, 4, 0, 0, 12, 192, + 0, 0, 170, 144, 1, 0, + 68, 160, 1, 0, 20, 160, + 1, 0, 0, 2, 0, 0, + 15, 224, 1, 0, 228, 144, + 255, 255, 0, 0, 83, 72, + 68, 82, 124, 0, 0, 0, + 64, 0, 1, 0, 31, 0, + 0, 0, 95, 0, 0, 3, + 114, 16, 16, 0, 0, 0, + 0, 0, 95, 0, 0, 3, + 242, 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, 242, 32, + 16, 0, 1, 0, 0, 0, + 54, 0, 0, 5, 114, 32, + 16, 0, 0, 0, 0, 0, + 70, 18, 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, 54, 0, + 0, 5, 242, 32, 16, 0, + 1, 0, 0, 0, 70, 30, + 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, + 80, 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, 54, 46, 51, 46, 57, + 54, 48, 48, 46, 49, 54, + 51, 56, 52, 0, 171, 171, + 73, 83, 71, 78, 72, 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, + 7, 7, 0, 0, 65, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3, 0, + 0, 0, 1, 0, 0, 0, + 15, 15, 0, 0, 80, 79, + 83, 73, 84, 73, 79, 78, + 0, 67, 79, 76, 79, 82, + 0, 171, 79, 83, 71, 78, + 76, 0, 0, 0, 2, 0, + 0, 0, 8, 0, 0, 0, + 56, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 3, 0, 0, 0, 0, 0, + 0, 0, 15, 0, 0, 0, + 68, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 3, 0, 0, 0, 1, 0, + 0, 0, 15, 0, 0, 0, + 83, 86, 95, 80, 79, 83, + 73, 84, 73, 79, 78, 0, + 67, 79, 76, 79, 82, 0, + 171, 171 +}; diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearsint11ps.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearsint11ps.h index 5e6238967f7d..6e009f4725a4 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearsint11ps.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearsint11ps.h @@ -1,195 +1,195 @@ -#if 0 -// -// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 -// -// -// -// Input signature: -// -// Name Index Mask Register SysValue Format Used -// -------------------- ----- ------ -------- -------- ------- ------ -// SV_POSITION 0 xyzw 0 POS float -// COLOR 0 xyzw 1 NONE int xyzw -// -// -// 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 -// -ps_4_0 -dcl_input_ps constant v1.xyzw -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 -mov o0.xyzw, v1.xyzw -mov o1.xyzw, v1.xyzw -mov o2.xyzw, v1.xyzw -mov o3.xyzw, v1.xyzw -mov o4.xyzw, v1.xyzw -mov o5.xyzw, v1.xyzw -mov o6.xyzw, v1.xyzw -mov o7.xyzw, v1.xyzw -ret -// Approximately 9 instruction slots used -#endif - -const BYTE g_PS_ClearSint[] = -{ - 68, 88, 66, 67, 206, 129, - 255, 236, 115, 217, 216, 20, - 88, 47, 155, 195, 145, 179, - 183, 28, 1, 0, 0, 0, - 88, 3, 0, 0, 5, 0, - 0, 0, 52, 0, 0, 0, - 140, 0, 0, 0, 224, 0, - 0, 0, 188, 1, 0, 0, - 220, 2, 0, 0, 82, 68, - 69, 70, 80, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 28, 0, 0, 0, 0, 4, - 255, 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, 54, 46, 51, - 46, 57, 54, 48, 48, 46, - 49, 54, 51, 56, 52, 0, - 171, 171, 73, 83, 71, 78, - 76, 0, 0, 0, 2, 0, - 0, 0, 8, 0, 0, 0, - 56, 0, 0, 0, 0, 0, - 0, 0, 1, 0, 0, 0, - 3, 0, 0, 0, 0, 0, - 0, 0, 15, 0, 0, 0, - 68, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 2, 0, 0, 0, 1, 0, - 0, 0, 15, 15, 0, 0, - 83, 86, 95, 80, 79, 83, - 73, 84, 73, 79, 78, 0, - 67, 79, 76, 79, 82, 0, - 171, 171, 79, 83, 71, 78, - 212, 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, - 200, 0, 0, 0, 7, 0, - 0, 0, 0, 0, 0, 0, - 2, 0, 0, 0, 7, 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, 98, 8, - 0, 3, 242, 16, 16, 0, - 1, 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, 54, 0, - 0, 5, 242, 32, 16, 0, - 0, 0, 0, 0, 70, 30, - 16, 0, 1, 0, 0, 0, - 54, 0, 0, 5, 242, 32, - 16, 0, 1, 0, 0, 0, - 70, 30, 16, 0, 1, 0, - 0, 0, 54, 0, 0, 5, - 242, 32, 16, 0, 2, 0, - 0, 0, 70, 30, 16, 0, - 1, 0, 0, 0, 54, 0, - 0, 5, 242, 32, 16, 0, - 3, 0, 0, 0, 70, 30, - 16, 0, 1, 0, 0, 0, - 54, 0, 0, 5, 242, 32, - 16, 0, 4, 0, 0, 0, - 70, 30, 16, 0, 1, 0, - 0, 0, 54, 0, 0, 5, - 242, 32, 16, 0, 5, 0, - 0, 0, 70, 30, 16, 0, - 1, 0, 0, 0, 54, 0, - 0, 5, 242, 32, 16, 0, - 6, 0, 0, 0, 70, 30, - 16, 0, 1, 0, 0, 0, - 54, 0, 0, 5, 242, 32, - 16, 0, 7, 0, 0, 0, - 70, 30, 16, 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, 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, - 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 -}; +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// COLOR 0 xyzw 1 NONE int xyzw +// +// +// 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 +// +ps_4_0 +dcl_input_ps constant v1.xyzw +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 +mov o0.xyzw, v1.xyzw +mov o1.xyzw, v1.xyzw +mov o2.xyzw, v1.xyzw +mov o3.xyzw, v1.xyzw +mov o4.xyzw, v1.xyzw +mov o5.xyzw, v1.xyzw +mov o6.xyzw, v1.xyzw +mov o7.xyzw, v1.xyzw +ret +// Approximately 9 instruction slots used +#endif + +const BYTE g_PS_ClearSint[] = +{ + 68, 88, 66, 67, 206, 129, + 255, 236, 115, 217, 216, 20, + 88, 47, 155, 195, 145, 179, + 183, 28, 1, 0, 0, 0, + 88, 3, 0, 0, 5, 0, + 0, 0, 52, 0, 0, 0, + 140, 0, 0, 0, 224, 0, + 0, 0, 188, 1, 0, 0, + 220, 2, 0, 0, 82, 68, + 69, 70, 80, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 28, 0, 0, 0, 0, 4, + 255, 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, 54, 46, 51, + 46, 57, 54, 48, 48, 46, + 49, 54, 51, 56, 52, 0, + 171, 171, 73, 83, 71, 78, + 76, 0, 0, 0, 2, 0, + 0, 0, 8, 0, 0, 0, + 56, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 3, 0, 0, 0, 0, 0, + 0, 0, 15, 0, 0, 0, + 68, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 2, 0, 0, 0, 1, 0, + 0, 0, 15, 15, 0, 0, + 83, 86, 95, 80, 79, 83, + 73, 84, 73, 79, 78, 0, + 67, 79, 76, 79, 82, 0, + 171, 171, 79, 83, 71, 78, + 212, 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, + 200, 0, 0, 0, 7, 0, + 0, 0, 0, 0, 0, 0, + 2, 0, 0, 0, 7, 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, 98, 8, + 0, 3, 242, 16, 16, 0, + 1, 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, 54, 0, + 0, 5, 242, 32, 16, 0, + 0, 0, 0, 0, 70, 30, + 16, 0, 1, 0, 0, 0, + 54, 0, 0, 5, 242, 32, + 16, 0, 1, 0, 0, 0, + 70, 30, 16, 0, 1, 0, + 0, 0, 54, 0, 0, 5, + 242, 32, 16, 0, 2, 0, + 0, 0, 70, 30, 16, 0, + 1, 0, 0, 0, 54, 0, + 0, 5, 242, 32, 16, 0, + 3, 0, 0, 0, 70, 30, + 16, 0, 1, 0, 0, 0, + 54, 0, 0, 5, 242, 32, + 16, 0, 4, 0, 0, 0, + 70, 30, 16, 0, 1, 0, + 0, 0, 54, 0, 0, 5, + 242, 32, 16, 0, 5, 0, + 0, 0, 70, 30, 16, 0, + 1, 0, 0, 0, 54, 0, + 0, 5, 242, 32, 16, 0, + 6, 0, 0, 0, 70, 30, + 16, 0, 1, 0, 0, 0, + 54, 0, 0, 5, 242, 32, + 16, 0, 7, 0, 0, 0, + 70, 30, 16, 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, 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, + 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/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearsint11vs.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearsint11vs.h index 7bc8fdb65dc5..f162b4449da2 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearsint11vs.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearsint11vs.h @@ -1,130 +1,130 @@ -#if 0 -// -// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 -// -// -// -// Input signature: -// -// Name Index Mask Register SysValue Format Used -// -------------------- ----- ------ -------- -------- ------- ------ -// POSITION 0 xyz 0 NONE float xyz -// COLOR 0 xyzw 1 NONE int xyzw -// -// -// Output signature: -// -// Name Index Mask Register SysValue Format Used -// -------------------- ----- ------ -------- -------- ------- ------ -// SV_POSITION 0 xyzw 0 POS float xyzw -// COLOR 0 xyzw 1 NONE int xyzw -// -vs_4_0 -dcl_input v0.xyz -dcl_input v1.xyzw -dcl_output_siv o0.xyzw, position -dcl_output o1.xyzw -mov o0.xyz, v0.xyzx -mov o0.w, l(1.000000) -mov o1.xyzw, v1.xyzw -ret -// Approximately 4 instruction slots used -#endif - -const BYTE g_VS_ClearSint[] = -{ - 68, 88, 66, 67, 20, 240, - 85, 136, 255, 181, 253, 103, - 207, 181, 122, 106, 92, 25, - 228, 89, 1, 0, 0, 0, - 48, 2, 0, 0, 5, 0, - 0, 0, 52, 0, 0, 0, - 140, 0, 0, 0, 220, 0, - 0, 0, 48, 1, 0, 0, - 180, 1, 0, 0, 82, 68, - 69, 70, 80, 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, 54, 46, 51, - 46, 57, 54, 48, 48, 46, - 49, 54, 51, 56, 52, 0, - 171, 171, 73, 83, 71, 78, - 72, 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, 7, 7, 0, 0, - 65, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 2, 0, 0, 0, 1, 0, - 0, 0, 15, 15, 0, 0, - 80, 79, 83, 73, 84, 73, - 79, 78, 0, 67, 79, 76, - 79, 82, 0, 171, 79, 83, - 71, 78, 76, 0, 0, 0, - 2, 0, 0, 0, 8, 0, - 0, 0, 56, 0, 0, 0, - 0, 0, 0, 0, 1, 0, - 0, 0, 3, 0, 0, 0, - 0, 0, 0, 0, 15, 0, - 0, 0, 68, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 2, 0, 0, 0, - 1, 0, 0, 0, 15, 0, - 0, 0, 83, 86, 95, 80, - 79, 83, 73, 84, 73, 79, - 78, 0, 67, 79, 76, 79, - 82, 0, 171, 171, 83, 72, - 68, 82, 124, 0, 0, 0, - 64, 0, 1, 0, 31, 0, - 0, 0, 95, 0, 0, 3, - 114, 16, 16, 0, 0, 0, - 0, 0, 95, 0, 0, 3, - 242, 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, 242, 32, - 16, 0, 1, 0, 0, 0, - 54, 0, 0, 5, 114, 32, - 16, 0, 0, 0, 0, 0, - 70, 18, 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, 54, 0, - 0, 5, 242, 32, 16, 0, - 1, 0, 0, 0, 70, 30, - 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 -}; +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// POSITION 0 xyz 0 NONE float xyz +// COLOR 0 xyzw 1 NONE int xyzw +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float xyzw +// COLOR 0 xyzw 1 NONE int xyzw +// +vs_4_0 +dcl_input v0.xyz +dcl_input v1.xyzw +dcl_output_siv o0.xyzw, position +dcl_output o1.xyzw +mov o0.xyz, v0.xyzx +mov o0.w, l(1.000000) +mov o1.xyzw, v1.xyzw +ret +// Approximately 4 instruction slots used +#endif + +const BYTE g_VS_ClearSint[] = +{ + 68, 88, 66, 67, 20, 240, + 85, 136, 255, 181, 253, 103, + 207, 181, 122, 106, 92, 25, + 228, 89, 1, 0, 0, 0, + 48, 2, 0, 0, 5, 0, + 0, 0, 52, 0, 0, 0, + 140, 0, 0, 0, 220, 0, + 0, 0, 48, 1, 0, 0, + 180, 1, 0, 0, 82, 68, + 69, 70, 80, 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, 54, 46, 51, + 46, 57, 54, 48, 48, 46, + 49, 54, 51, 56, 52, 0, + 171, 171, 73, 83, 71, 78, + 72, 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, 7, 7, 0, 0, + 65, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 2, 0, 0, 0, 1, 0, + 0, 0, 15, 15, 0, 0, + 80, 79, 83, 73, 84, 73, + 79, 78, 0, 67, 79, 76, + 79, 82, 0, 171, 79, 83, + 71, 78, 76, 0, 0, 0, + 2, 0, 0, 0, 8, 0, + 0, 0, 56, 0, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 3, 0, 0, 0, + 0, 0, 0, 0, 15, 0, + 0, 0, 68, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 2, 0, 0, 0, + 1, 0, 0, 0, 15, 0, + 0, 0, 83, 86, 95, 80, + 79, 83, 73, 84, 73, 79, + 78, 0, 67, 79, 76, 79, + 82, 0, 171, 171, 83, 72, + 68, 82, 124, 0, 0, 0, + 64, 0, 1, 0, 31, 0, + 0, 0, 95, 0, 0, 3, + 114, 16, 16, 0, 0, 0, + 0, 0, 95, 0, 0, 3, + 242, 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, 242, 32, + 16, 0, 1, 0, 0, 0, + 54, 0, 0, 5, 114, 32, + 16, 0, 0, 0, 0, 0, + 70, 18, 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, 54, 0, + 0, 5, 242, 32, 16, 0, + 1, 0, 0, 0, 70, 30, + 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 +}; diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearuint11ps.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearuint11ps.h index fdce95cc7b6b..c53650bd8f6c 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearuint11ps.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearuint11ps.h @@ -1,195 +1,195 @@ -#if 0 -// -// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 -// -// -// -// Input signature: -// -// Name Index Mask Register SysValue Format Used -// -------------------- ----- ------ -------- -------- ------- ------ -// SV_POSITION 0 xyzw 0 POS float -// COLOR 0 xyzw 1 NONE uint xyzw -// -// -// 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 -// -ps_4_0 -dcl_input_ps constant v1.xyzw -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 -mov o0.xyzw, v1.xyzw -mov o1.xyzw, v1.xyzw -mov o2.xyzw, v1.xyzw -mov o3.xyzw, v1.xyzw -mov o4.xyzw, v1.xyzw -mov o5.xyzw, v1.xyzw -mov o6.xyzw, v1.xyzw -mov o7.xyzw, v1.xyzw -ret -// Approximately 9 instruction slots used -#endif - -const BYTE g_PS_ClearUint[] = -{ - 68, 88, 66, 67, 117, 209, - 142, 159, 65, 29, 212, 206, - 242, 37, 169, 58, 35, 236, - 222, 73, 1, 0, 0, 0, - 88, 3, 0, 0, 5, 0, - 0, 0, 52, 0, 0, 0, - 140, 0, 0, 0, 224, 0, - 0, 0, 188, 1, 0, 0, - 220, 2, 0, 0, 82, 68, - 69, 70, 80, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 28, 0, 0, 0, 0, 4, - 255, 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, 54, 46, 51, - 46, 57, 54, 48, 48, 46, - 49, 54, 51, 56, 52, 0, - 171, 171, 73, 83, 71, 78, - 76, 0, 0, 0, 2, 0, - 0, 0, 8, 0, 0, 0, - 56, 0, 0, 0, 0, 0, - 0, 0, 1, 0, 0, 0, - 3, 0, 0, 0, 0, 0, - 0, 0, 15, 0, 0, 0, - 68, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 1, 0, 0, 0, 1, 0, - 0, 0, 15, 15, 0, 0, - 83, 86, 95, 80, 79, 83, - 73, 84, 73, 79, 78, 0, - 67, 79, 76, 79, 82, 0, - 171, 171, 79, 83, 71, 78, - 212, 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, - 200, 0, 0, 0, 7, 0, - 0, 0, 0, 0, 0, 0, - 1, 0, 0, 0, 7, 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, 98, 8, - 0, 3, 242, 16, 16, 0, - 1, 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, 54, 0, - 0, 5, 242, 32, 16, 0, - 0, 0, 0, 0, 70, 30, - 16, 0, 1, 0, 0, 0, - 54, 0, 0, 5, 242, 32, - 16, 0, 1, 0, 0, 0, - 70, 30, 16, 0, 1, 0, - 0, 0, 54, 0, 0, 5, - 242, 32, 16, 0, 2, 0, - 0, 0, 70, 30, 16, 0, - 1, 0, 0, 0, 54, 0, - 0, 5, 242, 32, 16, 0, - 3, 0, 0, 0, 70, 30, - 16, 0, 1, 0, 0, 0, - 54, 0, 0, 5, 242, 32, - 16, 0, 4, 0, 0, 0, - 70, 30, 16, 0, 1, 0, - 0, 0, 54, 0, 0, 5, - 242, 32, 16, 0, 5, 0, - 0, 0, 70, 30, 16, 0, - 1, 0, 0, 0, 54, 0, - 0, 5, 242, 32, 16, 0, - 6, 0, 0, 0, 70, 30, - 16, 0, 1, 0, 0, 0, - 54, 0, 0, 5, 242, 32, - 16, 0, 7, 0, 0, 0, - 70, 30, 16, 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, 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, - 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 -}; +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// COLOR 0 xyzw 1 NONE uint xyzw +// +// +// 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 +// +ps_4_0 +dcl_input_ps constant v1.xyzw +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 +mov o0.xyzw, v1.xyzw +mov o1.xyzw, v1.xyzw +mov o2.xyzw, v1.xyzw +mov o3.xyzw, v1.xyzw +mov o4.xyzw, v1.xyzw +mov o5.xyzw, v1.xyzw +mov o6.xyzw, v1.xyzw +mov o7.xyzw, v1.xyzw +ret +// Approximately 9 instruction slots used +#endif + +const BYTE g_PS_ClearUint[] = +{ + 68, 88, 66, 67, 117, 209, + 142, 159, 65, 29, 212, 206, + 242, 37, 169, 58, 35, 236, + 222, 73, 1, 0, 0, 0, + 88, 3, 0, 0, 5, 0, + 0, 0, 52, 0, 0, 0, + 140, 0, 0, 0, 224, 0, + 0, 0, 188, 1, 0, 0, + 220, 2, 0, 0, 82, 68, + 69, 70, 80, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 28, 0, 0, 0, 0, 4, + 255, 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, 54, 46, 51, + 46, 57, 54, 48, 48, 46, + 49, 54, 51, 56, 52, 0, + 171, 171, 73, 83, 71, 78, + 76, 0, 0, 0, 2, 0, + 0, 0, 8, 0, 0, 0, + 56, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 3, 0, 0, 0, 0, 0, + 0, 0, 15, 0, 0, 0, + 68, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 1, 0, + 0, 0, 15, 15, 0, 0, + 83, 86, 95, 80, 79, 83, + 73, 84, 73, 79, 78, 0, + 67, 79, 76, 79, 82, 0, + 171, 171, 79, 83, 71, 78, + 212, 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, + 200, 0, 0, 0, 7, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 7, 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, 98, 8, + 0, 3, 242, 16, 16, 0, + 1, 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, 54, 0, + 0, 5, 242, 32, 16, 0, + 0, 0, 0, 0, 70, 30, + 16, 0, 1, 0, 0, 0, + 54, 0, 0, 5, 242, 32, + 16, 0, 1, 0, 0, 0, + 70, 30, 16, 0, 1, 0, + 0, 0, 54, 0, 0, 5, + 242, 32, 16, 0, 2, 0, + 0, 0, 70, 30, 16, 0, + 1, 0, 0, 0, 54, 0, + 0, 5, 242, 32, 16, 0, + 3, 0, 0, 0, 70, 30, + 16, 0, 1, 0, 0, 0, + 54, 0, 0, 5, 242, 32, + 16, 0, 4, 0, 0, 0, + 70, 30, 16, 0, 1, 0, + 0, 0, 54, 0, 0, 5, + 242, 32, 16, 0, 5, 0, + 0, 0, 70, 30, 16, 0, + 1, 0, 0, 0, 54, 0, + 0, 5, 242, 32, 16, 0, + 6, 0, 0, 0, 70, 30, + 16, 0, 1, 0, 0, 0, + 54, 0, 0, 5, 242, 32, + 16, 0, 7, 0, 0, 0, + 70, 30, 16, 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, 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, + 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/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearuint11vs.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearuint11vs.h index ce1edbfc13a7..cfad90f687f9 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearuint11vs.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearuint11vs.h @@ -1,130 +1,130 @@ -#if 0 -// -// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 -// -// -// -// Input signature: -// -// Name Index Mask Register SysValue Format Used -// -------------------- ----- ------ -------- -------- ------- ------ -// POSITION 0 xyz 0 NONE float xyz -// COLOR 0 xyzw 1 NONE uint xyzw -// -// -// Output signature: -// -// Name Index Mask Register SysValue Format Used -// -------------------- ----- ------ -------- -------- ------- ------ -// SV_POSITION 0 xyzw 0 POS float xyzw -// COLOR 0 xyzw 1 NONE uint xyzw -// -vs_4_0 -dcl_input v0.xyz -dcl_input v1.xyzw -dcl_output_siv o0.xyzw, position -dcl_output o1.xyzw -mov o0.xyz, v0.xyzx -mov o0.w, l(1.000000) -mov o1.xyzw, v1.xyzw -ret -// Approximately 4 instruction slots used -#endif - -const BYTE g_VS_ClearUint[] = -{ - 68, 88, 66, 67, 62, 191, - 52, 95, 60, 98, 193, 75, - 194, 36, 187, 194, 54, 24, - 232, 224, 1, 0, 0, 0, - 48, 2, 0, 0, 5, 0, - 0, 0, 52, 0, 0, 0, - 140, 0, 0, 0, 220, 0, - 0, 0, 48, 1, 0, 0, - 180, 1, 0, 0, 82, 68, - 69, 70, 80, 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, 54, 46, 51, - 46, 57, 54, 48, 48, 46, - 49, 54, 51, 56, 52, 0, - 171, 171, 73, 83, 71, 78, - 72, 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, 7, 7, 0, 0, - 65, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 1, 0, 0, 0, 1, 0, - 0, 0, 15, 15, 0, 0, - 80, 79, 83, 73, 84, 73, - 79, 78, 0, 67, 79, 76, - 79, 82, 0, 171, 79, 83, - 71, 78, 76, 0, 0, 0, - 2, 0, 0, 0, 8, 0, - 0, 0, 56, 0, 0, 0, - 0, 0, 0, 0, 1, 0, - 0, 0, 3, 0, 0, 0, - 0, 0, 0, 0, 15, 0, - 0, 0, 68, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 1, 0, 0, 0, - 1, 0, 0, 0, 15, 0, - 0, 0, 83, 86, 95, 80, - 79, 83, 73, 84, 73, 79, - 78, 0, 67, 79, 76, 79, - 82, 0, 171, 171, 83, 72, - 68, 82, 124, 0, 0, 0, - 64, 0, 1, 0, 31, 0, - 0, 0, 95, 0, 0, 3, - 114, 16, 16, 0, 0, 0, - 0, 0, 95, 0, 0, 3, - 242, 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, 242, 32, - 16, 0, 1, 0, 0, 0, - 54, 0, 0, 5, 114, 32, - 16, 0, 0, 0, 0, 0, - 70, 18, 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, 54, 0, - 0, 5, 242, 32, 16, 0, - 1, 0, 0, 0, 70, 30, - 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 -}; +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// POSITION 0 xyz 0 NONE float xyz +// COLOR 0 xyzw 1 NONE uint xyzw +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float xyzw +// COLOR 0 xyzw 1 NONE uint xyzw +// +vs_4_0 +dcl_input v0.xyz +dcl_input v1.xyzw +dcl_output_siv o0.xyzw, position +dcl_output o1.xyzw +mov o0.xyz, v0.xyzx +mov o0.w, l(1.000000) +mov o1.xyzw, v1.xyzw +ret +// Approximately 4 instruction slots used +#endif + +const BYTE g_VS_ClearUint[] = +{ + 68, 88, 66, 67, 62, 191, + 52, 95, 60, 98, 193, 75, + 194, 36, 187, 194, 54, 24, + 232, 224, 1, 0, 0, 0, + 48, 2, 0, 0, 5, 0, + 0, 0, 52, 0, 0, 0, + 140, 0, 0, 0, 220, 0, + 0, 0, 48, 1, 0, 0, + 180, 1, 0, 0, 82, 68, + 69, 70, 80, 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, 54, 46, 51, + 46, 57, 54, 48, 48, 46, + 49, 54, 51, 56, 52, 0, + 171, 171, 73, 83, 71, 78, + 72, 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, 7, 7, 0, 0, + 65, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 1, 0, + 0, 0, 15, 15, 0, 0, + 80, 79, 83, 73, 84, 73, + 79, 78, 0, 67, 79, 76, + 79, 82, 0, 171, 79, 83, + 71, 78, 76, 0, 0, 0, + 2, 0, 0, 0, 8, 0, + 0, 0, 56, 0, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 3, 0, 0, 0, + 0, 0, 0, 0, 15, 0, + 0, 0, 68, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 15, 0, + 0, 0, 83, 86, 95, 80, + 79, 83, 73, 84, 73, 79, + 78, 0, 67, 79, 76, 79, + 82, 0, 171, 171, 83, 72, + 68, 82, 124, 0, 0, 0, + 64, 0, 1, 0, 31, 0, + 0, 0, 95, 0, 0, 3, + 114, 16, 16, 0, 0, 0, + 0, 0, 95, 0, 0, 3, + 242, 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, 242, 32, + 16, 0, 1, 0, 0, 0, + 54, 0, 0, 5, 114, 32, + 16, 0, 0, 0, 0, 0, + 70, 18, 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, 54, 0, + 0, 5, 242, 32, 16, 0, + 1, 0, 0, 0, 70, 30, + 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 +}; diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthrough2d11vs.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthrough2d11vs.h index 6cd540100117..050040e74b9f 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthrough2d11vs.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthrough2d11vs.h @@ -1,177 +1,177 @@ -#if 0 -// -// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 -// -// -// -// 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, 230, 95, - 115, 230, 65, 211, 74, 82, - 143, 170, 109, 175, 63, 210, - 14, 229, 1, 0, 0, 0, - 216, 2, 0, 0, 6, 0, - 0, 0, 56, 0, 0, 0, - 200, 0, 0, 0, 88, 1, - 0, 0, 212, 1, 0, 0, - 44, 2, 0, 0, 128, 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, 80, 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, 54, - 46, 51, 46, 57, 54, 48, - 48, 46, 49, 54, 51, 56, - 52, 0, 171, 171, 73, 83, - 71, 78, 76, 0, 0, 0, - 2, 0, 0, 0, 8, 0, - 0, 0, 56, 0, 0, 0, - 0, 0, 0, 0, 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 -}; +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 +// +// +// +// 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, 230, 95, + 115, 230, 65, 211, 74, 82, + 143, 170, 109, 175, 63, 210, + 14, 229, 1, 0, 0, 0, + 216, 2, 0, 0, 6, 0, + 0, 0, 56, 0, 0, 0, + 200, 0, 0, 0, 88, 1, + 0, 0, 212, 1, 0, 0, + 44, 2, 0, 0, 128, 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, 80, 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, 54, + 46, 51, 46, 57, 54, 48, + 48, 46, 49, 54, 51, 56, + 52, 0, 171, 171, 73, 83, + 71, 78, 76, 0, 0, 0, + 2, 0, 0, 0, 8, 0, + 0, 0, 56, 0, 0, 0, + 0, 0, 0, 0, 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/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthrough3d11gs.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthrough3d11gs.h index 86af2d9a1ccd..ae2d9485eb09 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthrough3d11gs.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthrough3d11gs.h @@ -1,191 +1,191 @@ -#if 0 -// -// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 -// -// -// -// 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, 92, 129, - 41, 170, 114, 75, 160, 250, - 95, 161, 230, 161, 11, 78, - 252, 65, 1, 0, 0, 0, - 72, 3, 0, 0, 5, 0, - 0, 0, 52, 0, 0, 0, - 140, 0, 0, 0, 0, 1, - 0, 0, 136, 1, 0, 0, - 204, 2, 0, 0, 82, 68, - 69, 70, 80, 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, 54, 46, 51, - 46, 57, 54, 48, 48, 46, - 49, 54, 51, 56, 52, 0, - 171, 171, 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 -}; +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 +// +// +// +// 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, 92, 129, + 41, 170, 114, 75, 160, 250, + 95, 161, 230, 161, 11, 78, + 252, 65, 1, 0, 0, 0, + 72, 3, 0, 0, 5, 0, + 0, 0, 52, 0, 0, 0, + 140, 0, 0, 0, 0, 1, + 0, 0, 136, 1, 0, 0, + 204, 2, 0, 0, 82, 68, + 69, 70, 80, 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, 54, 46, 51, + 46, 57, 54, 48, 48, 46, + 49, 54, 51, 56, 52, 0, + 171, 171, 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/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthrough3d11vs.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthrough3d11vs.h index f053642c895c..5701a4036a1f 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthrough3d11vs.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthrough3d11vs.h @@ -1,155 +1,155 @@ -#if 0 -// -// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 -// -// -// -// 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, 229, 65, - 217, 172, 143, 180, 152, 72, - 16, 12, 254, 66, 0, 215, - 50, 173, 1, 0, 0, 0, - 168, 2, 0, 0, 5, 0, - 0, 0, 52, 0, 0, 0, - 140, 0, 0, 0, 252, 0, - 0, 0, 112, 1, 0, 0, - 44, 2, 0, 0, 82, 68, - 69, 70, 80, 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, 54, 46, 51, - 46, 57, 54, 48, 48, 46, - 49, 54, 51, 56, 52, 0, - 171, 171, 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 -}; +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 +// +// +// +// 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, 229, 65, + 217, 172, 143, 180, 152, 72, + 16, 12, 254, 66, 0, 215, + 50, 173, 1, 0, 0, 0, + 168, 2, 0, 0, 5, 0, + 0, 0, 52, 0, 0, 0, + 140, 0, 0, 0, 252, 0, + 0, 0, 112, 1, 0, 0, + 44, 2, 0, 0, 82, 68, + 69, 70, 80, 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, 54, 46, 51, + 46, 57, 54, 48, 48, 46, + 49, 54, 51, 56, 52, 0, + 171, 171, 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/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughdepth2d11ps.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughdepth2d11ps.h index df5c87cb4862..38acea3aa715 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughdepth2d11ps.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughdepth2d11ps.h @@ -1,145 +1,145 @@ -#if 0 -// -// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 -// -// -// Resource Bindings: -// -// Name Type Format Dim Slot Elements -// ------------------------------ ---------- ------- ----------- ---- -------- -// Sampler sampler NA NA 0 1 -// TextureF texture float4 2d 0 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, 8, 33, - 154, 92, 164, 28, 139, 205, - 1, 168, 30, 229, 51, 127, - 173, 221, 1, 0, 0, 0, - 100, 2, 0, 0, 5, 0, - 0, 0, 52, 0, 0, 0, - 220, 0, 0, 0, 52, 1, - 0, 0, 104, 1, 0, 0, - 232, 1, 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, - 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, - 54, 46, 51, 46, 57, 54, - 48, 48, 46, 49, 54, 51, - 56, 52, 0, 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 -}; +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 +// +// +// Resource Bindings: +// +// Name Type Format Dim Slot Elements +// ------------------------------ ---------- ------- ----------- ---- -------- +// Sampler sampler NA NA 0 1 +// TextureF texture float4 2d 0 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, 8, 33, + 154, 92, 164, 28, 139, 205, + 1, 168, 30, 229, 51, 127, + 173, 221, 1, 0, 0, 0, + 100, 2, 0, 0, 5, 0, + 0, 0, 52, 0, 0, 0, + 220, 0, 0, 0, 52, 1, + 0, 0, 104, 1, 0, 0, + 232, 1, 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, + 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, + 54, 46, 51, 46, 57, 54, + 48, 48, 46, 49, 54, 51, + 56, 52, 0, 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/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughlum2d11ps.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughlum2d11ps.h index d801fe8ac809..e0bcbc8fe649 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughlum2d11ps.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughlum2d11ps.h @@ -1,196 +1,196 @@ -#if 0 -// -// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 -// -// -// Resource Bindings: -// -// Name Type Format Dim Slot Elements -// ------------------------------ ---------- ------- ----------- ---- -------- -// Sampler sampler NA NA 0 1 -// TextureF texture float4 2d 0 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, 144, 18, - 242, 89, 150, 125, 18, 219, - 193, 196, 127, 207, 14, 165, - 198, 119, 1, 0, 0, 0, - 28, 3, 0, 0, 6, 0, - 0, 0, 56, 0, 0, 0, - 208, 0, 0, 0, 108, 1, - 0, 0, 232, 1, 0, 0, - 144, 2, 0, 0, 232, 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, - 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, 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, 54, 46, - 51, 46, 57, 54, 48, 48, - 46, 49, 54, 51, 56, 52, - 0, 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 -}; +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 +// +// +// Resource Bindings: +// +// Name Type Format Dim Slot Elements +// ------------------------------ ---------- ------- ----------- ---- -------- +// Sampler sampler NA NA 0 1 +// TextureF texture float4 2d 0 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, 144, 18, + 242, 89, 150, 125, 18, 219, + 193, 196, 127, 207, 14, 165, + 198, 119, 1, 0, 0, 0, + 28, 3, 0, 0, 6, 0, + 0, 0, 56, 0, 0, 0, + 208, 0, 0, 0, 108, 1, + 0, 0, 232, 1, 0, 0, + 144, 2, 0, 0, 232, 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, + 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, 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, 54, 46, + 51, 46, 57, 54, 48, 48, + 46, 49, 54, 51, 56, 52, + 0, 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/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughlum3d11ps.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughlum3d11ps.h index d566b3d3106e..ac2bb40359aa 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughlum3d11ps.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughlum3d11ps.h @@ -1,160 +1,160 @@ -#if 0 -// -// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 -// -// -// Resource Bindings: -// -// Name Type Format Dim Slot Elements -// ------------------------------ ---------- ------- ----------- ---- -------- -// Sampler sampler NA NA 0 1 -// TextureF texture float4 3d 0 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, 173, 177, - 219, 35, 149, 130, 33, 215, - 183, 219, 250, 244, 100, 17, - 62, 106, 1, 0, 0, 0, - 176, 2, 0, 0, 5, 0, - 0, 0, 52, 0, 0, 0, - 220, 0, 0, 0, 100, 1, - 0, 0, 152, 1, 0, 0, - 52, 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, - 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, - 54, 46, 51, 46, 57, 54, - 48, 48, 46, 49, 54, 51, - 56, 52, 0, 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 -}; +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 +// +// +// Resource Bindings: +// +// Name Type Format Dim Slot Elements +// ------------------------------ ---------- ------- ----------- ---- -------- +// Sampler sampler NA NA 0 1 +// TextureF texture float4 3d 0 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, 173, 177, + 219, 35, 149, 130, 33, 215, + 183, 219, 250, 244, 100, 17, + 62, 106, 1, 0, 0, 0, + 176, 2, 0, 0, 5, 0, + 0, 0, 52, 0, 0, 0, + 220, 0, 0, 0, 100, 1, + 0, 0, 152, 1, 0, 0, + 52, 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, + 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, + 54, 46, 51, 46, 57, 54, + 48, 48, 46, 49, 54, 51, + 56, 52, 0, 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/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughlumalpha2d11ps.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughlumalpha2d11ps.h index e028b3f01792..88599fca9c27 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughlumalpha2d11ps.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughlumalpha2d11ps.h @@ -1,185 +1,185 @@ -#if 0 -// -// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 -// -// -// Resource Bindings: -// -// Name Type Format Dim Slot Elements -// ------------------------------ ---------- ------- ----------- ---- -------- -// Sampler sampler NA NA 0 1 -// TextureF texture float4 2d 0 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, 246, 240, - 158, 208, 214, 197, 166, 221, - 45, 58, 235, 164, 12, 157, - 62, 31, 1, 0, 0, 0, - 232, 2, 0, 0, 6, 0, - 0, 0, 56, 0, 0, 0, - 176, 0, 0, 0, 56, 1, - 0, 0, 180, 1, 0, 0, - 92, 2, 0, 0, 180, 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, 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, - 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, - 54, 46, 51, 46, 57, 54, - 48, 48, 46, 49, 54, 51, - 56, 52, 0, 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 -}; +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 +// +// +// Resource Bindings: +// +// Name Type Format Dim Slot Elements +// ------------------------------ ---------- ------- ----------- ---- -------- +// Sampler sampler NA NA 0 1 +// TextureF texture float4 2d 0 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, 246, 240, + 158, 208, 214, 197, 166, 221, + 45, 58, 235, 164, 12, 157, + 62, 31, 1, 0, 0, 0, + 232, 2, 0, 0, 6, 0, + 0, 0, 56, 0, 0, 0, + 176, 0, 0, 0, 56, 1, + 0, 0, 180, 1, 0, 0, + 92, 2, 0, 0, 180, 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, 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, + 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, + 54, 46, 51, 46, 57, 54, + 48, 48, 46, 49, 54, 51, + 56, 52, 0, 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/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughlumalpha3d11ps.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughlumalpha3d11ps.h index d82d64007613..19091d035773 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughlumalpha3d11ps.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughlumalpha3d11ps.h @@ -1,156 +1,156 @@ -#if 0 -// -// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 -// -// -// Resource Bindings: -// -// Name Type Format Dim Slot Elements -// ------------------------------ ---------- ------- ----------- ---- -------- -// Sampler sampler NA NA 0 1 -// TextureF texture float4 3d 0 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, 224, 152, - 208, 227, 44, 106, 62, 235, - 129, 97, 207, 213, 29, 232, - 163, 6, 1, 0, 0, 0, - 156, 2, 0, 0, 5, 0, - 0, 0, 52, 0, 0, 0, - 220, 0, 0, 0, 100, 1, - 0, 0, 152, 1, 0, 0, - 32, 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, - 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, - 54, 46, 51, 46, 57, 54, - 48, 48, 46, 49, 54, 51, - 56, 52, 0, 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 -}; +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 +// +// +// Resource Bindings: +// +// Name Type Format Dim Slot Elements +// ------------------------------ ---------- ------- ----------- ---- -------- +// Sampler sampler NA NA 0 1 +// TextureF texture float4 3d 0 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, 224, 152, + 208, 227, 44, 106, 62, 235, + 129, 97, 207, 213, 29, 232, + 163, 6, 1, 0, 0, 0, + 156, 2, 0, 0, 5, 0, + 0, 0, 52, 0, 0, 0, + 220, 0, 0, 0, 100, 1, + 0, 0, 152, 1, 0, 0, + 32, 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, + 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, + 54, 46, 51, 46, 57, 54, + 48, 48, 46, 49, 54, 51, + 56, 52, 0, 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/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr2d11ps.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr2d11ps.h index 3233bc210dba..d42101670058 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr2d11ps.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr2d11ps.h @@ -1,198 +1,198 @@ -#if 0 -// -// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 -// -// -// Resource Bindings: -// -// Name Type Format Dim Slot Elements -// ------------------------------ ---------- ------- ----------- ---- -------- -// Sampler sampler NA NA 0 1 -// TextureF texture float4 2d 0 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, 212, 251, - 117, 250, 99, 185, 28, 44, - 178, 14, 83, 133, 173, 0, - 182, 196, 1, 0, 0, 0, - 40, 3, 0, 0, 6, 0, - 0, 0, 56, 0, 0, 0, - 208, 0, 0, 0, 120, 1, - 0, 0, 244, 1, 0, 0, - 156, 2, 0, 0, 244, 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, - 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, 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, 54, 46, - 51, 46, 57, 54, 48, 48, - 46, 49, 54, 51, 56, 52, - 0, 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 -}; +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 +// +// +// Resource Bindings: +// +// Name Type Format Dim Slot Elements +// ------------------------------ ---------- ------- ----------- ---- -------- +// Sampler sampler NA NA 0 1 +// TextureF texture float4 2d 0 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, 212, 251, + 117, 250, 99, 185, 28, 44, + 178, 14, 83, 133, 173, 0, + 182, 196, 1, 0, 0, 0, + 40, 3, 0, 0, 6, 0, + 0, 0, 56, 0, 0, 0, + 208, 0, 0, 0, 120, 1, + 0, 0, 244, 1, 0, 0, + 156, 2, 0, 0, 244, 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, + 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, 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, 54, 46, + 51, 46, 57, 54, 48, 48, + 46, 49, 54, 51, 56, 52, + 0, 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/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr2di11ps.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr2di11ps.h index 4ec712bd7ed5..4d8d9933aab5 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr2di11ps.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr2di11ps.h @@ -1,167 +1,167 @@ -#if 0 -// -// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 -// -// -// Resource Bindings: -// -// Name Type Format Dim Slot Elements -// ------------------------------ ---------- ------- ----------- ---- -------- -// TextureI texture sint4 2d 0 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, 123, 230, - 45, 18, 63, 217, 12, 210, - 151, 254, 16, 78, 107, 211, - 57, 255, 1, 0, 0, 0, - 208, 2, 0, 0, 5, 0, - 0, 0, 52, 0, 0, 0, - 180, 0, 0, 0, 12, 1, - 0, 0, 64, 1, 0, 0, - 84, 2, 0, 0, 82, 68, - 69, 70, 120, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 1, 0, 0, 0, - 28, 0, 0, 0, 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, 54, 46, 51, 46, - 57, 54, 48, 48, 46, 49, - 54, 51, 56, 52, 0, 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 -}; +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 +// +// +// Resource Bindings: +// +// Name Type Format Dim Slot Elements +// ------------------------------ ---------- ------- ----------- ---- -------- +// TextureI texture sint4 2d 0 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, 123, 230, + 45, 18, 63, 217, 12, 210, + 151, 254, 16, 78, 107, 211, + 57, 255, 1, 0, 0, 0, + 208, 2, 0, 0, 5, 0, + 0, 0, 52, 0, 0, 0, + 180, 0, 0, 0, 12, 1, + 0, 0, 64, 1, 0, 0, + 84, 2, 0, 0, 82, 68, + 69, 70, 120, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 28, 0, 0, 0, 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, 54, 46, 51, 46, + 57, 54, 48, 48, 46, 49, + 54, 51, 56, 52, 0, 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/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr2dui11ps.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr2dui11ps.h index 1a1ebbbcfbde..3f3885a1f2a6 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr2dui11ps.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr2dui11ps.h @@ -1,167 +1,167 @@ -#if 0 -// -// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 -// -// -// Resource Bindings: -// -// Name Type Format Dim Slot Elements -// ------------------------------ ---------- ------- ----------- ---- -------- -// TextureUI texture uint4 2d 0 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, 4, 26, - 62, 109, 94, 45, 124, 238, - 150, 245, 85, 155, 185, 37, - 234, 152, 1, 0, 0, 0, - 208, 2, 0, 0, 5, 0, - 0, 0, 52, 0, 0, 0, - 180, 0, 0, 0, 12, 1, - 0, 0, 64, 1, 0, 0, - 84, 2, 0, 0, 82, 68, - 69, 70, 120, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 1, 0, 0, 0, - 28, 0, 0, 0, 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, 54, 46, 51, - 46, 57, 54, 48, 48, 46, - 49, 54, 51, 56, 52, 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, - 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 -}; +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 +// +// +// Resource Bindings: +// +// Name Type Format Dim Slot Elements +// ------------------------------ ---------- ------- ----------- ---- -------- +// TextureUI texture uint4 2d 0 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, 4, 26, + 62, 109, 94, 45, 124, 238, + 150, 245, 85, 155, 185, 37, + 234, 152, 1, 0, 0, 0, + 208, 2, 0, 0, 5, 0, + 0, 0, 52, 0, 0, 0, + 180, 0, 0, 0, 12, 1, + 0, 0, 64, 1, 0, 0, + 84, 2, 0, 0, 82, 68, + 69, 70, 120, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 28, 0, 0, 0, 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, 54, 46, 51, + 46, 57, 54, 48, 48, 46, + 49, 54, 51, 56, 52, 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, + 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/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr3d11ps.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr3d11ps.h index 365a9fa294ca..506baef443f3 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr3d11ps.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr3d11ps.h @@ -1,162 +1,162 @@ -#if 0 -// -// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 -// -// -// Resource Bindings: -// -// Name Type Format Dim Slot Elements -// ------------------------------ ---------- ------- ----------- ---- -------- -// Sampler sampler NA NA 0 1 -// TextureF texture float4 3d 0 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, 11, 235, - 208, 143, 219, 183, 141, 78, - 136, 182, 62, 182, 243, 12, - 239, 125, 1, 0, 0, 0, - 188, 2, 0, 0, 5, 0, - 0, 0, 52, 0, 0, 0, - 220, 0, 0, 0, 100, 1, - 0, 0, 152, 1, 0, 0, - 64, 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, - 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, - 54, 46, 51, 46, 57, 54, - 48, 48, 46, 49, 54, 51, - 56, 52, 0, 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 -}; +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 +// +// +// Resource Bindings: +// +// Name Type Format Dim Slot Elements +// ------------------------------ ---------- ------- ----------- ---- -------- +// Sampler sampler NA NA 0 1 +// TextureF texture float4 3d 0 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, 11, 235, + 208, 143, 219, 183, 141, 78, + 136, 182, 62, 182, 243, 12, + 239, 125, 1, 0, 0, 0, + 188, 2, 0, 0, 5, 0, + 0, 0, 52, 0, 0, 0, + 220, 0, 0, 0, 100, 1, + 0, 0, 152, 1, 0, 0, + 64, 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, + 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, + 54, 46, 51, 46, 57, 54, + 48, 48, 46, 49, 54, 51, + 56, 52, 0, 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/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr3di11ps.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr3di11ps.h index d8bd2eece744..89c35d600c90 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr3di11ps.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr3di11ps.h @@ -1,174 +1,174 @@ -#if 0 -// -// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 -// -// -// Resource Bindings: -// -// Name Type Format Dim Slot Elements -// ------------------------------ ---------- ------- ----------- ---- -------- -// TextureI texture sint4 3d 0 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, 222, 251, - 30, 61, 15, 80, 81, 247, - 175, 137, 44, 19, 23, 84, - 149, 211, 1, 0, 0, 0, - 244, 2, 0, 0, 5, 0, - 0, 0, 52, 0, 0, 0, - 180, 0, 0, 0, 60, 1, - 0, 0, 112, 1, 0, 0, - 120, 2, 0, 0, 82, 68, - 69, 70, 120, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 1, 0, 0, 0, - 28, 0, 0, 0, 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, 54, 46, 51, 46, - 57, 54, 48, 48, 46, 49, - 54, 51, 56, 52, 0, 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 -}; +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 +// +// +// Resource Bindings: +// +// Name Type Format Dim Slot Elements +// ------------------------------ ---------- ------- ----------- ---- -------- +// TextureI texture sint4 3d 0 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, 222, 251, + 30, 61, 15, 80, 81, 247, + 175, 137, 44, 19, 23, 84, + 149, 211, 1, 0, 0, 0, + 244, 2, 0, 0, 5, 0, + 0, 0, 52, 0, 0, 0, + 180, 0, 0, 0, 60, 1, + 0, 0, 112, 1, 0, 0, + 120, 2, 0, 0, 82, 68, + 69, 70, 120, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 28, 0, 0, 0, 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, 54, 46, 51, 46, + 57, 54, 48, 48, 46, 49, + 54, 51, 56, 52, 0, 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/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr3dui11ps.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr3dui11ps.h index 4316a93f3886..64386841c2db 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr3dui11ps.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr3dui11ps.h @@ -1,174 +1,174 @@ -#if 0 -// -// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 -// -// -// Resource Bindings: -// -// Name Type Format Dim Slot Elements -// ------------------------------ ---------- ------- ----------- ---- -------- -// TextureUI texture uint4 3d 0 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, 69, 5, - 86, 212, 201, 54, 97, 205, - 89, 161, 100, 72, 246, 114, - 40, 214, 1, 0, 0, 0, - 244, 2, 0, 0, 5, 0, - 0, 0, 52, 0, 0, 0, - 180, 0, 0, 0, 60, 1, - 0, 0, 112, 1, 0, 0, - 120, 2, 0, 0, 82, 68, - 69, 70, 120, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 1, 0, 0, 0, - 28, 0, 0, 0, 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, 54, 46, 51, - 46, 57, 54, 48, 48, 46, - 49, 54, 51, 56, 52, 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, - 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 -}; +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 +// +// +// Resource Bindings: +// +// Name Type Format Dim Slot Elements +// ------------------------------ ---------- ------- ----------- ---- -------- +// TextureUI texture uint4 3d 0 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, 69, 5, + 86, 212, 201, 54, 97, 205, + 89, 161, 100, 72, 246, 114, + 40, 214, 1, 0, 0, 0, + 244, 2, 0, 0, 5, 0, + 0, 0, 52, 0, 0, 0, + 180, 0, 0, 0, 60, 1, + 0, 0, 112, 1, 0, 0, + 120, 2, 0, 0, 82, 68, + 69, 70, 120, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 28, 0, 0, 0, 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, 54, 46, 51, + 46, 57, 54, 48, 48, 46, + 49, 54, 51, 56, 52, 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, + 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/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg2d11ps.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg2d11ps.h index 9fcc73b4ccbe..201cbff60caf 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg2d11ps.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg2d11ps.h @@ -1,198 +1,198 @@ -#if 0 -// -// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 -// -// -// Resource Bindings: -// -// Name Type Format Dim Slot Elements -// ------------------------------ ---------- ------- ----------- ---- -------- -// Sampler sampler NA NA 0 1 -// TextureF texture float4 2d 0 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, 217, 171, - 153, 248, 26, 15, 102, 119, - 86, 174, 121, 245, 223, 83, - 2, 181, 1, 0, 0, 0, - 40, 3, 0, 0, 6, 0, - 0, 0, 56, 0, 0, 0, - 208, 0, 0, 0, 120, 1, - 0, 0, 244, 1, 0, 0, - 156, 2, 0, 0, 244, 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, - 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, 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, 54, 46, - 51, 46, 57, 54, 48, 48, - 46, 49, 54, 51, 56, 52, - 0, 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 -}; +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 +// +// +// Resource Bindings: +// +// Name Type Format Dim Slot Elements +// ------------------------------ ---------- ------- ----------- ---- -------- +// Sampler sampler NA NA 0 1 +// TextureF texture float4 2d 0 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, 217, 171, + 153, 248, 26, 15, 102, 119, + 86, 174, 121, 245, 223, 83, + 2, 181, 1, 0, 0, 0, + 40, 3, 0, 0, 6, 0, + 0, 0, 56, 0, 0, 0, + 208, 0, 0, 0, 120, 1, + 0, 0, 244, 1, 0, 0, + 156, 2, 0, 0, 244, 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, + 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, 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, 54, 46, + 51, 46, 57, 54, 48, 48, + 46, 49, 54, 51, 56, 52, + 0, 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/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg2di11ps.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg2di11ps.h index 44f892b97656..a66e5309487a 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg2di11ps.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg2di11ps.h @@ -1,167 +1,167 @@ -#if 0 -// -// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 -// -// -// Resource Bindings: -// -// Name Type Format Dim Slot Elements -// ------------------------------ ---------- ------- ----------- ---- -------- -// TextureI texture sint4 2d 0 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, 89, 123, - 129, 251, 206, 105, 221, 141, - 5, 160, 186, 187, 168, 157, - 145, 246, 1, 0, 0, 0, - 208, 2, 0, 0, 5, 0, - 0, 0, 52, 0, 0, 0, - 180, 0, 0, 0, 12, 1, - 0, 0, 64, 1, 0, 0, - 84, 2, 0, 0, 82, 68, - 69, 70, 120, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 1, 0, 0, 0, - 28, 0, 0, 0, 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, 54, 46, 51, 46, - 57, 54, 48, 48, 46, 49, - 54, 51, 56, 52, 0, 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 -}; +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 +// +// +// Resource Bindings: +// +// Name Type Format Dim Slot Elements +// ------------------------------ ---------- ------- ----------- ---- -------- +// TextureI texture sint4 2d 0 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, 89, 123, + 129, 251, 206, 105, 221, 141, + 5, 160, 186, 187, 168, 157, + 145, 246, 1, 0, 0, 0, + 208, 2, 0, 0, 5, 0, + 0, 0, 52, 0, 0, 0, + 180, 0, 0, 0, 12, 1, + 0, 0, 64, 1, 0, 0, + 84, 2, 0, 0, 82, 68, + 69, 70, 120, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 28, 0, 0, 0, 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, 54, 46, 51, 46, + 57, 54, 48, 48, 46, 49, + 54, 51, 56, 52, 0, 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/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg2dui11ps.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg2dui11ps.h index 43d3e47474da..5146cd936229 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg2dui11ps.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg2dui11ps.h @@ -1,167 +1,167 @@ -#if 0 -// -// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 -// -// -// Resource Bindings: -// -// Name Type Format Dim Slot Elements -// ------------------------------ ---------- ------- ----------- ---- -------- -// TextureUI texture uint4 2d 0 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, 253, 188, - 138, 153, 226, 194, 182, 197, - 184, 36, 111, 24, 198, 171, - 241, 145, 1, 0, 0, 0, - 208, 2, 0, 0, 5, 0, - 0, 0, 52, 0, 0, 0, - 180, 0, 0, 0, 12, 1, - 0, 0, 64, 1, 0, 0, - 84, 2, 0, 0, 82, 68, - 69, 70, 120, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 1, 0, 0, 0, - 28, 0, 0, 0, 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, 54, 46, 51, - 46, 57, 54, 48, 48, 46, - 49, 54, 51, 56, 52, 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, - 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 -}; +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 +// +// +// Resource Bindings: +// +// Name Type Format Dim Slot Elements +// ------------------------------ ---------- ------- ----------- ---- -------- +// TextureUI texture uint4 2d 0 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, 253, 188, + 138, 153, 226, 194, 182, 197, + 184, 36, 111, 24, 198, 171, + 241, 145, 1, 0, 0, 0, + 208, 2, 0, 0, 5, 0, + 0, 0, 52, 0, 0, 0, + 180, 0, 0, 0, 12, 1, + 0, 0, 64, 1, 0, 0, + 84, 2, 0, 0, 82, 68, + 69, 70, 120, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 28, 0, 0, 0, 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, 54, 46, 51, + 46, 57, 54, 48, 48, 46, + 49, 54, 51, 56, 52, 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, + 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/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg3d11ps.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg3d11ps.h index 826127eb32f0..a313011707c3 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg3d11ps.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg3d11ps.h @@ -1,162 +1,162 @@ -#if 0 -// -// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 -// -// -// Resource Bindings: -// -// Name Type Format Dim Slot Elements -// ------------------------------ ---------- ------- ----------- ---- -------- -// Sampler sampler NA NA 0 1 -// TextureF texture float4 3d 0 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, 117, 159, - 238, 81, 51, 223, 126, 31, - 223, 171, 227, 2, 248, 7, - 72, 91, 1, 0, 0, 0, - 188, 2, 0, 0, 5, 0, - 0, 0, 52, 0, 0, 0, - 220, 0, 0, 0, 100, 1, - 0, 0, 152, 1, 0, 0, - 64, 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, - 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, - 54, 46, 51, 46, 57, 54, - 48, 48, 46, 49, 54, 51, - 56, 52, 0, 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 -}; +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 +// +// +// Resource Bindings: +// +// Name Type Format Dim Slot Elements +// ------------------------------ ---------- ------- ----------- ---- -------- +// Sampler sampler NA NA 0 1 +// TextureF texture float4 3d 0 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, 117, 159, + 238, 81, 51, 223, 126, 31, + 223, 171, 227, 2, 248, 7, + 72, 91, 1, 0, 0, 0, + 188, 2, 0, 0, 5, 0, + 0, 0, 52, 0, 0, 0, + 220, 0, 0, 0, 100, 1, + 0, 0, 152, 1, 0, 0, + 64, 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, + 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, + 54, 46, 51, 46, 57, 54, + 48, 48, 46, 49, 54, 51, + 56, 52, 0, 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/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg3di11ps.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg3di11ps.h index 19e68acf258e..ef6ec1723b70 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg3di11ps.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg3di11ps.h @@ -1,174 +1,174 @@ -#if 0 -// -// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 -// -// -// Resource Bindings: -// -// Name Type Format Dim Slot Elements -// ------------------------------ ---------- ------- ----------- ---- -------- -// TextureI texture sint4 3d 0 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, 62, 119, - 61, 21, 83, 42, 80, 125, - 121, 208, 247, 10, 223, 62, - 33, 18, 1, 0, 0, 0, - 244, 2, 0, 0, 5, 0, - 0, 0, 52, 0, 0, 0, - 180, 0, 0, 0, 60, 1, - 0, 0, 112, 1, 0, 0, - 120, 2, 0, 0, 82, 68, - 69, 70, 120, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 1, 0, 0, 0, - 28, 0, 0, 0, 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, 54, 46, 51, 46, - 57, 54, 48, 48, 46, 49, - 54, 51, 56, 52, 0, 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 -}; +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 +// +// +// Resource Bindings: +// +// Name Type Format Dim Slot Elements +// ------------------------------ ---------- ------- ----------- ---- -------- +// TextureI texture sint4 3d 0 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, 62, 119, + 61, 21, 83, 42, 80, 125, + 121, 208, 247, 10, 223, 62, + 33, 18, 1, 0, 0, 0, + 244, 2, 0, 0, 5, 0, + 0, 0, 52, 0, 0, 0, + 180, 0, 0, 0, 60, 1, + 0, 0, 112, 1, 0, 0, + 120, 2, 0, 0, 82, 68, + 69, 70, 120, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 28, 0, 0, 0, 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, 54, 46, 51, 46, + 57, 54, 48, 48, 46, 49, + 54, 51, 56, 52, 0, 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/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg3dui11ps.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg3dui11ps.h index 55e532310b93..d1540cee7121 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg3dui11ps.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg3dui11ps.h @@ -1,174 +1,174 @@ -#if 0 -// -// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 -// -// -// Resource Bindings: -// -// Name Type Format Dim Slot Elements -// ------------------------------ ---------- ------- ----------- ---- -------- -// TextureUI texture uint4 3d 0 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, 37, 56, - 43, 206, 81, 137, 125, 191, - 216, 50, 86, 76, 61, 78, - 25, 246, 1, 0, 0, 0, - 244, 2, 0, 0, 5, 0, - 0, 0, 52, 0, 0, 0, - 180, 0, 0, 0, 60, 1, - 0, 0, 112, 1, 0, 0, - 120, 2, 0, 0, 82, 68, - 69, 70, 120, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 1, 0, 0, 0, - 28, 0, 0, 0, 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, 54, 46, 51, - 46, 57, 54, 48, 48, 46, - 49, 54, 51, 56, 52, 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, - 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 -}; +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 +// +// +// Resource Bindings: +// +// Name Type Format Dim Slot Elements +// ------------------------------ ---------- ------- ----------- ---- -------- +// TextureUI texture uint4 3d 0 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, 37, 56, + 43, 206, 81, 137, 125, 191, + 216, 50, 86, 76, 61, 78, + 25, 246, 1, 0, 0, 0, + 244, 2, 0, 0, 5, 0, + 0, 0, 52, 0, 0, 0, + 180, 0, 0, 0, 60, 1, + 0, 0, 112, 1, 0, 0, + 120, 2, 0, 0, 82, 68, + 69, 70, 120, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 28, 0, 0, 0, 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, 54, 46, 51, + 46, 57, 54, 48, 48, 46, + 49, 54, 51, 56, 52, 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, + 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/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2d11ps.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2d11ps.h index c528d09c1b53..0047ef3ca141 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2d11ps.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2d11ps.h @@ -1,196 +1,196 @@ -#if 0 -// -// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 -// -// -// Resource Bindings: -// -// Name Type Format Dim Slot Elements -// ------------------------------ ---------- ------- ----------- ---- -------- -// Sampler sampler NA NA 0 1 -// TextureF texture float4 2d 0 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, 51, 90, - 49, 167, 211, 79, 20, 215, - 57, 227, 70, 56, 132, 117, - 66, 156, 1, 0, 0, 0, - 28, 3, 0, 0, 6, 0, - 0, 0, 56, 0, 0, 0, - 208, 0, 0, 0, 108, 1, - 0, 0, 232, 1, 0, 0, - 144, 2, 0, 0, 232, 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, - 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, 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, 54, 46, - 51, 46, 57, 54, 48, 48, - 46, 49, 54, 51, 56, 52, - 0, 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 -}; +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 +// +// +// Resource Bindings: +// +// Name Type Format Dim Slot Elements +// ------------------------------ ---------- ------- ----------- ---- -------- +// Sampler sampler NA NA 0 1 +// TextureF texture float4 2d 0 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, 51, 90, + 49, 167, 211, 79, 20, 215, + 57, 227, 70, 56, 132, 117, + 66, 156, 1, 0, 0, 0, + 28, 3, 0, 0, 6, 0, + 0, 0, 56, 0, 0, 0, + 208, 0, 0, 0, 108, 1, + 0, 0, 232, 1, 0, 0, + 144, 2, 0, 0, 232, 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, + 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, 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, 54, 46, + 51, 46, 57, 54, 48, 48, + 46, 49, 54, 51, 56, 52, + 0, 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/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2di11ps.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2di11ps.h index 3d115e908b4d..0f318fd8b477 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2di11ps.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2di11ps.h @@ -1,165 +1,165 @@ -#if 0 -// -// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 -// -// -// Resource Bindings: -// -// Name Type Format Dim Slot Elements -// ------------------------------ ---------- ------- ----------- ---- -------- -// TextureI texture sint4 2d 0 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, 16, 227, - 172, 190, 246, 118, 223, 239, - 176, 78, 90, 11, 135, 138, - 109, 174, 1, 0, 0, 0, - 196, 2, 0, 0, 5, 0, - 0, 0, 52, 0, 0, 0, - 180, 0, 0, 0, 12, 1, - 0, 0, 64, 1, 0, 0, - 72, 2, 0, 0, 82, 68, - 69, 70, 120, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 1, 0, 0, 0, - 28, 0, 0, 0, 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, 54, 46, 51, 46, - 57, 54, 48, 48, 46, 49, - 54, 51, 56, 52, 0, 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 -}; +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 +// +// +// Resource Bindings: +// +// Name Type Format Dim Slot Elements +// ------------------------------ ---------- ------- ----------- ---- -------- +// TextureI texture sint4 2d 0 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, 16, 227, + 172, 190, 246, 118, 223, 239, + 176, 78, 90, 11, 135, 138, + 109, 174, 1, 0, 0, 0, + 196, 2, 0, 0, 5, 0, + 0, 0, 52, 0, 0, 0, + 180, 0, 0, 0, 12, 1, + 0, 0, 64, 1, 0, 0, + 72, 2, 0, 0, 82, 68, + 69, 70, 120, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 28, 0, 0, 0, 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, 54, 46, 51, 46, + 57, 54, 48, 48, 46, 49, + 54, 51, 56, 52, 0, 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/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2dui11ps.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2dui11ps.h index d0ed4fd80997..943f7a2be95e 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2dui11ps.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2dui11ps.h @@ -1,165 +1,165 @@ -#if 0 -// -// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 -// -// -// Resource Bindings: -// -// Name Type Format Dim Slot Elements -// ------------------------------ ---------- ------- ----------- ---- -------- -// TextureUI texture uint4 2d 0 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, 245, 219, - 46, 32, 34, 74, 2, 47, - 124, 96, 216, 40, 253, 243, - 104, 178, 1, 0, 0, 0, - 196, 2, 0, 0, 5, 0, - 0, 0, 52, 0, 0, 0, - 180, 0, 0, 0, 12, 1, - 0, 0, 64, 1, 0, 0, - 72, 2, 0, 0, 82, 68, - 69, 70, 120, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 1, 0, 0, 0, - 28, 0, 0, 0, 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, 54, 46, 51, - 46, 57, 54, 48, 48, 46, - 49, 54, 51, 56, 52, 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, - 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 -}; +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 +// +// +// Resource Bindings: +// +// Name Type Format Dim Slot Elements +// ------------------------------ ---------- ------- ----------- ---- -------- +// TextureUI texture uint4 2d 0 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, 245, 219, + 46, 32, 34, 74, 2, 47, + 124, 96, 216, 40, 253, 243, + 104, 178, 1, 0, 0, 0, + 196, 2, 0, 0, 5, 0, + 0, 0, 52, 0, 0, 0, + 180, 0, 0, 0, 12, 1, + 0, 0, 64, 1, 0, 0, + 72, 2, 0, 0, 82, 68, + 69, 70, 120, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 28, 0, 0, 0, 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, 54, 46, 51, + 46, 57, 54, 48, 48, 46, + 49, 54, 51, 56, 52, 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, + 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/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb3d11ps.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb3d11ps.h index b8e14283f503..528f27361dd9 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb3d11ps.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb3d11ps.h @@ -1,160 +1,160 @@ -#if 0 -// -// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 -// -// -// Resource Bindings: -// -// Name Type Format Dim Slot Elements -// ------------------------------ ---------- ------- ----------- ---- -------- -// Sampler sampler NA NA 0 1 -// TextureF texture float4 3d 0 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, 3, 213, - 227, 200, 132, 255, 7, 95, - 0, 252, 77, 33, 254, 184, - 83, 110, 1, 0, 0, 0, - 176, 2, 0, 0, 5, 0, - 0, 0, 52, 0, 0, 0, - 220, 0, 0, 0, 100, 1, - 0, 0, 152, 1, 0, 0, - 52, 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, - 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, - 54, 46, 51, 46, 57, 54, - 48, 48, 46, 49, 54, 51, - 56, 52, 0, 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 -}; +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 +// +// +// Resource Bindings: +// +// Name Type Format Dim Slot Elements +// ------------------------------ ---------- ------- ----------- ---- -------- +// Sampler sampler NA NA 0 1 +// TextureF texture float4 3d 0 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, 3, 213, + 227, 200, 132, 255, 7, 95, + 0, 252, 77, 33, 254, 184, + 83, 110, 1, 0, 0, 0, + 176, 2, 0, 0, 5, 0, + 0, 0, 52, 0, 0, 0, + 220, 0, 0, 0, 100, 1, + 0, 0, 152, 1, 0, 0, + 52, 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, + 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, + 54, 46, 51, 46, 57, 54, + 48, 48, 46, 49, 54, 51, + 56, 52, 0, 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/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb3di11ps.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb3di11ps.h index cab943d6991e..fa2a63959c72 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb3di11ps.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb3di11ps.h @@ -1,172 +1,172 @@ -#if 0 -// -// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 -// -// -// Resource Bindings: -// -// Name Type Format Dim Slot Elements -// ------------------------------ ---------- ------- ----------- ---- -------- -// TextureI texture sint4 3d 0 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, 194, 157, - 8, 194, 167, 235, 14, 127, - 69, 198, 32, 35, 167, 35, - 213, 248, 1, 0, 0, 0, - 232, 2, 0, 0, 5, 0, - 0, 0, 52, 0, 0, 0, - 180, 0, 0, 0, 60, 1, - 0, 0, 112, 1, 0, 0, - 108, 2, 0, 0, 82, 68, - 69, 70, 120, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 1, 0, 0, 0, - 28, 0, 0, 0, 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, 54, 46, 51, 46, - 57, 54, 48, 48, 46, 49, - 54, 51, 56, 52, 0, 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 -}; +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 +// +// +// Resource Bindings: +// +// Name Type Format Dim Slot Elements +// ------------------------------ ---------- ------- ----------- ---- -------- +// TextureI texture sint4 3d 0 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, 194, 157, + 8, 194, 167, 235, 14, 127, + 69, 198, 32, 35, 167, 35, + 213, 248, 1, 0, 0, 0, + 232, 2, 0, 0, 5, 0, + 0, 0, 52, 0, 0, 0, + 180, 0, 0, 0, 60, 1, + 0, 0, 112, 1, 0, 0, + 108, 2, 0, 0, 82, 68, + 69, 70, 120, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 28, 0, 0, 0, 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, 54, 46, 51, 46, + 57, 54, 48, 48, 46, 49, + 54, 51, 56, 52, 0, 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/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb3dui11ps.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb3dui11ps.h index 7f22ead53c94..e90b40d0031e 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb3dui11ps.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb3dui11ps.h @@ -1,172 +1,172 @@ -#if 0 -// -// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 -// -// -// Resource Bindings: -// -// Name Type Format Dim Slot Elements -// ------------------------------ ---------- ------- ----------- ---- -------- -// TextureUI texture uint4 3d 0 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, 253, 147, - 1, 158, 41, 31, 253, 138, - 52, 213, 103, 41, 188, 192, - 79, 199, 1, 0, 0, 0, - 232, 2, 0, 0, 5, 0, - 0, 0, 52, 0, 0, 0, - 180, 0, 0, 0, 60, 1, - 0, 0, 112, 1, 0, 0, - 108, 2, 0, 0, 82, 68, - 69, 70, 120, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 1, 0, 0, 0, - 28, 0, 0, 0, 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, 54, 46, 51, - 46, 57, 54, 48, 48, 46, - 49, 54, 51, 56, 52, 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, - 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 -}; +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 +// +// +// Resource Bindings: +// +// Name Type Format Dim Slot Elements +// ------------------------------ ---------- ------- ----------- ---- -------- +// TextureUI texture uint4 3d 0 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, 253, 147, + 1, 158, 41, 31, 253, 138, + 52, 213, 103, 41, 188, 192, + 79, 199, 1, 0, 0, 0, + 232, 2, 0, 0, 5, 0, + 0, 0, 52, 0, 0, 0, + 180, 0, 0, 0, 60, 1, + 0, 0, 112, 1, 0, 0, + 108, 2, 0, 0, 82, 68, + 69, 70, 120, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 28, 0, 0, 0, 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, 54, 46, 51, + 46, 57, 54, 48, 48, 46, + 49, 54, 51, 56, 52, 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, + 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/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2d11ps.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2d11ps.h index f168a492b8d8..a4ee9d5ab44d 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2d11ps.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2d11ps.h @@ -1,176 +1,176 @@ -#if 0 -// -// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 -// -// -// Resource Bindings: -// -// Name Type Format Dim Slot Elements -// ------------------------------ ---------- ------- ----------- ---- -------- -// Sampler sampler NA NA 0 1 -// TextureF texture float4 2d 0 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, 240, 186, - 163, 221, 151, 45, 139, 68, - 172, 121, 30, 230, 203, 102, - 92, 33, 1, 0, 0, 0, - 192, 2, 0, 0, 6, 0, - 0, 0, 56, 0, 0, 0, - 164, 0, 0, 0, 16, 1, - 0, 0, 140, 1, 0, 0, - 52, 2, 0, 0, 140, 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, 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, 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, 54, 46, 51, 46, - 57, 54, 48, 48, 46, 49, - 54, 51, 56, 52, 0, 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 -}; +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 +// +// +// Resource Bindings: +// +// Name Type Format Dim Slot Elements +// ------------------------------ ---------- ------- ----------- ---- -------- +// Sampler sampler NA NA 0 1 +// TextureF texture float4 2d 0 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, 240, 186, + 163, 221, 151, 45, 139, 68, + 172, 121, 30, 230, 203, 102, + 92, 33, 1, 0, 0, 0, + 192, 2, 0, 0, 6, 0, + 0, 0, 56, 0, 0, 0, + 164, 0, 0, 0, 16, 1, + 0, 0, 140, 1, 0, 0, + 52, 2, 0, 0, 140, 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, 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, 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, 54, 46, 51, 46, + 57, 54, 48, 48, 46, 49, + 54, 51, 56, 52, 0, 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/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2di11ps.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2di11ps.h index d6ec0c11b640..d87d043d8cd1 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2di11ps.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2di11ps.h @@ -1,157 +1,157 @@ -#if 0 -// -// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 -// -// -// Resource Bindings: -// -// Name Type Format Dim Slot Elements -// ------------------------------ ---------- ------- ----------- ---- -------- -// TextureI texture sint4 2d 0 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, 81, 147, - 194, 141, 92, 236, 184, 192, - 11, 249, 14, 215, 122, 110, - 35, 111, 1, 0, 0, 0, - 156, 2, 0, 0, 5, 0, - 0, 0, 52, 0, 0, 0, - 180, 0, 0, 0, 12, 1, - 0, 0, 64, 1, 0, 0, - 32, 2, 0, 0, 82, 68, - 69, 70, 120, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 1, 0, 0, 0, - 28, 0, 0, 0, 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, 54, 46, 51, 46, - 57, 54, 48, 48, 46, 49, - 54, 51, 56, 52, 0, 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 -}; +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 +// +// +// Resource Bindings: +// +// Name Type Format Dim Slot Elements +// ------------------------------ ---------- ------- ----------- ---- -------- +// TextureI texture sint4 2d 0 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, 81, 147, + 194, 141, 92, 236, 184, 192, + 11, 249, 14, 215, 122, 110, + 35, 111, 1, 0, 0, 0, + 156, 2, 0, 0, 5, 0, + 0, 0, 52, 0, 0, 0, + 180, 0, 0, 0, 12, 1, + 0, 0, 64, 1, 0, 0, + 32, 2, 0, 0, 82, 68, + 69, 70, 120, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 28, 0, 0, 0, 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, 54, 46, 51, 46, + 57, 54, 48, 48, 46, 49, + 54, 51, 56, 52, 0, 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/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2dui11ps.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2dui11ps.h index 7bc981b22326..35cff53a4659 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2dui11ps.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2dui11ps.h @@ -1,157 +1,157 @@ -#if 0 -// -// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 -// -// -// Resource Bindings: -// -// Name Type Format Dim Slot Elements -// ------------------------------ ---------- ------- ----------- ---- -------- -// TextureUI texture uint4 2d 0 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, 128, 252, - 255, 238, 68, 109, 10, 133, - 175, 163, 216, 152, 219, 103, - 163, 223, 1, 0, 0, 0, - 156, 2, 0, 0, 5, 0, - 0, 0, 52, 0, 0, 0, - 180, 0, 0, 0, 12, 1, - 0, 0, 64, 1, 0, 0, - 32, 2, 0, 0, 82, 68, - 69, 70, 120, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 1, 0, 0, 0, - 28, 0, 0, 0, 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, 54, 46, 51, - 46, 57, 54, 48, 48, 46, - 49, 54, 51, 56, 52, 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, - 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 -}; +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 +// +// +// Resource Bindings: +// +// Name Type Format Dim Slot Elements +// ------------------------------ ---------- ------- ----------- ---- -------- +// TextureUI texture uint4 2d 0 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, 128, 252, + 255, 238, 68, 109, 10, 133, + 175, 163, 216, 152, 219, 103, + 163, 223, 1, 0, 0, 0, + 156, 2, 0, 0, 5, 0, + 0, 0, 52, 0, 0, 0, + 180, 0, 0, 0, 12, 1, + 0, 0, 64, 1, 0, 0, + 32, 2, 0, 0, 82, 68, + 69, 70, 120, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 28, 0, 0, 0, 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, 54, 46, 51, + 46, 57, 54, 48, 48, 46, + 49, 54, 51, 56, 52, 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, + 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/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba3d11ps.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba3d11ps.h index 3d5f90a11194..ac4cbeae9fa9 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba3d11ps.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba3d11ps.h @@ -1,149 +1,149 @@ -#if 0 -// -// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 -// -// -// Resource Bindings: -// -// Name Type Format Dim Slot Elements -// ------------------------------ ---------- ------- ----------- ---- -------- -// Sampler sampler NA NA 0 1 -// TextureF texture float4 3d 0 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, 246, 41, - 15, 240, 168, 172, 91, 145, - 236, 221, 187, 89, 12, 0, - 93, 149, 1, 0, 0, 0, - 128, 2, 0, 0, 5, 0, - 0, 0, 52, 0, 0, 0, - 220, 0, 0, 0, 100, 1, - 0, 0, 152, 1, 0, 0, - 4, 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, - 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, - 54, 46, 51, 46, 57, 54, - 48, 48, 46, 49, 54, 51, - 56, 52, 0, 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 -}; +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 +// +// +// Resource Bindings: +// +// Name Type Format Dim Slot Elements +// ------------------------------ ---------- ------- ----------- ---- -------- +// Sampler sampler NA NA 0 1 +// TextureF texture float4 3d 0 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, 246, 41, + 15, 240, 168, 172, 91, 145, + 236, 221, 187, 89, 12, 0, + 93, 149, 1, 0, 0, 0, + 128, 2, 0, 0, 5, 0, + 0, 0, 52, 0, 0, 0, + 220, 0, 0, 0, 100, 1, + 0, 0, 152, 1, 0, 0, + 4, 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, + 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, + 54, 46, 51, 46, 57, 54, + 48, 48, 46, 49, 54, 51, + 56, 52, 0, 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/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba3di11ps.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba3di11ps.h index 8932128e156b..1921c9f20bf8 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba3di11ps.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba3di11ps.h @@ -1,164 +1,164 @@ -#if 0 -// -// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 -// -// -// Resource Bindings: -// -// Name Type Format Dim Slot Elements -// ------------------------------ ---------- ------- ----------- ---- -------- -// TextureI texture sint4 3d 0 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, 139, 158, - 6, 251, 163, 134, 3, 183, - 5, 227, 185, 108, 35, 91, - 67, 191, 1, 0, 0, 0, - 192, 2, 0, 0, 5, 0, - 0, 0, 52, 0, 0, 0, - 180, 0, 0, 0, 60, 1, - 0, 0, 112, 1, 0, 0, - 68, 2, 0, 0, 82, 68, - 69, 70, 120, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 1, 0, 0, 0, - 28, 0, 0, 0, 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, 54, 46, 51, 46, - 57, 54, 48, 48, 46, 49, - 54, 51, 56, 52, 0, 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 -}; +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 +// +// +// Resource Bindings: +// +// Name Type Format Dim Slot Elements +// ------------------------------ ---------- ------- ----------- ---- -------- +// TextureI texture sint4 3d 0 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, 139, 158, + 6, 251, 163, 134, 3, 183, + 5, 227, 185, 108, 35, 91, + 67, 191, 1, 0, 0, 0, + 192, 2, 0, 0, 5, 0, + 0, 0, 52, 0, 0, 0, + 180, 0, 0, 0, 60, 1, + 0, 0, 112, 1, 0, 0, + 68, 2, 0, 0, 82, 68, + 69, 70, 120, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 28, 0, 0, 0, 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, 54, 46, 51, 46, + 57, 54, 48, 48, 46, 49, + 54, 51, 56, 52, 0, 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/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba3dui11ps.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba3dui11ps.h index d4ac68918aa8..cba1502da1b3 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba3dui11ps.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba3dui11ps.h @@ -1,164 +1,164 @@ -#if 0 -// -// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 -// -// -// Resource Bindings: -// -// Name Type Format Dim Slot Elements -// ------------------------------ ---------- ------- ----------- ---- -------- -// TextureUI texture uint4 3d 0 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, 16, 111, - 56, 218, 148, 233, 100, 164, - 0, 199, 73, 155, 213, 171, - 78, 18, 1, 0, 0, 0, - 192, 2, 0, 0, 5, 0, - 0, 0, 52, 0, 0, 0, - 180, 0, 0, 0, 60, 1, - 0, 0, 112, 1, 0, 0, - 68, 2, 0, 0, 82, 68, - 69, 70, 120, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 1, 0, 0, 0, - 28, 0, 0, 0, 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, 54, 46, 51, - 46, 57, 54, 48, 48, 46, - 49, 54, 51, 56, 52, 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, - 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 -}; +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 +// +// +// Resource Bindings: +// +// Name Type Format Dim Slot Elements +// ------------------------------ ---------- ------- ----------- ---- -------- +// TextureUI texture uint4 3d 0 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, 16, 111, + 56, 218, 148, 233, 100, 164, + 0, 199, 73, 155, 213, 171, + 78, 18, 1, 0, 0, 0, + 192, 2, 0, 0, 5, 0, + 0, 0, 52, 0, 0, 0, + 180, 0, 0, 0, 60, 1, + 0, 0, 112, 1, 0, 0, + 68, 2, 0, 0, 82, 68, + 69, 70, 120, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 28, 0, 0, 0, 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, 54, 46, 51, + 46, 57, 54, 48, 48, 46, + 49, 54, 51, 56, 52, 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, + 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/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlef2darrayps.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlef2darrayps.h index ed694e7951ed..b34914b39472 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlef2darrayps.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlef2darrayps.h @@ -1,278 +1,278 @@ -#if 0 -// -// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 -// -// -// Buffer Definitions: -// -// cbuffer SwizzleProperties -// { -// -// uint4 SwizzleIndices; // Offset: 0 Size: 16 -// -// } -// -// -// Resource Bindings: -// -// Name Type Format Dim Slot Elements -// ------------------------------ ---------- ------- ----------- ---- -------- -// Sampler sampler NA NA 0 1 -// TextureF2DArray texture float4 2darray 0 1 -// SwizzleProperties cbuffer NA NA 0 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, 39, 232, - 91, 166, 165, 217, 22, 39, - 183, 202, 191, 64, 238, 104, - 217, 199, 1, 0, 0, 0, - 204, 4, 0, 0, 5, 0, - 0, 0, 52, 0, 0, 0, - 104, 1, 0, 0, 240, 1, - 0, 0, 36, 2, 0, 0, - 80, 4, 0, 0, 82, 68, - 69, 70, 44, 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, 54, 46, 51, 46, 57, - 54, 48, 48, 46, 49, 54, - 51, 56, 52, 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, 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 -}; +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 +// +// +// Buffer Definitions: +// +// cbuffer SwizzleProperties +// { +// +// uint4 SwizzleIndices; // Offset: 0 Size: 16 +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim Slot Elements +// ------------------------------ ---------- ------- ----------- ---- -------- +// Sampler sampler NA NA 0 1 +// TextureF2DArray texture float4 2darray 0 1 +// SwizzleProperties cbuffer NA NA 0 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, 39, 232, + 91, 166, 165, 217, 22, 39, + 183, 202, 191, 64, 238, 104, + 217, 199, 1, 0, 0, 0, + 204, 4, 0, 0, 5, 0, + 0, 0, 52, 0, 0, 0, + 104, 1, 0, 0, 240, 1, + 0, 0, 36, 2, 0, 0, + 80, 4, 0, 0, 82, 68, + 69, 70, 44, 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, 54, 46, 51, 46, 57, + 54, 48, 48, 46, 49, 54, + 51, 56, 52, 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, 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/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlef2dps.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlef2dps.h index 9be40c611aca..ea57e8737f53 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlef2dps.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlef2dps.h @@ -1,256 +1,256 @@ -#if 0 -// -// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 -// -// -// Buffer Definitions: -// -// cbuffer SwizzleProperties -// { -// -// uint4 SwizzleIndices; // Offset: 0 Size: 16 -// -// } -// -// -// Resource Bindings: -// -// Name Type Format Dim Slot Elements -// ------------------------------ ---------- ------- ----------- ---- -------- -// Sampler sampler NA NA 0 1 -// TextureF2D texture float4 2d 0 1 -// SwizzleProperties cbuffer NA NA 0 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, 187, 204, - 160, 39, 195, 158, 245, 72, - 125, 249, 70, 140, 158, 199, - 246, 220, 1, 0, 0, 0, - 96, 4, 0, 0, 5, 0, - 0, 0, 52, 0, 0, 0, - 100, 1, 0, 0, 188, 1, - 0, 0, 240, 1, 0, 0, - 228, 3, 0, 0, 82, 68, - 69, 70, 40, 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, 54, 46, 51, - 46, 57, 54, 48, 48, 46, - 49, 54, 51, 56, 52, 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, 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 -}; +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 +// +// +// Buffer Definitions: +// +// cbuffer SwizzleProperties +// { +// +// uint4 SwizzleIndices; // Offset: 0 Size: 16 +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim Slot Elements +// ------------------------------ ---------- ------- ----------- ---- -------- +// Sampler sampler NA NA 0 1 +// TextureF2D texture float4 2d 0 1 +// SwizzleProperties cbuffer NA NA 0 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, 187, 204, + 160, 39, 195, 158, 245, 72, + 125, 249, 70, 140, 158, 199, + 246, 220, 1, 0, 0, 0, + 96, 4, 0, 0, 5, 0, + 0, 0, 52, 0, 0, 0, + 100, 1, 0, 0, 188, 1, + 0, 0, 240, 1, 0, 0, + 228, 3, 0, 0, 82, 68, + 69, 70, 40, 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, 54, 46, 51, + 46, 57, 54, 48, 48, 46, + 49, 54, 51, 56, 52, 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, 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/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlef3dps.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlef3dps.h index 950af03dc3e2..7938639e68a9 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlef3dps.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlef3dps.h @@ -1,265 +1,265 @@ -#if 0 -// -// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 -// -// -// Buffer Definitions: -// -// cbuffer SwizzleProperties -// { -// -// uint4 SwizzleIndices; // Offset: 0 Size: 16 -// -// } -// -// -// Resource Bindings: -// -// Name Type Format Dim Slot Elements -// ------------------------------ ---------- ------- ----------- ---- -------- -// Sampler sampler NA NA 0 1 -// TextureF3D texture float4 3d 0 1 -// SwizzleProperties cbuffer NA NA 0 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, 238, 60, - 80, 74, 42, 65, 120, 165, - 177, 91, 253, 216, 89, 102, - 2, 228, 1, 0, 0, 0, - 144, 4, 0, 0, 5, 0, - 0, 0, 52, 0, 0, 0, - 100, 1, 0, 0, 236, 1, - 0, 0, 32, 2, 0, 0, - 20, 4, 0, 0, 82, 68, - 69, 70, 40, 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, 54, 46, 51, - 46, 57, 54, 48, 48, 46, - 49, 54, 51, 56, 52, 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, 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 -}; +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 +// +// +// Buffer Definitions: +// +// cbuffer SwizzleProperties +// { +// +// uint4 SwizzleIndices; // Offset: 0 Size: 16 +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim Slot Elements +// ------------------------------ ---------- ------- ----------- ---- -------- +// Sampler sampler NA NA 0 1 +// TextureF3D texture float4 3d 0 1 +// SwizzleProperties cbuffer NA NA 0 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, 238, 60, + 80, 74, 42, 65, 120, 165, + 177, 91, 253, 216, 89, 102, + 2, 228, 1, 0, 0, 0, + 144, 4, 0, 0, 5, 0, + 0, 0, 52, 0, 0, 0, + 100, 1, 0, 0, 236, 1, + 0, 0, 32, 2, 0, 0, + 20, 4, 0, 0, 82, 68, + 69, 70, 40, 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, 54, 46, 51, + 46, 57, 54, 48, 48, 46, + 49, 54, 51, 56, 52, 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, 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/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlei2darrayps.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlei2darrayps.h index 0a6a9f7b23c4..76176fcbece6 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlei2darrayps.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlei2darrayps.h @@ -1,286 +1,286 @@ -#if 0 -// -// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 -// -// -// Buffer Definitions: -// -// cbuffer SwizzleProperties -// { -// -// uint4 SwizzleIndices; // Offset: 0 Size: 16 -// -// } -// -// -// Resource Bindings: -// -// Name Type Format Dim Slot Elements -// ------------------------------ ---------- ------- ----------- ---- -------- -// TextureI2DArray texture sint4 2darray 0 1 -// SwizzleProperties cbuffer NA NA 0 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, 85, 61, - 60, 36, 33, 245, 58, 113, - 238, 227, 230, 200, 136, 227, - 36, 193, 1, 0, 0, 0, - 240, 4, 0, 0, 5, 0, - 0, 0, 52, 0, 0, 0, - 64, 1, 0, 0, 200, 1, - 0, 0, 252, 1, 0, 0, - 116, 4, 0, 0, 82, 68, - 69, 70, 4, 1, 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, 54, 46, 51, - 46, 57, 54, 48, 48, 46, - 49, 54, 51, 56, 52, 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, 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 -}; +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 +// +// +// Buffer Definitions: +// +// cbuffer SwizzleProperties +// { +// +// uint4 SwizzleIndices; // Offset: 0 Size: 16 +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim Slot Elements +// ------------------------------ ---------- ------- ----------- ---- -------- +// TextureI2DArray texture sint4 2darray 0 1 +// SwizzleProperties cbuffer NA NA 0 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, 85, 61, + 60, 36, 33, 245, 58, 113, + 238, 227, 230, 200, 136, 227, + 36, 193, 1, 0, 0, 0, + 240, 4, 0, 0, 5, 0, + 0, 0, 52, 0, 0, 0, + 64, 1, 0, 0, 200, 1, + 0, 0, 252, 1, 0, 0, + 116, 4, 0, 0, 82, 68, + 69, 70, 4, 1, 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, 54, 46, 51, + 46, 57, 54, 48, 48, 46, + 49, 54, 51, 56, 52, 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, 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/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlei2dps.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlei2dps.h index 56ebd54737ee..1df27a0bfc85 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlei2dps.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlei2dps.h @@ -1,270 +1,270 @@ -#if 0 -// -// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 -// -// -// Buffer Definitions: -// -// cbuffer SwizzleProperties -// { -// -// uint4 SwizzleIndices; // Offset: 0 Size: 16 -// -// } -// -// -// Resource Bindings: -// -// Name Type Format Dim Slot Elements -// ------------------------------ ---------- ------- ----------- ---- -------- -// TextureI2D texture sint4 2d 0 1 -// SwizzleProperties cbuffer NA NA 0 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, 180, 37, - 54, 19, 39, 134, 185, 230, - 234, 82, 113, 129, 69, 135, - 140, 27, 1, 0, 0, 0, - 164, 4, 0, 0, 5, 0, - 0, 0, 52, 0, 0, 0, - 60, 1, 0, 0, 148, 1, - 0, 0, 200, 1, 0, 0, - 40, 4, 0, 0, 82, 68, - 69, 70, 0, 1, 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, 54, - 46, 51, 46, 57, 54, 48, - 48, 46, 49, 54, 51, 56, - 52, 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, - 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 -}; +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 +// +// +// Buffer Definitions: +// +// cbuffer SwizzleProperties +// { +// +// uint4 SwizzleIndices; // Offset: 0 Size: 16 +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim Slot Elements +// ------------------------------ ---------- ------- ----------- ---- -------- +// TextureI2D texture sint4 2d 0 1 +// SwizzleProperties cbuffer NA NA 0 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, 180, 37, + 54, 19, 39, 134, 185, 230, + 234, 82, 113, 129, 69, 135, + 140, 27, 1, 0, 0, 0, + 164, 4, 0, 0, 5, 0, + 0, 0, 52, 0, 0, 0, + 60, 1, 0, 0, 148, 1, + 0, 0, 200, 1, 0, 0, + 40, 4, 0, 0, 82, 68, + 69, 70, 0, 1, 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, 54, + 46, 51, 46, 57, 54, 48, + 48, 46, 49, 54, 51, 56, + 52, 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, + 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/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlei3dps.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlei3dps.h index 984f84731de2..96f042b5b702 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlei3dps.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlei3dps.h @@ -1,277 +1,277 @@ -#if 0 -// -// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 -// -// -// Buffer Definitions: -// -// cbuffer SwizzleProperties -// { -// -// uint4 SwizzleIndices; // Offset: 0 Size: 16 -// -// } -// -// -// Resource Bindings: -// -// Name Type Format Dim Slot Elements -// ------------------------------ ---------- ------- ----------- ---- -------- -// TextureI3D texture sint4 3d 0 1 -// SwizzleProperties cbuffer NA NA 0 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, 48, 84, - 97, 193, 216, 245, 101, 196, - 167, 81, 215, 168, 25, 164, - 144, 38, 1, 0, 0, 0, - 200, 4, 0, 0, 5, 0, - 0, 0, 52, 0, 0, 0, - 60, 1, 0, 0, 196, 1, - 0, 0, 248, 1, 0, 0, - 76, 4, 0, 0, 82, 68, - 69, 70, 0, 1, 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, 54, - 46, 51, 46, 57, 54, 48, - 48, 46, 49, 54, 51, 56, - 52, 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, - 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 -}; +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 +// +// +// Buffer Definitions: +// +// cbuffer SwizzleProperties +// { +// +// uint4 SwizzleIndices; // Offset: 0 Size: 16 +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim Slot Elements +// ------------------------------ ---------- ------- ----------- ---- -------- +// TextureI3D texture sint4 3d 0 1 +// SwizzleProperties cbuffer NA NA 0 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, 48, 84, + 97, 193, 216, 245, 101, 196, + 167, 81, 215, 168, 25, 164, + 144, 38, 1, 0, 0, 0, + 200, 4, 0, 0, 5, 0, + 0, 0, 52, 0, 0, 0, + 60, 1, 0, 0, 196, 1, + 0, 0, 248, 1, 0, 0, + 76, 4, 0, 0, 82, 68, + 69, 70, 0, 1, 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, 54, + 46, 51, 46, 57, 54, 48, + 48, 46, 49, 54, 51, 56, + 52, 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, + 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/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzleui2darrayps.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzleui2darrayps.h index 0871601007a8..cca965c6f248 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzleui2darrayps.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzleui2darrayps.h @@ -1,286 +1,286 @@ -#if 0 -// -// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 -// -// -// Buffer Definitions: -// -// cbuffer SwizzleProperties -// { -// -// uint4 SwizzleIndices; // Offset: 0 Size: 16 -// -// } -// -// -// Resource Bindings: -// -// Name Type Format Dim Slot Elements -// ------------------------------ ---------- ------- ----------- ---- -------- -// TextureUI2DArray texture uint4 2darray 0 1 -// SwizzleProperties cbuffer NA NA 0 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, 15, 124, - 179, 49, 45, 69, 64, 249, - 216, 189, 135, 190, 71, 234, - 72, 20, 1, 0, 0, 0, - 240, 4, 0, 0, 5, 0, - 0, 0, 52, 0, 0, 0, - 64, 1, 0, 0, 200, 1, - 0, 0, 252, 1, 0, 0, - 116, 4, 0, 0, 82, 68, - 69, 70, 4, 1, 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, 54, 46, 51, - 46, 57, 54, 48, 48, 46, - 49, 54, 51, 56, 52, 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, 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 -}; +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 +// +// +// Buffer Definitions: +// +// cbuffer SwizzleProperties +// { +// +// uint4 SwizzleIndices; // Offset: 0 Size: 16 +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim Slot Elements +// ------------------------------ ---------- ------- ----------- ---- -------- +// TextureUI2DArray texture uint4 2darray 0 1 +// SwizzleProperties cbuffer NA NA 0 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, 15, 124, + 179, 49, 45, 69, 64, 249, + 216, 189, 135, 190, 71, 234, + 72, 20, 1, 0, 0, 0, + 240, 4, 0, 0, 5, 0, + 0, 0, 52, 0, 0, 0, + 64, 1, 0, 0, 200, 1, + 0, 0, 252, 1, 0, 0, + 116, 4, 0, 0, 82, 68, + 69, 70, 4, 1, 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, 54, 46, 51, + 46, 57, 54, 48, 48, 46, + 49, 54, 51, 56, 52, 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, 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/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzleui2dps.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzleui2dps.h index bce67953843e..9de8b28a87ec 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzleui2dps.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzleui2dps.h @@ -1,270 +1,270 @@ -#if 0 -// -// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 -// -// -// Buffer Definitions: -// -// cbuffer SwizzleProperties -// { -// -// uint4 SwizzleIndices; // Offset: 0 Size: 16 -// -// } -// -// -// Resource Bindings: -// -// Name Type Format Dim Slot Elements -// ------------------------------ ---------- ------- ----------- ---- -------- -// TextureUI2D texture uint4 2d 0 1 -// SwizzleProperties cbuffer NA NA 0 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, 165, 190, - 35, 188, 235, 202, 154, 237, - 226, 86, 223, 212, 34, 38, - 81, 252, 1, 0, 0, 0, - 164, 4, 0, 0, 5, 0, - 0, 0, 52, 0, 0, 0, - 60, 1, 0, 0, 148, 1, - 0, 0, 200, 1, 0, 0, - 40, 4, 0, 0, 82, 68, - 69, 70, 0, 1, 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, 54, - 46, 51, 46, 57, 54, 48, - 48, 46, 49, 54, 51, 56, - 52, 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, 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 -}; +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 +// +// +// Buffer Definitions: +// +// cbuffer SwizzleProperties +// { +// +// uint4 SwizzleIndices; // Offset: 0 Size: 16 +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim Slot Elements +// ------------------------------ ---------- ------- ----------- ---- -------- +// TextureUI2D texture uint4 2d 0 1 +// SwizzleProperties cbuffer NA NA 0 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, 165, 190, + 35, 188, 235, 202, 154, 237, + 226, 86, 223, 212, 34, 38, + 81, 252, 1, 0, 0, 0, + 164, 4, 0, 0, 5, 0, + 0, 0, 52, 0, 0, 0, + 60, 1, 0, 0, 148, 1, + 0, 0, 200, 1, 0, 0, + 40, 4, 0, 0, 82, 68, + 69, 70, 0, 1, 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, 54, + 46, 51, 46, 57, 54, 48, + 48, 46, 49, 54, 51, 56, + 52, 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, 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/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzleui3dps.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzleui3dps.h index 8cd8e37266c8..c66821602b7b 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzleui3dps.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzleui3dps.h @@ -1,277 +1,277 @@ -#if 0 -// -// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 -// -// -// Buffer Definitions: -// -// cbuffer SwizzleProperties -// { -// -// uint4 SwizzleIndices; // Offset: 0 Size: 16 -// -// } -// -// -// Resource Bindings: -// -// Name Type Format Dim Slot Elements -// ------------------------------ ---------- ------- ----------- ---- -------- -// TextureUI3D texture uint4 3d 0 1 -// SwizzleProperties cbuffer NA NA 0 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, 186, 124, - 222, 110, 186, 145, 165, 56, - 152, 97, 247, 114, 115, 197, - 159, 190, 1, 0, 0, 0, - 200, 4, 0, 0, 5, 0, - 0, 0, 52, 0, 0, 0, - 60, 1, 0, 0, 196, 1, - 0, 0, 248, 1, 0, 0, - 76, 4, 0, 0, 82, 68, - 69, 70, 0, 1, 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, 54, - 46, 51, 46, 57, 54, 48, - 48, 46, 49, 54, 51, 56, - 52, 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, 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 -}; +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 +// +// +// Buffer Definitions: +// +// cbuffer SwizzleProperties +// { +// +// uint4 SwizzleIndices; // Offset: 0 Size: 16 +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim Slot Elements +// ------------------------------ ---------- ------- ----------- ---- -------- +// TextureUI3D texture uint4 3d 0 1 +// SwizzleProperties cbuffer NA NA 0 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, 186, 124, + 222, 110, 186, 145, 165, 56, + 152, 97, 247, 114, 115, 197, + 159, 190, 1, 0, 0, 0, + 200, 4, 0, 0, 5, 0, + 0, 0, 52, 0, 0, 0, + 60, 1, 0, 0, 196, 1, + 0, 0, 248, 1, 0, 0, + 76, 4, 0, 0, 82, 68, + 69, 70, 0, 1, 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, 54, + 46, 51, 46, 57, 54, 48, + 48, 46, 49, 54, 51, 56, + 52, 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, 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/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/generate_shaders.bat b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/generate_shaders.bat index 652c5eae90c3..bd62355c6fdb 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/generate_shaders.bat +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/shaders/generate_shaders.bat @@ -1,125 +1,125 @@ -@ECHO OFF -REM -REM Copyright (c) 2013 The ANGLE Project Authors. All rights reserved. -REM Use of this source code is governed by a BSD-style license that can be -REM found in the LICENSE file. -REM - -PATH %PATH%;%ProgramFiles(x86)%\Windows Kits\8.1\bin\x86;%DXSDK_DIR%\Utilities\bin\x86 - -setlocal -set errorCount=0 -set successCount=0 -set debug=0 - -if "%1" == "debug" ( - set debug=1 -) -if "%1" == "release" ( - set debug=0 -) - -:: Shaders for OpenGL ES 2.0 and OpenGL ES 3.0+ -:: | Input file | Entry point | Type | Output file | Debug | -call:BuildShader Passthrough2D11.hlsl VS_Passthrough2D vs_4_0_level_9_3 compiled\passthrough2d11vs.h %debug% -call:BuildShader Passthrough2D11.hlsl PS_PassthroughRGBA2D ps_4_0_level_9_3 compiled\passthroughrgba2d11ps.h %debug% -call:BuildShader Passthrough2D11.hlsl PS_PassthroughRGB2D ps_4_0_level_9_3 compiled\passthroughrgb2d11ps.h %debug% -call:BuildShader Passthrough2D11.hlsl PS_PassthroughRG2D ps_4_0_level_9_3 compiled\passthroughrg2d11ps.h %debug% -call:BuildShader Passthrough2D11.hlsl PS_PassthroughR2D ps_4_0_level_9_3 compiled\passthroughr2d11ps.h %debug% -call:BuildShader Passthrough2D11.hlsl PS_PassthroughLum2D ps_4_0_level_9_3 compiled\passthroughlum2d11ps.h %debug% -call:BuildShader Passthrough2D11.hlsl PS_PassthroughLumAlpha2D ps_4_0_level_9_3 compiled\passthroughlumalpha2d11ps.h %debug% - -call:BuildShader Clear11.hlsl VS_ClearFloat vs_4_0_level_9_3 compiled\clearfloat11vs.h %debug% -call:BuildShader Clear11.hlsl PS_ClearFloat_FL9 ps_4_0_level_9_3 compiled\clearfloat11_fl9ps.h %debug% -call:BuildShader Clear11.hlsl PS_ClearFloat ps_4_0 compiled\clearfloat11ps.h %debug% - - -:: Shaders for OpenGL ES 3.0+ only -:: | Input file | Entry point | Type | Output file | Debug | -call:BuildShader Passthrough2D11.hlsl PS_PassthroughDepth2D ps_4_0 compiled\passthroughdepth2d11ps.h %debug% -call:BuildShader Passthrough2D11.hlsl PS_PassthroughRGBA2DUI ps_4_0 compiled\passthroughrgba2dui11ps.h %debug% -call:BuildShader Passthrough2D11.hlsl PS_PassthroughRGBA2DI ps_4_0 compiled\passthroughrgba2di11ps.h %debug% -call:BuildShader Passthrough2D11.hlsl PS_PassthroughRGB2DUI ps_4_0 compiled\passthroughrgb2dui11ps.h %debug% -call:BuildShader Passthrough2D11.hlsl PS_PassthroughRGB2DI ps_4_0 compiled\passthroughrgb2di11ps.h %debug% -call:BuildShader Passthrough2D11.hlsl PS_PassthroughRG2DUI ps_4_0 compiled\passthroughrg2dui11ps.h %debug% -call:BuildShader Passthrough2D11.hlsl PS_PassthroughRG2DI ps_4_0 compiled\passthroughrg2di11ps.h %debug% -call:BuildShader Passthrough2D11.hlsl PS_PassthroughR2DUI ps_4_0 compiled\passthroughr2dui11ps.h %debug% -call:BuildShader Passthrough2D11.hlsl PS_PassthroughR2DI ps_4_0 compiled\passthroughr2di11ps.h %debug% - - -call:BuildShader Passthrough3D11.hlsl VS_Passthrough3D vs_4_0 compiled\passthrough3d11vs.h %debug% -call:BuildShader Passthrough3D11.hlsl GS_Passthrough3D gs_4_0 compiled\passthrough3d11gs.h %debug% -call:BuildShader Passthrough3D11.hlsl PS_PassthroughRGBA3D ps_4_0 compiled\passthroughrgba3d11ps.h %debug% -call:BuildShader Passthrough3D11.hlsl PS_PassthroughRGBA3DUI ps_4_0 compiled\passthroughrgba3dui11ps.h %debug% -call:BuildShader Passthrough3D11.hlsl PS_PassthroughRGBA3DI ps_4_0 compiled\passthroughrgba3di11ps.h %debug% -call:BuildShader Passthrough3D11.hlsl PS_PassthroughRGB3D ps_4_0 compiled\passthroughrgb3d11ps.h %debug% -call:BuildShader Passthrough3D11.hlsl PS_PassthroughRGB3DUI ps_4_0 compiled\passthroughrgb3dui11ps.h %debug% -call:BuildShader Passthrough3D11.hlsl PS_PassthroughRGB3DI ps_4_0 compiled\passthroughrgb3di11ps.h %debug% -call:BuildShader Passthrough3D11.hlsl PS_PassthroughRG3D ps_4_0 compiled\passthroughrg3d11ps.h %debug% -call:BuildShader Passthrough3D11.hlsl PS_PassthroughRG3DUI ps_4_0 compiled\passthroughrg3dui11ps.h %debug% -call:BuildShader Passthrough3D11.hlsl PS_PassthroughRG3DI ps_4_0 compiled\passthroughrg3di11ps.h %debug% -call:BuildShader Passthrough3D11.hlsl PS_PassthroughR3D ps_4_0 compiled\passthroughr3d11ps.h %debug% -call:BuildShader Passthrough3D11.hlsl PS_PassthroughR3DUI ps_4_0 compiled\passthroughr3dui11ps.h %debug% -call:BuildShader Passthrough3D11.hlsl PS_PassthroughR3DI ps_4_0 compiled\passthroughr3di11ps.h %debug% -call:BuildShader Passthrough3D11.hlsl PS_PassthroughLum3D ps_4_0 compiled\passthroughlum3d11ps.h %debug% -call:BuildShader Passthrough3D11.hlsl PS_PassthroughLumAlpha3D ps_4_0 compiled\passthroughlumalpha3d11ps.h %debug% - -call:BuildShader Swizzle11.hlsl PS_SwizzleF2D ps_4_0 compiled\swizzlef2dps.h %debug% -call:BuildShader Swizzle11.hlsl PS_SwizzleI2D ps_4_0 compiled\swizzlei2dps.h %debug% -call:BuildShader Swizzle11.hlsl PS_SwizzleUI2D ps_4_0 compiled\swizzleui2dps.h %debug% - -call:BuildShader Swizzle11.hlsl PS_SwizzleF3D ps_4_0 compiled\swizzlef3dps.h %debug% -call:BuildShader Swizzle11.hlsl PS_SwizzleI3D ps_4_0 compiled\swizzlei3dps.h %debug% -call:BuildShader Swizzle11.hlsl PS_SwizzleUI3D ps_4_0 compiled\swizzleui3dps.h %debug% - -call:BuildShader Swizzle11.hlsl PS_SwizzleF2DArray ps_4_0 compiled\swizzlef2darrayps.h %debug% -call:BuildShader Swizzle11.hlsl PS_SwizzleI2DArray ps_4_0 compiled\swizzlei2darrayps.h %debug% -call:BuildShader Swizzle11.hlsl PS_SwizzleUI2DArray ps_4_0 compiled\swizzleui2darrayps.h %debug% - -call:BuildShader Clear11.hlsl VS_ClearUint vs_4_0 compiled\clearuint11vs.h %debug% -call:BuildShader Clear11.hlsl PS_ClearUint ps_4_0 compiled\clearuint11ps.h %debug% - -call:BuildShader Clear11.hlsl VS_ClearSint vs_4_0 compiled\clearsint11vs.h %debug% -call:BuildShader Clear11.hlsl PS_ClearSint ps_4_0 compiled\clearsint11ps.h %debug% - -call:BuildShader BufferToTexture11.hlsl VS_BufferToTexture vs_4_0 compiled/buffertotexture11_vs.h %debug% -call:BuildShader BufferToTexture11.hlsl GS_BufferToTexture gs_4_0 compiled/buffertotexture11_gs.h %debug% -call:BuildShader BufferToTexture11.hlsl PS_BufferToTexture_4F ps_4_0 compiled/buffertotexture11_ps_4f.h %debug% -call:BuildShader BufferToTexture11.hlsl PS_BufferToTexture_4I ps_4_0 compiled/buffertotexture11_ps_4i.h %debug% -call:BuildShader BufferToTexture11.hlsl PS_BufferToTexture_4UI ps_4_0 compiled/buffertotexture11_ps_4ui.h %debug% - -echo. - -if %successCount% GTR 0 ( - echo %successCount% shaders compiled successfully. -) -if %errorCount% GTR 0 ( - echo There were %errorCount% shader compilation errors. -) - -endlocal -exit /b - -:BuildShader -set input=%~1 -set entry=%~2 -set type=%~3 -set output=%~4 -set debug=%~5 - -if %debug% == 0 ( - set "buildCMD=fxc /nologo /E %entry% /T %type% /Fh %output% %input%" -) else ( - set "buildCMD=fxc /nologo /Zi /Od /E %entry% /T %type% /Fh %output% %input%" -) - -set error=0 -%buildCMD% || set error=1 - -if %error% == 0 ( - set /a successCount=%successCount%+1 -) else ( - set /a errorCount=%errorCount%+1 -) - -exit /b +@ECHO OFF +REM +REM Copyright (c) 2013 The ANGLE Project Authors. All rights reserved. +REM Use of this source code is governed by a BSD-style license that can be +REM found in the LICENSE file. +REM + +PATH %PATH%;%ProgramFiles(x86)%\Windows Kits\8.1\bin\x86;%DXSDK_DIR%\Utilities\bin\x86 + +setlocal +set errorCount=0 +set successCount=0 +set debug=0 + +if "%1" == "debug" ( + set debug=1 +) +if "%1" == "release" ( + set debug=0 +) + +:: Shaders for OpenGL ES 2.0 and OpenGL ES 3.0+ +:: | Input file | Entry point | Type | Output file | Debug | +call:BuildShader Passthrough2D11.hlsl VS_Passthrough2D vs_4_0_level_9_3 compiled\passthrough2d11vs.h %debug% +call:BuildShader Passthrough2D11.hlsl PS_PassthroughRGBA2D ps_4_0_level_9_3 compiled\passthroughrgba2d11ps.h %debug% +call:BuildShader Passthrough2D11.hlsl PS_PassthroughRGB2D ps_4_0_level_9_3 compiled\passthroughrgb2d11ps.h %debug% +call:BuildShader Passthrough2D11.hlsl PS_PassthroughRG2D ps_4_0_level_9_3 compiled\passthroughrg2d11ps.h %debug% +call:BuildShader Passthrough2D11.hlsl PS_PassthroughR2D ps_4_0_level_9_3 compiled\passthroughr2d11ps.h %debug% +call:BuildShader Passthrough2D11.hlsl PS_PassthroughLum2D ps_4_0_level_9_3 compiled\passthroughlum2d11ps.h %debug% +call:BuildShader Passthrough2D11.hlsl PS_PassthroughLumAlpha2D ps_4_0_level_9_3 compiled\passthroughlumalpha2d11ps.h %debug% + +call:BuildShader Clear11.hlsl VS_ClearFloat vs_4_0_level_9_3 compiled\clearfloat11vs.h %debug% +call:BuildShader Clear11.hlsl PS_ClearFloat_FL9 ps_4_0_level_9_3 compiled\clearfloat11_fl9ps.h %debug% +call:BuildShader Clear11.hlsl PS_ClearFloat ps_4_0 compiled\clearfloat11ps.h %debug% + + +:: Shaders for OpenGL ES 3.0+ only +:: | Input file | Entry point | Type | Output file | Debug | +call:BuildShader Passthrough2D11.hlsl PS_PassthroughDepth2D ps_4_0 compiled\passthroughdepth2d11ps.h %debug% +call:BuildShader Passthrough2D11.hlsl PS_PassthroughRGBA2DUI ps_4_0 compiled\passthroughrgba2dui11ps.h %debug% +call:BuildShader Passthrough2D11.hlsl PS_PassthroughRGBA2DI ps_4_0 compiled\passthroughrgba2di11ps.h %debug% +call:BuildShader Passthrough2D11.hlsl PS_PassthroughRGB2DUI ps_4_0 compiled\passthroughrgb2dui11ps.h %debug% +call:BuildShader Passthrough2D11.hlsl PS_PassthroughRGB2DI ps_4_0 compiled\passthroughrgb2di11ps.h %debug% +call:BuildShader Passthrough2D11.hlsl PS_PassthroughRG2DUI ps_4_0 compiled\passthroughrg2dui11ps.h %debug% +call:BuildShader Passthrough2D11.hlsl PS_PassthroughRG2DI ps_4_0 compiled\passthroughrg2di11ps.h %debug% +call:BuildShader Passthrough2D11.hlsl PS_PassthroughR2DUI ps_4_0 compiled\passthroughr2dui11ps.h %debug% +call:BuildShader Passthrough2D11.hlsl PS_PassthroughR2DI ps_4_0 compiled\passthroughr2di11ps.h %debug% + + +call:BuildShader Passthrough3D11.hlsl VS_Passthrough3D vs_4_0 compiled\passthrough3d11vs.h %debug% +call:BuildShader Passthrough3D11.hlsl GS_Passthrough3D gs_4_0 compiled\passthrough3d11gs.h %debug% +call:BuildShader Passthrough3D11.hlsl PS_PassthroughRGBA3D ps_4_0 compiled\passthroughrgba3d11ps.h %debug% +call:BuildShader Passthrough3D11.hlsl PS_PassthroughRGBA3DUI ps_4_0 compiled\passthroughrgba3dui11ps.h %debug% +call:BuildShader Passthrough3D11.hlsl PS_PassthroughRGBA3DI ps_4_0 compiled\passthroughrgba3di11ps.h %debug% +call:BuildShader Passthrough3D11.hlsl PS_PassthroughRGB3D ps_4_0 compiled\passthroughrgb3d11ps.h %debug% +call:BuildShader Passthrough3D11.hlsl PS_PassthroughRGB3DUI ps_4_0 compiled\passthroughrgb3dui11ps.h %debug% +call:BuildShader Passthrough3D11.hlsl PS_PassthroughRGB3DI ps_4_0 compiled\passthroughrgb3di11ps.h %debug% +call:BuildShader Passthrough3D11.hlsl PS_PassthroughRG3D ps_4_0 compiled\passthroughrg3d11ps.h %debug% +call:BuildShader Passthrough3D11.hlsl PS_PassthroughRG3DUI ps_4_0 compiled\passthroughrg3dui11ps.h %debug% +call:BuildShader Passthrough3D11.hlsl PS_PassthroughRG3DI ps_4_0 compiled\passthroughrg3di11ps.h %debug% +call:BuildShader Passthrough3D11.hlsl PS_PassthroughR3D ps_4_0 compiled\passthroughr3d11ps.h %debug% +call:BuildShader Passthrough3D11.hlsl PS_PassthroughR3DUI ps_4_0 compiled\passthroughr3dui11ps.h %debug% +call:BuildShader Passthrough3D11.hlsl PS_PassthroughR3DI ps_4_0 compiled\passthroughr3di11ps.h %debug% +call:BuildShader Passthrough3D11.hlsl PS_PassthroughLum3D ps_4_0 compiled\passthroughlum3d11ps.h %debug% +call:BuildShader Passthrough3D11.hlsl PS_PassthroughLumAlpha3D ps_4_0 compiled\passthroughlumalpha3d11ps.h %debug% + +call:BuildShader Swizzle11.hlsl PS_SwizzleF2D ps_4_0 compiled\swizzlef2dps.h %debug% +call:BuildShader Swizzle11.hlsl PS_SwizzleI2D ps_4_0 compiled\swizzlei2dps.h %debug% +call:BuildShader Swizzle11.hlsl PS_SwizzleUI2D ps_4_0 compiled\swizzleui2dps.h %debug% + +call:BuildShader Swizzle11.hlsl PS_SwizzleF3D ps_4_0 compiled\swizzlef3dps.h %debug% +call:BuildShader Swizzle11.hlsl PS_SwizzleI3D ps_4_0 compiled\swizzlei3dps.h %debug% +call:BuildShader Swizzle11.hlsl PS_SwizzleUI3D ps_4_0 compiled\swizzleui3dps.h %debug% + +call:BuildShader Swizzle11.hlsl PS_SwizzleF2DArray ps_4_0 compiled\swizzlef2darrayps.h %debug% +call:BuildShader Swizzle11.hlsl PS_SwizzleI2DArray ps_4_0 compiled\swizzlei2darrayps.h %debug% +call:BuildShader Swizzle11.hlsl PS_SwizzleUI2DArray ps_4_0 compiled\swizzleui2darrayps.h %debug% + +call:BuildShader Clear11.hlsl VS_ClearUint vs_4_0 compiled\clearuint11vs.h %debug% +call:BuildShader Clear11.hlsl PS_ClearUint ps_4_0 compiled\clearuint11ps.h %debug% + +call:BuildShader Clear11.hlsl VS_ClearSint vs_4_0 compiled\clearsint11vs.h %debug% +call:BuildShader Clear11.hlsl PS_ClearSint ps_4_0 compiled\clearsint11ps.h %debug% + +call:BuildShader BufferToTexture11.hlsl VS_BufferToTexture vs_4_0 compiled/buffertotexture11_vs.h %debug% +call:BuildShader BufferToTexture11.hlsl GS_BufferToTexture gs_4_0 compiled/buffertotexture11_gs.h %debug% +call:BuildShader BufferToTexture11.hlsl PS_BufferToTexture_4F ps_4_0 compiled/buffertotexture11_ps_4f.h %debug% +call:BuildShader BufferToTexture11.hlsl PS_BufferToTexture_4I ps_4_0 compiled/buffertotexture11_ps_4i.h %debug% +call:BuildShader BufferToTexture11.hlsl PS_BufferToTexture_4UI ps_4_0 compiled/buffertotexture11_ps_4ui.h %debug% + +echo. + +if %successCount% GTR 0 ( + echo %successCount% shaders compiled successfully. +) +if %errorCount% GTR 0 ( + echo There were %errorCount% shader compilation errors. +) + +endlocal +exit /b + +:BuildShader +set input=%~1 +set entry=%~2 +set type=%~3 +set output=%~4 +set debug=%~5 + +if %debug% == 0 ( + set "buildCMD=fxc /nologo /E %entry% /T %type% /Fh %output% %input%" +) else ( + set "buildCMD=fxc /nologo /Zi /Od /E %entry% /T %type% /Fh %output% %input%" +) + +set error=0 +%buildCMD% || set error=1 + +if %error% == 0 ( + set /a successCount=%successCount%+1 +) else ( + set /a errorCount=%errorCount%+1 +) + +exit /b diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/texture_format_data.json b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/texture_format_data.json new file mode 100644 index 000000000000..0cd6454ed35a --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/texture_format_data.json @@ -0,0 +1,502 @@ +{ + "ANGLE_FORMAT_NONE": { + + }, + "ANGLE_FORMAT_A8_UNORM": { + "texFormat": "DXGI_FORMAT_A8_UNORM", + "srvFormat": "DXGI_FORMAT_A8_UNORM", + "rtvFormat": "DXGI_FORMAT_A8_UNORM", + "channels": "a", + "componentType": "unorm", + "bits": { "alpha": 8 }, + "glInternalFormat": "GL_ALPHA8_EXT" + }, + "ANGLE_FORMAT_R8G8B8A8_UNORM": { + "texFormat": "DXGI_FORMAT_R8G8B8A8_UNORM", + "srvFormat": "DXGI_FORMAT_R8G8B8A8_UNORM", + "rtvFormat": "DXGI_FORMAT_R8G8B8A8_UNORM", + "channels": "rgba", + "componentType": "unorm", + "bits": { "red": 8, "green": 8, "blue": 8, "alpha": 8 }, + "glInternalFormat": "GL_RGBA8" + }, + "ANGLE_FORMAT_R16G16B16A16_UNORM": { + "texFormat": "DXGI_FORMAT_R16G16B16A16_UNORM", + "srvFormat": "DXGI_FORMAT_R16G16B16A16_UNORM", + "rtvFormat": "DXGI_FORMAT_R16G16B16A16_UNORM", + "channels": "rgba", + "componentType": "unorm", + "bits": { "red": 16, "green": 16, "blue": 16, "alpha": 16 } + }, + "ANGLE_FORMAT_R16G16B16A16_FLOAT": { + "texFormat": "DXGI_FORMAT_R16G16B16A16_FLOAT", + "srvFormat": "DXGI_FORMAT_R16G16B16A16_FLOAT", + "rtvFormat": "DXGI_FORMAT_R16G16B16A16_FLOAT", + "channels": "rgba", + "componentType": "float", + "bits": { "red": 16, "green": 16, "blue": 16, "alpha": 16 }, + "glInternalFormat": "GL_RGBA16F" + }, + "ANGLE_FORMAT_R32G32B32A32_FLOAT": { + "texFormat": "DXGI_FORMAT_R32G32B32A32_FLOAT", + "srvFormat": "DXGI_FORMAT_R32G32B32A32_FLOAT", + "rtvFormat": "DXGI_FORMAT_R32G32B32A32_FLOAT", + "channels": "rgba", + "componentType": "float", + "bits": { "red": 32, "green": 32, "blue": 32, "alpha": 32 }, + "glInternalFormat": "GL_RGBA32F" + }, + "ANGLE_FORMAT_B8G8R8A8_UNORM": { + "texFormat": "DXGI_FORMAT_B8G8R8A8_UNORM", + "srvFormat": "DXGI_FORMAT_B8G8R8A8_UNORM", + "rtvFormat": "DXGI_FORMAT_B8G8R8A8_UNORM", + "channels": "bgra", + "componentType": "unorm", + "bits": { "red": 8, "green": 8, "blue": 8, "alpha": 8 }, + "glInternalFormat": "GL_BGRA8_EXT" + }, + "ANGLE_FORMAT_R8G8B8A8_UNORM_NONRENDERABLE": { + "texFormat": "DXGI_FORMAT_R8G8B8A8_UNORM", + "srvFormat": "DXGI_FORMAT_R8G8B8A8_UNORM", + "channels": "rgba", + "componentType": "unorm", + "bits": { "red": 8, "green": 8, "blue": 8, "alpha": 8 }, + "glInternalFormat": "GL_RGBA8" + }, + "ANGLE_FORMAT_BC1_UNORM": { + "texFormat": "DXGI_FORMAT_BC1_UNORM", + "srvFormat": "DXGI_FORMAT_BC1_UNORM", + "channels": "rgba", + "componentType": "unorm", + "swizzleFormat": "ANGLE_FORMAT_R8G8B8A8_UNORM", + "glInternalFormat": "GL_COMPRESSED_RGBA_S3TC_DXT1_EXT" + }, + "ANGLE_FORMAT_BC2_UNORM": { + "texFormat": "DXGI_FORMAT_BC2_UNORM", + "srvFormat": "DXGI_FORMAT_BC2_UNORM", + "channels": "rgba", + "componentType": "unorm", + "swizzleFormat": "ANGLE_FORMAT_R8G8B8A8_UNORM", + "glInternalFormat": "GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE" + }, + "ANGLE_FORMAT_BC3_UNORM": { + "texFormat": "DXGI_FORMAT_BC3_UNORM", + "srvFormat": "DXGI_FORMAT_BC3_UNORM", + "channels": "rgba", + "componentType": "unorm", + "swizzleFormat": "ANGLE_FORMAT_R8G8B8A8_UNORM", + "glInternalFormat": "GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE" + }, + "ANGLE_FORMAT_R8_SNORM_NONRENDERABLE": { + "texFormat": "DXGI_FORMAT_R8_SNORM", + "srvFormat": "DXGI_FORMAT_R8_SNORM", + "channels": "r", + "componentType": "snorm", + "bits": { "red": 8 }, + "glInternalFormat": "GL_R8_SNORM" + }, + "ANGLE_FORMAT_R8G8_SNORM_NONRENDERABLE": { + "texFormat": "DXGI_FORMAT_R8G8_SNORM", + "srvFormat": "DXGI_FORMAT_R8G8_SNORM", + "channels": "rg", + "componentType": "snorm", + "bits": { "red": 8, "green": 8 }, + "glInternalFormat": "GL_RG8_SNORM" + }, + "ANGLE_FORMAT_R8G8B8A8_UNORM_SRGB_NONRENDERABLE": { + "texFormat": "DXGI_FORMAT_R8G8B8A8_UNORM_SRGB", + "srvFormat": "DXGI_FORMAT_R8G8B8A8_UNORM_SRGB", + "channels": "rgba", + "componentType": "unorm", + "bits": { "red": 8, "green": 8, "blue": 8, "alpha": 8 }, + "glInternalFormat": "GL_SRGB8_ALPHA8" + }, + "ANGLE_FORMAT_D24_UNORM_S8_UINT_FL10": { + "texFormat": "DXGI_FORMAT_R24G8_TYPELESS", + "srvFormat": "DXGI_FORMAT_R24_UNORM_X8_TYPELESS", + "dsvFormat": "DXGI_FORMAT_D24_UNORM_S8_UINT", + "channels": "ds", + "bits": { "depth": 24, "stencil": 8 }, + "glInternalFormat": "GL_DEPTH24_STENCIL8_OES" + }, + "ANGLE_FORMAT_D24_UNORM_S8_UINT_FL9_3": { + "texFormat": "DXGI_FORMAT_D24_UNORM_S8_UINT", + "dsvFormat": "DXGI_FORMAT_D24_UNORM_S8_UINT", + "channels": "ds", + "bits": { "depth": 24, "stencil": 8 }, + "glInternalFormat": "GL_DEPTH24_STENCIL8_OES" + }, + "ANGLE_FORMAT_D32_FLOAT_S8X24_UINT_FL10": { + "texFormat": "DXGI_FORMAT_R32G8X24_TYPELESS", + "srvFormat": "DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS", + "dsvFormat": "DXGI_FORMAT_D32_FLOAT_S8X24_UINT", + "channels": "ds", + "bits": { "depth": 32, "stencil": 8 }, + "glInternalFormat": "GL_DEPTH32F_STENCIL8" + }, + "ANGLE_FORMAT_D16_UNORM_FL10": { + "texFormat": "DXGI_FORMAT_R16_TYPELESS", + "srvFormat": "DXGI_FORMAT_R16_UNORM", + "dsvFormat": "DXGI_FORMAT_D16_UNORM", + "channels": "d", + "componentType": "unorm", + "bits": { "depth": 16 }, + "glInternalFormat": "GL_DEPTH_COMPONENT16" + }, + "ANGLE_FORMAT_D16_UNORM_FL9_3": { + "texFormat": "DXGI_FORMAT_D16_UNORM", + "dsvFormat": "DXGI_FORMAT_D16_UNORM", + "channels": "d", + "componentType": "unorm", + "bits": { "depth": 16 }, + "glInternalFormat": "GL_DEPTH_COMPONENT16" + }, + "ANGLE_FORMAT_D32_FLOAT": { + "texFormat": "DXGI_FORMAT_R32_TYPELESS", + "srvFormat": "DXGI_FORMAT_R32_FLOAT", + "dsvFormat": "DXGI_FORMAT_D32_FLOAT", + "channels": "d", + "componentType": "float", + "bits": { "depth": 32 }, + "glInternalFormat": "GL_DEPTH_COMPONENT32F" + }, + "ANGLE_FORMAT_R11G11B10_FLOAT": { + "texFormat": "DXGI_FORMAT_R11G11B10_FLOAT", + "srvFormat": "DXGI_FORMAT_R11G11B10_FLOAT", + "rtvFormat": "DXGI_FORMAT_R11G11B10_FLOAT", + "channels": "rgb", + "componentType": "float", + "bits": { "red": 11, "green": 11, "blue": 10 }, + "glInternalFormat": "GL_R11F_G11F_B10F" + }, + "ANGLE_FORMAT_R16_FLOAT": { + "texFormat": "DXGI_FORMAT_R16_FLOAT", + "srvFormat": "DXGI_FORMAT_R16_FLOAT", + "rtvFormat": "DXGI_FORMAT_R16_FLOAT", + "channels": "r", + "componentType": "float", + "bits": { "red": 16 }, + "glInternalFormat": "GL_R16F" + }, + "ANGLE_FORMAT_R16_SINT": { + "texFormat": "DXGI_FORMAT_R16_SINT", + "srvFormat": "DXGI_FORMAT_R16_SINT", + "rtvFormat": "DXGI_FORMAT_R16_SINT", + "channels": "r", + "componentType": "int", + "bits": { "red": 16 }, + "glInternalFormat": "GL_R16I" + }, + "ANGLE_FORMAT_R16_UINT": { + "texFormat": "DXGI_FORMAT_R16_UINT", + "srvFormat": "DXGI_FORMAT_R16_UINT", + "rtvFormat": "DXGI_FORMAT_R16_UINT", + "channels": "r", + "componentType": "uint", + "bits": { "red": 16 }, + "glInternalFormat": "GL_R16UI" + }, + "ANGLE_FORMAT_R32_FLOAT": { + "texFormat": "DXGI_FORMAT_R32_FLOAT", + "srvFormat": "DXGI_FORMAT_R32_FLOAT", + "rtvFormat": "DXGI_FORMAT_R32_FLOAT", + "channels": "r", + "componentType": "float", + "bits": { "red": 32 }, + "glInternalFormat": "GL_R32F" + }, + "ANGLE_FORMAT_R32_SINT": { + "texFormat": "DXGI_FORMAT_R32_SINT", + "srvFormat": "DXGI_FORMAT_R32_SINT", + "rtvFormat": "DXGI_FORMAT_R32_SINT", + "channels": "r", + "componentType": "int", + "bits": { "red": 32 }, + "glInternalFormat": "GL_R32I" + }, + "ANGLE_FORMAT_R32_UINT": { + "texFormat": "DXGI_FORMAT_R32_UINT", + "srvFormat": "DXGI_FORMAT_R32_UINT", + "rtvFormat": "DXGI_FORMAT_R32_UINT", + "channels": "r", + "componentType": "uint", + "bits": { "red": 32 }, + "glInternalFormat": "GL_R32UI" + }, + "ANGLE_FORMAT_R8_UNORM_NONRENDERABLE": { + "texFormat": "DXGI_FORMAT_R8_UNORM", + "srvFormat": "DXGI_FORMAT_R8_UNORM", + "channels": "r", + "componentType": "unorm", + "bits": { "red": 8 }, + "glInternalFormat": "GL_R8" + }, + "ANGLE_FORMAT_R8_UNORM": { + "texFormat": "DXGI_FORMAT_R8_UNORM", + "srvFormat": "DXGI_FORMAT_R8_UNORM", + "rtvFormat": "DXGI_FORMAT_R8_UNORM", + "channels": "r", + "componentType": "unorm", + "bits": { "red": 8 }, + "glInternalFormat": "GL_R8" + }, + "ANGLE_FORMAT_R8_SINT": { + "texFormat": "DXGI_FORMAT_R8_SINT", + "srvFormat": "DXGI_FORMAT_R8_SINT", + "rtvFormat": "DXGI_FORMAT_R8_SINT", + "channels": "r", + "componentType": "int", + "bits": { "red": 8 }, + "glInternalFormat": "GL_R8I" + }, + "ANGLE_FORMAT_R8_UINT": { + "texFormat": "DXGI_FORMAT_R8_UINT", + "srvFormat": "DXGI_FORMAT_R8_UINT", + "rtvFormat": "DXGI_FORMAT_R8_UINT", + "channels": "r", + "componentType": "uint", + "bits": { "red": 8 }, + "glInternalFormat": "GL_R8UI" + }, + "ANGLE_FORMAT_R8_SNORM": { + "texFormat": "DXGI_FORMAT_R8_SNORM", + "srvFormat": "DXGI_FORMAT_R8_SNORM", + "channels": "r", + "componentType": "snorm", + "bits": { "red": 8 }, + "glInternalFormat": "GL_R8_SNORM" + }, + "ANGLE_FORMAT_R16G16_FLOAT": { + "texFormat": "DXGI_FORMAT_R16G16_FLOAT", + "srvFormat": "DXGI_FORMAT_R16G16_FLOAT", + "rtvFormat": "DXGI_FORMAT_R16G16_FLOAT", + "channels": "rg", + "componentType": "float", + "bits": { "red": 16, "green": 16 }, + "glInternalFormat": "GL_RG16F" + }, + "ANGLE_FORMAT_R16G16_SINT": { + "texFormat": "DXGI_FORMAT_R16G16_SINT", + "srvFormat": "DXGI_FORMAT_R16G16_SINT", + "rtvFormat": "DXGI_FORMAT_R16G16_SINT", + "channels": "rg", + "componentType": "int", + "bits": { "red": 16, "green": 16 }, + "glInternalFormat": "GL_RG16I" + }, + "ANGLE_FORMAT_R16G16_UINT": { + "texFormat": "DXGI_FORMAT_R16G16_UINT", + "srvFormat": "DXGI_FORMAT_R16G16_UINT", + "rtvFormat": "DXGI_FORMAT_R16G16_UINT", + "channels": "rg", + "componentType": "uint", + "bits": { "red": 16, "green": 16 }, + "glInternalFormat": "GL_RG16UI" + }, + "ANGLE_FORMAT_R32G32_FLOAT": { + "texFormat": "DXGI_FORMAT_R32G32_FLOAT", + "srvFormat": "DXGI_FORMAT_R32G32_FLOAT", + "rtvFormat": "DXGI_FORMAT_R32G32_FLOAT", + "channels": "rg", + "componentType": "float", + "bits": { "red": 32, "green": 32 }, + "glInternalFormat": "GL_RG32F" + }, + "ANGLE_FORMAT_R32G32_SINT": { + "texFormat": "DXGI_FORMAT_R32G32_SINT", + "srvFormat": "DXGI_FORMAT_R32G32_SINT", + "rtvFormat": "DXGI_FORMAT_R32G32_SINT", + "channels": "rg", + "componentType": "int", + "bits": { "red": 32, "green": 32 }, + "glInternalFormat": "GL_RG32I" + }, + "ANGLE_FORMAT_R32G32_UINT": { + "texFormat": "DXGI_FORMAT_R32G32_UINT", + "srvFormat": "DXGI_FORMAT_R32G32_UINT", + "rtvFormat": "DXGI_FORMAT_R32G32_UINT", + "channels": "rg", + "componentType": "uint", + "bits": { "red": 32, "green": 32 }, + "glInternalFormat": "GL_RG32UI" + }, + "ANGLE_FORMAT_R8G8_UNORM": { + "texFormat": "DXGI_FORMAT_R8G8_UNORM", + "srvFormat": "DXGI_FORMAT_R8G8_UNORM", + "rtvFormat": "DXGI_FORMAT_R8G8_UNORM", + "channels": "rg", + "componentType": "unorm", + "bits": { "red": 8, "green": 8 }, + "glInternalFormat": "GL_RG8" + }, + "ANGLE_FORMAT_R8G8_UNORM_NONRENDERABLE": { + "texFormat": "DXGI_FORMAT_R8G8_UNORM", + "srvFormat": "DXGI_FORMAT_R8G8_UNORM", + "channels": "rg", + "componentType": "unorm", + "bits": { "red": 8, "green": 8 }, + "glInternalFormat": "GL_RG8" + }, + "ANGLE_FORMAT_R8G8_SINT": { + "texFormat": "DXGI_FORMAT_R8G8_SINT", + "srvFormat": "DXGI_FORMAT_R8G8_SINT", + "rtvFormat": "DXGI_FORMAT_R8G8_SINT", + "channels": "rg", + "componentType": "int", + "bits": { "red": 8, "green": 8 }, + "glInternalFormat": "GL_RG8I" + }, + "ANGLE_FORMAT_R8G8_UINT": { + "texFormat": "DXGI_FORMAT_R8G8_UINT", + "srvFormat": "DXGI_FORMAT_R8G8_UINT", + "rtvFormat": "DXGI_FORMAT_R8G8_UINT", + "channels": "rg", + "componentType": "uint", + "bits": { "red": 8, "green": 8 }, + "glInternalFormat": "GL_RG8UI" + }, + "ANGLE_FORMAT_R8G8_SNORM": { + "texFormat": "DXGI_FORMAT_R8G8_SNORM", + "srvFormat": "DXGI_FORMAT_R8G8_SNORM", + "channels": "rg", + "componentType": "snorm", + "bits": { "red": 8, "green": 8 }, + "glInternalFormat": "GL_RG8_SNORM" + }, + "ANGLE_FORMAT_R10G10B10A2_UNORM": { + "texFormat": "DXGI_FORMAT_R10G10B10A2_UNORM", + "srvFormat": "DXGI_FORMAT_R10G10B10A2_UNORM", + "rtvFormat": "DXGI_FORMAT_R10G10B10A2_UNORM", + "channels": "rgba", + "componentType": "unorm", + "bits": { "red": 10, "green": 10, "blue": 10, "alpha": 2 }, + "glInternalFormat": "GL_RGB10_A2" + }, + "ANGLE_FORMAT_R10G10B10A2_UINT": { + "texFormat": "DXGI_FORMAT_R10G10B10A2_UINT", + "srvFormat": "DXGI_FORMAT_R10G10B10A2_UINT", + "rtvFormat": "DXGI_FORMAT_R10G10B10A2_UINT", + "channels": "rgba", + "componentType": "uint", + "bits": { "red": 10, "green": 10, "blue": 10, "alpha": 2 }, + "glInternalFormat": "GL_RGB10_A2UI" + }, + "ANGLE_FORMAT_R16G16B16A16_SINT": { + "texFormat": "DXGI_FORMAT_R16G16B16A16_SINT", + "srvFormat": "DXGI_FORMAT_R16G16B16A16_SINT", + "rtvFormat": "DXGI_FORMAT_R16G16B16A16_SINT", + "channels": "rgba", + "componentType": "int", + "bits": { "red": 16, "green": 16, "blue": 16, "alpha": 16 }, + "glInternalFormat": "GL_RGBA16I" + }, + "ANGLE_FORMAT_R16G16B16A16_UINT": { + "texFormat": "DXGI_FORMAT_R16G16B16A16_UINT", + "srvFormat": "DXGI_FORMAT_R16G16B16A16_UINT", + "rtvFormat": "DXGI_FORMAT_R16G16B16A16_UINT", + "channels": "rgba", + "componentType": "uint", + "bits": { "red": 16, "green": 16, "blue": 16, "alpha": 16 }, + "glInternalFormat": "GL_RGBA16UI" + }, + "ANGLE_FORMAT_R32G32B32A32_SINT": { + "texFormat": "DXGI_FORMAT_R32G32B32A32_SINT", + "srvFormat": "DXGI_FORMAT_R32G32B32A32_SINT", + "rtvFormat": "DXGI_FORMAT_R32G32B32A32_SINT", + "channels": "rgba", + "componentType": "int", + "bits": { "red": 32, "green": 32, "blue": 32, "alpha": 32 }, + "glInternalFormat": "GL_RGBA32I" + }, + "ANGLE_FORMAT_R32G32B32A32_UINT": { + "texFormat": "DXGI_FORMAT_R32G32B32A32_UINT", + "srvFormat": "DXGI_FORMAT_R32G32B32A32_UINT", + "rtvFormat": "DXGI_FORMAT_R32G32B32A32_UINT", + "channels": "rgba", + "componentType": "uint", + "bits": { "red": 32, "green": 32, "blue": 32, "alpha": 32 }, + "glInternalFormat": "GL_RGBA32UI" + }, + "ANGLE_FORMAT_B5G6R5_UNORM": { + "texFormat": "DXGI_FORMAT_B5G6R5_UNORM", + "srvFormat": "DXGI_FORMAT_B5G6R5_UNORM", + "rtvFormat": "DXGI_FORMAT_B5G6R5_UNORM", + "channels": "bgr", + "componentType": "unorm", + "bits": { "red": 5, "green": 6, "blue": 5 }, + "glInternalFormat": "GL_RGB565", + "channelStruct": "R5G6B5" + }, + "ANGLE_FORMAT_B5G5R5A1_UNORM": { + "texFormat": "DXGI_FORMAT_B5G5R5A1_UNORM", + "srvFormat": "DXGI_FORMAT_B5G5R5A1_UNORM", + "rtvFormat": "DXGI_FORMAT_B5G5R5A1_UNORM", + "channels": "bgra", + "componentType": "unorm", + "bits": { "red": 5, "green": 5, "blue": 5, "alpha": 1 }, + "glInternalFormat": "GL_RGB5_A1", + "channelStruct": "A1R5G5B5" + }, + "ANGLE_FORMAT_R8G8B8A8_SINT": { + "texFormat": "DXGI_FORMAT_R8G8B8A8_SINT", + "srvFormat": "DXGI_FORMAT_R8G8B8A8_SINT", + "rtvFormat": "DXGI_FORMAT_R8G8B8A8_SINT", + "channels": "rgba", + "componentType": "int", + "bits": { "red": 8, "green": 8, "blue": 8, "alpha": 8 }, + "glInternalFormat": "GL_RGBA8I" + }, + "ANGLE_FORMAT_R8G8B8A8_UINT": { + "texFormat": "DXGI_FORMAT_R8G8B8A8_UINT", + "srvFormat": "DXGI_FORMAT_R8G8B8A8_UINT", + "rtvFormat": "DXGI_FORMAT_R8G8B8A8_UINT", + "channels": "rgba", + "componentType": "uint", + "bits": { "red": 8, "green": 8, "blue": 8, "alpha": 8 }, + "glInternalFormat": "GL_RGBA8UI" + }, + "ANGLE_FORMAT_R8G8B8A8_SNORM": { + "texFormat": "DXGI_FORMAT_R8G8B8A8_SNORM", + "srvFormat": "DXGI_FORMAT_R8G8B8A8_SNORM", + "channels": "rgba", + "componentType": "snorm", + "bits": { "red": 8, "green": 8, "blue": 8, "alpha": 8 }, + "glInternalFormat": "GL_RGBA8_SNORM" + }, + "ANGLE_FORMAT_R9G9B9E5_SHAREDEXP": { + "texFormat": "DXGI_FORMAT_R9G9B9E5_SHAREDEXP", + "srvFormat": "DXGI_FORMAT_R9G9B9E5_SHAREDEXP", + "channels": "rgb", + "componentType": "float", + "bits": { "red": 9, "green": 9, "blue": 9, "shared": 5 }, + "glInternalFormat": "GL_RGB9_E5", + "channelStruct": "R9G9B9E5" + }, + "ANGLE_FORMAT_B4G4R4A4_UNORM": { + "texFormat": "DXGI_FORMAT_B4G4R4A4_UNORM", + "srvFormat": "DXGI_FORMAT_B4G4R4A4_UNORM", + "rtvFormat": "DXGI_FORMAT_B4G4R4A4_UNORM", + "channels": "bgra", + "componentType": "unorm", + "bits": { "red": 4, "green": 4, "blue": 4, "alpha": 4 }, + "glInternalFormat": "GL_RGBA4", + "channelStruct": "A4R4G4B4" + }, + "ANGLE_FORMAT_R8G8B8A8_UNORM_SRGB": { + "texFormat": "DXGI_FORMAT_R8G8B8A8_UNORM_SRGB", + "srvFormat": "DXGI_FORMAT_R8G8B8A8_UNORM_SRGB", + "rtvFormat": "DXGI_FORMAT_R8G8B8A8_UNORM_SRGB", + "channels": "rgba", + "componentType": "unorm", + "bits": { "red": 8, "green": 8, "blue": 8, "alpha": 8 }, + "glInternalFormat": "GL_SRGB8_ALPHA8" + }, + "ANGLE_FORMAT_X24_TYPELESS_G8_UINT": { + "texFormat": "DXGI_FORMAT_R24G8_TYPELESS", + "srvFormat": "DXGI_FORMAT_X24_TYPELESS_G8_UINT", + "dsvFormat": "DXGI_FORMAT_D24_UNORM_S8_UINT", + "channels": "ds", + "bits": { "depth": 24, "stencil": 8 }, + "glInternalFormat": "GL_DEPTH24_STENCIL8_OES" + } +} diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/texture_format_map.json b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/texture_format_map.json new file mode 100644 index 000000000000..2c579b46fa71 --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/texture_format_map.json @@ -0,0 +1,148 @@ +{ + "GL_ALPHA": { + "OnlyFL10Plus": "ANGLE_FORMAT_A8_UNORM", + "OnlyFL9_3": "ANGLE_FORMAT_R8G8B8A8_UNORM" + }, + "GL_ALPHA16F_EXT": "ANGLE_FORMAT_R16G16B16A16_FLOAT", + "GL_ALPHA32F_EXT": "ANGLE_FORMAT_R32G32B32A32_FLOAT", + "GL_ALPHA8_EXT": { + "OnlyFL10Plus": "ANGLE_FORMAT_A8_UNORM", + "OnlyFL9_3": "ANGLE_FORMAT_R8G8B8A8_UNORM" + }, + "GL_BGR5_A1_ANGLEX": "ANGLE_FORMAT_B8G8R8A8_UNORM", + "GL_BGRA4_ANGLEX": "ANGLE_FORMAT_B8G8R8A8_UNORM", + "GL_BGRA8_EXT": "ANGLE_FORMAT_B8G8R8A8_UNORM", + "GL_BGRA_EXT": "ANGLE_FORMAT_B8G8R8A8_UNORM", + "GL_COMPRESSED_R11_EAC": { + "OnlyFL10Plus": "ANGLE_FORMAT_R8_UNORM_NONRENDERABLE" + }, + "GL_COMPRESSED_RG11_EAC": { + "OnlyFL10Plus": "ANGLE_FORMAT_R8G8_UNORM_NONRENDERABLE" + }, + "GL_COMPRESSED_RGB8_ETC2": { + "OnlyFL10Plus": "ANGLE_FORMAT_R8G8B8A8_UNORM_NONRENDERABLE" + }, + "GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2": { + "OnlyFL10Plus": "ANGLE_FORMAT_R8G8B8A8_UNORM_NONRENDERABLE" + }, + "GL_COMPRESSED_RGBA8_ETC2_EAC": { + "OnlyFL10Plus": "ANGLE_FORMAT_R8G8B8A8_UNORM_NONRENDERABLE" + }, + "GL_COMPRESSED_RGBA_S3TC_DXT1_EXT": "ANGLE_FORMAT_BC1_UNORM", + "GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE": "ANGLE_FORMAT_BC2_UNORM", + "GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE": "ANGLE_FORMAT_BC3_UNORM", + "GL_COMPRESSED_RGB_S3TC_DXT1_EXT": "ANGLE_FORMAT_BC1_UNORM", + "GL_COMPRESSED_SIGNED_R11_EAC": { + "OnlyFL10Plus": "ANGLE_FORMAT_R8_SNORM_NONRENDERABLE" + }, + "GL_COMPRESSED_SIGNED_RG11_EAC": { + "OnlyFL10Plus": "ANGLE_FORMAT_R8G8_SNORM_NONRENDERABLE" + }, + "GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC": { + "OnlyFL10Plus": "ANGLE_FORMAT_R8G8B8A8_UNORM_SRGB_NONRENDERABLE" + }, + "GL_COMPRESSED_SRGB8_ETC2": { + "OnlyFL10Plus": "ANGLE_FORMAT_R8G8B8A8_UNORM_SRGB_NONRENDERABLE" + }, + "GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2": { + "OnlyFL10Plus": "ANGLE_FORMAT_R8G8B8A8_UNORM_SRGB_NONRENDERABLE" + }, + "GL_DEPTH24_STENCIL8": { + "OnlyFL10Plus": "ANGLE_FORMAT_D24_UNORM_S8_UINT_FL10", + "OnlyFL9_3": "ANGLE_FORMAT_D24_UNORM_S8_UINT_FL9_3" + }, + "GL_DEPTH32F_STENCIL8": { + "OnlyFL10Plus": "ANGLE_FORMAT_D32_FLOAT_S8X24_UINT_FL10", + "OnlyFL9_3": "ANGLE_FORMAT_NONE" + }, + "GL_DEPTH_COMPONENT16": { + "OnlyFL10Plus": "ANGLE_FORMAT_D16_UNORM_FL10", + "OnlyFL9_3": "ANGLE_FORMAT_D16_UNORM_FL9_3" + }, + "GL_DEPTH_COMPONENT24": { + "OnlyFL10Plus": "ANGLE_FORMAT_D24_UNORM_S8_UINT_FL10", + "OnlyFL9_3": "ANGLE_FORMAT_D24_UNORM_S8_UINT_FL9_3" + }, + "GL_DEPTH_COMPONENT32F": { + "OnlyFL10Plus": "ANGLE_FORMAT_D32_FLOAT", + "OnlyFL9_3": "ANGLE_FORMAT_NONE" + }, + "GL_DEPTH_COMPONENT32_OES": { + "OnlyFL10Plus": "ANGLE_FORMAT_D24_UNORM_S8_UINT_FL10" + }, + "GL_ETC1_RGB8_OES": "ANGLE_FORMAT_R8G8B8A8_UNORM_NONRENDERABLE", + "GL_ETC1_RGB8_LOSSY_DECODE_ANGLE": "ANGLE_FORMAT_BC1_UNORM", + "GL_LUMINANCE": "ANGLE_FORMAT_R8G8B8A8_UNORM", + "GL_LUMINANCE16F_EXT": "ANGLE_FORMAT_R16G16B16A16_FLOAT", + "GL_LUMINANCE32F_EXT": "ANGLE_FORMAT_R32G32B32A32_FLOAT", + "GL_LUMINANCE8_ALPHA8_EXT": "ANGLE_FORMAT_R8G8B8A8_UNORM", + "GL_LUMINANCE8_EXT": "ANGLE_FORMAT_R8G8B8A8_UNORM", + "GL_LUMINANCE_ALPHA": "ANGLE_FORMAT_R8G8B8A8_UNORM", + "GL_LUMINANCE_ALPHA16F_EXT": "ANGLE_FORMAT_R16G16B16A16_FLOAT", + "GL_LUMINANCE_ALPHA32F_EXT": "ANGLE_FORMAT_R32G32B32A32_FLOAT", + "GL_NONE": "ANGLE_FORMAT_NONE", + "GL_R11F_G11F_B10F": "ANGLE_FORMAT_R11G11B10_FLOAT", + "GL_R16F": "ANGLE_FORMAT_R16_FLOAT", + "GL_R16I": "ANGLE_FORMAT_R16_SINT", + "GL_R16UI": "ANGLE_FORMAT_R16_UINT", + "GL_R32F": "ANGLE_FORMAT_R32_FLOAT", + "GL_R32I": "ANGLE_FORMAT_R32_SINT", + "GL_R32UI": "ANGLE_FORMAT_R32_UINT", + "GL_R8": "ANGLE_FORMAT_R8_UNORM", + "GL_R8I": "ANGLE_FORMAT_R8_SINT", + "GL_R8UI": "ANGLE_FORMAT_R8_UINT", + "GL_R8_SNORM": "ANGLE_FORMAT_R8_SNORM", + "GL_RG16F": "ANGLE_FORMAT_R16G16_FLOAT", + "GL_RG16I": "ANGLE_FORMAT_R16G16_SINT", + "GL_RG16UI": "ANGLE_FORMAT_R16G16_UINT", + "GL_RG32F": "ANGLE_FORMAT_R32G32_FLOAT", + "GL_RG32I": "ANGLE_FORMAT_R32G32_SINT", + "GL_RG32UI": "ANGLE_FORMAT_R32G32_UINT", + "GL_RG8": "ANGLE_FORMAT_R8G8_UNORM", + "GL_RG8I": "ANGLE_FORMAT_R8G8_SINT", + "GL_RG8UI": "ANGLE_FORMAT_R8G8_UINT", + "GL_RG8_SNORM": "ANGLE_FORMAT_R8G8_SNORM", + "GL_RGB": "ANGLE_FORMAT_R8G8B8A8_UNORM", + "GL_RGB10_A2": "ANGLE_FORMAT_R10G10B10A2_UNORM", + "GL_RGB10_A2UI": "ANGLE_FORMAT_R10G10B10A2_UINT", + "GL_RGB16F": "ANGLE_FORMAT_R16G16B16A16_FLOAT", + "GL_RGB16I": "ANGLE_FORMAT_R16G16B16A16_SINT", + "GL_RGB16UI": "ANGLE_FORMAT_R16G16B16A16_UINT", + "GL_RGB32F": "ANGLE_FORMAT_R32G32B32A32_FLOAT", + "GL_RGB32I": "ANGLE_FORMAT_R32G32B32A32_SINT", + "GL_RGB32UI": "ANGLE_FORMAT_R32G32B32A32_UINT", + "GL_RGB565": { + "SupportsFormat": "ANGLE_FORMAT_R8G8B8A8_UNORM", + "SupportsFormat": "ANGLE_FORMAT_B5G6R5_UNORM" + }, + "GL_RGB5_A1": { + "SupportsFormat": "ANGLE_FORMAT_R8G8B8A8_UNORM", + "SupportsFormat": "ANGLE_FORMAT_B5G5R5A1_UNORM" + }, + "GL_RGB8": "ANGLE_FORMAT_R8G8B8A8_UNORM", + "GL_RGB8I": "ANGLE_FORMAT_R8G8B8A8_SINT", + "GL_RGB8UI": "ANGLE_FORMAT_R8G8B8A8_UINT", + "GL_RGB8_SNORM": "ANGLE_FORMAT_R8G8B8A8_SNORM", + "GL_RGB9_E5": "ANGLE_FORMAT_R9G9B9E5_SHAREDEXP", + "GL_RGBA": "ANGLE_FORMAT_R8G8B8A8_UNORM", + "GL_RGBA16F": "ANGLE_FORMAT_R16G16B16A16_FLOAT", + "GL_RGBA16I": "ANGLE_FORMAT_R16G16B16A16_SINT", + "GL_RGBA16UI": "ANGLE_FORMAT_R16G16B16A16_UINT", + "GL_RGBA32F": "ANGLE_FORMAT_R32G32B32A32_FLOAT", + "GL_RGBA32I": "ANGLE_FORMAT_R32G32B32A32_SINT", + "GL_RGBA32UI": "ANGLE_FORMAT_R32G32B32A32_UINT", + "GL_RGBA4": { + "SupportsFormat": "ANGLE_FORMAT_R8G8B8A8_UNORM", + "SupportsFormat": "ANGLE_FORMAT_B4G4R4A4_UNORM" + }, + "GL_RGBA8": "ANGLE_FORMAT_R8G8B8A8_UNORM", + "GL_RGBA8I": "ANGLE_FORMAT_R8G8B8A8_SINT", + "GL_RGBA8UI": "ANGLE_FORMAT_R8G8B8A8_UINT", + "GL_RGBA8_SNORM": "ANGLE_FORMAT_R8G8B8A8_SNORM", + "GL_SRGB8": "ANGLE_FORMAT_R8G8B8A8_UNORM_SRGB_NONRENDERABLE", + "GL_SRGB8_ALPHA8": "ANGLE_FORMAT_R8G8B8A8_UNORM_SRGB", + "GL_STENCIL_INDEX8": { + "OnlyFL10Plus": "ANGLE_FORMAT_X24_TYPELESS_G8_UINT", + "OnlyFL9_3": "ANGLE_FORMAT_D24_UNORM_S8_UINT_FL9_3" + } +} diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/texture_format_table.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/texture_format_table.h new file mode 100644 index 000000000000..813853e417d2 --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/texture_format_table.h @@ -0,0 +1,99 @@ +// +// 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/d3d/formatutilsD3D.h" +#include "libANGLE/renderer/d3d/d3d11/texture_format_table_autogen.h" + +namespace rx +{ + +struct Renderer11DeviceCaps; + +namespace d3d11 +{ + +struct LoadImageFunctionInfo +{ + LoadImageFunctionInfo() : loadFunction(nullptr), requiresConversion(false) {} + LoadImageFunctionInfo(LoadImageFunction loadFunction, bool requiresConversion) + : loadFunction(loadFunction), requiresConversion(requiresConversion) + { + } + + LoadImageFunction loadFunction; + bool requiresConversion; +}; + +struct ANGLEFormatSet +{ + ANGLEFormatSet(); + ANGLEFormatSet(ANGLEFormat format, + GLenum glInternalFormat, + DXGI_FORMAT texFormat, + DXGI_FORMAT srvFormat, + DXGI_FORMAT rtvFormat, + DXGI_FORMAT dsvFormat, + DXGI_FORMAT blitSRVFormat, + ANGLEFormat swizzleFormat, + MipGenerationFunction mipGenerationFunction, + ColorReadFunction colorReadFunction); + ANGLEFormatSet(const ANGLEFormatSet &) = default; + ANGLEFormatSet &operator=(const ANGLEFormatSet &) = default; + + ANGLEFormat format; + + // The closest matching GL internal format for the DXGI formats this format uses. Note that this + // may be a different internal format than the one this ANGLE format is used for. + GLenum glInternalFormat; + + DXGI_FORMAT texFormat; + DXGI_FORMAT srvFormat; + DXGI_FORMAT rtvFormat; + DXGI_FORMAT dsvFormat; + + DXGI_FORMAT blitSRVFormat; + + ANGLEFormat swizzleFormat; + + MipGenerationFunction mipGenerationFunction; + ColorReadFunction colorReadFunction; +}; + +struct TextureFormat : public angle::NonCopyable +{ + TextureFormat(GLenum internalFormat, + const ANGLEFormat angleFormat, + InitializeTextureDataFunction internalFormatInitializer); + + const ANGLEFormatSet *formatSet; + const ANGLEFormatSet *swizzleFormatSet; + + InitializeTextureDataFunction dataInitializerFunction; + typedef std::map LoadFunctionMap; + + LoadFunctionMap loadFunctions; +}; + +const ANGLEFormatSet &GetANGLEFormatSet(ANGLEFormat angleFormat); + +const TextureFormat &GetTextureFormatInfo(GLenum internalformat, + const Renderer11DeviceCaps &renderer11DeviceCaps); + +} // namespace d3d11 + +} // namespace rx + +#endif // LIBANGLE_RENDERER_D3D_D3D11_TEXTUREFORMATTABLE_H_ diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/texture_format_table_autogen.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/texture_format_table_autogen.cpp new file mode 100644 index 000000000000..02fed9f0ffe6 --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/texture_format_table_autogen.cpp @@ -0,0 +1,1871 @@ +// 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 "libANGLE/renderer/d3d/d3d11/formatutils11.h" +#include "libANGLE/renderer/d3d/d3d11/load_functions_table.h" +#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h" +#include "libANGLE/renderer/d3d/copyimage.h" +#include "libANGLE/renderer/d3d/generatemip.h" +#include "libANGLE/renderer/d3d/loadimage.h" + +namespace rx +{ + +namespace d3d11 +{ + +namespace +{ + +typedef bool (*FormatSupportFunction)(const Renderer11DeviceCaps &); + +bool OnlyFL10Plus(const Renderer11DeviceCaps &deviceCaps) +{ + return (deviceCaps.featureLevel >= D3D_FEATURE_LEVEL_10_0); +} + +bool OnlyFL9_3(const Renderer11DeviceCaps &deviceCaps) +{ + return (deviceCaps.featureLevel == D3D_FEATURE_LEVEL_9_3); +} + +template +bool SupportsFormat(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; + + if (d3d11_gl::GetMaximumClientVersion(deviceCaps.featureLevel) > 2) + { + mustSupport |= D3D11_FORMAT_SUPPORT_TEXTURE3D; + } + + 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); + } + else if (format == DXGI_FORMAT_B4G4R4A4_UNORM) + { + fullSupport = ((deviceCaps.B4G4R4A4support & mustSupport) == mustSupport); + } + else if (format == DXGI_FORMAT_B5G5R5A1_UNORM) + { + fullSupport = ((deviceCaps.B5G5R5A1support & mustSupport) == mustSupport); + } + else + { + UNREACHABLE(); + return false; + } + + // This 'SupportsFormat' function is used by individual entries in the D3D11 Format Map below, + // which maps GL formats to DXGI formats. + if (requireSupport) + { + // 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; + } + else + { + // This means that ANGLE would like to use the entry in the map if the inputted DXGI format + // *ISN'T* supported. + // This might be a fallback entry. e.g. for ANGLE to use DXGI_FORMAT_R8G8B8A8_UNORM if + // DXGI_FORMAT_B5G5R5A1 isn't supported. + // In this case, we should only return 'true' if the format *ISN'T* supported. + return !fullSupport; + } +} + +// End Format Support Functions +} // namespace + +ANGLEFormatSet::ANGLEFormatSet() + : format(ANGLE_FORMAT_NONE), + glInternalFormat(GL_NONE), + texFormat(DXGI_FORMAT_UNKNOWN), + srvFormat(DXGI_FORMAT_UNKNOWN), + rtvFormat(DXGI_FORMAT_UNKNOWN), + dsvFormat(DXGI_FORMAT_UNKNOWN), + blitSRVFormat(DXGI_FORMAT_UNKNOWN), + swizzleFormat(ANGLE_FORMAT_NONE), + mipGenerationFunction(nullptr), + colorReadFunction(nullptr) +{ +} + +// For sized GL internal formats, there are several possible corresponding D3D11 formats depending +// on device capabilities. +// This function allows querying for the DXGI texture formats to use for textures, SRVs, RTVs and +// DSVs given a GL internal format. +TextureFormat::TextureFormat(GLenum internalFormat, + const ANGLEFormat angleFormat, + InitializeTextureDataFunction internalFormatInitializer) + : dataInitializerFunction(internalFormatInitializer) +{ + formatSet = &GetANGLEFormatSet(angleFormat); + swizzleFormatSet = &GetANGLEFormatSet(formatSet->swizzleFormat); + + // Gather all the load functions for this internal format + loadFunctions = GetLoadFunctionsMap(internalFormat, formatSet->texFormat); + + ASSERT(loadFunctions.size() != 0 || internalFormat == GL_NONE); +} + +ANGLEFormatSet::ANGLEFormatSet(ANGLEFormat format, + GLenum glInternalFormat, + DXGI_FORMAT texFormat, + DXGI_FORMAT srvFormat, + DXGI_FORMAT rtvFormat, + DXGI_FORMAT dsvFormat, + DXGI_FORMAT blitSRVFormat, + ANGLEFormat swizzleFormat, + MipGenerationFunction mipGenerationFunction, + ColorReadFunction colorReadFunction) + : format(format), + glInternalFormat(glInternalFormat), + texFormat(texFormat), + srvFormat(srvFormat), + rtvFormat(rtvFormat), + dsvFormat(dsvFormat), + blitSRVFormat(blitSRVFormat), + swizzleFormat(swizzleFormat), + mipGenerationFunction(mipGenerationFunction), + colorReadFunction(colorReadFunction) +{ +} + +const ANGLEFormatSet &GetANGLEFormatSet(ANGLEFormat angleFormat) +{ + // clang-format off + switch (angleFormat) + { + case ANGLE_FORMAT_A8_UNORM: + { + static const ANGLEFormatSet formatInfo(ANGLE_FORMAT_A8_UNORM, + GL_ALPHA8_EXT, + DXGI_FORMAT_A8_UNORM, + DXGI_FORMAT_A8_UNORM, + DXGI_FORMAT_A8_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_A8_UNORM, + ANGLE_FORMAT_R8G8B8A8_UNORM, + GenerateMip, + ReadColor); + return formatInfo; + } + case ANGLE_FORMAT_B4G4R4A4_UNORM: + { + static const ANGLEFormatSet formatInfo(ANGLE_FORMAT_B4G4R4A4_UNORM, + GL_RGBA4, + DXGI_FORMAT_B4G4R4A4_UNORM, + DXGI_FORMAT_B4G4R4A4_UNORM, + DXGI_FORMAT_B4G4R4A4_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_B4G4R4A4_UNORM, + ANGLE_FORMAT_B4G4R4A4_UNORM, + GenerateMip, + ReadColor); + return formatInfo; + } + case ANGLE_FORMAT_B5G5R5A1_UNORM: + { + static const ANGLEFormatSet formatInfo(ANGLE_FORMAT_B5G5R5A1_UNORM, + GL_RGB5_A1, + DXGI_FORMAT_B5G5R5A1_UNORM, + DXGI_FORMAT_B5G5R5A1_UNORM, + DXGI_FORMAT_B5G5R5A1_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_B5G5R5A1_UNORM, + ANGLE_FORMAT_R8G8B8A8_UNORM, + GenerateMip, + ReadColor); + return formatInfo; + } + case ANGLE_FORMAT_B5G6R5_UNORM: + { + static const ANGLEFormatSet formatInfo(ANGLE_FORMAT_B5G6R5_UNORM, + GL_RGB565, + DXGI_FORMAT_B5G6R5_UNORM, + DXGI_FORMAT_B5G6R5_UNORM, + DXGI_FORMAT_B5G6R5_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_B5G6R5_UNORM, + ANGLE_FORMAT_R8G8B8A8_UNORM, + GenerateMip, + ReadColor); + return formatInfo; + } + case ANGLE_FORMAT_B8G8R8A8_UNORM: + { + static const ANGLEFormatSet formatInfo(ANGLE_FORMAT_B8G8R8A8_UNORM, + GL_BGRA8_EXT, + DXGI_FORMAT_B8G8R8A8_UNORM, + DXGI_FORMAT_B8G8R8A8_UNORM, + DXGI_FORMAT_B8G8R8A8_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_B8G8R8A8_UNORM, + ANGLE_FORMAT_B8G8R8A8_UNORM, + GenerateMip, + ReadColor); + return formatInfo; + } + case ANGLE_FORMAT_BC1_UNORM: + { + static const ANGLEFormatSet formatInfo(ANGLE_FORMAT_BC1_UNORM, + GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, + DXGI_FORMAT_BC1_UNORM, + DXGI_FORMAT_BC1_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_BC1_UNORM, + ANGLE_FORMAT_R8G8B8A8_UNORM, + nullptr, + nullptr); + return formatInfo; + } + case ANGLE_FORMAT_BC2_UNORM: + { + static const ANGLEFormatSet formatInfo(ANGLE_FORMAT_BC2_UNORM, + GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, + DXGI_FORMAT_BC2_UNORM, + DXGI_FORMAT_BC2_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_BC2_UNORM, + ANGLE_FORMAT_R8G8B8A8_UNORM, + nullptr, + nullptr); + return formatInfo; + } + case ANGLE_FORMAT_BC3_UNORM: + { + static const ANGLEFormatSet formatInfo(ANGLE_FORMAT_BC3_UNORM, + GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, + DXGI_FORMAT_BC3_UNORM, + DXGI_FORMAT_BC3_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_BC3_UNORM, + ANGLE_FORMAT_R8G8B8A8_UNORM, + nullptr, + nullptr); + return formatInfo; + } + case ANGLE_FORMAT_D16_UNORM_FL10: + { + static const ANGLEFormatSet formatInfo(ANGLE_FORMAT_D16_UNORM_FL10, + GL_DEPTH_COMPONENT16, + DXGI_FORMAT_R16_TYPELESS, + DXGI_FORMAT_R16_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_D16_UNORM, + DXGI_FORMAT_R16_UNORM, + ANGLE_FORMAT_R16G16B16A16_UNORM, + nullptr, + nullptr); + return formatInfo; + } + case ANGLE_FORMAT_D16_UNORM_FL9_3: + { + static const ANGLEFormatSet formatInfo(ANGLE_FORMAT_D16_UNORM_FL9_3, + GL_DEPTH_COMPONENT16, + DXGI_FORMAT_D16_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_D16_UNORM, + DXGI_FORMAT_UNKNOWN, + ANGLE_FORMAT_R16G16B16A16_UNORM, + nullptr, + nullptr); + return formatInfo; + } + case ANGLE_FORMAT_D24_UNORM_S8_UINT_FL10: + { + static const ANGLEFormatSet formatInfo(ANGLE_FORMAT_D24_UNORM_S8_UINT_FL10, + GL_DEPTH24_STENCIL8_OES, + DXGI_FORMAT_R24G8_TYPELESS, + DXGI_FORMAT_R24_UNORM_X8_TYPELESS, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_D24_UNORM_S8_UINT, + DXGI_FORMAT_R24_UNORM_X8_TYPELESS, + ANGLE_FORMAT_R32G32B32A32_FLOAT, + nullptr, + nullptr); + return formatInfo; + } + case ANGLE_FORMAT_D24_UNORM_S8_UINT_FL9_3: + { + static const ANGLEFormatSet formatInfo(ANGLE_FORMAT_D24_UNORM_S8_UINT_FL9_3, + GL_DEPTH24_STENCIL8_OES, + DXGI_FORMAT_D24_UNORM_S8_UINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_D24_UNORM_S8_UINT, + DXGI_FORMAT_UNKNOWN, + ANGLE_FORMAT_R32G32B32A32_FLOAT, + nullptr, + nullptr); + return formatInfo; + } + case ANGLE_FORMAT_D32_FLOAT: + { + static const ANGLEFormatSet formatInfo(ANGLE_FORMAT_D32_FLOAT, + GL_DEPTH_COMPONENT32F, + DXGI_FORMAT_R32_TYPELESS, + DXGI_FORMAT_R32_FLOAT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_D32_FLOAT, + DXGI_FORMAT_R32_FLOAT, + ANGLE_FORMAT_R32G32B32A32_FLOAT, + nullptr, + nullptr); + return formatInfo; + } + case ANGLE_FORMAT_D32_FLOAT_S8X24_UINT_FL10: + { + static const ANGLEFormatSet formatInfo(ANGLE_FORMAT_D32_FLOAT_S8X24_UINT_FL10, + GL_DEPTH32F_STENCIL8, + DXGI_FORMAT_R32G8X24_TYPELESS, + DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_D32_FLOAT_S8X24_UINT, + DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS, + ANGLE_FORMAT_R32G32B32A32_FLOAT, + nullptr, + nullptr); + return formatInfo; + } + case ANGLE_FORMAT_NONE: + { + static const ANGLEFormatSet formatInfo(ANGLE_FORMAT_NONE, + GL_NONE, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + ANGLE_FORMAT_NONE, + nullptr, + nullptr); + return formatInfo; + } + case ANGLE_FORMAT_R10G10B10A2_UINT: + { + static const ANGLEFormatSet formatInfo(ANGLE_FORMAT_R10G10B10A2_UINT, + GL_RGB10_A2UI, + DXGI_FORMAT_R10G10B10A2_UINT, + DXGI_FORMAT_R10G10B10A2_UINT, + DXGI_FORMAT_R10G10B10A2_UINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R10G10B10A2_UINT, + ANGLE_FORMAT_R16G16B16A16_UINT, + GenerateMip, + ReadColor); + return formatInfo; + } + case ANGLE_FORMAT_R10G10B10A2_UNORM: + { + static const ANGLEFormatSet formatInfo(ANGLE_FORMAT_R10G10B10A2_UNORM, + GL_RGB10_A2, + DXGI_FORMAT_R10G10B10A2_UNORM, + DXGI_FORMAT_R10G10B10A2_UNORM, + DXGI_FORMAT_R10G10B10A2_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R10G10B10A2_UNORM, + ANGLE_FORMAT_R16G16B16A16_UNORM, + GenerateMip, + ReadColor); + return formatInfo; + } + case ANGLE_FORMAT_R11G11B10_FLOAT: + { + static const ANGLEFormatSet formatInfo(ANGLE_FORMAT_R11G11B10_FLOAT, + GL_R11F_G11F_B10F, + DXGI_FORMAT_R11G11B10_FLOAT, + DXGI_FORMAT_R11G11B10_FLOAT, + DXGI_FORMAT_R11G11B10_FLOAT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R11G11B10_FLOAT, + ANGLE_FORMAT_R16G16B16A16_FLOAT, + GenerateMip, + ReadColor); + return formatInfo; + } + case ANGLE_FORMAT_R16G16B16A16_FLOAT: + { + static const ANGLEFormatSet formatInfo(ANGLE_FORMAT_R16G16B16A16_FLOAT, + GL_RGBA16F, + DXGI_FORMAT_R16G16B16A16_FLOAT, + DXGI_FORMAT_R16G16B16A16_FLOAT, + DXGI_FORMAT_R16G16B16A16_FLOAT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R16G16B16A16_FLOAT, + ANGLE_FORMAT_R16G16B16A16_FLOAT, + GenerateMip, + ReadColor); + return formatInfo; + } + case ANGLE_FORMAT_R16G16B16A16_SINT: + { + static const ANGLEFormatSet formatInfo(ANGLE_FORMAT_R16G16B16A16_SINT, + GL_RGBA16I, + DXGI_FORMAT_R16G16B16A16_SINT, + DXGI_FORMAT_R16G16B16A16_SINT, + DXGI_FORMAT_R16G16B16A16_SINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R16G16B16A16_SINT, + ANGLE_FORMAT_R16G16B16A16_SINT, + GenerateMip, + ReadColor); + return formatInfo; + } + case ANGLE_FORMAT_R16G16B16A16_UINT: + { + static const ANGLEFormatSet formatInfo(ANGLE_FORMAT_R16G16B16A16_UINT, + GL_RGBA16UI, + DXGI_FORMAT_R16G16B16A16_UINT, + DXGI_FORMAT_R16G16B16A16_UINT, + DXGI_FORMAT_R16G16B16A16_UINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R16G16B16A16_UINT, + ANGLE_FORMAT_R16G16B16A16_UINT, + GenerateMip, + ReadColor); + return formatInfo; + } + case ANGLE_FORMAT_R16G16B16A16_UNORM: + { + static const ANGLEFormatSet formatInfo(ANGLE_FORMAT_R16G16B16A16_UNORM, + GL_NONE, + DXGI_FORMAT_R16G16B16A16_UNORM, + DXGI_FORMAT_R16G16B16A16_UNORM, + DXGI_FORMAT_R16G16B16A16_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R16G16B16A16_UNORM, + ANGLE_FORMAT_R16G16B16A16_UNORM, + GenerateMip, + ReadColor); + return formatInfo; + } + case ANGLE_FORMAT_R16G16_FLOAT: + { + static const ANGLEFormatSet formatInfo(ANGLE_FORMAT_R16G16_FLOAT, + GL_RG16F, + DXGI_FORMAT_R16G16_FLOAT, + DXGI_FORMAT_R16G16_FLOAT, + DXGI_FORMAT_R16G16_FLOAT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R16G16_FLOAT, + ANGLE_FORMAT_R16G16B16A16_FLOAT, + GenerateMip, + ReadColor); + return formatInfo; + } + case ANGLE_FORMAT_R16G16_SINT: + { + static const ANGLEFormatSet formatInfo(ANGLE_FORMAT_R16G16_SINT, + GL_RG16I, + DXGI_FORMAT_R16G16_SINT, + DXGI_FORMAT_R16G16_SINT, + DXGI_FORMAT_R16G16_SINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R16G16_SINT, + ANGLE_FORMAT_R16G16B16A16_SINT, + GenerateMip, + ReadColor); + return formatInfo; + } + case ANGLE_FORMAT_R16G16_UINT: + { + static const ANGLEFormatSet formatInfo(ANGLE_FORMAT_R16G16_UINT, + GL_RG16UI, + DXGI_FORMAT_R16G16_UINT, + DXGI_FORMAT_R16G16_UINT, + DXGI_FORMAT_R16G16_UINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R16G16_UINT, + ANGLE_FORMAT_R16G16B16A16_UINT, + GenerateMip, + ReadColor); + return formatInfo; + } + case ANGLE_FORMAT_R16_FLOAT: + { + static const ANGLEFormatSet formatInfo(ANGLE_FORMAT_R16_FLOAT, + GL_R16F, + DXGI_FORMAT_R16_FLOAT, + DXGI_FORMAT_R16_FLOAT, + DXGI_FORMAT_R16_FLOAT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R16_FLOAT, + ANGLE_FORMAT_R16G16B16A16_FLOAT, + GenerateMip, + ReadColor); + return formatInfo; + } + case ANGLE_FORMAT_R16_SINT: + { + static const ANGLEFormatSet formatInfo(ANGLE_FORMAT_R16_SINT, + GL_R16I, + DXGI_FORMAT_R16_SINT, + DXGI_FORMAT_R16_SINT, + DXGI_FORMAT_R16_SINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R16_SINT, + ANGLE_FORMAT_R16G16B16A16_SINT, + GenerateMip, + ReadColor); + return formatInfo; + } + case ANGLE_FORMAT_R16_UINT: + { + static const ANGLEFormatSet formatInfo(ANGLE_FORMAT_R16_UINT, + GL_R16UI, + DXGI_FORMAT_R16_UINT, + DXGI_FORMAT_R16_UINT, + DXGI_FORMAT_R16_UINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R16_UINT, + ANGLE_FORMAT_R16G16B16A16_UINT, + GenerateMip, + ReadColor); + return formatInfo; + } + case ANGLE_FORMAT_R32G32B32A32_FLOAT: + { + static const ANGLEFormatSet formatInfo(ANGLE_FORMAT_R32G32B32A32_FLOAT, + GL_RGBA32F, + DXGI_FORMAT_R32G32B32A32_FLOAT, + DXGI_FORMAT_R32G32B32A32_FLOAT, + DXGI_FORMAT_R32G32B32A32_FLOAT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R32G32B32A32_FLOAT, + ANGLE_FORMAT_R32G32B32A32_FLOAT, + GenerateMip, + ReadColor); + return formatInfo; + } + case ANGLE_FORMAT_R32G32B32A32_SINT: + { + static const ANGLEFormatSet formatInfo(ANGLE_FORMAT_R32G32B32A32_SINT, + GL_RGBA32I, + DXGI_FORMAT_R32G32B32A32_SINT, + DXGI_FORMAT_R32G32B32A32_SINT, + DXGI_FORMAT_R32G32B32A32_SINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R32G32B32A32_SINT, + ANGLE_FORMAT_R32G32B32A32_SINT, + GenerateMip, + ReadColor); + return formatInfo; + } + case ANGLE_FORMAT_R32G32B32A32_UINT: + { + static const ANGLEFormatSet formatInfo(ANGLE_FORMAT_R32G32B32A32_UINT, + GL_RGBA32UI, + DXGI_FORMAT_R32G32B32A32_UINT, + DXGI_FORMAT_R32G32B32A32_UINT, + DXGI_FORMAT_R32G32B32A32_UINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R32G32B32A32_UINT, + ANGLE_FORMAT_R32G32B32A32_UINT, + GenerateMip, + ReadColor); + return formatInfo; + } + case ANGLE_FORMAT_R32G32_FLOAT: + { + static const ANGLEFormatSet formatInfo(ANGLE_FORMAT_R32G32_FLOAT, + GL_RG32F, + DXGI_FORMAT_R32G32_FLOAT, + DXGI_FORMAT_R32G32_FLOAT, + DXGI_FORMAT_R32G32_FLOAT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R32G32_FLOAT, + ANGLE_FORMAT_R32G32B32A32_FLOAT, + GenerateMip, + ReadColor); + return formatInfo; + } + case ANGLE_FORMAT_R32G32_SINT: + { + static const ANGLEFormatSet formatInfo(ANGLE_FORMAT_R32G32_SINT, + GL_RG32I, + DXGI_FORMAT_R32G32_SINT, + DXGI_FORMAT_R32G32_SINT, + DXGI_FORMAT_R32G32_SINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R32G32_SINT, + ANGLE_FORMAT_R32G32B32A32_SINT, + GenerateMip, + ReadColor); + return formatInfo; + } + case ANGLE_FORMAT_R32G32_UINT: + { + static const ANGLEFormatSet formatInfo(ANGLE_FORMAT_R32G32_UINT, + GL_RG32UI, + DXGI_FORMAT_R32G32_UINT, + DXGI_FORMAT_R32G32_UINT, + DXGI_FORMAT_R32G32_UINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R32G32_UINT, + ANGLE_FORMAT_R32G32B32A32_UINT, + GenerateMip, + ReadColor); + return formatInfo; + } + case ANGLE_FORMAT_R32_FLOAT: + { + static const ANGLEFormatSet formatInfo(ANGLE_FORMAT_R32_FLOAT, + GL_R32F, + DXGI_FORMAT_R32_FLOAT, + DXGI_FORMAT_R32_FLOAT, + DXGI_FORMAT_R32_FLOAT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R32_FLOAT, + ANGLE_FORMAT_R32G32B32A32_FLOAT, + GenerateMip, + ReadColor); + return formatInfo; + } + case ANGLE_FORMAT_R32_SINT: + { + static const ANGLEFormatSet formatInfo(ANGLE_FORMAT_R32_SINT, + GL_R32I, + DXGI_FORMAT_R32_SINT, + DXGI_FORMAT_R32_SINT, + DXGI_FORMAT_R32_SINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R32_SINT, + ANGLE_FORMAT_R32G32B32A32_SINT, + GenerateMip, + ReadColor); + return formatInfo; + } + case ANGLE_FORMAT_R32_UINT: + { + static const ANGLEFormatSet formatInfo(ANGLE_FORMAT_R32_UINT, + GL_R32UI, + DXGI_FORMAT_R32_UINT, + DXGI_FORMAT_R32_UINT, + DXGI_FORMAT_R32_UINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R32_UINT, + ANGLE_FORMAT_R32G32B32A32_UINT, + GenerateMip, + ReadColor); + return formatInfo; + } + case ANGLE_FORMAT_R8G8B8A8_SINT: + { + static const ANGLEFormatSet formatInfo(ANGLE_FORMAT_R8G8B8A8_SINT, + GL_RGBA8I, + DXGI_FORMAT_R8G8B8A8_SINT, + DXGI_FORMAT_R8G8B8A8_SINT, + DXGI_FORMAT_R8G8B8A8_SINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8B8A8_SINT, + ANGLE_FORMAT_R8G8B8A8_SINT, + GenerateMip, + ReadColor); + return formatInfo; + } + case ANGLE_FORMAT_R8G8B8A8_SNORM: + { + static const ANGLEFormatSet formatInfo(ANGLE_FORMAT_R8G8B8A8_SNORM, + GL_RGBA8_SNORM, + DXGI_FORMAT_R8G8B8A8_SNORM, + DXGI_FORMAT_R8G8B8A8_SNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8B8A8_SNORM, + ANGLE_FORMAT_R8G8B8A8_SNORM, + GenerateMip, + ReadColor); + return formatInfo; + } + case ANGLE_FORMAT_R8G8B8A8_UINT: + { + static const ANGLEFormatSet formatInfo(ANGLE_FORMAT_R8G8B8A8_UINT, + GL_RGBA8UI, + DXGI_FORMAT_R8G8B8A8_UINT, + DXGI_FORMAT_R8G8B8A8_UINT, + DXGI_FORMAT_R8G8B8A8_UINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8B8A8_UINT, + ANGLE_FORMAT_R8G8B8A8_UINT, + GenerateMip, + ReadColor); + return formatInfo; + } + case ANGLE_FORMAT_R8G8B8A8_UNORM: + { + static const ANGLEFormatSet formatInfo(ANGLE_FORMAT_R8G8B8A8_UNORM, + GL_RGBA8, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8B8A8_UNORM, + ANGLE_FORMAT_R8G8B8A8_UNORM, + GenerateMip, + ReadColor); + return formatInfo; + } + case ANGLE_FORMAT_R8G8B8A8_UNORM_NONRENDERABLE: + { + static const ANGLEFormatSet formatInfo(ANGLE_FORMAT_R8G8B8A8_UNORM_NONRENDERABLE, + GL_RGBA8, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8B8A8_UNORM, + ANGLE_FORMAT_R8G8B8A8_UNORM, + GenerateMip, + ReadColor); + return formatInfo; + } + case ANGLE_FORMAT_R8G8B8A8_UNORM_SRGB: + { + static const ANGLEFormatSet formatInfo(ANGLE_FORMAT_R8G8B8A8_UNORM_SRGB, + GL_SRGB8_ALPHA8, + DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, + DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, + DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, + ANGLE_FORMAT_R8G8B8A8_UNORM_SRGB, + GenerateMip, + ReadColor); + return formatInfo; + } + case ANGLE_FORMAT_R8G8B8A8_UNORM_SRGB_NONRENDERABLE: + { + static const ANGLEFormatSet formatInfo(ANGLE_FORMAT_R8G8B8A8_UNORM_SRGB_NONRENDERABLE, + GL_SRGB8_ALPHA8, + DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, + DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, + ANGLE_FORMAT_R8G8B8A8_UNORM, + GenerateMip, + ReadColor); + return formatInfo; + } + case ANGLE_FORMAT_R8G8_SINT: + { + static const ANGLEFormatSet formatInfo(ANGLE_FORMAT_R8G8_SINT, + GL_RG8I, + DXGI_FORMAT_R8G8_SINT, + DXGI_FORMAT_R8G8_SINT, + DXGI_FORMAT_R8G8_SINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8_SINT, + ANGLE_FORMAT_R8G8B8A8_SINT, + GenerateMip, + ReadColor); + return formatInfo; + } + case ANGLE_FORMAT_R8G8_SNORM: + { + static const ANGLEFormatSet formatInfo(ANGLE_FORMAT_R8G8_SNORM, + GL_RG8_SNORM, + DXGI_FORMAT_R8G8_SNORM, + DXGI_FORMAT_R8G8_SNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8_SNORM, + ANGLE_FORMAT_R8G8B8A8_SNORM, + GenerateMip, + ReadColor); + return formatInfo; + } + case ANGLE_FORMAT_R8G8_SNORM_NONRENDERABLE: + { + static const ANGLEFormatSet formatInfo(ANGLE_FORMAT_R8G8_SNORM_NONRENDERABLE, + GL_RG8_SNORM, + DXGI_FORMAT_R8G8_SNORM, + DXGI_FORMAT_R8G8_SNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8_SNORM, + ANGLE_FORMAT_R8G8B8A8_SNORM, + GenerateMip, + ReadColor); + return formatInfo; + } + case ANGLE_FORMAT_R8G8_UINT: + { + static const ANGLEFormatSet formatInfo(ANGLE_FORMAT_R8G8_UINT, + GL_RG8UI, + DXGI_FORMAT_R8G8_UINT, + DXGI_FORMAT_R8G8_UINT, + DXGI_FORMAT_R8G8_UINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8_UINT, + ANGLE_FORMAT_R8G8B8A8_UINT, + GenerateMip, + ReadColor); + return formatInfo; + } + case ANGLE_FORMAT_R8G8_UNORM: + { + static const ANGLEFormatSet formatInfo(ANGLE_FORMAT_R8G8_UNORM, + GL_RG8, + DXGI_FORMAT_R8G8_UNORM, + DXGI_FORMAT_R8G8_UNORM, + DXGI_FORMAT_R8G8_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8_UNORM, + ANGLE_FORMAT_R8G8B8A8_UNORM, + GenerateMip, + ReadColor); + return formatInfo; + } + case ANGLE_FORMAT_R8G8_UNORM_NONRENDERABLE: + { + static const ANGLEFormatSet formatInfo(ANGLE_FORMAT_R8G8_UNORM_NONRENDERABLE, + GL_RG8, + DXGI_FORMAT_R8G8_UNORM, + DXGI_FORMAT_R8G8_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8_UNORM, + ANGLE_FORMAT_R8G8B8A8_UNORM, + GenerateMip, + ReadColor); + return formatInfo; + } + case ANGLE_FORMAT_R8_SINT: + { + static const ANGLEFormatSet formatInfo(ANGLE_FORMAT_R8_SINT, + GL_R8I, + DXGI_FORMAT_R8_SINT, + DXGI_FORMAT_R8_SINT, + DXGI_FORMAT_R8_SINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8_SINT, + ANGLE_FORMAT_R8G8B8A8_SINT, + GenerateMip, + ReadColor); + return formatInfo; + } + case ANGLE_FORMAT_R8_SNORM: + { + static const ANGLEFormatSet formatInfo(ANGLE_FORMAT_R8_SNORM, + GL_R8_SNORM, + DXGI_FORMAT_R8_SNORM, + DXGI_FORMAT_R8_SNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8_SNORM, + ANGLE_FORMAT_R8G8B8A8_SNORM, + GenerateMip, + ReadColor); + return formatInfo; + } + case ANGLE_FORMAT_R8_SNORM_NONRENDERABLE: + { + static const ANGLEFormatSet formatInfo(ANGLE_FORMAT_R8_SNORM_NONRENDERABLE, + GL_R8_SNORM, + DXGI_FORMAT_R8_SNORM, + DXGI_FORMAT_R8_SNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8_SNORM, + ANGLE_FORMAT_R8G8B8A8_SNORM, + GenerateMip, + ReadColor); + return formatInfo; + } + case ANGLE_FORMAT_R8_UINT: + { + static const ANGLEFormatSet formatInfo(ANGLE_FORMAT_R8_UINT, + GL_R8UI, + DXGI_FORMAT_R8_UINT, + DXGI_FORMAT_R8_UINT, + DXGI_FORMAT_R8_UINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8_UINT, + ANGLE_FORMAT_R8G8B8A8_UINT, + GenerateMip, + ReadColor); + return formatInfo; + } + case ANGLE_FORMAT_R8_UNORM: + { + static const ANGLEFormatSet formatInfo(ANGLE_FORMAT_R8_UNORM, + GL_R8, + DXGI_FORMAT_R8_UNORM, + DXGI_FORMAT_R8_UNORM, + DXGI_FORMAT_R8_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8_UNORM, + ANGLE_FORMAT_R8G8B8A8_UNORM, + GenerateMip, + ReadColor); + return formatInfo; + } + case ANGLE_FORMAT_R8_UNORM_NONRENDERABLE: + { + static const ANGLEFormatSet formatInfo(ANGLE_FORMAT_R8_UNORM_NONRENDERABLE, + GL_R8, + DXGI_FORMAT_R8_UNORM, + DXGI_FORMAT_R8_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8_UNORM, + ANGLE_FORMAT_R8G8B8A8_UNORM, + GenerateMip, + ReadColor); + return formatInfo; + } + case ANGLE_FORMAT_R9G9B9E5_SHAREDEXP: + { + static const ANGLEFormatSet formatInfo(ANGLE_FORMAT_R9G9B9E5_SHAREDEXP, + GL_RGB9_E5, + DXGI_FORMAT_R9G9B9E5_SHAREDEXP, + DXGI_FORMAT_R9G9B9E5_SHAREDEXP, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R9G9B9E5_SHAREDEXP, + ANGLE_FORMAT_R16G16B16A16_FLOAT, + GenerateMip, + ReadColor); + return formatInfo; + } + case ANGLE_FORMAT_X24_TYPELESS_G8_UINT: + { + static const ANGLEFormatSet formatInfo(ANGLE_FORMAT_X24_TYPELESS_G8_UINT, + GL_DEPTH24_STENCIL8_OES, + DXGI_FORMAT_R24G8_TYPELESS, + DXGI_FORMAT_X24_TYPELESS_G8_UINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_D24_UNORM_S8_UINT, + DXGI_FORMAT_X24_TYPELESS_G8_UINT, + ANGLE_FORMAT_R32G32B32A32_FLOAT, + nullptr, + nullptr); + return formatInfo; + } + + default: + break; + } + // clang-format on + + UNREACHABLE(); + static const ANGLEFormatSet defaultInfo; + return defaultInfo; +} + +const TextureFormat &GetTextureFormatInfo(GLenum internalFormat, + const Renderer11DeviceCaps &renderer11DeviceCaps) +{ + // clang-format off + switch (internalFormat) + { + case GL_ALPHA: + { + if (OnlyFL10Plus(renderer11DeviceCaps)) + { + static const TextureFormat textureFormat(internalFormat, + ANGLE_FORMAT_A8_UNORM, + nullptr); + return textureFormat; + } + else if (OnlyFL9_3(renderer11DeviceCaps)) + { + static const TextureFormat textureFormat(internalFormat, + ANGLE_FORMAT_R8G8B8A8_UNORM, + nullptr); + return textureFormat; + } + else + { + break; + } + } + case GL_ALPHA16F_EXT: + { + static const TextureFormat textureFormat(internalFormat, + ANGLE_FORMAT_R16G16B16A16_FLOAT, + nullptr); + return textureFormat; + } + case GL_ALPHA32F_EXT: + { + static const TextureFormat textureFormat(internalFormat, + ANGLE_FORMAT_R32G32B32A32_FLOAT, + nullptr); + return textureFormat; + } + case GL_ALPHA8_EXT: + { + if (OnlyFL10Plus(renderer11DeviceCaps)) + { + static const TextureFormat textureFormat(internalFormat, + ANGLE_FORMAT_A8_UNORM, + nullptr); + return textureFormat; + } + else if (OnlyFL9_3(renderer11DeviceCaps)) + { + static const TextureFormat textureFormat(internalFormat, + ANGLE_FORMAT_R8G8B8A8_UNORM, + nullptr); + return textureFormat; + } + else + { + break; + } + } + case GL_BGR5_A1_ANGLEX: + { + static const TextureFormat textureFormat(internalFormat, + ANGLE_FORMAT_B8G8R8A8_UNORM, + nullptr); + return textureFormat; + } + case GL_BGRA4_ANGLEX: + { + static const TextureFormat textureFormat(internalFormat, + ANGLE_FORMAT_B8G8R8A8_UNORM, + nullptr); + return textureFormat; + } + case GL_BGRA8_EXT: + { + static const TextureFormat textureFormat(internalFormat, + ANGLE_FORMAT_B8G8R8A8_UNORM, + nullptr); + return textureFormat; + } + case GL_BGRA_EXT: + { + static const TextureFormat textureFormat(internalFormat, + ANGLE_FORMAT_B8G8R8A8_UNORM, + nullptr); + return textureFormat; + } + case GL_COMPRESSED_R11_EAC: + { + if (OnlyFL10Plus(renderer11DeviceCaps)) + { + static const TextureFormat textureFormat(internalFormat, + ANGLE_FORMAT_R8_UNORM_NONRENDERABLE, + nullptr); + return textureFormat; + } + else + { + break; + } + } + case GL_COMPRESSED_RG11_EAC: + { + if (OnlyFL10Plus(renderer11DeviceCaps)) + { + static const TextureFormat textureFormat(internalFormat, + ANGLE_FORMAT_R8G8_UNORM_NONRENDERABLE, + nullptr); + return textureFormat; + } + else + { + break; + } + } + case GL_COMPRESSED_RGB8_ETC2: + { + if (OnlyFL10Plus(renderer11DeviceCaps)) + { + static const TextureFormat textureFormat(internalFormat, + ANGLE_FORMAT_R8G8B8A8_UNORM_NONRENDERABLE, + Initialize4ComponentData); + return textureFormat; + } + else + { + break; + } + } + case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2: + { + if (OnlyFL10Plus(renderer11DeviceCaps)) + { + static const TextureFormat textureFormat(internalFormat, + ANGLE_FORMAT_R8G8B8A8_UNORM_NONRENDERABLE, + Initialize4ComponentData); + return textureFormat; + } + else + { + break; + } + } + case GL_COMPRESSED_RGBA8_ETC2_EAC: + { + if (OnlyFL10Plus(renderer11DeviceCaps)) + { + static const TextureFormat textureFormat(internalFormat, + ANGLE_FORMAT_R8G8B8A8_UNORM_NONRENDERABLE, + nullptr); + return textureFormat; + } + else + { + break; + } + } + case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: + { + static const TextureFormat textureFormat(internalFormat, + ANGLE_FORMAT_BC1_UNORM, + nullptr); + return textureFormat; + } + case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE: + { + static const TextureFormat textureFormat(internalFormat, + ANGLE_FORMAT_BC2_UNORM, + nullptr); + return textureFormat; + } + case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE: + { + static const TextureFormat textureFormat(internalFormat, + ANGLE_FORMAT_BC3_UNORM, + nullptr); + return textureFormat; + } + case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: + { + static const TextureFormat textureFormat(internalFormat, + ANGLE_FORMAT_BC1_UNORM, + nullptr); + return textureFormat; + } + case GL_COMPRESSED_SIGNED_R11_EAC: + { + if (OnlyFL10Plus(renderer11DeviceCaps)) + { + static const TextureFormat textureFormat(internalFormat, + ANGLE_FORMAT_R8_SNORM_NONRENDERABLE, + nullptr); + return textureFormat; + } + else + { + break; + } + } + case GL_COMPRESSED_SIGNED_RG11_EAC: + { + if (OnlyFL10Plus(renderer11DeviceCaps)) + { + static const TextureFormat textureFormat(internalFormat, + ANGLE_FORMAT_R8G8_SNORM_NONRENDERABLE, + nullptr); + return textureFormat; + } + else + { + break; + } + } + case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC: + { + if (OnlyFL10Plus(renderer11DeviceCaps)) + { + static const TextureFormat textureFormat(internalFormat, + ANGLE_FORMAT_R8G8B8A8_UNORM_SRGB_NONRENDERABLE, + nullptr); + return textureFormat; + } + else + { + break; + } + } + case GL_COMPRESSED_SRGB8_ETC2: + { + if (OnlyFL10Plus(renderer11DeviceCaps)) + { + static const TextureFormat textureFormat(internalFormat, + ANGLE_FORMAT_R8G8B8A8_UNORM_SRGB_NONRENDERABLE, + Initialize4ComponentData); + return textureFormat; + } + else + { + break; + } + } + case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2: + { + if (OnlyFL10Plus(renderer11DeviceCaps)) + { + static const TextureFormat textureFormat(internalFormat, + ANGLE_FORMAT_R8G8B8A8_UNORM_SRGB_NONRENDERABLE, + nullptr); + return textureFormat; + } + else + { + break; + } + } + case GL_DEPTH24_STENCIL8: + { + if (OnlyFL10Plus(renderer11DeviceCaps)) + { + static const TextureFormat textureFormat(internalFormat, + ANGLE_FORMAT_D24_UNORM_S8_UINT_FL10, + nullptr); + return textureFormat; + } + else if (OnlyFL9_3(renderer11DeviceCaps)) + { + static const TextureFormat textureFormat(internalFormat, + ANGLE_FORMAT_D24_UNORM_S8_UINT_FL9_3, + nullptr); + return textureFormat; + } + else + { + break; + } + } + case GL_DEPTH32F_STENCIL8: + { + if (OnlyFL10Plus(renderer11DeviceCaps)) + { + static const TextureFormat textureFormat(internalFormat, + ANGLE_FORMAT_D32_FLOAT_S8X24_UINT_FL10, + nullptr); + return textureFormat; + } + else if (OnlyFL9_3(renderer11DeviceCaps)) + { + static const TextureFormat textureFormat(internalFormat, + ANGLE_FORMAT_NONE, + nullptr); + return textureFormat; + } + else + { + break; + } + } + case GL_DEPTH_COMPONENT16: + { + if (OnlyFL10Plus(renderer11DeviceCaps)) + { + static const TextureFormat textureFormat(internalFormat, + ANGLE_FORMAT_D16_UNORM_FL10, + nullptr); + return textureFormat; + } + else if (OnlyFL9_3(renderer11DeviceCaps)) + { + static const TextureFormat textureFormat(internalFormat, + ANGLE_FORMAT_D16_UNORM_FL9_3, + nullptr); + return textureFormat; + } + else + { + break; + } + } + case GL_DEPTH_COMPONENT24: + { + if (OnlyFL10Plus(renderer11DeviceCaps)) + { + static const TextureFormat textureFormat(internalFormat, + ANGLE_FORMAT_D24_UNORM_S8_UINT_FL10, + nullptr); + return textureFormat; + } + else if (OnlyFL9_3(renderer11DeviceCaps)) + { + static const TextureFormat textureFormat(internalFormat, + ANGLE_FORMAT_D24_UNORM_S8_UINT_FL9_3, + nullptr); + return textureFormat; + } + else + { + break; + } + } + case GL_DEPTH_COMPONENT32F: + { + if (OnlyFL10Plus(renderer11DeviceCaps)) + { + static const TextureFormat textureFormat(internalFormat, + ANGLE_FORMAT_D32_FLOAT, + nullptr); + return textureFormat; + } + else if (OnlyFL9_3(renderer11DeviceCaps)) + { + static const TextureFormat textureFormat(internalFormat, + ANGLE_FORMAT_NONE, + nullptr); + return textureFormat; + } + else + { + break; + } + } + case GL_DEPTH_COMPONENT32_OES: + { + if (OnlyFL10Plus(renderer11DeviceCaps)) + { + static const TextureFormat textureFormat(internalFormat, + ANGLE_FORMAT_D24_UNORM_S8_UINT_FL10, + nullptr); + return textureFormat; + } + else + { + break; + } + } + case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE: + { + static const TextureFormat textureFormat(internalFormat, + ANGLE_FORMAT_BC1_UNORM, + nullptr); + return textureFormat; + } + case GL_ETC1_RGB8_OES: + { + static const TextureFormat textureFormat(internalFormat, + ANGLE_FORMAT_R8G8B8A8_UNORM_NONRENDERABLE, + Initialize4ComponentData); + return textureFormat; + } + case GL_LUMINANCE: + { + static const TextureFormat textureFormat(internalFormat, + ANGLE_FORMAT_R8G8B8A8_UNORM, + Initialize4ComponentData); + return textureFormat; + } + case GL_LUMINANCE16F_EXT: + { + static const TextureFormat textureFormat(internalFormat, + ANGLE_FORMAT_R16G16B16A16_FLOAT, + Initialize4ComponentData); + return textureFormat; + } + case GL_LUMINANCE32F_EXT: + { + static const TextureFormat textureFormat(internalFormat, + ANGLE_FORMAT_R32G32B32A32_FLOAT, + Initialize4ComponentData); + return textureFormat; + } + case GL_LUMINANCE8_ALPHA8_EXT: + { + static const TextureFormat textureFormat(internalFormat, + ANGLE_FORMAT_R8G8B8A8_UNORM, + nullptr); + return textureFormat; + } + case GL_LUMINANCE8_EXT: + { + static const TextureFormat textureFormat(internalFormat, + ANGLE_FORMAT_R8G8B8A8_UNORM, + Initialize4ComponentData); + return textureFormat; + } + case GL_LUMINANCE_ALPHA: + { + static const TextureFormat textureFormat(internalFormat, + ANGLE_FORMAT_R8G8B8A8_UNORM, + nullptr); + return textureFormat; + } + case GL_LUMINANCE_ALPHA16F_EXT: + { + static const TextureFormat textureFormat(internalFormat, + ANGLE_FORMAT_R16G16B16A16_FLOAT, + nullptr); + return textureFormat; + } + case GL_LUMINANCE_ALPHA32F_EXT: + { + static const TextureFormat textureFormat(internalFormat, + ANGLE_FORMAT_R32G32B32A32_FLOAT, + nullptr); + return textureFormat; + } + case GL_NONE: + { + static const TextureFormat textureFormat(internalFormat, + ANGLE_FORMAT_NONE, + nullptr); + return textureFormat; + } + case GL_R11F_G11F_B10F: + { + static const TextureFormat textureFormat(internalFormat, + ANGLE_FORMAT_R11G11B10_FLOAT, + nullptr); + return textureFormat; + } + case GL_R16F: + { + static const TextureFormat textureFormat(internalFormat, + ANGLE_FORMAT_R16_FLOAT, + nullptr); + return textureFormat; + } + case GL_R16I: + { + static const TextureFormat textureFormat(internalFormat, + ANGLE_FORMAT_R16_SINT, + nullptr); + return textureFormat; + } + case GL_R16UI: + { + static const TextureFormat textureFormat(internalFormat, + ANGLE_FORMAT_R16_UINT, + nullptr); + return textureFormat; + } + case GL_R32F: + { + static const TextureFormat textureFormat(internalFormat, + ANGLE_FORMAT_R32_FLOAT, + nullptr); + return textureFormat; + } + case GL_R32I: + { + static const TextureFormat textureFormat(internalFormat, + ANGLE_FORMAT_R32_SINT, + nullptr); + return textureFormat; + } + case GL_R32UI: + { + static const TextureFormat textureFormat(internalFormat, + ANGLE_FORMAT_R32_UINT, + nullptr); + return textureFormat; + } + case GL_R8: + { + static const TextureFormat textureFormat(internalFormat, + ANGLE_FORMAT_R8_UNORM, + nullptr); + return textureFormat; + } + case GL_R8I: + { + static const TextureFormat textureFormat(internalFormat, + ANGLE_FORMAT_R8_SINT, + nullptr); + return textureFormat; + } + case GL_R8UI: + { + static const TextureFormat textureFormat(internalFormat, + ANGLE_FORMAT_R8_UINT, + nullptr); + return textureFormat; + } + case GL_R8_SNORM: + { + static const TextureFormat textureFormat(internalFormat, + ANGLE_FORMAT_R8_SNORM, + nullptr); + return textureFormat; + } + case GL_RG16F: + { + static const TextureFormat textureFormat(internalFormat, + ANGLE_FORMAT_R16G16_FLOAT, + nullptr); + return textureFormat; + } + case GL_RG16I: + { + static const TextureFormat textureFormat(internalFormat, + ANGLE_FORMAT_R16G16_SINT, + nullptr); + return textureFormat; + } + case GL_RG16UI: + { + static const TextureFormat textureFormat(internalFormat, + ANGLE_FORMAT_R16G16_UINT, + nullptr); + return textureFormat; + } + case GL_RG32F: + { + static const TextureFormat textureFormat(internalFormat, + ANGLE_FORMAT_R32G32_FLOAT, + nullptr); + return textureFormat; + } + case GL_RG32I: + { + static const TextureFormat textureFormat(internalFormat, + ANGLE_FORMAT_R32G32_SINT, + nullptr); + return textureFormat; + } + case GL_RG32UI: + { + static const TextureFormat textureFormat(internalFormat, + ANGLE_FORMAT_R32G32_UINT, + nullptr); + return textureFormat; + } + case GL_RG8: + { + static const TextureFormat textureFormat(internalFormat, + ANGLE_FORMAT_R8G8_UNORM, + nullptr); + return textureFormat; + } + case GL_RG8I: + { + static const TextureFormat textureFormat(internalFormat, + ANGLE_FORMAT_R8G8_SINT, + nullptr); + return textureFormat; + } + case GL_RG8UI: + { + static const TextureFormat textureFormat(internalFormat, + ANGLE_FORMAT_R8G8_UINT, + nullptr); + return textureFormat; + } + case GL_RG8_SNORM: + { + static const TextureFormat textureFormat(internalFormat, + ANGLE_FORMAT_R8G8_SNORM, + nullptr); + return textureFormat; + } + case GL_RGB: + { + static const TextureFormat textureFormat(internalFormat, + ANGLE_FORMAT_R8G8B8A8_UNORM, + Initialize4ComponentData); + return textureFormat; + } + case GL_RGB10_A2: + { + static const TextureFormat textureFormat(internalFormat, + ANGLE_FORMAT_R10G10B10A2_UNORM, + nullptr); + return textureFormat; + } + case GL_RGB10_A2UI: + { + static const TextureFormat textureFormat(internalFormat, + ANGLE_FORMAT_R10G10B10A2_UINT, + nullptr); + return textureFormat; + } + case GL_RGB16F: + { + static const TextureFormat textureFormat(internalFormat, + ANGLE_FORMAT_R16G16B16A16_FLOAT, + Initialize4ComponentData); + return textureFormat; + } + case GL_RGB16I: + { + static const TextureFormat textureFormat(internalFormat, + ANGLE_FORMAT_R16G16B16A16_SINT, + Initialize4ComponentData); + return textureFormat; + } + case GL_RGB16UI: + { + static const TextureFormat textureFormat(internalFormat, + ANGLE_FORMAT_R16G16B16A16_UINT, + Initialize4ComponentData); + return textureFormat; + } + case GL_RGB32F: + { + static const TextureFormat textureFormat(internalFormat, + ANGLE_FORMAT_R32G32B32A32_FLOAT, + Initialize4ComponentData); + return textureFormat; + } + case GL_RGB32I: + { + static const TextureFormat textureFormat(internalFormat, + ANGLE_FORMAT_R32G32B32A32_SINT, + Initialize4ComponentData); + return textureFormat; + } + case GL_RGB32UI: + { + static const TextureFormat textureFormat(internalFormat, + ANGLE_FORMAT_R32G32B32A32_UINT, + Initialize4ComponentData); + return textureFormat; + } + case GL_RGB565: + { + if (SupportsFormat(renderer11DeviceCaps)) + { + static const TextureFormat textureFormat(internalFormat, + ANGLE_FORMAT_R8G8B8A8_UNORM, + Initialize4ComponentData); + return textureFormat; + } + else if (SupportsFormat(renderer11DeviceCaps)) + { + static const TextureFormat textureFormat(internalFormat, + ANGLE_FORMAT_B5G6R5_UNORM, + nullptr); + return textureFormat; + } + else + { + break; + } + } + case GL_RGB5_A1: + { + if (SupportsFormat(renderer11DeviceCaps)) + { + static const TextureFormat textureFormat(internalFormat, + ANGLE_FORMAT_R8G8B8A8_UNORM, + nullptr); + return textureFormat; + } + else if (SupportsFormat(renderer11DeviceCaps)) + { + static const TextureFormat textureFormat(internalFormat, + ANGLE_FORMAT_B5G5R5A1_UNORM, + nullptr); + return textureFormat; + } + else + { + break; + } + } + case GL_RGB8: + { + static const TextureFormat textureFormat(internalFormat, + ANGLE_FORMAT_R8G8B8A8_UNORM, + Initialize4ComponentData); + return textureFormat; + } + case GL_RGB8I: + { + static const TextureFormat textureFormat(internalFormat, + ANGLE_FORMAT_R8G8B8A8_SINT, + Initialize4ComponentData); + return textureFormat; + } + case GL_RGB8UI: + { + static const TextureFormat textureFormat(internalFormat, + ANGLE_FORMAT_R8G8B8A8_UINT, + Initialize4ComponentData); + return textureFormat; + } + case GL_RGB8_SNORM: + { + static const TextureFormat textureFormat(internalFormat, + ANGLE_FORMAT_R8G8B8A8_SNORM, + Initialize4ComponentData); + return textureFormat; + } + case GL_RGB9_E5: + { + static const TextureFormat textureFormat(internalFormat, + ANGLE_FORMAT_R9G9B9E5_SHAREDEXP, + nullptr); + return textureFormat; + } + case GL_RGBA: + { + static const TextureFormat textureFormat(internalFormat, + ANGLE_FORMAT_R8G8B8A8_UNORM, + nullptr); + return textureFormat; + } + case GL_RGBA16F: + { + static const TextureFormat textureFormat(internalFormat, + ANGLE_FORMAT_R16G16B16A16_FLOAT, + nullptr); + return textureFormat; + } + case GL_RGBA16I: + { + static const TextureFormat textureFormat(internalFormat, + ANGLE_FORMAT_R16G16B16A16_SINT, + nullptr); + return textureFormat; + } + case GL_RGBA16UI: + { + static const TextureFormat textureFormat(internalFormat, + ANGLE_FORMAT_R16G16B16A16_UINT, + nullptr); + return textureFormat; + } + case GL_RGBA32F: + { + static const TextureFormat textureFormat(internalFormat, + ANGLE_FORMAT_R32G32B32A32_FLOAT, + nullptr); + return textureFormat; + } + case GL_RGBA32I: + { + static const TextureFormat textureFormat(internalFormat, + ANGLE_FORMAT_R32G32B32A32_SINT, + nullptr); + return textureFormat; + } + case GL_RGBA32UI: + { + static const TextureFormat textureFormat(internalFormat, + ANGLE_FORMAT_R32G32B32A32_UINT, + nullptr); + return textureFormat; + } + case GL_RGBA4: + { + if (SupportsFormat(renderer11DeviceCaps)) + { + static const TextureFormat textureFormat(internalFormat, + ANGLE_FORMAT_R8G8B8A8_UNORM, + nullptr); + return textureFormat; + } + else if (SupportsFormat(renderer11DeviceCaps)) + { + static const TextureFormat textureFormat(internalFormat, + ANGLE_FORMAT_B4G4R4A4_UNORM, + nullptr); + return textureFormat; + } + else + { + break; + } + } + case GL_RGBA8: + { + static const TextureFormat textureFormat(internalFormat, + ANGLE_FORMAT_R8G8B8A8_UNORM, + nullptr); + return textureFormat; + } + case GL_RGBA8I: + { + static const TextureFormat textureFormat(internalFormat, + ANGLE_FORMAT_R8G8B8A8_SINT, + nullptr); + return textureFormat; + } + case GL_RGBA8UI: + { + static const TextureFormat textureFormat(internalFormat, + ANGLE_FORMAT_R8G8B8A8_UINT, + nullptr); + return textureFormat; + } + case GL_RGBA8_SNORM: + { + static const TextureFormat textureFormat(internalFormat, + ANGLE_FORMAT_R8G8B8A8_SNORM, + nullptr); + return textureFormat; + } + case GL_SRGB8: + { + static const TextureFormat textureFormat(internalFormat, + ANGLE_FORMAT_R8G8B8A8_UNORM_SRGB_NONRENDERABLE, + Initialize4ComponentData); + return textureFormat; + } + case GL_SRGB8_ALPHA8: + { + static const TextureFormat textureFormat(internalFormat, + ANGLE_FORMAT_R8G8B8A8_UNORM_SRGB, + nullptr); + return textureFormat; + } + case GL_STENCIL_INDEX8: + { + if (OnlyFL10Plus(renderer11DeviceCaps)) + { + static const TextureFormat textureFormat(internalFormat, + ANGLE_FORMAT_X24_TYPELESS_G8_UINT, + nullptr); + return textureFormat; + } + else if (OnlyFL9_3(renderer11DeviceCaps)) + { + static const TextureFormat textureFormat(internalFormat, + ANGLE_FORMAT_D24_UNORM_S8_UINT_FL9_3, + nullptr); + return textureFormat; + } + else + { + break; + } + } + + default: + break; + } + // clang-format on + + static const TextureFormat defaultInfo(GL_NONE, ANGLE_FORMAT_NONE, nullptr); + return defaultInfo; +} // GetTextureFormatInfo + +} // namespace d3d11 + +} // namespace rx diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/texture_format_table_autogen.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/texture_format_table_autogen.h new file mode 100644 index 000000000000..0cc345b24d62 --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/texture_format_table_autogen.h @@ -0,0 +1,79 @@ +// GENERATED FILE - DO NOT EDIT. +// Generated by gen_texture_format_table.py using data from texture_format_data.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. +// + +namespace rx +{ + +namespace d3d11 +{ + +enum ANGLEFormat +{ + ANGLE_FORMAT_A8_UNORM, + ANGLE_FORMAT_B4G4R4A4_UNORM, + ANGLE_FORMAT_B5G5R5A1_UNORM, + ANGLE_FORMAT_B5G6R5_UNORM, + ANGLE_FORMAT_B8G8R8A8_UNORM, + ANGLE_FORMAT_BC1_UNORM, + ANGLE_FORMAT_BC2_UNORM, + ANGLE_FORMAT_BC3_UNORM, + ANGLE_FORMAT_D16_UNORM_FL10, + ANGLE_FORMAT_D16_UNORM_FL9_3, + ANGLE_FORMAT_D24_UNORM_S8_UINT_FL10, + ANGLE_FORMAT_D24_UNORM_S8_UINT_FL9_3, + ANGLE_FORMAT_D32_FLOAT, + ANGLE_FORMAT_D32_FLOAT_S8X24_UINT_FL10, + ANGLE_FORMAT_NONE, + ANGLE_FORMAT_R10G10B10A2_UINT, + ANGLE_FORMAT_R10G10B10A2_UNORM, + ANGLE_FORMAT_R11G11B10_FLOAT, + ANGLE_FORMAT_R16G16B16A16_FLOAT, + ANGLE_FORMAT_R16G16B16A16_SINT, + ANGLE_FORMAT_R16G16B16A16_UINT, + ANGLE_FORMAT_R16G16B16A16_UNORM, + ANGLE_FORMAT_R16G16_FLOAT, + ANGLE_FORMAT_R16G16_SINT, + ANGLE_FORMAT_R16G16_UINT, + ANGLE_FORMAT_R16_FLOAT, + ANGLE_FORMAT_R16_SINT, + ANGLE_FORMAT_R16_UINT, + ANGLE_FORMAT_R32G32B32A32_FLOAT, + ANGLE_FORMAT_R32G32B32A32_SINT, + ANGLE_FORMAT_R32G32B32A32_UINT, + ANGLE_FORMAT_R32G32_FLOAT, + ANGLE_FORMAT_R32G32_SINT, + ANGLE_FORMAT_R32G32_UINT, + ANGLE_FORMAT_R32_FLOAT, + ANGLE_FORMAT_R32_SINT, + ANGLE_FORMAT_R32_UINT, + ANGLE_FORMAT_R8G8B8A8_SINT, + ANGLE_FORMAT_R8G8B8A8_SNORM, + ANGLE_FORMAT_R8G8B8A8_UINT, + ANGLE_FORMAT_R8G8B8A8_UNORM, + ANGLE_FORMAT_R8G8B8A8_UNORM_NONRENDERABLE, + ANGLE_FORMAT_R8G8B8A8_UNORM_SRGB, + ANGLE_FORMAT_R8G8B8A8_UNORM_SRGB_NONRENDERABLE, + ANGLE_FORMAT_R8G8_SINT, + ANGLE_FORMAT_R8G8_SNORM, + ANGLE_FORMAT_R8G8_SNORM_NONRENDERABLE, + ANGLE_FORMAT_R8G8_UINT, + ANGLE_FORMAT_R8G8_UNORM, + ANGLE_FORMAT_R8G8_UNORM_NONRENDERABLE, + ANGLE_FORMAT_R8_SINT, + ANGLE_FORMAT_R8_SNORM, + ANGLE_FORMAT_R8_SNORM_NONRENDERABLE, + ANGLE_FORMAT_R8_UINT, + ANGLE_FORMAT_R8_UNORM, + ANGLE_FORMAT_R8_UNORM_NONRENDERABLE, + ANGLE_FORMAT_R9G9B9E5_SHAREDEXP, + ANGLE_FORMAT_X24_TYPELESS_G8_UINT +}; + +} // namespace d3d11 + +} // namespace rx diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/win32/NativeWindow.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/win32/NativeWindow.cpp index 9d8f0bb96ced..05d7a4673320 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/win32/NativeWindow.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/win32/NativeWindow.cpp @@ -7,19 +7,38 @@ // NativeWindow.cpp: Handler for managing HWND native window types. #include "libANGLE/renderer/d3d/d3d11/NativeWindow.h" +#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h" #include "common/debug.h" +#include +#include + namespace rx { -NativeWindow::NativeWindow(EGLNativeWindowType window) : mWindow(window) +NativeWindow::NativeWindow(EGLNativeWindowType window, + const egl::Config *config, + bool directComposition) + : mWindow(window), + mDirectComposition(directComposition), + mDevice(nullptr), + mCompositionTarget(nullptr), + mVisual(nullptr), + mConfig(config) +{ +} + +NativeWindow::~NativeWindow() { + SafeRelease(mCompositionTarget); + SafeRelease(mDevice); + SafeRelease(mVisual); } bool NativeWindow::initialize() -{ - return true; +{ + return true; } bool NativeWindow::getClientRect(LPRECT rect) @@ -46,7 +65,113 @@ HRESULT NativeWindow::createSwapChain(ID3D11Device* device, DXGIFactory* factory return E_INVALIDARG; } - DXGI_SWAP_CHAIN_DESC swapChainDesc = { 0 }; + 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(mWindow, 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 = {0}; + 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 = + mConfig->alphaSize == 0 ? DXGI_ALPHA_MODE_IGNORE : DXGI_ALPHA_MODE_PREMULTIPLIED; + 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 = { 0 }; + 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_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, mWindow, &swapChainDesc, nullptr, nullptr, &swapChain1); + if (SUCCEEDED(result)) + { + *swapChain = static_cast(swapChain1); + } + SafeRelease(factory2); + return result; + } + + DXGI_SWAP_CHAIN_DESC swapChainDesc = {}; swapChainDesc.BufferCount = 1; swapChainDesc.BufferDesc.Format = format; swapChainDesc.BufferDesc.Width = width; @@ -55,7 +180,8 @@ HRESULT NativeWindow::createSwapChain(ID3D11Device* device, DXGIFactory* factory 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_BACK_BUFFER; + swapChainDesc.BufferUsage = + DXGI_USAGE_RENDER_TARGET_OUTPUT | DXGI_USAGE_SHADER_INPUT | DXGI_USAGE_BACK_BUFFER; swapChainDesc.Flags = 0; swapChainDesc.OutputWindow = mWindow; swapChainDesc.SampleDesc.Count = 1; @@ -65,4 +191,12 @@ HRESULT NativeWindow::createSwapChain(ID3D11Device* device, DXGIFactory* factory return factory->CreateSwapChain(device, &swapChainDesc, swapChain); } + +void NativeWindow::commitChange() +{ + if (mDevice) + { + mDevice->Commit(); + } +} } diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow.cpp index 8cfaa845e030..71f0e4208dba 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow.cpp @@ -24,7 +24,6 @@ bool CoreWindowNativeWindow::initialize(EGLNativeWindowType window, IPropertySet ComPtr props = propertySet; ComPtr win = window; SIZE swapChainSize = {}; - bool swapChainSizeSpecified = false; HRESULT result = S_OK; // IPropertySet is an optional parameter and can be null. @@ -33,12 +32,40 @@ bool CoreWindowNativeWindow::initialize(EGLNativeWindowType window, IPropertySet if (propertySet) { result = props.As(&mPropertyMap); - if (SUCCEEDED(result)) + if (FAILED(result)) { - // The EGLRenderSurfaceSizeProperty is optional and may be missing. The IPropertySet - // was prevalidated to contain the EGLNativeWindowType before being passed to - // this host. - result = GetOptionalSizePropertyValue(mPropertyMap, EGLRenderSurfaceSizeProperty, &swapChainSize, &swapChainSizeSpecified); + return false; + } + + // The EGLRenderSurfaceSizeProperty is optional and may be missing. The IPropertySet + // was prevalidated to contain the EGLNativeWindowType before being passed to + // this host. + result = GetOptionalSizePropertyValue(mPropertyMap, EGLRenderSurfaceSizeProperty, &swapChainSize, &mSwapChainSizeSpecified); + if (FAILED(result)) + { + return false; + } + + // The EGLRenderResolutionScaleProperty is optional and may be missing. The IPropertySet + // was prevalidated to contain the EGLNativeWindowType before being passed to + // this host. + result = GetOptionalSinglePropertyValue(mPropertyMap, EGLRenderResolutionScaleProperty, &mSwapChainScale, &mSwapChainScaleSpecified); + if (FAILED(result)) + { + return false; + } + + if (!mSwapChainScaleSpecified) + { + // Default value for the scale is 1.0f + mSwapChainScale = 1.0f; + } + + // A EGLRenderSurfaceSizeProperty and a EGLRenderResolutionScaleProperty can't both be specified + if (mSwapChainScaleSpecified && mSwapChainSizeSpecified) + { + ERR("It is invalid to specify both an EGLRenderSurfaceSizeProperty and a EGLRenderResolutionScaleProperty."); + return false; } } @@ -55,14 +82,19 @@ bool CoreWindowNativeWindow::initialize(EGLNativeWindowType window, IPropertySet // of the host. // Scaling of the swapchain output occurs automatically because if // the scaling mode setting DXGI_SCALING_STRETCH on the swapchain. - if (swapChainSizeSpecified) + if (mSwapChainSizeSpecified) { mClientRect = { 0, 0, swapChainSize.cx, swapChainSize.cy }; - mSupportsSwapChainResize = false; } else { - result = GetCoreWindowSizeInPixels(mCoreWindow, &mClientRect); + SIZE coreWindowSize; + result = GetCoreWindowSizeInPixels(mCoreWindow, &coreWindowSize); + + if (SUCCEEDED(result)) + { + mClientRect = { 0, 0, static_cast(coreWindowSize.cx * mSwapChainScale), static_cast(coreWindowSize.cy * mSwapChainScale) }; + } } } @@ -102,7 +134,13 @@ void CoreWindowNativeWindow::unregisterForSizeChangeEvents() mSizeChangedEventToken.value = 0; } -HRESULT CoreWindowNativeWindow::createSwapChain(ID3D11Device *device, DXGIFactory *factory, DXGI_FORMAT format, unsigned int width, unsigned int height, DXGISwapChain **swapChain) +HRESULT CoreWindowNativeWindow::createSwapChain(ID3D11Device *device, + DXGIFactory *factory, + DXGI_FORMAT format, + unsigned int width, + unsigned int height, + bool containsAlpha, + DXGISwapChain **swapChain) { if (device == NULL || factory == NULL || swapChain == NULL || width == 0 || height == 0) { @@ -116,10 +154,12 @@ HRESULT CoreWindowNativeWindow::createSwapChain(ID3D11Device *device, DXGIFactor swapChainDesc.Stereo = FALSE; swapChainDesc.SampleDesc.Count = 1; swapChainDesc.SampleDesc.Quality = 0; - swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT | DXGI_USAGE_BACK_BUFFER; + swapChainDesc.BufferUsage = + DXGI_USAGE_SHADER_INPUT | DXGI_USAGE_RENDER_TARGET_OUTPUT | DXGI_USAGE_BACK_BUFFER; swapChainDesc.BufferCount = 2; swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL; swapChainDesc.Scaling = DXGI_SCALING_STRETCH; + swapChainDesc.AlphaMode = DXGI_ALPHA_MODE_UNSPECIFIED; *swapChain = nullptr; @@ -154,13 +194,20 @@ HRESULT CoreWindowNativeWindow::createSwapChain(ID3D11Device *device, DXGIFactor return result; } -HRESULT GetCoreWindowSizeInPixels(const ComPtr& coreWindow, RECT *windowSize) +inline HRESULT CoreWindowNativeWindow::scaleSwapChain(const SIZE &windowSize, const RECT &clientRect) +{ + // We don't need to do any additional work to scale CoreWindow swapchains. + // Using DXGI_SCALING_STRETCH to create the swapchain above does all the necessary work. + return S_OK; +} + +HRESULT GetCoreWindowSizeInPixels(const ComPtr& coreWindow, SIZE *windowSize) { ABI::Windows::Foundation::Rect bounds; HRESULT result = coreWindow->get_Bounds(&bounds); if (SUCCEEDED(result)) { - *windowSize = { 0, 0, ConvertDipsToPixels(bounds.Width), ConvertDipsToPixels(bounds.Height) }; + *windowSize = { ConvertDipsToPixels(bounds.Width), ConvertDipsToPixels(bounds.Height) }; } return result; @@ -169,16 +216,18 @@ HRESULT GetCoreWindowSizeInPixels(const ComPtr displayProperties; - float dpi = 96.0f; if (SUCCEEDED(GetActivationFactory(HStringReference(RuntimeClass_Windows_Graphics_Display_DisplayProperties).Get(), displayProperties.GetAddressOf()))) { + float dpi = 96.0f; if (SUCCEEDED(displayProperties->get_LogicalDpi(&dpi))) { return dpi; } } - return dpi; + + // Return 96 dpi as a default if display properties cannot be obtained. + return 96.0f; } long ConvertDipsToPixels(float dips) diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow.h index c230c8418174..77470053fbe4 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow.h @@ -24,10 +24,20 @@ class CoreWindowNativeWindow : public InspectableNativeWindow, public std::enabl public: ~CoreWindowNativeWindow(); - bool initialize(EGLNativeWindowType window, IPropertySet *propertySet); + bool initialize(EGLNativeWindowType window, IPropertySet *propertySet) override; + HRESULT createSwapChain(ID3D11Device *device, + DXGIFactory *factory, + DXGI_FORMAT format, + unsigned int width, + unsigned int height, + bool containsAlpha, + DXGISwapChain **swapChain) override; + + protected: + HRESULT scaleSwapChain(const SIZE &windowSize, const RECT &clientRect) override; + bool registerForSizeChangeEvents(); void unregisterForSizeChangeEvents(); - HRESULT createSwapChain(ID3D11Device *device, DXGIFactory *factory, DXGI_FORMAT format, unsigned int width, unsigned int height, DXGISwapChain **swapChain); private: ComPtr mCoreWindow; @@ -72,7 +82,7 @@ class CoreWindowSizeChangedHandler : std::weak_ptr mHost; }; -HRESULT GetCoreWindowSizeInPixels(const ComPtr& coreWindow, RECT *windowSize); +HRESULT GetCoreWindowSizeInPixels(const ComPtr& coreWindow, SIZE *windowSize); } #endif // LIBANGLE_RENDERER_D3D_D3D11_WINRT_COREWINDOWNATIVEWINDOW_H_ diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow_unittest.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow_unittest.cpp index cc75cd11894d..6b5ae14c568d 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow_unittest.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow_unittest.cpp @@ -162,12 +162,35 @@ HRESULT CreatePropertyMap(IMap** propertyMap) return result; } +HRESULT CreatePropertyValueStatics(IPropertyValueStatics** propertyStatics) +{ + ComPtr propertyValueStatics; + HRESULT result = GetActivationFactory(HStringReference(RuntimeClass_Windows_Foundation_PropertyValue).Get(), &propertyValueStatics); + EXPECT_HRESULT_SUCCEEDED(result); + + result = propertyValueStatics.CopyTo(propertyStatics); + EXPECT_HRESULT_SUCCEEDED(result); + + return result; +} + HRESULT SetInspectablePropertyValue(const ComPtr>& propertyMap, const wchar_t* propertyName, IInspectable* inspectable) { boolean propertyReplaced = false; return propertyMap->Insert(HStringReference(propertyName).Get(), inspectable, &propertyReplaced); } +void expectNativeWindowInitCalls(MockCoreWindow &coreWindow, bool expectBounds) +{ + if (expectBounds) + { + EXPECT_CALL(coreWindow, get_Bounds(testing::_)).Times(1); + } + + EXPECT_CALL(coreWindow, add_SizeChanged(testing::_, testing::_)).Times(1); + EXPECT_CALL(coreWindow, remove_SizeChanged(testing::_)).Times(1); +} + TEST(NativeWindowTest, NativeWindowNull) { NativeWindow nativeWindow(nullptr); @@ -191,9 +214,7 @@ TEST(NativeWindowTest, NativeWindowNotInspectable) TEST(NativeWindowTest, NativeWindowValidCoreWindow) { MockCoreWindow mockCoreWindow; - EXPECT_CALL(mockCoreWindow, get_Bounds(testing::_)).Times(1); - EXPECT_CALL(mockCoreWindow, add_SizeChanged(testing::_, testing::_)).Times(1); - EXPECT_CALL(mockCoreWindow, remove_SizeChanged(testing::_)).Times(1); + expectNativeWindowInitCalls(mockCoreWindow, true); NativeWindow nativeWindow(&mockCoreWindow); EXPECT_TRUE(nativeWindow.initialize()); } @@ -205,11 +226,12 @@ TEST(NativeWindowTest, NativeWindowValidCoreWindowInPropertySet) { MockCoreWindow mockCoreWindow; ComPtr> propertySet; - EXPECT_CALL(mockCoreWindow, get_Bounds(testing::_)).Times(1); - EXPECT_CALL(mockCoreWindow, add_SizeChanged(testing::_, testing::_)).Times(1); - EXPECT_CALL(mockCoreWindow, remove_SizeChanged(testing::_)).Times(1); + + // Add the CoreWindow to the property set EXPECT_HRESULT_SUCCEEDED(CreatePropertyMap(&propertySet)); EXPECT_HRESULT_SUCCEEDED(SetInspectablePropertyValue(propertySet, EGLNativeWindowTypeProperty, &mockCoreWindow)); + + expectNativeWindowInitCalls(mockCoreWindow, true); NativeWindow nativeWindow(propertySet.Get()); EXPECT_TRUE(nativeWindow.initialize()); } @@ -223,11 +245,112 @@ TEST(NativeWindowTest, NativeWindowMissingCoreWindowInPropertySet) { MockCoreWindow mockCoreWindow; ComPtr> propertySet; + EXPECT_HRESULT_SUCCEEDED(CreatePropertyMap(&propertySet)); + NativeWindow nativeWindow(propertySet.Get()); EXPECT_FALSE(nativeWindow.initialize()); } CoUninitialize(); } +// Tests that the scale property works as expected in a property set with a SwapChainPanel +class CoreWindowScaleTest : public testing::TestWithParam> +{ +}; + +TEST_P(CoreWindowScaleTest, ValidateScale) +{ + float scale = GetParam().first; + bool expectedResult = GetParam().second; + + // COM is required to be initialized for creation of the property set + EXPECT_HRESULT_SUCCEEDED(CoInitializeEx(NULL, COINIT_MULTITHREADED)); + { + MockCoreWindow mockCoreWindow; + ComPtr> propertySet; + ComPtr propertyValueStatics; + ComPtr singleValue; + + // Create a simple property set + EXPECT_HRESULT_SUCCEEDED(CreatePropertyMap(&propertySet)); + EXPECT_HRESULT_SUCCEEDED(SetInspectablePropertyValue(propertySet, EGLNativeWindowTypeProperty, reinterpret_cast(&mockCoreWindow))); + + // Add a valid scale factor to the property set + EXPECT_HRESULT_SUCCEEDED(CreatePropertyValueStatics(propertyValueStatics.GetAddressOf())); + propertyValueStatics->CreateSingle(scale, reinterpret_cast(singleValue.GetAddressOf())); + EXPECT_HRESULT_SUCCEEDED(SetInspectablePropertyValue(propertySet, EGLRenderResolutionScaleProperty, reinterpret_cast(singleValue.Get()))); + + // Check native window init status and calls to the mock swapchainpanel + NativeWindow nativeWindow(propertySet.Get()); + if (expectedResult) + { + expectNativeWindowInitCalls(mockCoreWindow, true); + } + + EXPECT_EQ(nativeWindow.initialize(), expectedResult); + } + CoUninitialize(); +} + +typedef std::pair scaleValidPair; +static const scaleValidPair scales[] = { scaleValidPair(1.0f, true), + scaleValidPair(0.5f, true), + scaleValidPair(0.0f, false), + scaleValidPair(0.01f, true), + scaleValidPair(2.00f, true) }; + +INSTANTIATE_TEST_CASE_P(NativeWindowTest, + CoreWindowScaleTest, + testing::ValuesIn(scales)); + +// Tests that the size property works as expected in a property set with a SwapChainPanel +class CoreWindowSizeTest : public testing::TestWithParam> +{ +}; + +TEST_P(CoreWindowSizeTest, ValidateSize) +{ + Size renderSize = { std::get<0>(GetParam()), std::get<1>(GetParam()) }; + bool expectedResult = std::get<2>(GetParam()); + + // COM is required to be initialized for creation of the property set + EXPECT_HRESULT_SUCCEEDED(CoInitializeEx(NULL, COINIT_MULTITHREADED)); + { + MockCoreWindow mockCoreWindow; + ComPtr> propertySet; + ComPtr propertyValueStatics; + ComPtr sizeValue; + + // Create a simple property set + EXPECT_HRESULT_SUCCEEDED(CreatePropertyMap(&propertySet)); + EXPECT_HRESULT_SUCCEEDED(SetInspectablePropertyValue(propertySet, EGLNativeWindowTypeProperty, reinterpret_cast(&mockCoreWindow))); + + // Add a valid size to the property set + EXPECT_HRESULT_SUCCEEDED(CreatePropertyValueStatics(propertyValueStatics.GetAddressOf())); + propertyValueStatics->CreateSize(renderSize, reinterpret_cast(sizeValue.GetAddressOf())); + EXPECT_HRESULT_SUCCEEDED(SetInspectablePropertyValue(propertySet, EGLRenderSurfaceSizeProperty, reinterpret_cast(sizeValue.Get()))); + + // Check native window init status and calls to the mock swapchainpanel + NativeWindow nativeWindow(propertySet.Get()); + if (expectedResult) + { + expectNativeWindowInitCalls(mockCoreWindow, false); + } + + EXPECT_EQ(nativeWindow.initialize(), expectedResult); + } + CoUninitialize(); +} + +typedef std::tuple sizeValidPair; +static const sizeValidPair sizes[] = { sizeValidPair( 800, 480, true), + sizeValidPair( 0, 480, false), + sizeValidPair( 800, 0, false), + sizeValidPair( 0, 0, false) }; + +INSTANTIATE_TEST_CASE_P(NativeWindowTest, + CoreWindowSizeTest, + testing::ValuesIn(sizes)); + } // namespace diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/winrt/InspectableNativeWindow.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/winrt/InspectableNativeWindow.cpp index 7ac53c7b30de..47a6daed2d0b 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/winrt/InspectableNativeWindow.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/winrt/InspectableNativeWindow.cpp @@ -11,9 +11,20 @@ namespace rx { -NativeWindow::NativeWindow(EGLNativeWindowType window) +NativeWindow::NativeWindow(EGLNativeWindowType window, + const egl::Config *config, + bool directComposition) { mWindow = window; + mConfig = config; +} + +NativeWindow::~NativeWindow() +{ +} + +void NativeWindow::commitChange() +{ } bool NativeWindow::initialize() @@ -83,7 +94,9 @@ HRESULT NativeWindow::createSwapChain(ID3D11Device *device, DXGIFactory *factory { if (mImpl) { - return mImpl->createSwapChain(device, factory, format, width, height, swapChain); + bool containsAlpha = (mConfig->alphaSize > 0); + return mImpl->createSwapChain(device, factory, format, width, height, containsAlpha, + swapChain); } return E_UNEXPECTED; @@ -197,16 +210,47 @@ bool IsEGLConfiguredPropertySet(EGLNativeWindowType window, ABI::Windows::Founda // A Valid EGLNativeWindowType IInspectable can only be: // // ICoreWindow +// ISwapChainPanel // IPropertySet -// +// // Anything else will be rejected as an invalid IInspectable. bool IsValidEGLNativeWindowType(EGLNativeWindowType window) { return IsCoreWindow(window) || IsSwapChainPanel(window) || IsEGLConfiguredPropertySet(window); } +// Retrieve an optional property from a property set +HRESULT GetOptionalPropertyValue(const ComPtr> &propertyMap, + const wchar_t *propertyName, + boolean *hasKey, + ComPtr &propertyValue) +{ + if (!propertyMap || !hasKey) + { + return E_INVALIDARG; + } + + // Assume that the value does not exist + *hasKey = false; + + HRESULT result = propertyMap->HasKey(HStringReference(propertyName).Get(), hasKey); + if (SUCCEEDED(result) && !(*hasKey)) + { + // Value does not exist, so return S_OK and set the exists parameter to false to indicate + // that a the optional property does not exist. + return S_OK; + } + + if (SUCCEEDED(result)) + { + result = propertyMap->Lookup(HStringReference(propertyName).Get(), &propertyValue); + } + + return result; +} + // Attempts to read an optional SIZE property value that is assumed to be in the form of -// an ABI::Windows::Foundation::Size. This function validates the Size value before returning +// an ABI::Windows::Foundation::Size. This function validates the Size value before returning // it to the caller. // // Possible return values are: @@ -217,63 +261,112 @@ bool IsValidEGLNativeWindowType(EGLNativeWindowType window) // * Invalid property value (width/height must be > 0) // Additional errors may be returned from IMap or IPropertyValue // -HRESULT GetOptionalSizePropertyValue(const ComPtr>& propertyMap, const wchar_t *propertyName, SIZE *value, bool *valueExists) +HRESULT GetOptionalSizePropertyValue(const ComPtr> &propertyMap, + const wchar_t *propertyName, SIZE *value, bool *valueExists) { - if (!propertyMap || !propertyName || !value || !valueExists) + ComPtr propertyValue; + ABI::Windows::Foundation::PropertyType propertyType = ABI::Windows::Foundation::PropertyType::PropertyType_Empty; + Size sizeValue = { 0, 0 }; + boolean hasKey = false; + + if (!propertyMap || !value || !valueExists) { - return false; + return E_INVALIDARG; } // Assume that the value does not exist *valueExists = false; *value = { 0, 0 }; + HRESULT result = GetOptionalPropertyValue(propertyMap, propertyName, &hasKey, propertyValue); + if (SUCCEEDED(result) && hasKey) + { + result = propertyValue->get_Type(&propertyType); + + // Check if the expected Size property is of PropertyType_Size type. + if (SUCCEEDED(result) && propertyType == ABI::Windows::Foundation::PropertyType::PropertyType_Size) + { + if (SUCCEEDED(propertyValue->GetSize(&sizeValue)) && (sizeValue.Width > 0 && sizeValue.Height > 0)) + { + // A valid property value exists + *value = { static_cast(sizeValue.Width), static_cast(sizeValue.Height) }; + *valueExists = true; + result = S_OK; + } + else + { + // An invalid Size property was detected. Width/Height values must > 0 + result = E_INVALIDARG; + } + } + else + { + // An invalid property type was detected. Size property must be of PropertyType_Size + result = E_INVALIDARG; + } + } + + return result; +} + +// Attempts to read an optional float property value that is assumed to be in the form of +// an ABI::Windows::Foundation::Single. This function validates the Single value before returning +// it to the caller. +// +// Possible return values are: +// S_OK, valueExists == true - optional Single value was successfully retrieved and validated +// S_OK, valueExists == false - optional Single value was not found +// E_INVALIDARG, valueExists = false - optional Single value was malformed in the property set. +// * Incorrect property type ( must be PropertyType_Single) +// * Invalid property value (must be > 0) +// Additional errors may be returned from IMap or IPropertyValue +// +HRESULT GetOptionalSinglePropertyValue(const ComPtr> &propertyMap, + const wchar_t *propertyName, float *value, bool *valueExists) +{ ComPtr propertyValue; ABI::Windows::Foundation::PropertyType propertyType = ABI::Windows::Foundation::PropertyType::PropertyType_Empty; - Size sizeValue = { 0, 0 }; + float scaleValue = 0.0f; boolean hasKey = false; - HRESULT result = propertyMap->HasKey(HStringReference(propertyName).Get(), &hasKey); - if (SUCCEEDED(result) && !hasKey) + if (!propertyMap || !value || !valueExists) { - // Value does not exist, so return S_OK and set the exists parameter to false to indicate - // that a the optional property does not exist. - *valueExists = false; - return S_OK; + return E_INVALIDARG; } - if (SUCCEEDED(result)) - { - result = propertyMap->Lookup(HStringReference(propertyName).Get(), &propertyValue); - } + // Assume that the value does not exist + *valueExists = false; + *value = 0.0f; - if (SUCCEEDED(result)) + HRESULT result = GetOptionalPropertyValue(propertyMap, propertyName, &hasKey, propertyValue); + if (SUCCEEDED(result) && hasKey) { result = propertyValue->get_Type(&propertyType); - } - // Check if the expected Size property is of PropertyType_Size type. - if (SUCCEEDED(result) && propertyType == ABI::Windows::Foundation::PropertyType::PropertyType_Size) - { - if (SUCCEEDED(propertyValue->GetSize(&sizeValue)) && (sizeValue.Width > 0 && sizeValue.Height > 0)) + // Check if the expected Scale property is of PropertyType_Single type. + if (SUCCEEDED(result) && propertyType == ABI::Windows::Foundation::PropertyType::PropertyType_Single) { - // A valid property value exists - *value = { static_cast(sizeValue.Width), static_cast(sizeValue.Height) }; - *valueExists = true; - result = S_OK; + if (SUCCEEDED(propertyValue->GetSingle(&scaleValue)) && (scaleValue > 0.0f)) + { + // A valid property value exists + *value = scaleValue; + *valueExists = true; + result = S_OK; + } + else + { + // An invalid scale was set + result = E_INVALIDARG; + } } else { - // An invalid Size property was detected. Width/Height values must > 0 + // An invalid property type was detected. Size property must be of PropertyType_Single result = E_INVALIDARG; } } - else - { - // An invalid property type was detected. Size property must be of PropertyType_Size - result = E_INVALIDARG; - } return result; } + } diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/winrt/InspectableNativeWindow.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/winrt/InspectableNativeWindow.h index e89c9000a354..4b9cf802aec6 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/winrt/InspectableNativeWindow.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/winrt/InspectableNativeWindow.h @@ -31,7 +31,9 @@ class InspectableNativeWindow public: InspectableNativeWindow() : mSupportsSwapChainResize(true), - mRequiresSwapChainScaling(false), + mSwapChainSizeSpecified(false), + mSwapChainScaleSpecified(false), + mSwapChainScale(1.0f), mClientRectChanged(false), mClientRect({0,0,0,0}), mNewClientRect({0,0,0,0}) @@ -41,14 +43,17 @@ class InspectableNativeWindow virtual ~InspectableNativeWindow(){} virtual bool initialize(EGLNativeWindowType window, IPropertySet *propertySet) = 0; - virtual HRESULT createSwapChain(ID3D11Device *device, DXGIFactory *factory, DXGI_FORMAT format, unsigned int width, unsigned int height, DXGISwapChain **swapChain) = 0; - virtual bool registerForSizeChangeEvents() = 0; - virtual void unregisterForSizeChangeEvents() = 0; - virtual HRESULT scaleSwapChain(const SIZE& newSize) { return S_OK; } + virtual HRESULT createSwapChain(ID3D11Device *device, + DXGIFactory *factory, + DXGI_FORMAT format, + unsigned int width, + unsigned int height, + bool containsAlpha, + DXGISwapChain **swapChain) = 0; bool getClientRect(RECT *rect) { - if (mClientRectChanged && mSupportsSwapChainResize) + if (mClientRectChanged) { mClientRect = mNewClientRect; } @@ -58,23 +63,44 @@ class InspectableNativeWindow return true; } - void setNewClientSize(const SIZE &newSize) + // setNewClientSize is used by the WinRT size change handler. It isn't used by the rest of ANGLE. + void setNewClientSize(const SIZE &newWindowSize) { - if (mSupportsSwapChainResize && !mRequiresSwapChainScaling) - { - mNewClientRect = { 0, 0, newSize.cx, newSize.cy }; - mClientRectChanged = true; - } + // If the client doesn't support swapchain resizing then we should have already unregistered from size change handler + ASSERT(mSupportsSwapChainResize); - if (mRequiresSwapChainScaling) + if (mSupportsSwapChainResize) { - scaleSwapChain(newSize); + // If the swapchain size was specified then we should ignore this call too + if (!mSwapChainSizeSpecified) + { + // We don't have to check if a swapchain scale was specified here; the default value is 1.0f which will have no effect. + mNewClientRect = { 0, 0, static_cast(newWindowSize.cx * mSwapChainScale), static_cast(newWindowSize.cy * mSwapChainScale) }; + mClientRectChanged = true; + + // If a scale was specified, then now is the time to apply the scale matrix for the new swapchain size and window size + if (mSwapChainScaleSpecified) + { + scaleSwapChain(newWindowSize, mNewClientRect); + } + } + + // Even if the swapchain size was fixed, the window might have changed size. + // In this case, we should recalculate the scale matrix to account for the new window size + if (mSwapChainSizeSpecified) + { + scaleSwapChain(newWindowSize, mClientRect); + } } } -protected: - bool mSupportsSwapChainResize; - bool mRequiresSwapChainScaling; + protected: + virtual HRESULT scaleSwapChain(const SIZE &windowSize, const RECT &clientRect) = 0; + + bool mSupportsSwapChainResize; // Support for IDXGISwapChain::ResizeBuffers method + bool mSwapChainSizeSpecified; // If an EGLRenderSurfaceSizeProperty was specified + bool mSwapChainScaleSpecified; // If an EGLRenderResolutionScaleProperty was specified + float mSwapChainScale; // The scale value specified by the EGLRenderResolutionScaleProperty property RECT mClientRect; RECT mNewClientRect; bool mClientRectChanged; @@ -86,8 +112,17 @@ bool IsValidEGLNativeWindowType(EGLNativeWindowType window); bool IsCoreWindow(EGLNativeWindowType window, ComPtr *coreWindow = nullptr); bool IsSwapChainPanel(EGLNativeWindowType window, ComPtr *swapChainPanel = nullptr); bool IsEGLConfiguredPropertySet(EGLNativeWindowType window, ABI::Windows::Foundation::Collections::IPropertySet **propertySet = nullptr, IInspectable **inspectable = nullptr); -HRESULT GetOptionalSizePropertyValue(const ComPtr>& propertyMap, const wchar_t *propertyName, SIZE *value, bool *valueExists); +HRESULT GetOptionalPropertyValue(const ComPtr> &propertyMap, + const wchar_t *propertyName, + boolean *hasKey, + ComPtr &propertyValue); + +HRESULT GetOptionalSizePropertyValue(const ComPtr> &propertyMap, + const wchar_t *propertyName, SIZE *value, bool *valueExists); + +HRESULT GetOptionalSinglePropertyValue(const ComPtr> &propertyMap, + const wchar_t *propertyName, float *value, bool *valueExists); } #endif // LIBANGLE_RENDERER_D3D_D3D11_WINRT_INSPECTABLENATIVEWINDOW_H_ diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/winrt/SwapChainPanelNativeWindow.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/winrt/SwapChainPanelNativeWindow.cpp index 53899dbb30b1..1ed3645b9c96 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/winrt/SwapChainPanelNativeWindow.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/winrt/SwapChainPanelNativeWindow.cpp @@ -11,7 +11,11 @@ #include #include +using namespace ABI::Windows::Foundation; using namespace ABI::Windows::Foundation::Collections; +using namespace ABI::Windows::UI::Core; +using namespace ABI::Windows::UI::Xaml; +using namespace Microsoft::WRL; namespace rx { @@ -20,12 +24,74 @@ SwapChainPanelNativeWindow::~SwapChainPanelNativeWindow() unregisterForSizeChangeEvents(); } +template +struct AddFtmBase +{ + typedef Implements, T, FtmBase> Type; +}; + +template +HRESULT RunOnUIThread(CODE &&code, const ComPtr &dispatcher) +{ + ComPtr asyncAction; + HRESULT result = S_OK; + + boolean hasThreadAccess; + result = dispatcher->get_HasThreadAccess(&hasThreadAccess); + if (FAILED(result)) + { + return result; + } + + if (hasThreadAccess) + { + return code(); + } + else + { + Event waitEvent(CreateEventEx(NULL, NULL, CREATE_EVENT_MANUAL_RESET, EVENT_ALL_ACCESS)); + if (!waitEvent.IsValid()) + { + return E_FAIL; + } + + HRESULT codeResult = E_FAIL; + auto handler = + Callback::Type>([&codeResult, &code, &waitEvent] + { + codeResult = code(); + SetEvent(waitEvent.Get()); + return S_OK; + }); + + result = dispatcher->RunAsync(CoreDispatcherPriority_Normal, handler.Get(), + asyncAction.GetAddressOf()); + if (FAILED(result)) + { + return result; + } + + auto waitResult = WaitForSingleObjectEx(waitEvent.Get(), 10 * 1000, true); + if (waitResult != WAIT_OBJECT_0) + { + // Wait 10 seconds before giving up. At this point, the application is in an + // unrecoverable state (probably deadlocked). We therefore terminate the application + // entirely. This also prevents stack corruption if the async operation is eventually + // run. + ERR("Timeout waiting for async action on UI thread. The UI thread might be blocked."); + std::terminate(); + return E_FAIL; + } + + return codeResult; + } +} + bool SwapChainPanelNativeWindow::initialize(EGLNativeWindowType window, IPropertySet *propertySet) { ComPtr props = propertySet; ComPtr win = window; SIZE swapChainSize = {}; - bool swapChainSizeSpecified = false; HRESULT result = S_OK; // IPropertySet is an optional parameter and can be null. @@ -34,12 +100,40 @@ bool SwapChainPanelNativeWindow::initialize(EGLNativeWindowType window, IPropert if (propertySet) { result = props.As(&mPropertyMap); - if (SUCCEEDED(result)) + if (FAILED(result)) + { + return false; + } + + // The EGLRenderSurfaceSizeProperty is optional and may be missing. The IPropertySet + // was prevalidated to contain the EGLNativeWindowType before being passed to + // this host. + result = GetOptionalSizePropertyValue(mPropertyMap, EGLRenderSurfaceSizeProperty, &swapChainSize, &mSwapChainSizeSpecified); + if (FAILED(result)) { - // The EGLRenderSurfaceSizeProperty is optional and may be missing. The IPropertySet - // was prevalidated to contain the EGLNativeWindowType before being passed to - // this host. - result = GetOptionalSizePropertyValue(mPropertyMap, EGLRenderSurfaceSizeProperty, &swapChainSize, &swapChainSizeSpecified); + return false; + } + + // The EGLRenderResolutionScaleProperty is optional and may be missing. The IPropertySet + // was prevalidated to contain the EGLNativeWindowType before being passed to + // this host. + result = GetOptionalSinglePropertyValue(mPropertyMap, EGLRenderResolutionScaleProperty, &mSwapChainScale, &mSwapChainScaleSpecified); + if (FAILED(result)) + { + return false; + } + + if (!mSwapChainScaleSpecified) + { + // Default value for the scale is 1.0f + mSwapChainScale = 1.0f; + } + + // A EGLRenderSurfaceSizeProperty and a EGLRenderResolutionScaleProperty can't both be specified + if (mSwapChainScaleSpecified && mSwapChainSizeSpecified) + { + ERR("It is invalid to specify both an EGLRenderSurfaceSizeProperty and a EGLRenderResolutionScaleProperty."); + return false; } } @@ -48,6 +142,18 @@ bool SwapChainPanelNativeWindow::initialize(EGLNativeWindowType window, IPropert result = win.As(&mSwapChainPanel); } + ComPtr swapChainPanelDependencyObject; + if (SUCCEEDED(result)) + { + result = mSwapChainPanel.As(&swapChainPanelDependencyObject); + } + + if (SUCCEEDED(result)) + { + result = swapChainPanelDependencyObject->get_Dispatcher( + mSwapChainPanelDispatcher.GetAddressOf()); + } + if (SUCCEEDED(result)) { // If a swapchain size is specfied, then the automatic resize @@ -57,16 +163,21 @@ bool SwapChainPanelNativeWindow::initialize(EGLNativeWindowType window, IPropert // Scaling of the swapchain output needs to be handled by the // host for swapchain panels even though the scaling mode setting // DXGI_SCALING_STRETCH is configured on the swapchain. - if (swapChainSizeSpecified) + if (mSwapChainSizeSpecified) { mClientRect = { 0, 0, swapChainSize.cx, swapChainSize.cy }; - - // Enable host swapchain scaling - mRequiresSwapChainScaling = true; } else { - result = GetSwapChainPanelSize(mSwapChainPanel, &mClientRect); + SIZE swapChainPanelSize; + result = GetSwapChainPanelSize(mSwapChainPanel, mSwapChainPanelDispatcher, + &swapChainPanelSize); + + if (SUCCEEDED(result)) + { + // Update the client rect to account for any swapchain scale factor + mClientRect = { 0, 0, static_cast(swapChainPanelSize.cx * mSwapChainScale), static_cast(swapChainPanelSize.cy * mSwapChainScale) }; + } } } @@ -82,8 +193,8 @@ bool SwapChainPanelNativeWindow::initialize(EGLNativeWindowType window, IPropert bool SwapChainPanelNativeWindow::registerForSizeChangeEvents() { - ComPtr sizeChangedHandler; - ComPtr frameworkElement; + ComPtr sizeChangedHandler; + ComPtr frameworkElement; HRESULT result = Microsoft::WRL::MakeAndInitialize(sizeChangedHandler.ReleaseAndGetAddressOf(), this->shared_from_this()); if (SUCCEEDED(result)) @@ -93,7 +204,13 @@ bool SwapChainPanelNativeWindow::registerForSizeChangeEvents() if (SUCCEEDED(result)) { - result = frameworkElement->add_SizeChanged(sizeChangedHandler.Get(), &mSizeChangedEventToken); + result = RunOnUIThread( + [this, frameworkElement, sizeChangedHandler] + { + return frameworkElement->add_SizeChanged(sizeChangedHandler.Get(), + &mSizeChangedEventToken); + }, + mSwapChainPanelDispatcher); } if (SUCCEEDED(result)) @@ -106,16 +223,27 @@ bool SwapChainPanelNativeWindow::registerForSizeChangeEvents() void SwapChainPanelNativeWindow::unregisterForSizeChangeEvents() { - ComPtr frameworkElement; - if (SUCCEEDED(mSwapChainPanel.As(&frameworkElement))) + ComPtr frameworkElement; + if (mSwapChainPanel && SUCCEEDED(mSwapChainPanel.As(&frameworkElement))) { - (void)frameworkElement->remove_SizeChanged(mSizeChangedEventToken); + RunOnUIThread( + [this, frameworkElement] + { + return frameworkElement->remove_SizeChanged(mSizeChangedEventToken); + }, + mSwapChainPanelDispatcher); } mSizeChangedEventToken.value = 0; } -HRESULT SwapChainPanelNativeWindow::createSwapChain(ID3D11Device *device, DXGIFactory *factory, DXGI_FORMAT format, unsigned int width, unsigned int height, DXGISwapChain **swapChain) +HRESULT SwapChainPanelNativeWindow::createSwapChain(ID3D11Device *device, + DXGIFactory *factory, + DXGI_FORMAT format, + unsigned int width, + unsigned int height, + bool containsAlpha, + DXGISwapChain **swapChain) { if (device == NULL || factory == NULL || swapChain == NULL || width == 0 || height == 0) { @@ -129,17 +257,19 @@ HRESULT SwapChainPanelNativeWindow::createSwapChain(ID3D11Device *device, DXGIFa swapChainDesc.Stereo = FALSE; swapChainDesc.SampleDesc.Count = 1; swapChainDesc.SampleDesc.Quality = 0; - swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT | DXGI_USAGE_BACK_BUFFER; + swapChainDesc.BufferUsage = + DXGI_USAGE_SHADER_INPUT | DXGI_USAGE_RENDER_TARGET_OUTPUT | DXGI_USAGE_BACK_BUFFER; swapChainDesc.BufferCount = 2; swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL; swapChainDesc.Scaling = DXGI_SCALING_STRETCH; - swapChainDesc.AlphaMode = DXGI_ALPHA_MODE_IGNORE; + swapChainDesc.AlphaMode = + containsAlpha ? DXGI_ALPHA_MODE_PREMULTIPLIED : DXGI_ALPHA_MODE_IGNORE; *swapChain = nullptr; ComPtr newSwapChain; ComPtr swapChainPanelNative; - RECT currentPanelSize = {}; + SIZE currentPanelSize = {}; HRESULT result = factory->CreateSwapChainForComposition(device, &swapChainDesc, nullptr, newSwapChain.ReleaseAndGetAddressOf()); @@ -150,7 +280,12 @@ HRESULT SwapChainPanelNativeWindow::createSwapChain(ID3D11Device *device, DXGIFa if (SUCCEEDED(result)) { - result = swapChainPanelNative->SetSwapChain(newSwapChain.Get()); + result = RunOnUIThread( + [swapChainPanelNative, newSwapChain] + { + return swapChainPanelNative->SetSwapChain(newSwapChain.Get()); + }, + mSwapChainPanelDispatcher); } if (SUCCEEDED(result)) @@ -165,34 +300,28 @@ HRESULT SwapChainPanelNativeWindow::createSwapChain(ID3D11Device *device, DXGIFa // If the host is responsible for scaling the output of the swapchain, then // scale it now before returning an instance to the caller. This is done by // first reading the current size of the swapchain panel, then scaling - if (SUCCEEDED(result) && mRequiresSwapChainScaling) - { - result = GetSwapChainPanelSize(mSwapChainPanel, ¤tPanelSize); - } - - // Scale the swapchain to fit inside the contents of the panel. - if (SUCCEEDED(result) && mRequiresSwapChainScaling) - { - SIZE currentSize = { currentPanelSize.right, currentPanelSize.bottom }; - result = scaleSwapChain(currentSize); - } - if (SUCCEEDED(result)) { - // If automatic swapchain resize behaviors have been disabled, then - // unregister for the resize change events. - if (mSupportsSwapChainResize == false) + if (mSwapChainSizeSpecified || mSwapChainScaleSpecified) { - unregisterForSizeChangeEvents(); + result = GetSwapChainPanelSize(mSwapChainPanel, mSwapChainPanelDispatcher, + ¤tPanelSize); + + // Scale the swapchain to fit inside the contents of the panel. + if (SUCCEEDED(result)) + { + result = scaleSwapChain(currentPanelSize, mClientRect); + } } } return result; } -HRESULT SwapChainPanelNativeWindow::scaleSwapChain(const SIZE &newSize) +HRESULT SwapChainPanelNativeWindow::scaleSwapChain(const SIZE &windowSize, const RECT &clientRect) { - ABI::Windows::Foundation::Size renderScale = { (float)newSize.cx/(float)mClientRect.right, (float)newSize.cy/(float)mClientRect.bottom }; + Size renderScale = {(float)windowSize.cx / (float)clientRect.right, + (float)windowSize.cy / (float)clientRect.bottom}; // Setup a scale matrix for the swap chain DXGI_MATRIX_3X2_F scaleMatrix = {}; scaleMatrix._11 = renderScale.Width; @@ -208,21 +337,29 @@ HRESULT SwapChainPanelNativeWindow::scaleSwapChain(const SIZE &newSize) return result; } -HRESULT GetSwapChainPanelSize(const ComPtr &swapChainPanel, RECT *windowSize) +HRESULT GetSwapChainPanelSize( + const ComPtr &swapChainPanel, + const ComPtr &dispatcher, + SIZE *windowSize) { - ComPtr uiElement; - ABI::Windows::Foundation::Size renderSize = { 0, 0 }; + ComPtr uiElement; + Size renderSize = {0, 0}; HRESULT result = swapChainPanel.As(&uiElement); if (SUCCEEDED(result)) { - result = uiElement->get_RenderSize(&renderSize); + result = RunOnUIThread( + [uiElement, &renderSize] + { + return uiElement->get_RenderSize(&renderSize); + }, + dispatcher); } if (SUCCEEDED(result)) { - *windowSize = { 0, 0, lround(renderSize.Width), lround(renderSize.Height) }; + *windowSize = { lround(renderSize.Width), lround(renderSize.Height) }; } return result; } -} +} \ No newline at end of file diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/winrt/SwapChainPanelNativeWindow.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/winrt/SwapChainPanelNativeWindow.h index caf327d9131e..9cc051d1f452 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/winrt/SwapChainPanelNativeWindow.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/winrt/SwapChainPanelNativeWindow.h @@ -18,14 +18,24 @@ class SwapChainPanelNativeWindow : public InspectableNativeWindow, public std::e public: ~SwapChainPanelNativeWindow(); - bool initialize(EGLNativeWindowType window, IPropertySet *propertySet); + bool initialize(EGLNativeWindowType window, IPropertySet *propertySet) override; + HRESULT createSwapChain(ID3D11Device *device, + DXGIFactory *factory, + DXGI_FORMAT format, + unsigned int width, + unsigned int height, + bool containsAlpha, + DXGISwapChain **swapChain) override; + + protected: + HRESULT scaleSwapChain(const SIZE &windowSize, const RECT &clientRect) override; + bool registerForSizeChangeEvents(); void unregisterForSizeChangeEvents(); - HRESULT createSwapChain(ID3D11Device *device, DXGIFactory *factory, DXGI_FORMAT format, unsigned int width, unsigned int height, DXGISwapChain **swapChain); - HRESULT scaleSwapChain(const SIZE &newSize); private: ComPtr mSwapChainPanel; + ComPtr mSwapChainPanelDispatcher; ComPtr> mPropertyMap; ComPtr mSwapChain; }; @@ -74,6 +84,9 @@ class SwapChainPanelSizeChangedHandler : std::weak_ptr mHost; }; -HRESULT GetSwapChainPanelSize(const ComPtr &swapChainPanel, RECT *windowSize); +HRESULT GetSwapChainPanelSize( + const ComPtr &swapChainPanel, + const ComPtr &dispatcher, + SIZE *windowSize); } #endif // LIBANGLE_RENDERER_D3D_D3D11_WINRT_SWAPCHAINPANELNATIVEWINDOW_H_ diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/winrt/SwapChainPanelNativeWindow_unittest.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/winrt/SwapChainPanelNativeWindow_unittest.cpp index a3a7a498e0fe..026c424495e5 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/winrt/SwapChainPanelNativeWindow_unittest.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/winrt/SwapChainPanelNativeWindow_unittest.cpp @@ -269,38 +269,192 @@ HRESULT CreatePropertyMap(IMap** propertyMap) return result; } +HRESULT CreatePropertyValueStatics(IPropertyValueStatics** propertyStatics) +{ + ComPtr propertyValueStatics; + HRESULT result = GetActivationFactory(HStringReference(RuntimeClass_Windows_Foundation_PropertyValue).Get(), &propertyValueStatics); + EXPECT_HRESULT_SUCCEEDED(result); + + result = propertyValueStatics.CopyTo(propertyStatics); + EXPECT_HRESULT_SUCCEEDED(result); + + return result; +} + HRESULT SetInspectablePropertyValue(const ComPtr>& propertyMap, const wchar_t* propertyName, IInspectable* inspectable) { boolean propertyReplaced = false; return propertyMap->Insert(HStringReference(propertyName).Get(), inspectable, &propertyReplaced); } -TEST(NativeWindowTest, NativeWindowValidSwapChainPanel) +void expectNativeWindowInitCalls(MockSwapChainPanel &panel, bool expectRenderSize) +{ + if (expectRenderSize) + { + EXPECT_CALL(panel, get_RenderSize(testing::_)).Times(1); + } + + EXPECT_CALL(panel, add_SizeChanged(testing::_, testing::_)).Times(1); + EXPECT_CALL(panel, remove_SizeChanged(testing::_)).Times(1); +} + +TEST(NativeWindowTest, SwapChainPanelByItself) { MockSwapChainPanel mockSwapChainPanel; NativeWindow nativeWindow(reinterpret_cast(&mockSwapChainPanel)); - EXPECT_CALL(mockSwapChainPanel, get_RenderSize(testing::_)).Times(1); - EXPECT_CALL(mockSwapChainPanel, add_SizeChanged(testing::_, testing::_)).Times(1); - EXPECT_CALL(mockSwapChainPanel, remove_SizeChanged(testing::_)).Times(1); + expectNativeWindowInitCalls(mockSwapChainPanel, true); EXPECT_TRUE(nativeWindow.initialize()); } -TEST(NativeWindowTest, NativeWindowValidSwapChainPanelInPropertySet) +TEST(NativeWindowTest, SwapChainPanelInPropertySet) { // COM is required to be initialized for creation of the property set EXPECT_HRESULT_SUCCEEDED(CoInitializeEx(NULL, COINIT_MULTITHREADED)); { MockSwapChainPanel mockSwapChainPanel; ComPtr> propertySet; + + // Create a simple property set with the swapchainpanel EXPECT_HRESULT_SUCCEEDED(CreatePropertyMap(&propertySet)); EXPECT_HRESULT_SUCCEEDED(SetInspectablePropertyValue(propertySet, EGLNativeWindowTypeProperty, reinterpret_cast(&mockSwapChainPanel))); + + // Check native window init calls NativeWindow nativeWindow(propertySet.Get()); - EXPECT_CALL(mockSwapChainPanel, get_RenderSize(testing::_)).Times(1); - EXPECT_CALL(mockSwapChainPanel, add_SizeChanged(testing::_, testing::_)).Times(1); - EXPECT_CALL(mockSwapChainPanel, remove_SizeChanged(testing::_)).Times(1); + expectNativeWindowInitCalls(mockSwapChainPanel, true); EXPECT_TRUE(nativeWindow.initialize()); } CoUninitialize(); } +TEST(NativeWindowTest, SwapChainPanelInPropertySetWithSizeAndScale) +{ + // COM is required to be initialized for creation of the property set + EXPECT_HRESULT_SUCCEEDED(CoInitializeEx(NULL, COINIT_MULTITHREADED)); + { + MockSwapChainPanel mockSwapChainPanel; + ComPtr> propertySet; + ComPtr propertyValueStatics; + ComPtr singleValue; + ComPtr sizeValue; + + // Create a simple property set with the swapchainpanel + EXPECT_HRESULT_SUCCEEDED(CreatePropertyMap(&propertySet)); + EXPECT_HRESULT_SUCCEEDED(SetInspectablePropertyValue(propertySet, EGLNativeWindowTypeProperty, reinterpret_cast(&mockSwapChainPanel))); + + // Add a valid scale factor to the property set + EXPECT_HRESULT_SUCCEEDED(CreatePropertyValueStatics(propertyValueStatics.GetAddressOf())); + propertyValueStatics->CreateSingle(0.5f, reinterpret_cast(singleValue.GetAddressOf())); + EXPECT_HRESULT_SUCCEEDED(SetInspectablePropertyValue(propertySet, EGLRenderResolutionScaleProperty, reinterpret_cast(singleValue.Get()))); + + // Add a valid size to the property set + EXPECT_HRESULT_SUCCEEDED(CreatePropertyValueStatics(propertyValueStatics.GetAddressOf())); + propertyValueStatics->CreateSize({ 480, 800 }, reinterpret_cast(sizeValue.GetAddressOf())); + EXPECT_HRESULT_SUCCEEDED(SetInspectablePropertyValue(propertySet, EGLRenderSurfaceSizeProperty, reinterpret_cast(sizeValue.Get()))); + + // Check native window init fails, since we shouldn't be able to set a size and a scale together + NativeWindow nativeWindow(propertySet.Get()); + EXPECT_FALSE(nativeWindow.initialize()); + } + CoUninitialize(); +} + +// Tests that the scale property works as expected in a property set with a SwapChainPanel +class SwapChainPanelScaleTest : public testing::TestWithParam> +{ +}; + +TEST_P(SwapChainPanelScaleTest, ValidateScale) +{ + float scale = GetParam().first; + bool expectedResult = GetParam().second; + + // COM is required to be initialized for creation of the property set + EXPECT_HRESULT_SUCCEEDED(CoInitializeEx(NULL, COINIT_MULTITHREADED)); + { + MockSwapChainPanel mockSwapChainPanel; + ComPtr> propertySet; + ComPtr propertyValueStatics; + ComPtr singleValue; + + // Create a simple property set + EXPECT_HRESULT_SUCCEEDED(CreatePropertyMap(&propertySet)); + EXPECT_HRESULT_SUCCEEDED(SetInspectablePropertyValue(propertySet, EGLNativeWindowTypeProperty, reinterpret_cast(&mockSwapChainPanel))); + + // Add a valid scale factor to the property set + EXPECT_HRESULT_SUCCEEDED(CreatePropertyValueStatics(propertyValueStatics.GetAddressOf())); + propertyValueStatics->CreateSingle(scale, reinterpret_cast(singleValue.GetAddressOf())); + EXPECT_HRESULT_SUCCEEDED(SetInspectablePropertyValue(propertySet, EGLRenderResolutionScaleProperty, reinterpret_cast(singleValue.Get()))); + + // Check native window init status and calls to the mock swapchainpanel + NativeWindow nativeWindow(propertySet.Get()); + if (expectedResult) + { + expectNativeWindowInitCalls(mockSwapChainPanel, true); + } + + EXPECT_EQ(nativeWindow.initialize(), expectedResult); + } + CoUninitialize(); +} + +typedef std::pair scaleValidPair; +static const scaleValidPair scales[] = { scaleValidPair(1.0f, true), + scaleValidPair(0.5f, true), + scaleValidPair(0.0f, false), + scaleValidPair(0.01f, true), + scaleValidPair(2.00f, true) }; + +INSTANTIATE_TEST_CASE_P(NativeWindowTest, + SwapChainPanelScaleTest, + testing::ValuesIn(scales)); + +// Tests that the size property works as expected in a property set with a SwapChainPanel +class SwapChainPanelSizeTest : public testing::TestWithParam> +{ +}; + +TEST_P(SwapChainPanelSizeTest, ValidateSize) +{ + Size renderSize = { std::get<0>(GetParam()), std::get<1>(GetParam()) }; + bool expectedResult = std::get<2>(GetParam()); + + // COM is required to be initialized for creation of the property set + EXPECT_HRESULT_SUCCEEDED(CoInitializeEx(NULL, COINIT_MULTITHREADED)); + { + MockSwapChainPanel mockSwapChainPanel; + ComPtr> propertySet; + ComPtr propertyValueStatics; + ComPtr sizeValue; + + // Create a simple property set + EXPECT_HRESULT_SUCCEEDED(CreatePropertyMap(&propertySet)); + EXPECT_HRESULT_SUCCEEDED(SetInspectablePropertyValue(propertySet, EGLNativeWindowTypeProperty, reinterpret_cast(&mockSwapChainPanel))); + + // Add a valid size to the property set + EXPECT_HRESULT_SUCCEEDED(CreatePropertyValueStatics(propertyValueStatics.GetAddressOf())); + propertyValueStatics->CreateSize(renderSize, reinterpret_cast(sizeValue.GetAddressOf())); + EXPECT_HRESULT_SUCCEEDED(SetInspectablePropertyValue(propertySet, EGLRenderSurfaceSizeProperty, reinterpret_cast(sizeValue.Get()))); + + // Check native window init status and calls to the mock swapchainpanel + NativeWindow nativeWindow(propertySet.Get()); + if (expectedResult) + { + expectNativeWindowInitCalls(mockSwapChainPanel, false); + } + + EXPECT_EQ(nativeWindow.initialize(), expectedResult); + } + CoUninitialize(); +} + +typedef std::tuple sizeValidPair; +static const sizeValidPair sizes[] = { sizeValidPair( 800, 480, true), + sizeValidPair( 0, 480, false), + sizeValidPair( 800, 0, false), + sizeValidPair( 0, 0, false) }; + +INSTANTIATE_TEST_CASE_P(NativeWindowTest, + SwapChainPanelSizeTest, + testing::ValuesIn(sizes)); + } // namespace diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/Blit9.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/Blit9.cpp index 80eaa09aa0b1..2ac8ee3a29ca 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/Blit9.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/Blit9.cpp @@ -135,7 +135,7 @@ gl::Error Blit9::setShader(ShaderId source, const char *profile, { IDirect3DDevice9 *device = mRenderer->getDevice(); - D3DShaderType *shader; + D3DShaderType *shader = nullptr; if (mCompiledShaders[source] != NULL) { @@ -251,10 +251,11 @@ gl::Error Blit9::copy2D(const gl::Framebuffer *framebuffer, const RECT &sourceRe ASSERT(source); IDirect3DSurface9 *destSurface = NULL; - TextureStorage9_2D *storage9 = GetAs(storage); - error = storage9->getSurfaceLevel(level, true, &destSurface); + TextureStorage9 *storage9 = GetAs(storage); + error = storage9->getSurfaceLevel(GL_TEXTURE_2D, level, true, &destSurface); if (error.isError()) { + SafeRelease(source); return error; } ASSERT(destSurface); @@ -290,10 +291,11 @@ gl::Error Blit9::copyCube(const gl::Framebuffer *framebuffer, const RECT &source ASSERT(source); IDirect3DSurface9 *destSurface = NULL; - TextureStorage9_Cube *storage9 = GetAs(storage); - error = storage9->getCubeMapSurface(target, level, true, &destSurface); + TextureStorage9 *storage9 = GetAs(storage); + error = storage9->getSurfaceLevel(target, level, true, &destSurface); if (error.isError()) { + SafeRelease(source); return error; } ASSERT(destSurface); diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/Buffer9.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/Buffer9.cpp index c067aa1782c6..0ee0d8325b91 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/Buffer9.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/Buffer9.cpp @@ -14,7 +14,6 @@ namespace rx Buffer9::Buffer9(Renderer9 *renderer) : BufferD3D(renderer), - mRenderer(renderer), mSize(0) {} @@ -39,12 +38,9 @@ gl::Error Buffer9::setData(const void* data, size_t size, GLenum usage) memcpy(mMemory.data(), data, size); } - invalidateStaticData(); + updateD3DBufferUsage(usage); - if (usage == GL_STATIC_DRAW) - { - initializeStaticData(); - } + invalidateStaticData(); return gl::Error(GL_NO_ERROR); } @@ -108,9 +104,10 @@ gl::Error Buffer9::unmap(GLboolean *result) return gl::Error(GL_INVALID_OPERATION); } -void Buffer9::markTransformFeedbackUsage() +gl::Error Buffer9::markTransformFeedbackUsage() { UNREACHABLE(); + return gl::Error(GL_INVALID_OPERATION); } -} +} // namespace rx diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/Buffer9.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/Buffer9.h index f40b6606619a..219f8a6584c6 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/Buffer9.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/Buffer9.h @@ -26,23 +26,22 @@ class Buffer9 : public BufferD3D // BufferD3D implementation virtual size_t getSize() const { return mSize; } virtual bool supportsDirectBinding() const { return false; } + gl::Error getData(const uint8_t **outData) override; // BufferImpl implementation virtual gl::Error setData(const void* data, size_t size, GLenum usage); - gl::Error getData(const uint8_t **outData) override; virtual gl::Error setSubData(const void* data, size_t size, size_t offset); virtual gl::Error copySubData(BufferImpl* source, GLintptr sourceOffset, GLintptr destOffset, GLsizeiptr size); virtual gl::Error map(GLenum access, GLvoid **mapPtr); virtual gl::Error mapRange(size_t offset, size_t length, GLbitfield access, GLvoid **mapPtr); virtual gl::Error unmap(GLboolean *result); - virtual void markTransformFeedbackUsage(); + virtual gl::Error markTransformFeedbackUsage(); private: - Renderer9 *mRenderer; MemoryBuffer mMemory; size_t mSize; }; -} +} // namespace rx #endif // LIBANGLE_RENDERER_D3D_D3D9_BUFFER9_H_ diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/DebugAnnotator9.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/DebugAnnotator9.cpp index 09b229bcb108..6ec35e16a78c 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/DebugAnnotator9.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/DebugAnnotator9.cpp @@ -13,9 +13,9 @@ namespace rx { -void DebugAnnotator9::beginEvent(const std::wstring &eventName) +void DebugAnnotator9::beginEvent(const wchar_t *eventName) { - D3DPERF_BeginEvent(0, eventName.c_str()); + D3DPERF_BeginEvent(0, eventName); } void DebugAnnotator9::endEvent() @@ -23,9 +23,9 @@ void DebugAnnotator9::endEvent() D3DPERF_EndEvent(); } -void DebugAnnotator9::setMarker(const std::wstring &markerName) +void DebugAnnotator9::setMarker(const wchar_t *markerName) { - D3DPERF_SetMarker(0, markerName.c_str()); + D3DPERF_SetMarker(0, markerName); } bool DebugAnnotator9::getStatus() diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/DebugAnnotator9.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/DebugAnnotator9.h index 02956f7183c1..54e3bb949065 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/DebugAnnotator9.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/DebugAnnotator9.h @@ -18,9 +18,9 @@ class DebugAnnotator9 : public gl::DebugAnnotator { public: DebugAnnotator9() {} - void beginEvent(const std::wstring &eventName) override; + void beginEvent(const wchar_t *eventName) override; void endEvent() override; - void setMarker(const std::wstring &markerName) override; + void setMarker(const wchar_t *markerName) override; bool getStatus() override; }; diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/Framebuffer9.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/Framebuffer9.cpp index a6e11e22b9e9..9c269a856589 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/Framebuffer9.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/Framebuffer9.cpp @@ -22,8 +22,7 @@ namespace rx { Framebuffer9::Framebuffer9(const gl::Framebuffer::Data &data, Renderer9 *renderer) - : FramebufferD3D(data, renderer), - mRenderer(renderer) + : FramebufferD3D(data, renderer), mRenderer(renderer) { ASSERT(mRenderer != nullptr); } @@ -32,7 +31,28 @@ Framebuffer9::~Framebuffer9() { } -gl::Error Framebuffer9::clear(const gl::State &state, const ClearParameters &clearParams) +gl::Error Framebuffer9::discard(size_t, const GLenum *) +{ + // Extension not implemented in D3D9 renderer + UNREACHABLE(); + return gl::Error(GL_NO_ERROR); +} + +gl::Error Framebuffer9::invalidate(size_t, const GLenum *) +{ + // Shouldn't ever reach here in D3D9 + UNREACHABLE(); + return gl::Error(GL_NO_ERROR); +} + +gl::Error Framebuffer9::invalidateSub(size_t, const GLenum *, const gl::Rectangle &) +{ + // Shouldn't ever reach here in D3D9 + UNREACHABLE(); + return gl::Error(GL_NO_ERROR); +} + +gl::Error Framebuffer9::clear(const gl::Data &data, const ClearParameters &clearParams) { const gl::FramebufferAttachment *colorAttachment = mData.getColorAttachment(0); const gl::FramebufferAttachment *depthStencilAttachment = mData.getDepthOrStencilAttachment(); @@ -43,16 +63,22 @@ gl::Error Framebuffer9::clear(const gl::State &state, const ClearParameters &cle return error; } - float nearZ = state.getNearPlane(); - float farZ = state.getFarPlane(); - mRenderer->setViewport(state.getViewport(), nearZ, farZ, GL_TRIANGLES, state.getRasterizerState().frontFace, true); + float nearZ = data.state->getNearPlane(); + float farZ = data.state->getFarPlane(); + mRenderer->setViewport(data.caps, data.state->getViewport(), nearZ, farZ, GL_TRIANGLES, + data.state->getRasterizerState().frontFace, true); - mRenderer->setScissorRectangle(state.getScissor(), state.isScissorTestEnabled()); + mRenderer->setScissorRectangle(data.state->getScissor(), data.state->isScissorTestEnabled()); return mRenderer->clear(clearParams, colorAttachment, depthStencilAttachment); } -gl::Error Framebuffer9::readPixels(const gl::Rectangle &area, GLenum format, GLenum type, size_t outputPitch, const gl::PixelPackState &pack, uint8_t *pixels) const +gl::Error Framebuffer9::readPixelsImpl(const gl::Rectangle &area, + GLenum format, + GLenum type, + size_t outputPitch, + const gl::PixelPackState &pack, + uint8_t *pixels) const { ASSERT(pack.pixelBuffer.get() == nullptr); diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/Framebuffer9.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/Framebuffer9.h index 292118e6dbb7..fe12079ae0b6 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/Framebuffer9.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/Framebuffer9.h @@ -21,11 +21,19 @@ class Framebuffer9 : public FramebufferD3D Framebuffer9(const gl::Framebuffer::Data &data, Renderer9 *renderer); virtual ~Framebuffer9(); - private: - gl::Error clear(const gl::State &state, const ClearParameters &clearParams) override; + gl::Error discard(size_t count, const GLenum *attachments) override; + gl::Error invalidate(size_t count, const GLenum *attachments) override; + gl::Error invalidateSub(size_t count, const GLenum *attachments, const gl::Rectangle &area) override; - gl::Error readPixels(const gl::Rectangle &area, GLenum format, GLenum type, size_t outputPitch, - const gl::PixelPackState &pack, uint8_t *pixels) const override; + private: + gl::Error clear(const gl::Data &data, const ClearParameters &clearParams) override; + + gl::Error readPixelsImpl(const gl::Rectangle &area, + GLenum format, + GLenum type, + size_t outputPitch, + const gl::PixelPackState &pack, + uint8_t *pixels) const override; gl::Error blit(const gl::Rectangle &sourceArea, const gl::Rectangle &destArea, const gl::Rectangle *scissor, bool blitRenderTarget, bool blitDepth, bool blitStencil, GLenum filter, diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/Image9.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/Image9.cpp index be534034b187..fec7e3e19d1e 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/Image9.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/Image9.cpp @@ -330,8 +330,8 @@ gl::Error Image9::getSurface(IDirect3DSurface9 **outSurface) gl::Error Image9::setManagedSurface2D(TextureStorage *storage, int level) { IDirect3DSurface9 *surface = NULL; - TextureStorage9_2D *storage9 = GetAs(storage); - gl::Error error = storage9->getSurfaceLevel(level, false, &surface); + TextureStorage9 *storage9 = GetAs(storage); + gl::Error error = storage9->getSurfaceLevel(GL_TEXTURE_2D, level, false, &surface); if (error.isError()) { return error; @@ -342,8 +342,9 @@ gl::Error Image9::setManagedSurface2D(TextureStorage *storage, int level) gl::Error Image9::setManagedSurfaceCube(TextureStorage *storage, int face, int level) { IDirect3DSurface9 *surface = NULL; - TextureStorage9_Cube *storage9 = GetAs(storage); - gl::Error error = storage9->getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level, false, &surface); + TextureStorage9 *storage9 = GetAs(storage); + gl::Error error = + storage9->getSurfaceLevel(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level, false, &surface); if (error.isError()) { return error; @@ -384,12 +385,13 @@ gl::Error Image9::copyToStorage(TextureStorage *storage, const gl::ImageIndex &i return error; } + TextureStorage9 *storage9 = GetAs(storage); + IDirect3DSurface9 *destSurface = NULL; if (index.type == GL_TEXTURE_2D) { - TextureStorage9_2D *storage9 = GetAs(storage); - error = storage9->getSurfaceLevel(index.mipIndex, true, &destSurface); + error = storage9->getSurfaceLevel(GL_TEXTURE_2D, index.mipIndex, true, &destSurface); if (error.isError()) { return error; @@ -398,8 +400,7 @@ gl::Error Image9::copyToStorage(TextureStorage *storage, const gl::ImageIndex &i else { ASSERT(gl::IsCubeMapTextureTarget(index.type)); - TextureStorage9_Cube *storage9 = GetAs(storage); - error = storage9->getCubeMapSurface(index.type, index.mipIndex, true, &destSurface); + error = storage9->getSurfaceLevel(index.type, index.mipIndex, true, &destSurface); if (error.isError()) { return error; @@ -479,6 +480,8 @@ gl::Error Image9::loadData(const gl::Box &area, const gl::PixelUnpackState &unpa const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(mInternalFormat); GLsizei inputRowPitch = formatInfo.computeRowPitch(type, area.width, unpack.alignment, unpack.rowLength); + GLsizei inputSkipBytes = formatInfo.computeSkipPixels(inputRowPitch, 0, unpack.skipImages, + unpack.skipRows, unpack.skipPixels); const d3d9::TextureFormat &d3dFormatInfo = d3d9::GetTextureFormatInfo(mInternalFormat); ASSERT(d3dFormatInfo.loadFunction != NULL); @@ -497,8 +500,9 @@ gl::Error Image9::loadData(const gl::Box &area, const gl::PixelUnpackState &unpa } d3dFormatInfo.loadFunction(area.width, area.height, area.depth, - reinterpret_cast(input), inputRowPitch, 0, - reinterpret_cast(locked.pBits), locked.Pitch, 0); + reinterpret_cast(input) + inputSkipBytes, + inputRowPitch, 0, reinterpret_cast(locked.pBits), + locked.Pitch, 0); unlock(); @@ -512,7 +516,8 @@ gl::Error Image9::loadCompressedData(const gl::Box &area, const void *input) const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(mInternalFormat); GLsizei inputRowPitch = formatInfo.computeRowPitch(GL_UNSIGNED_BYTE, area.width, 1, 0); - GLsizei inputDepthPitch = formatInfo.computeDepthPitch(GL_UNSIGNED_BYTE, area.width, area.height, 1, 0); + GLsizei inputDepthPitch = + formatInfo.computeDepthPitch(GL_UNSIGNED_BYTE, area.width, area.height, 1, 0, 0); const d3d9::TextureFormat &d3d9FormatInfo = d3d9::GetTextureFormatInfo(mInternalFormat); @@ -544,7 +549,9 @@ gl::Error Image9::loadCompressedData(const gl::Box &area, const void *input) } // This implements glCopyTex[Sub]Image2D for non-renderable internal texture formats and incomplete textures -gl::Error Image9::copy(const gl::Offset &destOffset, const gl::Rectangle &sourceArea, RenderTargetD3D *source) +gl::Error Image9::copyFromRTInternal(const gl::Offset &destOffset, + const gl::Rectangle &sourceArea, + RenderTargetD3D *source) { ASSERT(source); @@ -772,11 +779,35 @@ gl::Error Image9::copy(const gl::Offset &destOffset, const gl::Rectangle &source return gl::Error(GL_NO_ERROR); } -gl::Error Image9::copy(const gl::Offset &destOffset, const gl::Box &area, const gl::ImageIndex &srcIndex, TextureStorage *srcStorage) +gl::Error Image9::copyFromTexStorage(const gl::ImageIndex &imageIndex, TextureStorage *source) { - // Currently unreachable, due to only being used in a D3D11-only workaround - UNIMPLEMENTED(); - return gl::Error(GL_INVALID_OPERATION); + RenderTargetD3D *renderTarget = nullptr; + gl::Error error = source->getRenderTarget(imageIndex, &renderTarget); + if (error.isError()) + { + return error; + } + + gl::Rectangle sourceArea(0, 0, mWidth, mHeight); + return copyFromRTInternal(gl::Offset(), sourceArea, renderTarget); } +gl::Error Image9::copyFromFramebuffer(const gl::Offset &destOffset, + const gl::Rectangle &sourceArea, + const gl::Framebuffer *source) +{ + const gl::FramebufferAttachment *srcAttachment = source->getReadColorbuffer(); + ASSERT(srcAttachment); + + RenderTargetD3D *renderTarget = NULL; + gl::Error error = srcAttachment->getRenderTarget(&renderTarget); + if (error.isError()) + { + return error; + } + + ASSERT(renderTarget); + return copyFromRTInternal(destOffset, sourceArea, renderTarget); } + +} // namespace rx diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/Image9.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/Image9.h index 0bc6d7653f1a..91448cc849b4 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/Image9.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/Image9.h @@ -45,9 +45,10 @@ class Image9 : public ImageD3D virtual gl::Error loadData(const gl::Box &area, const gl::PixelUnpackState &unpack, GLenum type, const void *input); virtual gl::Error loadCompressedData(const gl::Box &area, const void *input); - virtual gl::Error copy(const gl::Offset &destOffset, const gl::Rectangle &sourceArea, RenderTargetD3D *source); - virtual gl::Error copy(const gl::Offset &destOffset, const gl::Box &sourceArea, - const gl::ImageIndex &sourceIndex, TextureStorage *source); + gl::Error copyFromTexStorage(const gl::ImageIndex &imageIndex, TextureStorage *source) override; + gl::Error copyFromFramebuffer(const gl::Offset &destOffset, + const gl::Rectangle &sourceArea, + const gl::Framebuffer *source) override; private: gl::Error getSurface(IDirect3DSurface9 **outSurface); @@ -59,6 +60,10 @@ class Image9 : public ImageD3D gl::Error lock(D3DLOCKED_RECT *lockedRect, const RECT &rect); void unlock(); + gl::Error copyFromRTInternal(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. diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/Query9.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/Query9.cpp index 96f12d786889..c826abf81cde 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/Query9.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/Query9.cpp @@ -66,7 +66,14 @@ gl::Error Query9::end() return gl::Error(GL_NO_ERROR); } -gl::Error Query9::getResult(GLuint *params) +gl::Error Query9::queryCounter() +{ + UNIMPLEMENTED(); + return gl::Error(GL_INVALID_OPERATION, "Unimplemented"); +} + +template +gl::Error Query9::getResultBase(T *params) { while (!mQueryFinished) { @@ -83,12 +90,31 @@ gl::Error Query9::getResult(GLuint *params) } ASSERT(mQueryFinished); - *params = mResult; - + *params = static_cast(mResult); return gl::Error(GL_NO_ERROR); } -gl::Error Query9::isResultAvailable(GLuint *available) +gl::Error Query9::getResult(GLint *params) +{ + return getResultBase(params); +} + +gl::Error Query9::getResult(GLuint *params) +{ + return getResultBase(params); +} + +gl::Error Query9::getResult(GLint64 *params) +{ + return getResultBase(params); +} + +gl::Error Query9::getResult(GLuint64 *params) +{ + return getResultBase(params); +} + +gl::Error Query9::isResultAvailable(bool *available) { gl::Error error = testQuery(); if (error.isError()) @@ -96,7 +122,7 @@ gl::Error Query9::isResultAvailable(GLuint *available) return error; } - *available = (mQueryFinished ? GL_TRUE : GL_FALSE); + *available = mQueryFinished; return gl::Error(GL_NO_ERROR); } diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/Query9.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/Query9.h index 399da2ed83c3..9d17711a00bc 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/Query9.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/Query9.h @@ -23,13 +23,20 @@ class Query9 : public QueryImpl virtual gl::Error begin(); virtual gl::Error end(); + virtual gl::Error queryCounter(); + virtual gl::Error getResult(GLint *params); virtual gl::Error getResult(GLuint *params); - virtual gl::Error isResultAvailable(GLuint *available); + virtual gl::Error getResult(GLint64 *params); + virtual gl::Error getResult(GLuint64 *params); + virtual gl::Error isResultAvailable(bool *available); private: gl::Error testQuery(); - GLuint mResult; + template + gl::Error getResultBase(T *params); + + GLuint64 mResult; bool mQueryFinished; Renderer9 *mRenderer; diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/RenderTarget9.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/RenderTarget9.cpp index f71eaef523ec..419bff1f63e9 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/RenderTarget9.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/RenderTarget9.cpp @@ -17,7 +17,13 @@ namespace rx { // TODO: AddRef the incoming surface to take ownership instead of expecting that its ref is being given. -TextureRenderTarget9::TextureRenderTarget9(IDirect3DSurface9 *surface, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, +TextureRenderTarget9::TextureRenderTarget9(IDirect3DBaseTexture9 *texture, + size_t textureLevel, + IDirect3DSurface9 *surface, + GLenum internalFormat, + GLsizei width, + GLsizei height, + GLsizei depth, GLsizei samples) : mWidth(width), mHeight(height), @@ -25,6 +31,8 @@ TextureRenderTarget9::TextureRenderTarget9(IDirect3DSurface9 *surface, GLenum in mInternalFormat(internalFormat), mD3DFormat(D3DFMT_UNKNOWN), mSamples(samples), + mTexture(texture), + mTextureLevel(textureLevel), mRenderTarget(surface) { ASSERT(mDepth == 1); @@ -39,6 +47,7 @@ TextureRenderTarget9::TextureRenderTarget9(IDirect3DSurface9 *surface, GLenum in TextureRenderTarget9::~TextureRenderTarget9() { + SafeRelease(mTexture); SafeRelease(mRenderTarget); } @@ -67,7 +76,17 @@ GLsizei TextureRenderTarget9::getSamples() const return mSamples; } -IDirect3DSurface9 *TextureRenderTarget9::getSurface() +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 @@ -111,7 +130,7 @@ GLsizei SurfaceRenderTarget9::getDepth() const GLenum SurfaceRenderTarget9::getInternalFormat() const { - return (mDepth ? mSwapChain->GetDepthBufferInternalFormat() : mSwapChain->GetBackBufferInternalFormat()); + return (mDepth ? mSwapChain->GetDepthBufferInternalFormat() : mSwapChain->GetRenderTargetInternalFormat()); } GLsizei SurfaceRenderTarget9::getSamples() const @@ -120,11 +139,21 @@ GLsizei SurfaceRenderTarget9::getSamples() const return 0; } -IDirect3DSurface9 *SurfaceRenderTarget9::getSurface() +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; diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/RenderTarget9.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/RenderTarget9.h index 13e67e3c9a79..f19c54de7bf9 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/RenderTarget9.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/RenderTarget9.h @@ -22,8 +22,12 @@ class RenderTarget9 : public RenderTargetD3D public: RenderTarget9() { } virtual ~RenderTarget9() { } + // 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() = 0; + virtual IDirect3DSurface9 *getSurface() const = 0; virtual D3DFORMAT getD3DFormat() const = 0; }; @@ -31,7 +35,13 @@ class RenderTarget9 : public RenderTargetD3D class TextureRenderTarget9 : public RenderTarget9 { public: - TextureRenderTarget9(IDirect3DSurface9 *surface, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, + TextureRenderTarget9(IDirect3DBaseTexture9 *texture, + size_t textureLevel, + IDirect3DSurface9 *surface, + GLenum internalFormat, + GLsizei width, + GLsizei height, + GLsizei depth, GLsizei samples); virtual ~TextureRenderTarget9(); @@ -41,7 +51,9 @@ class TextureRenderTarget9 : public RenderTarget9 GLenum getInternalFormat() const override; GLsizei getSamples() const override; - IDirect3DSurface9 *getSurface() override; + IDirect3DBaseTexture9 *getTexture() const override; + size_t getTextureLevel() const override; + IDirect3DSurface9 *getSurface() const override; D3DFORMAT getD3DFormat() const override; @@ -53,6 +65,8 @@ class TextureRenderTarget9 : public RenderTarget9 D3DFORMAT mD3DFormat; GLsizei mSamples; + IDirect3DBaseTexture9 *mTexture; + size_t mTextureLevel; IDirect3DSurface9 *mRenderTarget; }; @@ -68,7 +82,9 @@ class SurfaceRenderTarget9 : public RenderTarget9 GLenum getInternalFormat() const override; GLsizei getSamples() const override; - IDirect3DSurface9 *getSurface() override; + IDirect3DBaseTexture9 *getTexture() const override; + size_t getTextureLevel() const override; + IDirect3DSurface9 *getSurface() const override; D3DFORMAT getD3DFormat() const override; diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/Renderer9.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/Renderer9.cpp index 90657bb9a515..9abb200e76d6 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/Renderer9.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/Renderer9.cpp @@ -8,50 +8,50 @@ #include "libANGLE/renderer/d3d/d3d9/Renderer9.h" +#include +#include + #include "common/utilities.h" +#include "libANGLE/angletypes.h" #include "libANGLE/Buffer.h" #include "libANGLE/Display.h" +#include "libANGLE/features.h" +#include "libANGLE/formatutils.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/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/TransformFeedbackD3D.h" #include "libANGLE/renderer/d3d/d3d9/Blit9.h" #include "libANGLE/renderer/d3d/d3d9/Buffer9.h" #include "libANGLE/renderer/d3d/d3d9/Fence9.h" +#include "libANGLE/renderer/d3d/d3d9/formatutils9.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/Query9.h" +#include "libANGLE/renderer/d3d/d3d9/renderer9_utils.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/renderer9_utils.h" -#include "libANGLE/renderer/d3d/d3d9/formatutils9.h" - +#include "libANGLE/renderer/d3d/CompilerD3D.h" +#include "libANGLE/renderer/d3d/DeviceD3D.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/TransformFeedbackD3D.h" +#include "libANGLE/State.h" +#include "libANGLE/Surface.h" +#include "libANGLE/Texture.h" #include "third_party/trace_event/trace_event.h" -#include -#include -#include #if !defined(ANGLE_COMPILE_OPTIMIZATION_LEVEL) #define ANGLE_COMPILE_OPTIMIZATION_LEVEL D3DCOMPILE_OPTIMIZATION_LEVEL3 @@ -77,12 +77,8 @@ enum MAX_TEXTURE_IMAGE_UNITS_VTF_SM3 = 4 }; -Renderer9::Renderer9(egl::Display *display) - : RendererD3D(display) +Renderer9::Renderer9(egl::Display *display) : RendererD3D(display), mStateManager(this) { - // Initialize global annotator - gl::InitializeDebugAnnotations(&mAnnotator); - mD3d9Module = NULL; mD3d9 = NULL; @@ -95,8 +91,8 @@ Renderer9::Renderer9(egl::Display *display) mAdapter = D3DADAPTER_DEFAULT; const egl::AttributeMap &attributes = display->getAttributeMap(); - EGLint requestedDeviceType = attributes.get(EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE, - EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE); + 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: @@ -134,6 +130,10 @@ Renderer9::Renderer9(egl::Display *display) mAppliedVertexShader = NULL; mAppliedPixelShader = NULL; mAppliedProgramSerial = 0; + + initializeDebugAnnotator(); + + mEGLDevice = nullptr; } Renderer9::~Renderer9() @@ -148,16 +148,17 @@ Renderer9::~Renderer9() } release(); - - gl::UninitializeDebugAnnotations(); } void Renderer9::release() { RendererD3D::cleanup(); + mTranslatedAttribCache.clear(); + releaseDeviceResources(); + SafeDelete(mEGLDevice); SafeRelease(mDevice); SafeRelease(mDeviceEx); SafeRelease(mD3d9); @@ -176,13 +177,6 @@ void Renderer9::release() egl::Error Renderer9::initialize() { - if (!mCompiler.initialize()) - { - return egl::Error(EGL_NOT_INITIALIZED, - D3D9_INIT_COMPILER_ERROR, - "Compiler failed to initialize."); - } - TRACE_EVENT0("gpu.angle", "GetModuleHandle_d3d9"); mD3d9Module = GetModuleHandle(TEXT("d3d9.dll")); @@ -354,14 +348,11 @@ void Renderer9::initializeDevice() const gl::Caps &rendererCaps = getRendererCaps(); - mForceSetVertexSamplerStates.resize(rendererCaps.maxVertexTextureImageUnits); mCurVertexSamplerStates.resize(rendererCaps.maxVertexTextureImageUnits); - - mForceSetPixelSamplerStates.resize(rendererCaps.maxTextureImageUnits); mCurPixelSamplerStates.resize(rendererCaps.maxTextureImageUnits); - mCurVertexTextureSerials.resize(rendererCaps.maxVertexTextureImageUnits); - mCurPixelTextureSerials.resize(rendererCaps.maxTextureImageUnits); + mCurVertexTextures.resize(rendererCaps.maxVertexTextureImageUnits); + mCurPixelTextures.resize(rendererCaps.maxTextureImageUnits); markAllStateDirty(); @@ -374,6 +365,8 @@ void Renderer9::initializeDevice() ASSERT(!mVertexDataManager && !mIndexDataManager); mVertexDataManager = new VertexDataManager(this); mIndexDataManager = new IndexDataManager(this, getRendererClass()); + + mTranslatedAttribCache.resize(getRendererCaps().maxVertexAttributes); } D3DPRESENT_PARAMETERS Renderer9::getDefaultPresentParameters() @@ -518,6 +511,31 @@ egl::ConfigSet Renderer9::generateConfigs() const return configs; } +void Renderer9::generateDisplayExtensions(egl::DisplayExtensions *outExtensions) const +{ + outExtensions->createContextRobustness = true; + + if (getShareHandleSupport()) + { + outExtensions->d3dShareHandleClientBuffer = true; + outExtensions->surfaceD3DTexture2DShareHandle = true; + } + + outExtensions->querySurfacePointer = true; + outExtensions->windowFixedSize = true; + outExtensions->postSubBuffer = true; + outExtensions->createContext = true; + outExtensions->deviceQuery = true; + outExtensions->createContextNoError = true; + + outExtensions->image = true; + outExtensions->imageBase = true; + outExtensions->glTexture2DImage = true; + outExtensions->glRenderbufferImage = true; + + outExtensions->flexibleSurfaceCompatibility = true; +} + void Renderer9::startScene() { if (!mSceneStarted) @@ -607,7 +625,7 @@ gl::Error Renderer9::finish() while (result == S_FALSE) { // Keep polling, but allow other threads to do something useful first - Sleep(0); + ScheduleYield(); result = query->GetData(NULL, 0, D3DGETDATA_FLUSH); @@ -637,15 +655,19 @@ gl::Error Renderer9::finish() return gl::Error(GL_NO_ERROR); } -bool Renderer9::shouldCreateChildWindowForSurface(EGLNativeWindowType window) const +SwapChainD3D *Renderer9::createSwapChain(NativeWindow nativeWindow, + HANDLE shareHandle, + GLenum backBufferFormat, + GLenum depthBufferFormat, + EGLint orientation) { - // D3D9 never needs to create child windows - return false; + return new SwapChain9(this, nativeWindow, shareHandle, backBufferFormat, depthBufferFormat, + orientation); } -SwapChainD3D *Renderer9::createSwapChain(NativeWindow nativeWindow, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat) +CompilerImpl *Renderer9::createCompiler() { - return new SwapChain9(this, nativeWindow, shareHandle, backBufferFormat, depthBufferFormat); + return new CompilerD3D(SH_HLSL_3_0_OUTPUT); } void *Renderer9::getD3DDevice() @@ -722,9 +744,9 @@ BufferImpl *Renderer9::createBuffer() return new Buffer9(this); } -VertexArrayImpl *Renderer9::createVertexArray() +VertexArrayImpl *Renderer9::createVertexArray(const gl::VertexArray::Data &data) { - return new VertexArray9(this); + return new VertexArray9(data); } QueryImpl *Renderer9::createQuery(GLenum type) @@ -749,6 +771,13 @@ TransformFeedbackImpl* Renderer9::createTransformFeedback() return new TransformFeedbackD3D(); } +StreamImpl *Renderer9::createStream(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. @@ -772,46 +801,52 @@ gl::Error Renderer9::generateSwizzle(gl::Texture *texture) gl::Error Renderer9::setSamplerState(gl::SamplerType type, int index, gl::Texture *texture, const gl::SamplerState &samplerState) { - std::vector &forceSetSamplers = (type == gl::SAMPLER_PIXEL) ? mForceSetPixelSamplerStates : mForceSetVertexSamplerStates; - std::vector &appliedSamplers = (type == gl::SAMPLER_PIXEL) ? mCurPixelSamplerStates: mCurVertexSamplerStates; + CurSamplerState &appliedSampler = (type == gl::SAMPLER_PIXEL) ? mCurPixelSamplerStates[index] + : mCurVertexSamplerStates[index]; - if (forceSetSamplers[index] || memcmp(&samplerState, &appliedSamplers[index], sizeof(gl::SamplerState)) != 0) - { - int d3dSamplerOffset = (type == gl::SAMPLER_PIXEL) ? 0 : D3DVERTEXTEXTURESAMPLER0; - int d3dSampler = index + d3dSamplerOffset; + // Make sure to add the level offset for our tiny compressed texture workaround + TextureD3D *textureD3D = GetImplAs(texture); - // Make sure to add the level offset for our tiny compressed texture workaround - TextureD3D *textureD3D = GetImplAs(texture); + TextureStorage *storage = nullptr; + gl::Error error = textureD3D->getNativeTexture(&storage); + if (error.isError()) + { + return error; + } - TextureStorage *storage = nullptr; - gl::Error error = textureD3D->getNativeTexture(&storage); - if (error.isError()) - { - return error; - } + // Storage should exist, texture should be complete + ASSERT(storage); - // Storage should exist, texture should be complete - ASSERT(storage); + DWORD baseLevel = texture->getBaseLevel() + storage->getTopLevel(); - DWORD baseLevel = samplerState.baseLevel + storage->getTopLevel(); + if (appliedSampler.forceSet || appliedSampler.baseLevel != baseLevel || + memcmp(&samplerState, &appliedSampler, sizeof(gl::SamplerState)) != 0) + { + int d3dSamplerOffset = (type == gl::SAMPLER_PIXEL) ? 0 : D3DVERTEXTEXTURESAMPLER0; + int d3dSampler = index + d3dSamplerOffset; mDevice->SetSamplerState(d3dSampler, D3DSAMP_ADDRESSU, gl_d3d9::ConvertTextureWrap(samplerState.wrapS)); mDevice->SetSamplerState(d3dSampler, D3DSAMP_ADDRESSV, gl_d3d9::ConvertTextureWrap(samplerState.wrapT)); mDevice->SetSamplerState(d3dSampler, D3DSAMP_MAGFILTER, gl_d3d9::ConvertMagFilter(samplerState.magFilter, samplerState.maxAnisotropy)); + D3DTEXTUREFILTERTYPE d3dMinFilter, d3dMipFilter; - gl_d3d9::ConvertMinFilter(samplerState.minFilter, &d3dMinFilter, &d3dMipFilter, samplerState.maxAnisotropy); + float lodBias; + gl_d3d9::ConvertMinFilter(samplerState.minFilter, &d3dMinFilter, &d3dMipFilter, &lodBias, + samplerState.maxAnisotropy, 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 (getRendererExtensions().textureFilterAnisotropic) { mDevice->SetSamplerState(d3dSampler, D3DSAMP_MAXANISOTROPY, (DWORD)samplerState.maxAnisotropy); } } - forceSetSamplers[index] = false; - appliedSamplers[index] = samplerState; + appliedSampler.forceSet = false; + appliedSampler.samplerState = samplerState; + appliedSampler.baseLevel = baseLevel; return gl::Error(GL_NO_ERROR); } @@ -821,10 +856,9 @@ gl::Error Renderer9::setTexture(gl::SamplerType type, int index, gl::Texture *te int d3dSamplerOffset = (type == gl::SAMPLER_PIXEL) ? 0 : D3DVERTEXTEXTURESAMPLER0; int d3dSampler = index + d3dSamplerOffset; IDirect3DBaseTexture9 *d3dTexture = NULL; - unsigned int serial = 0; bool forceSetTexture = false; - std::vector &appliedSerials = (type == gl::SAMPLER_PIXEL) ? mCurPixelTextureSerials : mCurVertexTextureSerials; + std::vector &appliedTextures = (type == gl::SAMPLER_PIXEL) ? mCurPixelTextures : mCurVertexTextures; if (texture) { @@ -851,372 +885,99 @@ gl::Error Renderer9::setTexture(gl::SamplerType type, int index, gl::Texture *te // in the texture class and we're unexpectedly missing the d3d texture ASSERT(d3dTexture != NULL); - serial = texture->getTextureSerial(); forceSetTexture = textureImpl->hasDirtyImages(); textureImpl->resetDirty(); } - if (forceSetTexture || appliedSerials[index] != serial) + if (forceSetTexture || appliedTextures[index] != reinterpret_cast(d3dTexture)) { mDevice->SetTexture(d3dSampler, d3dTexture); } - appliedSerials[index] = serial; + appliedTextures[index] = reinterpret_cast(d3dTexture); return gl::Error(GL_NO_ERROR); } gl::Error Renderer9::setUniformBuffers(const gl::Data &/*data*/, - const GLint /*vertexUniformBuffers*/[], - const GLint /*fragmentUniformBuffers*/[]) + const std::vector &/*vertexUniformBuffers*/, + const std::vector &/*fragmentUniformBuffers*/) { // No effect in ES2/D3D9 return gl::Error(GL_NO_ERROR); } -gl::Error Renderer9::setRasterizerState(const gl::RasterizerState &rasterState) +void Renderer9::syncState(const gl::State &state, const gl::State::DirtyBits &bitmask) { - bool rasterStateChanged = mForceSetRasterState || memcmp(&rasterState, &mCurRasterState, sizeof(gl::RasterizerState)) != 0; - - if (rasterStateChanged) - { - // Set the cull mode - if (rasterState.cullFace) - { - mDevice->SetRenderState(D3DRS_CULLMODE, gl_d3d9::ConvertCullMode(rasterState.cullMode, rasterState.frontFace)); - } - else - { - mDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); - } - - if (rasterState.polygonOffsetFill) - { - if (mCurDepthSize > 0) - { - mDevice->SetRenderState(D3DRS_SLOPESCALEDEPTHBIAS, *(DWORD*)&rasterState.polygonOffsetFactor); - - float depthBias = ldexp(rasterState.polygonOffsetUnits, -static_cast(mCurDepthSize)); - mDevice->SetRenderState(D3DRS_DEPTHBIAS, *(DWORD*)&depthBias); - } - } - else - { - mDevice->SetRenderState(D3DRS_SLOPESCALEDEPTHBIAS, 0); - mDevice->SetRenderState(D3DRS_DEPTHBIAS, 0); - } - - mCurRasterState = rasterState; - } - - mForceSetRasterState = false; - - return gl::Error(GL_NO_ERROR); + mStateManager.syncState(state, bitmask); } -gl::Error Renderer9::setBlendState(const gl::Framebuffer *framebuffer, const gl::BlendState &blendState, const gl::ColorF &blendColor, - unsigned int sampleMask) +gl::Error Renderer9::updateState(const gl::Data &data, GLenum drawMode) { - bool blendStateChanged = mForceSetBlendState || memcmp(&blendState, &mCurBlendState, sizeof(gl::BlendState)) != 0; - bool blendColorChanged = mForceSetBlendState || memcmp(&blendColor, &mCurBlendColor, sizeof(gl::ColorF)) != 0; - bool sampleMaskChanged = mForceSetBlendState || sampleMask != mCurSampleMask; - - if (blendStateChanged || blendColorChanged) - { - if (blendState.blend) - { - mDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); - - 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) - { - mDevice->SetRenderState(D3DRS_BLENDFACTOR, gl_d3d9::ConvertColor(blendColor)); - } - else - { - mDevice->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))); - } - - mDevice->SetRenderState(D3DRS_SRCBLEND, gl_d3d9::ConvertBlendFunc(blendState.sourceBlendRGB)); - mDevice->SetRenderState(D3DRS_DESTBLEND, gl_d3d9::ConvertBlendFunc(blendState.destBlendRGB)); - mDevice->SetRenderState(D3DRS_BLENDOP, gl_d3d9::ConvertBlendOp(blendState.blendEquationRGB)); - - if (blendState.sourceBlendRGB != blendState.sourceBlendAlpha || - blendState.destBlendRGB != blendState.destBlendAlpha || - blendState.blendEquationRGB != blendState.blendEquationAlpha) - { - mDevice->SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, TRUE); - - mDevice->SetRenderState(D3DRS_SRCBLENDALPHA, gl_d3d9::ConvertBlendFunc(blendState.sourceBlendAlpha)); - mDevice->SetRenderState(D3DRS_DESTBLENDALPHA, gl_d3d9::ConvertBlendFunc(blendState.destBlendAlpha)); - mDevice->SetRenderState(D3DRS_BLENDOPALPHA, gl_d3d9::ConvertBlendOp(blendState.blendEquationAlpha)); - } - else - { - mDevice->SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, FALSE); - } - } - else - { - mDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); - } - - if (blendState.sampleAlphaToCoverage) - { - FIXME("Sample alpha to coverage is unimplemented."); - } - - const gl::FramebufferAttachment *attachment = framebuffer->getFirstColorbuffer(); - GLenum internalFormat = attachment ? attachment->getInternalFormat() : GL_NONE; - - // Set the color mask - bool zeroColorMaskAllowed = getVendorId() != VENDOR_ID_AMD; - // 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://code.google.com/p/angleproject/issues/detail?id=169 - - const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalFormat); - DWORD colorMask = gl_d3d9::ConvertColorMask(formatInfo.redBits > 0 && blendState.colorMaskRed, - formatInfo.greenBits > 0 && blendState.colorMaskGreen, - formatInfo.blueBits > 0 && blendState.colorMaskBlue, - formatInfo.alphaBits > 0 && blendState.colorMaskAlpha); - if (colorMask == 0 && !zeroColorMaskAllowed) - { - // Enable green channel, but set blending so nothing will be drawn. - mDevice->SetRenderState(D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_GREEN); - mDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); - - mDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ZERO); - mDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE); - mDevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD); - } - else - { - mDevice->SetRenderState(D3DRS_COLORWRITEENABLE, colorMask); - } + // Applies the render target surface, depth stencil surface, viewport rectangle and + // scissor rectangle to the renderer + const gl::Framebuffer *framebufferObject = data.state->getDrawFramebuffer(); + ASSERT(framebufferObject && framebufferObject->checkStatus(data) == GL_FRAMEBUFFER_COMPLETE); - mDevice->SetRenderState(D3DRS_DITHERENABLE, blendState.dither ? TRUE : FALSE); - - mCurBlendState = blendState; - mCurBlendColor = blendColor; - } - - if (sampleMaskChanged) + gl::Error error = applyRenderTarget(framebufferObject); + if (error.isError()) { - // Set the multisample mask - mDevice->SetRenderState(D3DRS_MULTISAMPLEANTIALIAS, TRUE); - mDevice->SetRenderState(D3DRS_MULTISAMPLEMASK, static_cast(sampleMask)); - - mCurSampleMask = sampleMask; + return error; } - mForceSetBlendState = false; + // Setting viewport state + setViewport(data.caps, data.state->getViewport(), data.state->getNearPlane(), + data.state->getFarPlane(), drawMode, data.state->getRasterizerState().frontFace, + false); - return gl::Error(GL_NO_ERROR); -} + // Setting scissors state + setScissorRectangle(data.state->getScissor(), data.state->isScissorTestEnabled()); -gl::Error Renderer9::setDepthStencilState(const gl::DepthStencilState &depthStencilState, int stencilRef, - int stencilBackRef, bool frontFaceCCW) -{ - bool depthStencilStateChanged = mForceSetDepthStencilState || - memcmp(&depthStencilState, &mCurDepthStencilState, sizeof(gl::DepthStencilState)) != 0; - bool stencilRefChanged = mForceSetDepthStencilState || stencilRef != mCurStencilRef || - stencilBackRef != mCurStencilBackRef; - bool frontFaceCCWChanged = mForceSetDepthStencilState || frontFaceCCW != mCurFrontFaceCCW; + // Setting blend, depth stencil, and rasterizer states + int samples = framebufferObject->getSamples(data); + gl::RasterizerState rasterizer = data.state->getRasterizerState(); + rasterizer.pointDrawMode = (drawMode == GL_POINTS); + rasterizer.multiSample = (samples != 0); - if (depthStencilStateChanged) - { - if (depthStencilState.depthTest) - { - mDevice->SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE); - mDevice->SetRenderState(D3DRS_ZFUNC, gl_d3d9::ConvertComparison(depthStencilState.depthFunc)); - } - else - { - mDevice->SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE); - } + unsigned int mask = GetBlendSampleMask(data, samples); + error = setBlendDepthRasterStates(data, mask); - mCurDepthStencilState = depthStencilState; - } - - if (depthStencilStateChanged || stencilRefChanged || frontFaceCCWChanged) + if (error.isError()) { - if (depthStencilState.stencilTest && mCurStencilSize > 0) - { - mDevice->SetRenderState(D3DRS_STENCILENABLE, TRUE); - mDevice->SetRenderState(D3DRS_TWOSIDEDSTENCILMODE, TRUE); - - // FIXME: Unsupported by D3D9 - const D3DRENDERSTATETYPE D3DRS_CCW_STENCILREF = D3DRS_STENCILREF; - const D3DRENDERSTATETYPE D3DRS_CCW_STENCILMASK = D3DRS_STENCILMASK; - const D3DRENDERSTATETYPE D3DRS_CCW_STENCILWRITEMASK = D3DRS_STENCILWRITEMASK; - - ASSERT(depthStencilState.stencilWritemask == depthStencilState.stencilBackWritemask); - ASSERT(stencilRef == stencilBackRef); - ASSERT(depthStencilState.stencilMask == depthStencilState.stencilBackMask); - - // get the maximum size of the stencil ref - unsigned int maxStencil = (1 << mCurStencilSize) - 1; - - mDevice->SetRenderState(frontFaceCCW ? D3DRS_STENCILWRITEMASK : D3DRS_CCW_STENCILWRITEMASK, - depthStencilState.stencilWritemask); - mDevice->SetRenderState(frontFaceCCW ? D3DRS_STENCILFUNC : D3DRS_CCW_STENCILFUNC, - gl_d3d9::ConvertComparison(depthStencilState.stencilFunc)); - - mDevice->SetRenderState(frontFaceCCW ? D3DRS_STENCILREF : D3DRS_CCW_STENCILREF, - (stencilRef < (int)maxStencil) ? stencilRef : maxStencil); - mDevice->SetRenderState(frontFaceCCW ? D3DRS_STENCILMASK : D3DRS_CCW_STENCILMASK, - depthStencilState.stencilMask); - - mDevice->SetRenderState(frontFaceCCW ? D3DRS_STENCILFAIL : D3DRS_CCW_STENCILFAIL, - gl_d3d9::ConvertStencilOp(depthStencilState.stencilFail)); - mDevice->SetRenderState(frontFaceCCW ? D3DRS_STENCILZFAIL : D3DRS_CCW_STENCILZFAIL, - gl_d3d9::ConvertStencilOp(depthStencilState.stencilPassDepthFail)); - mDevice->SetRenderState(frontFaceCCW ? D3DRS_STENCILPASS : D3DRS_CCW_STENCILPASS, - gl_d3d9::ConvertStencilOp(depthStencilState.stencilPassDepthPass)); - - mDevice->SetRenderState(!frontFaceCCW ? D3DRS_STENCILWRITEMASK : D3DRS_CCW_STENCILWRITEMASK, - depthStencilState.stencilBackWritemask); - mDevice->SetRenderState(!frontFaceCCW ? D3DRS_STENCILFUNC : D3DRS_CCW_STENCILFUNC, - gl_d3d9::ConvertComparison(depthStencilState.stencilBackFunc)); - - mDevice->SetRenderState(!frontFaceCCW ? D3DRS_STENCILREF : D3DRS_CCW_STENCILREF, - (stencilBackRef < (int)maxStencil) ? stencilBackRef : maxStencil); - mDevice->SetRenderState(!frontFaceCCW ? D3DRS_STENCILMASK : D3DRS_CCW_STENCILMASK, - depthStencilState.stencilBackMask); - - mDevice->SetRenderState(!frontFaceCCW ? D3DRS_STENCILFAIL : D3DRS_CCW_STENCILFAIL, - gl_d3d9::ConvertStencilOp(depthStencilState.stencilBackFail)); - mDevice->SetRenderState(!frontFaceCCW ? D3DRS_STENCILZFAIL : D3DRS_CCW_STENCILZFAIL, - gl_d3d9::ConvertStencilOp(depthStencilState.stencilBackPassDepthFail)); - mDevice->SetRenderState(!frontFaceCCW ? D3DRS_STENCILPASS : D3DRS_CCW_STENCILPASS, - gl_d3d9::ConvertStencilOp(depthStencilState.stencilBackPassDepthPass)); - } - else - { - mDevice->SetRenderState(D3DRS_STENCILENABLE, FALSE); - } - - mDevice->SetRenderState(D3DRS_ZWRITEENABLE, depthStencilState.depthMask ? TRUE : FALSE); - - mCurStencilRef = stencilRef; - mCurStencilBackRef = stencilBackRef; - mCurFrontFaceCCW = frontFaceCCW; + return error; } - mForceSetDepthStencilState = false; + mStateManager.resetDirtyBits(); - return gl::Error(GL_NO_ERROR); + return error; } void Renderer9::setScissorRectangle(const gl::Rectangle &scissor, bool enabled) { - bool scissorChanged = mForceSetScissor || - memcmp(&scissor, &mCurScissor, sizeof(gl::Rectangle)) != 0 || - enabled != mScissorEnabled; - - if (scissorChanged) - { - if (enabled) - { - RECT rect; - rect.left = gl::clamp(scissor.x, 0, static_cast(mRenderTargetDesc.width)); - rect.top = gl::clamp(scissor.y, 0, static_cast(mRenderTargetDesc.height)); - rect.right = gl::clamp(scissor.x + scissor.width, 0, static_cast(mRenderTargetDesc.width)); - rect.bottom = gl::clamp(scissor.y + scissor.height, 0, static_cast(mRenderTargetDesc.height)); - mDevice->SetScissorRect(&rect); - } - - mDevice->SetRenderState(D3DRS_SCISSORTESTENABLE, enabled ? TRUE : FALSE); + mStateManager.setScissorState(scissor, enabled); +} - mScissorEnabled = enabled; - mCurScissor = scissor; - } +gl::Error Renderer9::setBlendDepthRasterStates(const gl::Data &glData, GLenum drawMode) +{ + int samples = glData.state->getDrawFramebuffer()->getSamples(glData); + gl::RasterizerState rasterizer = glData.state->getRasterizerState(); + rasterizer.pointDrawMode = (drawMode == GL_POINTS); + rasterizer.multiSample = (samples != 0); - mForceSetScissor = false; + unsigned int mask = GetBlendSampleMask(glData, samples); + return mStateManager.setBlendDepthRasterStates(*glData.state, mask); } -void Renderer9::setViewport(const gl::Rectangle &viewport, float zNear, float zFar, GLenum drawMode, GLenum frontFace, +void Renderer9::setViewport(const gl::Caps *caps, + const gl::Rectangle &viewport, + float zNear, + float zFar, + GLenum drawMode, + GLenum frontFace, bool ignoreViewport) { - gl::Rectangle actualViewport = viewport; - float actualZNear = gl::clamp01(zNear); - float actualZFar = gl::clamp01(zFar); - if (ignoreViewport) - { - actualViewport.x = 0; - actualViewport.y = 0; - actualViewport.width = mRenderTargetDesc.width; - actualViewport.height = mRenderTargetDesc.height; - actualZNear = 0.0f; - actualZFar = 1.0f; - } - - D3DVIEWPORT9 dxViewport; - dxViewport.X = gl::clamp(actualViewport.x, 0, static_cast(mRenderTargetDesc.width)); - dxViewport.Y = gl::clamp(actualViewport.y, 0, static_cast(mRenderTargetDesc.height)); - dxViewport.Width = gl::clamp(actualViewport.width, 0, static_cast(mRenderTargetDesc.width) - static_cast(dxViewport.X)); - dxViewport.Height = gl::clamp(actualViewport.height, 0, static_cast(mRenderTargetDesc.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); - - bool viewportChanged = mForceSetViewport || memcmp(&actualViewport, &mCurViewport, sizeof(gl::Rectangle)) != 0 || - actualZNear != mCurNear || actualZFar != mCurFar || mCurDepthFront != depthFront; - if (viewportChanged) - { - mDevice->SetViewport(&dxViewport); - - mCurViewport = actualViewport; - mCurNear = actualZNear; - mCurFar = actualZFar; - mCurDepthFront = depthFront; - - dx_VertexConstants vc = {0}; - dx_PixelConstants pc = {0}; - - vc.viewAdjust[0] = (float)((actualViewport.width - (int)dxViewport.Width) + 2 * (actualViewport.x - (int)dxViewport.X) - 1) / dxViewport.Width; - vc.viewAdjust[1] = (float)((actualViewport.height - (int)dxViewport.Height) + 2 * (actualViewport.y - (int)dxViewport.Y) - 1) / dxViewport.Height; - vc.viewAdjust[2] = (float)actualViewport.width / dxViewport.Width; - vc.viewAdjust[3] = (float)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_VertexConstants)) != 0) - { - mVertexConstants = vc; - mDxUniformsDirty = true; - } - - if (memcmp(&pc, &mPixelConstants, sizeof(dx_PixelConstants)) != 0) - { - mPixelConstants = pc; - mDxUniformsDirty = true; - } - } - - mForceSetViewport = false; + mStateManager.setViewportState(caps, viewport, zNear, zFar, drawMode, frontFace, + ignoreViewport); } bool Renderer9::applyPrimitiveType(GLenum mode, GLsizei count, bool usesPointSize) @@ -1264,15 +1025,14 @@ gl::Error Renderer9::getNullColorbuffer(const gl::FramebufferAttachment *depthbu { ASSERT(depthbuffer); - GLsizei width = depthbuffer->getWidth(); - GLsizei height = depthbuffer->getHeight(); + const gl::Extents &size = depthbuffer->getSize(); // search cached nullcolorbuffers for (int i = 0; i < NUM_NULL_COLORBUFFER_CACHE_ENTRIES; i++) { if (mNullColorbufferCache[i].buffer != NULL && - mNullColorbufferCache[i].width == width && - mNullColorbufferCache[i].height == height) + mNullColorbufferCache[i].width == size.width && + mNullColorbufferCache[i].height == size.height) { mNullColorbufferCache[i].lruCount = ++mMaxNullColorbufferLRU; *outColorBuffer = mNullColorbufferCache[i].buffer; @@ -1281,7 +1041,7 @@ gl::Error Renderer9::getNullColorbuffer(const gl::FramebufferAttachment *depthbu } gl::Renderbuffer *nullRenderbuffer = new gl::Renderbuffer(createRenderbuffer(), 0); - gl::Error error = nullRenderbuffer->setStorage(GL_NONE, width, height); + gl::Error error = nullRenderbuffer->setStorage(GL_NONE, size.width, size.height); if (error.isError()) { SafeDelete(nullRenderbuffer); @@ -1303,8 +1063,8 @@ gl::Error Renderer9::getNullColorbuffer(const gl::FramebufferAttachment *depthbu delete oldest->buffer; oldest->buffer = nullbuffer; oldest->lruCount = ++mMaxNullColorbufferLRU; - oldest->width = width; - oldest->height = height; + oldest->width = size.width; + oldest->height = size.height; *outColorBuffer = nullbuffer; return gl::Error(GL_NO_ERROR); @@ -1314,12 +1074,13 @@ gl::Error Renderer9::applyRenderTarget(const gl::FramebufferAttachment *colorAtt const gl::FramebufferAttachment *depthStencilAttachment) { const gl::FramebufferAttachment *renderAttachment = colorAttachment; + gl::Error error(GL_NO_ERROR); // 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. if (renderAttachment == nullptr) { - gl::Error error = getNullColorbuffer(depthStencilAttachment, &renderAttachment); + error = getNullColorbuffer(depthStencilAttachment, &renderAttachment); if (error.isError()) { return error; @@ -1331,19 +1092,19 @@ gl::Error Renderer9::applyRenderTarget(const gl::FramebufferAttachment *colorAtt size_t renderTargetHeight = 0; D3DFORMAT renderTargetFormat = D3DFMT_UNKNOWN; + RenderTarget9 *renderTarget = nullptr; + error = renderAttachment->getRenderTarget(&renderTarget); + if (error.isError()) + { + return error; + } + ASSERT(renderTarget); + bool renderTargetChanged = false; - unsigned int renderTargetSerial = GetAttachmentSerial(renderAttachment); + unsigned int renderTargetSerial = renderTarget->getSerial(); if (renderTargetSerial != mAppliedRenderTargetSerial) { // Apply the render target on the device - RenderTarget9 *renderTarget = nullptr; - gl::Error error = renderAttachment->getRenderTarget(&renderTarget); - if (error.isError()) - { - return error; - } - ASSERT(renderTarget); - IDirect3DSurface9 *renderTargetSurface = renderTarget->getSurface(); ASSERT(renderTargetSurface); @@ -1358,24 +1119,29 @@ gl::Error Renderer9::applyRenderTarget(const gl::FramebufferAttachment *colorAtt renderTargetChanged = true; } - unsigned int depthStencilSerial = (depthStencilAttachment != nullptr) ? - GetAttachmentSerial(depthStencilAttachment) : 0; + RenderTarget9 *depthStencilRenderTarget = nullptr; + unsigned int depthStencilSerial = 0; + + if (depthStencilAttachment != nullptr) + { + error = depthStencilAttachment->getRenderTarget(&depthStencilRenderTarget); + if (error.isError()) + { + return error; + } + ASSERT(depthStencilRenderTarget); + + depthStencilSerial = depthStencilRenderTarget->getSerial(); + } + if (depthStencilSerial != mAppliedDepthStencilSerial || !mDepthStencilInitialized) { unsigned int depthSize = 0; unsigned int stencilSize = 0; // Apply the depth stencil on the device - if (depthStencilAttachment) + if (depthStencilRenderTarget) { - RenderTarget9 *depthStencilRenderTarget = nullptr; - gl::Error error = depthStencilAttachment->getRenderTarget(&depthStencilRenderTarget); - if (error.isError()) - { - return error; - } - ASSERT(depthStencilRenderTarget); - IDirect3DSurface9 *depthStencilSurface = depthStencilRenderTarget->getSurface(); ASSERT(depthStencilSurface); @@ -1390,17 +1156,8 @@ gl::Error Renderer9::applyRenderTarget(const gl::FramebufferAttachment *colorAtt mDevice->SetDepthStencilSurface(NULL); } - if (!mDepthStencilInitialized || depthSize != mCurDepthSize) - { - mCurDepthSize = depthSize; - mForceSetRasterState = true; - } - - if (!mDepthStencilInitialized || stencilSize != mCurStencilSize) - { - mCurStencilSize = stencilSize; - mForceSetDepthStencilState = true; - } + mStateManager.updateDepthSizeIfChanged(mDepthStencilInitialized, depthSize); + mStateManager.updateStencilSizeIfChanged(mDepthStencilInitialized, stencilSize); mAppliedDepthStencilSerial = depthStencilSerial; mDepthStencilInitialized = true; @@ -1408,13 +1165,9 @@ gl::Error Renderer9::applyRenderTarget(const gl::FramebufferAttachment *colorAtt if (renderTargetChanged || !mRenderTargetDescInitialized) { - mForceSetScissor = true; - mForceSetViewport = true; - mForceSetBlendState = true; - - mRenderTargetDesc.width = renderTargetWidth; - mRenderTargetDesc.height = renderTargetHeight; - mRenderTargetDesc.format = renderTargetFormat; + mStateManager.forceSetBlendState(); + mStateManager.forceSetScissorState(); + mStateManager.setRenderTargetBounds(renderTargetWidth, renderTargetHeight); mRenderTargetDescInitialized = true; } @@ -1426,22 +1179,35 @@ gl::Error Renderer9::applyRenderTarget(const gl::Framebuffer *framebuffer) return applyRenderTarget(framebuffer->getColorbuffer(0), framebuffer->getDepthOrStencilbuffer()); } -gl::Error Renderer9::applyVertexBuffer(const gl::State &state, GLenum mode, GLint first, GLsizei count, GLsizei instances) +gl::Error Renderer9::applyVertexBuffer(const gl::State &state, + GLenum mode, + GLint first, + GLsizei count, + GLsizei instances, + TranslatedIndexData * /*indexInfo*/) { - TranslatedAttribute attributes[gl::MAX_VERTEX_ATTRIBS]; - gl::Error error = mVertexDataManager->prepareVertexData(state, first, count, attributes, instances); + gl::Error error = mVertexDataManager->prepareVertexData(state, first, count, &mTranslatedAttribCache, instances); if (error.isError()) { return error; } - return mVertexDeclarationCache.applyDeclaration(mDevice, attributes, state.getProgram(), instances, &mRepeatDraw); + return mVertexDeclarationCache.applyDeclaration( + mDevice, mTranslatedAttribCache, state.getProgram(), first, instances, &mRepeatDraw); } // Applies the indices and element array bindings to the Direct3D 9 device -gl::Error Renderer9::applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementArrayBuffer, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo) -{ - gl::Error error = mIndexDataManager->prepareIndexData(type, count, elementArrayBuffer, indices, indexInfo); +gl::Error Renderer9::applyIndexBuffer(const gl::Data &data, + const GLvoid *indices, + GLsizei count, + GLenum mode, + GLenum type, + TranslatedIndexData *indexInfo) +{ + gl::VertexArray *vao = data.state->getVertexArray(); + gl::Buffer *elementArrayBuffer = vao->getElementArrayBuffer().get(); + gl::Error error = mIndexDataManager->prepareIndexData(type, count, elementArrayBuffer, indices, + indexInfo, false); if (error.isError()) { return error; @@ -1461,12 +1227,17 @@ gl::Error Renderer9::applyIndexBuffer(const GLvoid *indices, gl::Buffer *element return gl::Error(GL_NO_ERROR); } -void Renderer9::applyTransformFeedbackBuffers(const gl::State& state) +gl::Error Renderer9::applyTransformFeedbackBuffers(const gl::State &state) { ASSERT(!state.isTransformFeedbackActiveUnpaused()); + return gl::Error(GL_NO_ERROR); } -gl::Error Renderer9::drawArrays(const gl::Data &data, GLenum mode, GLsizei count, GLsizei instances, bool usesPointSize) +gl::Error Renderer9::drawArraysImpl(const gl::Data &data, + GLenum mode, + GLint startVertex, + GLsizei count, + GLsizei instances) { ASSERT(!data.state->isTransformFeedbackActiveUnpaused()); @@ -1507,13 +1278,21 @@ gl::Error Renderer9::drawArrays(const gl::Data &data, GLenum mode, GLsizei count } } -gl::Error Renderer9::drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, - gl::Buffer *elementArrayBuffer, const TranslatedIndexData &indexInfo, GLsizei /*instances*/) +gl::Error Renderer9::drawElementsImpl(const gl::Data &data, + const TranslatedIndexData &indexInfo, + GLenum mode, + GLsizei count, + GLenum type, + const GLvoid *indices, + GLsizei /*instances*/) { startScene(); int minIndex = static_cast(indexInfo.indexRange.start); + gl::VertexArray *vao = data.state->getVertexArray(); + gl::Buffer *elementArrayBuffer = vao->getElementArrayBuffer().get(); + if (mode == GL_POINTS) { return drawIndexedPoints(count, type, indices, minIndex, elementArrayBuffer); @@ -1524,10 +1303,12 @@ gl::Error Renderer9::drawElements(GLenum mode, GLsizei count, GLenum type, const } else { + size_t vertexCount = indexInfo.indexRange.vertexCount(); for (int i = 0; i < mRepeatDraw; i++) { - GLsizei vertexCount = static_cast(indexInfo.indexRange.length()) + 1; - mDevice->DrawIndexedPrimitive(mPrimitiveType, -minIndex, minIndex, vertexCount, indexInfo.startIndex, mPrimitiveCount); + mDevice->DrawIndexedPrimitive(mPrimitiveType, -minIndex, minIndex, + static_cast(vertexCount), indexInfo.startIndex, + mPrimitiveCount); } return gl::Error(GL_NO_ERROR); } @@ -1767,7 +1548,7 @@ gl::Error Renderer9::getCountingIB(size_t count, StaticIndexBufferInterface **ou // 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 = count * sizeof(unsigned short); + const unsigned int spaceNeeded = static_cast(count) * sizeof(unsigned short); if (!mCountingIB || mCountingIB->getBufferSize() < spaceNeeded) { @@ -1797,7 +1578,7 @@ gl::Error Renderer9::getCountingIB(size_t count, StaticIndexBufferInterface **ou } else if (getRendererExtensions().elementIndexUint) { - const unsigned int spaceNeeded = count * sizeof(unsigned int); + const unsigned int spaceNeeded = static_cast(count) * sizeof(unsigned int); if (!mCountingIB || mCountingIB->getBufferSize() < spaceNeeded) { @@ -1813,7 +1594,7 @@ gl::Error Renderer9::getCountingIB(size_t count, StaticIndexBufferInterface **ou } unsigned int *data = reinterpret_cast(mappedMemory); - for (size_t i = 0; i < count; i++) + for (unsigned int i = 0; i < count; i++) { data[i] = i; } @@ -1834,13 +1615,10 @@ gl::Error Renderer9::getCountingIB(size_t count, StaticIndexBufferInterface **ou return gl::Error(GL_NO_ERROR); } -gl::Error Renderer9::applyShaders(gl::Program *program, const gl::VertexFormat inputLayout[], const gl::Framebuffer *framebuffer, - bool rasterizerDiscard, bool transformFeedbackActive) +gl::Error Renderer9::applyShadersImpl(const gl::Data &data, GLenum /*drawMode*/) { - ASSERT(!transformFeedbackActive); - ASSERT(!rasterizerDiscard); - - ProgramD3D *programD3D = GetImplAs(program); + ProgramD3D *programD3D = GetImplAs(data.state->getProgram()); + const auto &inputLayout = programD3D->getCachedInputLayout(); ShaderExecutableD3D *vertexExe = NULL; gl::Error error = programD3D->getVertexExecutableForInputLayout(inputLayout, &vertexExe, nullptr); @@ -1849,8 +1627,9 @@ gl::Error Renderer9::applyShaders(gl::Program *program, const gl::VertexFormat i return error; } + const gl::Framebuffer *drawFramebuffer = data.state->getDrawFramebuffer(); ShaderExecutableD3D *pixelExe = NULL; - error = programD3D->getPixelExecutableForFramebuffer(framebuffer, &pixelExe); + error = programD3D->getPixelExecutableForFramebuffer(drawFramebuffer, &pixelExe); if (error.isError()) { return error; @@ -1880,68 +1659,63 @@ gl::Error Renderer9::applyShaders(gl::Program *program, const gl::VertexFormat i if (programSerial != mAppliedProgramSerial) { programD3D->dirtyAllUniforms(); - mDxUniformsDirty = true; + mStateManager.forceSetDXUniformsState(); mAppliedProgramSerial = programSerial; } return gl::Error(GL_NO_ERROR); } -gl::Error Renderer9::applyUniforms(const ProgramImpl &program, const std::vector &uniformArray) +gl::Error Renderer9::applyUniforms(const ProgramD3D &programD3D, + GLenum /*drawMode*/, + const std::vector &uniformArray) { - for (size_t uniformIndex = 0; uniformIndex < uniformArray.size(); uniformIndex++) + for (const D3DUniform *targetUniform : uniformArray) { - gl::LinkedUniform *targetUniform = uniformArray[uniformIndex]; + if (!targetUniform->dirty) + continue; - if (targetUniform->dirty) - { - GLfloat *f = (GLfloat*)targetUniform->data; - GLint *i = (GLint*)targetUniform->data; + GLfloat *f = (GLfloat *)targetUniform->data; + GLint *i = (GLint *)targetUniform->data; - switch (targetUniform->type) - { - case GL_SAMPLER_2D: - case GL_SAMPLER_CUBE: + switch (targetUniform->type) + { + case GL_SAMPLER_2D: + case GL_SAMPLER_CUBE: break; - case GL_BOOL: - case GL_BOOL_VEC2: - case GL_BOOL_VEC3: - case GL_BOOL_VEC4: + 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: + 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: + case GL_INT: + case GL_INT_VEC2: + case GL_INT_VEC3: + case GL_INT_VEC4: applyUniformniv(targetUniform, i); break; - default: + default: UNREACHABLE(); - } } } // Driver uniforms - if (mDxUniformsDirty) - { - mDevice->SetVertexShaderConstantF(0, (float*)&mVertexConstants, sizeof(dx_VertexConstants) / sizeof(float[4])); - mDevice->SetPixelShaderConstantF(0, (float*)&mPixelConstants, sizeof(dx_PixelConstants) / sizeof(float[4])); - mDxUniformsDirty = false; - } + mStateManager.setShaderConstants(); return gl::Error(GL_NO_ERROR); } -void Renderer9::applyUniformnfv(gl::LinkedUniform *targetUniform, const GLfloat *v) +void Renderer9::applyUniformnfv(const D3DUniform *targetUniform, const GLfloat *v) { if (targetUniform->isReferencedByFragmentShader()) { @@ -1954,7 +1728,7 @@ void Renderer9::applyUniformnfv(gl::LinkedUniform *targetUniform, const GLfloat } } -void Renderer9::applyUniformniv(gl::LinkedUniform *targetUniform, const GLint *v) +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]; @@ -1970,7 +1744,7 @@ void Renderer9::applyUniformniv(gl::LinkedUniform *targetUniform, const GLint *v applyUniformnfv(targetUniform, (GLfloat*)vector); } -void Renderer9::applyUniformnbv(gl::LinkedUniform *targetUniform, const GLint *v) +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]; @@ -2170,14 +1944,17 @@ gl::Error Renderer9::clear(const ClearParameters &clearParams, 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] = mRenderTargetDesc.height - 0.5f; + quad[0][1] = renderTargetHeight - 0.5f; quad[0][2] = 0.0f; quad[0][3] = 1.0f; - quad[1][0] = mRenderTargetDesc.width - 0.5f; - quad[1][1] = mRenderTargetDesc.height - 0.5f; + quad[1][0] = renderTargetWidth - 0.5f; + quad[1][1] = renderTargetHeight - 0.5f; quad[1][2] = 0.0f; quad[1][3] = 1.0f; @@ -2186,7 +1963,7 @@ gl::Error Renderer9::clear(const ClearParameters &clearParams, quad[2][2] = 0.0f; quad[2][3] = 1.0f; - quad[3][0] = mRenderTargetDesc.width - 0.5f; + quad[3][0] = renderTargetWidth - 0.5f; quad[3][1] = -0.5f; quad[3][2] = 0.0f; quad[3][3] = 1.0f; @@ -2235,31 +2012,31 @@ void Renderer9::markAllStateDirty() mDepthStencilInitialized = false; mRenderTargetDescInitialized = false; - mForceSetDepthStencilState = true; - mForceSetRasterState = true; - mForceSetScissor = true; - mForceSetViewport = true; - mForceSetBlendState = true; + mStateManager.forceSetRasterState(); + mStateManager.forceSetDepthStencilState(); + mStateManager.forceSetBlendState(); + mStateManager.forceSetScissorState(); + mStateManager.forceSetViewportState(); - ASSERT(mForceSetVertexSamplerStates.size() == mCurVertexTextureSerials.size()); - for (unsigned int i = 0; i < mForceSetVertexSamplerStates.size(); i++) + ASSERT(mCurVertexSamplerStates.size() == mCurVertexTextures.size()); + for (unsigned int i = 0; i < mCurVertexTextures.size(); i++) { - mForceSetVertexSamplerStates[i] = true; - mCurVertexTextureSerials[i] = 0; + mCurVertexSamplerStates[i].forceSet = true; + mCurVertexTextures[i] = angle::DirtyPointer; } - ASSERT(mForceSetPixelSamplerStates.size() == mCurPixelTextureSerials.size()); - for (unsigned int i = 0; i < mForceSetPixelSamplerStates.size(); i++) + ASSERT(mCurPixelSamplerStates.size() == mCurPixelTextures.size()); + for (unsigned int i = 0; i < mCurPixelSamplerStates.size(); i++) { - mForceSetPixelSamplerStates[i] = true; - mCurPixelTextureSerials[i] = 0; + mCurPixelSamplerStates[i].forceSet = true; + mCurPixelTextures[i] = angle::DirtyPointer; } mAppliedIBSerial = 0; mAppliedVertexShader = NULL; mAppliedPixelShader = NULL; mAppliedProgramSerial = 0; - mDxUniformsDirty = true; + mStateManager.forceSetDXUniformsState(); mVertexDeclarationCache.markStateDirty(); } @@ -2472,19 +2249,26 @@ std::string Renderer9::getRendererDescription() const return rendererString.str(); } -GUID Renderer9::getAdapterIdentifier() const +DeviceIdentifier Renderer9::getAdapterIdentifier() const { - return mAdapterIdentifier.DeviceIdentifier; + DeviceIdentifier deviceIdentifier = { 0 }; + 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 2; // dx_ViewAdjust and dx_DepthRange. + return d3d9_gl::GetReservedVertexUniformVectors(); } unsigned int Renderer9::getReservedFragmentUniformVectors() const { - return 3; // dx_ViewCoords, dx_DepthFront and dx_DepthRange. + return d3d9_gl::GetReservedFragmentUniformVectors(); } unsigned int Renderer9::getReservedVertexUniformBuffers() const @@ -2503,11 +2287,6 @@ bool Renderer9::getShareHandleSupport() const return (mD3d9Ex != NULL) && !gl::DebugAnnotationsActive(); } -bool Renderer9::getPostSubBufferSupport() const -{ - return true; -} - int Renderer9::getMajorShaderModel() const { return D3DSHADER_VERSION_MAJOR(mDeviceCaps.PixelShaderVersion); @@ -2592,6 +2371,7 @@ gl::Error Renderer9::createRenderTarget(int width, int height, GLenum format, GL const gl::TextureCaps &textureCaps = getRendererTextureCaps().get(format); GLuint supportedSamples = textureCaps.getNearestSamples(samples); + IDirect3DTexture9 *texture = nullptr; IDirect3DSurface9 *renderTarget = NULL; if (width > 0 && height > 0) { @@ -2607,10 +2387,23 @@ gl::Error Renderer9::createRenderTarget(int width, int height, GLenum format, GL } else { - requiresInitialization = (d3d9FormatInfo.dataInitializerFunction != NULL); - result = mDevice->CreateRenderTarget(width, height, d3d9FormatInfo.renderFormat, - gl_d3d9::GetMultisampleType(supportedSamples), - 0, FALSE, &renderTarget, NULL); + 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); + } + } } if (FAILED(result)) @@ -2632,13 +2425,36 @@ gl::Error Renderer9::createRenderTarget(int width, int height, GLenum format, GL } } - *outRT = new TextureRenderTarget9(renderTarget, format, width, height, 1, supportedSamples); + *outRT = new TextureRenderTarget9(texture, 0, renderTarget, format, width, height, 1, + supportedSamples); return gl::Error(GL_NO_ERROR); } -FramebufferImpl *Renderer9::createDefaultFramebuffer(const gl::Framebuffer::Data &data) +gl::Error Renderer9::createRenderTargetCopy(RenderTargetD3D *source, RenderTargetD3D **outRT) { - return createFramebuffer(data); + ASSERT(source != nullptr); + + RenderTargetD3D *newRT = nullptr; + gl::Error error = createRenderTarget(source->getWidth(), source->getHeight(), + source->getInternalFormat(), source->getSamples(), &newRT); + if (error.isError()) + { + return error; + } + + RenderTarget9 *source9 = GetAs(source); + RenderTarget9 *dest9 = GetAs(newRT); + + HRESULT result = mDevice->StretchRect(source9->getSurface(), nullptr, dest9->getSurface(), + nullptr, D3DTEXF_NONE); + if (FAILED(result)) + { + ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to copy render target, result: 0x%X.", result); + } + + *outRT = newRT; + return gl::Error(GL_NO_ERROR); } FramebufferImpl *Renderer9::createFramebuffer(const gl::Framebuffer::Data &data) @@ -2646,27 +2462,25 @@ FramebufferImpl *Renderer9::createFramebuffer(const gl::Framebuffer::Data &data) return new Framebuffer9(data, this); } -CompilerImpl *Renderer9::createCompiler(const gl::Data &data) -{ - return new CompilerD3D(data, SH_HLSL9_OUTPUT); -} - -ShaderImpl *Renderer9::createShader(GLenum type) +ShaderImpl *Renderer9::createShader(const gl::Shader::Data &data) { - return new ShaderD3D(type); + return new ShaderD3D(data); } -ProgramImpl *Renderer9::createProgram() +ProgramImpl *Renderer9::createProgram(const gl::Program::Data &data) { - return new ProgramD3D(this); + return new ProgramD3D(data, this); } -gl::Error Renderer9::loadExecutable(const void *function, size_t length, ShaderType type, - const std::vector &transformFeedbackVaryings, - bool separatedOutputBuffers, ShaderExecutableD3D **outExecutable) +gl::Error Renderer9::loadExecutable(const void *function, + size_t length, + ShaderType type, + const std::vector &streamOutVaryings, + bool separatedOutputBuffers, + ShaderExecutableD3D **outExecutable) { // Transform feedback is not supported in ES2 or D3D9 - ASSERT(transformFeedbackVaryings.size() == 0); + ASSERT(streamOutVaryings.empty()); switch (type) { @@ -2700,13 +2514,16 @@ gl::Error Renderer9::loadExecutable(const void *function, size_t length, ShaderT return gl::Error(GL_NO_ERROR); } -gl::Error Renderer9::compileToExecutable(gl::InfoLog &infoLog, const std::string &shaderHLSL, ShaderType type, - const std::vector &transformFeedbackVaryings, - bool separatedOutputBuffers, const D3DCompilerWorkarounds &workarounds, +gl::Error Renderer9::compileToExecutable(gl::InfoLog &infoLog, + const std::string &shaderHLSL, + ShaderType type, + const std::vector &streamOutVaryings, + bool separatedOutputBuffers, + const D3DCompilerWorkarounds &workarounds, ShaderExecutableD3D **outExectuable) { // Transform feedback is not supported in ES2 or D3D9 - ASSERT(transformFeedbackVaryings.size() == 0); + ASSERT(streamOutVaryings.empty()); const char *profileType = NULL; switch (type) @@ -2769,7 +2586,7 @@ gl::Error Renderer9::compileToExecutable(gl::InfoLog &infoLog, const std::string } error = loadExecutable(binary->GetBufferPointer(), binary->GetBufferSize(), type, - transformFeedbackVaryings, separatedOutputBuffers, outExectuable); + streamOutVaryings, separatedOutputBuffers, outExectuable); SafeRelease(binary); if (error.isError()) @@ -2860,7 +2677,8 @@ gl::Error Renderer9::generateMipmap(ImageD3D *dest, ImageD3D *src) return Image9::generateMipmap(dst9, src9); } -gl::Error Renderer9::generateMipmapsUsingD3D(TextureStorage *storage, const gl::SamplerState &samplerState) +gl::Error Renderer9::generateMipmapsUsingD3D(TextureStorage *storage, + const gl::TextureState &textureState) { UNREACHABLE(); return gl::Error(GL_NO_ERROR); @@ -2872,6 +2690,11 @@ TextureStorage *Renderer9::createTextureStorage2D(SwapChainD3D *swapChain) return new TextureStorage9_2D(this, swapChain9); } +TextureStorage *Renderer9::createTextureStorageEGLImage(EGLImageD3D *eglImage) +{ + return new TextureStorage9_EGLImage(this, eglImage); +} + TextureStorage *Renderer9::createTextureStorage2D(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, int levels, bool hintLevelZeroOnly) { return new TextureStorage9_2D(this, internalformat, renderTarget, width, height, levels); @@ -2930,24 +2753,107 @@ bool Renderer9::getLUID(LUID *adapterLuid) const return false; } -VertexConversionType Renderer9::getVertexConversionType(const gl::VertexFormat &vertexFormat) const +VertexConversionType Renderer9::getVertexConversionType(gl::VertexFormatType vertexFormatType) const { - return d3d9::GetVertexFormatInfo(getCapsDeclTypes(), vertexFormat).conversionType; + return d3d9::GetVertexFormatInfo(getCapsDeclTypes(), vertexFormatType).conversionType; } -GLenum Renderer9::getVertexComponentType(const gl::VertexFormat &vertexFormat) const +GLenum Renderer9::getVertexComponentType(gl::VertexFormatType vertexFormatType) const { - return d3d9::GetVertexFormatInfo(getCapsDeclTypes(), vertexFormat).componentType; + return d3d9::GetVertexFormatInfo(getCapsDeclTypes(), vertexFormatType).componentType; +} + +gl::ErrorOrResult Renderer9::getVertexSpaceRequired(const gl::VertexAttribute &attrib, + GLsizei count, + GLsizei instances) const +{ + gl::VertexFormatType vertexFormatType = gl::GetVertexFormatType(attrib, GL_FLOAT); + const d3d9::VertexFormat &d3d9VertexInfo = + d3d9::GetVertexFormatInfo(getCapsDeclTypes(), vertexFormatType); + + if (!attrib.enabled) + { + return 16u; + } + + unsigned int elementCount = 0; + if (instances == 0 || attrib.divisor == 0) + { + elementCount = static_cast(count); + } + else + { + // Round up to divisor, if possible + elementCount = UnsignedCeilDivide(static_cast(instances), attrib.divisor); + } + + if (d3d9VertexInfo.outputElementSize > std::numeric_limits::max() / elementCount) + { + return gl::Error(GL_OUT_OF_MEMORY, "New vertex buffer size would result in an overflow."); + } + + return static_cast(d3d9VertexInfo.outputElementSize) * elementCount; } -void Renderer9::generateCaps(gl::Caps *outCaps, gl::TextureCapsMap *outTextureCaps, gl::Extensions *outExtensions) const +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); + d3d9_gl::GenerateCaps(mD3d9, mDevice, mDeviceType, mAdapter, outCaps, outTextureCaps, + outExtensions, outLimitations); } -Workarounds Renderer9::generateWorkarounds() const +WorkaroundsD3D Renderer9::generateWorkarounds() const { return d3d9::GenerateWorkarounds(); } +void Renderer9::createAnnotator() +{ + mAnnotator = new DebugAnnotator9(); +} + +gl::Error Renderer9::clearTextures(gl::SamplerType samplerType, size_t rangeStart, size_t rangeEnd) +{ + // TODO(jmadill): faster way? + for (size_t samplerIndex = rangeStart; samplerIndex < rangeEnd; samplerIndex++) + { + gl::Error error = setTexture(samplerType, static_cast(samplerIndex), nullptr); + if (error.isError()) + { + return error; + } + } + + return gl::Error(GL_NO_ERROR); +} + +egl::Error Renderer9::getEGLDevice(DeviceImpl **device) +{ + if (mEGLDevice == nullptr) + { + ASSERT(mDevice != nullptr); + mEGLDevice = new DeviceD3D(); + egl::Error error = mEGLDevice->initialize(reinterpret_cast(mDevice), + EGL_D3D9_DEVICE_ANGLE, EGL_FALSE); + + if (error.isError()) + { + SafeDelete(mEGLDevice); + return error; + } + } + + *device = static_cast(mEGLDevice); + return egl::Error(EGL_SUCCESS); +} + +Renderer9::CurSamplerState::CurSamplerState() + : forceSet(true), + baseLevel(std::numeric_limits::max()), + samplerState() +{ +} + } diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/Renderer9.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/Renderer9.h index dc9725e37844..b6456ae12f53 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/Renderer9.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/Renderer9.h @@ -17,6 +17,7 @@ #include "libANGLE/renderer/d3d/d3d9/DebugAnnotator9.h" #include "libANGLE/renderer/d3d/d3d9/ShaderCache.h" #include "libANGLE/renderer/d3d/d3d9/VertexDeclarationCache.h" +#include "libANGLE/renderer/d3d/d3d9/StateManager9.h" namespace gl { @@ -32,10 +33,12 @@ namespace rx { class Blit9; class IndexDataManager; +class ProgramD3D; class StreamingIndexBufferInterface; class StaticIndexBufferInterface; class VertexDataManager; struct ClearParameters; +struct D3DUniform; struct TranslatedAttribute; enum D3D9InitError @@ -68,6 +71,7 @@ class Renderer9 : public RendererD3D virtual bool resetDevice(); egl::ConfigSet generateConfigs() const override; + void generateDisplayExtensions(egl::DisplayExtensions *outExtensions) const override; void startScene(); void endScene(); @@ -75,8 +79,13 @@ class Renderer9 : public RendererD3D gl::Error flush() override; gl::Error finish() override; - bool shouldCreateChildWindowForSurface(EGLNativeWindowType window) const override; - virtual SwapChainD3D *createSwapChain(NativeWindow nativeWindow, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat); + SwapChainD3D *createSwapChain(NativeWindow nativeWindow, + HANDLE shareHandle, + GLenum backBufferFormat, + GLenum depthBufferFormat, + EGLint orientation) override; + + CompilerImpl *createCompiler() override; gl::Error allocateEventQuery(IDirect3DQuery9 **outQuery); void freeEventQuery(IDirect3DQuery9* query); @@ -91,34 +100,41 @@ class Renderer9 : public RendererD3D virtual gl::Error setTexture(gl::SamplerType type, int index, gl::Texture *texture); gl::Error setUniformBuffers(const gl::Data &data, - const GLint vertexUniformBuffers[], - const GLint fragmentUniformBuffers[]) override; + const std::vector &vertexUniformBuffers, + const std::vector &fragmentUniformBuffers) override; - virtual gl::Error setRasterizerState(const gl::RasterizerState &rasterState); - gl::Error setBlendState(const gl::Framebuffer *framebuffer, const gl::BlendState &blendState, const gl::ColorF &blendColor, - unsigned int sampleMask) override; - virtual gl::Error setDepthStencilState(const gl::DepthStencilState &depthStencilState, int stencilRef, - int stencilBackRef, bool frontFaceCCW); + gl::Error updateState(const gl::Data &data, GLenum drawMode) override; - virtual void setScissorRectangle(const gl::Rectangle &scissor, bool enabled); - virtual void setViewport(const gl::Rectangle &viewport, float zNear, float zFar, GLenum drawMode, GLenum frontFace, - bool ignoreViewport); + void setScissorRectangle(const gl::Rectangle &scissor, bool enabled); + void setViewport(const gl::Caps *caps, + const gl::Rectangle &viewport, + float zNear, + float zFar, + GLenum drawMode, + GLenum frontFace, + bool ignoreViewport); gl::Error applyRenderTarget(const gl::Framebuffer *frameBuffer) override; gl::Error applyRenderTarget(const gl::FramebufferAttachment *colorAttachment, const gl::FramebufferAttachment *depthStencilAttachment); - virtual gl::Error applyShaders(gl::Program *program, const gl::VertexFormat inputLayout[], const gl::Framebuffer *framebuffer, - bool rasterizerDiscard, bool transformFeedbackActive); - virtual gl::Error applyUniforms(const ProgramImpl &program, const std::vector &uniformArray); + gl::Error applyUniforms(const ProgramD3D &programD3D, + GLenum drawMode, + const std::vector &uniformArray) override; virtual bool applyPrimitiveType(GLenum primitiveType, GLsizei elementCount, bool usesPointSize); - virtual gl::Error applyVertexBuffer(const gl::State &state, GLenum mode, GLint first, GLsizei count, GLsizei instances); - virtual gl::Error applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementArrayBuffer, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo); - - void applyTransformFeedbackBuffers(const gl::State &state) override; - - gl::Error drawArrays(const gl::Data &data, GLenum mode, GLsizei count, GLsizei instances, bool usesPointSize) override; - virtual gl::Error drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, - gl::Buffer *elementArrayBuffer, const TranslatedIndexData &indexInfo, GLsizei instances); + virtual gl::Error applyVertexBuffer(const gl::State &state, + GLenum mode, + GLint first, + GLsizei count, + GLsizei instances, + TranslatedIndexData *indexInfo); + gl::Error applyIndexBuffer(const gl::Data &data, + const GLvoid *indices, + GLsizei count, + GLenum mode, + GLenum type, + TranslatedIndexData *indexInfo) override; + + gl::Error applyTransformFeedbackBuffers(const gl::State &state) override; gl::Error clear(const ClearParameters &clearParams, const gl::FramebufferAttachment *colorBuffer, @@ -130,9 +146,9 @@ class Renderer9 : public RendererD3D bool testDeviceLost() override; bool testDeviceResettable() override; - VendorID getVendorId() const override; + VendorID getVendorId() const; std::string getRendererDescription() const override; - GUID getAdapterIdentifier() const override; + DeviceIdentifier getAdapterIdentifier() const override; IDirect3DDevice9 *getDevice() { return mDevice; } void *getD3DDevice() override; @@ -141,8 +157,8 @@ class Renderer9 : public RendererD3D virtual unsigned int getReservedFragmentUniformVectors() const; virtual unsigned int getReservedVertexUniformBuffers() const; virtual unsigned int getReservedFragmentUniformBuffers() const; - virtual bool getShareHandleSupport() const; - virtual bool getPostSubBufferSupport() const; + + bool getShareHandleSupport() const; virtual int getMajorShaderModel() const; int getMinorShaderModel() const override; @@ -162,31 +178,38 @@ class Renderer9 : public RendererD3D // RenderTarget creation virtual gl::Error createRenderTarget(int width, int height, GLenum format, GLsizei samples, RenderTargetD3D **outRT); + gl::Error createRenderTargetCopy(RenderTargetD3D *source, RenderTargetD3D **outRT) override; // Framebuffer creation - FramebufferImpl *createDefaultFramebuffer(const gl::Framebuffer::Data &data) override; FramebufferImpl *createFramebuffer(const gl::Framebuffer::Data &data) override; // Shader creation - virtual CompilerImpl *createCompiler(const gl::Data &data); - virtual ShaderImpl *createShader(GLenum type); - virtual ProgramImpl *createProgram(); + ShaderImpl *createShader(const gl::Shader::Data &data) override; + ProgramImpl *createProgram(const gl::Program::Data &data) override; // Shader operations - virtual gl::Error loadExecutable(const void *function, size_t length, ShaderType type, - const std::vector &transformFeedbackVaryings, - bool separatedOutputBuffers, ShaderExecutableD3D **outExecutable); - virtual gl::Error compileToExecutable(gl::InfoLog &infoLog, const std::string &shaderHLSL, ShaderType type, - const std::vector &transformFeedbackVaryings, - bool separatedOutputBuffers, const D3DCompilerWorkarounds &workarounds, - ShaderExecutableD3D **outExectuable); - virtual UniformStorageD3D *createUniformStorage(size_t storageSize); + gl::Error loadExecutable(const void *function, + size_t length, + ShaderType type, + const std::vector &streamOutVaryings, + bool separatedOutputBuffers, + ShaderExecutableD3D **outExecutable) override; + gl::Error compileToExecutable(gl::InfoLog &infoLog, + const std::string &shaderHLSL, + ShaderType type, + const std::vector &streamOutVaryings, + bool separatedOutputBuffers, + const D3DCompilerWorkarounds &workarounds, + ShaderExecutableD3D **outExectuable) override; + UniformStorageD3D *createUniformStorage(size_t storageSize) override; // Image operations virtual ImageD3D *createImage(); gl::Error generateMipmap(ImageD3D *dest, ImageD3D *source) override; - gl::Error generateMipmapsUsingD3D(TextureStorage *storage, const gl::SamplerState &samplerState) override; + gl::Error generateMipmapsUsingD3D(TextureStorage *storage, + const gl::TextureState &textureState) override; virtual TextureStorage *createTextureStorage2D(SwapChainD3D *swapChain); + TextureStorage *createTextureStorageEGLImage(EGLImageD3D *eglImage) override; virtual TextureStorage *createTextureStorage2D(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, int levels, bool hintLevelZeroOnly); virtual TextureStorage *createTextureStorageCube(GLenum internalformat, bool renderTarget, int size, int levels, bool hintLevelZeroOnly); virtual TextureStorage *createTextureStorage3D(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, GLsizei depth, int levels); @@ -204,7 +227,7 @@ class Renderer9 : public RendererD3D virtual IndexBuffer *createIndexBuffer(); // Vertex Array creation - virtual VertexArrayImpl *createVertexArray(); + VertexArrayImpl *createVertexArray(const gl::VertexArray::Data &data) override; // Query and Fence creation virtual QueryImpl *createQuery(GLenum type); @@ -214,19 +237,27 @@ class Renderer9 : public RendererD3D // Transform Feedback creation virtual TransformFeedbackImpl* createTransformFeedback(); + // Stream Creation + StreamImpl *createStream(const egl::AttributeMap &attribs) override; + // Buffer-to-texture and Texture-to-buffer copies virtual bool supportsFastCopyBufferToTexture(GLenum internalFormat) const; virtual gl::Error fastCopyBufferToTexture(const gl::PixelUnpackState &unpack, unsigned int offset, RenderTargetD3D *destRenderTarget, GLenum destinationFormat, GLenum sourcePixelsType, const gl::Box &destArea); + void syncState(const gl::State &state, const gl::State::DirtyBits &bitmask) override; + // D3D9-renderer specific methods gl::Error boxFilter(IDirect3DSurface9 *source, IDirect3DSurface9 *dest); D3DPOOL getTexturePool(DWORD usage) const; bool getLUID(LUID *adapterLuid) const override; - virtual VertexConversionType getVertexConversionType(const gl::VertexFormat &vertexFormat) const; - virtual GLenum getVertexComponentType(const gl::VertexFormat &vertexFormat) const; + VertexConversionType getVertexConversionType(gl::VertexFormatType vertexFormatType) const override; + GLenum getVertexComponentType(gl::VertexFormatType vertexFormatType) const override; + gl::ErrorOrResult getVertexSpaceRequired(const gl::VertexAttribute &attrib, + GLsizei count, + GLsizei instances) const override; gl::Error copyToRenderTarget(IDirect3DSurface9 *dest, IDirect3DSurface9 *source, bool fromManaged); @@ -234,15 +265,40 @@ class Renderer9 : public RendererD3D D3DDEVTYPE getD3D9DeviceType() const { return mDeviceType; } + egl::Error getEGLDevice(DeviceImpl **device) override; + + protected: + void createAnnotator() override; + gl::Error clearTextures(gl::SamplerType samplerType, size_t rangeStart, size_t rangeEnd) override; + gl::Error applyShadersImpl(const gl::Data &data, GLenum drawMode) override; + private: - void generateCaps(gl::Caps *outCaps, gl::TextureCapsMap *outTextureCaps, gl::Extensions *outExtensions) const override; - Workarounds generateWorkarounds() const override; + gl::Error drawArraysImpl(const gl::Data &data, + GLenum mode, + GLint startVertex, + GLsizei count, + GLsizei instances) override; + gl::Error drawElementsImpl(const gl::Data &data, + const TranslatedIndexData &indexInfo, + GLenum mode, + GLsizei count, + GLenum type, + const GLvoid *indices, + GLsizei instances) override; + + void generateCaps(gl::Caps *outCaps, gl::TextureCapsMap *outTextureCaps, + gl::Extensions *outExtensions, + gl::Limitations *outLimitations) const override; + + WorkaroundsD3D generateWorkarounds() const override; + + gl::Error setBlendDepthRasterStates(const gl::Data &glData, GLenum drawMode); void release(); - void applyUniformnfv(gl::LinkedUniform *targetUniform, const GLfloat *v); - void applyUniformniv(gl::LinkedUniform *targetUniform, const GLint *v); - void applyUniformnbv(gl::LinkedUniform *targetUniform, const GLint *v); + void applyUniformnfv(const D3DUniform *targetUniform, const GLfloat *v); + void applyUniformniv(const D3DUniform *targetUniform, const GLint *v); + void applyUniformnbv(const D3DUniform *targetUniform, const GLint *v); gl::Error drawLineLoop(GLsizei count, GLenum type, const GLvoid *indices, int minIndex, gl::Buffer *elementArrayBuffer); gl::Error drawIndexedPoints(GLsizei count, GLenum type, const GLvoid *indices, int minIndex, gl::Buffer *elementArrayBuffer); @@ -292,64 +348,32 @@ class Renderer9 : public RendererD3D unsigned int mAppliedDepthStencilSerial; bool mDepthStencilInitialized; bool mRenderTargetDescInitialized; - unsigned int mCurStencilSize; - unsigned int mCurDepthSize; - - struct RenderTargetDesc - { - size_t width; - size_t height; - D3DFORMAT format; - }; - RenderTargetDesc mRenderTargetDesc; IDirect3DStateBlock9 *mMaskedClearSavedState; - // previously set render states - bool mForceSetDepthStencilState; - gl::DepthStencilState mCurDepthStencilState; - int mCurStencilRef; - int mCurStencilBackRef; - bool mCurFrontFaceCCW; - - bool mForceSetRasterState; - gl::RasterizerState mCurRasterState; - - bool mForceSetScissor; - gl::Rectangle mCurScissor; - bool mScissorEnabled; - - bool mForceSetViewport; - gl::Rectangle mCurViewport; - float mCurNear; - float mCurFar; - float mCurDepthFront; - - bool mForceSetBlendState; - gl::BlendState mCurBlendState; - gl::ColorF mCurBlendColor; - GLuint mCurSampleMask; + StateManager9 mStateManager; // Currently applied sampler states - std::vector mForceSetVertexSamplerStates; - std::vector mCurVertexSamplerStates; + struct CurSamplerState + { + CurSamplerState(); - std::vector mForceSetPixelSamplerStates; - std::vector mCurPixelSamplerStates; + bool forceSet; + size_t baseLevel; + gl::SamplerState samplerState; + }; + std::vector mCurVertexSamplerStates; + std::vector mCurPixelSamplerStates; // Currently applied textures - std::vector mCurVertexTextureSerials; - std::vector mCurPixelTextureSerials; + std::vector mCurVertexTextures; + std::vector mCurPixelTextures; unsigned int mAppliedIBSerial; IDirect3DVertexShader9 *mAppliedVertexShader; IDirect3DPixelShader9 *mAppliedPixelShader; unsigned int mAppliedProgramSerial; - dx_VertexConstants mVertexConstants; - dx_PixelConstants mPixelConstants; - bool mDxUniformsDirty; - // A pool of event queries that are currently unused. std::vector mEventQueryPool; VertexShaderCache mVertexShaderCache; @@ -372,7 +396,8 @@ class Renderer9 : public RendererD3D } mNullColorbufferCache[NUM_NULL_COLORBUFFER_CACHE_ENTRIES]; UINT mMaxNullColorbufferLRU; - DebugAnnotator9 mAnnotator; + DeviceD3D *mEGLDevice; + std::vector mTranslatedAttribCache; }; } diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/ShaderExecutable9.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/ShaderExecutable9.cpp index 28a486056b6c..dcce8fd2f251 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/ShaderExecutable9.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/ShaderExecutable9.cpp @@ -44,4 +44,4 @@ IDirect3DPixelShader9 *ShaderExecutable9::getPixelShader() const return mPixelExecutable; } -} \ No newline at end of file +} diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/StateManager9.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/StateManager9.cpp new file mode 100644 index 000000000000..c4c600aedb84 --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/StateManager9.cpp @@ -0,0 +1,903 @@ +// +// Copyright (c) 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/BitSetIterator.h" +#include "common/utilities.h" +#include "libANGLE/formatutils.h" +#include "libANGLE/renderer/d3d/d3d9/renderer9_utils.h" +#include "libANGLE/renderer/d3d/d3d9/Framebuffer9.h" +#include "libANGLE/renderer/d3d/d3d9/Renderer9.h" + +namespace rx +{ + +StateManager9::StateManager9(Renderer9 *renderer9) + : 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::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 : angle::IterateBitSet(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); + } + 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); + } + 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); + } + break; + } + case gl::State::DIRTY_BIT_SAMPLE_ALPHA_TO_COVERAGE_ENABLED: + if (state.getBlendState().sampleAlphaToCoverage != + mCurBlendState.sampleAlphaToCoverage) + { + 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); + } + break; + } + case gl::State::DIRTY_BIT_DITHER_ENABLED: + if (state.getBlendState().dither != mCurBlendState.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); + } + } + 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: + if (state.getDepthStencilState().depthTest != mCurDepthStencilState.depthTest) + { + mDirtyBits.set(DIRTY_BIT_STENCIL_DEPTH_FUNC); + } + break; + case gl::State::DIRTY_BIT_DEPTH_FUNC: + if (state.getDepthStencilState().depthFunc != mCurDepthStencilState.depthFunc) + { + mDirtyBits.set(DIRTY_BIT_STENCIL_DEPTH_FUNC); + } + break; + case gl::State::DIRTY_BIT_STENCIL_TEST_ENABLED: + if (state.getDepthStencilState().stencilTest != mCurDepthStencilState.stencilTest) + { + 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: + { + const gl::DepthStencilState &depthStencilState = state.getDepthStencilState(); + if (depthStencilState.stencilFunc != mCurDepthStencilState.stencilFunc || + depthStencilState.stencilMask != mCurDepthStencilState.stencilMask || + state.getStencilRef() != mCurStencilRef) + { + mDirtyBits.set(DIRTY_BIT_STENCIL_FUNCS_FRONT); + } + break; + } + case gl::State::DIRTY_BIT_STENCIL_FUNCS_BACK: + { + const gl::DepthStencilState &depthStencilState = state.getDepthStencilState(); + if (depthStencilState.stencilBackFunc != mCurDepthStencilState.stencilBackFunc || + depthStencilState.stencilBackMask != mCurDepthStencilState.stencilBackMask || + state.getStencilBackRef() != mCurStencilBackRef) + { + mDirtyBits.set(DIRTY_BIT_STENCIL_FUNCS_BACK); + } + break; + } + case gl::State::DIRTY_BIT_STENCIL_WRITEMASK_FRONT: + if (state.getDepthStencilState().stencilWritemask != + mCurDepthStencilState.stencilWritemask) + { + mDirtyBits.set(DIRTY_BIT_STENCIL_WRITEMASK_FRONT); + } + break; + case gl::State::DIRTY_BIT_STENCIL_WRITEMASK_BACK: + if (state.getDepthStencilState().stencilBackWritemask != + mCurDepthStencilState.stencilBackWritemask) + { + mDirtyBits.set(DIRTY_BIT_STENCIL_WRITEMASK_BACK); + } + break; + case gl::State::DIRTY_BIT_STENCIL_OPS_FRONT: + { + const gl::DepthStencilState &depthStencilState = state.getDepthStencilState(); + if (depthStencilState.stencilFail != mCurDepthStencilState.stencilFail || + depthStencilState.stencilPassDepthFail != + mCurDepthStencilState.stencilPassDepthFail || + depthStencilState.stencilPassDepthPass != + mCurDepthStencilState.stencilPassDepthPass) + { + mDirtyBits.set(DIRTY_BIT_STENCIL_OPS_FRONT); + } + break; + } + case gl::State::DIRTY_BIT_STENCIL_OPS_BACK: + { + const gl::DepthStencilState &depthStencilState = state.getDepthStencilState(); + if (depthStencilState.stencilBackFail != mCurDepthStencilState.stencilBackFail || + depthStencilState.stencilBackPassDepthFail != + mCurDepthStencilState.stencilBackPassDepthFail || + depthStencilState.stencilBackPassDepthPass != + mCurDepthStencilState.stencilBackPassDepthPass) + { + 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: + if (state.getNearPlane() != mCurNear || state.getFarPlane() != mCurFar) + { + mDirtyBits.set(DIRTY_BIT_VIEWPORT); + } + break; + case gl::State::DIRTY_BIT_VIEWPORT: + if (state.getViewport() != mCurViewport) + { + mDirtyBits.set(DIRTY_BIT_VIEWPORT); + } + break; + default: + break; + } + } +} + +gl::Error 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 : angle::IterateBitSet(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(blendState.sampleAlphaToCoverage); + break; + case DIRTY_BIT_COLOR_MASK: + setColorMask(framebuffer, blendState.colorMaskRed, blendState.colorMaskBlue, + blendState.colorMaskGreen, blendState.colorMaskAlpha); + break; + case DIRTY_BIT_DITHER: + setDither(blendState.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); + } + + return gl::Error(GL_NO_ERROR); +} + +void StateManager9::setViewportState(const gl::Caps *caps, + const gl::Rectangle &viewport, + float zNear, + float zFar, + GLenum 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); + } + 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) + { + FIXME("Sample alpha to coverage is 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); + mCurBlendState.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 + bool zeroColorMaskAllowed = mRenderer9->getVendorId() != VENDOR_ID_AMD; + // 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://code.google.com/p/angleproject/issues/detail?id=169 + + const gl::FramebufferAttachment *attachment = framebuffer->getFirstColorbuffer(); + GLenum internalFormat = attachment ? attachment->getInternalFormat() : GL_NONE; + + const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalFormat); + + DWORD colorMask = gl_d3d9::ConvertColorMask( + formatInfo.redBits > 0 && red, formatInfo.greenBits > 0 && green, + formatInfo.blueBits > 0 && blue, formatInfo.alphaBits > 0 && alpha); + + if (colorMask == 0 && !zeroColorMaskAllowed) + { + 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); + } + 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, GLenum 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/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/StateManager9.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/StateManager9.h new file mode 100644 index 000000000000..d8c1eb9812ae --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/StateManager9.h @@ -0,0 +1,206 @@ +// +// Copyright (c) 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/angletypes.h" +#include "libANGLE/Data.h" +#include "libANGLE/State.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 syncState(const gl::State &state, const gl::State::DirtyBits &dirtyBits); + + gl::Error setBlendDepthRasterStates(const gl::State &glState, unsigned int sampleMask); + void setScissorState(const gl::Rectangle &scissor, bool enabled); + void setViewportState(const gl::Caps *caps, + const gl::Rectangle &viewport, + float zNear, + float zFar, + GLenum 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 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, GLenum 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 + }; + + typedef std::bitset DirtyBits; + + // 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/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/SwapChain9.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/SwapChain9.cpp index ab2ce350913c..be6a9c424ca0 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/SwapChain9.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/SwapChain9.cpp @@ -15,21 +15,26 @@ namespace rx { -SwapChain9::SwapChain9(Renderer9 *renderer, NativeWindow nativeWindow, HANDLE shareHandle, - GLenum backBufferFormat, GLenum depthBufferFormat) - : mRenderer(renderer), - SwapChainD3D(nativeWindow, shareHandle, backBufferFormat, depthBufferFormat), +SwapChain9::SwapChain9(Renderer9 *renderer, + NativeWindow nativeWindow, + HANDLE shareHandle, + GLenum backBufferFormat, + GLenum depthBufferFormat, + EGLint orientation) + : SwapChainD3D(nativeWindow, shareHandle, backBufferFormat, depthBufferFormat), + mRenderer(renderer), + mWidth(-1), + mHeight(-1), + mSwapInterval(-1), + mSwapChain(nullptr), + mBackBuffer(nullptr), + mRenderTarget(nullptr), + mDepthStencil(nullptr), + mOffscreenTexture(nullptr), mColorRenderTarget(this, false), mDepthStencilRenderTarget(this, true) { - mSwapChain = NULL; - mBackBuffer = NULL; - mDepthStencil = NULL; - mRenderTarget = NULL; - mOffscreenTexture = NULL; - mWidth = -1; - mHeight = -1; - mSwapInterval = -1; + ASSERT(orientation == 0); } SwapChain9::~SwapChain9() @@ -104,7 +109,7 @@ EGLint SwapChain9::reset(int backbufferWidth, int backbufferHeight, EGLint swapI pShareHandle = &mShareHandle; } - const d3d9::TextureFormat &backBufferd3dFormatInfo = d3d9::GetTextureFormatInfo(mBackBufferFormat); + const d3d9::TextureFormat &backBufferd3dFormatInfo = d3d9::GetTextureFormatInfo(mOffscreenRenderTargetFormat); result = device->CreateTexture(backbufferWidth, backbufferHeight, 1, D3DUSAGE_RENDERTARGET, backBufferd3dFormatInfo.texFormat, D3DPOOL_DEFAULT, &mOffscreenTexture, pShareHandle); @@ -312,8 +317,8 @@ EGLint SwapChain9::swapRect(EGLint x, EGLint y, EGLint width, EGLint height) RECT rect = { - x, mHeight - y - height, - x + width, mHeight - y + static_cast(x), static_cast(mHeight - y - height), + static_cast(x + width), static_cast(mHeight - y) }; HRESULT result = mSwapChain->Present(&rect, &rect, NULL, NULL, 0); @@ -384,6 +389,12 @@ IDirect3DTexture9 *SwapChain9::getOffscreenTexture() return mOffscreenTexture; } +void *SwapChain9::getKeyedMutex() +{ + UNREACHABLE(); + return nullptr; +} + void SwapChain9::recreate() { if (!mSwapChain) diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/SwapChain9.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/SwapChain9.h index a7517b5fd3b0..55a700c2d64b 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/SwapChain9.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/SwapChain9.h @@ -20,8 +20,12 @@ class Renderer9; class SwapChain9 : public SwapChainD3D { public: - SwapChain9(Renderer9 *renderer, NativeWindow nativeWindow, HANDLE shareHandle, - GLenum backBufferFormat, GLenum depthBufferFormat); + SwapChain9(Renderer9 *renderer, + NativeWindow nativeWindow, + HANDLE shareHandle, + GLenum backBufferFormat, + GLenum depthBufferFormat, + EGLint orientation); virtual ~SwapChain9(); EGLint resize(EGLint backbufferWidth, EGLint backbufferHeight); @@ -39,12 +43,14 @@ class SwapChain9 : public SwapChainD3D EGLint getWidth() const { return mWidth; } EGLint getHeight() const { return mHeight; } + void *getKeyedMutex() override; + private: void release(); Renderer9 *mRenderer; - EGLint mHeight; EGLint mWidth; + EGLint mHeight; EGLint mSwapInterval; IDirect3DSwapChain9 *mSwapChain; diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/TextureStorage9.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/TextureStorage9.cpp index 59af582e6b74..b28d5076b5a9 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/TextureStorage9.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/TextureStorage9.cpp @@ -9,14 +9,16 @@ // D3D9 texture. #include "libANGLE/renderer/d3d/d3d9/TextureStorage9.h" -#include "libANGLE/renderer/d3d/d3d9/Renderer9.h" -#include "libANGLE/renderer/d3d/d3d9/SwapChain9.h" -#include "libANGLE/renderer/d3d/d3d9/RenderTarget9.h" -#include "libANGLE/renderer/d3d/d3d9/renderer9_utils.h" -#include "libANGLE/renderer/d3d/d3d9/formatutils9.h" -#include "libANGLE/renderer/d3d/TextureD3D.h" + #include "libANGLE/formatutils.h" #include "libANGLE/Texture.h" +#include "libANGLE/renderer/d3d/EGLImageD3D.h" +#include "libANGLE/renderer/d3d/TextureD3D.h" +#include "libANGLE/renderer/d3d/d3d9/formatutils9.h" +#include "libANGLE/renderer/d3d/d3d9/renderer9_utils.h" +#include "libANGLE/renderer/d3d/d3d9/Renderer9.h" +#include "libANGLE/renderer/d3d/d3d9/RenderTarget9.h" +#include "libANGLE/renderer/d3d/d3d9/SwapChain9.h" namespace rx { @@ -88,7 +90,7 @@ int TextureStorage9::getTopLevel() const int TextureStorage9::getLevelCount() const { - return mMipLevels - mTopLevel; + return static_cast(mMipLevels) - mTopLevel; } gl::Error TextureStorage9::setData(const gl::ImageIndex &index, ImageD3D *image, const gl::Box *destBox, GLenum type, @@ -105,7 +107,7 @@ TextureStorage9_2D::TextureStorage9_2D(Renderer9 *renderer, SwapChain9 *swapchai mTexture = surfaceTexture; mMipLevels = surfaceTexture->GetLevelCount(); - mInternalFormat = swapchain->GetBackBufferInternalFormat(); + mInternalFormat = swapchain->GetRenderTargetInternalFormat(); D3DSURFACE_DESC surfaceDesc; surfaceTexture->GetLevelDesc(0, &surfaceDesc); @@ -113,16 +115,13 @@ TextureStorage9_2D::TextureStorage9_2D(Renderer9 *renderer, SwapChain9 *swapchai mTextureHeight = surfaceDesc.Height; mTextureFormat = surfaceDesc.Format; - mRenderTarget = NULL; - - initializeSerials(1, 1); + mRenderTargets.resize(mMipLevels, nullptr); } TextureStorage9_2D::TextureStorage9_2D(Renderer9 *renderer, GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, int levels) : TextureStorage9(renderer, GetTextureUsage(internalformat, renderTarget)) { mTexture = NULL; - mRenderTarget = NULL; mInternalFormat = internalformat; @@ -134,19 +133,28 @@ TextureStorage9_2D::TextureStorage9_2D(Renderer9 *renderer, GLenum internalforma mTextureHeight = height; mMipLevels = mTopLevel + levels; - initializeSerials(getLevelCount(), 1); + mRenderTargets.resize(levels, nullptr); } TextureStorage9_2D::~TextureStorage9_2D() { SafeRelease(mTexture); - SafeDelete(mRenderTarget); + for (auto &renderTarget : mRenderTargets) + { + SafeDelete(renderTarget); + } } // Increments refcount on surface. // caller must Release() the returned surface -gl::Error TextureStorage9_2D::getSurfaceLevel(int level, bool dirty, IDirect3DSurface9 **outSurface) +gl::Error TextureStorage9_2D::getSurfaceLevel(GLenum target, + int level, + bool dirty, + IDirect3DSurface9 **outSurface) { + ASSERT(target == GL_TEXTURE_2D); + UNUSED_ASSERTION_VARIABLE(target); + IDirect3DBaseTexture9 *baseTexture = NULL; gl::Error error = getBaseTexture(&baseTexture); if (error.isError()) @@ -173,36 +181,52 @@ gl::Error TextureStorage9_2D::getSurfaceLevel(int level, bool dirty, IDirect3DSu return gl::Error(GL_NO_ERROR); } -gl::Error TextureStorage9_2D::getRenderTarget(const gl::ImageIndex &/*index*/, RenderTargetD3D **outRT) +gl::Error TextureStorage9_2D::getRenderTarget(const gl::ImageIndex &index, RenderTargetD3D **outRT) { - if (!mRenderTarget && isRenderTarget()) + ASSERT(index.mipIndex < getLevelCount()); + + if (!mRenderTargets[index.mipIndex] && isRenderTarget()) { + IDirect3DBaseTexture9 *baseTexture = NULL; + gl::Error error = getBaseTexture(&baseTexture); + if (error.isError()) + { + return error; + } + IDirect3DSurface9 *surface = NULL; - gl::Error error = getSurfaceLevel(0, false, &surface); + error = getSurfaceLevel(GL_TEXTURE_2D, index.mipIndex, false, &surface); if (error.isError()) { return error; } - mRenderTarget = new TextureRenderTarget9(surface, mInternalFormat, mTextureWidth, mTextureHeight, 1, 0); + size_t textureMipLevel = mTopLevel + index.mipIndex; + size_t mipWidth = std::max(mTextureWidth >> textureMipLevel, 1u); + size_t mipHeight = std::max(mTextureHeight >> textureMipLevel, 1u); + + baseTexture->AddRef(); + mRenderTargets[index.mipIndex] = new TextureRenderTarget9( + baseTexture, textureMipLevel, surface, mInternalFormat, static_cast(mipWidth), + static_cast(mipHeight), 1, 0); } ASSERT(outRT); - *outRT = mRenderTarget; + *outRT = mRenderTargets[index.mipIndex]; return gl::Error(GL_NO_ERROR); } gl::Error TextureStorage9_2D::generateMipmap(const gl::ImageIndex &sourceIndex, const gl::ImageIndex &destIndex) { IDirect3DSurface9 *upper = NULL; - gl::Error error = getSurfaceLevel(sourceIndex.mipIndex, false, &upper); + gl::Error error = getSurfaceLevel(GL_TEXTURE_2D, sourceIndex.mipIndex, false, &upper); if (error.isError()) { return error; } IDirect3DSurface9 *lower = NULL; - error = getSurfaceLevel(destIndex.mipIndex, true, &lower); + error = getSurfaceLevel(GL_TEXTURE_2D, destIndex.mipIndex, true, &lower); if (error.isError()) { SafeRelease(upper); @@ -227,8 +251,10 @@ gl::Error TextureStorage9_2D::getBaseTexture(IDirect3DBaseTexture9 **outTexture) ASSERT(mMipLevels > 0); IDirect3DDevice9 *device = mRenderer->getDevice(); - HRESULT result = device->CreateTexture(mTextureWidth, mTextureHeight, mMipLevels, getUsage(), mTextureFormat, - getPool(), &mTexture, NULL); + HRESULT result = device->CreateTexture(static_cast(mTextureWidth), + static_cast(mTextureHeight), + static_cast(mMipLevels), getUsage(), + mTextureFormat, getPool(), &mTexture, NULL); if (FAILED(result)) { @@ -251,14 +277,14 @@ gl::Error TextureStorage9_2D::copyToStorage(TextureStorage *destStorage) for (int i = 0; i < levels; ++i) { IDirect3DSurface9 *srcSurf = NULL; - gl::Error error = getSurfaceLevel(i, false, &srcSurf); + gl::Error error = getSurfaceLevel(GL_TEXTURE_2D, i, false, &srcSurf); if (error.isError()) { return error; } IDirect3DSurface9 *dstSurf = NULL; - error = dest9->getSurfaceLevel(i, true, &dstSurf); + error = dest9->getSurfaceLevel(GL_TEXTURE_2D, i, true, &dstSurf); if (error.isError()) { SafeRelease(srcSurf); @@ -279,6 +305,131 @@ gl::Error TextureStorage9_2D::copyToStorage(TextureStorage *destStorage) return gl::Error(GL_NO_ERROR); } +TextureStorage9_EGLImage::TextureStorage9_EGLImage(Renderer9 *renderer, EGLImageD3D *image) + : TextureStorage9(renderer, D3DUSAGE_RENDERTARGET), mImage(image) +{ + RenderTargetD3D *renderTargetD3D = nullptr; + mImage->getRenderTarget(&renderTargetD3D); + + RenderTarget9 *renderTarget9 = GetAs(renderTargetD3D); + + mInternalFormat = renderTarget9->getInternalFormat(); + mTextureFormat = renderTarget9->getD3DFormat(); + mTextureWidth = renderTarget9->getWidth(); + mTextureHeight = renderTarget9->getHeight(); + mTopLevel = static_cast(renderTarget9->getTextureLevel()); + mMipLevels = mTopLevel + 1; +} + +TextureStorage9_EGLImage::~TextureStorage9_EGLImage() +{ +} + +gl::Error TextureStorage9_EGLImage::getSurfaceLevel(GLenum target, + int level, + bool, + IDirect3DSurface9 **outSurface) +{ + ASSERT(target == GL_TEXTURE_2D); + ASSERT(level == 0); + UNUSED_ASSERTION_VARIABLE(target); + UNUSED_ASSERTION_VARIABLE(level); + + RenderTargetD3D *renderTargetD3D = nullptr; + gl::Error error = mImage->getRenderTarget(&renderTargetD3D); + if (error.isError()) + { + return error; + } + + RenderTarget9 *renderTarget9 = GetAs(renderTargetD3D); + + *outSurface = renderTarget9->getSurface(); + return gl::Error(GL_NO_ERROR); +} + +gl::Error TextureStorage9_EGLImage::getRenderTarget(const gl::ImageIndex &index, + RenderTargetD3D **outRT) +{ + ASSERT(!index.hasLayer()); + ASSERT(index.mipIndex == 0); + UNUSED_ASSERTION_VARIABLE(index); + + return mImage->getRenderTarget(outRT); +} + +gl::Error TextureStorage9_EGLImage::getBaseTexture(IDirect3DBaseTexture9 **outTexture) +{ + RenderTargetD3D *renderTargetD3D = nullptr; + gl::Error error = mImage->getRenderTarget(&renderTargetD3D); + if (error.isError()) + { + return error; + } + + RenderTarget9 *renderTarget9 = GetAs(renderTargetD3D); + *outTexture = renderTarget9->getTexture(); + ASSERT(*outTexture != nullptr); + + return gl::Error(GL_NO_ERROR); +} + +gl::Error TextureStorage9_EGLImage::generateMipmap(const gl::ImageIndex &, const gl::ImageIndex &) +{ + UNREACHABLE(); + return gl::Error(GL_INVALID_OPERATION); +} + +gl::Error TextureStorage9_EGLImage::copyToStorage(TextureStorage *destStorage) +{ + ASSERT(destStorage); + ASSERT(getLevelCount() == 1); + + TextureStorage9 *dest9 = GetAs(destStorage); + + IDirect3DBaseTexture9 *destBaseTexture9 = nullptr; + gl::Error error = dest9->getBaseTexture(&destBaseTexture9); + if (error.isError()) + { + return error; + } + + IDirect3DTexture9 *destTexture9 = static_cast(destBaseTexture9); + + IDirect3DSurface9 *destSurface = nullptr; + HRESULT result = destTexture9->GetSurfaceLevel(destStorage->getTopLevel(), &destSurface); + if (FAILED(result)) + { + return gl::Error(GL_OUT_OF_MEMORY, + "Failed to get the surface from a texture, result: 0x%X.", result); + } + + RenderTargetD3D *sourceRenderTarget = nullptr; + error = mImage->getRenderTarget(&sourceRenderTarget); + if (error.isError()) + { + SafeRelease(destSurface); + return error; + } + + RenderTarget9 *sourceRenderTarget9 = GetAs(sourceRenderTarget); + error = + mRenderer->copyToRenderTarget(destSurface, sourceRenderTarget9->getSurface(), isManaged()); + if (error.isError()) + { + SafeRelease(destSurface); + return error; + } + + if (destStorage->getTopLevel() != 0) + { + destTexture9->AddDirtyRect(nullptr); + } + + SafeRelease(destSurface); + return gl::Error(GL_NO_ERROR); +} + TextureStorage9_Cube::TextureStorage9_Cube(Renderer9 *renderer, GLenum internalformat, bool renderTarget, int size, int levels, bool hintLevelZeroOnly) : TextureStorage9(renderer, GetTextureUsage(internalformat, renderTarget)) { @@ -298,8 +449,6 @@ TextureStorage9_Cube::TextureStorage9_Cube(Renderer9 *renderer, GLenum internalf mTextureWidth = size; mTextureHeight = size; mMipLevels = mTopLevel + levels; - - initializeSerials(getLevelCount() * CUBE_FACE_COUNT, CUBE_FACE_COUNT); } TextureStorage9_Cube::~TextureStorage9_Cube() @@ -314,7 +463,10 @@ TextureStorage9_Cube::~TextureStorage9_Cube() // Increments refcount on surface. // caller must Release() the returned surface -gl::Error TextureStorage9_Cube::getCubeMapSurface(GLenum faceTarget, int level, bool dirty, IDirect3DSurface9 **outSurface) +gl::Error TextureStorage9_Cube::getSurfaceLevel(GLenum target, + int level, + bool dirty, + IDirect3DSurface9 **outSurface) { IDirect3DBaseTexture9 *baseTexture = NULL; gl::Error error = getBaseTexture(&baseTexture); @@ -325,8 +477,8 @@ gl::Error TextureStorage9_Cube::getCubeMapSurface(GLenum faceTarget, int level, IDirect3DCubeTexture9 *texture = static_cast(baseTexture); - D3DCUBEMAP_FACES face = gl_d3d9::ConvertCubeFace(faceTarget); - HRESULT result = texture->GetCubeMapSurface(face, level + mTopLevel, outSurface); + D3DCUBEMAP_FACES face = gl_d3d9::ConvertCubeFace(target); + HRESULT result = texture->GetCubeMapSurface(face, level, outSurface); ASSERT(SUCCEEDED(result)); if (FAILED(result)) @@ -351,14 +503,25 @@ gl::Error TextureStorage9_Cube::getRenderTarget(const gl::ImageIndex &index, Ren if (mRenderTarget[index.layerIndex] == NULL && isRenderTarget()) { + IDirect3DBaseTexture9 *baseTexture = NULL; + gl::Error error = getBaseTexture(&baseTexture); + if (error.isError()) + { + return error; + } + IDirect3DSurface9 *surface = NULL; - gl::Error error = getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + index.layerIndex, 0, false, &surface); + error = getSurfaceLevel(GL_TEXTURE_CUBE_MAP_POSITIVE_X + index.layerIndex, + mTopLevel + index.mipIndex, false, &surface); if (error.isError()) { return error; } - mRenderTarget[index.layerIndex] = new TextureRenderTarget9(surface, mInternalFormat, mTextureWidth, mTextureHeight, 1, 0); + baseTexture->AddRef(); + mRenderTarget[index.layerIndex] = new TextureRenderTarget9( + baseTexture, mTopLevel + index.mipIndex, surface, mInternalFormat, + static_cast(mTextureWidth), static_cast(mTextureHeight), 1, 0); } *outRT = mRenderTarget[index.layerIndex]; @@ -368,14 +531,14 @@ gl::Error TextureStorage9_Cube::getRenderTarget(const gl::ImageIndex &index, Ren gl::Error TextureStorage9_Cube::generateMipmap(const gl::ImageIndex &sourceIndex, const gl::ImageIndex &destIndex) { IDirect3DSurface9 *upper = NULL; - gl::Error error = getCubeMapSurface(sourceIndex.type, sourceIndex.mipIndex, false, &upper); + gl::Error error = getSurfaceLevel(sourceIndex.type, sourceIndex.mipIndex, false, &upper); if (error.isError()) { return error; } IDirect3DSurface9 *lower = NULL; - error = getCubeMapSurface(destIndex.type, destIndex.mipIndex, true, &lower); + error = getSurfaceLevel(destIndex.type, destIndex.mipIndex, true, &lower); if (error.isError()) { SafeRelease(upper); @@ -401,8 +564,9 @@ gl::Error TextureStorage9_Cube::getBaseTexture(IDirect3DBaseTexture9 **outTextur ASSERT(mTextureWidth == mTextureHeight); IDirect3DDevice9 *device = mRenderer->getDevice(); - HRESULT result = device->CreateCubeTexture(mTextureWidth, mMipLevels, getUsage(), mTextureFormat, getPool(), - &mTexture, NULL); + HRESULT result = device->CreateCubeTexture( + static_cast(mTextureWidth), static_cast(mMipLevels), + getUsage(), mTextureFormat, getPool(), &mTexture, NULL); if (FAILED(result)) { @@ -427,14 +591,15 @@ gl::Error TextureStorage9_Cube::copyToStorage(TextureStorage *destStorage) for (int i = 0; i < levels; i++) { IDirect3DSurface9 *srcSurf = NULL; - gl::Error error = getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + f, i, false, &srcSurf); + gl::Error error = + getSurfaceLevel(GL_TEXTURE_CUBE_MAP_POSITIVE_X + f, i, false, &srcSurf); if (error.isError()) { return error; } IDirect3DSurface9 *dstSurf = NULL; - error = dest9->getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + f, i, true, &dstSurf); + error = dest9->getSurfaceLevel(GL_TEXTURE_CUBE_MAP_POSITIVE_X + f, i, true, &dstSurf); if (error.isError()) { SafeRelease(srcSurf); diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/TextureStorage9.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/TextureStorage9.h index 1f3d8e7c9837..50e63a6f14f1 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/TextureStorage9.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/TextureStorage9.h @@ -16,6 +16,7 @@ namespace rx { +class EGLImageD3D; class Renderer9; class SwapChain9; class RenderTargetD3D; @@ -31,6 +32,10 @@ class TextureStorage9 : public TextureStorage D3DPOOL getPool() const; DWORD getUsage() const; + virtual gl::Error getSurfaceLevel(GLenum target, + int level, + bool dirty, + IDirect3DSurface9 **outSurface) = 0; virtual gl::Error getBaseTexture(IDirect3DBaseTexture9 **outTexture) = 0; virtual gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTargetD3D **outRT) = 0; @@ -67,7 +72,10 @@ class TextureStorage9_2D : public TextureStorage9 TextureStorage9_2D(Renderer9 *renderer, GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, int levels); virtual ~TextureStorage9_2D(); - gl::Error getSurfaceLevel(int level, bool dirty, IDirect3DSurface9 **outSurface); + gl::Error getSurfaceLevel(GLenum target, + int level, + bool dirty, + IDirect3DSurface9 **outSurface) override; virtual gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTargetD3D **outRT); virtual gl::Error getBaseTexture(IDirect3DBaseTexture9 **outTexture); virtual gl::Error generateMipmap(const gl::ImageIndex &sourceIndex, const gl::ImageIndex &destIndex); @@ -75,7 +83,27 @@ class TextureStorage9_2D : public TextureStorage9 private: IDirect3DTexture9 *mTexture; - RenderTarget9 *mRenderTarget; + std::vector mRenderTargets; +}; + +class TextureStorage9_EGLImage final : public TextureStorage9 +{ + public: + TextureStorage9_EGLImage(Renderer9 *renderer, EGLImageD3D *image); + ~TextureStorage9_EGLImage() override; + + gl::Error getSurfaceLevel(GLenum target, + int level, + bool dirty, + IDirect3DSurface9 **outSurface) override; + gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTargetD3D **outRT) override; + gl::Error getBaseTexture(IDirect3DBaseTexture9 **outTexture) override; + gl::Error generateMipmap(const gl::ImageIndex &sourceIndex, + const gl::ImageIndex &destIndex) override; + gl::Error copyToStorage(TextureStorage *destStorage) override; + + private: + EGLImageD3D *mImage; }; class TextureStorage9_Cube : public TextureStorage9 @@ -84,7 +112,10 @@ class TextureStorage9_Cube : public TextureStorage9 TextureStorage9_Cube(Renderer9 *renderer, GLenum internalformat, bool renderTarget, int size, int levels, bool hintLevelZeroOnly); virtual ~TextureStorage9_Cube(); - gl::Error getCubeMapSurface(GLenum faceTarget, int level, bool dirty, IDirect3DSurface9 **outSurface); + gl::Error getSurfaceLevel(GLenum target, + int level, + bool dirty, + IDirect3DSurface9 **outSurface) override; virtual gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTargetD3D **outRT); virtual gl::Error getBaseTexture(IDirect3DBaseTexture9 **outTexture); virtual gl::Error generateMipmap(const gl::ImageIndex &sourceIndex, const gl::ImageIndex &destIndex); diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/VertexArray9.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/VertexArray9.h index fb626bc0cf8c..992201737f81 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/VertexArray9.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/VertexArray9.h @@ -19,21 +19,12 @@ class Renderer9; class VertexArray9 : public VertexArrayImpl { public: - VertexArray9(Renderer9 *renderer) - : VertexArrayImpl(), - mRenderer(renderer) + VertexArray9(const gl::VertexArray::Data &data) + : VertexArrayImpl(data) { } virtual ~VertexArray9() { } - - virtual void setElementArrayBuffer(const gl::Buffer *buffer) { } - virtual void setAttribute(size_t idx, const gl::VertexAttribute &attr) { } - virtual void setAttributeDivisor(size_t idx, GLuint divisor) { } - virtual void enableAttribute(size_t idx, bool enabledState) { } - - private: - Renderer9 *mRenderer; }; } diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/VertexBuffer9.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/VertexBuffer9.cpp index 7ea8b20d61b1..c5c07c348cfd 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/VertexBuffer9.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/VertexBuffer9.cpp @@ -56,67 +56,49 @@ gl::Error VertexBuffer9::initialize(unsigned int size, bool dynamicUsage) return gl::Error(GL_NO_ERROR); } -gl::Error VertexBuffer9::storeVertexAttributes(const gl::VertexAttribute &attrib, const gl::VertexAttribCurrentValueData ¤tValue, - GLint start, GLsizei count, GLsizei instances, unsigned int offset) +gl::Error VertexBuffer9::storeVertexAttributes(const gl::VertexAttribute &attrib, + GLenum currentValueType, + GLint start, + GLsizei count, + GLsizei instances, + unsigned int offset, + const uint8_t *sourceData) { if (!mVertexBuffer) { return gl::Error(GL_OUT_OF_MEMORY, "Internal vertex buffer is not initialized."); } - gl::Buffer *buffer = attrib.buffer.get(); - - int inputStride = gl::ComputeVertexAttributeStride(attrib); - int elementSize = gl::ComputeVertexAttributeTypeSize(attrib); + int inputStride = static_cast(gl::ComputeVertexAttributeStride(attrib)); + int elementSize = static_cast(gl::ComputeVertexAttributeTypeSize(attrib)); DWORD lockFlags = mDynamicUsage ? D3DLOCK_NOOVERWRITE : 0; - uint8_t *mapPtr = NULL; + uint8_t *mapPtr = nullptr; - unsigned int mapSize; - gl::Error error = spaceRequired(attrib, count, instances, &mapSize); - if (error.isError()) + auto errorOrMapSize = mRenderer->getVertexSpaceRequired(attrib, count, instances); + if (errorOrMapSize.isError()) { - return error; + return errorOrMapSize.getError(); } + unsigned int mapSize = errorOrMapSize.getResult(); + HRESULT result = mVertexBuffer->Lock(offset, mapSize, reinterpret_cast(&mapPtr), lockFlags); if (FAILED(result)) { return gl::Error(GL_OUT_OF_MEMORY, "Failed to lock internal vertex buffer, HRESULT: 0x%08x.", result); } - const uint8_t *input = NULL; - if (attrib.enabled) - { - if (buffer) - { - BufferD3D *storage = GetImplAs(buffer); - ASSERT(storage); - error = storage->getData(&input); - if (error.isError()) - { - return error; - } - input += static_cast(attrib.offset); - } - else - { - input = static_cast(attrib.pointer); - } - } - else - { - input = reinterpret_cast(currentValue.FloatValues); - } + const uint8_t *input = sourceData; if (instances == 0 || attrib.divisor == 0) { input += inputStride * start; } - gl::VertexFormat vertexFormat(attrib, currentValue.Type); - const d3d9::VertexFormat &d3dVertexInfo = d3d9::GetVertexFormatInfo(mRenderer->getCapsDeclTypes(), vertexFormat); + gl::VertexFormatType vertexFormatType = gl::GetVertexFormatType(attrib, currentValueType); + const d3d9::VertexFormat &d3dVertexInfo = d3d9::GetVertexFormatInfo(mRenderer->getCapsDeclTypes(), vertexFormatType); bool needsConversion = (d3dVertexInfo.conversionType & VERTEX_CONVERT_CPU) > 0; if (!needsConversion && inputStride == elementSize) @@ -134,12 +116,6 @@ gl::Error VertexBuffer9::storeVertexAttributes(const gl::VertexAttribute &attrib return gl::Error(GL_NO_ERROR); } -gl::Error VertexBuffer9::getSpaceRequired(const gl::VertexAttribute &attrib, GLsizei count, GLsizei instances, - unsigned int *outSpaceRequired) const -{ - return spaceRequired(attrib, count, instances, outSpaceRequired); -} - unsigned int VertexBuffer9::getBufferSize() const { return mBufferSize; @@ -186,48 +162,4 @@ IDirect3DVertexBuffer9 * VertexBuffer9::getBuffer() const { return mVertexBuffer; } - -gl::Error VertexBuffer9::spaceRequired(const gl::VertexAttribute &attrib, std::size_t count, GLsizei instances, - unsigned int *outSpaceRequired) const -{ - gl::VertexFormat vertexFormat(attrib, GL_FLOAT); - const d3d9::VertexFormat &d3d9VertexInfo = d3d9::GetVertexFormatInfo(mRenderer->getCapsDeclTypes(), vertexFormat); - - if (attrib.enabled) - { - unsigned int elementCount = 0; - if (instances == 0 || attrib.divisor == 0) - { - elementCount = count; - } - else - { - // Round up to divisor, if possible - elementCount = UnsignedCeilDivide(static_cast(instances), attrib.divisor); - } - - if (d3d9VertexInfo.outputElementSize <= std::numeric_limits::max() / elementCount) - { - if (outSpaceRequired) - { - *outSpaceRequired = d3d9VertexInfo.outputElementSize * elementCount; - } - return gl::Error(GL_NO_ERROR); - } - else - { - return gl::Error(GL_OUT_OF_MEMORY, "New vertex buffer size would result in an overflow."); - } - } - else - { - const unsigned int elementSize = 4; - if (outSpaceRequired) - { - *outSpaceRequired = elementSize * 4; - } - return gl::Error(GL_NO_ERROR); - } -} - -} +} // namespace rx diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/VertexBuffer9.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/VertexBuffer9.h index b12d3529d8bb..0d2d8c288a18 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/VertexBuffer9.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/VertexBuffer9.h @@ -19,30 +19,30 @@ class VertexBuffer9 : public VertexBuffer { public: explicit VertexBuffer9(Renderer9 *renderer); - virtual ~VertexBuffer9(); - virtual gl::Error initialize(unsigned int size, bool dynamicUsage); + gl::Error initialize(unsigned int size, bool dynamicUsage) override; - virtual gl::Error storeVertexAttributes(const gl::VertexAttribute &attrib, const gl::VertexAttribCurrentValueData ¤tValue, - GLint start, GLsizei count, GLsizei instances, unsigned int offset); + gl::Error storeVertexAttributes(const gl::VertexAttribute &attrib, + GLenum currentValueType, + GLint start, + GLsizei count, + GLsizei instances, + unsigned int offset, + const uint8_t *sourceData) override; - virtual gl::Error getSpaceRequired(const gl::VertexAttribute &attrib, GLsizei count, GLsizei instances, unsigned int *outSpaceRequired) const; - - virtual unsigned int getBufferSize() const; - virtual gl::Error setBufferSize(unsigned int size); - virtual gl::Error discard(); + unsigned int getBufferSize() const override; + gl::Error setBufferSize(unsigned int size) override; + gl::Error discard() override; IDirect3DVertexBuffer9 *getBuffer() const; private: + ~VertexBuffer9() override; Renderer9 *mRenderer; IDirect3DVertexBuffer9 *mVertexBuffer; unsigned int mBufferSize; bool mDynamicUsage; - - gl::Error spaceRequired(const gl::VertexAttribute &attrib, std::size_t count, GLsizei instances, - unsigned int *outSpaceRequired) const; }; } diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/VertexDeclarationCache.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/VertexDeclarationCache.cpp index 74af90517c99..afae5188c6bc 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/VertexDeclarationCache.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/VertexDeclarationCache.cpp @@ -7,10 +7,12 @@ // VertexDeclarationCache.cpp: Implements a helper class to construct and cache vertex declarations. #include "libANGLE/renderer/d3d/d3d9/VertexDeclarationCache.h" + +#include "libANGLE/VertexAttribute.h" +#include "libANGLE/formatutils.h" +#include "libANGLE/renderer/d3d/ProgramD3D.h" #include "libANGLE/renderer/d3d/d3d9/VertexBuffer9.h" #include "libANGLE/renderer/d3d/d3d9/formatutils9.h" -#include "libANGLE/Program.h" -#include "libANGLE/VertexAttribute.h" namespace rx { @@ -40,16 +42,25 @@ VertexDeclarationCache::~VertexDeclarationCache() } } -gl::Error VertexDeclarationCache::applyDeclaration(IDirect3DDevice9 *device, TranslatedAttribute attributes[], gl::Program *program, GLsizei instances, GLsizei *repeatDraw) +gl::Error VertexDeclarationCache::applyDeclaration( + IDirect3DDevice9 *device, + const std::vector &attributes, + gl::Program *program, + GLint start, + GLsizei instances, + GLsizei *repeatDraw) { + ASSERT(gl::MAX_VERTEX_ATTRIBS >= attributes.size()); + *repeatDraw = 1; - int indexedAttribute = gl::MAX_VERTEX_ATTRIBS; - int instancedAttribute = gl::MAX_VERTEX_ATTRIBS; + const size_t invalidAttribIndex = attributes.size(); + size_t indexedAttribute = invalidAttribIndex; + size_t instancedAttribute = invalidAttribIndex; if (instances == 0) { - for (int i = 0; i < gl::MAX_VERTEX_ATTRIBS; ++i) + for (size_t i = 0; i < attributes.size(); ++i) { if (attributes[i].divisor != 0) { @@ -64,26 +75,26 @@ gl::Error VertexDeclarationCache::applyDeclaration(IDirect3DDevice9 *device, Tra if (instances > 0) { // Find an indexed attribute to be mapped to D3D stream 0 - for (int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++) + for (size_t i = 0; i < attributes.size(); i++) { if (attributes[i].active) { - if (indexedAttribute == gl::MAX_VERTEX_ATTRIBS && attributes[i].divisor == 0) + if (indexedAttribute == invalidAttribIndex && attributes[i].divisor == 0) { indexedAttribute = i; } - else if (instancedAttribute == gl::MAX_VERTEX_ATTRIBS && attributes[i].divisor != 0) + else if (instancedAttribute == invalidAttribIndex && attributes[i].divisor != 0) { instancedAttribute = i; } - if (indexedAttribute != gl::MAX_VERTEX_ATTRIBS && instancedAttribute != gl::MAX_VERTEX_ATTRIBS) + 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 != gl::MAX_VERTEX_ATTRIBS); + ASSERT(indexedAttribute != invalidAttribIndex); } D3DCAPS9 caps; @@ -92,19 +103,22 @@ gl::Error VertexDeclarationCache::applyDeclaration(IDirect3DDevice9 *device, Tra D3DVERTEXELEMENT9 elements[gl::MAX_VERTEX_ATTRIBS + 1]; D3DVERTEXELEMENT9 *element = &elements[0]; - for (int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++) + 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 == NULL); - int stream = i; + 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 == gl::MAX_VERTEX_ATTRIBS) + if (instancedAttribute == invalidAttribIndex) { *repeatDraw = instances; } @@ -116,7 +130,7 @@ gl::Error VertexDeclarationCache::applyDeclaration(IDirect3DDevice9 *device, Tra } else if (i == 0) { - stream = indexedAttribute; + stream = static_cast(indexedAttribute); } UINT frequency = 1; @@ -135,32 +149,36 @@ gl::Error VertexDeclarationCache::applyDeclaration(IDirect3DDevice9 *device, Tra } } - VertexBuffer9 *vertexBuffer = GetAs(attributes[i].vertexBuffer); + VertexBuffer9 *vertexBuffer = GetAs(attributes[i].vertexBuffer.get()); + + unsigned int offset = 0; + ANGLE_TRY_RESULT(attributes[i].computeOffset(start), offset); if (mAppliedVBs[stream].serial != attributes[i].serial || mAppliedVBs[stream].stride != attributes[i].stride || - mAppliedVBs[stream].offset != attributes[i].offset) + mAppliedVBs[stream].offset != offset) { - device->SetStreamSource(stream, vertexBuffer->getBuffer(), attributes[i].offset, attributes[i].stride); + device->SetStreamSource(stream, vertexBuffer->getBuffer(), offset, + attributes[i].stride); mAppliedVBs[stream].serial = attributes[i].serial; mAppliedVBs[stream].stride = attributes[i].stride; - mAppliedVBs[stream].offset = attributes[i].offset; + mAppliedVBs[stream].offset = offset; } - gl::VertexFormat vertexFormat(*attributes[i].attribute, GL_FLOAT); - const d3d9::VertexFormat &d3d9VertexInfo = d3d9::GetVertexFormatInfo(caps.DeclTypes, vertexFormat); + gl::VertexFormatType vertexformatType = gl::GetVertexFormatType(*attributes[i].attribute, GL_FLOAT); + const d3d9::VertexFormat &d3d9VertexInfo = d3d9::GetVertexFormatInfo(caps.DeclTypes, vertexformatType); 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(program->getSemanticIndex(i)); + element->UsageIndex = static_cast(semanticIndexes[i]); element++; } } - if (instances == 0 || instancedAttribute == gl::MAX_VERTEX_ATTRIBS) + if (instances == 0 || instancedAttribute == invalidAttribIndex) { if (mInstancingEnabled) { diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/VertexDeclarationCache.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/VertexDeclarationCache.h index fbd673097f88..7bd7cabae492 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/VertexDeclarationCache.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/VertexDeclarationCache.h @@ -27,7 +27,12 @@ class VertexDeclarationCache VertexDeclarationCache(); ~VertexDeclarationCache(); - gl::Error applyDeclaration(IDirect3DDevice9 *device, TranslatedAttribute attributes[], gl::Program *program, GLsizei instances, GLsizei *repeatDraw); + gl::Error applyDeclaration(IDirect3DDevice9 *device, + const std::vector &attributes, + gl::Program *program, + GLint start, + GLsizei instances, + GLsizei *repeatDraw); void markStateDirty(); diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/formatutils9.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/formatutils9.cpp index 25938ced5a7f..b672a60e3cca 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/formatutils9.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/formatutils9.cpp @@ -119,8 +119,8 @@ static D3D9FormatInfoMap BuildD3D9FormatInfoMap() InsertD3DFormatInfo(&map, D3DFMT_L8, 8, 1, 1, 0, 0, 0, 0, 8, 0, 0, GL_LUMINANCE8_EXT, GenerateMip, ReadColor ); InsertD3DFormatInfo(&map, D3DFMT_A8, 8, 1, 1, 0, 0, 0, 8, 0, 0, 0, GL_ALPHA8_EXT, GenerateMip, ReadColor ); InsertD3DFormatInfo(&map, D3DFMT_A8L8, 16, 1, 1, 0, 0, 0, 8, 8, 0, 0, GL_LUMINANCE8_ALPHA8_EXT, GenerateMip, ReadColor ); - InsertD3DFormatInfo(&map, D3DFMT_A4R4G4B4, 16, 1, 1, 4, 4, 4, 4, 0, 0, 0, GL_BGRA4_ANGLEX, GenerateMip, ReadColor ); - InsertD3DFormatInfo(&map, D3DFMT_A1R5G5B5, 16, 1, 1, 5, 5, 5, 1, 0, 0, 0, GL_BGR5_A1_ANGLEX, GenerateMip, ReadColor ); + InsertD3DFormatInfo(&map, D3DFMT_A4R4G4B4, 16, 1, 1, 4, 4, 4, 4, 0, 0, 0, GL_BGRA4_ANGLEX, GenerateMip, ReadColor ); + InsertD3DFormatInfo(&map, D3DFMT_A1R5G5B5, 16, 1, 1, 5, 5, 5, 1, 0, 0, 0, GL_BGR5_A1_ANGLEX, GenerateMip, ReadColor ); InsertD3DFormatInfo(&map, D3DFMT_R5G6B5, 16, 1, 1, 5, 6, 5, 0, 0, 0, 0, GL_RGB565, GenerateMip, ReadColor ); InsertD3DFormatInfo(&map, D3DFMT_X8R8G8B8, 32, 1, 1, 8, 8, 8, 0, 0, 0, 0, GL_BGRA8_EXT, GenerateMip, ReadColor ); InsertD3DFormatInfo(&map, D3DFMT_A8R8G8B8, 32, 1, 1, 8, 8, 8, 8, 0, 0, 0, GL_BGRA8_EXT, GenerateMip, ReadColor ); @@ -475,16 +475,25 @@ template struct UseFallback { enum { type = T::fallback }; }; // and the D3DDECLTYPE member needed for the vertex declaration in declflag. template class PreferenceRule> struct Converter - : VertexDataConverter::type, - WidenRule >::type, size>, - ConversionRule >::type>, - DefaultVertexValues >::type>::type, normalized > > + : VertexDataConverter< + typename GLToCType::type, + WidenRule>::type, size>, + ConversionRule>::type>, + DefaultVertexValues>::type>::type, + normalized>> { private: - enum { d3dtype = PreferenceRule< VertexTypeMapping >::type }; - enum { d3dsize = WidenRule::finalWidth }; + enum + { + d3dtype = PreferenceRule>::type + }; + enum + { + d3dsize = WidenRule::finalWidth + }; public: enum { capflag = VertexTypeFlags::capflag }; @@ -555,7 +564,7 @@ static inline unsigned int ComputeTypeIndex(GLenum type) } } -const VertexFormat &GetVertexFormatInfo(DWORD supportedDeclTypes, const gl::VertexFormat &vertexFormat) +const VertexFormat &GetVertexFormatInfo(DWORD supportedDeclTypes, gl::VertexFormatType vertexFormatType) { static bool initialized = false; static DWORD initializedDeclTypes = 0; @@ -592,9 +601,11 @@ const VertexFormat &GetVertexFormatInfo(DWORD supportedDeclTypes, const gl::Vert initializedDeclTypes = supportedDeclTypes; } + const gl::VertexFormat &vertexFormat = gl::GetVertexFormatFromType(vertexFormatType); + // Pure integer attributes only supported in ES3.0 - ASSERT(!vertexFormat.mPureInteger); - return formatConverters[ComputeTypeIndex(vertexFormat.mType)][vertexFormat.mNormalized][vertexFormat.mComponents - 1]; + ASSERT(!vertexFormat.pureInteger); + return formatConverters[ComputeTypeIndex(vertexFormat.type)][vertexFormat.normalized][vertexFormat.components - 1]; } } diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/formatutils9.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/formatutils9.h index 15e26599c871..c55010760d50 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/formatutils9.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/formatutils9.h @@ -10,12 +10,12 @@ #ifndef LIBANGLE_RENDERER_D3D_D3D9_FORMATUTILS9_H_ #define LIBANGLE_RENDERER_D3D_D3D9_FORMATUTILS9_H_ -#include "libANGLE/renderer/d3d/formatutilsD3D.h" -#include "libANGLE/angletypes.h" +#include #include "common/platform.h" - -#include +#include "libANGLE/angletypes.h" +#include "libANGLE/formatutils.h" +#include "libANGLE/renderer/d3d/formatutilsD3D.h" namespace rx { @@ -64,7 +64,7 @@ struct VertexFormat D3DDECLTYPE nativeFormat; GLenum componentType; }; -const VertexFormat &GetVertexFormatInfo(DWORD supportedDeclTypes, const gl::VertexFormat &vertexFormat); +const VertexFormat &GetVertexFormatInfo(DWORD supportedDeclTypes, gl::VertexFormatType vertexFormatType); struct TextureFormat { diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/renderer9_utils.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/renderer9_utils.cpp index 1235c72c5a72..8622dc4d1325 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/renderer9_utils.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/renderer9_utils.cpp @@ -8,16 +8,17 @@ // specific to the D3D9 renderer. #include "libANGLE/renderer/d3d/d3d9/renderer9_utils.h" -#include "libANGLE/renderer/d3d/d3d9/formatutils9.h" -#include "libANGLE/renderer/d3d/FramebufferD3D.h" -#include "libANGLE/renderer/Workarounds.h" -#include "libANGLE/formatutils.h" -#include "libANGLE/Framebuffer.h" -#include "libANGLE/renderer/d3d/d3d9/RenderTarget9.h" #include "common/mathutil.h" #include "common/debug.h" +#include "libANGLE/formatutils.h" +#include "libANGLE/Framebuffer.h" +#include "libANGLE/renderer/d3d/d3d9/formatutils9.h" +#include "libANGLE/renderer/d3d/d3d9/RenderTarget9.h" +#include "libANGLE/renderer/d3d/FramebufferD3D.h" +#include "libANGLE/renderer/d3d/WorkaroundsD3D.h" + #include "third_party/systeminfo/SystemInfo.h" namespace rx @@ -208,7 +209,8 @@ D3DTEXTUREFILTERTYPE ConvertMagFilter(GLenum magFilter, float maxAnisotropy) return d3dMagFilter; } -void ConvertMinFilter(GLenum minFilter, D3DTEXTUREFILTERTYPE *d3dMinFilter, D3DTEXTUREFILTERTYPE *d3dMipFilter, float maxAnisotropy) +void ConvertMinFilter(GLenum minFilter, D3DTEXTUREFILTERTYPE *d3dMinFilter, D3DTEXTUREFILTERTYPE *d3dMipFilter, + float *d3dLodBias, float maxAnisotropy, size_t baseLevel) { switch (minFilter) { @@ -242,6 +244,20 @@ void ConvertMinFilter(GLenum minFilter, D3DTEXTUREFILTERTYPE *d3dMinFilter, D3DT 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; @@ -258,6 +274,16 @@ D3DMULTISAMPLE_TYPE GetMultisampleType(GLuint samples) namespace d3d9_gl { +unsigned int GetReservedVertexUniformVectors() +{ + return 3; // dx_ViewCoords, dx_ViewAdjust and dx_DepthRange. +} + +unsigned int GetReservedFragmentUniformVectors() +{ + return 3; // dx_ViewCoords, dx_DepthFront and dx_DepthRange. +} + GLsizei GetSamplesCount(D3DMULTISAMPLE_TYPE type) { return (type != D3DMULTISAMPLE_NONMASKABLE) ? type : 0; @@ -303,7 +329,7 @@ static gl::TextureCaps GenerateTextureFormatCaps(GLenum internalFormat, IDirect3 } textureCaps.sampleCounts.insert(1); - for (size_t i = D3DMULTISAMPLE_2_SAMPLES; i <= D3DMULTISAMPLE_16_SAMPLES; i++) + for (unsigned int i = D3DMULTISAMPLE_2_SAMPLES; i <= D3DMULTISAMPLE_16_SAMPLES; i++) { D3DMULTISAMPLE_TYPE multisampleType = D3DMULTISAMPLE_TYPE(i); @@ -318,8 +344,14 @@ static gl::TextureCaps GenerateTextureFormatCaps(GLenum internalFormat, IDirect3 return textureCaps; } -void GenerateCaps(IDirect3D9 *d3d9, IDirect3DDevice9 *device, D3DDEVTYPE deviceType, UINT adapter, gl::Caps *caps, - gl::TextureCapsMap *textureCapsMap, gl::Extensions *extensions) +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))) @@ -413,9 +445,9 @@ void GenerateCaps(IDirect3D9 *d3d9, IDirect3DDevice9 *device, D3DDEVTYPE deviceT // Vertex shader limits caps->maxVertexAttributes = 16; - const size_t reservedVertexUniformVectors = 2; // dx_ViewAdjust and dx_DepthRange. const size_t MAX_VERTEX_CONSTANT_VECTORS_D3D9 = 256; - caps->maxVertexUniformVectors = MAX_VERTEX_CONSTANT_VECTORS_D3D9 - reservedVertexUniformVectors; + caps->maxVertexUniformVectors = + MAX_VERTEX_CONSTANT_VECTORS_D3D9 - GetReservedVertexUniformVectors(); caps->maxVertexUniformComponents = caps->maxVertexUniformVectors * 4; caps->maxVertexUniformBlocks = 0; @@ -441,12 +473,12 @@ void GenerateCaps(IDirect3D9 *d3d9, IDirect3DDevice9 *device, D3DDEVTYPE deviceT } // Fragment shader limits - const size_t reservedPixelUniformVectors = 3; // dx_ViewCoords, dx_DepthFront and dx_DepthRange. - 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) - reservedPixelUniformVectors; + caps->maxFragmentUniformVectors = + ((deviceCaps.PixelShaderVersion >= D3DPS_VERSION(3, 0)) ? MAX_PIXEL_CONSTANT_VECTORS_SM3 + : MAX_PIXEL_CONSTANT_VECTORS_SM2) - + GetReservedFragmentUniformVectors(); caps->maxFragmentUniformComponents = caps->maxFragmentUniformVectors * 4; caps->maxFragmentUniformBlocks = 0; caps->maxFragmentInputComponents = caps->maxVertexOutputComponents; @@ -478,7 +510,6 @@ void GenerateCaps(IDirect3D9 *d3d9, IDirect3DDevice9 *device, D3DDEVTYPE deviceT // GL extension support extensions->setTextureExtensionSupport(*textureCapsMap); extensions->elementIndexUint = deviceCaps.MaxVertexIndex >= (1 << 16); - extensions->packedDepthStencil = true; extensions->getProgramBinary = true; extensions->rgb8rgba8 = true; extensions->readFormatBGRA = true; @@ -489,7 +520,7 @@ void GenerateCaps(IDirect3D9 *d3d9, IDirect3DDevice9 *device, D3DDEVTYPE deviceT // textureRG is emulated and not performant. extensions->textureRG = false; - D3DADAPTER_IDENTIFIER9 adapterId = { 0 }; + D3DADAPTER_IDENTIFIER9 adapterId = {}; if (SUCCEEDED(d3d9->GetAdapterIdentifier(adapter, 0, &adapterId))) { // ATI cards on XP have problems with non-power-of-two textures. @@ -527,6 +558,7 @@ void GenerateCaps(IDirect3D9 *d3d9, IDirect3DDevice9 *device, D3DDEVTYPE deviceT SafeRelease(eventQuery); extensions->timerQuery = false; // Unimplemented + extensions->disjointTimerQuery = false; extensions->robustness = true; extensions->blendMinMax = true; extensions->framebufferBlit = true; @@ -539,7 +571,26 @@ void GenerateCaps(IDirect3D9 *d3d9, IDirect3DDevice9 *device, D3DDEVTYPE deviceT extensions->textureUsage = true; extensions->translatedShaderSource = true; extensions->fboRenderMipmap = false; + extensions->discardFramebuffer = false; // It would be valid to set this to true, since glDiscardFramebufferEXT is just a hint extensions->colorBufferFloat = false; + extensions->debugMarker = true; + extensions->eglImage = true; + extensions->unpackSubimage = true; + extensions->packSubimage = true; + extensions->vertexArrayObject = true; + extensions->noError = 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; } } @@ -574,9 +625,9 @@ void MakeValidSize(bool isImage, D3DFORMAT format, GLsizei *requestWidth, GLsize *levelOffset = upsampleCount; } -Workarounds GenerateWorkarounds() +WorkaroundsD3D GenerateWorkarounds() { - Workarounds workarounds; + WorkaroundsD3D workarounds; workarounds.mrtPerfWorkaround = true; workarounds.setDataFasterThanImageUpload = false; workarounds.useInstancedPointSpriteEmulation = false; diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/renderer9_utils.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/renderer9_utils.h index 3efc174e4d01..aa494adb62f4 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/renderer9_utils.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/renderer9_utils.h @@ -22,7 +22,7 @@ class FramebufferAttachment; namespace rx { class RenderTarget9; -struct Workarounds; +struct WorkaroundsD3D; namespace gl_d3d9 { @@ -37,7 +37,8 @@ D3DCULL ConvertCullMode(GLenum cullFace, GLenum frontFace); D3DCUBEMAP_FACES ConvertCubeFace(GLenum 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 maxAnisotropy); +void ConvertMinFilter(GLenum minFilter, D3DTEXTUREFILTERTYPE *d3dMinFilter, D3DTEXTUREFILTERTYPE *d3dMipFilter, + float *d3dLodBias, float maxAnisotropy, size_t baseLevel); D3DMULTISAMPLE_TYPE GetMultisampleType(GLuint samples); @@ -46,13 +47,22 @@ D3DMULTISAMPLE_TYPE GetMultisampleType(GLuint samples); namespace d3d9_gl { +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); - +void GenerateCaps(IDirect3D9 *d3d9, + IDirect3DDevice9 *device, + D3DDEVTYPE deviceType, + UINT adapter, + gl::Caps *caps, + gl::TextureCapsMap *textureCapsMap, + gl::Extensions *extensions, + gl::Limitations *limitations); } namespace d3d9 @@ -76,8 +86,7 @@ inline bool isDeviceLostError(HRESULT errorCode) } } -Workarounds GenerateWorkarounds(); - +WorkaroundsD3D GenerateWorkarounds(); } } diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/shaders/compiled/componentmaskps.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/shaders/compiled/componentmaskps.h index 04073a5d472c..24482d755c9d 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/shaders/compiled/componentmaskps.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/shaders/compiled/componentmaskps.h @@ -1,84 +1,84 @@ -#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 -}; +#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/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/shaders/compiled/flipyvs.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/shaders/compiled/flipyvs.h index 360e970c6ec0..5eb5131328e5 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/shaders/compiled/flipyvs.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/shaders/compiled/flipyvs.h @@ -1,66 +1,66 @@ -#if 0 -// -// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 -// -// Parameters: -// -// float4 halfPixelSize; -// -// -// Registers: -// -// Name Reg Size -// ------------- ----- ---- -// halfPixelSize c0 1 -// - - vs_2_0 - def c1, 0.5, 1, 0, 0 - dcl_position v0 - add oPos, v0, c0 - mad oT0, v0, c1.xxyy, c1.xxzz - -// approximately 2 instruction slots used -#endif - -const BYTE g_vs20_flipyvs[] = -{ - 0, 2, 254, 255, 254, 255, - 36, 0, 67, 84, 65, 66, - 28, 0, 0, 0, 87, 0, - 0, 0, 0, 2, 254, 255, - 1, 0, 0, 0, 28, 0, - 0, 0, 0, 1, 0, 0, - 80, 0, 0, 0, 48, 0, - 0, 0, 2, 0, 0, 0, - 1, 0, 0, 0, 64, 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, 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, 171, - 171, 171, 81, 0, 0, 5, - 1, 0, 15, 160, 0, 0, - 0, 63, 0, 0, 128, 63, - 0, 0, 0, 0, 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, 224, 0, 0, 228, 144, - 1, 0, 80, 160, 1, 0, - 160, 160, 255, 255, 0, 0 -}; +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 +// +// Parameters: +// +// float4 halfPixelSize; +// +// +// Registers: +// +// Name Reg Size +// ------------- ----- ---- +// halfPixelSize c0 1 +// + + vs_2_0 + def c1, 0.5, 1, 0, 0 + dcl_position v0 + add oPos, v0, c0 + mad oT0, v0, c1.xxyy, c1.xxzz + +// approximately 2 instruction slots used +#endif + +const BYTE g_vs20_flipyvs[] = +{ + 0, 2, 254, 255, 254, 255, + 36, 0, 67, 84, 65, 66, + 28, 0, 0, 0, 87, 0, + 0, 0, 0, 2, 254, 255, + 1, 0, 0, 0, 28, 0, + 0, 0, 0, 1, 0, 0, + 80, 0, 0, 0, 48, 0, + 0, 0, 2, 0, 0, 0, + 1, 0, 0, 0, 64, 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, 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, 171, + 171, 171, 81, 0, 0, 5, + 1, 0, 15, 160, 0, 0, + 0, 63, 0, 0, 128, 63, + 0, 0, 0, 0, 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, 224, 0, 0, 228, 144, + 1, 0, 80, 160, 1, 0, + 160, 160, 255, 255, 0, 0 +}; diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/shaders/compiled/luminanceps.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/shaders/compiled/luminanceps.h index 1f4d4822569f..bdd25ac13632 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/shaders/compiled/luminanceps.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/shaders/compiled/luminanceps.h @@ -1,94 +1,94 @@ -#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 -}; +#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/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/shaders/compiled/passthroughps.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/shaders/compiled/passthroughps.h index f43f6f2f2849..337af92ec64b 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/shaders/compiled/passthroughps.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/shaders/compiled/passthroughps.h @@ -1,61 +1,61 @@ -#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 -}; +#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/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/shaders/compiled/standardvs.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/shaders/compiled/standardvs.h index a268877b6962..a83050d8c2e4 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/shaders/compiled/standardvs.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/shaders/compiled/standardvs.h @@ -1,66 +1,66 @@ -#if 0 -// -// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 -// -// Parameters: -// -// float4 halfPixelSize; -// -// -// Registers: -// -// Name Reg Size -// ------------- ----- ---- -// halfPixelSize c0 1 -// - - vs_2_0 - def c1, 0.5, -0.5, 1, 0 - dcl_position v0 - add oPos, v0, c0 - mad oT0, v0, c1.xyzz, c1.xxww - -// approximately 2 instruction slots used -#endif - -const BYTE g_vs20_standardvs[] = -{ - 0, 2, 254, 255, 254, 255, - 36, 0, 67, 84, 65, 66, - 28, 0, 0, 0, 87, 0, - 0, 0, 0, 2, 254, 255, - 1, 0, 0, 0, 28, 0, - 0, 0, 0, 1, 0, 0, - 80, 0, 0, 0, 48, 0, - 0, 0, 2, 0, 0, 0, - 1, 0, 0, 0, 64, 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, 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, 171, - 171, 171, 81, 0, 0, 5, - 1, 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, 224, 0, 0, 228, 144, - 1, 0, 164, 160, 1, 0, - 240, 160, 255, 255, 0, 0 -}; +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 +// +// Parameters: +// +// float4 halfPixelSize; +// +// +// Registers: +// +// Name Reg Size +// ------------- ----- ---- +// halfPixelSize c0 1 +// + + vs_2_0 + def c1, 0.5, -0.5, 1, 0 + dcl_position v0 + add oPos, v0, c0 + mad oT0, v0, c1.xyzz, c1.xxww + +// approximately 2 instruction slots used +#endif + +const BYTE g_vs20_standardvs[] = +{ + 0, 2, 254, 255, 254, 255, + 36, 0, 67, 84, 65, 66, + 28, 0, 0, 0, 87, 0, + 0, 0, 0, 2, 254, 255, + 1, 0, 0, 0, 28, 0, + 0, 0, 0, 1, 0, 0, + 80, 0, 0, 0, 48, 0, + 0, 0, 2, 0, 0, 0, + 1, 0, 0, 0, 64, 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, 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, 171, + 171, 171, 81, 0, 0, 5, + 1, 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, 224, 0, 0, 228, 144, + 1, 0, 164, 160, 1, 0, + 240, 160, 255, 255, 0, 0 +}; diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/shaders/generate_shaders.bat b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/shaders/generate_shaders.bat index a12b8afa22b4..19a99ba91493 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/shaders/generate_shaders.bat +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/shaders/generate_shaders.bat @@ -1,63 +1,63 @@ -@ECHO OFF -REM -REM Copyright (c) 2013 The ANGLE Project Authors. All rights reserved. -REM Use of this source code is governed by a BSD-style license that can be -REM found in the LICENSE file. -REM - -PATH %PATH%;%ProgramFiles(x86)%\Windows Kits\8.1\bin\x86;%DXSDK_DIR%\Utilities\bin\x86 - -setlocal -set errorCount=0 -set successCount=0 -set debug=0 - -if "%1" == "debug" ( - set debug=1 -) -if "%1" == "release" ( - set debug=0 -) - -:: | Input file | Entry point | Type | Output file | Debug | -call:BuildShader Blit.vs standardvs vs_2_0 compiled\standardvs.h %debug% -call:BuildShader Blit.vs flipyvs vs_2_0 compiled\flipyvs.h %debug% -call:BuildShader Blit.ps passthroughps ps_2_0 compiled\passthroughps.h %debug% -call:BuildShader Blit.ps luminanceps ps_2_0 compiled\luminanceps.h %debug% -call:BuildShader Blit.ps componentmaskps ps_2_0 compiled\componentmaskps.h %debug% - -echo. - -if %successCount% GTR 0 ( - echo %successCount% shaders compiled successfully. -) -if %errorCount% GTR 0 ( - echo There were %errorCount% shader compilation errors. -) - -endlocal -exit /b - -:BuildShader -set input=%~1 -set entry=%~2 -set type=%~3 -set output=%~4 -set debug=%~5 - -if %debug% == 0 ( - set "buildCMD=fxc /nologo /E %entry% /T %type% /Fh %output% %input%" -) else ( - set "buildCMD=fxc /nologo /Zi /Od /E %entry% /T %type% /Fh %output% %input%" -) - -set error=0 -%buildCMD% || set error=1 - -if %error% == 0 ( - set /a successCount=%successCount%+1 -) else ( - set /a errorCount=%errorCount%+1 -) - -exit /b +@ECHO OFF +REM +REM Copyright (c) 2013 The ANGLE Project Authors. All rights reserved. +REM Use of this source code is governed by a BSD-style license that can be +REM found in the LICENSE file. +REM + +PATH %PATH%;%ProgramFiles(x86)%\Windows Kits\8.1\bin\x86;%DXSDK_DIR%\Utilities\bin\x86 + +setlocal +set errorCount=0 +set successCount=0 +set debug=0 + +if "%1" == "debug" ( + set debug=1 +) +if "%1" == "release" ( + set debug=0 +) + +:: | Input file | Entry point | Type | Output file | Debug | +call:BuildShader Blit.vs standardvs vs_2_0 compiled\standardvs.h %debug% +call:BuildShader Blit.vs flipyvs vs_2_0 compiled\flipyvs.h %debug% +call:BuildShader Blit.ps passthroughps ps_2_0 compiled\passthroughps.h %debug% +call:BuildShader Blit.ps luminanceps ps_2_0 compiled\luminanceps.h %debug% +call:BuildShader Blit.ps componentmaskps ps_2_0 compiled\componentmaskps.h %debug% + +echo. + +if %successCount% GTR 0 ( + echo %successCount% shaders compiled successfully. +) +if %errorCount% GTR 0 ( + echo There were %errorCount% shader compilation errors. +) + +endlocal +exit /b + +:BuildShader +set input=%~1 +set entry=%~2 +set type=%~3 +set output=%~4 +set debug=%~5 + +if %debug% == 0 ( + set "buildCMD=fxc /nologo /E %entry% /T %type% /Fh %output% %input%" +) else ( + set "buildCMD=fxc /nologo /Zi /Od /E %entry% /T %type% /Fh %output% %input%" +) + +set error=0 +%buildCMD% || set error=1 + +if %error% == 0 ( + set /a successCount=%successCount%+1 +) else ( + set /a errorCount=%errorCount%+1 +) + +exit /b diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/vertexconversion.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/vertexconversion.h index 32eb376a780e..aa05934bc883 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/vertexconversion.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/vertexconversion.h @@ -149,7 +149,10 @@ struct NormalizedDefaultValues // 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 > +template > struct VertexDataConverter { typedef typename Converter::OutputType OutputType; diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/formatutilsD3D.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/formatutilsD3D.cpp index 8a4d41cbd98b..e1c955eb067a 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/formatutilsD3D.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/formatutilsD3D.cpp @@ -106,8 +106,8 @@ static FormatWriteFunctionMap BuildFormatWriteFunctionMap() InsertFormatWriteFunctionMapping(&map, GL_ALPHA, GL_HALF_FLOAT_OES, WriteColor ); InsertFormatWriteFunctionMapping(&map, GL_BGRA_EXT, GL_UNSIGNED_BYTE, WriteColor ); - InsertFormatWriteFunctionMapping(&map, GL_BGRA_EXT, GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT, WriteColor ); - InsertFormatWriteFunctionMapping(&map, GL_BGRA_EXT, GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT, WriteColor ); + InsertFormatWriteFunctionMapping(&map, GL_BGRA_EXT, GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT, WriteColor ); + InsertFormatWriteFunctionMapping(&map, GL_BGRA_EXT, GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT, WriteColor ); InsertFormatWriteFunctionMapping(&map, GL_SRGB_EXT, GL_UNSIGNED_BYTE, WriteColor ); InsertFormatWriteFunctionMapping(&map, GL_SRGB_ALPHA_EXT, GL_UNSIGNED_BYTE, WriteColor ); diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/imageformats.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/imageformats.h index 123359ca0df2..76f1830e64ce 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/imageformats.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/imageformats.h @@ -285,6 +285,8 @@ struct B8G8R8 struct R5G6B5 { + // OpenGL ES 2.0.25 spec Section 3.6.2: "Components are packed with the first component in the most significant + // bits of the bitfield, and successive component occupying progressively less significant locations" unsigned short RGB; static void readColor(gl::ColorF *dst, const R5G6B5 *src) @@ -491,157 +493,123 @@ struct B8G8R8X8 } }; -struct B5G5R5A1 +struct A1R5G5B5 { - unsigned short BGRA; + unsigned short ARGB; - static void readColor(gl::ColorF *dst, const B5G5R5A1 *src) + static void readColor(gl::ColorF *dst, const A1R5G5B5 *src) { - dst->alpha = gl::normalizedToFloat<1>(gl::getShiftedData<1, 15>(src->BGRA)); - dst->red = gl::normalizedToFloat<5>(gl::getShiftedData<5, 10>(src->BGRA)); - dst->green = gl::normalizedToFloat<5>(gl::getShiftedData<5, 5>(src->BGRA)); - dst->blue = gl::normalizedToFloat<5>(gl::getShiftedData<5, 0>(src->BGRA)); + dst->alpha = gl::normalizedToFloat<1>(gl::getShiftedData<1, 15>(src->ARGB)); + dst->red = gl::normalizedToFloat<5>(gl::getShiftedData<5, 10>(src->ARGB)); + dst->green = gl::normalizedToFloat<5>(gl::getShiftedData<5, 5>(src->ARGB)); + dst->blue = gl::normalizedToFloat<5>(gl::getShiftedData<5, 0>(src->ARGB)); } - static void writeColor(B5G5R5A1 *dst, const gl::ColorF *src) + static void writeColor(A1R5G5B5 *dst, const gl::ColorF *src) { - dst->BGRA = gl::shiftData<1, 15>(gl::floatToNormalized<1, unsigned short>(src->alpha)) | + dst->ARGB = gl::shiftData<1, 15>(gl::floatToNormalized<1, unsigned short>(src->alpha)) | gl::shiftData<5, 10>(gl::floatToNormalized<5, unsigned short>(src->red)) | gl::shiftData<5, 5>(gl::floatToNormalized<5, unsigned short>(src->green)) | gl::shiftData<5, 0>(gl::floatToNormalized<5, unsigned short>(src->blue)); } - static void average(B5G5R5A1 *dst, const B5G5R5A1 *src1, const B5G5R5A1 *src2) + static void average(A1R5G5B5 *dst, const A1R5G5B5 *src1, const A1R5G5B5 *src2) { - dst->BGRA = gl::shiftData<1, 15>(gl::average(gl::getShiftedData<1, 15>(src1->BGRA), gl::getShiftedData<1, 15>(src2->BGRA))) | - gl::shiftData<5, 10>(gl::average(gl::getShiftedData<5, 10>(src1->BGRA), gl::getShiftedData<5, 10>(src2->BGRA))) | - gl::shiftData<5, 5>(gl::average(gl::getShiftedData<5, 5>(src1->BGRA), gl::getShiftedData<5, 5>(src2->BGRA))) | - gl::shiftData<5, 0>(gl::average(gl::getShiftedData<5, 0>(src1->BGRA), gl::getShiftedData<5, 0>(src2->BGRA))); + dst->ARGB = gl::shiftData<1, 15>(gl::average(gl::getShiftedData<1, 15>(src1->ARGB), gl::getShiftedData<1, 15>(src2->ARGB))) | + gl::shiftData<5, 10>(gl::average(gl::getShiftedData<5, 10>(src1->ARGB), gl::getShiftedData<5, 10>(src2->ARGB))) | + gl::shiftData<5, 5>(gl::average(gl::getShiftedData<5, 5>(src1->ARGB), gl::getShiftedData<5, 5>(src2->ARGB))) | + gl::shiftData<5, 0>(gl::average(gl::getShiftedData<5, 0>(src1->ARGB), gl::getShiftedData<5, 0>(src2->ARGB))); } }; struct R5G5B5A1 { + // OpenGL ES 2.0.25 spec Section 3.6.2: "Components are packed with the first component in the most significant + // bits of the bitfield, and successive component occupying progressively less significant locations" unsigned short RGBA; static void readColor(gl::ColorF *dst, const R5G5B5A1 *src) { - dst->alpha = gl::normalizedToFloat<1>(gl::getShiftedData<1, 15>(src->RGBA)); - dst->blue = gl::normalizedToFloat<5>(gl::getShiftedData<5, 10>(src->RGBA)); - dst->green = gl::normalizedToFloat<5>(gl::getShiftedData<5, 5>(src->RGBA)); - dst->red = gl::normalizedToFloat<5>(gl::getShiftedData<5, 0>(src->RGBA)); + dst->red = gl::normalizedToFloat<5>(gl::getShiftedData<5, 11>(src->RGBA)); + dst->green = gl::normalizedToFloat<5>(gl::getShiftedData<5, 6>(src->RGBA)); + dst->blue = gl::normalizedToFloat<5>(gl::getShiftedData<5, 1>(src->RGBA)); + dst->alpha = gl::normalizedToFloat<1>(gl::getShiftedData<1, 0>(src->RGBA)); } static void writeColor(R5G5B5A1 *dst, const gl::ColorF *src) { - dst->RGBA = gl::shiftData<1, 15>(gl::floatToNormalized<1, unsigned short>(src->alpha)) | - gl::shiftData<5, 10>(gl::floatToNormalized<5, unsigned short>(src->blue)) | - gl::shiftData<5, 5>(gl::floatToNormalized<5, unsigned short>(src->green)) | - gl::shiftData<5, 0>(gl::floatToNormalized<5, unsigned short>(src->red)); + dst->RGBA = gl::shiftData<5, 11>(gl::floatToNormalized<5, unsigned short>(src->red)) | + gl::shiftData<5, 6>(gl::floatToNormalized<5, unsigned short>(src->green)) | + gl::shiftData<5, 1>(gl::floatToNormalized<5, unsigned short>(src->blue)) | + gl::shiftData<1, 0>(gl::floatToNormalized<1, unsigned short>(src->alpha)); } static void average(R5G5B5A1 *dst, const R5G5B5A1 *src1, const R5G5B5A1 *src2) { - dst->RGBA = gl::shiftData<1, 15>(gl::average(gl::getShiftedData<1, 15>(src1->RGBA), gl::getShiftedData<1, 15>(src2->RGBA))) | - gl::shiftData<5, 10>(gl::average(gl::getShiftedData<5, 10>(src1->RGBA), gl::getShiftedData<5, 10>(src2->RGBA))) | - gl::shiftData<5, 5>(gl::average(gl::getShiftedData<5, 5>(src1->RGBA), gl::getShiftedData<5, 5>(src2->RGBA))) | - gl::shiftData<5, 0>(gl::average(gl::getShiftedData<5, 0>(src1->RGBA), gl::getShiftedData<5, 0>(src2->RGBA))); + dst->RGBA = gl::shiftData<5, 11>(gl::average(gl::getShiftedData<5, 11>(src1->RGBA), gl::getShiftedData<5, 11>(src2->RGBA))) | + gl::shiftData<5, 6>(gl::average(gl::getShiftedData<5, 6>(src1->RGBA), gl::getShiftedData<5, 6>(src2->RGBA))) | + gl::shiftData<5, 1>(gl::average(gl::getShiftedData<5, 1>(src1->RGBA), gl::getShiftedData<5, 1>(src2->RGBA))) | + gl::shiftData<1, 0>(gl::average(gl::getShiftedData<1, 0>(src1->RGBA), gl::getShiftedData<1, 0>(src2->RGBA))); } }; struct R4G4B4A4 { - unsigned char R : 4; - unsigned char G : 4; - unsigned char B : 4; - unsigned char A : 4; + // OpenGL ES 2.0.25 spec Section 3.6.2: "Components are packed with the first component in the most significant + // bits of the bitfield, and successive component occupying progressively less significant locations" + unsigned short RGBA; static void readColor(gl::ColorF *dst, const R4G4B4A4 *src) { - dst->red = gl::normalizedToFloat<4>(src->R); - dst->green = gl::normalizedToFloat<4>(src->G); - dst->blue = gl::normalizedToFloat<4>(src->B); - dst->alpha = gl::normalizedToFloat<4>(src->A); + dst->red = gl::normalizedToFloat<4>(gl::getShiftedData<4, 12>(src->RGBA)); + dst->green = gl::normalizedToFloat<4>(gl::getShiftedData<4, 8>(src->RGBA)); + dst->blue = gl::normalizedToFloat<4>(gl::getShiftedData<4, 4>(src->RGBA)); + dst->alpha = gl::normalizedToFloat<4>(gl::getShiftedData<4, 0>(src->RGBA)); } static void writeColor(R4G4B4A4 *dst, const gl::ColorF *src) { - dst->R = gl::floatToNormalized<4, unsigned char>(src->red); - dst->G = gl::floatToNormalized<4, unsigned char>(src->green); - dst->B = gl::floatToNormalized<4, unsigned char>(src->blue); - dst->A = gl::floatToNormalized<4, unsigned char>(src->alpha); + dst->RGBA = gl::shiftData<4, 12>(gl::floatToNormalized<4, unsigned short>(src->red)) | + gl::shiftData<4, 8>(gl::floatToNormalized<4, unsigned short>(src->green)) | + gl::shiftData<4, 4>(gl::floatToNormalized<4, unsigned short>(src->blue)) | + gl::shiftData<4, 0>(gl::floatToNormalized<4, unsigned short>(src->alpha)); } static void average(R4G4B4A4 *dst, const R4G4B4A4 *src1, const R4G4B4A4 *src2) { - dst->R = gl::average(src1->R, src2->R); - dst->G = gl::average(src1->G, src2->G); - dst->B = gl::average(src1->B, src2->B); - dst->A = gl::average(src1->A, src2->A); + dst->RGBA = gl::shiftData<4, 12>(gl::average(gl::getShiftedData<4, 12>(src1->RGBA), gl::getShiftedData<4, 12>(src2->RGBA))) | + gl::shiftData<4, 8>(gl::average(gl::getShiftedData<4, 8>(src1->RGBA), gl::getShiftedData<4, 8>(src2->RGBA))) | + gl::shiftData<4, 4>(gl::average(gl::getShiftedData<4, 4>(src1->RGBA), gl::getShiftedData<4, 4>(src2->RGBA))) | + gl::shiftData<4, 0>(gl::average(gl::getShiftedData<4, 0>(src1->RGBA), gl::getShiftedData<4, 0>(src2->RGBA))); } }; struct A4R4G4B4 { - unsigned char A : 4; - unsigned char R : 4; - unsigned char G : 4; - unsigned char B : 4; + unsigned short ARGB; static void readColor(gl::ColorF *dst, const A4R4G4B4 *src) { - dst->red = gl::normalizedToFloat<4>(src->R); - dst->green = gl::normalizedToFloat<4>(src->G); - dst->blue = gl::normalizedToFloat<4>(src->B); - dst->alpha = gl::normalizedToFloat<4>(src->A); + dst->alpha = gl::normalizedToFloat<4>(gl::getShiftedData<4, 12>(src->ARGB)); + dst->red = gl::normalizedToFloat<4>(gl::getShiftedData<4, 8>(src->ARGB)); + dst->green = gl::normalizedToFloat<4>(gl::getShiftedData<4, 4>(src->ARGB)); + dst->blue = gl::normalizedToFloat<4>(gl::getShiftedData<4, 0>(src->ARGB)); } static void writeColor(A4R4G4B4 *dst, const gl::ColorF *src) { - dst->R = gl::floatToNormalized<4, unsigned char>(src->red); - dst->G = gl::floatToNormalized<4, unsigned char>(src->green); - dst->B = gl::floatToNormalized<4, unsigned char>(src->blue); - dst->A = gl::floatToNormalized<4, unsigned char>(src->alpha); + dst->ARGB = gl::shiftData<4, 12>(gl::floatToNormalized<4, unsigned short>(src->alpha)) | + gl::shiftData<4, 8>(gl::floatToNormalized<4, unsigned short>(src->red)) | + gl::shiftData<4, 4>(gl::floatToNormalized<4, unsigned short>(src->green)) | + gl::shiftData<4, 0>(gl::floatToNormalized<4, unsigned short>(src->blue)); } static void average(A4R4G4B4 *dst, const A4R4G4B4 *src1, const A4R4G4B4 *src2) { - dst->R = gl::average(src1->R, src2->R); - dst->G = gl::average(src1->G, src2->G); - dst->B = gl::average(src1->B, src2->B); - dst->A = gl::average(src1->A, src2->A); - } -}; - -struct B4G4R4A4 -{ - unsigned char B : 4; - unsigned char G : 4; - unsigned char R : 4; - unsigned char A : 4; - - static void readColor(gl::ColorF *dst, const B4G4R4A4 *src) - { - dst->red = gl::normalizedToFloat<4>(src->R); - dst->green = gl::normalizedToFloat<4>(src->G); - dst->blue = gl::normalizedToFloat<4>(src->B); - dst->alpha = gl::normalizedToFloat<4>(src->A); - } - - static void writeColor(B4G4R4A4 *dst, const gl::ColorF *src) - { - dst->R = gl::floatToNormalized<4, unsigned char>(src->red); - dst->G = gl::floatToNormalized<4, unsigned char>(src->green); - dst->B = gl::floatToNormalized<4, unsigned char>(src->blue); - dst->A = gl::floatToNormalized<4, unsigned char>(src->alpha); - } - - static void average(B4G4R4A4 *dst, const B4G4R4A4 *src1, const B4G4R4A4 *src2) - { - dst->R = gl::average(src1->R, src2->R); - dst->G = gl::average(src1->G, src2->G); - dst->B = gl::average(src1->B, src2->B); - dst->A = gl::average(src1->A, src2->A); + dst->ARGB = gl::shiftData<4, 12>(gl::average(gl::getShiftedData<4, 12>(src1->ARGB), gl::getShiftedData<4, 12>(src2->ARGB))) | + gl::shiftData<4, 8>(gl::average(gl::getShiftedData<4, 8>(src1->ARGB), gl::getShiftedData<4, 8>(src2->ARGB))) | + gl::shiftData<4, 4>(gl::average(gl::getShiftedData<4, 4>(src1->ARGB), gl::getShiftedData<4, 4>(src2->ARGB))) | + gl::shiftData<4, 0>(gl::average(gl::getShiftedData<4, 0>(src1->ARGB), gl::getShiftedData<4, 0>(src2->ARGB))); } }; diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/loadimage.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/loadimage.cpp index 4560bd0b6215..b9b9e5e4ab30 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/loadimage.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/loadimage.cpp @@ -348,6 +348,24 @@ void LoadRGBA8ToBGRA8(size_t width, size_t height, size_t depth, } } +void LoadRGBA4ToARGB4(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) +{ + for (size_t z = 0; z < depth; z++) + { + for (size_t y = 0; y < height; y++) + { + const uint16_t *source = OffsetDataPointer(input, y, z, inputRowPitch, inputDepthPitch); + uint16_t *dest = OffsetDataPointer(output, y, z, outputRowPitch, outputDepthPitch); + for (size_t x = 0; x < width; x++) + { + dest[x] = ANGLE_ROTR16(source[x], 4); + } + } + } +} + void LoadRGBA4ToBGRA8(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) @@ -414,6 +432,24 @@ void LoadBGRA4ToBGRA8(size_t width, size_t height, size_t depth, } } +void LoadRGB5A1ToA1RGB5(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) +{ + for (size_t z = 0; z < depth; z++) + { + for (size_t y = 0; y < height; y++) + { + const uint16_t *source = OffsetDataPointer(input, y, z, inputRowPitch, inputDepthPitch); + uint16_t *dest = OffsetDataPointer(output, y, z, outputRowPitch, outputDepthPitch); + for (size_t x = 0; x < width; x++) + { + dest[x] = ANGLE_ROTR16(source[x], 1); + } + } + } +} + void LoadRGB5A1ToBGRA8(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) @@ -458,7 +494,6 @@ void LoadRGB5A1ToRGBA8(size_t width, size_t height, size_t depth, } } - void LoadBGR5A1ToBGRA8(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) diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/loadimage.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/loadimage.h index 6967dc868e45..6c5118365e30 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/loadimage.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/loadimage.h @@ -96,6 +96,10 @@ void LoadRGBA8ToBGRA8(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); +void LoadRGBA4ToARGB4(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); + void LoadRGBA4ToBGRA8(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); @@ -108,6 +112,10 @@ void LoadBGRA4ToBGRA8(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); +void LoadRGB5A1ToA1RGB5(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); + void LoadRGB5A1ToBGRA8(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); diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/loadimage_etc.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/loadimage_etc.cpp new file mode 100644 index 000000000000..cdb9389b3aaa --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/loadimage_etc.cpp @@ -0,0 +1,1504 @@ +// +// Copyright (c) 2013-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. +// + +// loadimage_etc.cpp: Decodes ETC and EAC encoded textures. + +#include "libANGLE/renderer/d3d/loadimage_etc.h" + +#include "libANGLE/renderer/d3d/loadimage.h" +#include "libANGLE/renderer/d3d/imageformats.h" + +namespace rx +{ +namespace +{ +// Table 3.17.2 sorted according to table 3.17.3 +// clang-format off +static const int intensityModifierDefault[][4] = +{ + { 2, 8, -2, -8 }, + { 5, 17, -5, -17 }, + { 9, 29, -9, -29 }, + { 13, 42, -13, -42 }, + { 18, 60, -18, -60 }, + { 24, 80, -24, -80 }, + { 33, 106, -33, -106 }, + { 47, 183, -47, -183 }, +}; +// clang-format on + +// Table C.12, intensity modifier for non opaque punchthrough alpha +// clang-format off +static const int intensityModifierNonOpaque[][4] = +{ + { 0, 8, 0, -8 }, + { 0, 17, 0, -17 }, + { 0, 29, 0, -29 }, + { 0, 42, 0, -42 }, + { 0, 60, 0, -60 }, + { 0, 80, 0, -80 }, + { 0, 106, 0, -106 }, + { 0, 183, 0, -183 }, +}; +// clang-format on + +struct ETC2Block +{ + // Decodes unsigned single or dual channel block to bytes + void decodeAsSingleChannel(uint8_t *dest, + size_t x, + size_t y, + size_t w, + size_t h, + size_t destPixelStride, + size_t destRowPitch, + bool isSigned) const + { + for (size_t j = 0; j < 4 && (y + j) < h; j++) + { + uint8_t *row = dest + (j * destRowPitch); + for (size_t i = 0; i < 4 && (x + i) < w; i++) + { + uint8_t *pixel = row + (i * destPixelStride); + if (isSigned) + { + *pixel = clampSByte(getSingleChannel(i, j, isSigned)); + } + else + { + *pixel = clampByte(getSingleChannel(i, j, isSigned)); + } + } + } + } + + // Decodes RGB block to rgba8 + void decodeAsRGB(uint8_t *dest, + size_t x, + size_t y, + size_t w, + size_t h, + size_t destRowPitch, + const uint8_t alphaValues[4][4], + bool punchThroughAlpha) const + { + bool opaqueBit = u.idht.mode.idm.diffbit; + bool nonOpaquePunchThroughAlpha = punchThroughAlpha && !opaqueBit; + // Select mode + if (u.idht.mode.idm.diffbit || punchThroughAlpha) + { + const auto &block = u.idht.mode.idm.colors.diff; + int r = (block.R + block.dR); + int g = (block.G + block.dG); + int b = (block.B + block.dB); + if (r < 0 || r > 31) + { + decodeTBlock(dest, x, y, w, h, destRowPitch, alphaValues, + nonOpaquePunchThroughAlpha); + } + else if (g < 0 || g > 31) + { + decodeHBlock(dest, x, y, w, h, destRowPitch, alphaValues, + nonOpaquePunchThroughAlpha); + } + else if (b < 0 || b > 31) + { + decodePlanarBlock(dest, x, y, w, h, destRowPitch, alphaValues); + } + else + { + decodeDifferentialBlock(dest, x, y, w, h, destRowPitch, alphaValues, + nonOpaquePunchThroughAlpha); + } + } + else + { + decodeIndividualBlock(dest, x, y, w, h, destRowPitch, alphaValues, + nonOpaquePunchThroughAlpha); + } + } + + // Transcodes RGB block to BC1 + void transcodeAsBC1(uint8_t *dest, + size_t x, + size_t y, + size_t w, + size_t h, + const uint8_t alphaValues[4][4], + bool punchThroughAlpha) const + { + bool opaqueBit = u.idht.mode.idm.diffbit; + bool nonOpaquePunchThroughAlpha = punchThroughAlpha && !opaqueBit; + // Select mode + if (u.idht.mode.idm.diffbit || punchThroughAlpha) + { + const auto &block = u.idht.mode.idm.colors.diff; + int r = (block.R + block.dR); + int g = (block.G + block.dG); + int b = (block.B + block.dB); + if (r < 0 || r > 31) + { + transcodeTBlockToBC1(dest, x, y, w, h, alphaValues, nonOpaquePunchThroughAlpha); + } + else if (g < 0 || g > 31) + { + transcodeHBlockToBC1(dest, x, y, w, h, alphaValues, nonOpaquePunchThroughAlpha); + } + else if (b < 0 || b > 31) + { + transcodePlanarBlockToBC1(dest, x, y, w, h, alphaValues); + } + else + { + transcodeDifferentialBlockToBC1(dest, x, y, w, h, alphaValues, + nonOpaquePunchThroughAlpha); + } + } + else + { + transcodeIndividualBlockToBC1(dest, x, y, w, h, alphaValues, + nonOpaquePunchThroughAlpha); + } + } + + private: + union + { + // Individual, differential, H and T modes + struct + { + union + { + // Individual and differential modes + struct + { + union + { + struct // Individual colors + { + unsigned char R2 : 4; + unsigned char R1 : 4; + unsigned char G2 : 4; + unsigned char G1 : 4; + unsigned char B2 : 4; + unsigned char B1 : 4; + } indiv; + struct // Differential colors + { + signed char dR : 3; + unsigned char R : 5; + signed char dG : 3; + unsigned char G : 5; + signed char dB : 3; + unsigned char B : 5; + } diff; + } colors; + bool flipbit : 1; + bool diffbit : 1; + unsigned char cw2 : 3; + unsigned char cw1 : 3; + } idm; + // T mode + struct + { + // Byte 1 + unsigned char TR1b : 2; + unsigned char TdummyB : 1; + unsigned char TR1a : 2; + unsigned char TdummyA : 3; + // Byte 2 + unsigned char TB1 : 4; + unsigned char TG1 : 4; + // Byte 3 + unsigned char TG2 : 4; + unsigned char TR2 : 4; + // Byte 4 + unsigned char Tdb : 1; + bool Tflipbit : 1; + unsigned char Tda : 2; + unsigned char TB2 : 4; + } tm; + // H mode + struct + { + // Byte 1 + unsigned char HG1a : 3; + unsigned char HR1 : 4; + unsigned char HdummyA : 1; + // Byte 2 + unsigned char HB1b : 2; + unsigned char HdummyC : 1; + unsigned char HB1a : 1; + unsigned char HG1b : 1; + unsigned char HdummyB : 3; + // Byte 3 + unsigned char HG2a : 3; + unsigned char HR2 : 4; + unsigned char HB1c : 1; + // Byte 4 + unsigned char Hdb : 1; + bool Hflipbit : 1; + unsigned char Hda : 1; + unsigned char HB2 : 4; + unsigned char HG2b : 1; + } hm; + } mode; + unsigned char pixelIndexMSB[2]; + unsigned char pixelIndexLSB[2]; + } idht; + // planar mode + struct + { + // Byte 1 + unsigned char GO1 : 1; + unsigned char RO : 6; + unsigned char PdummyA : 1; + // Byte 2 + unsigned char BO1 : 1; + unsigned char GO2 : 6; + unsigned char PdummyB : 1; + // Byte 3 + unsigned char BO3a : 2; + unsigned char PdummyD : 1; + unsigned char BO2 : 2; + unsigned char PdummyC : 3; + // Byte 4 + unsigned char RH2 : 1; + bool Pflipbit : 1; + unsigned char RH1 : 5; + unsigned char BO3b : 1; + // Byte 5 + unsigned char BHa : 1; + unsigned char GH : 7; + // Byte 6 + unsigned char RVa : 3; + unsigned char BHb : 5; + // Byte 7 + unsigned char GVa : 5; + unsigned char RVb : 3; + // Byte 8 + unsigned char BV : 6; + unsigned char GVb : 2; + } pblk; + // Single channel block + struct + { + union + { + unsigned char us; + signed char s; + } base_codeword; + unsigned char table_index : 4; + unsigned char multiplier : 4; + unsigned char mc1 : 2; + unsigned char mb : 3; + unsigned char ma : 3; + unsigned char mf1 : 1; + unsigned char me : 3; + unsigned char md : 3; + unsigned char mc2 : 1; + unsigned char mh : 3; + unsigned char mg : 3; + unsigned char mf2 : 2; + unsigned char mk1 : 2; + unsigned char mj : 3; + unsigned char mi : 3; + unsigned char mn1 : 1; + unsigned char mm : 3; + unsigned char ml : 3; + unsigned char mk2 : 1; + unsigned char mp : 3; + unsigned char mo : 3; + unsigned char mn2 : 2; + } scblk; + } u; + + static unsigned char clampByte(int value) + { + return static_cast(gl::clamp(value, 0, 255)); + } + + static signed char clampSByte(int value) + { + return static_cast(gl::clamp(value, -128, 127)); + } + + static R8G8B8A8 createRGBA(int red, int green, int blue, int alpha) + { + R8G8B8A8 rgba; + rgba.R = clampByte(red); + rgba.G = clampByte(green); + rgba.B = clampByte(blue); + rgba.A = clampByte(alpha); + return rgba; + } + + static R8G8B8A8 createRGBA(int red, int green, int blue) + { + return createRGBA(red, green, blue, 255); + } + + static int extend_4to8bits(int x) { return (x << 4) | x; } + static int extend_5to8bits(int x) { return (x << 3) | (x >> 2); } + static int extend_6to8bits(int x) { return (x << 2) | (x >> 4); } + static int extend_7to8bits(int x) { return (x << 1) | (x >> 6); } + + void decodeIndividualBlock(uint8_t *dest, + size_t x, + size_t y, + size_t w, + size_t h, + size_t destRowPitch, + const uint8_t alphaValues[4][4], + bool nonOpaquePunchThroughAlpha) const + { + const auto &block = u.idht.mode.idm.colors.indiv; + int r1 = extend_4to8bits(block.R1); + int g1 = extend_4to8bits(block.G1); + int b1 = extend_4to8bits(block.B1); + int r2 = extend_4to8bits(block.R2); + int g2 = extend_4to8bits(block.G2); + int b2 = extend_4to8bits(block.B2); + decodeIndividualOrDifferentialBlock(dest, x, y, w, h, destRowPitch, r1, g1, b1, r2, g2, b2, + alphaValues, nonOpaquePunchThroughAlpha); + } + + void decodeDifferentialBlock(uint8_t *dest, + size_t x, + size_t y, + size_t w, + size_t h, + size_t destRowPitch, + const uint8_t alphaValues[4][4], + bool nonOpaquePunchThroughAlpha) const + { + const auto &block = u.idht.mode.idm.colors.diff; + int b1 = extend_5to8bits(block.B); + int g1 = extend_5to8bits(block.G); + int r1 = extend_5to8bits(block.R); + int r2 = extend_5to8bits(block.R + block.dR); + int g2 = extend_5to8bits(block.G + block.dG); + int b2 = extend_5to8bits(block.B + block.dB); + decodeIndividualOrDifferentialBlock(dest, x, y, w, h, destRowPitch, r1, g1, b1, r2, g2, b2, + alphaValues, nonOpaquePunchThroughAlpha); + } + + void decodeIndividualOrDifferentialBlock(uint8_t *dest, + size_t x, + size_t y, + size_t w, + size_t h, + size_t destRowPitch, + int r1, + int g1, + int b1, + int r2, + int g2, + int b2, + const uint8_t alphaValues[4][4], + bool nonOpaquePunchThroughAlpha) const + { + const auto intensityModifier = + nonOpaquePunchThroughAlpha ? intensityModifierNonOpaque : intensityModifierDefault; + + R8G8B8A8 subblockColors0[4]; + R8G8B8A8 subblockColors1[4]; + for (size_t modifierIdx = 0; modifierIdx < 4; modifierIdx++) + { + const int i1 = intensityModifier[u.idht.mode.idm.cw1][modifierIdx]; + subblockColors0[modifierIdx] = createRGBA(r1 + i1, g1 + i1, b1 + i1); + + const int i2 = intensityModifier[u.idht.mode.idm.cw2][modifierIdx]; + subblockColors1[modifierIdx] = createRGBA(r2 + i2, g2 + i2, b2 + i2); + } + + if (u.idht.mode.idm.flipbit) + { + uint8_t *curPixel = dest; + for (size_t j = 0; j < 2 && (y + j) < h; j++) + { + R8G8B8A8 *row = reinterpret_cast(curPixel); + for (size_t i = 0; i < 4 && (x + i) < w; i++) + { + row[i] = subblockColors0[getIndex(i, j)]; + row[i].A = alphaValues[j][i]; + } + curPixel += destRowPitch; + } + for (size_t j = 2; j < 4 && (y + j) < h; j++) + { + R8G8B8A8 *row = reinterpret_cast(curPixel); + for (size_t i = 0; i < 4 && (x + i) < w; i++) + { + row[i] = subblockColors1[getIndex(i, j)]; + row[i].A = alphaValues[j][i]; + } + curPixel += destRowPitch; + } + } + else + { + uint8_t *curPixel = dest; + for (size_t j = 0; j < 4 && (y + j) < h; j++) + { + R8G8B8A8 *row = reinterpret_cast(curPixel); + for (size_t i = 0; i < 2 && (x + i) < w; i++) + { + row[i] = subblockColors0[getIndex(i, j)]; + row[i].A = alphaValues[j][i]; + } + for (size_t i = 2; i < 4 && (x + i) < w; i++) + { + row[i] = subblockColors1[getIndex(i, j)]; + row[i].A = alphaValues[j][i]; + } + curPixel += destRowPitch; + } + } + if (nonOpaquePunchThroughAlpha) + { + decodePunchThroughAlphaBlock(dest, x, y, w, h, destRowPitch); + } + } + + void decodeTBlock(uint8_t *dest, + size_t x, + size_t y, + size_t w, + size_t h, + size_t destRowPitch, + const uint8_t alphaValues[4][4], + bool nonOpaquePunchThroughAlpha) const + { + // Table C.8, distance index for T and H modes + const auto &block = u.idht.mode.tm; + + int r1 = extend_4to8bits(block.TR1a << 2 | block.TR1b); + int g1 = extend_4to8bits(block.TG1); + int b1 = extend_4to8bits(block.TB1); + int r2 = extend_4to8bits(block.TR2); + int g2 = extend_4to8bits(block.TG2); + int b2 = extend_4to8bits(block.TB2); + + static int distance[8] = {3, 6, 11, 16, 23, 32, 41, 64}; + const int d = distance[block.Tda << 1 | block.Tdb]; + + const R8G8B8A8 paintColors[4] = { + createRGBA(r1, g1, b1), createRGBA(r2 + d, g2 + d, b2 + d), createRGBA(r2, g2, b2), + createRGBA(r2 - d, g2 - d, b2 - d), + }; + + uint8_t *curPixel = dest; + for (size_t j = 0; j < 4 && (y + j) < h; j++) + { + R8G8B8A8 *row = reinterpret_cast(curPixel); + for (size_t i = 0; i < 4 && (x + i) < w; i++) + { + row[i] = paintColors[getIndex(i, j)]; + row[i].A = alphaValues[j][i]; + } + curPixel += destRowPitch; + } + + if (nonOpaquePunchThroughAlpha) + { + decodePunchThroughAlphaBlock(dest, x, y, w, h, destRowPitch); + } + } + + void decodeHBlock(uint8_t *dest, + size_t x, + size_t y, + size_t w, + size_t h, + size_t destRowPitch, + const uint8_t alphaValues[4][4], + bool nonOpaquePunchThroughAlpha) const + { + // Table C.8, distance index for T and H modes + const auto &block = u.idht.mode.hm; + + int r1 = extend_4to8bits(block.HR1); + int g1 = extend_4to8bits(block.HG1a << 1 | block.HG1b); + int b1 = extend_4to8bits(block.HB1a << 3 | block.HB1b << 1 | block.HB1c); + int r2 = extend_4to8bits(block.HR2); + int g2 = extend_4to8bits(block.HG2a << 1 | block.HG2b); + int b2 = extend_4to8bits(block.HB2); + + static const int distance[8] = {3, 6, 11, 16, 23, 32, 41, 64}; + const int d = distance[(block.Hda << 2) | (block.Hdb << 1) | + ((r1 << 16 | g1 << 8 | b1) >= (r2 << 16 | g2 << 8 | b2) ? 1 : 0)]; + + const R8G8B8A8 paintColors[4] = { + createRGBA(r1 + d, g1 + d, b1 + d), createRGBA(r1 - d, g1 - d, b1 - d), + createRGBA(r2 + d, g2 + d, b2 + d), createRGBA(r2 - d, g2 - d, b2 - d), + }; + + uint8_t *curPixel = dest; + for (size_t j = 0; j < 4 && (y + j) < h; j++) + { + R8G8B8A8 *row = reinterpret_cast(curPixel); + for (size_t i = 0; i < 4 && (x + i) < w; i++) + { + row[i] = paintColors[getIndex(i, j)]; + row[i].A = alphaValues[j][i]; + } + curPixel += destRowPitch; + } + + if (nonOpaquePunchThroughAlpha) + { + decodePunchThroughAlphaBlock(dest, x, y, w, h, destRowPitch); + } + } + + void decodePlanarBlock(uint8_t *dest, + size_t x, + size_t y, + size_t w, + size_t h, + size_t pitch, + const uint8_t alphaValues[4][4]) const + { + int ro = extend_6to8bits(u.pblk.RO); + int go = extend_7to8bits(u.pblk.GO1 << 6 | u.pblk.GO2); + int bo = + extend_6to8bits(u.pblk.BO1 << 5 | u.pblk.BO2 << 3 | u.pblk.BO3a << 1 | u.pblk.BO3b); + int rh = extend_6to8bits(u.pblk.RH1 << 1 | u.pblk.RH2); + int gh = extend_7to8bits(u.pblk.GH); + int bh = extend_6to8bits(u.pblk.BHa << 5 | u.pblk.BHb); + int rv = extend_6to8bits(u.pblk.RVa << 3 | u.pblk.RVb); + int gv = extend_7to8bits(u.pblk.GVa << 2 | u.pblk.GVb); + int bv = extend_6to8bits(u.pblk.BV); + + uint8_t *curPixel = dest; + for (size_t j = 0; j < 4 && (y + j) < h; j++) + { + R8G8B8A8 *row = reinterpret_cast(curPixel); + + int ry = static_cast(j) * (rv - ro) + 2; + int gy = static_cast(j) * (gv - go) + 2; + int by = static_cast(j) * (bv - bo) + 2; + for (size_t i = 0; i < 4 && (x + i) < w; i++) + { + row[i] = createRGBA(((static_cast(i) * (rh - ro) + ry) >> 2) + ro, + ((static_cast(i) * (gh - go) + gy) >> 2) + go, + ((static_cast(i) * (bh - bo) + by) >> 2) + bo, + alphaValues[j][i]); + } + curPixel += pitch; + } + } + + // Index for individual, differential, H and T modes + size_t getIndex(size_t x, size_t y) const + { + size_t bitIndex = x * 4 + y; + size_t bitOffset = bitIndex & 7; + size_t lsb = (u.idht.pixelIndexLSB[1 - (bitIndex >> 3)] >> bitOffset) & 1; + size_t msb = (u.idht.pixelIndexMSB[1 - (bitIndex >> 3)] >> bitOffset) & 1; + return (msb << 1) | lsb; + } + + void decodePunchThroughAlphaBlock(uint8_t *dest, + size_t x, + size_t y, + size_t w, + size_t h, + size_t destRowPitch) const + { + uint8_t *curPixel = dest; + for (size_t j = 0; j < 4 && (y + j) < h; j++) + { + R8G8B8A8 *row = reinterpret_cast(curPixel); + for (size_t i = 0; i < 4 && (x + i) < w; i++) + { + if (getIndex(i, j) == 2) // msb == 1 && lsb == 0 + { + row[i] = createRGBA(0, 0, 0, 0); + } + } + curPixel += destRowPitch; + } + } + + uint16_t RGB8ToRGB565(const R8G8B8A8 &rgba) const + { + return (static_cast(rgba.R >> 3) << 11) | + (static_cast(rgba.G >> 2) << 5) | + (static_cast(rgba.B >> 3) << 0); + } + + uint32_t matchBC1Bits(const R8G8B8A8 *rgba, + const R8G8B8A8 &minColor, + const R8G8B8A8 &maxColor, + bool opaque) const + { + // Project each pixel on the (maxColor, minColor) line to decide which + // BC1 code to assign to it. + + uint8_t decodedColors[2][3] = {{maxColor.R, maxColor.G, maxColor.B}, + {minColor.R, minColor.G, minColor.B}}; + + int direction[3]; + for (int ch = 0; ch < 3; ch++) + { + direction[ch] = decodedColors[0][ch] - decodedColors[1][ch]; + } + + int stops[2]; + for (int i = 0; i < 2; i++) + { + stops[i] = decodedColors[i][0] * direction[0] + decodedColors[i][1] * direction[1] + + decodedColors[i][2] * direction[2]; + } + + uint32_t bits = 0; + if (opaque) + { + for (int i = 15; i >= 0; i--) + { + // In opaque mode, the code is from 0 to 3. + + bits <<= 2; + const int dot = + rgba[i].R * direction[0] + rgba[i].G * direction[1] + rgba[i].B * direction[2]; + const int factor = gl::clamp( + static_cast( + (static_cast(dot - stops[1]) / (stops[0] - stops[1])) * 3 + 0.5f), + 0, 3); + switch (factor) + { + case 0: + bits |= 1; + break; + case 1: + bits |= 3; + break; + case 2: + bits |= 2; + break; + case 3: + default: + bits |= 0; + break; + } + } + } + else + { + for (int i = 15; i >= 0; i--) + { + // In non-opaque mode, 3 is for tranparent pixels. + + bits <<= 2; + if (0 == rgba[i].A) + { + bits |= 3; + } + else + { + const int dot = rgba[i].R * direction[0] + rgba[i].G * direction[1] + + rgba[i].B * direction[2]; + const int factor = gl::clamp( + static_cast( + (static_cast(dot - stops[1]) / (stops[0] - stops[1])) * 2 + + 0.5f), + 0, 2); + switch (factor) + { + case 0: + bits |= 0; + break; + case 1: + bits |= 2; + break; + case 2: + default: + bits |= 1; + break; + } + } + } + } + + return bits; + } + + void packBC1(void *bc1, + const R8G8B8A8 *rgba, + const R8G8B8A8 &minColor, + const R8G8B8A8 &maxColor, + bool opaque) const + { + uint32_t bits; + uint16_t max16 = RGB8ToRGB565(maxColor); + uint16_t min16 = RGB8ToRGB565(minColor); + if (max16 != min16) + { + // Find the best BC1 code for each pixel + bits = matchBC1Bits(rgba, minColor, maxColor, opaque); + } + else + { + // Same colors, BC1 index 0 is the color in both opaque and transparent mode + bits = 0; + // BC1 index 3 is transparent + if (!opaque) + { + for (int i = 0; i < 16; i++) + { + if (0 == rgba[i].A) + { + bits |= (3 << (i * 2)); + } + } + } + } + + if (max16 < min16) + { + std::swap(max16, min16); + + uint32_t xorMask = 0; + if (opaque) + { + // In opaque mode switching the two colors is doing the + // following code swaps: 0 <-> 1 and 2 <-> 3. This is + // equivalent to flipping the first bit of each code + // (5 = 0b0101) + xorMask = 0x55555555; + } + else + { + // In transparent mode switching the colors is doing the + // following code swap: 0 <-> 1. 0xA selects the second bit of + // each code, bits >> 1 selects the first bit of the code when + // the seconds bit is set (case 2 and 3). We invert all the + // non-selected bits, that is the first bit when the code is + // 0 or 1. + xorMask = ~((bits >> 1) | 0xAAAAAAAA); + } + bits ^= xorMask; + } + + struct BC1Block + { + uint16_t color0; + uint16_t color1; + uint32_t bits; + }; + + // Encode the opaqueness in the order of the two BC1 colors + BC1Block *dest = reinterpret_cast(bc1); + if (opaque) + { + dest->color0 = max16; + dest->color1 = min16; + } + else + { + dest->color0 = min16; + dest->color1 = max16; + } + dest->bits = bits; + } + + void transcodeIndividualBlockToBC1(uint8_t *dest, + size_t x, + size_t y, + size_t w, + size_t h, + const uint8_t alphaValues[4][4], + bool nonOpaquePunchThroughAlpha) const + { + const auto &block = u.idht.mode.idm.colors.indiv; + int r1 = extend_4to8bits(block.R1); + int g1 = extend_4to8bits(block.G1); + int b1 = extend_4to8bits(block.B1); + int r2 = extend_4to8bits(block.R2); + int g2 = extend_4to8bits(block.G2); + int b2 = extend_4to8bits(block.B2); + transcodeIndividualOrDifferentialBlockToBC1(dest, x, y, w, h, r1, g1, b1, r2, g2, b2, + alphaValues, nonOpaquePunchThroughAlpha); + } + + void transcodeDifferentialBlockToBC1(uint8_t *dest, + size_t x, + size_t y, + size_t w, + size_t h, + const uint8_t alphaValues[4][4], + bool nonOpaquePunchThroughAlpha) const + { + const auto &block = u.idht.mode.idm.colors.diff; + int b1 = extend_5to8bits(block.B); + int g1 = extend_5to8bits(block.G); + int r1 = extend_5to8bits(block.R); + int r2 = extend_5to8bits(block.R + block.dR); + int g2 = extend_5to8bits(block.G + block.dG); + int b2 = extend_5to8bits(block.B + block.dB); + transcodeIndividualOrDifferentialBlockToBC1(dest, x, y, w, h, r1, g1, b1, r2, g2, b2, + alphaValues, nonOpaquePunchThroughAlpha); + } + + void decodeSubblock(R8G8B8A8 *rgbaBlock, + size_t x, + size_t y, + size_t w, + size_t h, + const uint8_t alphaValues[4][4], + bool flipbit, + size_t subblockIdx, + const R8G8B8A8 subblockColors[2][4]) const + { + size_t dxBegin = 0; + size_t dxEnd = 4; + size_t dyBegin = subblockIdx * 2; + size_t dyEnd = dyBegin + 2; + if (!flipbit) + { + std::swap(dxBegin, dyBegin); + std::swap(dxEnd, dyEnd); + } + + for (size_t j = dyBegin; j < dyEnd && (y + j) < h; j++) + { + R8G8B8A8 *row = &rgbaBlock[j * 4]; + for (size_t i = dxBegin; i < dxEnd && (x + i) < w; i++) + { + const size_t pixelIndex = getIndex(i, j); + row[i] = subblockColors[subblockIdx][pixelIndex]; + row[i].A = alphaValues[j][i]; + } + } + } + + void selectEndPointPCA(const R8G8B8A8 *pixels, R8G8B8A8 *minColor, R8G8B8A8 *maxColor) const + { + static const int kNumPixels = 16; + + // determine color distribution + int mu[3], min[3], max[3]; + for (int ch = 0; ch < 3; ch++) + { + int muv, minv, maxv; + + muv = minv = maxv = (&pixels[0].R)[ch]; + for (size_t i = 1; i < kNumPixels; i++) + { + muv += (&pixels[i].R)[ch]; + minv = std::min(minv, (&pixels[i].R)[ch]); + maxv = std::max(maxv, (&pixels[i].R)[ch]); + } + + mu[ch] = (muv + kNumPixels / 2) / kNumPixels; + min[ch] = minv; + max[ch] = maxv; + } + + // determine covariance matrix + int cov[6] = {0, 0, 0, 0, 0, 0}; + for (size_t i = 0; i < kNumPixels; i++) + { + int r = pixels[i].R - mu[0]; + int g = pixels[i].G - mu[1]; + int b = pixels[i].B - mu[2]; + + cov[0] += r * r; + cov[1] += r * g; + cov[2] += r * b; + cov[3] += g * g; + cov[4] += g * b; + cov[5] += b * b; + } + + // Power iteration algorithm to get the eigenvalues and eigenvector + + // Starts with diagonal vector + float vfr = static_cast(max[0] - min[0]); + float vfg = static_cast(max[1] - min[1]); + float vfb = static_cast(max[2] - min[2]); + float eigenvalue; + + static const size_t kPowerIterations = 4; + for (size_t i = 0; i < kPowerIterations; i++) + { + float r = vfr * cov[0] + vfg * cov[1] + vfb * cov[2]; + float g = vfr * cov[1] + vfg * cov[3] + vfb * cov[4]; + float b = vfr * cov[2] + vfg * cov[4] + vfb * cov[5]; + + vfr = r; + vfg = g; + vfb = b; + + eigenvalue = sqrt(r * r + g * g + b * b); + if (eigenvalue > 0) + { + float invNorm = 1.0f / eigenvalue; + vfr *= invNorm; + vfg *= invNorm; + vfb *= invNorm; + } + } + + int vr, vg, vb; + + static const float kDefaultLuminanceThreshold = 4.0f * 255; + static const float kQuantizeRange = 512.0f; + if (eigenvalue < kDefaultLuminanceThreshold) // too small, default to luminance + { + // Luminance weights defined by ITU-R Recommendation BT.601, scaled by 1000 + vr = 299; + vg = 587; + vb = 114; + } + else + { + // From the eigenvalue and eigenvector, choose the axis to project + // colors on. When projecting colors we want to do integer computations + // for speed, so we normalize the eigenvector to the [0, 512] range. + float magn = std::max(std::max(std::abs(vfr), std::abs(vfg)), std::abs(vfb)); + magn = kQuantizeRange / magn; + vr = static_cast(vfr * magn); + vg = static_cast(vfg * magn); + vb = static_cast(vfb * magn); + } + + // Pick colors at extreme points + int minD = pixels[0].R * vr + pixels[0].G * vg + pixels[0].B * vb; + int maxD = minD; + size_t minIndex = 0; + size_t maxIndex = 0; + for (size_t i = 1; i < kNumPixels; i++) + { + int dot = pixels[i].R * vr + pixels[i].G * vg + pixels[i].B * vb; + if (dot < minD) + { + minD = dot; + minIndex = i; + } + if (dot > maxD) + { + maxD = dot; + maxIndex = i; + } + } + + *minColor = pixels[minIndex]; + *maxColor = pixels[maxIndex]; + } + + void transcodeIndividualOrDifferentialBlockToBC1(uint8_t *dest, + size_t x, + size_t y, + size_t w, + size_t h, + int r1, + int g1, + int b1, + int r2, + int g2, + int b2, + const uint8_t alphaValues[4][4], + bool nonOpaquePunchThroughAlpha) const + { + // A BC1 block has 2 endpoints, pixels is encoded as linear + // interpolations of them. A ETC1/ETC2 individual or differential block + // has 2 subblocks. Each subblock has one color and a modifier. We + // select axis by principal component analysis (PCA) to use as + // our two BC1 endpoints and then map pixels to BC1 by projecting on the + // line between the two endpoints and choosing the right fraction. + // + // In the future, we have a potential improvements to this algorithm. + // 1. We don't actually need to decode ETC blocks to RGBs. Instead, + // the subblock colors and pixel indices alreay contains enough + // information for transcode. A direct mapping would be more + // efficient here. + + const auto intensityModifier = + nonOpaquePunchThroughAlpha ? intensityModifierNonOpaque : intensityModifierDefault; + + // Compute the colors that pixels can have in each subblock both for + // the decoding of the RGBA data and BC1 encoding + R8G8B8A8 subblockColors[2][4]; + for (size_t modifierIdx = 0; modifierIdx < 4; modifierIdx++) + { + const int i1 = intensityModifier[u.idht.mode.idm.cw1][modifierIdx]; + subblockColors[0][modifierIdx] = createRGBA(r1 + i1, g1 + i1, b1 + i1); + + const int i2 = intensityModifier[u.idht.mode.idm.cw2][modifierIdx]; + subblockColors[1][modifierIdx] = createRGBA(r2 + i2, g2 + i2, b2 + i2); + } + + R8G8B8A8 rgbaBlock[16]; + // Decode the block in rgbaBlock. + for (size_t blockIdx = 0; blockIdx < 2; blockIdx++) + { + decodeSubblock(rgbaBlock, x, y, w, h, alphaValues, u.idht.mode.idm.flipbit, blockIdx, + subblockColors); + } + if (nonOpaquePunchThroughAlpha) + { + decodePunchThroughAlphaBlock(reinterpret_cast(rgbaBlock), x, y, w, h, + sizeof(R8G8B8A8) * 4); + } + + R8G8B8A8 minColor, maxColor; + selectEndPointPCA(rgbaBlock, &minColor, &maxColor); + + packBC1(dest, rgbaBlock, minColor, maxColor, !nonOpaquePunchThroughAlpha); + } + + void transcodeTBlockToBC1(uint8_t *dest, + size_t x, + size_t y, + size_t w, + size_t h, + const uint8_t alphaValues[4][4], + bool nonOpaquePunchThroughAlpha) const + { + // TODO (mgong): Will be implemented soon + UNIMPLEMENTED(); + } + + void transcodeHBlockToBC1(uint8_t *dest, + size_t x, + size_t y, + size_t w, + size_t h, + const uint8_t alphaValues[4][4], + bool nonOpaquePunchThroughAlpha) const + { + // TODO (mgong): Will be implemented soon + UNIMPLEMENTED(); + } + + void transcodePlanarBlockToBC1(uint8_t *dest, + size_t x, + size_t y, + size_t w, + size_t h, + const uint8_t alphaValues[4][4]) const + { + // TODO (mgong): Will be implemented soon + UNIMPLEMENTED(); + } + + // Single channel utility functions + int getSingleChannel(size_t x, size_t y, bool isSigned) const + { + int codeword = isSigned ? u.scblk.base_codeword.s : u.scblk.base_codeword.us; + return codeword + getSingleChannelModifier(x, y) * u.scblk.multiplier; + } + + int getSingleChannelIndex(size_t x, size_t y) const + { + ASSERT(x < 4 && y < 4); + + // clang-format off + switch (x * 4 + y) + { + case 0: return u.scblk.ma; + case 1: return u.scblk.mb; + case 2: return u.scblk.mc1 << 1 | u.scblk.mc2; + case 3: return u.scblk.md; + case 4: return u.scblk.me; + case 5: return u.scblk.mf1 << 2 | u.scblk.mf2; + case 6: return u.scblk.mg; + case 7: return u.scblk.mh; + case 8: return u.scblk.mi; + case 9: return u.scblk.mj; + case 10: return u.scblk.mk1 << 1 | u.scblk.mk2; + case 11: return u.scblk.ml; + case 12: return u.scblk.mm; + case 13: return u.scblk.mn1 << 2 | u.scblk.mn2; + case 14: return u.scblk.mo; + case 15: return u.scblk.mp; + default: UNREACHABLE(); return 0; + } + // clang-format on + } + + int getSingleChannelModifier(size_t x, size_t y) const + { + // clang-format off + static const int modifierTable[16][8] = + { + { -3, -6, -9, -15, 2, 5, 8, 14 }, + { -3, -7, -10, -13, 2, 6, 9, 12 }, + { -2, -5, -8, -13, 1, 4, 7, 12 }, + { -2, -4, -6, -13, 1, 3, 5, 12 }, + { -3, -6, -8, -12, 2, 5, 7, 11 }, + { -3, -7, -9, -11, 2, 6, 8, 10 }, + { -4, -7, -8, -11, 3, 6, 7, 10 }, + { -3, -5, -8, -11, 2, 4, 7, 10 }, + { -2, -6, -8, -10, 1, 5, 7, 9 }, + { -2, -5, -8, -10, 1, 4, 7, 9 }, + { -2, -4, -8, -10, 1, 3, 7, 9 }, + { -2, -5, -7, -10, 1, 4, 6, 9 }, + { -3, -4, -7, -10, 2, 3, 6, 9 }, + { -1, -2, -3, -10, 0, 1, 2, 9 }, + { -4, -6, -8, -9, 3, 5, 7, 8 }, + { -3, -5, -7, -9, 2, 4, 6, 8 } + }; + // clang-format on + + return modifierTable[u.scblk.table_index][getSingleChannelIndex(x, y)]; + } +}; + +// clang-format off +static const uint8_t DefaultETCAlphaValues[4][4] = +{ + { 255, 255, 255, 255 }, + { 255, 255, 255, 255 }, + { 255, 255, 255, 255 }, + { 255, 255, 255, 255 }, +}; +// clang-format on + +void LoadR11EACToR8(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, + bool isSigned) +{ + for (size_t z = 0; z < depth; z++) + { + for (size_t y = 0; y < height; y += 4) + { + const ETC2Block *sourceRow = + OffsetDataPointer(input, y / 4, z, inputRowPitch, inputDepthPitch); + uint8_t *destRow = + OffsetDataPointer(output, y, z, outputRowPitch, outputDepthPitch); + + for (size_t x = 0; x < width; x += 4) + { + const ETC2Block *sourceBlock = sourceRow + (x / 4); + uint8_t *destPixels = destRow + x; + + sourceBlock->decodeAsSingleChannel(destPixels, x, y, width, height, 1, + outputRowPitch, isSigned); + } + } + } +} + +void LoadRG11EACToRG8(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, + bool isSigned) +{ + for (size_t z = 0; z < depth; z++) + { + for (size_t y = 0; y < height; y += 4) + { + const ETC2Block *sourceRow = + OffsetDataPointer(input, y / 4, z, inputRowPitch, inputDepthPitch); + uint8_t *destRow = + OffsetDataPointer(output, y, z, outputRowPitch, outputDepthPitch); + + for (size_t x = 0; x < width; x += 4) + { + uint8_t *destPixelsRed = destRow + (x * 2); + const ETC2Block *sourceBlockRed = sourceRow + (x / 2); + sourceBlockRed->decodeAsSingleChannel(destPixelsRed, x, y, width, height, 2, + outputRowPitch, isSigned); + + uint8_t *destPixelsGreen = destPixelsRed + 1; + const ETC2Block *sourceBlockGreen = sourceBlockRed + 1; + sourceBlockGreen->decodeAsSingleChannel(destPixelsGreen, x, y, width, height, 2, + outputRowPitch, isSigned); + } + } + } +} + +void LoadETC2RGB8ToRGBA8(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, + bool punchthroughAlpha) +{ + for (size_t z = 0; z < depth; z++) + { + for (size_t y = 0; y < height; y += 4) + { + const ETC2Block *sourceRow = + OffsetDataPointer(input, y / 4, z, inputRowPitch, inputDepthPitch); + uint8_t *destRow = + OffsetDataPointer(output, y, z, outputRowPitch, outputDepthPitch); + + for (size_t x = 0; x < width; x += 4) + { + const ETC2Block *sourceBlock = sourceRow + (x / 4); + uint8_t *destPixels = destRow + (x * 4); + + sourceBlock->decodeAsRGB(destPixels, x, y, width, height, outputRowPitch, + DefaultETCAlphaValues, punchthroughAlpha); + } + } + } +} + +void LoadETC2RGB8ToBC1(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, + bool punchthroughAlpha) +{ + for (size_t z = 0; z < depth; z++) + { + for (size_t y = 0; y < height; y += 4) + { + const ETC2Block *sourceRow = + OffsetDataPointer(input, y / 4, z, inputRowPitch, inputDepthPitch); + uint8_t *destRow = + OffsetDataPointer(output, y / 4, z, outputRowPitch, outputDepthPitch); + + for (size_t x = 0; x < width; x += 4) + { + const ETC2Block *sourceBlock = sourceRow + (x / 4); + uint8_t *destPixels = destRow + (x * 2); + + sourceBlock->transcodeAsBC1(destPixels, x, y, width, height, DefaultETCAlphaValues, + punchthroughAlpha); + } + } + } +} + +void LoadETC2RGBA8ToRGBA8(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, + bool srgb) +{ + uint8_t decodedAlphaValues[4][4]; + + for (size_t z = 0; z < depth; z++) + { + for (size_t y = 0; y < height; y += 4) + { + const ETC2Block *sourceRow = + OffsetDataPointer(input, y / 4, z, inputRowPitch, inputDepthPitch); + uint8_t *destRow = + OffsetDataPointer(output, y, z, outputRowPitch, outputDepthPitch); + + for (size_t x = 0; x < width; x += 4) + { + const ETC2Block *sourceBlockAlpha = sourceRow + (x / 2); + sourceBlockAlpha->decodeAsSingleChannel( + reinterpret_cast(decodedAlphaValues), x, y, width, height, 1, 4, + false); + + uint8_t *destPixels = destRow + (x * 4); + const ETC2Block *sourceBlockRGB = sourceBlockAlpha + 1; + sourceBlockRGB->decodeAsRGB(destPixels, x, y, width, height, outputRowPitch, + decodedAlphaValues, false); + } + } + } +} + +} // anonymous namespace + +void LoadETC1RGB8ToRGBA8(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) +{ + LoadETC2RGB8ToRGBA8(width, height, depth, input, inputRowPitch, inputDepthPitch, output, + outputRowPitch, outputDepthPitch, false); +} + +void LoadETC1RGB8ToBC1(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) +{ + LoadETC2RGB8ToBC1(width, height, depth, input, inputRowPitch, inputDepthPitch, output, + outputRowPitch, outputDepthPitch, false); +} + +void LoadEACR11ToR8(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) +{ + LoadR11EACToR8(width, height, depth, input, inputRowPitch, inputDepthPitch, output, + outputRowPitch, outputDepthPitch, false); +} + +void LoadEACR11SToR8(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) +{ + LoadR11EACToR8(width, height, depth, input, inputRowPitch, inputDepthPitch, output, + outputRowPitch, outputDepthPitch, true); +} + +void LoadEACRG11ToRG8(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) +{ + LoadRG11EACToRG8(width, height, depth, input, inputRowPitch, inputDepthPitch, output, + outputRowPitch, outputDepthPitch, false); +} + +void LoadEACRG11SToRG8(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) +{ + LoadRG11EACToRG8(width, height, depth, input, inputRowPitch, inputDepthPitch, output, + outputRowPitch, outputDepthPitch, true); +} + +void LoadETC2RGB8ToRGBA8(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) +{ + LoadETC2RGB8ToRGBA8(width, height, depth, input, inputRowPitch, inputDepthPitch, output, + outputRowPitch, outputDepthPitch, false); +} + +void LoadETC2SRGB8ToRGBA8(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) +{ + LoadETC2RGB8ToRGBA8(width, height, depth, input, inputRowPitch, inputDepthPitch, output, + outputRowPitch, outputDepthPitch, false); +} + +void LoadETC2RGB8A1ToRGBA8(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) +{ + LoadETC2RGB8ToRGBA8(width, height, depth, input, inputRowPitch, inputDepthPitch, output, + outputRowPitch, outputDepthPitch, true); +} + +void LoadETC2SRGB8A1ToRGBA8(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) +{ + LoadETC2RGB8ToRGBA8(width, height, depth, input, inputRowPitch, inputDepthPitch, output, + outputRowPitch, outputDepthPitch, true); +} + +void LoadETC2RGBA8ToRGBA8(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) +{ + LoadETC2RGBA8ToRGBA8(width, height, depth, input, inputRowPitch, inputDepthPitch, output, + outputRowPitch, outputDepthPitch, false); +} + +void LoadETC2SRGBA8ToSRGBA8(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) +{ + LoadETC2RGBA8ToRGBA8(width, height, depth, input, inputRowPitch, inputDepthPitch, output, + outputRowPitch, outputDepthPitch, true); +} + +} // namespace rx diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/loadimage_etc.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/loadimage_etc.h new file mode 100644 index 000000000000..dc64e0461b9f --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/loadimage_etc.h @@ -0,0 +1,140 @@ +// +// Copyright (c) 2013-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. +// + +// loadimage_etc.h: Decodes ETC and EAC encoded textures. + +#ifndef LIBANGLE_RENDERER_D3D_LOADIMAGE_ETC_H_ +#define LIBANGLE_RENDERER_D3D_LOADIMAGE_ETC_H_ + +#include "libANGLE/angletypes.h" + +#include + +namespace rx +{ + +void LoadETC1RGB8ToRGBA8(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); + +void LoadETC1RGB8ToBC1(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); + +void LoadEACR11ToR8(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); + +void LoadEACR11SToR8(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); + +void LoadEACRG11ToRG8(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); + +void LoadEACRG11SToRG8(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); + +void LoadETC2RGB8ToRGBA8(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); + +void LoadETC2SRGB8ToRGBA8(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); + +void LoadETC2RGB8A1ToRGBA8(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); + +void LoadETC2SRGB8A1ToRGBA8(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); + +void LoadETC2RGBA8ToRGBA8(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); + +void LoadETC2SRGBA8ToSRGBA8(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); +} + +#endif // LIBANGLE_RENDERER_D3D_LOADIMAGE_ETC_H_ diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/BlitGL.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/BlitGL.cpp new file mode 100644 index 000000000000..0a624dcb17dd --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/BlitGL.cpp @@ -0,0 +1,304 @@ +// +// 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. +// + +// BlitGL.cpp: Implements the BlitGL class, a helper for blitting textures + +#include "libANGLE/renderer/gl/BlitGL.h" + +#include "libANGLE/formatutils.h" +#include "libANGLE/Framebuffer.h" +#include "libANGLE/renderer/gl/formatutilsgl.h" +#include "libANGLE/renderer/gl/FramebufferGL.h" +#include "libANGLE/renderer/gl/FunctionsGL.h" +#include "libANGLE/renderer/gl/TextureGL.h" +#include "libANGLE/renderer/gl/StateManagerGL.h" +#include "libANGLE/renderer/gl/WorkaroundsGL.h" + +namespace +{ + +gl::Error CheckCompileStatus(const rx::FunctionsGL *functions, GLuint shader) +{ + GLint compileStatus = GL_FALSE; + functions->getShaderiv(shader, GL_COMPILE_STATUS, &compileStatus); + ASSERT(compileStatus == GL_TRUE); + if (compileStatus == GL_FALSE) + { + return gl::Error(GL_OUT_OF_MEMORY, "Failed to compile internal blit shader."); + } + + return gl::Error(GL_NO_ERROR); +} + +gl::Error CheckLinkStatus(const rx::FunctionsGL *functions, GLuint program) +{ + GLint linkStatus = GL_FALSE; + functions->getProgramiv(program, GL_LINK_STATUS, &linkStatus); + ASSERT(linkStatus == GL_TRUE); + if (linkStatus == GL_FALSE) + { + return gl::Error(GL_OUT_OF_MEMORY, "Failed to link internal blit program."); + } + + return gl::Error(GL_NO_ERROR); +} + +} // anonymous namespace + +namespace rx +{ + +BlitGL::BlitGL(const FunctionsGL *functions, + const WorkaroundsGL &workarounds, + StateManagerGL *stateManager) + : mFunctions(functions), + mWorkarounds(workarounds), + mStateManager(stateManager), + mBlitProgram(0), + mScratchFBO(0), + mVAO(0) +{ + for (size_t i = 0; i < ArraySize(mScratchTextures); i++) + { + mScratchTextures[i] = 0; + } + + ASSERT(mFunctions); + ASSERT(mStateManager); +} + +BlitGL::~BlitGL() +{ + if (mBlitProgram != 0) + { + mStateManager->deleteProgram(mBlitProgram); + mBlitProgram = 0; + } + + for (size_t i = 0; i < ArraySize(mScratchTextures); i++) + { + if (mScratchTextures[i] != 0) + { + mStateManager->deleteTexture(mScratchTextures[i]); + mScratchTextures[i] = 0; + } + } + + if (mScratchFBO != 0) + { + mStateManager->deleteFramebuffer(mScratchFBO); + mScratchFBO = 0; + } + + if (mVAO != 0) + { + mStateManager->deleteVertexArray(mVAO); + mVAO = 0; + } +} + +gl::Error BlitGL::copyImageToLUMAWorkaroundTexture(GLuint texture, + GLenum textureType, + GLenum target, + GLenum lumaFormat, + size_t level, + const gl::Rectangle &sourceArea, + GLenum internalFormat, + const gl::Framebuffer *source) +{ + mStateManager->bindTexture(textureType, texture); + + // Allocate the texture memory + const gl::InternalFormat &internalFormatInfo = gl::GetInternalFormatInfo(internalFormat); + mFunctions->texImage2D(target, static_cast(level), internalFormat, sourceArea.width, + sourceArea.height, 0, internalFormatInfo.format, + source->getImplementationColorReadType(), nullptr); + + return copySubImageToLUMAWorkaroundTexture(texture, textureType, target, lumaFormat, level, + gl::Offset(0, 0, 0), sourceArea, source); +} + +gl::Error BlitGL::copySubImageToLUMAWorkaroundTexture(GLuint texture, + GLenum textureType, + GLenum target, + GLenum lumaFormat, + size_t level, + const gl::Offset &destOffset, + const gl::Rectangle &sourceArea, + const gl::Framebuffer *source) +{ + gl::Error error = initializeResources(); + if (error.isError()) + { + return error; + } + + // Blit the framebuffer to the first scratch texture + const FramebufferGL *sourceFramebufferGL = GetImplAs(source); + mStateManager->bindFramebuffer(GL_FRAMEBUFFER, sourceFramebufferGL->getFramebufferID()); + + nativegl::CopyTexImageImageFormat copyTexImageFormat = nativegl::GetCopyTexImageImageFormat( + mFunctions, mWorkarounds, source->getImplementationColorReadFormat(), + source->getImplementationColorReadType()); + const gl::InternalFormat &internalFormatInfo = + gl::GetInternalFormatInfo(copyTexImageFormat.internalFormat); + + mStateManager->activeTexture(0); + mStateManager->bindTexture(GL_TEXTURE_2D, mScratchTextures[0]); + mFunctions->copyTexImage2D(GL_TEXTURE_2D, 0, copyTexImageFormat.internalFormat, sourceArea.x, + sourceArea.y, sourceArea.width, sourceArea.height, 0); + + // Set the swizzle of the scratch texture so that the channels sample into the correct emulated + // LUMA channels. + GLint swizzle[4] = { + (lumaFormat == GL_ALPHA) ? GL_ALPHA : GL_RED, + (lumaFormat == GL_LUMINANCE_ALPHA) ? GL_ALPHA : GL_ZERO, GL_ZERO, GL_ZERO, + }; + mFunctions->texParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzle); + + // Make a temporary framebuffer using the second scratch texture to render the swizzled result + // to. + mStateManager->bindTexture(GL_TEXTURE_2D, mScratchTextures[1]); + mFunctions->texImage2D(GL_TEXTURE_2D, 0, copyTexImageFormat.internalFormat, sourceArea.width, + sourceArea.height, 0, internalFormatInfo.format, + source->getImplementationColorReadType(), nullptr); + + mStateManager->bindFramebuffer(GL_FRAMEBUFFER, mScratchFBO); + mFunctions->framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, + mScratchTextures[1], 0); + + // Render to the destination texture, sampling from the scratch texture + mStateManager->useProgram(mBlitProgram); + mStateManager->setViewport(gl::Rectangle(0, 0, sourceArea.width, sourceArea.height)); + mStateManager->setScissorTestEnabled(false); + mStateManager->setDepthRange(0.0f, 1.0f); + mStateManager->setBlendEnabled(false); + mStateManager->setColorMask(true, true, true, true); + mStateManager->setSampleAlphaToCoverageEnabled(false); + mStateManager->setSampleCoverageEnabled(false); + mStateManager->setDepthTestEnabled(false); + mStateManager->setStencilTestEnabled(false); + mStateManager->setCullFaceEnabled(false); + mStateManager->setPolygonOffsetFillEnabled(false); + mStateManager->setRasterizerDiscardEnabled(false); + mStateManager->bindTexture(GL_TEXTURE_2D, mScratchTextures[0]); + + mStateManager->bindVertexArray(mVAO, 0); + + mFunctions->drawArrays(GL_TRIANGLES, 0, 6); + + // Finally, copy the swizzled texture to the destination texture + mStateManager->bindTexture(textureType, texture); + mFunctions->copyTexSubImage2D(target, static_cast(level), destOffset.x, destOffset.y, 0, + 0, sourceArea.width, sourceArea.height); + + return gl::Error(GL_NO_ERROR); +} + +gl::Error BlitGL::initializeResources() +{ + if (mBlitProgram == 0) + { + mBlitProgram = mFunctions->createProgram(); + + // Compile the fragment shader + const char *vsSource = + "#version 150\n" + "out vec2 v_texcoord;\n" + "\n" + "void main()\n" + "{\n" + " const vec2 quad_positions[6] = vec2[6]\n" + " (\n" + " vec2(0.0f, 0.0f),\n" + " vec2(0.0f, 1.0f),\n" + " vec2(1.0f, 0.0f),\n" + "\n" + " vec2(0.0f, 1.0f),\n" + " vec2(1.0f, 0.0f),\n" + " vec2(1.0f, 1.0f)\n" + " );\n" + "\n" + " gl_Position = vec4((quad_positions[gl_VertexID] * 2.0) - 1.0, 0.0, 1.0);\n" + " v_texcoord = quad_positions[gl_VertexID];\n" + "}\n"; + + GLuint vs = mFunctions->createShader(GL_VERTEX_SHADER); + mFunctions->shaderSource(vs, 1, &vsSource, nullptr); + mFunctions->compileShader(vs); + gl::Error error = CheckCompileStatus(mFunctions, vs); + + mFunctions->attachShader(mBlitProgram, vs); + mFunctions->deleteShader(vs); + + if (error.isError()) + { + return error; + } + + // Compile the vertex shader + const char *fsSource = + "#version 150\n" + "uniform sampler2D u_source_texture;\n" + "in vec2 v_texcoord;\n" + "out vec4 output_color;\n" + "\n" + "void main()\n" + "{\n" + " output_color = texture(u_source_texture, v_texcoord);\n" + "}\n"; + + GLuint fs = mFunctions->createShader(GL_FRAGMENT_SHADER); + mFunctions->shaderSource(fs, 1, &fsSource, nullptr); + mFunctions->compileShader(fs); + error = CheckCompileStatus(mFunctions, fs); + + mFunctions->attachShader(mBlitProgram, fs); + mFunctions->deleteShader(fs); + + if (error.isError()) + { + return error; + } + + mFunctions->linkProgram(mBlitProgram); + error = CheckLinkStatus(mFunctions, mBlitProgram); + if (error.isError()) + { + return error; + } + + GLuint textureUniform = mFunctions->getUniformLocation(mBlitProgram, "u_source_texture"); + mStateManager->useProgram(mBlitProgram); + mFunctions->uniform1i(textureUniform, 0); + } + + for (size_t i = 0; i < ArraySize(mScratchTextures); i++) + { + if (mScratchTextures[i] == 0) + { + mFunctions->genTextures(1, &mScratchTextures[i]); + mStateManager->bindTexture(GL_TEXTURE_2D, mScratchTextures[i]); + + // Use nearest, non-mipmapped sampling with the scratch texture + mFunctions->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + mFunctions->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + } + } + + if (mScratchFBO == 0) + { + mFunctions->genFramebuffers(1, &mScratchFBO); + } + + if (mVAO == 0) + { + mFunctions->genVertexArrays(1, &mVAO); + } + + return gl::Error(GL_NO_ERROR); +} +} diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/BlitGL.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/BlitGL.h new file mode 100644 index 000000000000..3ab8319bb138 --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/BlitGL.h @@ -0,0 +1,71 @@ +// +// 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. +// + +// BlitGL.h: Defines the BlitGL class, a helper for blitting textures + +#ifndef LIBANGLE_RENDERER_GL_BLITGL_H_ +#define LIBANGLE_RENDERER_GL_BLITGL_H_ + +#include "angle_gl.h" +#include "common/angleutils.h" +#include "libANGLE/angletypes.h" +#include "libANGLE/Error.h" + +namespace gl +{ +class Framebuffer; +} + +namespace rx +{ + +class FramebufferGL; +class FunctionsGL; +class StateManagerGL; +struct WorkaroundsGL; + +class BlitGL : public angle::NonCopyable +{ + public: + BlitGL(const FunctionsGL *functions, + const WorkaroundsGL &workarounds, + StateManagerGL *stateManager); + ~BlitGL(); + + gl::Error copyImageToLUMAWorkaroundTexture(GLuint texture, + GLenum textureType, + GLenum target, + GLenum lumaFormat, + size_t level, + const gl::Rectangle &sourceArea, + GLenum internalFormat, + const gl::Framebuffer *source); + gl::Error copySubImageToLUMAWorkaroundTexture(GLuint texture, + GLenum textureType, + GLenum target, + GLenum lumaFormat, + size_t level, + const gl::Offset &destOffset, + const gl::Rectangle &sourceArea, + const gl::Framebuffer *source); + + gl::Error initializeResources(); + + private: + const FunctionsGL *mFunctions; + const WorkaroundsGL &mWorkarounds; + StateManagerGL *mStateManager; + + GLuint mBlitProgram; + + GLuint mScratchTextures[2]; + GLuint mScratchFBO; + + GLuint mVAO; +}; +} + +#endif // LIBANGLE_RENDERER_GL_BLITGL_H_ diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/BufferGL.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/BufferGL.cpp index 1ce91de56bf4..cd82733d7745 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/BufferGL.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/BufferGL.cpp @@ -9,9 +9,12 @@ #include "libANGLE/renderer/gl/BufferGL.h" #include "common/debug.h" +#include "common/utilities.h" #include "libANGLE/angletypes.h" +#include "libANGLE/formatutils.h" #include "libANGLE/renderer/gl/FunctionsGL.h" #include "libANGLE/renderer/gl/StateManagerGL.h" +#include "libANGLE/renderer/gl/renderergl_utils.h" namespace rx { @@ -28,6 +31,12 @@ static const GLenum DestBufferOperationTarget = GL_ARRAY_BUFFER; BufferGL::BufferGL(const FunctionsGL *functions, StateManagerGL *stateManager) : BufferImpl(), + mIsMapped(false), + mMapOffset(0), + mMapSize(0), + mShadowBufferData(!CanMapBufferForRead(functions)), + mShadowCopy(), + mBufferSize(0), mFunctions(functions), mStateManager(stateManager), mBufferID(0) @@ -40,17 +49,30 @@ BufferGL::BufferGL(const FunctionsGL *functions, StateManagerGL *stateManager) BufferGL::~BufferGL() { - if (mBufferID) - { - mFunctions->deleteBuffers(1, &mBufferID); - mBufferID = 0; - } + mStateManager->deleteBuffer(mBufferID); + mBufferID = 0; } gl::Error BufferGL::setData(const void* data, size_t size, GLenum usage) { mStateManager->bindBuffer(DestBufferOperationTarget, mBufferID); mFunctions->bufferData(DestBufferOperationTarget, size, data, usage); + + if (mShadowBufferData) + { + if (!mShadowCopy.resize(size)) + { + return gl::Error(GL_OUT_OF_MEMORY, "Failed to resize buffer data shadow copy."); + } + + if (size > 0 && data != nullptr) + { + memcpy(mShadowCopy.data(), data, size); + } + } + + mBufferSize = size; + return gl::Error(GL_NO_ERROR); } @@ -58,6 +80,12 @@ gl::Error BufferGL::setSubData(const void* data, size_t size, size_t offset) { mStateManager->bindBuffer(DestBufferOperationTarget, mBufferID); mFunctions->bufferSubData(DestBufferOperationTarget, offset, size, data); + + if (mShadowBufferData && size > 0) + { + memcpy(mShadowCopy.data() + offset, data, size); + } + return gl::Error(GL_NO_ERROR); } @@ -70,36 +98,100 @@ gl::Error BufferGL::copySubData(BufferImpl* source, GLintptr sourceOffset, GLint mFunctions->copyBufferSubData(SourceBufferOperationTarget, DestBufferOperationTarget, sourceOffset, destOffset, size); + if (mShadowBufferData && size > 0) + { + ASSERT(sourceGL->mShadowBufferData); + memcpy(mShadowCopy.data() + destOffset, sourceGL->mShadowCopy.data() + sourceOffset, size); + } + return gl::Error(GL_NO_ERROR); } gl::Error BufferGL::map(GLenum access, GLvoid **mapPtr) { - mStateManager->bindBuffer(DestBufferOperationTarget, mBufferID); - *mapPtr = mFunctions->mapBuffer(DestBufferOperationTarget, access); + if (mShadowBufferData) + { + *mapPtr = mShadowCopy.data(); + } + else + { + mStateManager->bindBuffer(DestBufferOperationTarget, mBufferID); + *mapPtr = mFunctions->mapBuffer(DestBufferOperationTarget, access); + } + + mIsMapped = true; + mMapOffset = 0; + mMapSize = mBufferSize; + return gl::Error(GL_NO_ERROR); } gl::Error BufferGL::mapRange(size_t offset, size_t length, GLbitfield access, GLvoid **mapPtr) { - mStateManager->bindBuffer(DestBufferOperationTarget, mBufferID); - *mapPtr = mFunctions->mapBufferRange(DestBufferOperationTarget, offset, length, access); + if (mShadowBufferData) + { + *mapPtr = mShadowCopy.data() + offset; + } + else + { + mStateManager->bindBuffer(DestBufferOperationTarget, mBufferID); + *mapPtr = mFunctions->mapBufferRange(DestBufferOperationTarget, offset, length, access); + } + + mIsMapped = true; + mMapOffset = offset; + mMapSize = length; + return gl::Error(GL_NO_ERROR); } gl::Error BufferGL::unmap(GLboolean *result) { - ASSERT(*result); + ASSERT(result); + ASSERT(mIsMapped); - mStateManager->bindBuffer(DestBufferOperationTarget, mBufferID); - *result = mFunctions->unmapBuffer(DestBufferOperationTarget); + if (mShadowBufferData) + { + mStateManager->bindBuffer(DestBufferOperationTarget, mBufferID); + mFunctions->bufferSubData(DestBufferOperationTarget, mMapOffset, mMapSize, + mShadowCopy.data() + mMapOffset); + *result = GL_TRUE; + } + else + { + mStateManager->bindBuffer(DestBufferOperationTarget, mBufferID); + *result = mFunctions->unmapBuffer(DestBufferOperationTarget); + } + + mIsMapped = false; return gl::Error(GL_NO_ERROR); } -gl::Error BufferGL::getData(const uint8_t **outData) +gl::Error BufferGL::getIndexRange(GLenum type, + size_t offset, + size_t count, + bool primitiveRestartEnabled, + gl::IndexRange *outRange) { - UNIMPLEMENTED(); - return gl::Error(GL_INVALID_OPERATION); + ASSERT(!mIsMapped); + + if (mShadowBufferData) + { + *outRange = gl::ComputeIndexRange(type, mShadowCopy.data() + offset, count, + primitiveRestartEnabled); + } + else + { + mStateManager->bindBuffer(DestBufferOperationTarget, mBufferID); + + const gl::Type &typeInfo = gl::GetTypeInfo(type); + const uint8_t *bufferData = MapBufferRangeWithFallback( + mFunctions, DestBufferOperationTarget, offset, count * typeInfo.bytes, GL_MAP_READ_BIT); + *outRange = gl::ComputeIndexRange(type, bufferData, count, primitiveRestartEnabled); + mFunctions->unmapBuffer(DestBufferOperationTarget); + } + + return gl::Error(GL_NO_ERROR); } GLuint BufferGL::getBufferID() const diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/BufferGL.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/BufferGL.h index 2fe7525a75c3..e787ec86e990 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/BufferGL.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/BufferGL.h @@ -9,6 +9,7 @@ #ifndef LIBANGLE_RENDERER_GL_BUFFERGL_H_ #define LIBANGLE_RENDERER_GL_BUFFERGL_H_ +#include "common/MemoryBuffer.h" #include "libANGLE/renderer/BufferImpl.h" namespace rx @@ -30,13 +31,24 @@ class BufferGL : public BufferImpl gl::Error mapRange(size_t offset, size_t length, GLbitfield access, GLvoid **mapPtr) override; gl::Error unmap(GLboolean *result) override; - // This method may not have a corresponding GL-backed function. It is necessary - // for validation, for certain indexed draw calls. - gl::Error getData(const uint8_t **outData) override; + gl::Error getIndexRange(GLenum type, + size_t offset, + size_t count, + bool primitiveRestartEnabled, + gl::IndexRange *outRange) override; GLuint getBufferID() const; private: + bool mIsMapped; + size_t mMapOffset; + size_t mMapSize; + + bool mShadowBufferData; + MemoryBuffer mShadowCopy; + + size_t mBufferSize; + const FunctionsGL *mFunctions; StateManagerGL *mStateManager; diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/CompilerGL.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/CompilerGL.cpp index 74eed618a621..71be1561140a 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/CompilerGL.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/CompilerGL.cpp @@ -3,120 +3,89 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // - -// CompilerGL.cpp: Implements the class methods for CompilerGL. +// CompilerGL: +// Implementation of the GL compiler methods. +// #include "libANGLE/renderer/gl/CompilerGL.h" -#include "common/debug.h" -#include "libANGLE/Caps.h" -#include "libANGLE/Data.h" +#include "libANGLE/renderer/gl/FunctionsGL.h" namespace rx { -// Global count of active shader compiler handles. Needed to know when to call ShInitialize and ShFinalize. -static size_t activeCompilerHandles = 0; - -CompilerGL::CompilerGL(const gl::Data &data) - : CompilerImpl(), - mSpec(data.clientVersion > 2 ? SH_GLES3_SPEC : SH_GLES2_SPEC), - mOutputType(SH_GLSL_OUTPUT), - mResources(), - mFragmentCompiler(nullptr), - mVertexCompiler(nullptr) +namespace { - ASSERT(data.clientVersion == 2 || data.clientVersion == 3); - - const gl::Caps &caps = *data.caps; - const gl::Extensions &extensions = *data.extensions; - - ShInitBuiltInResources(&mResources); - mResources.MaxVertexAttribs = caps.maxVertexAttributes; - mResources.MaxVertexUniformVectors = caps.maxVertexUniformVectors; - mResources.MaxVaryingVectors = caps.maxVaryingVectors; - mResources.MaxVertexTextureImageUnits = caps.maxVertexTextureImageUnits; - mResources.MaxCombinedTextureImageUnits = caps.maxCombinedTextureImageUnits; - mResources.MaxTextureImageUnits = caps.maxTextureImageUnits; - mResources.MaxFragmentUniformVectors = caps.maxFragmentUniformVectors; - mResources.MaxDrawBuffers = caps.maxDrawBuffers; - mResources.OES_standard_derivatives = extensions.standardDerivatives; - mResources.EXT_draw_buffers = extensions.drawBuffers; - mResources.EXT_shader_texture_lod = extensions.shaderTextureLOD; - mResources.OES_EGL_image_external = 0; // TODO: disabled until the extension is actually supported. - mResources.FragmentPrecisionHigh = 1; // TODO: use shader precision caps to determine if high precision is supported? - mResources.EXT_frag_depth = extensions.fragDepth; - - // GLSL ES 3.0 constants - mResources.MaxVertexOutputVectors = caps.maxVertexOutputComponents / 4; - mResources.MaxFragmentInputVectors = caps.maxFragmentInputComponents / 4; - mResources.MinProgramTexelOffset = caps.minProgramTexelOffset; - mResources.MaxProgramTexelOffset = caps.maxProgramTexelOffset; -} -CompilerGL::~CompilerGL() +ShShaderOutput GetShaderOutputType(const FunctionsGL *functions) { - release(); -} - -gl::Error CompilerGL::release() -{ - if (mFragmentCompiler) - { - ShDestruct(mFragmentCompiler); - mFragmentCompiler = NULL; - - ASSERT(activeCompilerHandles > 0); - activeCompilerHandles--; - } + ASSERT(functions); - if (mVertexCompiler) + if (functions->standard == STANDARD_GL_DESKTOP) { - ShDestruct(mVertexCompiler); - mVertexCompiler = NULL; - - ASSERT(activeCompilerHandles > 0); - activeCompilerHandles--; + // GLSL outputs + if (functions->isAtLeastGL(gl::Version(4, 5))) + { + return SH_GLSL_450_CORE_OUTPUT; + } + else if (functions->isAtLeastGL(gl::Version(4, 4))) + { + return SH_GLSL_440_CORE_OUTPUT; + } + else if (functions->isAtLeastGL(gl::Version(4, 3))) + { + return SH_GLSL_430_CORE_OUTPUT; + } + else if (functions->isAtLeastGL(gl::Version(4, 2))) + { + return SH_GLSL_420_CORE_OUTPUT; + } + else if (functions->isAtLeastGL(gl::Version(4, 1))) + { + return SH_GLSL_410_CORE_OUTPUT; + } + else if (functions->isAtLeastGL(gl::Version(4, 0))) + { + return SH_GLSL_400_CORE_OUTPUT; + } + else if (functions->isAtLeastGL(gl::Version(3, 3))) + { + return SH_GLSL_330_CORE_OUTPUT; + } + else if (functions->isAtLeastGL(gl::Version(3, 2))) + { + return SH_GLSL_150_CORE_OUTPUT; + } + else if (functions->isAtLeastGL(gl::Version(3, 1))) + { + return SH_GLSL_140_OUTPUT; + } + else if (functions->isAtLeastGL(gl::Version(3, 0))) + { + return SH_GLSL_130_OUTPUT; + } + else + { + return SH_GLSL_COMPATIBILITY_OUTPUT; + } } - - if (activeCompilerHandles == 0) + else if (functions->standard == STANDARD_GL_ES) { - ShFinalize(); + // ESSL outputs + return SH_ESSL_OUTPUT; } - - return gl::Error(GL_NO_ERROR); -} - -ShHandle CompilerGL::getCompilerHandle(GLenum type) -{ - ShHandle *compiler = NULL; - switch (type) + else { - case GL_VERTEX_SHADER: - compiler = &mVertexCompiler; - break; - - case GL_FRAGMENT_SHADER: - compiler = &mFragmentCompiler; - break; - - default: UNREACHABLE(); - return NULL; + return ShShaderOutput(0); } +} - if ((*compiler) == nullptr) - { - if (activeCompilerHandles == 0) - { - ShInitialize(); - } - - *compiler = ShConstructCompiler(type, mSpec, mOutputType, &mResources); - activeCompilerHandles++; - } +} // anonymous namespace - return *compiler; +CompilerGL::CompilerGL(const FunctionsGL *functions) + : mTranslatorOutputType(GetShaderOutputType(functions)) +{ } -} +} // namespace rx diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/CompilerGL.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/CompilerGL.h index a8ee2f7b461e..eadbf67edb3e 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/CompilerGL.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/CompilerGL.h @@ -11,33 +11,21 @@ #include "libANGLE/renderer/CompilerImpl.h" -#include "GLSLANG/ShaderLang.h" - -namespace gl -{ -struct Data; -} - namespace rx { +class FunctionsGL; class CompilerGL : public CompilerImpl { public: - CompilerGL(const gl::Data &data); - ~CompilerGL() override; - - gl::Error release() override; + CompilerGL(const FunctionsGL *functions); + ~CompilerGL() override {} - ShHandle getCompilerHandle(GLenum type); + gl::Error release() override { return gl::Error(GL_NO_ERROR); } + ShShaderOutput getTranslatorOutputType() const override { return mTranslatorOutputType; } private: - ShShaderSpec mSpec; - ShShaderOutput mOutputType; - ShBuiltInResources mResources; - - ShHandle mFragmentCompiler; - ShHandle mVertexCompiler; + ShShaderOutput mTranslatorOutputType; }; } diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/DisplayGL.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/DisplayGL.cpp index 3a354c62527f..93aa0499f542 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/DisplayGL.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/DisplayGL.cpp @@ -10,6 +10,7 @@ #include "libANGLE/AttributeMap.h" #include "libANGLE/Context.h" +#include "libANGLE/Display.h" #include "libANGLE/Surface.h" #include "libANGLE/renderer/gl/RendererGL.h" #include "libANGLE/renderer/gl/SurfaceGL.h" @@ -30,7 +31,14 @@ DisplayGL::~DisplayGL() egl::Error DisplayGL::initialize(egl::Display *display) { - mRenderer = new RendererGL(getFunctionsGL()); + mRenderer = new RendererGL(getFunctionsGL(), display->getAttributeMap()); + + const gl::Version &maxVersion = mRenderer->getMaxSupportedESVersion(); + if (maxVersion < gl::Version(2, 0)) + { + return egl::Error(EGL_NOT_INITIALIZED, "OpenGL ES 2.0 is not supportable."); + } + return egl::Error(EGL_SUCCESS); } @@ -39,16 +47,26 @@ void DisplayGL::terminate() SafeDelete(mRenderer); } -egl::Error DisplayGL::createContext(const egl::Config *config, const gl::Context *shareContext, const egl::AttributeMap &attribs, gl::Context **outContext) +ImageImpl *DisplayGL::createImage(EGLenum target, + egl::ImageSibling *buffer, + const egl::AttributeMap &attribs) { - ASSERT(mRenderer != nullptr); + UNIMPLEMENTED(); + return nullptr; +} - EGLint clientVersion = attribs.get(EGL_CONTEXT_CLIENT_VERSION, 1); - bool notifyResets = (attribs.get(EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT, EGL_NO_RESET_NOTIFICATION_EXT) == EGL_LOSE_CONTEXT_ON_RESET_EXT); - bool robustAccess = (attribs.get(EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT, EGL_FALSE) == EGL_TRUE); +gl::Context *DisplayGL::createContext(const egl::Config *config, + const gl::Context *shareContext, + const egl::AttributeMap &attribs) +{ + ASSERT(mRenderer != nullptr); + return new gl::Context(config, shareContext, mRenderer, attribs); +} - *outContext = new gl::Context(config, clientVersion, shareContext, mRenderer, notifyResets, robustAccess); - return egl::Error(EGL_SUCCESS); +StreamImpl *DisplayGL::createStream(const egl::AttributeMap &attribs) +{ + UNREACHABLE(); + return nullptr; } egl::Error DisplayGL::makeCurrent(egl::Surface *drawSurface, egl::Surface *readSurface, gl::Context *context) @@ -62,4 +80,10 @@ egl::Error DisplayGL::makeCurrent(egl::Surface *drawSurface, egl::Surface *readS return glDrawSurface->makeCurrent(); } +const gl::Version &DisplayGL::getMaxSupportedESVersion() const +{ + ASSERT(mRenderer != nullptr); + return mRenderer->getMaxSupportedESVersion(); +} + } diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/DisplayGL.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/DisplayGL.h index a8ea8f90ccf3..dd7bb3cf551a 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/DisplayGL.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/DisplayGL.h @@ -26,11 +26,24 @@ class DisplayGL : public DisplayImpl egl::Error initialize(egl::Display *display) override; void terminate() override; - egl::Error createContext(const egl::Config *config, const gl::Context *shareContext, const egl::AttributeMap &attribs, - gl::Context **outContext) override; + ImageImpl *createImage(EGLenum target, + egl::ImageSibling *buffer, + const egl::AttributeMap &attribs) override; + + gl::Context *createContext(const egl::Config *config, + const gl::Context *shareContext, + const egl::AttributeMap &attribs) override; + + StreamImpl *createStream(const egl::AttributeMap &attribs) override; egl::Error makeCurrent(egl::Surface *drawSurface, egl::Surface *readSurface, gl::Context *context) override; + virtual egl::Error getDriverVersion(std::string *version) const = 0; + + protected: + RendererGL *getRenderer() const { return mRenderer; }; + const gl::Version &getMaxSupportedESVersion() const; + private: virtual const FunctionsGL *getFunctionsGL() const = 0; diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/FeatureSupportGL.md b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/FeatureSupportGL.md new file mode 100644 index 000000000000..edc2353ab831 --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/FeatureSupportGL.md @@ -0,0 +1,107 @@ +# ANGLE RendererGL feature support +Documentation of OpenGL ES and EGL features, caps and formats and required extensions. + +## OpenGL ES Feature Support +|Feature|OpenGL version|OpenGL extension|OpenGL ES version|OpenGL ES extension|Notes| +|---|---|---|---|---|---| +|Framebuffer/renderbuffer objects|3.0|[GL_EXT_framebuffer_object](https://www.opengl.org/registry/specs/EXT/framebuffer_object.txt)|2.0|--|Can potentially be emulated with Pbuffers but realistically this extension is always required.| +|Blit framebuffer|3.0|[GL_EXT_framebuffer_blit](https://www.opengl.org/registry/specs/EXT/framebuffer_blit.txt)|3.0|[GL_ANGLE_framebuffer_blit](https://www.khronos.org/registry/gles/extensions/ANGLE/ANGLE_framebuffer_blit.txt) or [GL_NV_framebuffer_blit](https://www.khronos.org/registry/gles/extensions/NV/NV_framebuffer_blit.txt)|| +|Multisampling|3.0|[GL_EXT_framebuffer_multisample](https://www.opengl.org/registry/specs/EXT/framebuffer_multisample.txt)|3.0|[GL_EXT_multisampled_render_to_texture](https://www.khronos.org/registry/gles/extensions/EXT/EXT_multisampled_render_to_texture.txt) or [GL_ANGLE_framebuffer_multisample](https://www.khronos.org/registry/gles/extensions/ANGLE/ANGLE_framebuffer_multisample.txt)|| +|Depth textures|3.0|[GL_ARB_depth_texture](https://www.opengl.org/registry/specs/ARB/depth_texture.txt)|3.0|[GL_OES_depth_texture](https://www.khronos.org/registry/gles/extensions/OES/OES_depth_texture.txt) or [GL_ANGLE_depth_texture](https://www.khronos.org/registry/gles/extensions/ANGLE/ANGLE_depth_texture.txt) +|Draw buffers (MRT)|2.0?|[GL_ARB_draw_buffers](https://www.opengl.org/registry/specs/ARB/draw_buffers.txt) or [GL_EXT_draw_buffers2](https://www.opengl.org/registry/specs/EXT/draw_buffers2.txt)|3.0|[GL_EXT_draw_buffers](https://www.khronos.org/registry/gles/extensions/EXT/EXT_draw_buffers.txt)|| +|3D textures|1.2|[GL_EXT_texture3D](https://www.opengl.org/registry/specs/EXT/texture3D.txt)|3.0|[GL_OES_texture_3D](https://www.khronos.org/registry/gles/extensions/OES/OES_texture_3D.txt)|| +|Array textures|3.0|[GL_EXT_texture_array](https://www.opengl.org/registry/specs/EXT/texture_array.txt)|3.0|--|| +|Texture storage|4.2|[GL_EXT_texture_storage](https://www.khronos.org/registry/gles/extensions/EXT/EXT_texture_storage.txt)|3.0|[GL_EXT_texture_storage](https://www.khronos.org/registry/gles/extensions/EXT/EXT_texture_storage.txt)|Can be emulated with TexImage calls.| +|Uniform buffer object|3.1|[GL_ARB_uniform_buffer_object](https://www.opengl.org/registry/specs/ARB/uniform_buffer_object.txt)|3.0|--|| +|Sync objects|3.2|[GL_ARB_sync](https://www.opengl.org/registry/specs/ARB/sync.txt)|3.0|--|| +|Fence objects|--|[GL_NV_fence](https://www.opengl.org/registry/specs/NV/fence.txt)|--|[GL_NV_fence](https://www.opengl.org/registry/specs/NV/fence.txt)|| +|MapBuffer|1.5|--|--|[GL_OES_mapbuffer](https://www.khronos.org/registry/gles/extensions/OES/OES_mapbuffer.txt)|| +|MapBufferRange|3.0|[GL_ARB_map_buffer_range](https://www.opengl.org/registry/specs/ARB/map_buffer_range.txt)|3.0|[GL_EXT_map_buffer_range](https://www.khronos.org/registry/gles/extensions/EXT/EXT_map_buffer_range.txt)|| +|Transform feedback|3.0|[GL_EXT_transform_feedback](GL_EXT_transform_feedback) or [GL_EXT_transform_feedback2](http://developer.download.nvidia.com/opengl/specs/GL_EXT_transform_feedback2.txt) or [GL_ARB_transform_feedback3](https://www.opengl.org/registry/specs/ARB/transform_feedback3.txt)|3.0|--|| +|Sampler object|3.3|[GL_ARB_sampler_objects](https://www.opengl.org/registry/specs/ARB/sampler_objects.txt)|3.0|--|| +|Occlusion query|1.5|[GL_ARB_occlusion_query](https://www.opengl.org/registry/specs/ARB/occlusion_query.txt)|2.0|--|| +|Timer query|3.3|[GL_ARB_timer_query](https://www.opengl.org/registry/specs/ARB/timer_query.txt)|--|[GL_EXT_disjoint_timer_query](https://www.khronos.org/registry/gles/extensions/EXT/EXT_disjoint_timer_query.txt)|| +|Vertex array object|3.0|[GL_ARB_vertex_array_object](https://www.opengl.org/registry/specs/ARB/vertex_array_object.txt)|3.0|[GL_OES_vertex_array_object](https://www.khronos.org/registry/gles/extensions/OES/OES_vertex_array_object.txt)|Can be emulated but costsmany extra API calls. Virtualized contexts also require some kind of emulation of the default attribute state.| +|Anisotropic filtering|--|[GL_EXT_texture_filter_anisotropic](https://www.opengl.org/registry/specs/EXT/texture_filter_anisotropic.txt)|--|[GL_EXT_texture_filter_anisotropic](https://www.opengl.org/registry/specs/EXT/texture_filter_anisotropic.txt)|Ubiquitous extension.| + +## OpenGL ES Caps +|Cap(s)|OpenGL version|OpenGL extension|OpenGL ES version|OpenGL ES extension|Notes| +|---|---|---|---|---|---| +|GL_MAX_ELEMENT_INDEX|4.3|[GL_ARB_ES3_compatibility](https://www.opengl.org/registry/specs/ARB/ES3_compatibility.txt)|3.0|--|Seems pretty safe to use an arbitrary limit, all implementations tested return 0xFFFFFFFF.| +|GL_MAX_3D_TEXTURE_SIZE|1.2|[GL_EXT_texture3D](https://www.opengl.org/registry/specs/EXT/texture3D.txt)|3.0|[GL_OES_texture_3D](https://www.khronos.org/registry/gles/extensions/OES/OES_texture_3D.txt)|| +|GL_MAX_TEXTURE_SIZE|1.0|--|2.0|--|| +|GL_MAX_CUBE_MAP_TEXTURE_SIZE|1.3|--|2.0|| +|GL_MAX_ARRAY_TEXTURE_LAYERS|3.0|[GL_EXT_texture_array](https://www.opengl.org/registry/specs/EXT/texture_array.txt)|3.0|--|| +|GL_MAX_TEXTURE_LOD_BIAS|1.5|[GL_EXT_texture_lod_bias](https://www.opengl.org/registry/specs/EXT/texture_lod_bias.txt)|3.0|--|| +|GL_MAX_RENDERBUFFER_SIZE GL_MAX_COLOR_ATTACHMENTS|3.0|[GL_EXT_framebuffer_object](https://www.opengl.org/registry/specs/EXT/framebuffer_object.txt) |2.0|--|| +|GL_MAX_DRAW_BUFFERS|2.0?|[GL_ARB_draw_buffers](https://www.opengl.org/registry/specs/ARB/draw_buffers.txt) or [GL_EXT_draw_buffers2](https://www.opengl.org/registry/specs/EXT/draw_buffers2.txt)|3.0|[GL_EXT_draw_buffers](https://www.khronos.org/registry/gles/extensions/EXT/EXT_draw_buffers.txt)|| +|GL_MAX_VIEWPORT_DIMS|1.0|--|2.0|--|| +|GL_ALIASED_POINT_SIZE_RANGE|1.0?|--|2.0|--|| +|GL_ALIASED_LINE_WIDTH_RANGE|1.2|--|2.0|--|| +|GL_ALIASED_LINE_WIDTH_RANGE|1.2|--|2.0|--|| +|GL_MAX_ELEMENTS_INDICES|1.2|--|3.0|--|| +|GL_MAX_ELEMENTS_VERTICES|1.2|--|3.0|--|| +|Shader format precision (glGetShaderPrecisionFormat)|4.1|[GL_ARB_ES2_compatibility](https://www.opengl.org/registry/specs/ARB/ES2_compatibility.txt)|2.0|--|Can use reasonable default values (IEEE float and twos complement integer).| +|GL_MAX_VERTEX_ATTRIBS|2.0|--|2.0|--|| +|GL_MAX_VERTEX_UNIFORM_COMPONENTS|2.0|--|2.0|--|| +|GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS|2.0|--|2.0|--|| +|GL_MAX_VERTEX_UNIFORM_VECTORS GL_MAX_FRAGMENT_UNIFORM_VECTORS|4.1|[GL_ARB_ES2_compatibility](https://www.opengl.org/registry/specs/ARB/ES2_compatibility.txt)|2.0|--|Defined as GL_MAX_VERTEX_UNIFORM_COMPONENTS / 4 and GL_MAX_FRAGMENT_UNIFORM_COMPONENTS / 4. Can simply use those values when the cap is not available.| +|GL_MAX_VERTEX_UNIFORM_BLOCKS GL_MAX_FRAGMENT_UNIFORM_BLOCKS GL_MAX_UNIFORM_BUFFER_BINDINGS GL_MAX_UNIFORM_BLOCK_SIZE GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT GL_MAX_COMBINED_UNIFORM_BLOCKS GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS |3.1|[GL_ARB_uniform_buffer_object](https://www.opengl.org/registry/specs/ARB/uniform_buffer_object.txt)|3.0|--|| +|GL_MAX_VERTEX_OUTPUT_COMPONENTS|3.2|--|3.0|--|Doesn't seem to be a desktop extension for this cap, it may be possible to use the minimum ES3 value (64) if lower than GL 3.2.| +|GL_MAX_FRAGMENT_UNIFORM_COMPONENTS|2.0|--|2.0|--|| +|GL_MAX_TEXTURE_IMAGE_UNITS|2.0|--|2.0|--|| +|GL_MAX_FRAGMENT_INPUT_COMPONENTS|3.2|--|3.0|--|Doesn't seem to be a desktop extension for this cap either, it may be possible to use the minimum ES3 value (60) if lower than GL 3.2.| +|GL_MIN_PROGRAM_TEXEL_OFFSET GL_MAX_PROGRAM_TEXEL_OFFSET|3.0|--|3.0|--|Could potentially be emulated in the shader by adding the offsets in normalized texture coordinates before sampling.| +|GL_MAX_VARYING_COMPONENTS|3.0|[GL_ARB_ES3_compatibility](https://www.opengl.org/registry/specs/ARB/ES3_compatibility.txt)|3.0|--|Was depricated in the OpenGL core spec but re-added in GL_ARB_ES3_compatibility| +|GL_MAX_VARYING_VECTORS|4.1|[GL_ARB_ES2_compatibility](https://www.opengl.org/registry/specs/ARB/ES2_compatibility.txt)|2.0|--|Defined as GL_MAX_VARYING_COMPONENTS / 4.| +|GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS|3.0|[GL_EXT_transform_feedback](GL_EXT_transform_feedback) or [GL_EXT_transform_feedback2](http://developer.download.nvidia.com/opengl/specs/GL_EXT_transform_feedback2.txt) or [GL_ARB_transform_feedback3](https://www.opengl.org/registry/specs/ARB/transform_feedback3.txt)|3.0|-- +|GL_MAX_SAMPLES|3.0|[GL_EXT_framebuffer_multisample](https://www.opengl.org/registry/specs/EXT/framebuffer_multisample.txt)|3.0|[GL_EXT_multisampled_render_to_texture](https://www.khronos.org/registry/gles/extensions/EXT/EXT_multisampled_render_to_texture.txt) or [GL_ANGLE_framebuffer_multisample](https://www.khronos.org/registry/gles/extensions/ANGLE/ANGLE_framebuffer_multisample.txt)|| +|GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT|--|[GL_EXT_texture_filter_anisotropic](https://www.opengl.org/registry/specs/EXT/texture_filter_anisotropic.txt)|--|[GL_EXT_texture_filter_anisotropic](https://www.opengl.org/registry/specs/EXT/texture_filter_anisotropic.txt)|Ubiquitous extension.| +|IMPLEMENTATION_COLOR_READ_FORMAT IMPLEMENTATION_COLOR_READ_TYPE|--|[GL_ARB_ES2_compatibility](https://www.opengl.org/registry/specs/ARB/ES2_compatibility.txt)|2.0|--|Desktop GL doesn't as many limitations as ES for ReadPixels, can either always return GL_RGBA/GL_UNSIGNED_BYTE or return the format and type of the read buffer.| + +##OpenGL ES Formats (TODO) +|Format|OpenGL version|OpenGL extension|OpenGL ES version|OpenGL ES extension|Notes| +|---|---|---|---|---|---| +|GL_RGBA8
GL_RGB8 |1.0|--|3.0|[GL_OES_rgb8_rgba8](https://www.khronos.org/registry/gles/extensions/OES/OES_rgb8_rgba8.txt)|| + +## ESSL Features (TODO) +|Feature|GLSL version|Notes| +|---|---|---| +|Unsigned integers|1.30|| +|Pack layout std140|1.40|| + +## ESSL3 Builtins +Builtins that are added going from ESSL1 to ESSL3. + +|Function|GLSL version|Extension|Notes| +|---|---|---|---| +|sinh
cosh
tanh
asinh
acosh|1.30||| +|atanh|1.10||| +|abs (genIType)|1.30|[GL_EXT_gpu_shader4](https://www.opengl.org/registry/specs/EXT/gpu_shader4.txt)|| +|sign (genIType)|1.50|[GL_EXT_gpu_shader4](https://www.opengl.org/registry/specs/EXT/gpu_shader4.txt)|Can be emulated easily.| +|trunc|1.30||| +|round
roundEven|1.30||| +|min (genIType, genUType)
max (genIType, genUType)
clamp (genIType, genUType)|1.30|| +|mix (genBType)|4.50|[GL_EXT_shader_integer_mix](https://www.opengl.org/registry/specs/EXT/shader_integer_mix.txt)|Should be possible to emulate with a ternery operation.| +|modf|1.30||| +|isnan|1.30||| +|isinf|1.10||| +|floatBitsToInt
floatBitsToUint
intBitsToFloat
uintBitsToFloat|3.30|[GL_ARB_shader_bit_encoding](https://www.opengl.org/registry/specs/ARB/shader_bit_encoding.txt) or [ARB_gpu_shader5](https://www.opengl.org/registry/specs/ARB/gpu_shader5.txt)|| +|packSnorm2x16
packHalf2x16
unpackSnorm2x16
unpackHalf2x16|4.20|[GL_ARB_shading_language_packing](https://www.opengl.org/registry/specs/ARB/shading_language_packing.txt)|Can be emulated using bit casting functions.| +|packUnorm2x16
unpackUnorm2x16|4.10|[GL_ARB_shading_language_packing](https://www.opengl.org/registry/specs/ARB/shading_language_packing.txt)|Can be emulated using bit casting functions.| +|matrixCompMult (NxM matrices)|1.10||| +|outerProduct|1.20||| +|transpose|1.20||| +|determinant|1.50||Can be emulated.| +|inverse|1.40||Can be emulated.| +|lessThan (uvec)
lessThanEqual (uvec)
greaterThan (uvec)
greaterThanEqual (uvec)
equal (uvec)
notEqual (uvec)|1.30||| +|texture
textureProj
textureLod
textureOffset
textureProjOffset
textureLodOffset
textureProjLod
textureProjLodOffset
texelFetch
texelFetchOffset
textureGrad
textureGradOffset
textureProjGrad
textureProjGradOffset
textureSize|1.30||Equivalent to texture2D, textureCube, etc| +|dFdx
dFdy
fwidth|1.10|| + +## EGL Feature Support (TODO) +|Feature|EGL version|EGL extension|WGL core|WGL extension|GLX version|GLX extensions|Notes| +|---|---|---|---|---|---|---|---| +|Pbuffers|||No|[WGL_ARB_pbuffer](https://www.opengl.org/registry/specs/ARB/wgl_pbuffer.txt)|||| +|BindTexImage|||No|[WGL_ARB_render_texture](https://www.opengl.org/registry/specs/ARB/wgl_render_texture.txt)|||Possibly to emulate with OpenGL textures but not strictly required, it is possible only export EGL configs without EGL_BIND_TO_TEXTURE_RGB and EGL_BIND_TO_TEXTURE_RGBA. Bindable pbuffers may be required by Chrome though.| +|Pixmaps|||||||| +|Swap control|||No|[WGL_EXT_swap_control](https://www.opengl.org/registry/specs/EXT/wgl_swap_control.txt)|No|[GLX_EXT_swap_control](https://www.opengl.org/registry/specs/EXT/swap_control.txt)|| diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/FramebufferGL.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/FramebufferGL.cpp index 53c1ab8c1e63..6c9f046a1ee5 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/FramebufferGL.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/FramebufferGL.cpp @@ -8,6 +8,7 @@ #include "libANGLE/renderer/gl/FramebufferGL.h" +#include "common/BitSetIterator.h" #include "common/debug.h" #include "libANGLE/Data.h" #include "libANGLE/State.h" @@ -18,39 +19,61 @@ #include "libANGLE/renderer/gl/RenderbufferGL.h" #include "libANGLE/renderer/gl/StateManagerGL.h" #include "libANGLE/renderer/gl/TextureGL.h" +#include "libANGLE/renderer/gl/WorkaroundsGL.h" +#include "platform/Platform.h" + +using namespace gl; namespace rx { -FramebufferGL::FramebufferGL(const gl::Framebuffer::Data &data, const FunctionsGL *functions, StateManagerGL *stateManager, bool isDefault) +FramebufferGL::FramebufferGL(const Framebuffer::Data &data, + const FunctionsGL *functions, + StateManagerGL *stateManager, + const WorkaroundsGL &workarounds, + bool isDefault) : FramebufferImpl(data), mFunctions(functions), mStateManager(stateManager), - mFramebufferID(0) + mWorkarounds(workarounds), + mFramebufferID(0), + mIsDefault(isDefault) { - if (!isDefault) + if (!mIsDefault) { mFunctions->genFramebuffers(1, &mFramebufferID); } } +FramebufferGL::FramebufferGL(GLuint id, + const Framebuffer::Data &data, + const FunctionsGL *functions, + const WorkaroundsGL &workarounds, + StateManagerGL *stateManager) + : FramebufferImpl(data), + mFunctions(functions), + mStateManager(stateManager), + mWorkarounds(workarounds), + mFramebufferID(id), + mIsDefault(true) +{ +} + FramebufferGL::~FramebufferGL() { - if (mFramebufferID != 0) - { - mFunctions->deleteFramebuffers(1, &mFramebufferID); - mFramebufferID = 0; - } + mStateManager->deleteFramebuffer(mFramebufferID); + mFramebufferID = 0; } -static void BindFramebufferAttachment(const FunctionsGL *functions, GLenum attachmentPoint, - const gl::FramebufferAttachment *attachment) +static void BindFramebufferAttachment(const FunctionsGL *functions, + GLenum attachmentPoint, + const FramebufferAttachment *attachment) { if (attachment) { if (attachment->type() == GL_TEXTURE) { - const gl::Texture *texture = attachment->getTexture(); + const Texture *texture = attachment->getTexture(); const TextureGL *textureGL = GetImplAs(texture); if (texture->getTarget() == GL_TEXTURE_2D) @@ -75,7 +98,7 @@ static void BindFramebufferAttachment(const FunctionsGL *functions, GLenum attac } else if (attachment->type() == GL_RENDERBUFFER) { - const gl::Renderbuffer *renderbuffer = attachment->getRenderbuffer(); + const Renderbuffer *renderbuffer = attachment->getRenderbuffer(); const RenderbufferGL *renderbufferGL = GetImplAs(renderbuffer); functions->framebufferRenderbuffer(GL_FRAMEBUFFER, attachmentPoint, GL_RENDERBUFFER, @@ -93,201 +116,204 @@ static void BindFramebufferAttachment(const FunctionsGL *functions, GLenum attac } } -void FramebufferGL::onUpdateColorAttachment(size_t index) -{ - if (mFramebufferID != 0) - { - mStateManager->bindFramebuffer(GL_FRAMEBUFFER, mFramebufferID); - BindFramebufferAttachment(mFunctions, - GL_COLOR_ATTACHMENT0 + index, - mData.getColorAttachment(static_cast(index))); - } -} - -void FramebufferGL::onUpdateDepthAttachment() -{ - if (mFramebufferID != 0) - { - mStateManager->bindFramebuffer(GL_FRAMEBUFFER, mFramebufferID); - BindFramebufferAttachment(mFunctions, - GL_DEPTH_ATTACHMENT, - mData.getDepthAttachment()); - } -} - -void FramebufferGL::onUpdateStencilAttachment() -{ - if (mFramebufferID != 0) - { - mStateManager->bindFramebuffer(GL_FRAMEBUFFER, mFramebufferID); - BindFramebufferAttachment(mFunctions, - GL_STENCIL_ATTACHMENT, - mData.getStencilAttachment()); - } -} - -void FramebufferGL::onUpdateDepthStencilAttachment() +Error FramebufferGL::discard(size_t count, const GLenum *attachments) { - if (mFramebufferID != 0) - { - mStateManager->bindFramebuffer(GL_FRAMEBUFFER, mFramebufferID); - BindFramebufferAttachment(mFunctions, - GL_DEPTH_STENCIL_ATTACHMENT, - mData.getDepthStencilAttachment()); - } + UNIMPLEMENTED(); + return Error(GL_INVALID_OPERATION); } -void FramebufferGL::setDrawBuffers(size_t count, const GLenum *buffers) -{ - if (mFramebufferID != 0) - { - mStateManager->bindFramebuffer(GL_FRAMEBUFFER, mFramebufferID); - mFunctions->drawBuffers(count, buffers); - } -} - -void FramebufferGL::setReadBuffer(GLenum buffer) -{ - if (mFramebufferID != 0) - { - mStateManager->bindFramebuffer(GL_FRAMEBUFFER, mFramebufferID); - mFunctions->readBuffer(buffer); - } -} - -gl::Error FramebufferGL::invalidate(size_t count, const GLenum *attachments) +Error FramebufferGL::invalidate(size_t count, const GLenum *attachments) { // Since this function is just a hint and not available until OpenGL 4.3, only call it if it is available. if (mFunctions->invalidateFramebuffer) { mStateManager->bindFramebuffer(GL_FRAMEBUFFER, mFramebufferID); - mFunctions->invalidateFramebuffer(GL_FRAMEBUFFER, count, attachments); + mFunctions->invalidateFramebuffer(GL_FRAMEBUFFER, static_cast(count), attachments); } - return gl::Error(GL_NO_ERROR); + return Error(GL_NO_ERROR); } -gl::Error FramebufferGL::invalidateSub(size_t count, const GLenum *attachments, const gl::Rectangle &area) +Error FramebufferGL::invalidateSub(size_t count, + const GLenum *attachments, + const gl::Rectangle &area) { // Since this function is just a hint and not available until OpenGL 4.3, only call it if it is available. if (mFunctions->invalidateSubFramebuffer) { mStateManager->bindFramebuffer(GL_FRAMEBUFFER, mFramebufferID); - mFunctions->invalidateSubFramebuffer(GL_FRAMEBUFFER, count, attachments, area.x, area.y, area.width, area.height); + mFunctions->invalidateSubFramebuffer(GL_FRAMEBUFFER, static_cast(count), + attachments, area.x, area.y, area.width, area.height); } - return gl::Error(GL_NO_ERROR); + return Error(GL_NO_ERROR); } -gl::Error FramebufferGL::clear(const gl::Data &data, GLbitfield mask) +Error FramebufferGL::clear(const Data &data, GLbitfield mask) { - mStateManager->setClearState(*data.state, mask); + syncClearState(mask); mStateManager->bindFramebuffer(GL_FRAMEBUFFER, mFramebufferID); mFunctions->clear(mask); - return gl::Error(GL_NO_ERROR); -} - -static GLbitfield GetClearBufferMask(GLenum buffer) -{ - switch (buffer) - { - case GL_COLOR: return GL_COLOR_BUFFER_BIT; - case GL_DEPTH: return GL_DEPTH_BUFFER_BIT; - case GL_STENCIL: return GL_STENCIL_BUFFER_BIT; - case GL_DEPTH_STENCIL: return GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT; - default: UNREACHABLE(); return 0; - } + return Error(GL_NO_ERROR); } -gl::Error FramebufferGL::clearBufferfv(const gl::State &state, GLenum buffer, GLint drawbuffer, const GLfloat *values) +Error FramebufferGL::clearBufferfv(const Data &data, + GLenum buffer, + GLint drawbuffer, + const GLfloat *values) { - mStateManager->setClearState(state, GetClearBufferMask(buffer)); + syncClearBufferState(buffer, drawbuffer); mStateManager->bindFramebuffer(GL_FRAMEBUFFER, mFramebufferID); mFunctions->clearBufferfv(buffer, drawbuffer, values); - return gl::Error(GL_NO_ERROR); + return Error(GL_NO_ERROR); } -gl::Error FramebufferGL::clearBufferuiv(const gl::State &state, GLenum buffer, GLint drawbuffer, const GLuint *values) +Error FramebufferGL::clearBufferuiv(const Data &data, + GLenum buffer, + GLint drawbuffer, + const GLuint *values) { - mStateManager->setClearState(state, GetClearBufferMask(buffer)); + syncClearBufferState(buffer, drawbuffer); mStateManager->bindFramebuffer(GL_FRAMEBUFFER, mFramebufferID); mFunctions->clearBufferuiv(buffer, drawbuffer, values); - return gl::Error(GL_NO_ERROR); + return Error(GL_NO_ERROR); } -gl::Error FramebufferGL::clearBufferiv(const gl::State &state, GLenum buffer, GLint drawbuffer, const GLint *values) +Error FramebufferGL::clearBufferiv(const Data &data, + GLenum buffer, + GLint drawbuffer, + const GLint *values) { - mStateManager->setClearState(state, GetClearBufferMask(buffer)); + syncClearBufferState(buffer, drawbuffer); mStateManager->bindFramebuffer(GL_FRAMEBUFFER, mFramebufferID); mFunctions->clearBufferiv(buffer, drawbuffer, values); - return gl::Error(GL_NO_ERROR); + return Error(GL_NO_ERROR); } -gl::Error FramebufferGL::clearBufferfi(const gl::State &state, GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil) +Error FramebufferGL::clearBufferfi(const Data &data, + GLenum buffer, + GLint drawbuffer, + GLfloat depth, + GLint stencil) { - mStateManager->setClearState(state, GetClearBufferMask(buffer)); + syncClearBufferState(buffer, drawbuffer); mStateManager->bindFramebuffer(GL_FRAMEBUFFER, mFramebufferID); mFunctions->clearBufferfi(buffer, drawbuffer, depth, stencil); - return gl::Error(GL_NO_ERROR); + return Error(GL_NO_ERROR); } GLenum FramebufferGL::getImplementationColorReadFormat() const { - const gl::FramebufferAttachment *readAttachment = getData().getReadAttachment(); + const FramebufferAttachment *readAttachment = getData().getReadAttachment(); GLenum internalFormat = readAttachment->getInternalFormat(); - const gl::InternalFormat &internalFormatInfo = gl::GetInternalFormatInfo(internalFormat); + const InternalFormat &internalFormatInfo = GetInternalFormatInfo(internalFormat); return internalFormatInfo.format; } GLenum FramebufferGL::getImplementationColorReadType() const { - const gl::FramebufferAttachment *readAttachment = getData().getReadAttachment(); + const FramebufferAttachment *readAttachment = getData().getReadAttachment(); GLenum internalFormat = readAttachment->getInternalFormat(); - const gl::InternalFormat &internalFormatInfo = gl::GetInternalFormatInfo(internalFormat); + const InternalFormat &internalFormatInfo = GetInternalFormatInfo(internalFormat); return internalFormatInfo.type; } -gl::Error FramebufferGL::readPixels(const gl::State &state, const gl::Rectangle &area, GLenum format, GLenum type, GLvoid *pixels) const +Error FramebufferGL::readPixels(const State &state, + const gl::Rectangle &area, + GLenum format, + GLenum type, + GLvoid *pixels) const { - const gl::PixelPackState &packState = state.getPackState(); - - // TODO: set pack state - if (packState.rowLength != 0 || packState.skipRows != 0 || packState.skipPixels != 0) - { - UNIMPLEMENTED(); - return gl::Error(GL_INVALID_OPERATION, "invalid pixel store parameters in readPixels"); - } + // TODO: don't sync the pixel pack state here once the dirty bits contain the pixel pack buffer + // binding + const PixelPackState &packState = state.getPackState(); + mStateManager->setPixelPackState(packState); mStateManager->bindFramebuffer(GL_READ_FRAMEBUFFER, mFramebufferID); mFunctions->readPixels(area.x, area.y, area.width, area.height, format, type, pixels); - return gl::Error(GL_NO_ERROR); + return Error(GL_NO_ERROR); } -gl::Error FramebufferGL::blit(const gl::State &state, const gl::Rectangle &sourceArea, const gl::Rectangle &destArea, - GLbitfield mask, GLenum filter, const gl::Framebuffer *sourceFramebuffer) +Error FramebufferGL::blit(const State &state, + const gl::Rectangle &sourceArea, + const gl::Rectangle &destArea, + GLbitfield mask, + GLenum filter, + const Framebuffer *sourceFramebuffer) { const FramebufferGL *sourceFramebufferGL = GetImplAs(sourceFramebuffer); mStateManager->bindFramebuffer(GL_READ_FRAMEBUFFER, sourceFramebufferGL->getFramebufferID()); mStateManager->bindFramebuffer(GL_DRAW_FRAMEBUFFER, mFramebufferID); - mFunctions->blitFramebuffer(sourceArea.x, sourceArea.y, sourceArea.x + sourceArea.width, sourceArea.y + sourceArea.height, - destArea.x, destArea.y, destArea.x + destArea.width, destArea.y + destArea.height, - mask, filter); + mFunctions->blitFramebuffer(sourceArea.x, sourceArea.y, sourceArea.x1(), sourceArea.y1(), + destArea.x, destArea.y, destArea.x1(), destArea.y1(), mask, filter); - return gl::Error(GL_NO_ERROR); + return Error(GL_NO_ERROR); } -GLenum FramebufferGL::checkStatus() const +bool FramebufferGL::checkStatus() const { mStateManager->bindFramebuffer(GL_FRAMEBUFFER, mFramebufferID); - return mFunctions->checkFramebufferStatus(GL_FRAMEBUFFER); + GLenum status = mFunctions->checkFramebufferStatus(GL_FRAMEBUFFER); + if (status != GL_FRAMEBUFFER_COMPLETE) + { + ANGLEPlatformCurrent()->logWarning("GL framebuffer returned incomplete."); + } + return (status == GL_FRAMEBUFFER_COMPLETE); +} + +void FramebufferGL::syncState(const Framebuffer::DirtyBits &dirtyBits) +{ + // Don't need to sync state for the default FBO. + if (mIsDefault) + { + return; + } + + mStateManager->bindFramebuffer(GL_FRAMEBUFFER, mFramebufferID); + + for (auto dirtyBit : angle::IterateBitSet(dirtyBits)) + { + switch (dirtyBit) + { + case Framebuffer::DIRTY_BIT_DEPTH_ATTACHMENT: + BindFramebufferAttachment(mFunctions, GL_DEPTH_ATTACHMENT, + mData.getDepthAttachment()); + break; + case Framebuffer::DIRTY_BIT_STENCIL_ATTACHMENT: + BindFramebufferAttachment(mFunctions, GL_STENCIL_ATTACHMENT, + mData.getStencilAttachment()); + break; + case Framebuffer::DIRTY_BIT_DRAW_BUFFERS: + { + const auto &drawBuffers = mData.getDrawBufferStates(); + mFunctions->drawBuffers(static_cast(drawBuffers.size()), + drawBuffers.data()); + break; + } + case Framebuffer::DIRTY_BIT_READ_BUFFER: + mFunctions->readBuffer(mData.getReadBufferState()); + break; + default: + { + ASSERT(Framebuffer::DIRTY_BIT_COLOR_ATTACHMENT_0 == 0 && + dirtyBit < Framebuffer::DIRTY_BIT_COLOR_ATTACHMENT_MAX); + size_t index = + static_cast(dirtyBit - Framebuffer::DIRTY_BIT_COLOR_ATTACHMENT_0); + BindFramebufferAttachment(mFunctions, + static_cast(GL_COLOR_ATTACHMENT0 + index), + mData.getColorAttachment(index)); + break; + } + } + } } GLuint FramebufferGL::getFramebufferID() const @@ -295,4 +321,75 @@ GLuint FramebufferGL::getFramebufferID() const return mFramebufferID; } +void FramebufferGL::syncDrawState() const +{ + if (mFunctions->standard == STANDARD_GL_DESKTOP) + { + // Enable SRGB blending for all framebuffers except the default framebuffer on Desktop + // OpenGL. + // When SRGB blending is enabled, only SRGB capable formats will use it but the default + // framebuffer will always use it if it is enabled. + // TODO(geofflang): Update this when the framebuffer binding dirty changes, when it exists. + mStateManager->setFramebufferSRGBEnabled(!mIsDefault); + } +} + +void FramebufferGL::syncClearState(GLbitfield mask) +{ + if (mFunctions->standard == STANDARD_GL_DESKTOP) + { + if (mWorkarounds.doesSRGBClearsOnLinearFramebufferAttachments && + (mask & GL_COLOR_BUFFER_BIT) != 0 && !mIsDefault) + { + bool hasSRBAttachment = false; + for (const auto &attachment : mData.getColorAttachments()) + { + if (attachment.isAttached() && attachment.getColorEncoding() == GL_SRGB) + { + hasSRBAttachment = true; + break; + } + } + + mStateManager->setFramebufferSRGBEnabled(hasSRBAttachment); + } + else + { + mStateManager->setFramebufferSRGBEnabled(!mIsDefault); + } + } +} + +void FramebufferGL::syncClearBufferState(GLenum buffer, GLint drawBuffer) +{ + if (mFunctions->standard == STANDARD_GL_DESKTOP) + { + if (mWorkarounds.doesSRGBClearsOnLinearFramebufferAttachments && buffer == GL_COLOR && + !mIsDefault) + { + // If doing a clear on a color buffer, set SRGB blend enabled only if the color buffer + // is an SRGB format. + const auto &drawbufferState = mData.getDrawBufferStates(); + const auto &colorAttachments = mData.getColorAttachments(); + + const FramebufferAttachment *attachment = nullptr; + if (drawbufferState[drawBuffer] >= GL_COLOR_ATTACHMENT0 && + drawbufferState[drawBuffer] < GL_COLOR_ATTACHMENT0 + colorAttachments.size()) + { + size_t attachmentIdx = + static_cast(drawbufferState[drawBuffer] - GL_COLOR_ATTACHMENT0); + attachment = &colorAttachments[attachmentIdx]; + } + + if (attachment != nullptr) + { + mStateManager->setFramebufferSRGBEnabled(attachment->getColorEncoding() == GL_SRGB); + } + } + else + { + mStateManager->setFramebufferSRGBEnabled(!mIsDefault); + } + } } +} // namespace rx diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/FramebufferGL.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/FramebufferGL.h index 3dbdf6612e27..224b10c7b973 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/FramebufferGL.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/FramebufferGL.h @@ -16,29 +16,48 @@ namespace rx class FunctionsGL; class StateManagerGL; +struct WorkaroundsGL; class FramebufferGL : public FramebufferImpl { public: - FramebufferGL(const gl::Framebuffer::Data &data, const FunctionsGL *functions, StateManagerGL *stateManager, bool isDefault); + FramebufferGL(const gl::Framebuffer::Data &data, + const FunctionsGL *functions, + StateManagerGL *stateManager, + const WorkaroundsGL &workarounds, + bool isDefault); + // Constructor called when we need to create a FramebufferGL from an + // existing framebuffer name, for example for the default framebuffer + // on the Mac EGL CGL backend. + FramebufferGL(GLuint id, + const gl::Framebuffer::Data &data, + const FunctionsGL *functions, + const WorkaroundsGL &workarounds, + StateManagerGL *stateManager); ~FramebufferGL() override; - void onUpdateColorAttachment(size_t index) override; - void onUpdateDepthAttachment() override; - void onUpdateStencilAttachment() override; - void onUpdateDepthStencilAttachment() override; - - void setDrawBuffers(size_t count, const GLenum *buffers) override; - void setReadBuffer(GLenum buffer) override; - + gl::Error discard(size_t count, const GLenum *attachments) override; gl::Error invalidate(size_t count, const GLenum *attachments) override; gl::Error invalidateSub(size_t count, const GLenum *attachments, const gl::Rectangle &area) override; gl::Error clear(const gl::Data &data, GLbitfield mask) override; - gl::Error clearBufferfv(const gl::State &state, GLenum buffer, GLint drawbuffer, const GLfloat *values) override; - gl::Error clearBufferuiv(const gl::State &state, GLenum buffer, GLint drawbuffer, const GLuint *values) override; - gl::Error clearBufferiv(const gl::State &state, GLenum buffer, GLint drawbuffer, const GLint *values) override; - gl::Error clearBufferfi(const gl::State &state, GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil) override; + gl::Error clearBufferfv(const gl::Data &data, + GLenum buffer, + GLint drawbuffer, + const GLfloat *values) override; + gl::Error clearBufferuiv(const gl::Data &data, + GLenum buffer, + GLint drawbuffer, + const GLuint *values) override; + gl::Error clearBufferiv(const gl::Data &data, + GLenum buffer, + GLint drawbuffer, + const GLint *values) override; + gl::Error clearBufferfi(const gl::Data &data, + GLenum buffer, + GLint drawbuffer, + GLfloat depth, + GLint stencil) override; GLenum getImplementationColorReadFormat() const override; GLenum getImplementationColorReadType() const override; @@ -47,15 +66,24 @@ class FramebufferGL : public FramebufferImpl gl::Error blit(const gl::State &state, const gl::Rectangle &sourceArea, const gl::Rectangle &destArea, GLbitfield mask, GLenum filter, const gl::Framebuffer *sourceFramebuffer) override; - GLenum checkStatus() const override; + bool checkStatus() const override; + + void syncState(const gl::Framebuffer::DirtyBits &dirtyBits) override; + + void syncDrawState() const; GLuint getFramebufferID() const; private: + void syncClearState(GLbitfield mask); + void syncClearBufferState(GLenum buffer, GLint drawBuffer); + const FunctionsGL *mFunctions; StateManagerGL *mStateManager; + const WorkaroundsGL &mWorkarounds; GLuint mFramebufferID; + bool mIsDefault; }; } diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/FunctionsGL.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/FunctionsGL.cpp index 423678c06641..bd7d773f1489 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/FunctionsGL.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/FunctionsGL.cpp @@ -10,48 +10,32 @@ #include +#include "common/string_utils.h" #include "libANGLE/renderer/gl/renderergl_utils.h" namespace rx { -static void GetGLVersion(PFNGLGETSTRINGPROC getStringFunction, GLuint *outMajorVersion, GLuint *outMinorVersion, - bool *outIsES) +static void GetGLVersion(PFNGLGETSTRINGPROC getStringFunction, gl::Version *outVersion, StandardGL *outStandard) { const std::string version = reinterpret_cast(getStringFunction(GL_VERSION)); if (version.find("OpenGL ES") == std::string::npos) - { - // ES spec states that the GL_VERSION string will be in the following format: - // "OpenGL ES N.M vendor-specific information" - *outIsES = false; - *outMajorVersion = version[0] - '0'; - *outMinorVersion = version[2] - '0'; - } - else { // OpenGL spec states the GL_VERSION string will be in the following format: // // The version number is either of the form major number.minor number or major // number.minor number.release number, where the numbers all have one or more // digits - *outIsES = true; - *outMajorVersion = version[10] - '0'; - *outMinorVersion = version[12] - '0'; + *outStandard = STANDARD_GL_DESKTOP; + *outVersion = gl::Version(version[0] - '0', version[2] - '0'); } -} - -static std::vector GetNonIndexedExtensions(PFNGLGETSTRINGPROC getStringFunction) -{ - std::vector result; - - std::istringstream stream(reinterpret_cast(getStringFunction(GL_EXTENSIONS))); - std::string extension; - while (std::getline(stream, extension, ' ')) + else { - result.push_back(extension); + // ES spec states that the GL_VERSION string will be in the following format: + // "OpenGL ES N.M vendor-specific information" + *outStandard = STANDARD_GL_ES; + *outVersion = gl::Version(version[10] - '0', version[12] - '0'); } - - return result; } static std::vector GetIndexedExtensions(PFNGLGETINTEGERVPROC getIntegerFunction, PFNGLGETSTRINGIPROC getStringIFunction) @@ -78,18 +62,25 @@ static void AssignGLEntryPoint(void *function, T *outFunction) } template -static void AssignGLExtensionEntryPoint(const std::vector &extensions, const std::string &extension, void *function, T *outFunction) +static void AssignGLExtensionEntryPoint(const std::vector &extensions, const char *requiredExtensionString, + void *function, T *outFunction) { - if (std::find(extensions.begin(), extensions.end(), extension) != extensions.end()) + std::vector requiredExtensions; + angle::SplitStringAlongWhitespace(requiredExtensionString, &requiredExtensions); + for (const std::string& requiredExtension : requiredExtensions) { - *outFunction = reinterpret_cast(function); + if (std::find(extensions.begin(), extensions.end(), requiredExtension) == extensions.end()) + { + return; + } } + + *outFunction = reinterpret_cast(function); } FunctionsGL::FunctionsGL() - : majorVersion(0), - minorVersion(0), - openGLES(false), + : version(), + standard(), extensions(), blendFunc(nullptr), @@ -618,6 +609,7 @@ FunctionsGL::FunctionsGL() getDebugMessageLog(nullptr), getFramebufferParameteriv(nullptr), getInternalformati64v(nullptr), + getPointerv(nullptr), getObjectLabel(nullptr), getObjectPtrLabel(nullptr), getProgramInterfaceiv(nullptr), @@ -768,7 +760,11 @@ FunctionsGL::FunctionsGL() vertexArrayBindingDivisor(nullptr), vertexArrayElementBuffer(nullptr), vertexArrayVertexBuffer(nullptr), - vertexArrayVertexBuffers(nullptr) + vertexArrayVertexBuffers(nullptr), + blendBarrier(nullptr), + primitiveBoundingBox(nullptr), + eglImageTargetRenderbufferStorageOES(nullptr), + eglImageTargetTexture2DOES(nullptr) { } @@ -780,22 +776,193 @@ void FunctionsGL::initialize() { // Grab the version number AssignGLEntryPoint(loadProcAddress("glGetString"), &getString); - GetGLVersion(getString, &majorVersion, &minorVersion, &openGLES); + AssignGLEntryPoint(loadProcAddress("glGetIntegerv"), &getIntegerv); + GetGLVersion(getString, &version, &standard); // Grab the GL extensions - if (majorVersion >= 3) + if (isAtLeastGL(gl::Version(3, 0)) || isAtLeastGLES(gl::Version(3, 0))) { - AssignGLEntryPoint(loadProcAddress("glGetIntegerv"), &getIntegerv); AssignGLEntryPoint(loadProcAddress("glGetStringi"), &getStringi); extensions = GetIndexedExtensions(getIntegerv, getStringi); } else { - extensions = GetNonIndexedExtensions(getString); + const char *exts = reinterpret_cast(getString(GL_EXTENSIONS)); + angle::SplitStringAlongWhitespace(std::string(exts), &extensions); + } + + // Load the entry points + switch (standard) + { + case STANDARD_GL_DESKTOP: + initializeProcsDesktopGL(); + break; + + case STANDARD_GL_ES: + initializeProcsGLES(); + break; + + default: + UNREACHABLE(); + break; + } +} + +void FunctionsGL::initializeProcsDesktopGL() +{ + // Check the context profile + profile = 0; + if (isAtLeastGL(gl::Version(3, 2))) + { + getIntegerv(GL_CONTEXT_PROFILE_MASK, &profile); } + // clang-format off + + // Load extensions + // Even though extensions are written against specific versions of GL, many drivers expose the extensions + // in even older versions. Always try loading the extensions regardless of GL version. + + // GL_NV_fence + AssignGLExtensionEntryPoint(extensions, "GL_NV_fence", loadProcAddress("glDeleteFencesNV"), &deleteFencesNV); + AssignGLExtensionEntryPoint(extensions, "GL_NV_fence", loadProcAddress("glGenFencesNV"), &genFencesNV); + AssignGLExtensionEntryPoint(extensions, "GL_NV_fence", loadProcAddress("glIsFenceNV"), &isFenceNV); + AssignGLExtensionEntryPoint(extensions, "GL_NV_fence", loadProcAddress("glTestFenceNV"), &testFenceNV); + AssignGLExtensionEntryPoint(extensions, "GL_NV_fence", loadProcAddress("glGetFenceivNV"), &getFenceivNV); + AssignGLExtensionEntryPoint(extensions, "GL_NV_fence", loadProcAddress("glFinishFenceNV"), &finishFenceNV); + AssignGLExtensionEntryPoint(extensions, "GL_NV_fence", loadProcAddress("glSetFenceNV"), &setFenceNV); + + // GL_EXT_texture_storage + AssignGLExtensionEntryPoint(extensions, "GL_EXT_texture_storage", loadProcAddress("glTexStorage1DEXT"), &texStorage1D); + AssignGLExtensionEntryPoint(extensions, "GL_EXT_texture_storage", loadProcAddress("glTexStorage2DEXT"), &texStorage2D); + AssignGLExtensionEntryPoint(extensions, "GL_EXT_texture_storage GL_EXT_texture3D", loadProcAddress("glTexStorage3DEXT"), &texStorage3D); + AssignGLExtensionEntryPoint(extensions, "GL_EXT_texture_storage GL_EXT_direct_state_access", loadProcAddress("glTextureStorage1DEXT"), &textureStorage1D); + AssignGLExtensionEntryPoint(extensions, "GL_EXT_texture_storage GL_EXT_direct_state_access", loadProcAddress("glTextureStorage2DEXT"), &textureStorage2D); + AssignGLExtensionEntryPoint(extensions, "GL_EXT_texture_storage GL_EXT_direct_state_access GL_EXT_texture3D", loadProcAddress("glTextureStorage3DEXT"), &textureStorage3D); + + // GL_ARB_vertex_array_object + AssignGLExtensionEntryPoint(extensions, "GL_ARB_vertex_array_object", loadProcAddress("glBindVertexArray"), &bindVertexArray); + AssignGLExtensionEntryPoint(extensions, "GL_ARB_vertex_array_object", loadProcAddress("glDeleteVertexArrays"), &deleteVertexArrays); + AssignGLExtensionEntryPoint(extensions, "GL_ARB_vertex_array_object", loadProcAddress("glGenVertexArrays"), &genVertexArrays); + AssignGLExtensionEntryPoint(extensions, "GL_ARB_vertex_array_object", loadProcAddress("glIsVertexArray"), &isVertexArray); + + // GL_ARB_sync + AssignGLExtensionEntryPoint(extensions, "GL_ARB_sync", loadProcAddress("glClientWaitSync"), &clientWaitSync); + AssignGLExtensionEntryPoint(extensions, "GL_ARB_sync", loadProcAddress("glDeleteSync"), &deleteSync); + AssignGLExtensionEntryPoint(extensions, "GL_ARB_sync", loadProcAddress("glFenceSync"), &fenceSync); + AssignGLExtensionEntryPoint(extensions, "GL_ARB_sync", loadProcAddress("glGetInteger64i_v"), &getInteger64i_v); + AssignGLExtensionEntryPoint(extensions, "GL_ARB_sync", loadProcAddress("glGetInteger64v"), &getInteger64v); + AssignGLExtensionEntryPoint(extensions, "GL_ARB_sync", loadProcAddress("glGetSynciv"), &getSynciv); + AssignGLExtensionEntryPoint(extensions, "GL_ARB_sync", loadProcAddress("glIsSync"), &isSync); + AssignGLExtensionEntryPoint(extensions, "GL_ARB_sync", loadProcAddress("glWaitSync"), &waitSync); + + // GL_EXT_framebuffer_object + AssignGLExtensionEntryPoint(extensions, "GL_EXT_framebuffer_object", loadProcAddress("glIsRenderbufferEXT"), &isRenderbuffer); + AssignGLExtensionEntryPoint(extensions, "GL_EXT_framebuffer_object", loadProcAddress("glBindRenderbufferEXT"), &bindRenderbuffer); + AssignGLExtensionEntryPoint(extensions, "GL_EXT_framebuffer_object", loadProcAddress("glDeleteRenderbuffersEXT"), &deleteRenderbuffers); + AssignGLExtensionEntryPoint(extensions, "GL_EXT_framebuffer_object", loadProcAddress("glGenRenderbuffersEXT"), &genRenderbuffers); + AssignGLExtensionEntryPoint(extensions, "GL_EXT_framebuffer_object", loadProcAddress("glRenderbufferStorageEXT"), &renderbufferStorage); + AssignGLExtensionEntryPoint(extensions, "GL_EXT_framebuffer_object", loadProcAddress("glGetRenderbufferParameterivEXT"), &getRenderbufferParameteriv); + AssignGLExtensionEntryPoint(extensions, "GL_EXT_framebuffer_object", loadProcAddress("glIsFramebufferEXT"), &isFramebuffer); + AssignGLExtensionEntryPoint(extensions, "GL_EXT_framebuffer_object", loadProcAddress("glBindFramebufferEXT"), &bindFramebuffer); + AssignGLExtensionEntryPoint(extensions, "GL_EXT_framebuffer_object", loadProcAddress("glDeleteFramebuffersEXT"), &deleteFramebuffers); + AssignGLExtensionEntryPoint(extensions, "GL_EXT_framebuffer_object", loadProcAddress("glGenFramebuffersEXT"), &genFramebuffers); + AssignGLExtensionEntryPoint(extensions, "GL_EXT_framebuffer_object", loadProcAddress("glCheckFramebufferStatusEXT"), &checkFramebufferStatus); + AssignGLExtensionEntryPoint(extensions, "GL_EXT_framebuffer_object", loadProcAddress("glFramebufferTexture1DEXT"), &framebufferTexture1D); + AssignGLExtensionEntryPoint(extensions, "GL_EXT_framebuffer_object", loadProcAddress("glFramebufferTexture2DEXT"), &framebufferTexture2D); + AssignGLExtensionEntryPoint(extensions, "GL_EXT_framebuffer_object", loadProcAddress("glFramebufferTexture3DEXT"), &framebufferTexture3D); + AssignGLExtensionEntryPoint(extensions, "GL_EXT_framebuffer_object", loadProcAddress("glFramebufferRenderbufferEXT"), &framebufferRenderbuffer); + AssignGLExtensionEntryPoint(extensions, "GL_EXT_framebuffer_object", loadProcAddress("glGetFramebufferAttachmentParameterivEXT"), &getFramebufferAttachmentParameteriv); + AssignGLExtensionEntryPoint(extensions, "GL_EXT_framebuffer_object", loadProcAddress("glGenerateMipmapEXT"), &generateMipmap); + + // GL_EXT_framebuffer_blit + AssignGLExtensionEntryPoint(extensions, "GL_EXT_framebuffer_blit", loadProcAddress("glBlitFramebufferEXT"), &blitFramebuffer); + + // GL_KHR_debug + AssignGLExtensionEntryPoint(extensions, "GL_KHR_debug", loadProcAddress("glDebugMessageControl"), &debugMessageControl); + AssignGLExtensionEntryPoint(extensions, "GL_KHR_debug", loadProcAddress("glDebugMessageInsert"), &debugMessageInsert); + AssignGLExtensionEntryPoint(extensions, "GL_KHR_debug", loadProcAddress("glDebugMessageCallback"), &debugMessageCallback); + AssignGLExtensionEntryPoint(extensions, "GL_KHR_debug", loadProcAddress("glGetDebugMessageLog"), &getDebugMessageLog); + AssignGLExtensionEntryPoint(extensions, "GL_KHR_debug", loadProcAddress("glGetPointerv"), &getPointerv); + AssignGLExtensionEntryPoint(extensions, "GL_KHR_debug", loadProcAddress("glPushDebugGroup"), &pushDebugGroup); + AssignGLExtensionEntryPoint(extensions, "GL_KHR_debug", loadProcAddress("glPopDebugGroup"), &popDebugGroup); + AssignGLExtensionEntryPoint(extensions, "GL_KHR_debug", loadProcAddress("glObjectLabel"), &objectLabel); + AssignGLExtensionEntryPoint(extensions, "GL_KHR_debug", loadProcAddress("glGetObjectLabel"), &getObjectLabel); + AssignGLExtensionEntryPoint(extensions, "GL_KHR_debug", loadProcAddress("glObjectPtrLabel"), &objectPtrLabel); + AssignGLExtensionEntryPoint(extensions, "GL_KHR_debug", loadProcAddress("glGetObjectPtrLabel"), &getObjectPtrLabel); + + // GL_ARB_internalformat_query + AssignGLExtensionEntryPoint(extensions, "GL_ARB_internalformat_query", loadProcAddress("glGetInternalformativ"), &getInternalformativ); + + // GL_ARB_ES2_compatibility + AssignGLExtensionEntryPoint(extensions, "GL_ARB_ES2_compatibility", loadProcAddress("glReleaseShaderCompiler"), &releaseShaderCompiler); + AssignGLExtensionEntryPoint(extensions, "GL_ARB_ES2_compatibility", loadProcAddress("glShaderBinary"), &shaderBinary); + AssignGLExtensionEntryPoint(extensions, "GL_ARB_ES2_compatibility", loadProcAddress("glGetShaderPrecisionFormat"), &getShaderPrecisionFormat); + AssignGLExtensionEntryPoint(extensions, "GL_ARB_ES2_compatibility", loadProcAddress("glDepthRangef"), &depthRangef); + AssignGLExtensionEntryPoint(extensions, "GL_ARB_ES2_compatibility", loadProcAddress("glClearDepthf"), &clearDepthf); + + // GL_ARB_instanced_arrays + AssignGLExtensionEntryPoint(extensions, "GL_ARB_instanced_arrays", loadProcAddress("glVertexAttribDivisorARB"), &vertexAttribDivisor); + + // GL_EXT_draw_instanced + AssignGLExtensionEntryPoint(extensions, "GL_EXT_draw_instanced", loadProcAddress("glDrawArraysInstancedEXT"), &drawArraysInstanced); + AssignGLExtensionEntryPoint(extensions, "GL_EXT_draw_instanced", loadProcAddress("glDrawElementsInstancedEXT"), &drawElementsInstanced); + + // GL_ARB_draw_instanced + AssignGLExtensionEntryPoint(extensions, "GL_ARB_draw_instanced", loadProcAddress("glDrawArraysInstancedARB"), &drawArraysInstanced); + AssignGLExtensionEntryPoint(extensions, "GL_ARB_draw_instanced", loadProcAddress("glDrawElementsInstancedARB"), &drawElementsInstanced); + + // GL_ARB_sampler_objects + AssignGLExtensionEntryPoint(extensions, "GL_ARB_sampler_objects", loadProcAddress("glGenSamplers"), &genSamplers); + AssignGLExtensionEntryPoint(extensions, "GL_ARB_sampler_objects", loadProcAddress("glDeleteSamplers"), &deleteSamplers); + AssignGLExtensionEntryPoint(extensions, "GL_ARB_sampler_objects", loadProcAddress("glIsSampler"), &isSampler); + AssignGLExtensionEntryPoint(extensions, "GL_ARB_sampler_objects", loadProcAddress("glBindSampler"), &bindSampler); + AssignGLExtensionEntryPoint(extensions, "GL_ARB_sampler_objects", loadProcAddress("glSamplerParameteri"), &samplerParameteri); + AssignGLExtensionEntryPoint(extensions, "GL_ARB_sampler_objects", loadProcAddress("glSamplerParameterf"), &samplerParameterf); + AssignGLExtensionEntryPoint(extensions, "GL_ARB_sampler_objects", loadProcAddress("glSamplerParameteriv"), &samplerParameteriv); + AssignGLExtensionEntryPoint(extensions, "GL_ARB_sampler_objects", loadProcAddress("glSamplerParameterfv"), &samplerParameterfv); + AssignGLExtensionEntryPoint(extensions, "GL_ARB_sampler_objects", loadProcAddress("glSamplerParameterIiv"), &samplerParameterIiv); + AssignGLExtensionEntryPoint(extensions, "GL_ARB_sampler_objects", loadProcAddress("glSamplerParameterIuiv"), &samplerParameterIuiv); + AssignGLExtensionEntryPoint(extensions, "GL_ARB_sampler_objects", loadProcAddress("glGetSamplerParameteriv"), &getSamplerParameteriv); + AssignGLExtensionEntryPoint(extensions, "GL_ARB_sampler_objects", loadProcAddress("glGetSamplerParameterfv"), &getSamplerParameterfv); + AssignGLExtensionEntryPoint(extensions, "GL_ARB_sampler_objects", loadProcAddress("glGetSamplerParameterIiv"), &getSamplerParameterIiv); + AssignGLExtensionEntryPoint(extensions, "GL_ARB_sampler_objects", loadProcAddress("glGetSamplerParameterIuiv"), &getSamplerParameterIuiv); + + // GL_ARB_occlusion_query + AssignGLExtensionEntryPoint(extensions, "GL_ARB_occlusion_query", loadProcAddress("glGenQueriesARB"), &genQueries); + AssignGLExtensionEntryPoint(extensions, "GL_ARB_occlusion_query", loadProcAddress("glDeleteQueriesARB"), &deleteQueries); + AssignGLExtensionEntryPoint(extensions, "GL_ARB_occlusion_query", loadProcAddress("glIsQueryARB"), &isQuery); + AssignGLExtensionEntryPoint(extensions, "GL_ARB_occlusion_query", loadProcAddress("glBeginQueryARB"), &beginQuery); + AssignGLExtensionEntryPoint(extensions, "GL_ARB_occlusion_query", loadProcAddress("glEndQueryARB"), &endQuery); + AssignGLExtensionEntryPoint(extensions, "GL_ARB_occlusion_query", loadProcAddress("glGetQueryivARB"), &getQueryiv); + AssignGLExtensionEntryPoint(extensions, "GL_ARB_occlusion_query", loadProcAddress("glGetQueryObjectivARB"), &getQueryObjectiv); + AssignGLExtensionEntryPoint(extensions, "GL_ARB_occlusion_query", loadProcAddress("glGetQueryObjectuivARB"), &getQueryObjectuiv); + + // EXT_transform_feedback + AssignGLExtensionEntryPoint(extensions, "EXT_transform_feedback", loadProcAddress("glBindBufferRangeEXT"), &bindBufferRange); + AssignGLExtensionEntryPoint(extensions, "EXT_transform_feedback", loadProcAddress("glBindBufferBaseEXT"), &bindBufferBase); + AssignGLExtensionEntryPoint(extensions, "EXT_transform_feedback", loadProcAddress("glBeginTransformFeedbackEXT"), &beginTransformFeedback); + AssignGLExtensionEntryPoint(extensions, "EXT_transform_feedback", loadProcAddress("glEndTransformFeedbackEXT"), &endTransformFeedback); + AssignGLExtensionEntryPoint(extensions, "EXT_transform_feedback", loadProcAddress("glTransformFeedbackVaryingsEXT"), &transformFeedbackVaryings); + AssignGLExtensionEntryPoint(extensions, "EXT_transform_feedback", loadProcAddress("glGetTransformFeedbackVaryingEXT"), &getTransformFeedbackVarying); + + // GL_ARB_transform_feedback2 + AssignGLExtensionEntryPoint(extensions, "GL_ARB_transform_feedback2", loadProcAddress("glBindTransformFeedback"), &bindTransformFeedback); + AssignGLExtensionEntryPoint(extensions, "GL_ARB_transform_feedback2", loadProcAddress("glDeleteTransformFeedbacks"), &deleteTransformFeedbacks); + AssignGLExtensionEntryPoint(extensions, "GL_ARB_transform_feedback2", loadProcAddress("glGenTransformFeedbacks"), &genTransformFeedbacks); + AssignGLExtensionEntryPoint(extensions, "GL_ARB_transform_feedback2", loadProcAddress("glIsTransformFeedback"), &isTransformFeedback); + AssignGLExtensionEntryPoint(extensions, "GL_ARB_transform_feedback2", loadProcAddress("glPauseTransformFeedback"), &pauseTransformFeedback); + AssignGLExtensionEntryPoint(extensions, "GL_ARB_transform_feedback2", loadProcAddress("glResumeTransformFeedback"), &resumeTransformFeedback); + AssignGLExtensionEntryPoint(extensions, "GL_ARB_transform_feedback2", loadProcAddress("glDrawTransformFeedback"), &drawTransformFeedback); + + // GL_ARB_transform_feedback3 + AssignGLExtensionEntryPoint(extensions, "GL_ARB_transform_feedback3", loadProcAddress("glDrawTransformFeedbackStream"), &drawTransformFeedbackStream); + AssignGLExtensionEntryPoint(extensions, "GL_ARB_transform_feedback3", loadProcAddress("glBeginQueryIndexed"), &beginQueryIndexed); + AssignGLExtensionEntryPoint(extensions, "GL_ARB_transform_feedback3", loadProcAddress("glEndQueryIndexed"), &endQueryIndexed); + AssignGLExtensionEntryPoint(extensions, "GL_ARB_transform_feedback3", loadProcAddress("glGetQueryIndexediv"), &getQueryIndexediv); + // 1.0 - if (majorVersion >= 1) + if (isAtLeastGL(gl::Version(1, 0))) { AssignGLEntryPoint(loadProcAddress("glBlendFunc"), &blendFunc); AssignGLEntryPoint(loadProcAddress("glClear"), &clear); @@ -848,7 +1015,7 @@ void FunctionsGL::initialize() } // 1.1 - if (majorVersion > 1 || (majorVersion == 1 && minorVersion >= 1)) + if (isAtLeastGL(gl::Version(1, 1))) { AssignGLEntryPoint(loadProcAddress("glBindTexture"), &bindTexture); AssignGLEntryPoint(loadProcAddress("glCopyTexImage1D"), ©TexImage1D); @@ -866,7 +1033,7 @@ void FunctionsGL::initialize() } // 1.2 - if (majorVersion > 1 || (majorVersion == 1 && minorVersion >= 2)) + if (isAtLeastGL(gl::Version(1, 2))) { AssignGLEntryPoint(loadProcAddress("glBlendColor"), &blendColor); AssignGLEntryPoint(loadProcAddress("glBlendEquation"), &blendEquation); @@ -874,19 +1041,10 @@ void FunctionsGL::initialize() AssignGLEntryPoint(loadProcAddress("glDrawRangeElements"), &drawRangeElements); AssignGLEntryPoint(loadProcAddress("glTexImage3D"), &texImage3D); AssignGLEntryPoint(loadProcAddress("glTexSubImage3D"), &texSubImage3D); - - // Extensions - AssignGLExtensionEntryPoint(extensions, "GL_NV_fence", loadProcAddress("glDeleteFencesNV"), &deleteFencesNV); - AssignGLExtensionEntryPoint(extensions, "GL_NV_fence", loadProcAddress("glGenFencesNV"), &genFencesNV); - AssignGLExtensionEntryPoint(extensions, "GL_NV_fence", loadProcAddress("glIsFenceNV"), &isFenceNV); - AssignGLExtensionEntryPoint(extensions, "GL_NV_fence", loadProcAddress("glTestFenceNV"), &testFenceNV); - AssignGLExtensionEntryPoint(extensions, "GL_NV_fence", loadProcAddress("glGetFenceivNV"), &getFenceivNV); - AssignGLExtensionEntryPoint(extensions, "GL_NV_fence", loadProcAddress("glFinishFenceNV"), &finishFenceNV); - AssignGLExtensionEntryPoint(extensions, "GL_NV_fence", loadProcAddress("glSetFenceNV"), &setFenceNV); } // 1.3 - if (majorVersion > 1 || (majorVersion == 1 && minorVersion >= 3)) + if (isAtLeastGL(gl::Version(1, 3))) { AssignGLEntryPoint(loadProcAddress("glActiveTexture"), &activeTexture); AssignGLEntryPoint(loadProcAddress("glCompressedTexImage1D"), &compressedTexImage1D); @@ -900,7 +1058,7 @@ void FunctionsGL::initialize() } // 1.4 - if (majorVersion > 1 || (majorVersion == 1 && minorVersion >= 4)) + if (isAtLeastGL(gl::Version(1, 4))) { AssignGLEntryPoint(loadProcAddress("glBlendFuncSeparate"), &blendFuncSeparate); AssignGLEntryPoint(loadProcAddress("glMultiDrawArrays"), &multiDrawArrays); @@ -912,7 +1070,7 @@ void FunctionsGL::initialize() } // 1.5 - if (majorVersion > 1 || (majorVersion == 1 && minorVersion >= 5)) + if (isAtLeastGL(gl::Version(1, 5))) { AssignGLEntryPoint(loadProcAddress("glBeginQuery"), &beginQuery); AssignGLEntryPoint(loadProcAddress("glBindBuffer"), &bindBuffer); @@ -936,7 +1094,7 @@ void FunctionsGL::initialize() } // 2.0 - if (majorVersion >= 2) + if (isAtLeastGL(gl::Version(2, 0))) { AssignGLEntryPoint(loadProcAddress("glAttachShader"), &attachShader); AssignGLEntryPoint(loadProcAddress("glBindAttribLocation"), &bindAttribLocation); @@ -1034,7 +1192,7 @@ void FunctionsGL::initialize() } // 2.1 - if (majorVersion > 2 || (majorVersion == 2 && minorVersion >= 1)) + if (isAtLeastGL(gl::Version(2, 1))) { AssignGLEntryPoint(loadProcAddress("glUniformMatrix2x3fv"), &uniformMatrix2x3fv); AssignGLEntryPoint(loadProcAddress("glUniformMatrix2x4fv"), &uniformMatrix2x4fv); @@ -1045,7 +1203,7 @@ void FunctionsGL::initialize() } // 3.0 - if (majorVersion >= 3) + if (isAtLeastGL(gl::Version(3, 0))) { AssignGLEntryPoint(loadProcAddress("glBeginConditionalRender"), &beginConditionalRender); AssignGLEntryPoint(loadProcAddress("glBeginTransformFeedback"), &beginTransformFeedback); @@ -1131,13 +1289,10 @@ void FunctionsGL::initialize() AssignGLEntryPoint(loadProcAddress("glVertexAttribI4uiv"), &vertexAttribI4uiv); AssignGLEntryPoint(loadProcAddress("glVertexAttribI4usv"), &vertexAttribI4usv); AssignGLEntryPoint(loadProcAddress("glVertexAttribIPointer"), &vertexAttribIPointer); - - // Extensions - AssignGLExtensionEntryPoint(extensions, "GL_ARB_internalformat_query", loadProcAddress("glGetInternalformativ"), &getInternalformativ); } // 3.1 - if (majorVersion > 3 || (majorVersion == 3 && minorVersion >= 1)) + if (isAtLeastGL(gl::Version(3, 1))) { AssignGLEntryPoint(loadProcAddress("glCopyBufferSubData"), ©BufferSubData); AssignGLEntryPoint(loadProcAddress("glDrawArraysInstanced"), &drawArraysInstanced); @@ -1151,20 +1306,10 @@ void FunctionsGL::initialize() AssignGLEntryPoint(loadProcAddress("glPrimitiveRestartIndex"), &primitiveRestartIndex); AssignGLEntryPoint(loadProcAddress("glTexBuffer"), &texBuffer); AssignGLEntryPoint(loadProcAddress("glUniformBlockBinding"), &uniformBlockBinding); - - // Extensions - AssignGLExtensionEntryPoint(extensions, "GL_ARB_sync", loadProcAddress("glClientWaitSync"), &clientWaitSync); - AssignGLExtensionEntryPoint(extensions, "GL_ARB_sync", loadProcAddress("glDeleteSync"), &deleteSync); - AssignGLExtensionEntryPoint(extensions, "GL_ARB_sync", loadProcAddress("glFenceSync"), &fenceSync); - AssignGLExtensionEntryPoint(extensions, "GL_ARB_sync", loadProcAddress("glGetInteger64i_v"), &getInteger64i_v); - AssignGLExtensionEntryPoint(extensions, "GL_ARB_sync", loadProcAddress("glGetInteger64v"), &getInteger64v); - AssignGLExtensionEntryPoint(extensions, "GL_ARB_sync", loadProcAddress("glGetSynciv"), &getSynciv); - AssignGLExtensionEntryPoint(extensions, "GL_ARB_sync", loadProcAddress("glIsSync"), &isSync); - AssignGLExtensionEntryPoint(extensions, "GL_ARB_sync", loadProcAddress("glWaitSync"), &waitSync); } // 3.2 - if (majorVersion > 3 || (majorVersion == 3 && minorVersion >= 2)) + if (isAtLeastGL(gl::Version(3, 2))) { AssignGLEntryPoint(loadProcAddress("glClientWaitSync"), &clientWaitSync); AssignGLEntryPoint(loadProcAddress("glDeleteSync"), &deleteSync); @@ -1188,7 +1333,7 @@ void FunctionsGL::initialize() } // 3.3 - if (majorVersion > 3 || (majorVersion == 3 && minorVersion >= 3)) + if (isAtLeastGL(gl::Version(3, 3))) { AssignGLEntryPoint(loadProcAddress("glBindFragDataLocationIndexed"), &bindFragDataLocationIndexed); AssignGLEntryPoint(loadProcAddress("glBindSampler"), &bindSampler); @@ -1221,7 +1366,7 @@ void FunctionsGL::initialize() } // 4.0 - if (majorVersion >= 4) + if (isAtLeastGL(gl::Version(4, 0))) { AssignGLEntryPoint(loadProcAddress("glBeginQueryIndexed"), &beginQueryIndexed); AssignGLEntryPoint(loadProcAddress("glBindTransformFeedback"), &bindTransformFeedback); @@ -1272,7 +1417,7 @@ void FunctionsGL::initialize() } // 4.1 - if (majorVersion > 4 || (majorVersion == 4 && minorVersion >= 1)) + if (isAtLeastGL(gl::Version(4, 1))) { AssignGLEntryPoint(loadProcAddress("glActiveShaderProgram"), &activeShaderProgram); AssignGLEntryPoint(loadProcAddress("glBindProgramPipeline"), &bindProgramPipeline); @@ -1365,7 +1510,7 @@ void FunctionsGL::initialize() } // 4.2 - if (majorVersion > 4 || (majorVersion == 4 && minorVersion >= 2)) + if (isAtLeastGL(gl::Version(4, 2))) { AssignGLEntryPoint(loadProcAddress("glBindImageTexture"), &bindImageTexture); AssignGLEntryPoint(loadProcAddress("glDrawArraysInstancedBaseInstance"), &drawArraysInstancedBaseInstance); @@ -1382,7 +1527,7 @@ void FunctionsGL::initialize() } // 4.3 - if (majorVersion > 4 || (majorVersion == 4 && minorVersion >= 3)) + if (isAtLeastGL(gl::Version(4, 3))) { AssignGLEntryPoint(loadProcAddress("glBindVertexBuffer"), &bindVertexBuffer); AssignGLEntryPoint(loadProcAddress("glClearBufferData"), &clearBufferData); @@ -1397,6 +1542,7 @@ void FunctionsGL::initialize() AssignGLEntryPoint(loadProcAddress("glGetDebugMessageLog"), &getDebugMessageLog); AssignGLEntryPoint(loadProcAddress("glGetFramebufferParameteriv"), &getFramebufferParameteriv); AssignGLEntryPoint(loadProcAddress("glGetInternalformati64v"), &getInternalformati64v); + AssignGLEntryPoint(loadProcAddress("glGetPointerv"), &getPointerv); AssignGLEntryPoint(loadProcAddress("glGetObjectLabel"), &getObjectLabel); AssignGLEntryPoint(loadProcAddress("glGetObjectPtrLabel"), &getObjectPtrLabel); AssignGLEntryPoint(loadProcAddress("glGetProgramInterfaceiv"), &getProgramInterfaceiv); @@ -1430,7 +1576,7 @@ void FunctionsGL::initialize() } // 4.4 - if (majorVersion > 4 || (majorVersion == 4 && minorVersion >= 4)) + if (isAtLeastGL(gl::Version(4, 4))) { AssignGLEntryPoint(loadProcAddress("glBindBuffersBase"), &bindBuffersBase); AssignGLEntryPoint(loadProcAddress("glBindBuffersRange"), &bindBuffersRange); @@ -1444,7 +1590,7 @@ void FunctionsGL::initialize() } // 4.5 - if (majorVersion > 4 || (majorVersion == 4 && minorVersion >= 5)) + if (isAtLeastGL(gl::Version(4, 5))) { AssignGLEntryPoint(loadProcAddress("glBindTextureUnit"), &bindTextureUnit); AssignGLEntryPoint(loadProcAddress("glBlitNamedFramebuffer"), &blitNamedFramebuffer); @@ -1557,6 +1703,498 @@ void FunctionsGL::initialize() AssignGLEntryPoint(loadProcAddress("glVertexArrayVertexBuffer"), &vertexArrayVertexBuffer); AssignGLEntryPoint(loadProcAddress("glVertexArrayVertexBuffers"), &vertexArrayVertexBuffers); } + + // clang-format on +} + +void FunctionsGL::initializeProcsGLES() +{ + // No profiles in GLES + profile = 0; + + // clang-format off + + // GL_OES_texture_3D + AssignGLExtensionEntryPoint(extensions, "GL_OES_texture_3D", loadProcAddress("glTexImage3DOES"), &texImage3D); + AssignGLExtensionEntryPoint(extensions, "GL_OES_texture_3D", loadProcAddress("glTexSubImage3DOES"), &texSubImage3D); + AssignGLExtensionEntryPoint(extensions, "GL_OES_texture_3D", loadProcAddress("glCopyTexSubImage3DOES"), ©TexSubImage3D); + + // GL_NV_fence + AssignGLExtensionEntryPoint(extensions, "GL_NV_fence", loadProcAddress("glDeleteFencesNV"), &deleteFencesNV); + AssignGLExtensionEntryPoint(extensions, "GL_NV_fence", loadProcAddress("glGenFencesNV"), &genFencesNV); + AssignGLExtensionEntryPoint(extensions, "GL_NV_fence", loadProcAddress("glIsFenceNV"), &isFenceNV); + AssignGLExtensionEntryPoint(extensions, "GL_NV_fence", loadProcAddress("glTestFenceNV"), &testFenceNV); + AssignGLExtensionEntryPoint(extensions, "GL_NV_fence", loadProcAddress("glGetFenceivNV"), &getFenceivNV); + AssignGLExtensionEntryPoint(extensions, "GL_NV_fence", loadProcAddress("glFinishFenceNV"), &finishFenceNV); + AssignGLExtensionEntryPoint(extensions, "GL_NV_fence", loadProcAddress("glSetFenceNV"), &setFenceNV); + + // GL_EXT_texture_storage + AssignGLExtensionEntryPoint(extensions, "GL_EXT_texture_storage", loadProcAddress("glTexStorage2DEXT"), &texStorage2D); + AssignGLExtensionEntryPoint(extensions, "GL_EXT_texture_storage GL_OES_texture3D", loadProcAddress("glTexStorage3DEXT"), &texStorage3D); + + // GL_OES_vertex_array_object + AssignGLExtensionEntryPoint(extensions, "GL_OES_vertex_array_object", loadProcAddress("glBindVertexArray"), &bindVertexArray); + AssignGLExtensionEntryPoint(extensions, "GL_OES_vertex_array_object", loadProcAddress("glDeleteVertexArrays"), &deleteVertexArrays); + AssignGLExtensionEntryPoint(extensions, "GL_OES_vertex_array_object", loadProcAddress("glGenVertexArrays"), &genVertexArrays); + AssignGLExtensionEntryPoint(extensions, "GL_OES_vertex_array_object", loadProcAddress("glIsVertexArray"), &isVertexArray); + + // GL_EXT_map_buffer_range + AssignGLExtensionEntryPoint(extensions, "GL_EXT_map_buffer_range", loadProcAddress("glMapBufferRangeEXT"), &mapBufferRange); + AssignGLExtensionEntryPoint(extensions, "GL_EXT_map_buffer_range", loadProcAddress("glFlushMappedBufferRangeEXT"), &flushMappedBufferRange); + AssignGLExtensionEntryPoint(extensions, "GL_EXT_map_buffer_range", loadProcAddress("glUnmapBufferOES"), &unmapBuffer); + + // GL_OES_mapbuffer + AssignGLExtensionEntryPoint(extensions, "GL_OES_mapbuffer", loadProcAddress("glMapBufferOES"), &mapBuffer); + AssignGLExtensionEntryPoint(extensions, "GL_OES_mapbuffer", loadProcAddress("glUnmapBufferOES"), &unmapBuffer); + + // GL_KHR_debug + AssignGLExtensionEntryPoint(extensions, "GL_KHR_debug", loadProcAddress("glDebugMessageControl"), &debugMessageControl); + AssignGLExtensionEntryPoint(extensions, "GL_KHR_debug", loadProcAddress("glDebugMessageInsert"), &debugMessageInsert); + AssignGLExtensionEntryPoint(extensions, "GL_KHR_debug", loadProcAddress("glDebugMessageCallback"), &debugMessageCallback); + AssignGLExtensionEntryPoint(extensions, "GL_KHR_debug", loadProcAddress("glGetDebugMessageLog"), &getDebugMessageLog); + AssignGLExtensionEntryPoint(extensions, "GL_KHR_debug", loadProcAddress("glGetPointerv"), &getPointerv); + AssignGLExtensionEntryPoint(extensions, "GL_KHR_debug", loadProcAddress("glPushDebugGroup"), &pushDebugGroup); + AssignGLExtensionEntryPoint(extensions, "GL_KHR_debug", loadProcAddress("glPopDebugGroup"), &popDebugGroup); + AssignGLExtensionEntryPoint(extensions, "GL_KHR_debug", loadProcAddress("glObjectLabel"), &objectLabel); + AssignGLExtensionEntryPoint(extensions, "GL_KHR_debug", loadProcAddress("glGetObjectLabel"), &getObjectLabel); + AssignGLExtensionEntryPoint(extensions, "GL_KHR_debug", loadProcAddress("glObjectPtrLabel"), &objectPtrLabel); + AssignGLExtensionEntryPoint(extensions, "GL_KHR_debug", loadProcAddress("glGetObjectPtrLabel"), &getObjectPtrLabel); + + // GL_EXT_draw_instanced + AssignGLExtensionEntryPoint(extensions, "GL_EXT_draw_instanced", loadProcAddress("glVertexAttribDivisorEXT"), &vertexAttribDivisor); + AssignGLExtensionEntryPoint(extensions, "GL_EXT_draw_instanced", loadProcAddress("glDrawArraysInstancedEXT"), &drawArraysInstanced); + AssignGLExtensionEntryPoint(extensions, "GL_EXT_draw_instanced", loadProcAddress("glDrawElementsInstancedEXT"), &drawElementsInstanced); + + // GL_EXT_occlusion_query_boolean + AssignGLExtensionEntryPoint(extensions, "GL_EXT_occlusion_query_boolean", loadProcAddress("glGenQueriesEXT"), &genQueries); + AssignGLExtensionEntryPoint(extensions, "GL_EXT_occlusion_query_boolean", loadProcAddress("glDeleteQueriesEXT"), &deleteQueries); + AssignGLExtensionEntryPoint(extensions, "GL_EXT_occlusion_query_boolean", loadProcAddress("glIsQueryEXT"), &isQuery); + AssignGLExtensionEntryPoint(extensions, "GL_EXT_occlusion_query_boolean", loadProcAddress("glBeginQueryEXT"), &beginQuery); + AssignGLExtensionEntryPoint(extensions, "GL_EXT_occlusion_query_boolean", loadProcAddress("glEndQueryEXT"), &endQuery); + AssignGLExtensionEntryPoint(extensions, "GL_EXT_occlusion_query_boolean", loadProcAddress("glGetQueryivEXT"), &getQueryiv); + AssignGLExtensionEntryPoint(extensions, "GL_EXT_occlusion_query_boolean", loadProcAddress("glGetQueryObjectuivEXT"), &getQueryObjectuiv); + + // GL_EXT_disjoint_timer_query + AssignGLExtensionEntryPoint(extensions, "GL_EXT_disjoint_timer_query", loadProcAddress("glGenQueriesEXT"), &genQueries); + AssignGLExtensionEntryPoint(extensions, "GL_EXT_disjoint_timer_query", loadProcAddress("glDeleteQueriesEXT"), &deleteQueries); + AssignGLExtensionEntryPoint(extensions, "GL_EXT_disjoint_timer_query", loadProcAddress("glIsQueryEXT"), &isQuery); + AssignGLExtensionEntryPoint(extensions, "GL_EXT_disjoint_timer_query", loadProcAddress("glBeginQueryEXT"), &beginQuery); + AssignGLExtensionEntryPoint(extensions, "GL_EXT_disjoint_timer_query", loadProcAddress("glEndQueryEXT"), &endQuery); + AssignGLExtensionEntryPoint(extensions, "GL_EXT_disjoint_timer_query", loadProcAddress("glQueryCounterEXT"), &queryCounter); + AssignGLExtensionEntryPoint(extensions, "GL_EXT_disjoint_timer_query", loadProcAddress("glGetQueryivEXT"), &getQueryiv); + AssignGLExtensionEntryPoint(extensions, "GL_EXT_disjoint_timer_query", loadProcAddress("glGetQueryObjectivEXT"), &getQueryObjectiv); + AssignGLExtensionEntryPoint(extensions, "GL_EXT_disjoint_timer_query", loadProcAddress("glGetQueryObjectuivEXT"), &getQueryObjectuiv); + AssignGLExtensionEntryPoint(extensions, "GL_EXT_disjoint_timer_query", loadProcAddress("glGetQueryObjecti64vEXT"), &getQueryObjecti64v); + AssignGLExtensionEntryPoint(extensions, "GL_EXT_disjoint_timer_query", loadProcAddress("glGetQueryObjectui64vEXT"), &getQueryObjectui64v); + + // GL_OES_EGL_image + AssignGLExtensionEntryPoint(extensions, "GL_OES_EGL_image", loadProcAddress("glEGLImageTargetRenderbufferStorageOES"), &eglImageTargetRenderbufferStorageOES); + AssignGLExtensionEntryPoint(extensions, "GL_OES_EGL_image", loadProcAddress("glEGLImageTargetTexture2DOES"), &eglImageTargetTexture2DOES); + + // 2.0 + if (isAtLeastGLES(gl::Version(2, 0))) + { + AssignGLEntryPoint(loadProcAddress("glActiveTexture"), &activeTexture); + AssignGLEntryPoint(loadProcAddress("glAttachShader"), &attachShader); + AssignGLEntryPoint(loadProcAddress("glBindAttribLocation"), &bindAttribLocation); + AssignGLEntryPoint(loadProcAddress("glBindBuffer"), &bindBuffer); + AssignGLEntryPoint(loadProcAddress("glBindFramebuffer"), &bindFramebuffer); + AssignGLEntryPoint(loadProcAddress("glBindRenderbuffer"), &bindRenderbuffer); + AssignGLEntryPoint(loadProcAddress("glBindTexture"), &bindTexture); + AssignGLEntryPoint(loadProcAddress("glBlendColor"), &blendColor); + AssignGLEntryPoint(loadProcAddress("glBlendEquation"), &blendEquation); + AssignGLEntryPoint(loadProcAddress("glBlendEquationSeparate"), &blendEquationSeparate); + AssignGLEntryPoint(loadProcAddress("glBlendFunc"), &blendFunc); + AssignGLEntryPoint(loadProcAddress("glBlendFuncSeparate"), &blendFuncSeparate); + AssignGLEntryPoint(loadProcAddress("glBufferData"), &bufferData); + AssignGLEntryPoint(loadProcAddress("glBufferSubData"), &bufferSubData); + AssignGLEntryPoint(loadProcAddress("glCheckFramebufferStatus"), &checkFramebufferStatus); + AssignGLEntryPoint(loadProcAddress("glClear"), &clear); + AssignGLEntryPoint(loadProcAddress("glClearColor"), &clearColor); + AssignGLEntryPoint(loadProcAddress("glClearDepthf"), &clearDepthf); + AssignGLEntryPoint(loadProcAddress("glClearStencil"), &clearStencil); + AssignGLEntryPoint(loadProcAddress("glColorMask"), &colorMask); + AssignGLEntryPoint(loadProcAddress("glCompileShader"), &compileShader); + AssignGLEntryPoint(loadProcAddress("glCompressedTexImage2D"), &compressedTexImage2D); + AssignGLEntryPoint(loadProcAddress("glCompressedTexSubImage2D"), &compressedTexSubImage2D); + AssignGLEntryPoint(loadProcAddress("glCopyTexImage2D"), ©TexImage2D); + AssignGLEntryPoint(loadProcAddress("glCopyTexSubImage2D"), ©TexSubImage2D); + AssignGLEntryPoint(loadProcAddress("glCreateProgram"), &createProgram); + AssignGLEntryPoint(loadProcAddress("glCreateShader"), &createShader); + AssignGLEntryPoint(loadProcAddress("glCullFace"), &cullFace); + AssignGLEntryPoint(loadProcAddress("glDeleteBuffers"), &deleteBuffers); + AssignGLEntryPoint(loadProcAddress("glDeleteFramebuffers"), &deleteFramebuffers); + AssignGLEntryPoint(loadProcAddress("glDeleteProgram"), &deleteProgram); + AssignGLEntryPoint(loadProcAddress("glDeleteRenderbuffers"), &deleteRenderbuffers); + AssignGLEntryPoint(loadProcAddress("glDeleteShader"), &deleteShader); + AssignGLEntryPoint(loadProcAddress("glDeleteTextures"), &deleteTextures); + AssignGLEntryPoint(loadProcAddress("glDepthFunc"), &depthFunc); + AssignGLEntryPoint(loadProcAddress("glDepthMask"), &depthMask); + AssignGLEntryPoint(loadProcAddress("glDepthRangef"), &depthRangef); + AssignGLEntryPoint(loadProcAddress("glDetachShader"), &detachShader); + AssignGLEntryPoint(loadProcAddress("glDisable"), &disable); + AssignGLEntryPoint(loadProcAddress("glDisableVertexAttribArray"), &disableVertexAttribArray); + AssignGLEntryPoint(loadProcAddress("glDrawArrays"), &drawArrays); + AssignGLEntryPoint(loadProcAddress("glDrawElements"), &drawElements); + AssignGLEntryPoint(loadProcAddress("glEnable"), &enable); + AssignGLEntryPoint(loadProcAddress("glEnableVertexAttribArray"), &enableVertexAttribArray); + AssignGLEntryPoint(loadProcAddress("glFinish"), &finish); + AssignGLEntryPoint(loadProcAddress("glFlush"), &flush); + AssignGLEntryPoint(loadProcAddress("glFramebufferRenderbuffer"), &framebufferRenderbuffer); + AssignGLEntryPoint(loadProcAddress("glFramebufferTexture2D"), &framebufferTexture2D); + AssignGLEntryPoint(loadProcAddress("glFrontFace"), &frontFace); + AssignGLEntryPoint(loadProcAddress("glGenBuffers"), &genBuffers); + AssignGLEntryPoint(loadProcAddress("glGenerateMipmap"), &generateMipmap); + AssignGLEntryPoint(loadProcAddress("glGenFramebuffers"), &genFramebuffers); + AssignGLEntryPoint(loadProcAddress("glGenRenderbuffers"), &genRenderbuffers); + AssignGLEntryPoint(loadProcAddress("glGenTextures"), &genTextures); + AssignGLEntryPoint(loadProcAddress("glGetActiveAttrib"), &getActiveAttrib); + AssignGLEntryPoint(loadProcAddress("glGetActiveUniform"), &getActiveUniform); + AssignGLEntryPoint(loadProcAddress("glGetAttachedShaders"), &getAttachedShaders); + AssignGLEntryPoint(loadProcAddress("glGetAttribLocation"), &getAttribLocation); + AssignGLEntryPoint(loadProcAddress("glGetBooleanv"), &getBooleanv); + AssignGLEntryPoint(loadProcAddress("glGetBufferParameteriv"), &getBufferParameteriv); + AssignGLEntryPoint(loadProcAddress("glGetError"), &getError); + AssignGLEntryPoint(loadProcAddress("glGetFloatv"), &getFloatv); + AssignGLEntryPoint(loadProcAddress("glGetFramebufferAttachmentParameteriv"), &getFramebufferAttachmentParameteriv); + AssignGLEntryPoint(loadProcAddress("glGetIntegerv"), &getIntegerv); + AssignGLEntryPoint(loadProcAddress("glGetProgramiv"), &getProgramiv); + AssignGLEntryPoint(loadProcAddress("glGetProgramInfoLog"), &getProgramInfoLog); + AssignGLEntryPoint(loadProcAddress("glGetRenderbufferParameteriv"), &getRenderbufferParameteriv); + AssignGLEntryPoint(loadProcAddress("glGetShaderiv"), &getShaderiv); + AssignGLEntryPoint(loadProcAddress("glGetShaderInfoLog"), &getShaderInfoLog); + AssignGLEntryPoint(loadProcAddress("glGetShaderPrecisionFormat"), &getShaderPrecisionFormat); + AssignGLEntryPoint(loadProcAddress("glGetShaderSource"), &getShaderSource); + AssignGLEntryPoint(loadProcAddress("glGetString"), &getString); + AssignGLEntryPoint(loadProcAddress("glGetTexParameterfv"), &getTexParameterfv); + AssignGLEntryPoint(loadProcAddress("glGetTexParameteriv"), &getTexParameteriv); + AssignGLEntryPoint(loadProcAddress("glGetUniformfv"), &getUniformfv); + AssignGLEntryPoint(loadProcAddress("glGetUniformiv"), &getUniformiv); + AssignGLEntryPoint(loadProcAddress("glGetUniformLocation"), &getUniformLocation); + AssignGLEntryPoint(loadProcAddress("glGetVertexAttribfv"), &getVertexAttribfv); + AssignGLEntryPoint(loadProcAddress("glGetVertexAttribiv"), &getVertexAttribiv); + AssignGLEntryPoint(loadProcAddress("glGetVertexAttribPointerv"), &getVertexAttribPointerv); + AssignGLEntryPoint(loadProcAddress("glHint"), &hint); + AssignGLEntryPoint(loadProcAddress("glIsBuffer"), &isBuffer); + AssignGLEntryPoint(loadProcAddress("glIsEnabled"), &isEnabled); + AssignGLEntryPoint(loadProcAddress("glIsFramebuffer"), &isFramebuffer); + AssignGLEntryPoint(loadProcAddress("glIsProgram"), &isProgram); + AssignGLEntryPoint(loadProcAddress("glIsRenderbuffer"), &isRenderbuffer); + AssignGLEntryPoint(loadProcAddress("glIsShader"), &isShader); + AssignGLEntryPoint(loadProcAddress("glIsTexture"), &isTexture); + AssignGLEntryPoint(loadProcAddress("glLineWidth"), &lineWidth); + AssignGLEntryPoint(loadProcAddress("glLinkProgram"), &linkProgram); + AssignGLEntryPoint(loadProcAddress("glPixelStorei"), &pixelStorei); + AssignGLEntryPoint(loadProcAddress("glPolygonOffset"), &polygonOffset); + AssignGLEntryPoint(loadProcAddress("glReadPixels"), &readPixels); + AssignGLEntryPoint(loadProcAddress("glReleaseShaderCompiler"), &releaseShaderCompiler); + AssignGLEntryPoint(loadProcAddress("glRenderbufferStorage"), &renderbufferStorage); + AssignGLEntryPoint(loadProcAddress("glSampleCoverage"), &sampleCoverage); + AssignGLEntryPoint(loadProcAddress("glScissor"), &scissor); + AssignGLEntryPoint(loadProcAddress("glShaderBinary"), &shaderBinary); + AssignGLEntryPoint(loadProcAddress("glShaderSource"), &shaderSource); + AssignGLEntryPoint(loadProcAddress("glStencilFunc"), &stencilFunc); + AssignGLEntryPoint(loadProcAddress("glStencilFuncSeparate"), &stencilFuncSeparate); + AssignGLEntryPoint(loadProcAddress("glStencilMask"), &stencilMask); + AssignGLEntryPoint(loadProcAddress("glStencilMaskSeparate"), &stencilMaskSeparate); + AssignGLEntryPoint(loadProcAddress("glStencilOp"), &stencilOp); + AssignGLEntryPoint(loadProcAddress("glStencilOpSeparate"), &stencilOpSeparate); + AssignGLEntryPoint(loadProcAddress("glTexImage2D"), &texImage2D); + AssignGLEntryPoint(loadProcAddress("glTexParameterf"), &texParameterf); + AssignGLEntryPoint(loadProcAddress("glTexParameterfv"), &texParameterfv); + AssignGLEntryPoint(loadProcAddress("glTexParameteri"), &texParameteri); + AssignGLEntryPoint(loadProcAddress("glTexParameteriv"), &texParameteriv); + AssignGLEntryPoint(loadProcAddress("glTexSubImage2D"), &texSubImage2D); + AssignGLEntryPoint(loadProcAddress("glUniform1f"), &uniform1f); + AssignGLEntryPoint(loadProcAddress("glUniform1fv"), &uniform1fv); + AssignGLEntryPoint(loadProcAddress("glUniform1i"), &uniform1i); + AssignGLEntryPoint(loadProcAddress("glUniform1iv"), &uniform1iv); + AssignGLEntryPoint(loadProcAddress("glUniform2f"), &uniform2f); + AssignGLEntryPoint(loadProcAddress("glUniform2fv"), &uniform2fv); + AssignGLEntryPoint(loadProcAddress("glUniform2i"), &uniform2i); + AssignGLEntryPoint(loadProcAddress("glUniform2iv"), &uniform2iv); + AssignGLEntryPoint(loadProcAddress("glUniform3f"), &uniform3f); + AssignGLEntryPoint(loadProcAddress("glUniform3fv"), &uniform3fv); + AssignGLEntryPoint(loadProcAddress("glUniform3i"), &uniform3i); + AssignGLEntryPoint(loadProcAddress("glUniform3iv"), &uniform3iv); + AssignGLEntryPoint(loadProcAddress("glUniform4f"), &uniform4f); + AssignGLEntryPoint(loadProcAddress("glUniform4fv"), &uniform4fv); + AssignGLEntryPoint(loadProcAddress("glUniform4i"), &uniform4i); + AssignGLEntryPoint(loadProcAddress("glUniform4iv"), &uniform4iv); + AssignGLEntryPoint(loadProcAddress("glUniformMatrix2fv"), &uniformMatrix2fv); + AssignGLEntryPoint(loadProcAddress("glUniformMatrix3fv"), &uniformMatrix3fv); + AssignGLEntryPoint(loadProcAddress("glUniformMatrix4fv"), &uniformMatrix4fv); + AssignGLEntryPoint(loadProcAddress("glUseProgram"), &useProgram); + AssignGLEntryPoint(loadProcAddress("glValidateProgram"), &validateProgram); + AssignGLEntryPoint(loadProcAddress("glVertexAttrib1f"), &vertexAttrib1f); + AssignGLEntryPoint(loadProcAddress("glVertexAttrib1fv"), &vertexAttrib1fv); + AssignGLEntryPoint(loadProcAddress("glVertexAttrib2f"), &vertexAttrib2f); + AssignGLEntryPoint(loadProcAddress("glVertexAttrib2fv"), &vertexAttrib2fv); + AssignGLEntryPoint(loadProcAddress("glVertexAttrib3f"), &vertexAttrib3f); + AssignGLEntryPoint(loadProcAddress("glVertexAttrib3fv"), &vertexAttrib3fv); + AssignGLEntryPoint(loadProcAddress("glVertexAttrib4f"), &vertexAttrib4f); + AssignGLEntryPoint(loadProcAddress("glVertexAttrib4fv"), &vertexAttrib4fv); + AssignGLEntryPoint(loadProcAddress("glVertexAttribPointer"), &vertexAttribPointer); + AssignGLEntryPoint(loadProcAddress("glViewport"), &viewport); + } + + // 3.0 + if (isAtLeastGLES(gl::Version(3, 0))) + { + AssignGLEntryPoint(loadProcAddress("glReadBuffer"), &readBuffer); + AssignGLEntryPoint(loadProcAddress("glDrawRangeElements"), &drawRangeElements); + AssignGLEntryPoint(loadProcAddress("glTexImage3D"), &texImage3D); + AssignGLEntryPoint(loadProcAddress("glTexSubImage3D"), &texSubImage3D); + AssignGLEntryPoint(loadProcAddress("glCopyTexSubImage3D"), ©TexSubImage3D); + AssignGLEntryPoint(loadProcAddress("glCompressedTexImage3D"), &compressedTexImage3D); + AssignGLEntryPoint(loadProcAddress("glCompressedTexSubImage3D"), &compressedTexSubImage3D); + AssignGLEntryPoint(loadProcAddress("glGenQueries"), &genQueries); + AssignGLEntryPoint(loadProcAddress("glDeleteQueries"), &deleteQueries); + AssignGLEntryPoint(loadProcAddress("glIsQuery"), &isQuery); + AssignGLEntryPoint(loadProcAddress("glBeginQuery"), &beginQuery); + AssignGLEntryPoint(loadProcAddress("glEndQuery"), &endQuery); + AssignGLEntryPoint(loadProcAddress("glGetQueryiv"), &getQueryiv); + AssignGLEntryPoint(loadProcAddress("glGetQueryObjectuiv"), &getQueryObjectuiv); + AssignGLEntryPoint(loadProcAddress("glUnmapBuffer"), &unmapBuffer); + AssignGLEntryPoint(loadProcAddress("glGetBufferPointerv"), &getBufferPointerv); + AssignGLEntryPoint(loadProcAddress("glDrawBuffers"), &drawBuffers); + AssignGLEntryPoint(loadProcAddress("glUniformMatrix2x3fv"), &uniformMatrix2x3fv); + AssignGLEntryPoint(loadProcAddress("glUniformMatrix3x2fv"), &uniformMatrix3x2fv); + AssignGLEntryPoint(loadProcAddress("glUniformMatrix2x4fv"), &uniformMatrix2x4fv); + AssignGLEntryPoint(loadProcAddress("glUniformMatrix4x2fv"), &uniformMatrix4x2fv); + AssignGLEntryPoint(loadProcAddress("glUniformMatrix3x4fv"), &uniformMatrix3x4fv); + AssignGLEntryPoint(loadProcAddress("glUniformMatrix4x3fv"), &uniformMatrix4x3fv); + AssignGLEntryPoint(loadProcAddress("glBlitFramebuffer"), &blitFramebuffer); + AssignGLEntryPoint(loadProcAddress("glRenderbufferStorageMultisample"), &renderbufferStorageMultisample); + AssignGLEntryPoint(loadProcAddress("glFramebufferTextureLayer"), &framebufferTextureLayer); + AssignGLEntryPoint(loadProcAddress("glMapBufferRange"), &mapBufferRange); + AssignGLEntryPoint(loadProcAddress("glFlushMappedBufferRange"), &flushMappedBufferRange); + AssignGLEntryPoint(loadProcAddress("glBindVertexArray"), &bindVertexArray); + AssignGLEntryPoint(loadProcAddress("glDeleteVertexArrays"), &deleteVertexArrays); + AssignGLEntryPoint(loadProcAddress("glGenVertexArrays"), &genVertexArrays); + AssignGLEntryPoint(loadProcAddress("glIsVertexArray"), &isVertexArray); + AssignGLEntryPoint(loadProcAddress("glGetIntegeri_v"), &getIntegeri_v); + AssignGLEntryPoint(loadProcAddress("glBeginTransformFeedback"), &beginTransformFeedback); + AssignGLEntryPoint(loadProcAddress("glEndTransformFeedback"), &endTransformFeedback); + AssignGLEntryPoint(loadProcAddress("glBindBufferRange"), &bindBufferRange); + AssignGLEntryPoint(loadProcAddress("glBindBufferBase"), &bindBufferBase); + AssignGLEntryPoint(loadProcAddress("glTransformFeedbackVaryings"), &transformFeedbackVaryings); + AssignGLEntryPoint(loadProcAddress("glGetTransformFeedbackVarying"), &getTransformFeedbackVarying); + AssignGLEntryPoint(loadProcAddress("glVertexAttribIPointer"), &vertexAttribIPointer); + AssignGLEntryPoint(loadProcAddress("glGetVertexAttribIiv"), &getVertexAttribIiv); + AssignGLEntryPoint(loadProcAddress("glGetVertexAttribIuiv"), &getVertexAttribIuiv); + AssignGLEntryPoint(loadProcAddress("glVertexAttribI4i"), &vertexAttribI4i); + AssignGLEntryPoint(loadProcAddress("glVertexAttribI4ui"), &vertexAttribI4ui); + AssignGLEntryPoint(loadProcAddress("glVertexAttribI4iv"), &vertexAttribI4iv); + AssignGLEntryPoint(loadProcAddress("glVertexAttribI4uiv"), &vertexAttribI4uiv); + AssignGLEntryPoint(loadProcAddress("glGetUniformuiv"), &getUniformuiv); + AssignGLEntryPoint(loadProcAddress("glGetFragDataLocation"), &getFragDataLocation); + AssignGLEntryPoint(loadProcAddress("glUniform1ui"), &uniform1ui); + AssignGLEntryPoint(loadProcAddress("glUniform2ui"), &uniform2ui); + AssignGLEntryPoint(loadProcAddress("glUniform3ui"), &uniform3ui); + AssignGLEntryPoint(loadProcAddress("glUniform4ui"), &uniform4ui); + AssignGLEntryPoint(loadProcAddress("glUniform1uiv"), &uniform1uiv); + AssignGLEntryPoint(loadProcAddress("glUniform2uiv"), &uniform2uiv); + AssignGLEntryPoint(loadProcAddress("glUniform3uiv"), &uniform3uiv); + AssignGLEntryPoint(loadProcAddress("glUniform4uiv"), &uniform4uiv); + AssignGLEntryPoint(loadProcAddress("glClearBufferiv"), &clearBufferiv); + AssignGLEntryPoint(loadProcAddress("glClearBufferuiv"), &clearBufferuiv); + AssignGLEntryPoint(loadProcAddress("glClearBufferfv"), &clearBufferfv); + AssignGLEntryPoint(loadProcAddress("glClearBufferfi"), &clearBufferfi); + AssignGLEntryPoint(loadProcAddress("glGetStringi"), &getStringi); + AssignGLEntryPoint(loadProcAddress("glCopyBufferSubData"), ©BufferSubData); + AssignGLEntryPoint(loadProcAddress("glGetUniformIndices"), &getUniformIndices); + AssignGLEntryPoint(loadProcAddress("glGetActiveUniformsiv"), &getActiveUniformsiv); + AssignGLEntryPoint(loadProcAddress("glGetUniformBlockIndex"), &getUniformBlockIndex); + AssignGLEntryPoint(loadProcAddress("glGetActiveUniformBlockiv"), &getActiveUniformBlockiv); + AssignGLEntryPoint(loadProcAddress("glGetActiveUniformBlockName"), &getActiveUniformBlockName); + AssignGLEntryPoint(loadProcAddress("glUniformBlockBinding"), &uniformBlockBinding); + AssignGLEntryPoint(loadProcAddress("glDrawArraysInstanced"), &drawArraysInstanced); + AssignGLEntryPoint(loadProcAddress("glDrawElementsInstanced"), &drawElementsInstanced); + AssignGLEntryPoint(loadProcAddress("glFenceSync"), &fenceSync); + AssignGLEntryPoint(loadProcAddress("glIsSync"), &isSync); + AssignGLEntryPoint(loadProcAddress("glDeleteSync"), &deleteSync); + AssignGLEntryPoint(loadProcAddress("glClientWaitSync"), &clientWaitSync); + AssignGLEntryPoint(loadProcAddress("glWaitSync"), &waitSync); + AssignGLEntryPoint(loadProcAddress("glGetInteger64v"), &getInteger64v); + AssignGLEntryPoint(loadProcAddress("glGetSynciv"), &getSynciv); + AssignGLEntryPoint(loadProcAddress("glGetInteger64i_v"), &getInteger64i_v); + AssignGLEntryPoint(loadProcAddress("glGetBufferParameteri64v"), &getBufferParameteri64v); + AssignGLEntryPoint(loadProcAddress("glGenSamplers"), &genSamplers); + AssignGLEntryPoint(loadProcAddress("glDeleteSamplers"), &deleteSamplers); + AssignGLEntryPoint(loadProcAddress("glIsSampler"), &isSampler); + AssignGLEntryPoint(loadProcAddress("glBindSampler"), &bindSampler); + AssignGLEntryPoint(loadProcAddress("glSamplerParameteri"), &samplerParameteri); + AssignGLEntryPoint(loadProcAddress("glSamplerParameteriv"), &samplerParameteriv); + AssignGLEntryPoint(loadProcAddress("glSamplerParameterf"), &samplerParameterf); + AssignGLEntryPoint(loadProcAddress("glSamplerParameterfv"), &samplerParameterfv); + AssignGLEntryPoint(loadProcAddress("glGetSamplerParameteriv"), &getSamplerParameteriv); + AssignGLEntryPoint(loadProcAddress("glGetSamplerParameterfv"), &getSamplerParameterfv); + AssignGLEntryPoint(loadProcAddress("glVertexAttribDivisor"), &vertexAttribDivisor); + AssignGLEntryPoint(loadProcAddress("glBindTransformFeedback"), &bindTransformFeedback); + AssignGLEntryPoint(loadProcAddress("glDeleteTransformFeedbacks"), &deleteTransformFeedbacks); + AssignGLEntryPoint(loadProcAddress("glGenTransformFeedbacks"), &genTransformFeedbacks); + AssignGLEntryPoint(loadProcAddress("glIsTransformFeedback"), &isTransformFeedback); + AssignGLEntryPoint(loadProcAddress("glPauseTransformFeedback"), &pauseTransformFeedback); + AssignGLEntryPoint(loadProcAddress("glResumeTransformFeedback"), &resumeTransformFeedback); + AssignGLEntryPoint(loadProcAddress("glGetProgramBinary"), &getProgramBinary); + AssignGLEntryPoint(loadProcAddress("glProgramBinary"), &programBinary); + AssignGLEntryPoint(loadProcAddress("glProgramParameteri"), &programParameteri); + AssignGLEntryPoint(loadProcAddress("glInvalidateFramebuffer"), &invalidateFramebuffer); + AssignGLEntryPoint(loadProcAddress("glInvalidateSubFramebuffer"), &invalidateSubFramebuffer); + AssignGLEntryPoint(loadProcAddress("glTexStorage2D"), &texStorage2D); + AssignGLEntryPoint(loadProcAddress("glTexStorage3D"), &texStorage3D); + AssignGLEntryPoint(loadProcAddress("glGetInternalformativ"), &getInternalformativ); + } + + // 3.1 + if (isAtLeastGLES(gl::Version(3, 1))) + { + AssignGLEntryPoint(loadProcAddress("glDispatchCompute"), &dispatchCompute); + AssignGLEntryPoint(loadProcAddress("glDispatchComputeIndirect"), &dispatchComputeIndirect); + AssignGLEntryPoint(loadProcAddress("glDrawArraysIndirect"), &drawArraysIndirect); + AssignGLEntryPoint(loadProcAddress("glDrawElementsIndirect"), &drawElementsIndirect); + AssignGLEntryPoint(loadProcAddress("glFramebufferParameteri"), &framebufferParameteri); + AssignGLEntryPoint(loadProcAddress("glGetFramebufferParameteriv"), &getFramebufferParameteriv); + AssignGLEntryPoint(loadProcAddress("glGetProgramInterfaceiv"), &getProgramInterfaceiv); + AssignGLEntryPoint(loadProcAddress("glGetProgramResourceIndex"), &getProgramResourceIndex); + AssignGLEntryPoint(loadProcAddress("glGetProgramResourceName"), &getProgramResourceName); + AssignGLEntryPoint(loadProcAddress("glGetProgramResourceiv"), &getProgramResourceiv); + AssignGLEntryPoint(loadProcAddress("glGetProgramResourceLocation"), &getProgramResourceLocation); + AssignGLEntryPoint(loadProcAddress("glUseProgramStages"), &useProgramStages); + AssignGLEntryPoint(loadProcAddress("glActiveShaderProgram"), &activeShaderProgram); + AssignGLEntryPoint(loadProcAddress("glCreateShaderProgramv"), &createShaderProgramv); + AssignGLEntryPoint(loadProcAddress("glBindProgramPipeline"), &bindProgramPipeline); + AssignGLEntryPoint(loadProcAddress("glDeleteProgramPipelines"), &deleteProgramPipelines); + AssignGLEntryPoint(loadProcAddress("glGenProgramPipelines"), &genProgramPipelines); + AssignGLEntryPoint(loadProcAddress("glIsProgramPipeline"), &isProgramPipeline); + AssignGLEntryPoint(loadProcAddress("glGetProgramPipelineiv"), &getProgramPipelineiv); + AssignGLEntryPoint(loadProcAddress("glProgramUniform1i"), &programUniform1i); + AssignGLEntryPoint(loadProcAddress("glProgramUniform2i"), &programUniform2i); + AssignGLEntryPoint(loadProcAddress("glProgramUniform3i"), &programUniform3i); + AssignGLEntryPoint(loadProcAddress("glProgramUniform4i"), &programUniform4i); + AssignGLEntryPoint(loadProcAddress("glProgramUniform1ui"), &programUniform1ui); + AssignGLEntryPoint(loadProcAddress("glProgramUniform2ui"), &programUniform2ui); + AssignGLEntryPoint(loadProcAddress("glProgramUniform3ui"), &programUniform3ui); + AssignGLEntryPoint(loadProcAddress("glProgramUniform4ui"), &programUniform4ui); + AssignGLEntryPoint(loadProcAddress("glProgramUniform1f"), &programUniform1f); + AssignGLEntryPoint(loadProcAddress("glProgramUniform2f"), &programUniform2f); + AssignGLEntryPoint(loadProcAddress("glProgramUniform3f"), &programUniform3f); + AssignGLEntryPoint(loadProcAddress("glProgramUniform4f"), &programUniform4f); + AssignGLEntryPoint(loadProcAddress("glProgramUniform1iv"), &programUniform1iv); + AssignGLEntryPoint(loadProcAddress("glProgramUniform2iv"), &programUniform2iv); + AssignGLEntryPoint(loadProcAddress("glProgramUniform3iv"), &programUniform3iv); + AssignGLEntryPoint(loadProcAddress("glProgramUniform4iv"), &programUniform4iv); + AssignGLEntryPoint(loadProcAddress("glProgramUniform1uiv"), &programUniform1uiv); + AssignGLEntryPoint(loadProcAddress("glProgramUniform2uiv"), &programUniform2uiv); + AssignGLEntryPoint(loadProcAddress("glProgramUniform3uiv"), &programUniform3uiv); + AssignGLEntryPoint(loadProcAddress("glProgramUniform4uiv"), &programUniform4uiv); + AssignGLEntryPoint(loadProcAddress("glProgramUniform1fv"), &programUniform1fv); + AssignGLEntryPoint(loadProcAddress("glProgramUniform2fv"), &programUniform2fv); + AssignGLEntryPoint(loadProcAddress("glProgramUniform3fv"), &programUniform3fv); + AssignGLEntryPoint(loadProcAddress("glProgramUniform4fv"), &programUniform4fv); + AssignGLEntryPoint(loadProcAddress("glProgramUniformMatrix2fv"), &programUniformMatrix2fv); + AssignGLEntryPoint(loadProcAddress("glProgramUniformMatrix3fv"), &programUniformMatrix3fv); + AssignGLEntryPoint(loadProcAddress("glProgramUniformMatrix4fv"), &programUniformMatrix4fv); + AssignGLEntryPoint(loadProcAddress("glProgramUniformMatrix2x3fv"), &programUniformMatrix2x3fv); + AssignGLEntryPoint(loadProcAddress("glProgramUniformMatrix3x2fv"), &programUniformMatrix3x2fv); + AssignGLEntryPoint(loadProcAddress("glProgramUniformMatrix2x4fv"), &programUniformMatrix2x4fv); + AssignGLEntryPoint(loadProcAddress("glProgramUniformMatrix4x2fv"), &programUniformMatrix4x2fv); + AssignGLEntryPoint(loadProcAddress("glProgramUniformMatrix3x4fv"), &programUniformMatrix3x4fv); + AssignGLEntryPoint(loadProcAddress("glProgramUniformMatrix4x3fv"), &programUniformMatrix4x3fv); + AssignGLEntryPoint(loadProcAddress("glValidateProgramPipeline"), &validateProgramPipeline); + AssignGLEntryPoint(loadProcAddress("glGetProgramPipelineInfoLog"), &getProgramPipelineInfoLog); + AssignGLEntryPoint(loadProcAddress("glBindImageTexture"), &bindImageTexture); + AssignGLEntryPoint(loadProcAddress("glGetBooleani_v"), &getBooleani_v); + AssignGLEntryPoint(loadProcAddress("glMemoryBarrier"), &memoryBarrier); + AssignGLEntryPoint(loadProcAddress("glMemoryBarrierByRegion"), &memoryBarrierByRegion); + AssignGLEntryPoint(loadProcAddress("glTexStorage2DMultisample"), &texStorage2DMultisample); + AssignGLEntryPoint(loadProcAddress("glGetMultisamplefv"), &getMultisamplefv); + AssignGLEntryPoint(loadProcAddress("glSampleMaski"), &sampleMaski); + AssignGLEntryPoint(loadProcAddress("glGetTexLevelParameteriv"), &getTexLevelParameteriv); + AssignGLEntryPoint(loadProcAddress("glGetTexLevelParameterfv"), &getTexLevelParameterfv); + AssignGLEntryPoint(loadProcAddress("glBindVertexBuffer"), &bindVertexBuffer); + AssignGLEntryPoint(loadProcAddress("glVertexAttribFormat"), &vertexAttribFormat); + AssignGLEntryPoint(loadProcAddress("glVertexAttribIFormat"), &vertexAttribIFormat); + AssignGLEntryPoint(loadProcAddress("glVertexAttribBinding"), &vertexAttribBinding); + AssignGLEntryPoint(loadProcAddress("glVertexBindingDivisor"), &vertexBindingDivisor); + } + + // 3.2 + if (isAtLeastGLES(gl::Version(3, 2))) + { + AssignGLEntryPoint(loadProcAddress("glBlendBarrier"), &blendBarrier); + AssignGLEntryPoint(loadProcAddress("glCopyImageSubData"), ©ImageSubData); + AssignGLEntryPoint(loadProcAddress("glDebugMessageControl"), &debugMessageControl); + AssignGLEntryPoint(loadProcAddress("glDebugMessageInsert"), &debugMessageInsert); + AssignGLEntryPoint(loadProcAddress("glDebugMessageCallback"), &debugMessageCallback); + AssignGLEntryPoint(loadProcAddress("glGetDebugMessageLog"), &getDebugMessageLog); + AssignGLEntryPoint(loadProcAddress("glPushDebugGroup"), &pushDebugGroup); + AssignGLEntryPoint(loadProcAddress("glPopDebugGroup"), &popDebugGroup); + AssignGLEntryPoint(loadProcAddress("glObjectLabel"), &objectLabel); + AssignGLEntryPoint(loadProcAddress("glGetObjectLabel"), &getObjectLabel); + AssignGLEntryPoint(loadProcAddress("glObjectPtrLabel"), &objectPtrLabel); + AssignGLEntryPoint(loadProcAddress("glGetObjectPtrLabel"), &getObjectPtrLabel); + AssignGLEntryPoint(loadProcAddress("glGetPointerv"), &getPointerv); + AssignGLEntryPoint(loadProcAddress("glEnablei"), &enablei); + AssignGLEntryPoint(loadProcAddress("glDisablei"), &disablei); + AssignGLEntryPoint(loadProcAddress("glBlendEquationi"), &blendEquationi); + AssignGLEntryPoint(loadProcAddress("glBlendEquationSeparatei"), &blendEquationSeparatei); + AssignGLEntryPoint(loadProcAddress("glBlendFunci"), &blendFunci); + AssignGLEntryPoint(loadProcAddress("glBlendFuncSeparatei"), &blendFuncSeparatei); + AssignGLEntryPoint(loadProcAddress("glColorMaski"), &colorMaski); + AssignGLEntryPoint(loadProcAddress("glIsEnabledi"), &isEnabledi); + AssignGLEntryPoint(loadProcAddress("glDrawElementsBaseVertex"), &drawElementsBaseVertex); + AssignGLEntryPoint(loadProcAddress("glDrawRangeElementsBaseVertex"), &drawRangeElementsBaseVertex); + AssignGLEntryPoint(loadProcAddress("glDrawElementsInstancedBaseVertex"), &drawElementsInstancedBaseVertex); + AssignGLEntryPoint(loadProcAddress("glFramebufferTexture"), &framebufferTexture); + AssignGLEntryPoint(loadProcAddress("glPrimitiveBoundingBox"), &primitiveBoundingBox); + AssignGLEntryPoint(loadProcAddress("glGetGraphicsResetStatus"), &getGraphicsResetStatus); + AssignGLEntryPoint(loadProcAddress("glReadnPixels"), &readnPixels); + AssignGLEntryPoint(loadProcAddress("glGetnUniformfv"), &getnUniformfv); + AssignGLEntryPoint(loadProcAddress("glGetnUniformiv"), &getnUniformiv); + AssignGLEntryPoint(loadProcAddress("glGetnUniformuiv"), &getnUniformuiv); + AssignGLEntryPoint(loadProcAddress("glMinSampleShading"), &minSampleShading); + AssignGLEntryPoint(loadProcAddress("glPatchParameteri"), &patchParameteri); + AssignGLEntryPoint(loadProcAddress("glTexParameterIiv"), &texParameterIiv); + AssignGLEntryPoint(loadProcAddress("glTexParameterIuiv"), &texParameterIuiv); + AssignGLEntryPoint(loadProcAddress("glGetTexParameterIiv"), &getTexParameterIiv); + AssignGLEntryPoint(loadProcAddress("glGetTexParameterIuiv"), &getTexParameterIuiv); + AssignGLEntryPoint(loadProcAddress("glSamplerParameterIiv"), &samplerParameterIiv); + AssignGLEntryPoint(loadProcAddress("glSamplerParameterIuiv"), &samplerParameterIuiv); + AssignGLEntryPoint(loadProcAddress("glGetSamplerParameterIiv"), &getSamplerParameterIiv); + AssignGLEntryPoint(loadProcAddress("glGetSamplerParameterIuiv"), &getSamplerParameterIuiv); + AssignGLEntryPoint(loadProcAddress("glTexBuffer"), &texBuffer); + AssignGLEntryPoint(loadProcAddress("glTexBufferRange"), &texBufferRange); + AssignGLEntryPoint(loadProcAddress("glTexStorage3DMultisample"), &texStorage3DMultisample); + } + + // clang-format on +} + +bool FunctionsGL::isAtLeastGL(const gl::Version &glVersion) const +{ + return standard == STANDARD_GL_DESKTOP && version >= glVersion; +} + +bool FunctionsGL::isAtLeastGLES(const gl::Version &glesVersion) const +{ + return standard == STANDARD_GL_ES && version >= glesVersion; +} + +bool FunctionsGL::hasExtension(const std::string &ext) const +{ + return std::find(extensions.begin(), extensions.end(), ext) != extensions.end(); +} + +bool FunctionsGL::hasGLExtension(const std::string &ext) const +{ + return standard == STANDARD_GL_DESKTOP && hasExtension(ext); +} + +bool FunctionsGL::hasGLESExtension(const std::string &ext) const +{ + return standard == STANDARD_GL_ES && hasExtension(ext); } } diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/FunctionsGL.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/FunctionsGL.h index bf6c2bf2e21c..c33c1a01c53f 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/FunctionsGL.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/FunctionsGL.h @@ -10,12 +10,19 @@ #define LIBANGLE_RENDERER_GL_FUNCTIONSGL_H_ #include "common/debug.h" +#include "libANGLE/Version.h" #include "libANGLE/renderer/gl/functionsgl_enums.h" #include "libANGLE/renderer/gl/functionsgl_typedefs.h" namespace rx { +enum StandardGL +{ + STANDARD_GL_DESKTOP, + STANDARD_GL_ES, +}; + class FunctionsGL { public: @@ -25,12 +32,17 @@ class FunctionsGL void initialize(); // Version information - GLuint majorVersion; - GLuint minorVersion; - bool openGLES; + gl::Version version; + StandardGL standard; + GLint profile; + bool isAtLeastGL(const gl::Version &glVersion) const; + bool isAtLeastGLES(const gl::Version &glesVersion) const; // Extensions std::vector extensions; + bool hasExtension(const std::string &ext) const; + bool hasGLExtension(const std::string &ext) const; + bool hasGLESExtension(const std::string &ext) const; // Entry Points // 1.0 @@ -576,6 +588,7 @@ class FunctionsGL PFNGLGETDEBUGMESSAGELOGPROC getDebugMessageLog; PFNGLGETFRAMEBUFFERPARAMETERIVPROC getFramebufferParameteriv; PFNGLGETINTERNALFORMATI64VPROC getInternalformati64v; + PFNGLGETPOINTERVPROC getPointerv; PFNGLGETOBJECTLABELPROC getObjectLabel; PFNGLGETOBJECTPTRLABELPROC getObjectPtrLabel; PFNGLGETPROGRAMINTERFACEIVPROC getProgramInterfaceiv; @@ -730,7 +743,18 @@ class FunctionsGL PFNGLVERTEXARRAYVERTEXBUFFERPROC vertexArrayVertexBuffer; PFNGLVERTEXARRAYVERTEXBUFFERSPROC vertexArrayVertexBuffers; + // ES 3.2 + PFNGLBLENDBARRIERPROC blendBarrier; + PFNGLPRIMITIVEBOUNDINGBOXPROC primitiveBoundingBox; + + // ES extensions + PFNGLEGLIMAGETARGETRENDERBUFFERSTORAGEOESPROC eglImageTargetRenderbufferStorageOES; + PFNGLEGLIMAGETARGETTEXTURE2DOESPROC eglImageTargetTexture2DOES; + private: + void initializeProcsDesktopGL(); + void initializeProcsGLES(); + virtual void *loadProcAddress(const std::string &function) = 0; }; diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/ProgramGL.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/ProgramGL.cpp index debbec71a81c..71d73fd446e0 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/ProgramGL.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/ProgramGL.cpp @@ -13,51 +13,32 @@ #include "libANGLE/renderer/gl/FunctionsGL.h" #include "libANGLE/renderer/gl/ShaderGL.h" #include "libANGLE/renderer/gl/StateManagerGL.h" +#include "libANGLE/renderer/gl/WorkaroundsGL.h" +#include "platform/Platform.h" namespace rx { -ProgramGL::ProgramGL(const FunctionsGL *functions, StateManagerGL *stateManager) - : ProgramImpl(), +ProgramGL::ProgramGL(const gl::Program::Data &data, + const FunctionsGL *functions, + const WorkaroundsGL &workarounds, + StateManagerGL *stateManager) + : ProgramImpl(data), mFunctions(functions), + mWorkarounds(workarounds), mStateManager(stateManager), mProgramID(0) { ASSERT(mFunctions); ASSERT(mStateManager); -} - -ProgramGL::~ProgramGL() -{ - if (mProgramID != 0) - { - mFunctions->deleteProgram(mProgramID); - mProgramID = 0; - } -} - -bool ProgramGL::usesPointSize() const -{ - UNIMPLEMENTED(); - return bool(); -} - -int ProgramGL::getShaderVersion() const -{ - UNIMPLEMENTED(); - return int(); -} -GLenum ProgramGL::getTransformFeedbackBufferMode() const -{ - UNIMPLEMENTED(); - return GLenum(); + mProgramID = mFunctions->createProgram(); } -GLenum ProgramGL::getBinaryFormat() +ProgramGL::~ProgramGL() { - UNIMPLEMENTED(); - return GLenum(); + mFunctions->deleteProgram(mProgramID); + mProgramID = 0; } LinkResult ProgramGL::load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream) @@ -72,170 +53,213 @@ gl::Error ProgramGL::save(gl::BinaryOutputStream *stream) return gl::Error(GL_INVALID_OPERATION); } -LinkResult ProgramGL::link(const gl::Data &data, gl::InfoLog &infoLog, - gl::Shader *fragmentShader, gl::Shader *vertexShader, - const std::vector &transformFeedbackVaryings, - GLenum transformFeedbackBufferMode, - int *registers, std::vector *linkedVaryings, - std::map *outputVariables) +void ProgramGL::setBinaryRetrievableHint(bool retrievable) +{ + UNIMPLEMENTED(); +} + +LinkResult ProgramGL::link(const gl::Data &data, gl::InfoLog &infoLog) { // Reset the program state, delete the current program if one exists reset(); - ShaderGL *vertexShaderGL = GetImplAs(vertexShader); - ShaderGL *fragmentShaderGL = GetImplAs(fragmentShader); + // Set the transform feedback state + std::vector transformFeedbackVaryings; + for (const auto &tfVarying : mData.getTransformFeedbackVaryingNames()) + { + transformFeedbackVaryings.push_back(tfVarying.c_str()); + } - // Generate a new program, make sure one doesn't already exist - ASSERT(mProgramID == 0); - mProgramID = mFunctions->createProgram(); + if (transformFeedbackVaryings.empty()) + { + if (mFunctions->transformFeedbackVaryings) + { + mFunctions->transformFeedbackVaryings(mProgramID, 0, nullptr, + mData.getTransformFeedbackBufferMode()); + } + } + else + { + ASSERT(mFunctions->transformFeedbackVaryings); + mFunctions->transformFeedbackVaryings( + mProgramID, static_cast(transformFeedbackVaryings.size()), + &transformFeedbackVaryings[0], mData.getTransformFeedbackBufferMode()); + } + + const gl::Shader *vertexShader = mData.getAttachedVertexShader(); + const gl::Shader *fragmentShader = mData.getAttachedFragmentShader(); + + const ShaderGL *vertexShaderGL = GetImplAs(vertexShader); + const ShaderGL *fragmentShaderGL = GetImplAs(fragmentShader); // Attach the shaders mFunctions->attachShader(mProgramID, vertexShaderGL->getShaderID()); mFunctions->attachShader(mProgramID, fragmentShaderGL->getShaderID()); - // TODO: bind attribute locations? + // Bind attribute locations to match the GL layer. + for (const sh::Attribute &attribute : mData.getAttributes()) + { + if (!attribute.staticUse) + { + continue; + } + + mFunctions->bindAttribLocation(mProgramID, attribute.location, attribute.name.c_str()); + } // Link and verify mFunctions->linkProgram(mProgramID); + // Detach the shaders + mFunctions->detachShader(mProgramID, vertexShaderGL->getShaderID()); + mFunctions->detachShader(mProgramID, fragmentShaderGL->getShaderID()); + + // Verify the link GLint linkStatus = GL_FALSE; mFunctions->getProgramiv(mProgramID, GL_LINK_STATUS, &linkStatus); - ASSERT(linkStatus == GL_TRUE); if (linkStatus == GL_FALSE) { // Linking failed, put the error into the info log GLint infoLogLength = 0; mFunctions->getProgramiv(mProgramID, GL_INFO_LOG_LENGTH, &infoLogLength); - std::vector buf(infoLogLength); - mFunctions->getProgramInfoLog(mProgramID, infoLogLength, nullptr, &buf[0]); + std::string warning; - mFunctions->deleteProgram(mProgramID); - mProgramID = 0; + // Info log length includes the null terminator, so 1 means that the info log is an empty + // string. + if (infoLogLength > 1) + { + std::vector buf(infoLogLength); + mFunctions->getProgramInfoLog(mProgramID, infoLogLength, nullptr, &buf[0]); - infoLog.append(&buf[0]); - TRACE("\n%s", &buf[0]); + mFunctions->deleteProgram(mProgramID); + mProgramID = 0; + + infoLog << buf.data(); + + warning = FormatString("Program link failed unexpectedly: %s", buf.data()); + } + else + { + warning = "Program link failed unexpectedly with no info log."; + } + ANGLEPlatformCurrent()->logWarning(warning.c_str()); + TRACE("\n%s", warning.c_str()); // TODO, return GL_OUT_OF_MEMORY or just fail the link? This is an unexpected case return LinkResult(false, gl::Error(GL_NO_ERROR)); } - // Query the uniform information - // TODO: A lot of this logic should be done at the gl::Program level - GLint activeUniformMaxLength = 0; - mFunctions->getProgramiv(mProgramID, GL_ACTIVE_UNIFORM_MAX_LENGTH, &activeUniformMaxLength); - - std::vector uniformNameBuffer(activeUniformMaxLength); - - GLint uniformCount = 0; - mFunctions->getProgramiv(mProgramID, GL_ACTIVE_UNIFORMS, &uniformCount); - for (GLint i = 0; i < uniformCount; i++) + if (mWorkarounds.alwaysCallUseProgramAfterLink) { - GLsizei uniformNameLength = 0; - GLint uniformSize = 0; - GLenum uniformType = GL_NONE; - mFunctions->getActiveUniform(mProgramID, i, uniformNameBuffer.size(), &uniformNameLength, &uniformSize, &uniformType, &uniformNameBuffer[0]); - - std::string uniformName = gl::ParseUniformName(std::string(&uniformNameBuffer[0], uniformNameLength), nullptr); + mStateManager->forceUseProgram(mProgramID); + } - for (size_t arrayIndex = 0; arrayIndex < static_cast(uniformSize); arrayIndex++) + // Query the uniform information + ASSERT(mUniformRealLocationMap.empty()); + const auto &uniforms = mData.getUniforms(); + for (const gl::VariableLocation &entry : mData.getUniformLocations()) + { + // From the spec: + // "Locations for sequential array indices are not required to be sequential." + const gl::LinkedUniform &uniform = uniforms[entry.index]; + std::stringstream fullNameStr; + fullNameStr << uniform.name; + if (uniform.isArray()) { - std::string locationName = uniformName; - if (uniformSize > 1) - { - locationName += "[" + Str(arrayIndex) + "]"; - } - - GLint location = mFunctions->getUniformLocation(mProgramID, locationName.c_str()); - if (location >= 0) - { - // Make sure the uniform index array is large enough - if (static_cast(location) >= mUniformIndex.size()) - { - mUniformIndex.resize(location + 1); - } - - mUniformIndex[location] = gl::VariableLocation(uniformName, arrayIndex, static_cast(mUniforms.size())); - } + fullNameStr << "[" << entry.element << "]"; } + const std::string &fullName = fullNameStr.str(); - // ANGLE uses 0 to identify an non-array uniform. - unsigned int arraySize = (uniformSize > 1) ? static_cast(uniformSize) : 0; - - // TODO: determine uniform precision - mUniforms.push_back(new gl::LinkedUniform(uniformType, GL_NONE, uniformName, arraySize, -1, sh::BlockMemberInfo::getDefaultBlockInfo())); + GLint realLocation = mFunctions->getUniformLocation(mProgramID, fullName.c_str()); + mUniformRealLocationMap.push_back(realLocation); } - // Query the attribute information - GLint activeAttributeMaxLength = 0; - mFunctions->getProgramiv(mProgramID, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &activeAttributeMaxLength); + mUniformIndexToSamplerIndex.resize(mData.getUniforms().size(), GL_INVALID_INDEX); - std::vector attributeNameBuffer(activeAttributeMaxLength); - - GLint attributeCount = 0; - mFunctions->getProgramiv(mProgramID, GL_ACTIVE_ATTRIBUTES, &attributeCount); - for (GLint i = 0; i < attributeCount; i++) + for (size_t uniformId = 0; uniformId < uniforms.size(); ++uniformId) { - GLsizei attributeNameLength = 0; - GLint attributeSize = 0; - GLenum attributeType = GL_NONE; - mFunctions->getActiveAttrib(mProgramID, i, attributeNameBuffer.size(), &attributeNameLength, &attributeSize, &attributeType, &attributeNameBuffer[0]); + const gl::LinkedUniform &linkedUniform = uniforms[uniformId]; + + if (!linkedUniform.isSampler() || !linkedUniform.staticUse) + continue; - std::string attributeName(&attributeNameBuffer[0], attributeNameLength); + mUniformIndexToSamplerIndex[uniformId] = mSamplerBindings.size(); - // TODO: determine attribute precision - setShaderAttribute(static_cast(i), attributeType, GL_NONE, attributeName, attributeSize, i); + // If uniform is a sampler type, insert it into the mSamplerBindings array + SamplerBindingGL samplerBinding; + samplerBinding.textureType = gl::SamplerTypeToTextureType(linkedUniform.type); + samplerBinding.boundTextureUnits.resize(linkedUniform.elementCount(), 0); + mSamplerBindings.push_back(samplerBinding); } return LinkResult(true, gl::Error(GL_NO_ERROR)); } +GLboolean ProgramGL::validate(const gl::Caps & /*caps*/, gl::InfoLog * /*infoLog*/) +{ + // TODO(jmadill): implement validate + return true; +} + void ProgramGL::setUniform1fv(GLint location, GLsizei count, const GLfloat *v) { mStateManager->useProgram(mProgramID); - mFunctions->uniform1fv(location, count, v); + mFunctions->uniform1fv(uniLoc(location), count, v); } void ProgramGL::setUniform2fv(GLint location, GLsizei count, const GLfloat *v) { mStateManager->useProgram(mProgramID); - mFunctions->uniform2fv(location, count, v); + mFunctions->uniform2fv(uniLoc(location), count, v); } void ProgramGL::setUniform3fv(GLint location, GLsizei count, const GLfloat *v) { mStateManager->useProgram(mProgramID); - mFunctions->uniform3fv(location, count, v); + mFunctions->uniform3fv(uniLoc(location), count, v); } void ProgramGL::setUniform4fv(GLint location, GLsizei count, const GLfloat *v) { mStateManager->useProgram(mProgramID); - mFunctions->uniform4fv(location, count, v); + mFunctions->uniform4fv(uniLoc(location), count, v); } void ProgramGL::setUniform1iv(GLint location, GLsizei count, const GLint *v) { mStateManager->useProgram(mProgramID); - mFunctions->uniform1iv(location, count, v); + mFunctions->uniform1iv(uniLoc(location), count, v); + + const gl::VariableLocation &locationEntry = mData.getUniformLocations()[location]; + + size_t samplerIndex = mUniformIndexToSamplerIndex[locationEntry.index]; + if (samplerIndex != GL_INVALID_INDEX) + { + std::vector &boundTextureUnits = mSamplerBindings[samplerIndex].boundTextureUnits; + + size_t copyCount = + std::max(count, boundTextureUnits.size() - locationEntry.element); + std::copy(v, v + copyCount, boundTextureUnits.begin() + locationEntry.element); + } } void ProgramGL::setUniform2iv(GLint location, GLsizei count, const GLint *v) { mStateManager->useProgram(mProgramID); - mFunctions->uniform2iv(location, count, v); + mFunctions->uniform2iv(uniLoc(location), count, v); } void ProgramGL::setUniform3iv(GLint location, GLsizei count, const GLint *v) { mStateManager->useProgram(mProgramID); - mFunctions->uniform3iv(location, count, v); + mFunctions->uniform3iv(uniLoc(location), count, v); } void ProgramGL::setUniform4iv(GLint location, GLsizei count, const GLint *v) { mStateManager->useProgram(mProgramID); - mFunctions->uniform4iv(location, count, v); + mFunctions->uniform4iv(uniLoc(location), count, v); } void ProgramGL::setUniform1uiv(GLint location, GLsizei count, const GLuint *v) @@ -247,173 +271,158 @@ void ProgramGL::setUniform1uiv(GLint location, GLsizei count, const GLuint *v) void ProgramGL::setUniform2uiv(GLint location, GLsizei count, const GLuint *v) { mStateManager->useProgram(mProgramID); - mFunctions->uniform2uiv(location, count, v); + mFunctions->uniform2uiv(uniLoc(location), count, v); } void ProgramGL::setUniform3uiv(GLint location, GLsizei count, const GLuint *v) { mStateManager->useProgram(mProgramID); - mFunctions->uniform3uiv(location, count, v); + mFunctions->uniform3uiv(uniLoc(location), count, v); } void ProgramGL::setUniform4uiv(GLint location, GLsizei count, const GLuint *v) { mStateManager->useProgram(mProgramID); - mFunctions->uniform4uiv(location, count, v); + mFunctions->uniform4uiv(uniLoc(location), count, v); } void ProgramGL::setUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) { mStateManager->useProgram(mProgramID); - mFunctions->uniformMatrix2fv(location, count, transpose, value); + mFunctions->uniformMatrix2fv(uniLoc(location), count, transpose, value); } void ProgramGL::setUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) { mStateManager->useProgram(mProgramID); - mFunctions->uniformMatrix3fv(location, count, transpose, value); + mFunctions->uniformMatrix3fv(uniLoc(location), count, transpose, value); } void ProgramGL::setUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) { mStateManager->useProgram(mProgramID); - mFunctions->uniformMatrix4fv(location, count, transpose, value); + mFunctions->uniformMatrix4fv(uniLoc(location), count, transpose, value); } void ProgramGL::setUniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) { mStateManager->useProgram(mProgramID); - mFunctions->uniformMatrix2x3fv(location, count, transpose, value); + mFunctions->uniformMatrix2x3fv(uniLoc(location), count, transpose, value); } void ProgramGL::setUniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) { mStateManager->useProgram(mProgramID); - mFunctions->uniformMatrix3x2fv(location, count, transpose, value); + mFunctions->uniformMatrix3x2fv(uniLoc(location), count, transpose, value); } void ProgramGL::setUniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) { mStateManager->useProgram(mProgramID); - mFunctions->uniformMatrix2x4fv(location, count, transpose, value); + mFunctions->uniformMatrix2x4fv(uniLoc(location), count, transpose, value); } void ProgramGL::setUniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) { mStateManager->useProgram(mProgramID); - mFunctions->uniformMatrix4x2fv(location, count, transpose, value); + mFunctions->uniformMatrix4x2fv(uniLoc(location), count, transpose, value); } void ProgramGL::setUniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) { mStateManager->useProgram(mProgramID); - mFunctions->uniformMatrix3x4fv(location, count, transpose, value); + mFunctions->uniformMatrix3x4fv(uniLoc(location), count, transpose, value); } void ProgramGL::setUniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) { mStateManager->useProgram(mProgramID); - mFunctions->uniformMatrix4x3fv(location, count, transpose, value); + mFunctions->uniformMatrix4x3fv(uniLoc(location), count, transpose, value); } -void ProgramGL::getUniformfv(GLint location, GLfloat *params) +void ProgramGL::setUniformBlockBinding(GLuint uniformBlockIndex, GLuint uniformBlockBinding) { - mFunctions->getUniformfv(mProgramID, location, params); -} - -void ProgramGL::getUniformiv(GLint location, GLint *params) -{ - mFunctions->getUniformiv(mProgramID, location, params); -} - -void ProgramGL::getUniformuiv(GLint location, GLuint *params) -{ - mFunctions->getUniformuiv(mProgramID, location, params); -} + // Lazy init + if (mUniformBlockRealLocationMap.empty()) + { + mUniformBlockRealLocationMap.reserve(mData.getUniformBlocks().size()); + for (const gl::UniformBlock &uniformBlock : mData.getUniformBlocks()) + { + const std::string &nameWithIndex = uniformBlock.nameWithArrayIndex(); + GLuint blockIndex = mFunctions->getUniformBlockIndex(mProgramID, nameWithIndex.c_str()); + mUniformBlockRealLocationMap.push_back(blockIndex); + } + } -GLint ProgramGL::getSamplerMapping(gl::SamplerType type, unsigned int samplerIndex, const gl::Caps &caps) const -{ - UNIMPLEMENTED(); - return GLint(); + GLuint realBlockIndex = mUniformBlockRealLocationMap[uniformBlockIndex]; + if (realBlockIndex != GL_INVALID_INDEX) + { + mFunctions->uniformBlockBinding(mProgramID, realBlockIndex, uniformBlockBinding); + } } -GLenum ProgramGL::getSamplerTextureType(gl::SamplerType type, unsigned int samplerIndex) const +void ProgramGL::reset() { - UNIMPLEMENTED(); - return GLenum(); + mUniformRealLocationMap.clear(); + mUniformBlockRealLocationMap.clear(); + mSamplerBindings.clear(); + mUniformIndexToSamplerIndex.clear(); } -GLint ProgramGL::getUsedSamplerRange(gl::SamplerType type) const +GLuint ProgramGL::getProgramID() const { - UNIMPLEMENTED(); - return GLint(); + return mProgramID; } -void ProgramGL::updateSamplerMapping() +const std::vector &ProgramGL::getAppliedSamplerUniforms() const { - UNIMPLEMENTED(); + return mSamplerBindings; } -bool ProgramGL::validateSamplers(gl::InfoLog *infoLog, const gl::Caps &caps) +bool ProgramGL::getUniformBlockSize(const std::string &blockName, size_t *sizeOut) const { - //UNIMPLEMENTED(); - return true; -} + ASSERT(mProgramID != 0u); -LinkResult ProgramGL::compileProgramExecutables(gl::InfoLog &infoLog, gl::Shader *fragmentShader, gl::Shader *vertexShader, - int registers) -{ - //UNIMPLEMENTED(); - return LinkResult(true, gl::Error(GL_NO_ERROR)); -} + GLuint blockIndex = mFunctions->getUniformBlockIndex(mProgramID, blockName.c_str()); + if (blockIndex == GL_INVALID_INDEX) + { + *sizeOut = 0; + return false; + } -bool ProgramGL::linkUniforms(gl::InfoLog &infoLog, const gl::Shader &vertexShader, const gl::Shader &fragmentShader, - const gl::Caps &caps) -{ - //UNIMPLEMENTED(); + GLint dataSize = 0; + mFunctions->getActiveUniformBlockiv(mProgramID, blockIndex, GL_UNIFORM_BLOCK_DATA_SIZE, + &dataSize); + *sizeOut = static_cast(dataSize); return true; } -bool ProgramGL::defineUniformBlock(gl::InfoLog &infoLog, const gl::Shader &shader, const sh::InterfaceBlock &interfaceBlock, - const gl::Caps &caps) -{ - UNIMPLEMENTED(); - return bool(); -} - -gl::Error ProgramGL::applyUniforms() -{ - UNIMPLEMENTED(); - return gl::Error(GL_INVALID_OPERATION); -} - -gl::Error ProgramGL::applyUniformBuffers(const gl::Data &data, GLuint uniformBlockBindings[]) -{ - UNIMPLEMENTED(); - return gl::Error(GL_INVALID_OPERATION); -} - -bool ProgramGL::assignUniformBlockRegister(gl::InfoLog &infoLog, gl::UniformBlock *uniformBlock, GLenum shader, - unsigned int registerIndex, const gl::Caps &caps) +bool ProgramGL::getUniformBlockMemberInfo(const std::string &memberUniformName, + sh::BlockMemberInfo *memberInfoOut) const { - UNIMPLEMENTED(); - return bool(); -} + GLuint uniformIndex; + const GLchar *memberNameGLStr = memberUniformName.c_str(); + mFunctions->getUniformIndices(mProgramID, 1, &memberNameGLStr, &uniformIndex); -void ProgramGL::reset() -{ - ProgramImpl::reset(); - - if (mProgramID) + if (uniformIndex == GL_INVALID_INDEX) { - mFunctions->deleteProgram(mProgramID); - mProgramID = 0; + *memberInfoOut = sh::BlockMemberInfo::getDefaultBlockInfo(); + return false; } -} -GLuint ProgramGL::getProgramID() const -{ - return mProgramID; + mFunctions->getActiveUniformsiv(mProgramID, 1, &uniformIndex, GL_UNIFORM_OFFSET, + &memberInfoOut->offset); + mFunctions->getActiveUniformsiv(mProgramID, 1, &uniformIndex, GL_UNIFORM_ARRAY_STRIDE, + &memberInfoOut->arrayStride); + mFunctions->getActiveUniformsiv(mProgramID, 1, &uniformIndex, GL_UNIFORM_MATRIX_STRIDE, + &memberInfoOut->matrixStride); + + // TODO(jmadill): possibly determine this at the gl::Program level. + GLint isRowMajorMatrix = 0; + mFunctions->getActiveUniformsiv(mProgramID, 1, &uniformIndex, GL_UNIFORM_IS_ROW_MAJOR, + &isRowMajorMatrix); + memberInfoOut->isRowMajorMatrix = isRowMajorMatrix != GL_FALSE; + return true; } -} +} // namespace rx diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/ProgramGL.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/ProgramGL.h index 20e5a3b3b26b..a7b1888041ed 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/ProgramGL.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/ProgramGL.h @@ -9,6 +9,7 @@ #ifndef LIBANGLE_RENDERER_GL_PROGRAMGL_H_ #define LIBANGLE_RENDERER_GL_PROGRAMGL_H_ +#include "libANGLE/renderer/gl/WorkaroundsGL.h" #include "libANGLE/renderer/ProgramImpl.h" namespace rx @@ -17,26 +18,27 @@ namespace rx class FunctionsGL; class StateManagerGL; +struct SamplerBindingGL +{ + GLenum textureType; + std::vector boundTextureUnits; +}; + class ProgramGL : public ProgramImpl { public: - ProgramGL(const FunctionsGL *functions, StateManagerGL *stateManager); + ProgramGL(const gl::Program::Data &data, + const FunctionsGL *functions, + const WorkaroundsGL &workarounds, + StateManagerGL *stateManager); ~ProgramGL() override; - bool usesPointSize() const override; - int getShaderVersion() const override; - GLenum getTransformFeedbackBufferMode() const override; - - GLenum getBinaryFormat() override; LinkResult load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream) override; gl::Error save(gl::BinaryOutputStream *stream) override; + void setBinaryRetrievableHint(bool retrievable) override; - LinkResult link(const gl::Data &data, gl::InfoLog &infoLog, - gl::Shader *fragmentShader, gl::Shader *vertexShader, - const std::vector &transformFeedbackVaryings, - GLenum transformFeedbackBufferMode, - int *registers, std::vector *linkedVaryings, - std::map *outputVariables) override; + LinkResult link(const gl::Data &data, gl::InfoLog &infoLog) override; + GLboolean validate(const gl::Caps &caps, gl::InfoLog *infoLog) override; void setUniform1fv(GLint location, GLsizei count, const GLfloat *v) override; void setUniform2fv(GLint location, GLsizei count, const GLfloat *v) override; @@ -60,37 +62,34 @@ class ProgramGL : public ProgramImpl 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(GLint location, GLfloat *params) override; - void getUniformiv(GLint location, GLint *params) override; - void getUniformuiv(GLint location, GLuint *params) override; - - GLint getSamplerMapping(gl::SamplerType type, unsigned int samplerIndex, const gl::Caps &caps) const override; - GLenum getSamplerTextureType(gl::SamplerType type, unsigned int samplerIndex) const override; - GLint getUsedSamplerRange(gl::SamplerType type) const override; - void updateSamplerMapping() override; - bool validateSamplers(gl::InfoLog *infoLog, const gl::Caps &caps) override; - - LinkResult compileProgramExecutables(gl::InfoLog &infoLog, gl::Shader *fragmentShader, gl::Shader *vertexShader, - int registers) override; - - bool linkUniforms(gl::InfoLog &infoLog, const gl::Shader &vertexShader, const gl::Shader &fragmentShader, - const gl::Caps &caps) override; - bool defineUniformBlock(gl::InfoLog &infoLog, const gl::Shader &shader, const sh::InterfaceBlock &interfaceBlock, - const gl::Caps &caps) override; + void setUniformBlockBinding(GLuint uniformBlockIndex, GLuint uniformBlockBinding) override; - gl::Error applyUniforms() override; - gl::Error applyUniformBuffers(const gl::Data &data, GLuint uniformBlockBindings[]) override; - bool assignUniformBlockRegister(gl::InfoLog &infoLog, gl::UniformBlock *uniformBlock, GLenum shader, - unsigned int registerIndex, const gl::Caps &caps) override; - - void reset() override; + bool getUniformBlockSize(const std::string &blockName, size_t *sizeOut) const override; + bool getUniformBlockMemberInfo(const std::string &memberUniformName, + sh::BlockMemberInfo *memberInfoOut) const override; GLuint getProgramID() const; + const std::vector &getAppliedSamplerUniforms() const; private: + void reset(); + + // Helper function, makes it simpler to type. + GLint uniLoc(GLint glLocation) const { return mUniformRealLocationMap[glLocation]; } + const FunctionsGL *mFunctions; + const WorkaroundsGL &mWorkarounds; StateManagerGL *mStateManager; + std::vector mUniformRealLocationMap; + std::vector mUniformBlockRealLocationMap; + + // An array of the samplers that are used by the program + std::vector mSamplerBindings; + + // A map from a mData.getUniforms() index to a mSamplerBindings index. + std::vector mUniformIndexToSamplerIndex; + GLuint mProgramID; }; diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/QueryGL.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/QueryGL.cpp index 8f1d25f3bbd7..6d9df5d76018 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/QueryGL.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/QueryGL.cpp @@ -9,39 +9,214 @@ #include "libANGLE/renderer/gl/QueryGL.h" #include "common/debug.h" +#include "libANGLE/renderer/gl/FunctionsGL.h" +#include "libANGLE/renderer/gl/StateManagerGL.h" + +namespace +{ + +GLuint64 MergeQueryResults(GLenum type, GLuint64 currentResult, GLuint64 newResult) +{ + switch (type) + { + case GL_ANY_SAMPLES_PASSED: + case GL_ANY_SAMPLES_PASSED_CONSERVATIVE: + return (currentResult == GL_TRUE || newResult == GL_TRUE) ? GL_TRUE : GL_FALSE; + + case GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN: + return currentResult + newResult; + + case GL_TIME_ELAPSED: + return currentResult + newResult; + + case GL_TIMESTAMP: + return newResult; + + default: + UNREACHABLE(); + return 0; + } +} + +} // anonymous namespace namespace rx { -QueryGL::QueryGL(GLenum type) - : QueryImpl(type) -{} +QueryGL::QueryGL(GLenum type, const FunctionsGL *functions, StateManagerGL *stateManager) + : QueryImpl(type), + mType(type), + mFunctions(functions), + mStateManager(stateManager), + mActiveQuery(0), + mPendingQueries(), + mResultSum(0) +{ +} QueryGL::~QueryGL() -{} +{ + mStateManager->deleteQuery(mActiveQuery); + mStateManager->onDeleteQueryObject(this); + while (!mPendingQueries.empty()) + { + mStateManager->deleteQuery(mPendingQueries.front()); + mPendingQueries.pop_front(); + } +} gl::Error QueryGL::begin() { - UNIMPLEMENTED(); - return gl::Error(GL_INVALID_OPERATION); + mResultSum = 0; + mStateManager->onBeginQuery(this); + return resume(); } gl::Error QueryGL::end() { - UNIMPLEMENTED(); - return gl::Error(GL_INVALID_OPERATION); + return pause(); +} + +gl::Error QueryGL::queryCounter() +{ + ASSERT(mType == GL_TIMESTAMP); + + // Directly create a query for the timestamp and add it to the pending query queue, as timestamp + // queries do not have the traditional begin/end block and never need to be paused/resumed + GLuint query; + mFunctions->genQueries(1, &query); + mFunctions->queryCounter(query, GL_TIMESTAMP); + mPendingQueries.push_back(query); + + return gl::Error(GL_NO_ERROR); +} + +template +gl::Error QueryGL::getResultBase(T *params) +{ + ASSERT(mActiveQuery == 0); + + gl::Error error = flush(true); + if (error.isError()) + { + return error; + } + + ASSERT(mPendingQueries.empty()); + *params = static_cast(mResultSum); + + return gl::Error(GL_NO_ERROR); +} + +gl::Error QueryGL::getResult(GLint *params) +{ + return getResultBase(params); } gl::Error QueryGL::getResult(GLuint *params) { - UNIMPLEMENTED(); - return gl::Error(GL_INVALID_OPERATION); + return getResultBase(params); +} + +gl::Error QueryGL::getResult(GLint64 *params) +{ + return getResultBase(params); +} + +gl::Error QueryGL::getResult(GLuint64 *params) +{ + return getResultBase(params); } -gl::Error QueryGL::isResultAvailable(GLuint *available) +gl::Error QueryGL::isResultAvailable(bool *available) { - UNIMPLEMENTED(); - return gl::Error(GL_INVALID_OPERATION); + ASSERT(mActiveQuery == 0); + + gl::Error error = flush(false); + if (error.isError()) + { + return error; + } + + *available = mPendingQueries.empty(); + return gl::Error(GL_NO_ERROR); +} + +gl::Error QueryGL::pause() +{ + if (mActiveQuery != 0) + { + mStateManager->endQuery(mType, mActiveQuery); + + mPendingQueries.push_back(mActiveQuery); + mActiveQuery = 0; + } + + // Flush to make sure the pending queries don't add up too much. + gl::Error error = flush(false); + if (error.isError()) + { + return error; + } + + return gl::Error(GL_NO_ERROR); +} + +gl::Error QueryGL::resume() +{ + if (mActiveQuery == 0) + { + // Flush to make sure the pending queries don't add up too much. + gl::Error error = flush(false); + if (error.isError()) + { + return error; + } + + mFunctions->genQueries(1, &mActiveQuery); + mStateManager->beginQuery(mType, mActiveQuery); + } + + return gl::Error(GL_NO_ERROR); +} + +gl::Error QueryGL::flush(bool force) +{ + while (!mPendingQueries.empty()) + { + GLuint id = mPendingQueries.front(); + if (!force) + { + GLuint resultAvailable = 0; + mFunctions->getQueryObjectuiv(id, GL_QUERY_RESULT_AVAILABLE, &resultAvailable); + if (resultAvailable == GL_FALSE) + { + return gl::Error(GL_NO_ERROR); + } + } + + // Even though getQueryObjectui64v was introduced for timer queries, there is nothing in the + // standard that says that it doesn't work for any other queries. It also passes on all the + // trybots, so we use it if it is available + if (mFunctions->getQueryObjectui64v != nullptr) + { + GLuint64 result = 0; + mFunctions->getQueryObjectui64v(id, GL_QUERY_RESULT, &result); + mResultSum = MergeQueryResults(mType, mResultSum, result); + } + else + { + GLuint result = 0; + mFunctions->getQueryObjectuiv(id, GL_QUERY_RESULT, &result); + mResultSum = MergeQueryResults(mType, mResultSum, static_cast(result)); + } + + mStateManager->deleteQuery(id); + + mPendingQueries.pop_front(); + } + + return gl::Error(GL_NO_ERROR); } } diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/QueryGL.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/QueryGL.h index c6b7cfbfef4d..5e280b1f7bcd 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/QueryGL.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/QueryGL.h @@ -9,21 +9,54 @@ #ifndef LIBANGLE_RENDERER_GL_QUERYGL_H_ #define LIBANGLE_RENDERER_GL_QUERYGL_H_ +#include + #include "libANGLE/renderer/QueryImpl.h" namespace rx { +class FunctionsGL; +class StateManagerGL; + class QueryGL : public QueryImpl { public: - QueryGL(GLenum type); + QueryGL(GLenum type, const FunctionsGL *functions, StateManagerGL *stateManager); ~QueryGL() override; gl::Error begin() override; gl::Error end() override; + gl::Error queryCounter() override; + gl::Error getResult(GLint *params) override; gl::Error getResult(GLuint *params) override; - gl::Error isResultAvailable(GLuint *available) override; + gl::Error getResult(GLint64 *params) override; + gl::Error getResult(GLuint64 *params) override; + gl::Error isResultAvailable(bool *available) override; + + // OpenGL is only allowed to have one query of each type active at any given time. Since ANGLE + // virtualizes contexts, queries need to be able to be paused and resumed. + // A query is "paused" by ending it and pushing the ID into a list of queries awaiting readback. + // When it is "resumed", a new query is generated and started. + // When a result is required, the queries are "flushed" by iterating over the list of pending + // queries and merging their results. + gl::Error pause(); + gl::Error resume(); + + private: + gl::Error flush(bool force); + + template + gl::Error getResultBase(T *params); + + GLenum mType; + + const FunctionsGL *mFunctions; + StateManagerGL *mStateManager; + + GLuint mActiveQuery; + std::deque mPendingQueries; + GLuint64 mResultSum; }; } diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/RenderbufferGL.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/RenderbufferGL.cpp index dcfd7bb6591b..bfc2bb254fbf 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/RenderbufferGL.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/RenderbufferGL.cpp @@ -13,41 +13,53 @@ #include "libANGLE/angletypes.h" #include "libANGLE/renderer/gl/FunctionsGL.h" #include "libANGLE/renderer/gl/StateManagerGL.h" +#include "libANGLE/renderer/gl/formatutilsgl.h" #include "libANGLE/renderer/gl/renderergl_utils.h" namespace rx { - -RenderbufferGL::RenderbufferGL(const FunctionsGL *functions, StateManagerGL *stateManager, const gl::TextureCapsMap &textureCaps) +RenderbufferGL::RenderbufferGL(const FunctionsGL *functions, + const WorkaroundsGL &workarounds, + StateManagerGL *stateManager, + const gl::TextureCapsMap &textureCaps) : RenderbufferImpl(), mFunctions(functions), + mWorkarounds(workarounds), mStateManager(stateManager), mTextureCaps(textureCaps), mRenderbufferID(0) { mFunctions->genRenderbuffers(1, &mRenderbufferID); + mStateManager->bindRenderbuffer(GL_RENDERBUFFER, mRenderbufferID); } RenderbufferGL::~RenderbufferGL() { - if (mRenderbufferID != 0) - { - mFunctions->deleteRenderbuffers(1, &mRenderbufferID); - mRenderbufferID = 0; - } + mStateManager->deleteRenderbuffer(mRenderbufferID); + mRenderbufferID = 0; } gl::Error RenderbufferGL::setStorage(GLenum internalformat, size_t width, size_t height) { mStateManager->bindRenderbuffer(GL_RENDERBUFFER, mRenderbufferID); - mFunctions->renderbufferStorage(GL_RENDERBUFFER, internalformat, width, height); + + nativegl::RenderbufferFormat renderbufferFormat = + nativegl::GetRenderbufferFormat(mFunctions, mWorkarounds, internalformat); + mFunctions->renderbufferStorage(GL_RENDERBUFFER, renderbufferFormat.internalFormat, + static_cast(width), static_cast(height)); + return gl::Error(GL_NO_ERROR); } gl::Error RenderbufferGL::setStorageMultisample(size_t samples, GLenum internalformat, size_t width, size_t height) { mStateManager->bindRenderbuffer(GL_RENDERBUFFER, mRenderbufferID); - mFunctions->renderbufferStorageMultisample(GL_RENDERBUFFER, samples, internalformat, width, height); + + nativegl::RenderbufferFormat renderbufferFormat = + nativegl::GetRenderbufferFormat(mFunctions, mWorkarounds, internalformat); + mFunctions->renderbufferStorageMultisample( + GL_RENDERBUFFER, static_cast(samples), renderbufferFormat.internalFormat, + static_cast(width), static_cast(height)); const gl::TextureCaps &formatCaps = mTextureCaps.get(internalformat); if (samples > formatCaps.getMaxSamples()) @@ -70,6 +82,12 @@ gl::Error RenderbufferGL::setStorageMultisample(size_t samples, GLenum internalf return gl::Error(GL_NO_ERROR); } +gl::Error RenderbufferGL::setStorageEGLImageTarget(egl::Image *image) +{ + UNIMPLEMENTED(); + return gl::Error(GL_INVALID_OPERATION); +} + GLuint RenderbufferGL::getRenderbufferID() const { return mRenderbufferID; diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/RenderbufferGL.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/RenderbufferGL.h index f26341f57284..eeb164378c23 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/RenderbufferGL.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/RenderbufferGL.h @@ -21,15 +21,20 @@ namespace rx class FunctionsGL; class StateManagerGL; +struct WorkaroundsGL; class RenderbufferGL : public RenderbufferImpl { public: - RenderbufferGL(const FunctionsGL *functions, StateManagerGL *stateManager, const gl::TextureCapsMap &textureCaps); + RenderbufferGL(const FunctionsGL *functions, + const WorkaroundsGL &workarounds, + StateManagerGL *stateManager, + const gl::TextureCapsMap &textureCaps); ~RenderbufferGL() override; virtual gl::Error setStorage(GLenum internalformat, size_t width, size_t height) override; virtual gl::Error setStorageMultisample(size_t samples, GLenum internalformat, size_t width, size_t height) override; + virtual gl::Error setStorageEGLImageTarget(egl::Image *image) override; GLuint getRenderbufferID() const; @@ -41,6 +46,7 @@ class RenderbufferGL : public RenderbufferImpl private: const FunctionsGL *mFunctions; + const WorkaroundsGL &mWorkarounds; StateManagerGL *mStateManager; const gl::TextureCapsMap &mTextureCaps; diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/RendererGL.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/RendererGL.cpp index 7e1b0b0beb47..4defb463f667 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/RendererGL.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/RendererGL.cpp @@ -8,9 +8,13 @@ #include "libANGLE/renderer/gl/RendererGL.h" +#include + #include "common/debug.h" +#include "libANGLE/AttributeMap.h" #include "libANGLE/Data.h" #include "libANGLE/Surface.h" +#include "libANGLE/renderer/gl/BlitGL.h" #include "libANGLE/renderer/gl/BufferGL.h" #include "libANGLE/renderer/gl/CompilerGL.h" #include "libANGLE/renderer/gl/FenceNVGL.h" @@ -20,6 +24,7 @@ #include "libANGLE/renderer/gl/ProgramGL.h" #include "libANGLE/renderer/gl/QueryGL.h" #include "libANGLE/renderer/gl/RenderbufferGL.h" +#include "libANGLE/renderer/gl/SamplerGL.h" #include "libANGLE/renderer/gl/ShaderGL.h" #include "libANGLE/renderer/gl/StateManagerGL.h" #include "libANGLE/renderer/gl/SurfaceGL.h" @@ -28,20 +33,94 @@ #include "libANGLE/renderer/gl/VertexArrayGL.h" #include "libANGLE/renderer/gl/renderergl_utils.h" +#ifndef NDEBUG +static void INTERNAL_GL_APIENTRY LogGLDebugMessage(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, + const GLchar *message, const void *userParam) +{ + std::string sourceText; + switch (source) + { + case GL_DEBUG_SOURCE_API: sourceText = "OpenGL"; break; + case GL_DEBUG_SOURCE_WINDOW_SYSTEM: sourceText = "Windows"; break; + case GL_DEBUG_SOURCE_SHADER_COMPILER: sourceText = "Shader Compiler"; break; + case GL_DEBUG_SOURCE_THIRD_PARTY: sourceText = "Third Party"; break; + case GL_DEBUG_SOURCE_APPLICATION: sourceText = "Application"; break; + case GL_DEBUG_SOURCE_OTHER: sourceText = "Other"; break; + default: sourceText = "UNKNOWN"; break; + } + + std::string typeText; + switch (type) + { + case GL_DEBUG_TYPE_ERROR: typeText = "Error"; break; + case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR: typeText = "Deprecated behavior"; break; + case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR: typeText = "Undefined behavior"; break; + case GL_DEBUG_TYPE_PORTABILITY: typeText = "Portability"; break; + case GL_DEBUG_TYPE_PERFORMANCE: typeText = "Performance"; break; + case GL_DEBUG_TYPE_OTHER: typeText = "Other"; break; + case GL_DEBUG_TYPE_MARKER: typeText = "Marker"; break; + default: typeText = "UNKNOWN"; break; + } + + std::string severityText; + switch (severity) + { + case GL_DEBUG_SEVERITY_HIGH: severityText = "High"; break; + case GL_DEBUG_SEVERITY_MEDIUM: severityText = "Medium"; break; + case GL_DEBUG_SEVERITY_LOW: severityText = "Low"; break; + case GL_DEBUG_SEVERITY_NOTIFICATION: severityText = "Notification"; break; + default: severityText = "UNKNOWN"; break; + } + + ERR("\n\tSource: %s\n\tType: %s\n\tID: %d\n\tSeverity: %s\n\tMessage: %s", sourceText.c_str(), typeText.c_str(), id, + severityText.c_str(), message); +} +#endif + namespace rx { -RendererGL::RendererGL(const FunctionsGL *functions) +RendererGL::RendererGL(const FunctionsGL *functions, const egl::AttributeMap &attribMap) : Renderer(), + mMaxSupportedESVersion(0, 0), mFunctions(functions), - mStateManager(nullptr) + mStateManager(nullptr), + mBlitter(nullptr), + mHasDebugOutput(false), + mSkipDrawCalls(false) { ASSERT(mFunctions); mStateManager = new StateManagerGL(mFunctions, getRendererCaps()); + nativegl_gl::GenerateWorkarounds(mFunctions, &mWorkarounds); + mBlitter = new BlitGL(functions, mWorkarounds, mStateManager); + + mHasDebugOutput = mFunctions->isAtLeastGL(gl::Version(4, 3)) || + mFunctions->hasGLExtension("GL_KHR_debug") || + mFunctions->isAtLeastGLES(gl::Version(3, 2)) || + mFunctions->hasGLESExtension("GL_KHR_debug"); +#ifndef NDEBUG + if (mHasDebugOutput) + { + mFunctions->enable(GL_DEBUG_OUTPUT_SYNCHRONOUS); + mFunctions->debugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_HIGH, 0, nullptr, GL_TRUE); + mFunctions->debugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_MEDIUM, 0, nullptr, GL_TRUE); + mFunctions->debugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_LOW, 0, nullptr, GL_FALSE); + mFunctions->debugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_NOTIFICATION, 0, nullptr, GL_FALSE); + mFunctions->debugMessageCallback(&LogGLDebugMessage, nullptr); + } +#endif + + EGLint deviceType = + static_cast(attribMap.get(EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE, EGL_NONE)); + if (deviceType == EGL_PLATFORM_ANGLE_DEVICE_TYPE_NULL_ANGLE) + { + mSkipDrawCalls = true; + } } RendererGL::~RendererGL() { + SafeDelete(mBlitter); SafeDelete(mStateManager); } @@ -53,78 +132,161 @@ gl::Error RendererGL::flush() gl::Error RendererGL::finish() { +#ifdef NDEBUG + if (mWorkarounds.finishDoesNotCauseQueriesToBeAvailable && mHasDebugOutput) + { + mFunctions->enable(GL_DEBUG_OUTPUT_SYNCHRONOUS); + } +#endif + mFunctions->finish(); + +#ifdef NDEBUG + if (mWorkarounds.finishDoesNotCauseQueriesToBeAvailable && mHasDebugOutput) + { + mFunctions->disable(GL_DEBUG_OUTPUT_SYNCHRONOUS); + } +#endif + return gl::Error(GL_NO_ERROR); } -gl::Error RendererGL::drawArrays(const gl::Data &data, GLenum mode, - GLint first, GLsizei count, GLsizei instances) +gl::Error RendererGL::drawArrays(const gl::Data &data, GLenum mode, GLint first, GLsizei count) { - gl::Error error = mStateManager->setDrawArraysState(data, first, count); + gl::Error error = mStateManager->setDrawArraysState(data, first, count, 0); if (error.isError()) { return error; } - mFunctions->drawArrays(mode, first, count); + if (!mSkipDrawCalls) + { + mFunctions->drawArrays(mode, first, count); + } return gl::Error(GL_NO_ERROR); } -gl::Error RendererGL::drawElements(const gl::Data &data, GLenum mode, GLsizei count, GLenum type, - const GLvoid *indices, GLsizei instances, - const RangeUI &indexRange) +gl::Error RendererGL::drawArraysInstanced(const gl::Data &data, + GLenum mode, + GLint first, + GLsizei count, + GLsizei instanceCount) { - if (instances > 0) + gl::Error error = mStateManager->setDrawArraysState(data, first, count, instanceCount); + if (error.isError()) + { + return error; + } + + if (!mSkipDrawCalls) { - UNIMPLEMENTED(); + mFunctions->drawArraysInstanced(mode, first, count, instanceCount); } + return gl::Error(GL_NO_ERROR); +} + +gl::Error RendererGL::drawElements(const gl::Data &data, + GLenum mode, + GLsizei count, + GLenum type, + const GLvoid *indices, + const gl::IndexRange &indexRange) +{ const GLvoid *drawIndexPointer = nullptr; - gl::Error error = mStateManager->setDrawElementsState(data, count, type, indices, &drawIndexPointer); + gl::Error error = + mStateManager->setDrawElementsState(data, count, type, indices, 0, &drawIndexPointer); if (error.isError()) { return error; } - mFunctions->drawElements(mode, count, type, drawIndexPointer); + if (!mSkipDrawCalls) + { + mFunctions->drawElements(mode, count, type, drawIndexPointer); + } return gl::Error(GL_NO_ERROR); } -CompilerImpl *RendererGL::createCompiler(const gl::Data &data) +gl::Error RendererGL::drawElementsInstanced(const gl::Data &data, + GLenum mode, + GLsizei count, + GLenum type, + const GLvoid *indices, + GLsizei instances, + const gl::IndexRange &indexRange) { - return new CompilerGL(data); + const GLvoid *drawIndexPointer = nullptr; + gl::Error error = mStateManager->setDrawElementsState(data, count, type, indices, instances, + &drawIndexPointer); + if (error.isError()) + { + return error; + } + + if (!mSkipDrawCalls) + { + mFunctions->drawElementsInstanced(mode, count, type, drawIndexPointer, instances); + } + + return gl::Error(GL_NO_ERROR); } -ShaderImpl *RendererGL::createShader(GLenum type) +gl::Error RendererGL::drawRangeElements(const gl::Data &data, + GLenum mode, + GLuint start, + GLuint end, + GLsizei count, + GLenum type, + const GLvoid *indices, + const gl::IndexRange &indexRange) { - return new ShaderGL(type, mFunctions); + const GLvoid *drawIndexPointer = nullptr; + gl::Error error = + mStateManager->setDrawElementsState(data, count, type, indices, 0, &drawIndexPointer); + if (error.isError()) + { + return error; + } + + if (!mSkipDrawCalls) + { + mFunctions->drawRangeElements(mode, start, end, count, type, drawIndexPointer); + } + + return gl::Error(GL_NO_ERROR); } -ProgramImpl *RendererGL::createProgram() +CompilerImpl *RendererGL::createCompiler() { - return new ProgramGL(mFunctions, mStateManager); + return new CompilerGL(mFunctions); } -FramebufferImpl *RendererGL::createDefaultFramebuffer(const gl::Framebuffer::Data &data) +ShaderImpl *RendererGL::createShader(const gl::Shader::Data &data) { - return new FramebufferGL(data, mFunctions, mStateManager, true); + return new ShaderGL(data, mFunctions, mWorkarounds); +} + +ProgramImpl *RendererGL::createProgram(const gl::Program::Data &data) +{ + return new ProgramGL(data, mFunctions, mWorkarounds, mStateManager); } FramebufferImpl *RendererGL::createFramebuffer(const gl::Framebuffer::Data &data) { - return new FramebufferGL(data, mFunctions, mStateManager, false); + return new FramebufferGL(data, mFunctions, mStateManager, mWorkarounds, false); } TextureImpl *RendererGL::createTexture(GLenum target) { - return new TextureGL(target, mFunctions, mStateManager); + return new TextureGL(target, mFunctions, mWorkarounds, mStateManager, mBlitter); } RenderbufferImpl *RendererGL::createRenderbuffer() { - return new RenderbufferGL(mFunctions, mStateManager, getRendererTextureCaps()); + return new RenderbufferGL(mFunctions, mWorkarounds, mStateManager, getRendererTextureCaps()); } BufferImpl *RendererGL::createBuffer() @@ -132,14 +294,14 @@ BufferImpl *RendererGL::createBuffer() return new BufferGL(mFunctions, mStateManager); } -VertexArrayImpl *RendererGL::createVertexArray() +VertexArrayImpl *RendererGL::createVertexArray(const gl::VertexArray::Data &data) { - return new VertexArrayGL(mFunctions, mStateManager); + return new VertexArrayGL(data, mFunctions, mStateManager); } QueryImpl *RendererGL::createQuery(GLenum type) { - return new QueryGL(type); + return new QueryGL(type, mFunctions, mStateManager); } FenceNVImpl *RendererGL::createFenceNV() @@ -154,7 +316,29 @@ FenceSyncImpl *RendererGL::createFenceSync() TransformFeedbackImpl *RendererGL::createTransformFeedback() { - return new TransformFeedbackGL(); + return new TransformFeedbackGL(mFunctions, mStateManager, + getRendererCaps().maxTransformFeedbackSeparateComponents); +} + +SamplerImpl *RendererGL::createSampler() +{ + return new SamplerGL(mFunctions, mStateManager); +} + +void RendererGL::insertEventMarker(GLsizei length, const char *marker) +{ + mFunctions->debugMessageInsert(GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_MARKER, 0, + GL_DEBUG_SEVERITY_NOTIFICATION, length, marker); +} + +void RendererGL::pushGroupMarker(GLsizei length, const char *marker) +{ + mFunctions->pushDebugGroup(GL_DEBUG_SOURCE_APPLICATION, 0, length, marker); +} + +void RendererGL::popGroupMarker() +{ + mFunctions->popDebugGroup(); } void RendererGL::notifyDeviceLost() @@ -180,12 +364,6 @@ bool RendererGL::testDeviceResettable() return bool(); } -VendorID RendererGL::getVendorId() const -{ - UNIMPLEMENTED(); - return VendorID(); -} - std::string RendererGL::getVendorString() const { return std::string(reinterpret_cast(mFunctions->getString(GL_VENDOR))); @@ -198,24 +376,64 @@ std::string RendererGL::getRendererDescription() const std::ostringstream rendererString; rendererString << nativeVendorString << " " << nativeRendererString << " OpenGL"; - if (mFunctions->openGLES) + if (mFunctions->standard == STANDARD_GL_ES) { rendererString << " ES"; } - rendererString << " " << mFunctions->majorVersion << "." << mFunctions->minorVersion; + rendererString << " " << mFunctions->version.major << "." << mFunctions->version.minor; + if (mFunctions->standard == STANDARD_GL_DESKTOP) + { + // Some drivers (NVIDIA) use a profile mask of 0 when in compatibility profile. + if ((mFunctions->profile & GL_CONTEXT_COMPATIBILITY_PROFILE_BIT) != 0 || + (mFunctions->isAtLeastGL(gl::Version(3, 2)) && mFunctions->profile == 0)) + { + rendererString << " compatibility"; + } + else if ((mFunctions->profile & GL_CONTEXT_CORE_PROFILE_BIT) != 0) + { + rendererString << " core"; + } + } return rendererString.str(); } -void RendererGL::generateCaps(gl::Caps *outCaps, gl::TextureCapsMap* outTextureCaps, gl::Extensions *outExtensions) const +const gl::Version &RendererGL::getMaxSupportedESVersion() const +{ + // Force generation of caps + getRendererCaps(); + + return mMaxSupportedESVersion; +} + +void RendererGL::generateCaps(gl::Caps *outCaps, gl::TextureCapsMap* outTextureCaps, + gl::Extensions *outExtensions, + gl::Limitations * /* outLimitations */) const +{ + nativegl_gl::GenerateCaps(mFunctions, outCaps, outTextureCaps, outExtensions, &mMaxSupportedESVersion); +} + +void RendererGL::syncState(const gl::State &state, const gl::State::DirtyBits &dirtyBits) { - nativegl_gl::GenerateCaps(mFunctions, outCaps, outTextureCaps, outExtensions); + mStateManager->syncState(state, dirtyBits); } -Workarounds RendererGL::generateWorkarounds() const +GLint RendererGL::getGPUDisjoint() { - Workarounds workarounds; - return workarounds; + // TODO(ewell): On GLES backends we should find a way to reliably query disjoint events + return 0; } +GLint64 RendererGL::getTimestamp() +{ + GLint64 result = 0; + mFunctions->getInteger64v(GL_TIMESTAMP, &result); + return result; +} + +void RendererGL::onMakeCurrent(const gl::Data &data) +{ + // Queries need to be paused/resumed on context switches + mStateManager->onMakeCurrent(data); +} } diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/RendererGL.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/RendererGL.h index 26fdbdf15e5f..0a66fedbc20f 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/RendererGL.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/RendererGL.h @@ -9,35 +9,60 @@ #ifndef LIBANGLE_RENDERER_GL_RENDERERGL_H_ #define LIBANGLE_RENDERER_GL_RENDERERGL_H_ +#include "libANGLE/Version.h" #include "libANGLE/renderer/Renderer.h" +#include "libANGLE/renderer/gl/WorkaroundsGL.h" namespace rx { +class BlitGL; class FunctionsGL; class StateManagerGL; class RendererGL : public Renderer { public: - RendererGL(const FunctionsGL *functions); + RendererGL(const FunctionsGL *functions, const egl::AttributeMap &attribMap); ~RendererGL() override; gl::Error flush() override; gl::Error finish() override; - gl::Error drawArrays(const gl::Data &data, GLenum mode, - GLint first, GLsizei count, GLsizei instances) override; - gl::Error drawElements(const gl::Data &data, GLenum mode, GLsizei count, GLenum type, - const GLvoid *indices, GLsizei instances, - const RangeUI &indexRange) override; + gl::Error drawArrays(const gl::Data &data, GLenum mode, GLint first, GLsizei count) override; + gl::Error drawArraysInstanced(const gl::Data &data, + GLenum mode, + GLint first, + GLsizei count, + GLsizei instanceCount) override; + + gl::Error drawElements(const gl::Data &data, + GLenum mode, + GLsizei count, + GLenum type, + const GLvoid *indices, + const gl::IndexRange &indexRange) override; + gl::Error drawElementsInstanced(const gl::Data &data, + GLenum mode, + GLsizei count, + GLenum type, + const GLvoid *indices, + GLsizei instances, + const gl::IndexRange &indexRange) override; + gl::Error drawRangeElements(const gl::Data &data, + GLenum mode, + GLuint start, + GLuint end, + GLsizei count, + GLenum type, + const GLvoid *indices, + const gl::IndexRange &indexRange) override; // Shader creation - CompilerImpl *createCompiler(const gl::Data &data) override; - ShaderImpl *createShader(GLenum type) override; - ProgramImpl *createProgram() override; + CompilerImpl *createCompiler() override; + ShaderImpl *createShader(const gl::Shader::Data &data) override; + ProgramImpl *createProgram(const gl::Program::Data &data) override; // Framebuffer creation - FramebufferImpl *createDefaultFramebuffer(const gl::Framebuffer::Data &data) override; FramebufferImpl *createFramebuffer(const gl::Framebuffer::Data &data) override; // Texture creation @@ -50,7 +75,7 @@ class RendererGL : public Renderer BufferImpl *createBuffer() override; // Vertex Array creation - VertexArrayImpl *createVertexArray() override; + VertexArrayImpl *createVertexArray(const gl::VertexArray::Data &data) override; // Query and Fence creation QueryImpl *createQuery(GLenum type) override; @@ -60,22 +85,53 @@ class RendererGL : public Renderer // Transform Feedback creation TransformFeedbackImpl *createTransformFeedback() override; + // Sampler object creation + SamplerImpl *createSampler() override; + + // EXT_debug_marker + void insertEventMarker(GLsizei length, const char *marker) override; + void pushGroupMarker(GLsizei length, const char *marker) override; + void popGroupMarker() override; + // lost device void notifyDeviceLost() override; bool isDeviceLost() const override; bool testDeviceLost() override; bool testDeviceResettable() override; - VendorID getVendorId() const override; std::string getVendorString() const override; std::string getRendererDescription() const override; + void syncState(const gl::State &state, const gl::State::DirtyBits &dirtyBits) override; + + GLint getGPUDisjoint() override; + GLint64 getTimestamp() override; + + void onMakeCurrent(const gl::Data &data) override; + + const gl::Version &getMaxSupportedESVersion() const; + const FunctionsGL *getFunctions() const { return mFunctions; } + StateManagerGL *getStateManager() const { return mStateManager; } + const WorkaroundsGL &getWorkarounds() const { return mWorkarounds; } + private: - void generateCaps(gl::Caps *outCaps, gl::TextureCapsMap* outTextureCaps, gl::Extensions *outExtensions) const override; - Workarounds generateWorkarounds() const override; + void generateCaps(gl::Caps *outCaps, gl::TextureCapsMap* outTextureCaps, + gl::Extensions *outExtensions, + gl::Limitations *outLimitations) const override; + + mutable gl::Version mMaxSupportedESVersion; const FunctionsGL *mFunctions; StateManagerGL *mStateManager; + + BlitGL *mBlitter; + + WorkaroundsGL mWorkarounds; + + bool mHasDebugOutput; + + // For performance debugging + bool mSkipDrawCalls; }; } diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/SamplerGL.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/SamplerGL.cpp new file mode 100644 index 000000000000..bffc89ec9811 --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/SamplerGL.cpp @@ -0,0 +1,72 @@ +// +// 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. +// + +// SamplerGL.cpp: Defines the rx::SamplerGL class, an implementation of SamplerImpl. + +#include "libANGLE/renderer/gl/SamplerGL.h" + +#include "libANGLE/renderer/gl/FunctionsGL.h" +#include "libANGLE/renderer/gl/StateManagerGL.h" + +namespace +{ + +template +static inline void SyncSamplerStateMember(const rx::FunctionsGL *functions, + GLuint sampler, + const gl::SamplerState &newState, + gl::SamplerState &curState, + GLenum name, + T(gl::SamplerState::*samplerMember)) +{ + if (curState.*samplerMember != newState.*samplerMember) + { + curState.*samplerMember = newState.*samplerMember; + functions->samplerParameterf(sampler, name, static_cast(curState.*samplerMember)); + } +} +} + +namespace rx +{ + +SamplerGL::SamplerGL(const FunctionsGL *functions, StateManagerGL *stateManager) + : SamplerImpl(), + mFunctions(functions), + mStateManager(stateManager), + mAppliedSamplerState(), + mSamplerID(0) +{ + mFunctions->genSamplers(1, &mSamplerID); +} + +SamplerGL::~SamplerGL() +{ + mStateManager->deleteSampler(mSamplerID); + mSamplerID = 0; +} + +void SamplerGL::syncState(const gl::SamplerState &samplerState) const +{ + // clang-format off + SyncSamplerStateMember(mFunctions, mSamplerID, samplerState, mAppliedSamplerState, GL_TEXTURE_MIN_FILTER, &gl::SamplerState::minFilter); + SyncSamplerStateMember(mFunctions, mSamplerID, samplerState, mAppliedSamplerState, GL_TEXTURE_MAG_FILTER, &gl::SamplerState::magFilter); + SyncSamplerStateMember(mFunctions, mSamplerID, samplerState, mAppliedSamplerState, GL_TEXTURE_WRAP_S, &gl::SamplerState::wrapS); + SyncSamplerStateMember(mFunctions, mSamplerID, samplerState, mAppliedSamplerState, GL_TEXTURE_WRAP_T, &gl::SamplerState::wrapT); + SyncSamplerStateMember(mFunctions, mSamplerID, samplerState, mAppliedSamplerState, GL_TEXTURE_WRAP_R, &gl::SamplerState::wrapR); + SyncSamplerStateMember(mFunctions, mSamplerID, samplerState, mAppliedSamplerState, GL_TEXTURE_MAX_ANISOTROPY_EXT, &gl::SamplerState::maxAnisotropy); + SyncSamplerStateMember(mFunctions, mSamplerID, samplerState, mAppliedSamplerState, GL_TEXTURE_MIN_LOD, &gl::SamplerState::minLod); + SyncSamplerStateMember(mFunctions, mSamplerID, samplerState, mAppliedSamplerState, GL_TEXTURE_MAX_LOD, &gl::SamplerState::maxLod); + SyncSamplerStateMember(mFunctions, mSamplerID, samplerState, mAppliedSamplerState, GL_TEXTURE_COMPARE_MODE, &gl::SamplerState::compareMode); + SyncSamplerStateMember(mFunctions, mSamplerID, samplerState, mAppliedSamplerState, GL_TEXTURE_COMPARE_FUNC, &gl::SamplerState::compareFunc); + // clang-format on +} + +GLuint SamplerGL::getSamplerID() const +{ + return mSamplerID; +} +} diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/SamplerGL.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/SamplerGL.h new file mode 100644 index 000000000000..c3fcfde808a3 --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/SamplerGL.h @@ -0,0 +1,40 @@ +// +// 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. +// + +// SamplerGL.h: Defines the rx::SamplerGL class, an implementation of SamplerImpl. + +#ifndef LIBANGLE_RENDERER_GL_SAMPLERGL_H_ +#define LIBANGLE_RENDERER_GL_SAMPLERGL_H_ + +#include "libANGLE/angletypes.h" +#include "libANGLE/renderer/SamplerImpl.h" + +namespace rx +{ + +class FunctionsGL; +class StateManagerGL; + +class SamplerGL : public SamplerImpl +{ + public: + SamplerGL(const FunctionsGL *functions, StateManagerGL *stateManager); + ~SamplerGL() override; + + void syncState(const gl::SamplerState &samplerState) const; + + GLuint getSamplerID() const; + + private: + const FunctionsGL *mFunctions; + StateManagerGL *mStateManager; + + mutable gl::SamplerState mAppliedSamplerState; + GLuint mSamplerID; +}; +} + +#endif // LIBANGLE_RENDERER_GL_SAMPLERGL_H_ diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/ShaderGL.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/ShaderGL.cpp index a97c2c1432b9..aa54d17c2c0d 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/ShaderGL.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/ShaderGL.cpp @@ -10,40 +10,19 @@ #include "common/debug.h" #include "libANGLE/Compiler.h" -#include "libANGLE/renderer/gl/CompilerGL.h" #include "libANGLE/renderer/gl/FunctionsGL.h" +#include "libANGLE/renderer/gl/RendererGL.h" +#include "libANGLE/renderer/gl/WorkaroundsGL.h" -template -static std::vector GetFilteredShaderVariables(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.staticUse) - { - result.push_back(var); - } - } - return result; -} - -template -static const std::vector &GetShaderVariables(const std::vector *variableList) -{ - ASSERT(variableList); - return *variableList; -} +#include namespace rx { -ShaderGL::ShaderGL(GLenum type, const FunctionsGL *functions) - : ShaderImpl(), - mFunctions(functions), - mType(type), - mShaderID(0) +ShaderGL::ShaderGL(const gl::Shader::Data &data, + const FunctionsGL *functions, + const WorkaroundsGL &workarounds) + : ShaderImpl(data), mFunctions(functions), mWorkarounds(workarounds), mShaderID(0) { ASSERT(mFunctions); } @@ -57,84 +36,67 @@ ShaderGL::~ShaderGL() } } -bool ShaderGL::compile(gl::Compiler *compiler, const std::string &source) +int ShaderGL::prepareSourceAndReturnOptions(std::stringstream *sourceStream, + std::string * /*sourcePath*/) { // Reset the previous state - mActiveAttributes.clear(); - mVaryings.clear(); - mUniforms.clear(); - mInterfaceBlocks.clear(); - mActiveOutputVariables.clear(); if (mShaderID != 0) { mFunctions->deleteShader(mShaderID); mShaderID = 0; } - // Translate the ESSL into GLSL - CompilerGL *compilerGL = GetImplAs(compiler); - ShHandle compilerHandle = compilerGL->getCompilerHandle(mType); + *sourceStream << mData.getSource(); - int compileOptions = (SH_OBJECT_CODE | SH_VARIABLES); - const char* sourceCString = source.c_str(); - if (!ShCompile(compilerHandle, &sourceCString, 1, compileOptions)) + int options = SH_INIT_GL_POSITION; + + if (mWorkarounds.doWhileGLSLCausesGPUHang) { - mInfoLog = ShGetInfoLog(compilerHandle); - TRACE("\n%s", mInfoLog.c_str()); - return false; + options |= SH_REWRITE_DO_WHILE_LOOPS; } - mTranslatedSource = ShGetObjectCode(compilerHandle); - const char* translatedSourceCString = mTranslatedSource.c_str(); + return options; +} + +bool ShaderGL::postTranslateCompile(gl::Compiler *compiler, std::string *infoLog) +{ + // Translate the ESSL into GLSL + const char *translatedSourceCString = mData.getTranslatedSource().c_str(); // Generate a shader object and set the source - mShaderID = mFunctions->createShader(mType); + mShaderID = mFunctions->createShader(mData.getShaderType()); mFunctions->shaderSource(mShaderID, 1, &translatedSourceCString, nullptr); mFunctions->compileShader(mShaderID); // Check for compile errors from the native driver GLint compileStatus = GL_FALSE; mFunctions->getShaderiv(mShaderID, GL_COMPILE_STATUS, &compileStatus); - ASSERT(compileStatus == GL_TRUE); if (compileStatus == GL_FALSE) { // Compilation failed, put the error into the info log GLint infoLogLength = 0; mFunctions->getShaderiv(mShaderID, GL_INFO_LOG_LENGTH, &infoLogLength); - std::vector buf(infoLogLength); - mFunctions->getShaderInfoLog(mShaderID, infoLogLength, nullptr, &buf[0]); + // Info log length includes the null terminator, so 1 means that the info log is an empty + // string. + if (infoLogLength > 1) + { + std::vector buf(infoLogLength); + mFunctions->getShaderInfoLog(mShaderID, infoLogLength, nullptr, &buf[0]); - mFunctions->deleteShader(mShaderID); - mShaderID = 0; + mFunctions->deleteShader(mShaderID); + mShaderID = 0; - mInfoLog = &buf[0]; - TRACE("\n%s", mInfoLog.c_str()); + *infoLog = &buf[0]; + TRACE("\n%s", infoLog->c_str()); + } + else + { + TRACE("\nShader compilation failed with no info log."); + } return false; } - // Gather the shader information - // TODO: refactor this out, gathering of the attributes, varyings and outputs should be done - // at the gl::Shader level - if (mType == GL_VERTEX_SHADER) - { - mActiveAttributes = GetFilteredShaderVariables(ShGetAttributes(compilerHandle)); - } - - const std::vector &varyings = GetShaderVariables(ShGetVaryings(compilerHandle)); - for (size_t varyingIndex = 0; varyingIndex < varyings.size(); varyingIndex++) - { - mVaryings.push_back(gl::PackedVarying(varyings[varyingIndex])); - } - - mUniforms = GetShaderVariables(ShGetUniforms(compilerHandle)); - mInterfaceBlocks = GetShaderVariables(ShGetInterfaceBlocks(compilerHandle)); - - if (mType == GL_FRAGMENT_SHADER) - { - mActiveOutputVariables = GetFilteredShaderVariables(ShGetOutputVariables(compilerHandle)); - } - return true; } diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/ShaderGL.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/ShaderGL.h index e2783bafda94..76139ace8f38 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/ShaderGL.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/ShaderGL.h @@ -13,24 +13,29 @@ namespace rx { - class FunctionsGL; +struct WorkaroundsGL; class ShaderGL : public ShaderImpl { public: - ShaderGL(GLenum type, const FunctionsGL *functions); + ShaderGL(const gl::Shader::Data &data, + const FunctionsGL *functions, + const WorkaroundsGL &workarounds); ~ShaderGL() override; - bool compile(gl::Compiler *compiler, const std::string &source) override; + // ShaderImpl implementation + int prepareSourceAndReturnOptions(std::stringstream *sourceStream, + std::string *sourcePath) override; + bool postTranslateCompile(gl::Compiler *compiler, std::string *infoLog) override; std::string getDebugInfo() const override; GLuint getShaderID() const; private: const FunctionsGL *mFunctions; + const WorkaroundsGL &mWorkarounds; - GLenum mType; GLuint mShaderID; }; diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/StateManagerGL.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/StateManagerGL.cpp index 9bea1ef61233..f2e591cfee4f 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/StateManagerGL.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/StateManagerGL.cpp @@ -8,28 +8,58 @@ #include "libANGLE/renderer/gl/StateManagerGL.h" +#include "common/BitSetIterator.h" #include "libANGLE/Data.h" #include "libANGLE/Framebuffer.h" +#include "libANGLE/TransformFeedback.h" #include "libANGLE/VertexArray.h" +#include "libANGLE/Query.h" +#include "libANGLE/renderer/gl/BufferGL.h" #include "libANGLE/renderer/gl/FramebufferGL.h" #include "libANGLE/renderer/gl/FunctionsGL.h" #include "libANGLE/renderer/gl/ProgramGL.h" +#include "libANGLE/renderer/gl/SamplerGL.h" #include "libANGLE/renderer/gl/TextureGL.h" +#include "libANGLE/renderer/gl/TransformFeedbackGL.h" #include "libANGLE/renderer/gl/VertexArrayGL.h" +#include "libANGLE/renderer/gl/QueryGL.h" namespace rx { +static const GLenum QueryTypes[] = {GL_ANY_SAMPLES_PASSED, GL_ANY_SAMPLES_PASSED_CONSERVATIVE, + GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, GL_TIME_ELAPSED}; + +StateManagerGL::IndexedBufferBinding::IndexedBufferBinding() : offset(0), size(0), buffer(0) +{ +} + StateManagerGL::StateManagerGL(const FunctionsGL *functions, const gl::Caps &rendererCaps) : mFunctions(functions), mProgram(0), mVAO(0), + mVertexAttribCurrentValues(rendererCaps.maxVertexAttributes), mBuffers(), + mIndexedBuffers(), mTextureUnitIndex(0), mTextures(), + mSamplers(rendererCaps.maxCombinedTextureImageUnits, 0), + mTransformFeedback(0), + mQueries(), + mPrevDrawTransformFeedback(nullptr), + mCurrentQueries(), + mPrevDrawContext(0), mUnpackAlignment(4), mUnpackRowLength(0), - mFramebuffers(), + mUnpackSkipRows(0), + mUnpackSkipPixels(0), + mUnpackImageHeight(0), + mUnpackSkipImages(0), + mPackAlignment(4), + mPackRowLength(0), + mPackSkipRows(0), + mPackSkipPixels(0), + mFramebuffers(angle::FramebufferBindingSingletonMax, 0), mRenderbuffer(0), mScissorTestEnabled(false), mScissor(0, 0, 0, 0), @@ -74,13 +104,15 @@ StateManagerGL::StateManagerGL(const FunctionsGL *functions, const gl::Caps &ren mPolygonOffsetFillEnabled(false), mPolygonOffsetFactor(0.0f), mPolygonOffsetUnits(0.0f), - mMultisampleEnabled(true), mRasterizerDiscardEnabled(false), mLineWidth(1.0f), mPrimitiveRestartEnabled(false), mClearColor(0.0f, 0.0f, 0.0f, 0.0f), mClearDepth(1.0f), - mClearStencil(0) + mClearStencil(0), + mFramebufferSRGBEnabled(false), + mTextureCubemapSeamlessEnabled(false), + mLocalDirtyBits() { ASSERT(mFunctions); @@ -89,24 +121,203 @@ StateManagerGL::StateManagerGL(const FunctionsGL *functions, const gl::Caps &ren mTextures[GL_TEXTURE_2D_ARRAY].resize(rendererCaps.maxCombinedTextureImageUnits); mTextures[GL_TEXTURE_3D].resize(rendererCaps.maxCombinedTextureImageUnits); - mFramebuffers[GL_READ_FRAMEBUFFER] = 0; - mFramebuffers[GL_DRAW_FRAMEBUFFER] = 0; + mIndexedBuffers[GL_UNIFORM_BUFFER].resize(rendererCaps.maxCombinedUniformBlocks); + + for (GLenum queryType : QueryTypes) + { + mQueries[queryType] = 0; + } + + // Initialize point sprite state for desktop GL + if (mFunctions->standard == STANDARD_GL_DESKTOP) + { + mFunctions->enable(GL_PROGRAM_POINT_SIZE); + + // GL_POINT_SPRITE was deprecated in the core profile. Point rasterization is always + // performed + // as though POINT_SPRITE were enabled. + if ((mFunctions->profile & GL_CONTEXT_CORE_PROFILE_BIT) == 0) + { + mFunctions->enable(GL_POINT_SPRITE); + } + } +} + +void StateManagerGL::deleteProgram(GLuint program) +{ + if (program != 0) + { + if (mProgram == program) + { + useProgram(0); + } + + mFunctions->deleteProgram(program); + } +} + +void StateManagerGL::deleteVertexArray(GLuint vao) +{ + if (vao != 0) + { + if (mVAO == vao) + { + bindVertexArray(0, 0); + } + + mFunctions->deleteVertexArrays(1, &vao); + } +} + +void StateManagerGL::deleteTexture(GLuint texture) +{ + if (texture != 0) + { + for (const auto &textureTypeIter : mTextures) + { + const std::vector &textureVector = textureTypeIter.second; + for (size_t textureUnitIndex = 0; textureUnitIndex < textureVector.size(); textureUnitIndex++) + { + if (textureVector[textureUnitIndex] == texture) + { + activeTexture(textureUnitIndex); + bindTexture(textureTypeIter.first, 0); + } + } + } + + mFunctions->deleteTextures(1, &texture); + } +} + +void StateManagerGL::deleteSampler(GLuint sampler) +{ + if (sampler != 0) + { + for (size_t unit = 0; unit < mSamplers.size(); unit++) + { + if (mSamplers[unit] == sampler) + { + bindSampler(unit, 0); + } + } + + mFunctions->deleteSamplers(1, &sampler); + } +} + +void StateManagerGL::deleteBuffer(GLuint buffer) +{ + if (buffer != 0) + { + for (const auto &bufferTypeIter : mBuffers) + { + if (bufferTypeIter.second == buffer) + { + bindBuffer(bufferTypeIter.first, 0); + } + } + + for (const auto &bufferTypeIter : mIndexedBuffers) + { + for (size_t bindIndex = 0; bindIndex < bufferTypeIter.second.size(); bindIndex++) + { + if (bufferTypeIter.second[bindIndex].buffer == buffer) + { + bindBufferBase(bufferTypeIter.first, bindIndex, 0); + } + } + } + + mFunctions->deleteBuffers(1, &buffer); + } +} + +void StateManagerGL::deleteFramebuffer(GLuint fbo) +{ + if (fbo != 0) + { + for (size_t binding = 0; binding < mFramebuffers.size(); ++binding) + { + if (mFramebuffers[binding] == fbo) + { + GLenum enumValue = angle::FramebufferBindingToEnum( + static_cast(binding)); + bindFramebuffer(enumValue, 0); + } + mFunctions->deleteFramebuffers(1, &fbo); + } + } +} + +void StateManagerGL::deleteRenderbuffer(GLuint rbo) +{ + if (rbo != 0) + { + if (mRenderbuffer == rbo) + { + bindRenderbuffer(GL_RENDERBUFFER, 0); + } + + mFunctions->deleteRenderbuffers(1, &rbo); + } +} + +void StateManagerGL::deleteTransformFeedback(GLuint transformFeedback) +{ + if (transformFeedback != 0) + { + if (mTransformFeedback == transformFeedback) + { + bindTransformFeedback(GL_TRANSFORM_FEEDBACK, 0); + } + + if (mPrevDrawTransformFeedback != nullptr && + mPrevDrawTransformFeedback->getTransformFeedbackID() == transformFeedback) + { + mPrevDrawTransformFeedback = nullptr; + } + + mFunctions->deleteTransformFeedbacks(1, &transformFeedback); + } +} + +void StateManagerGL::deleteQuery(GLuint query) +{ + if (query != 0) + { + for (auto &activeQuery : mQueries) + { + GLuint activeQueryID = activeQuery.second; + if (activeQueryID == query) + { + GLenum type = activeQuery.first; + endQuery(type, query); + } + } + } } void StateManagerGL::useProgram(GLuint program) { if (mProgram != program) { - mProgram = program; - mFunctions->useProgram(mProgram); + forceUseProgram(program); } } -void StateManagerGL::bindVertexArray(GLuint vao) +void StateManagerGL::forceUseProgram(GLuint program) +{ + mProgram = program; + mFunctions->useProgram(mProgram); +} + +void StateManagerGL::bindVertexArray(GLuint vao, GLuint elementArrayBuffer) { if (mVAO != vao) { mVAO = vao; + mBuffers[GL_ELEMENT_ARRAY_BUFFER] = elementArrayBuffer; mFunctions->bindVertexArray(vao); } } @@ -120,12 +331,41 @@ void StateManagerGL::bindBuffer(GLenum type, GLuint buffer) } } +void StateManagerGL::bindBufferBase(GLenum type, size_t index, GLuint buffer) +{ + auto &binding = mIndexedBuffers[type][index]; + if (binding.buffer != buffer || binding.offset != static_cast(-1) || + binding.size != static_cast(-1)) + { + binding.buffer = buffer; + binding.offset = static_cast(-1); + binding.size = static_cast(-1); + mFunctions->bindBufferBase(type, static_cast(index), buffer); + } +} + +void StateManagerGL::bindBufferRange(GLenum type, + size_t index, + GLuint buffer, + size_t offset, + size_t size) +{ + auto &binding = mIndexedBuffers[type][index]; + if (binding.buffer != buffer || binding.offset != offset || binding.size != size) + { + binding.buffer = buffer; + binding.offset = offset; + binding.size = size; + mFunctions->bindBufferRange(type, static_cast(index), buffer, offset, size); + } +} + void StateManagerGL::activeTexture(size_t unit) { if (mTextureUnitIndex != unit) { mTextureUnitIndex = unit; - mFunctions->activeTexture(GL_TEXTURE0 + mTextureUnitIndex); + mFunctions->activeTexture(GL_TEXTURE0 + static_cast(mTextureUnitIndex)); } } @@ -138,38 +378,157 @@ void StateManagerGL::bindTexture(GLenum type, GLuint texture) } } -void StateManagerGL::setPixelUnpackState(GLint alignment, GLint rowLength) +void StateManagerGL::bindSampler(size_t unit, GLuint sampler) +{ + if (mSamplers[unit] != sampler) + { + mSamplers[unit] = sampler; + mFunctions->bindSampler(static_cast(unit), sampler); + } +} + +void StateManagerGL::setPixelUnpackState(const gl::PixelUnpackState &unpack) +{ + GLuint unpackBufferID = 0; + const gl::Buffer *unpackBuffer = unpack.pixelBuffer.get(); + if (unpackBuffer != nullptr) + { + unpackBufferID = GetImplAs(unpackBuffer)->getBufferID(); + } + setPixelUnpackState(unpack.alignment, unpack.rowLength, unpack.skipRows, unpack.skipPixels, + unpack.imageHeight, unpack.skipImages, unpackBufferID); +} + +void StateManagerGL::setPixelUnpackState(GLint alignment, + GLint rowLength, + GLint skipRows, + GLint skipPixels, + GLint imageHeight, + GLint skipImages, + GLuint unpackBuffer) { if (mUnpackAlignment != alignment) { mUnpackAlignment = alignment; mFunctions->pixelStorei(GL_UNPACK_ALIGNMENT, mUnpackAlignment); + + mLocalDirtyBits.set(gl::State::DIRTY_BIT_UNPACK_ALIGNMENT); } if (mUnpackRowLength != rowLength) { mUnpackRowLength = rowLength; mFunctions->pixelStorei(GL_UNPACK_ROW_LENGTH, mUnpackRowLength); + + mLocalDirtyBits.set(gl::State::DIRTY_BIT_UNPACK_ROW_LENGTH); + } + + if (mUnpackSkipRows != skipRows) + { + mUnpackSkipRows = skipRows; + mFunctions->pixelStorei(GL_UNPACK_SKIP_ROWS, mUnpackSkipRows); + + // TODO: set dirty bit once one exists } + + if (mUnpackSkipPixels != skipPixels) + { + mUnpackSkipPixels = skipPixels; + mFunctions->pixelStorei(GL_UNPACK_SKIP_PIXELS, mUnpackSkipPixels); + + // TODO: set dirty bit once one exists + } + + if (mUnpackImageHeight != imageHeight) + { + mUnpackImageHeight = imageHeight; + mFunctions->pixelStorei(GL_UNPACK_IMAGE_HEIGHT, mUnpackImageHeight); + + // TODO: set dirty bit once one exists + } + + if (mUnpackSkipImages != skipImages) + { + mUnpackSkipImages = skipImages; + mFunctions->pixelStorei(GL_UNPACK_SKIP_IMAGES, mUnpackSkipImages); + + // TODO: set dirty bit once one exists + } + + bindBuffer(GL_PIXEL_UNPACK_BUFFER, unpackBuffer); +} + +void StateManagerGL::setPixelPackState(const gl::PixelPackState &pack) +{ + GLuint packBufferID = 0; + const gl::Buffer *packBuffer = pack.pixelBuffer.get(); + if (packBuffer != nullptr) + { + packBufferID = GetImplAs(packBuffer)->getBufferID(); + } + setPixelPackState(pack.alignment, pack.rowLength, pack.skipRows, pack.skipPixels, packBufferID); +} + +void StateManagerGL::setPixelPackState(GLint alignment, + GLint rowLength, + GLint skipRows, + GLint skipPixels, + GLuint packBuffer) +{ + if (mPackAlignment != alignment) + { + mPackAlignment = alignment; + mFunctions->pixelStorei(GL_PACK_ALIGNMENT, mPackAlignment); + + mLocalDirtyBits.set(gl::State::DIRTY_BIT_PACK_ALIGNMENT); + } + + if (mPackRowLength != rowLength) + { + mPackRowLength = rowLength; + mFunctions->pixelStorei(GL_PACK_ROW_LENGTH, mPackRowLength); + + mLocalDirtyBits.set(gl::State::DIRTY_BIT_UNPACK_ROW_LENGTH); + } + + if (mPackSkipRows != skipRows) + { + mPackSkipRows = skipRows; + mFunctions->pixelStorei(GL_PACK_SKIP_ROWS, mPackSkipRows); + + // TODO: set dirty bit once one exists + } + + if (mPackSkipPixels != skipPixels) + { + mPackSkipPixels = skipPixels; + mFunctions->pixelStorei(GL_PACK_SKIP_PIXELS, mPackSkipPixels); + + // TODO: set dirty bit once one exists + } + + bindBuffer(GL_PIXEL_PACK_BUFFER, packBuffer); } void StateManagerGL::bindFramebuffer(GLenum type, GLuint framebuffer) { if (type == GL_FRAMEBUFFER) { - if (mFramebuffers[GL_READ_FRAMEBUFFER] != framebuffer || - mFramebuffers[GL_DRAW_FRAMEBUFFER] != framebuffer) + if (mFramebuffers[angle::FramebufferBindingRead] != framebuffer || + mFramebuffers[angle::FramebufferBindingDraw] != framebuffer) { - mFramebuffers[GL_READ_FRAMEBUFFER] = framebuffer; - mFramebuffers[GL_DRAW_FRAMEBUFFER] = framebuffer; + mFramebuffers[angle::FramebufferBindingRead] = framebuffer; + mFramebuffers[angle::FramebufferBindingDraw] = framebuffer; mFunctions->bindFramebuffer(GL_FRAMEBUFFER, framebuffer); } } else { - if (mFramebuffers[type] != framebuffer) + angle::FramebufferBinding binding = angle::EnumToFramebufferBinding(type); + + if (mFramebuffers[binding] != framebuffer) { - mFramebuffers[type] = framebuffer; + mFramebuffers[binding] = framebuffer; mFunctions->bindFramebuffer(type, framebuffer); } } @@ -185,104 +544,184 @@ void StateManagerGL::bindRenderbuffer(GLenum type, GLuint renderbuffer) } } -void StateManagerGL::setClearState(const gl::State &state, GLbitfield mask) +void StateManagerGL::bindTransformFeedback(GLenum type, GLuint transformFeedback) { - // Only apply the state required to do a clear - const gl::RasterizerState &rasterizerState = state.getRasterizerState(); - setRasterizerDiscardEnabled(rasterizerState.rasterizerDiscard); - if (!rasterizerState.rasterizerDiscard) + ASSERT(type == GL_TRANSFORM_FEEDBACK); + if (mTransformFeedback != transformFeedback) { - setScissor(state.getScissor()); - setViewport(state.getViewport()); - - if ((mask & GL_COLOR_BUFFER_BIT) != 0) + // Pause the current transform feedback if one is active. + // To handle virtualized contexts, StateManagerGL needs to be able to bind a new transform + // feedback at any time, even if there is one active. + if (mPrevDrawTransformFeedback != nullptr && + mPrevDrawTransformFeedback->getTransformFeedbackID() != transformFeedback) { - setClearColor(state.getColorClearValue()); - - const gl::BlendState &blendState = state.getBlendState(); - setColorMask(blendState.colorMaskRed, blendState.colorMaskGreen, blendState.colorMaskBlue, blendState.colorMaskAlpha); + mPrevDrawTransformFeedback->syncPausedState(true); + mPrevDrawTransformFeedback = nullptr; } - if ((mask & GL_DEPTH_BUFFER_BIT) != 0) - { - setClearDepth(state.getDepthClearValue()); - setDepthMask(state.getDepthStencilState().depthMask); - } - - if ((mask & GL_STENCIL_BUFFER_BIT) != 0) - { - setClearStencil(state.getStencilClearValue()); - setStencilFrontWritemask(state.getDepthStencilState().stencilWritemask); - setStencilBackWritemask(state.getDepthStencilState().stencilBackWritemask); - } + mTransformFeedback = transformFeedback; + mFunctions->bindTransformFeedback(type, mTransformFeedback); } } -gl::Error StateManagerGL::setDrawArraysState(const gl::Data &data, GLint first, GLsizei count) +void StateManagerGL::beginQuery(GLenum type, GLuint query) +{ + // Make sure this is a valid query type and there is no current active query of this type + ASSERT(mQueries.find(type) != mQueries.end()); + ASSERT(mQueries[type] == 0); + ASSERT(query != 0); + + mQueries[type] = query; + mFunctions->beginQuery(type, query); +} + +void StateManagerGL::endQuery(GLenum type, GLuint query) +{ + ASSERT(mQueries[type] == query); + mQueries[type] = 0; + mFunctions->endQuery(type); +} + +void StateManagerGL::onBeginQuery(QueryGL *query) +{ + mCurrentQueries.insert(query); +} + +void StateManagerGL::onDeleteQueryObject(QueryGL *query) +{ + mCurrentQueries.erase(query); +} + +gl::Error StateManagerGL::setDrawArraysState(const gl::Data &data, + GLint first, + GLsizei count, + GLsizei instanceCount) { const gl::State &state = *data.state; + const gl::Program *program = state.getProgram(); + const gl::VertexArray *vao = state.getVertexArray(); const VertexArrayGL *vaoGL = GetImplAs(vao); - vaoGL->syncDrawArraysState(first, count); - bindVertexArray(vaoGL->getVertexArrayID()); + + gl::Error error = vaoGL->syncDrawArraysState(program->getActiveAttribLocationsMask(), first, + count, instanceCount); + if (error.isError()) + { + return error; + } + + bindVertexArray(vaoGL->getVertexArrayID(), vaoGL->getAppliedElementArrayBufferID()); return setGenericDrawState(data); } -gl::Error StateManagerGL::setDrawElementsState(const gl::Data &data, GLsizei count, GLenum type, const GLvoid *indices, +gl::Error StateManagerGL::setDrawElementsState(const gl::Data &data, + GLsizei count, + GLenum type, + const GLvoid *indices, + GLsizei instanceCount, const GLvoid **outIndices) { const gl::State &state = *data.state; + const gl::Program *program = state.getProgram(); + const gl::VertexArray *vao = state.getVertexArray(); const VertexArrayGL *vaoGL = GetImplAs(vao); - gl::Error error = vaoGL->syncDrawElementsState(count, type, indices, outIndices); + gl::Error error = + vaoGL->syncDrawElementsState(program->getActiveAttribLocationsMask(), count, type, indices, + instanceCount, state.isPrimitiveRestartEnabled(), outIndices); if (error.isError()) { return error; } - bindVertexArray(vaoGL->getVertexArrayID()); + bindVertexArray(vaoGL->getVertexArrayID(), vaoGL->getAppliedElementArrayBufferID()); return setGenericDrawState(data); } +gl::Error StateManagerGL::onMakeCurrent(const gl::Data &data) +{ + const gl::State &state = *data.state; + + // If the context has changed, pause the previous context's transform feedback and queries + if (data.context != mPrevDrawContext) + { + if (mPrevDrawTransformFeedback != nullptr) + { + mPrevDrawTransformFeedback->syncPausedState(true); + } + + for (QueryGL *prevQuery : mCurrentQueries) + { + prevQuery->pause(); + } + } + mCurrentQueries.clear(); + mPrevDrawTransformFeedback = nullptr; + mPrevDrawContext = data.context; + + // Set the current query state + for (GLenum queryType : QueryTypes) + { + gl::Query *query = state.getActiveQuery(queryType); + if (query != nullptr) + { + QueryGL *queryGL = GetImplAs(query); + queryGL->resume(); + + mCurrentQueries.insert(queryGL); + } + } + + return gl::Error(GL_NO_ERROR); +} + gl::Error StateManagerGL::setGenericDrawState(const gl::Data &data) { const gl::State &state = *data.state; - const gl::Caps &caps = *data.caps; + // Sync the current program state const gl::Program *program = state.getProgram(); const ProgramGL *programGL = GetImplAs(program); useProgram(programGL->getProgramID()); - // TODO: Only apply textures referenced by the program. - for (auto textureTypeIter = mTextures.begin(); textureTypeIter != mTextures.end(); textureTypeIter++) + for (size_t uniformBlockIndex = 0; uniformBlockIndex < program->getActiveUniformBlockCount(); + uniformBlockIndex++) { - GLenum textureType = textureTypeIter->first; - - // Determine if this texture type can exist in the source context - bool validTextureType = (textureType == GL_TEXTURE_2D || textureType == GL_TEXTURE_CUBE_MAP || - (textureType == GL_TEXTURE_2D_ARRAY && data.clientVersion >= 3) || - (textureType == GL_TEXTURE_3D && data.clientVersion >= 3)); + GLuint binding = program->getUniformBlockBinding(static_cast(uniformBlockIndex)); + const OffsetBindingPointer &uniformBuffer = + data.state->getIndexedUniformBuffer(binding); - const std::vector &textureVector = textureTypeIter->second; - for (size_t textureUnitIndex = 0; textureUnitIndex < textureVector.size(); textureUnitIndex++) + if (uniformBuffer.get() != nullptr) { - const gl::Texture *texture = nullptr; + BufferGL *bufferGL = GetImplAs(uniformBuffer.get()); - bool validTextureUnit = textureUnitIndex < caps.maxCombinedTextureImageUnits; - if (validTextureType && validTextureUnit) + if (uniformBuffer.getSize() == 0) { - texture = state.getSamplerTexture(textureUnitIndex, textureType); + bindBufferBase(GL_UNIFORM_BUFFER, binding, bufferGL->getBufferID()); } + else + { + bindBufferRange(GL_UNIFORM_BUFFER, binding, bufferGL->getBufferID(), + uniformBuffer.getOffset(), uniformBuffer.getSize()); + } + } + } + const std::vector &appliedSamplerUniforms = programGL->getAppliedSamplerUniforms(); + for (const SamplerBindingGL &samplerUniform : appliedSamplerUniforms) + { + GLenum textureType = samplerUniform.textureType; + for (GLuint textureUnitIndex : samplerUniform.boundTextureUnits) + { + const gl::Texture *texture = state.getSamplerTexture(textureUnitIndex, textureType); if (texture != nullptr) { const TextureGL *textureGL = GetImplAs(texture); - textureGL->syncSamplerState(texture->getSamplerState()); if (mTextures[textureType][textureUnitIndex] != textureGL->getTextureID()) { @@ -290,7 +729,7 @@ gl::Error StateManagerGL::setGenericDrawState(const gl::Data &data) bindTexture(textureType, textureGL->getTextureID()); } - // TODO: apply sampler object if one is bound + textureGL->syncState(textureUnitIndex, texture->getTextureState()); } else { @@ -300,75 +739,75 @@ gl::Error StateManagerGL::setGenericDrawState(const gl::Data &data) bindTexture(textureType, 0); } } + + const gl::Sampler *sampler = state.getSampler(textureUnitIndex); + if (sampler != nullptr) + { + const SamplerGL *samplerGL = GetImplAs(sampler); + samplerGL->syncState(sampler->getSamplerState()); + bindSampler(textureUnitIndex, samplerGL->getSamplerID()); + } + else + { + bindSampler(textureUnitIndex, 0); + } } } const gl::Framebuffer *framebuffer = state.getDrawFramebuffer(); const FramebufferGL *framebufferGL = GetImplAs(framebuffer); bindFramebuffer(GL_DRAW_FRAMEBUFFER, framebufferGL->getFramebufferID()); + framebufferGL->syncDrawState(); - setScissorTestEnabled(state.isScissorTestEnabled()); - if (state.isScissorTestEnabled()) - { - setScissor(state.getScissor()); - } - - setViewport(state.getViewport()); - setDepthRange(state.getNearPlane(), state.getFarPlane()); + // Seamless cubemaps are required for ES3 and higher contexts. + setTextureCubemapSeamlessEnabled(data.clientVersion >= 3); - const gl::BlendState &blendState = state.getBlendState(); - setBlendEnabled(blendState.blend); - if (blendState.blend) + // Set the current transform feedback state + gl::TransformFeedback *transformFeedback = state.getCurrentTransformFeedback(); + if (transformFeedback) { - setBlendColor(state.getBlendColor()); - setBlendFuncs(blendState.sourceBlendRGB, blendState.destBlendRGB, blendState.sourceBlendAlpha, blendState.destBlendAlpha); - setBlendEquations(blendState.blendEquationRGB, blendState.blendEquationAlpha); - setColorMask(blendState.colorMaskRed, blendState.colorMaskGreen, blendState.colorMaskBlue, blendState.colorMaskAlpha); + TransformFeedbackGL *transformFeedbackGL = + GetImplAs(transformFeedback); + bindTransformFeedback(GL_TRANSFORM_FEEDBACK, transformFeedbackGL->getTransformFeedbackID()); + transformFeedbackGL->syncActiveState(transformFeedback->isActive(), + transformFeedback->getPrimitiveMode()); + transformFeedbackGL->syncPausedState(transformFeedback->isPaused()); + mPrevDrawTransformFeedback = transformFeedbackGL; } - setSampleAlphaToCoverageEnabled(blendState.sampleAlphaToCoverage); - setSampleCoverageEnabled(state.isSampleCoverageEnabled()); - setSampleCoverage(state.getSampleCoverageValue(), state.getSampleCoverageInvert()); - - const gl::DepthStencilState &depthStencilState = state.getDepthStencilState(); - setDepthTestEnabled(depthStencilState.depthTest); - if (depthStencilState.depthTest) + else { - setDepthFunc(depthStencilState.depthFunc); - setDepthMask(depthStencilState.depthMask); + bindTransformFeedback(GL_TRANSFORM_FEEDBACK, 0); + mPrevDrawTransformFeedback = nullptr; } - setStencilTestEnabled(depthStencilState.stencilTest); - if (depthStencilState.stencilTest) - { - setStencilFrontWritemask(state.getDepthStencilState().stencilWritemask); - setStencilBackWritemask(state.getDepthStencilState().stencilBackWritemask); - setStencilFrontFuncs(depthStencilState.stencilFunc, state.getStencilRef(), depthStencilState.stencilMask); - setStencilBackFuncs(depthStencilState.stencilBackFunc, state.getStencilBackRef(), depthStencilState.stencilBackMask); - setStencilFrontOps(depthStencilState.stencilFail, depthStencilState.stencilPassDepthFail, depthStencilState.stencilPassDepthPass); - setStencilBackOps(depthStencilState.stencilBackFail, depthStencilState.stencilBackPassDepthFail, depthStencilState.stencilBackPassDepthPass); - } + return gl::Error(GL_NO_ERROR); +} - const gl::RasterizerState &rasterizerState = state.getRasterizerState(); - setCullFaceEnabled(rasterizerState.cullFace); - if (rasterizerState.cullFace) +void StateManagerGL::setAttributeCurrentData(size_t index, + const gl::VertexAttribCurrentValueData &data) +{ + if (mVertexAttribCurrentValues[index] != data) { - setCullFace(rasterizerState.cullMode); - setFrontFace(rasterizerState.frontFace); - } + mVertexAttribCurrentValues[index] = data; + switch (mVertexAttribCurrentValues[index].Type) + { + case GL_FLOAT: + mFunctions->vertexAttrib4fv(static_cast(index), + mVertexAttribCurrentValues[index].FloatValues); + break; + case GL_INT: + mFunctions->vertexAttrib4iv(static_cast(index), + mVertexAttribCurrentValues[index].IntValues); + break; + case GL_UNSIGNED_INT: + mFunctions->vertexAttrib4uiv(static_cast(index), + mVertexAttribCurrentValues[index].UnsignedIntValues); + break; + default: UNREACHABLE(); + } - setPolygonOffsetFillEnabled(rasterizerState.polygonOffsetFill); - if (rasterizerState.polygonOffsetFill) - { - setPolygonOffset(rasterizerState.polygonOffsetFactor, rasterizerState.polygonOffsetUnits); + mLocalDirtyBits.set(gl::State::DIRTY_BIT_CURRENT_VALUE_0 + index); } - - setMultisampleEnabled(rasterizerState.multiSample); - setRasterizerDiscardEnabled(rasterizerState.rasterizerDiscard); - setLineWidth(state.getLineWidth()); - - setPrimitiveRestartEnabled(state.isPrimitiveRestartEnabled()); - - return gl::Error(GL_NO_ERROR); } void StateManagerGL::setScissorTestEnabled(bool enabled) @@ -384,6 +823,8 @@ void StateManagerGL::setScissorTestEnabled(bool enabled) { mFunctions->disable(GL_SCISSOR_TEST); } + + mLocalDirtyBits.set(gl::State::DIRTY_BIT_SCISSOR_TEST_ENABLED); } } @@ -393,6 +834,8 @@ void StateManagerGL::setScissor(const gl::Rectangle &scissor) { mScissor = scissor; mFunctions->scissor(mScissor.x, mScissor.y, mScissor.width, mScissor.height); + + mLocalDirtyBits.set(gl::State::DIRTY_BIT_SCISSOR); } } @@ -402,6 +845,8 @@ void StateManagerGL::setViewport(const gl::Rectangle &viewport) { mViewport = viewport; mFunctions->viewport(mViewport.x, mViewport.y, mViewport.width, mViewport.height); + + mLocalDirtyBits.set(gl::State::DIRTY_BIT_VIEWPORT); } } @@ -411,7 +856,20 @@ void StateManagerGL::setDepthRange(float near, float far) { mNear = near; mFar = far; - mFunctions->depthRange(mNear, mFar); + + // The glDepthRangef function isn't available until OpenGL 4.1. Prefer it when it is + // available because OpenGL ES only works in floats. + if (mFunctions->depthRangef) + { + mFunctions->depthRangef(mNear, mFar); + } + else + { + ASSERT(mFunctions->depthRange); + mFunctions->depthRange(mNear, mFar); + } + + mLocalDirtyBits.set(gl::State::DIRTY_BIT_DEPTH_RANGE); } } @@ -428,6 +886,8 @@ void StateManagerGL::setBlendEnabled(bool enabled) { mFunctions->disable(GL_BLEND); } + + mLocalDirtyBits.set(gl::State::DIRTY_BIT_BLEND_ENABLED); } } @@ -437,10 +897,14 @@ void StateManagerGL::setBlendColor(const gl::ColorF &blendColor) { mBlendColor = blendColor; mFunctions->blendColor(mBlendColor.red, mBlendColor.green, mBlendColor.blue, mBlendColor.alpha); + + mLocalDirtyBits.set(gl::State::DIRTY_BIT_BLEND_COLOR); } } -void StateManagerGL::setBlendFuncs(GLenum sourceBlendRGB, GLenum destBlendRGB, GLenum sourceBlendAlpha, +void StateManagerGL::setBlendFuncs(GLenum sourceBlendRGB, + GLenum destBlendRGB, + GLenum sourceBlendAlpha, GLenum destBlendAlpha) { if (mSourceBlendRGB != sourceBlendRGB || mDestBlendRGB != destBlendRGB || @@ -452,6 +916,8 @@ void StateManagerGL::setBlendFuncs(GLenum sourceBlendRGB, GLenum destBlendRGB, G mDestBlendAlpha = destBlendAlpha; mFunctions->blendFuncSeparate(mSourceBlendRGB, mDestBlendRGB, mSourceBlendAlpha, mDestBlendAlpha); + + mLocalDirtyBits.set(gl::State::DIRTY_BIT_BLEND_FUNCS); } } @@ -460,9 +926,11 @@ void StateManagerGL::setBlendEquations(GLenum blendEquationRGB, GLenum blendEqua if (mBlendEquationRGB != blendEquationRGB || mBlendEquationAlpha != blendEquationAlpha) { mBlendEquationRGB = blendEquationRGB; - mBlendEquationAlpha = mDestBlendAlpha; + mBlendEquationAlpha = blendEquationAlpha; mFunctions->blendEquationSeparate(mBlendEquationRGB, mBlendEquationAlpha); + + mLocalDirtyBits.set(gl::State::DIRTY_BIT_BLEND_EQUATIONS); } } @@ -475,6 +943,8 @@ void StateManagerGL::setColorMask(bool red, bool green, bool blue, bool alpha) mColorMaskBlue = blue; mColorMaskAlpha = alpha; mFunctions->colorMask(mColorMaskRed, mColorMaskGreen, mColorMaskBlue, mColorMaskAlpha); + + mLocalDirtyBits.set(gl::State::DIRTY_BIT_COLOR_MASK); } } @@ -491,6 +961,8 @@ void StateManagerGL::setSampleAlphaToCoverageEnabled(bool enabled) { mFunctions->disable(GL_SAMPLE_ALPHA_TO_COVERAGE); } + + mLocalDirtyBits.set(gl::State::DIRTY_BIT_SAMPLE_ALPHA_TO_COVERAGE_ENABLED); } } @@ -507,6 +979,8 @@ void StateManagerGL::setSampleCoverageEnabled(bool enabled) { mFunctions->disable(GL_SAMPLE_COVERAGE); } + + mLocalDirtyBits.set(gl::State::DIRTY_BIT_SAMPLE_COVERAGE_ENABLED); } } @@ -517,6 +991,8 @@ void StateManagerGL::setSampleCoverage(float value, bool invert) mSampleCoverageValue = value; mSampleCoverageInvert = invert; mFunctions->sampleCoverage(mSampleCoverageValue, mSampleCoverageInvert); + + mLocalDirtyBits.set(gl::State::DIRTY_BIT_SAMPLE_COVERAGE); } } @@ -533,6 +1009,8 @@ void StateManagerGL::setDepthTestEnabled(bool enabled) { mFunctions->disable(GL_DEPTH_TEST); } + + mLocalDirtyBits.set(gl::State::DIRTY_BIT_DEPTH_TEST_ENABLED); } } @@ -542,6 +1020,8 @@ void StateManagerGL::setDepthFunc(GLenum depthFunc) { mDepthFunc = depthFunc; mFunctions->depthFunc(mDepthFunc); + + mLocalDirtyBits.set(gl::State::DIRTY_BIT_DEPTH_FUNC); } } @@ -551,6 +1031,8 @@ void StateManagerGL::setDepthMask(bool mask) { mDepthMask = mask; mFunctions->depthMask(mDepthMask); + + mLocalDirtyBits.set(gl::State::DIRTY_BIT_DEPTH_MASK); } } @@ -567,6 +1049,8 @@ void StateManagerGL::setStencilTestEnabled(bool enabled) { mFunctions->disable(GL_STENCIL_TEST); } + + mLocalDirtyBits.set(gl::State::DIRTY_BIT_STENCIL_TEST_ENABLED); } } @@ -576,6 +1060,8 @@ void StateManagerGL::setStencilFrontWritemask(GLuint mask) { mStencilFrontWritemask = mask; mFunctions->stencilMaskSeparate(GL_FRONT, mStencilFrontWritemask); + + mLocalDirtyBits.set(gl::State::DIRTY_BIT_STENCIL_WRITEMASK_FRONT); } } @@ -585,6 +1071,8 @@ void StateManagerGL::setStencilBackWritemask(GLuint mask) { mStencilBackWritemask = mask; mFunctions->stencilMaskSeparate(GL_BACK, mStencilBackWritemask); + + mLocalDirtyBits.set(gl::State::DIRTY_BIT_STENCIL_WRITEMASK_BACK); } } @@ -596,6 +1084,8 @@ void StateManagerGL::setStencilFrontFuncs(GLenum func, GLint ref, GLuint mask) mStencilFrontRef = ref; mStencilFrontValueMask = mask; mFunctions->stencilFuncSeparate(GL_FRONT, mStencilFrontFunc, mStencilFrontRef, mStencilFrontValueMask); + + mLocalDirtyBits.set(gl::State::DIRTY_BIT_STENCIL_FUNCS_FRONT); } } @@ -607,6 +1097,8 @@ void StateManagerGL::setStencilBackFuncs(GLenum func, GLint ref, GLuint mask) mStencilBackRef = ref; mStencilBackValueMask = mask; mFunctions->stencilFuncSeparate(GL_BACK, mStencilBackFunc, mStencilBackRef, mStencilBackValueMask); + + mLocalDirtyBits.set(gl::State::DIRTY_BIT_STENCIL_FUNCS_BACK); } } @@ -618,6 +1110,8 @@ void StateManagerGL::setStencilFrontOps(GLenum sfail, GLenum dpfail, GLenum dppa mStencilFrontStencilPassDepthFailOp = dpfail; mStencilFrontStencilPassDepthPassOp = dppass; mFunctions->stencilOpSeparate(GL_FRONT, mStencilFrontStencilFailOp, mStencilFrontStencilPassDepthFailOp, mStencilFrontStencilPassDepthPassOp); + + mLocalDirtyBits.set(gl::State::DIRTY_BIT_STENCIL_OPS_FRONT); } } @@ -629,6 +1123,8 @@ void StateManagerGL::setStencilBackOps(GLenum sfail, GLenum dpfail, GLenum dppas mStencilBackStencilPassDepthFailOp = dpfail; mStencilBackStencilPassDepthPassOp = dppass; mFunctions->stencilOpSeparate(GL_BACK, mStencilBackStencilFailOp, mStencilBackStencilPassDepthFailOp, mStencilBackStencilPassDepthPassOp); + + mLocalDirtyBits.set(gl::State::DIRTY_BIT_STENCIL_OPS_BACK); } } @@ -645,6 +1141,8 @@ void StateManagerGL::setCullFaceEnabled(bool enabled) { mFunctions->disable(GL_CULL_FACE); } + + mLocalDirtyBits.set(gl::State::DIRTY_BIT_CULL_FACE_ENABLED); } } @@ -654,6 +1152,8 @@ void StateManagerGL::setCullFace(GLenum cullFace) { mCullFace = cullFace; mFunctions->cullFace(mCullFace); + + mLocalDirtyBits.set(gl::State::DIRTY_BIT_CULL_FACE); } } @@ -663,6 +1163,8 @@ void StateManagerGL::setFrontFace(GLenum frontFace) { mFrontFace = frontFace; mFunctions->frontFace(mFrontFace); + + mLocalDirtyBits.set(gl::State::DIRTY_BIT_FRONT_FACE); } } @@ -679,6 +1181,8 @@ void StateManagerGL::setPolygonOffsetFillEnabled(bool enabled) { mFunctions->disable(GL_POLYGON_OFFSET_FILL); } + + mLocalDirtyBits.set(gl::State::DIRTY_BIT_POLYGON_OFFSET_FILL_ENABLED); } } @@ -689,22 +1193,8 @@ void StateManagerGL::setPolygonOffset(float factor, float units) mPolygonOffsetFactor = factor; mPolygonOffsetUnits = units; mFunctions->polygonOffset(mPolygonOffsetFactor, mPolygonOffsetUnits); - } -} -void StateManagerGL::setMultisampleEnabled(bool enabled) -{ - if (mMultisampleEnabled != enabled) - { - mMultisampleEnabled = enabled; - if (mMultisampleEnabled) - { - mFunctions->enable(GL_MULTISAMPLE); - } - else - { - mFunctions->disable(GL_MULTISAMPLE); - } + mLocalDirtyBits.set(gl::State::DIRTY_BIT_POLYGON_OFFSET); } } @@ -721,6 +1211,8 @@ void StateManagerGL::setRasterizerDiscardEnabled(bool enabled) { mFunctions->disable(GL_RASTERIZER_DISCARD); } + + mLocalDirtyBits.set(gl::State::DIRTY_BIT_RASTERIZER_DISCARD_ENABLED); } } @@ -730,6 +1222,8 @@ void StateManagerGL::setLineWidth(float width) { mLineWidth = width; mFunctions->lineWidth(mLineWidth); + + mLocalDirtyBits.set(gl::State::DIRTY_BIT_LINE_WIDTH); } } @@ -747,6 +1241,8 @@ void StateManagerGL::setPrimitiveRestartEnabled(bool enabled) { mFunctions->disable(GL_PRIMITIVE_RESTART_FIXED_INDEX); } + + mLocalDirtyBits.set(gl::State::DIRTY_BIT_PRIMITIVE_RESTART_ENABLED); } } @@ -755,7 +1251,20 @@ void StateManagerGL::setClearDepth(float clearDepth) if (mClearDepth != clearDepth) { mClearDepth = clearDepth; - mFunctions->clearDepth(mClearDepth); + + // The glClearDepthf function isn't available until OpenGL 4.1. Prefer it when it is + // available because OpenGL ES only works in floats. + if (mFunctions->clearDepthf) + { + mFunctions->clearDepthf(mClearDepth); + } + else + { + ASSERT(mFunctions->clearDepth); + mFunctions->clearDepth(mClearDepth); + } + + mLocalDirtyBits.set(gl::State::DIRTY_BIT_CLEAR_DEPTH); } } @@ -765,6 +1274,8 @@ void StateManagerGL::setClearColor(const gl::ColorF &clearColor) { mClearColor = clearColor; mFunctions->clearColor(mClearColor.red, mClearColor.green, mClearColor.blue, mClearColor.alpha); + + mLocalDirtyBits.set(gl::State::DIRTY_BIT_CLEAR_COLOR); } } @@ -774,6 +1285,270 @@ void StateManagerGL::setClearStencil(GLint clearStencil) { mClearStencil = clearStencil; mFunctions->clearStencil(mClearStencil); + + mLocalDirtyBits.set(gl::State::DIRTY_BIT_CLEAR_STENCIL); + } +} + +void StateManagerGL::syncState(const gl::State &state, const gl::State::DirtyBits &glDirtyBits) +{ + const auto &glAndLocalDirtyBits = (glDirtyBits | mLocalDirtyBits); + + if (!glAndLocalDirtyBits.any()) + { + return; + } + + // TODO(jmadill): Investigate only syncing vertex state for active attributes + for (auto dirtyBit : angle::IterateBitSet(glAndLocalDirtyBits)) + { + switch (dirtyBit) + { + case gl::State::DIRTY_BIT_SCISSOR_TEST_ENABLED: + setScissorTestEnabled(state.isScissorTestEnabled()); + break; + case gl::State::DIRTY_BIT_SCISSOR: + setScissor(state.getScissor()); + break; + case gl::State::DIRTY_BIT_VIEWPORT: + setViewport(state.getViewport()); + break; + case gl::State::DIRTY_BIT_DEPTH_RANGE: + setDepthRange(state.getNearPlane(), state.getFarPlane()); + break; + case gl::State::DIRTY_BIT_BLEND_ENABLED: + setBlendEnabled(state.isBlendEnabled()); + break; + case gl::State::DIRTY_BIT_BLEND_COLOR: + setBlendColor(state.getBlendColor()); + break; + case gl::State::DIRTY_BIT_BLEND_FUNCS: + { + const auto &blendState = state.getBlendState(); + setBlendFuncs(blendState.sourceBlendRGB, blendState.destBlendRGB, + blendState.sourceBlendAlpha, blendState.destBlendAlpha); + break; + } + case gl::State::DIRTY_BIT_BLEND_EQUATIONS: + { + const auto &blendState = state.getBlendState(); + setBlendEquations(blendState.blendEquationRGB, blendState.blendEquationAlpha); + break; + } + case gl::State::DIRTY_BIT_COLOR_MASK: + { + const auto &blendState = state.getBlendState(); + setColorMask(blendState.colorMaskRed, blendState.colorMaskGreen, + blendState.colorMaskBlue, blendState.colorMaskAlpha); + break; + } + case gl::State::DIRTY_BIT_SAMPLE_ALPHA_TO_COVERAGE_ENABLED: + setSampleAlphaToCoverageEnabled(state.isSampleAlphaToCoverageEnabled()); + break; + case gl::State::DIRTY_BIT_SAMPLE_COVERAGE_ENABLED: + setSampleCoverageEnabled(state.isSampleCoverageEnabled()); + break; + case gl::State::DIRTY_BIT_SAMPLE_COVERAGE: + setSampleCoverage(state.getSampleCoverageValue(), state.getSampleCoverageInvert()); + break; + case gl::State::DIRTY_BIT_DEPTH_TEST_ENABLED: + setDepthTestEnabled(state.isDepthTestEnabled()); + break; + case gl::State::DIRTY_BIT_DEPTH_FUNC: + setDepthFunc(state.getDepthStencilState().depthFunc); + break; + case gl::State::DIRTY_BIT_DEPTH_MASK: + setDepthMask(state.getDepthStencilState().depthMask); + break; + case gl::State::DIRTY_BIT_STENCIL_TEST_ENABLED: + setStencilTestEnabled(state.isStencilTestEnabled()); + break; + case gl::State::DIRTY_BIT_STENCIL_FUNCS_FRONT: + { + const auto &depthStencilState = state.getDepthStencilState(); + setStencilFrontFuncs(depthStencilState.stencilFunc, state.getStencilRef(), + depthStencilState.stencilMask); + break; + } + case gl::State::DIRTY_BIT_STENCIL_FUNCS_BACK: + { + const auto &depthStencilState = state.getDepthStencilState(); + setStencilBackFuncs(depthStencilState.stencilBackFunc, state.getStencilBackRef(), + depthStencilState.stencilBackMask); + break; + } + case gl::State::DIRTY_BIT_STENCIL_OPS_FRONT: + { + const auto &depthStencilState = state.getDepthStencilState(); + setStencilFrontOps(depthStencilState.stencilFail, + depthStencilState.stencilPassDepthFail, + depthStencilState.stencilPassDepthPass); + break; + } + case gl::State::DIRTY_BIT_STENCIL_OPS_BACK: + { + const auto &depthStencilState = state.getDepthStencilState(); + setStencilBackOps(depthStencilState.stencilBackFail, + depthStencilState.stencilBackPassDepthFail, + depthStencilState.stencilBackPassDepthPass); + break; + } + case gl::State::DIRTY_BIT_STENCIL_WRITEMASK_FRONT: + setStencilFrontWritemask(state.getDepthStencilState().stencilWritemask); + break; + case gl::State::DIRTY_BIT_STENCIL_WRITEMASK_BACK: + setStencilBackWritemask(state.getDepthStencilState().stencilBackWritemask); + break; + case gl::State::DIRTY_BIT_CULL_FACE_ENABLED: + setCullFaceEnabled(state.isCullFaceEnabled()); + break; + case gl::State::DIRTY_BIT_CULL_FACE: + setCullFace(state.getRasterizerState().cullMode); + break; + case gl::State::DIRTY_BIT_FRONT_FACE: + setFrontFace(state.getRasterizerState().frontFace); + break; + case gl::State::DIRTY_BIT_POLYGON_OFFSET_FILL_ENABLED: + setPolygonOffsetFillEnabled(state.isPolygonOffsetFillEnabled()); + break; + case gl::State::DIRTY_BIT_POLYGON_OFFSET: + { + const auto &rasterizerState = state.getRasterizerState(); + setPolygonOffset(rasterizerState.polygonOffsetFactor, + rasterizerState.polygonOffsetUnits); + break; + } + case gl::State::DIRTY_BIT_RASTERIZER_DISCARD_ENABLED: + setRasterizerDiscardEnabled(state.isRasterizerDiscardEnabled()); + break; + case gl::State::DIRTY_BIT_LINE_WIDTH: + setLineWidth(state.getLineWidth()); + break; + case gl::State::DIRTY_BIT_PRIMITIVE_RESTART_ENABLED: + setPrimitiveRestartEnabled(state.isPrimitiveRestartEnabled()); + break; + case gl::State::DIRTY_BIT_CLEAR_COLOR: + setClearColor(state.getColorClearValue()); + break; + case gl::State::DIRTY_BIT_CLEAR_DEPTH: + setClearDepth(state.getDepthClearValue()); + break; + case gl::State::DIRTY_BIT_CLEAR_STENCIL: + setClearStencil(state.getStencilClearValue()); + break; + case gl::State::DIRTY_BIT_UNPACK_ALIGNMENT: + // TODO(jmadill): split this + setPixelUnpackState(state.getUnpackState()); + break; + case gl::State::DIRTY_BIT_UNPACK_ROW_LENGTH: + // TODO(jmadill): split this + setPixelUnpackState(state.getUnpackState()); + break; + case gl::State::DIRTY_BIT_UNPACK_IMAGE_HEIGHT: + // TODO(jmadill): split this + setPixelUnpackState(state.getUnpackState()); + break; + case gl::State::DIRTY_BIT_UNPACK_SKIP_IMAGES: + // TODO(jmadill): split this + setPixelUnpackState(state.getUnpackState()); + break; + case gl::State::DIRTY_BIT_UNPACK_SKIP_ROWS: + // TODO(jmadill): split this + setPixelUnpackState(state.getUnpackState()); + break; + case gl::State::DIRTY_BIT_UNPACK_SKIP_PIXELS: + // TODO(jmadill): split this + setPixelUnpackState(state.getUnpackState()); + break; + case gl::State::DIRTY_BIT_PACK_ALIGNMENT: + // TODO(jmadill): split this + setPixelPackState(state.getPackState()); + break; + case gl::State::DIRTY_BIT_PACK_REVERSE_ROW_ORDER: + // TODO(jmadill): split this + setPixelPackState(state.getPackState()); + break; + case gl::State::DIRTY_BIT_PACK_ROW_LENGTH: + // TODO(jmadill): split this + setPixelPackState(state.getPackState()); + break; + case gl::State::DIRTY_BIT_PACK_SKIP_ROWS: + // TODO(jmadill): split this + setPixelPackState(state.getPackState()); + break; + case gl::State::DIRTY_BIT_PACK_SKIP_PIXELS: + // TODO(jmadill): split this + setPixelPackState(state.getPackState()); + break; + case gl::State::DIRTY_BIT_DITHER_ENABLED: + // TODO(jmadill): implement this + break; + case gl::State::DIRTY_BIT_GENERATE_MIPMAP_HINT: + // TODO(jmadill): implement this + break; + case gl::State::DIRTY_BIT_SHADER_DERIVATIVE_HINT: + // TODO(jmadill): implement this + break; + case gl::State::DIRTY_BIT_READ_FRAMEBUFFER_BINDING: + // TODO(jmadill): implement this + break; + case gl::State::DIRTY_BIT_DRAW_FRAMEBUFFER_BINDING: + // TODO(jmadill): implement this + break; + case gl::State::DIRTY_BIT_RENDERBUFFER_BINDING: + // TODO(jmadill): implement this + break; + case gl::State::DIRTY_BIT_VERTEX_ARRAY_BINDING: + // TODO(jmadill): implement this + break; + case gl::State::DIRTY_BIT_PROGRAM_BINDING: + // TODO(jmadill): implement this + break; + default: + { + ASSERT(dirtyBit >= gl::State::DIRTY_BIT_CURRENT_VALUE_0 && + dirtyBit < gl::State::DIRTY_BIT_CURRENT_VALUE_MAX); + size_t attribIndex = + static_cast(dirtyBit) - gl::State::DIRTY_BIT_CURRENT_VALUE_0; + setAttributeCurrentData(attribIndex, state.getVertexAttribCurrentValue( + static_cast(attribIndex))); + break; + } + } + + mLocalDirtyBits.reset(); + } +} + +void StateManagerGL::setFramebufferSRGBEnabled(bool enabled) +{ + if (mFramebufferSRGBEnabled != enabled) + { + mFramebufferSRGBEnabled = enabled; + if (mFramebufferSRGBEnabled) + { + mFunctions->enable(GL_FRAMEBUFFER_SRGB); + } + else + { + mFunctions->disable(GL_FRAMEBUFFER_SRGB); + } + } +} + +void StateManagerGL::setTextureCubemapSeamlessEnabled(bool enabled) +{ + if (mTextureCubemapSeamlessEnabled != enabled) + { + mTextureCubemapSeamlessEnabled = enabled; + if (mTextureCubemapSeamlessEnabled) + { + mFunctions->enable(GL_TEXTURE_CUBE_MAP_SEAMLESS); + } + else + { + mFunctions->disable(GL_TEXTURE_CUBE_MAP_SEAMLESS); + } } } diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/StateManagerGL.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/StateManagerGL.h index 5232a2446b18..d211869bc5f2 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/StateManagerGL.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/StateManagerGL.h @@ -11,6 +11,7 @@ #include "common/debug.h" #include "libANGLE/Error.h" +#include "libANGLE/State.h" #include "libANGLE/angletypes.h" #include "libANGLE/renderer/gl/functionsgl_typedefs.h" @@ -27,29 +28,41 @@ namespace rx { class FunctionsGL; +class TransformFeedbackGL; +class QueryGL; -class StateManagerGL : angle::NonCopyable +class StateManagerGL final : angle::NonCopyable { public: StateManagerGL(const FunctionsGL *functions, const gl::Caps &rendererCaps); + void deleteProgram(GLuint program); + void deleteVertexArray(GLuint vao); + void deleteTexture(GLuint texture); + void deleteSampler(GLuint sampler); + void deleteBuffer(GLuint buffer); + void deleteFramebuffer(GLuint fbo); + void deleteRenderbuffer(GLuint rbo); + void deleteTransformFeedback(GLuint transformFeedback); + void deleteQuery(GLuint query); + void useProgram(GLuint program); - void bindVertexArray(GLuint vao); + void forceUseProgram(GLuint program); + void bindVertexArray(GLuint vao, GLuint elementArrayBuffer); void bindBuffer(GLenum type, GLuint buffer); + void bindBufferBase(GLenum type, size_t index, GLuint buffer); + void bindBufferRange(GLenum type, size_t index, GLuint buffer, size_t offset, size_t size); void activeTexture(size_t unit); void bindTexture(GLenum type, GLuint texture); - void setPixelUnpackState(GLint alignment, GLint rowLength); + void bindSampler(size_t unit, GLuint sampler); void bindFramebuffer(GLenum type, GLuint framebuffer); void bindRenderbuffer(GLenum type, GLuint renderbuffer); + void bindTransformFeedback(GLenum type, GLuint transformFeedback); + void beginQuery(GLenum type, GLuint query); + void endQuery(GLenum type, GLuint query); + void onBeginQuery(QueryGL *query); - void setClearState(const gl::State &state, GLbitfield mask); - - gl::Error setDrawArraysState(const gl::Data &data, GLint first, GLsizei count); - gl::Error setDrawElementsState(const gl::Data &data, GLsizei count, GLenum type, const GLvoid *indices, - const GLvoid **outIndices); - - private: - gl::Error setGenericDrawState(const gl::Data &data); + void setAttributeCurrentData(size_t index, const gl::VertexAttribCurrentValueData &data); void setScissorTestEnabled(bool enabled); void setScissor(const gl::Rectangle &scissor); @@ -59,7 +72,10 @@ class StateManagerGL : angle::NonCopyable void setBlendEnabled(bool enabled); void setBlendColor(const gl::ColorF &blendColor); - void setBlendFuncs(GLenum sourceBlendRGB, GLenum destBlendRGB, GLenum sourceBlendAlpha, GLenum destBlendAlpha); + void setBlendFuncs(GLenum sourceBlendRGB, + GLenum destBlendRGB, + GLenum sourceBlendAlpha, + GLenum destBlendAlpha); void setBlendEquations(GLenum blendEquationRGB, GLenum blendEquationAlpha); void setColorMask(bool red, bool green, bool blue, bool alpha); void setSampleAlphaToCoverageEnabled(bool enabled); @@ -82,7 +98,6 @@ class StateManagerGL : angle::NonCopyable void setFrontFace(GLenum frontFace); void setPolygonOffsetFillEnabled(bool enabled); void setPolygonOffset(float factor, float units); - void setMultisampleEnabled(bool enabled); void setRasterizerDiscardEnabled(bool enabled); void setLineWidth(float width); @@ -92,19 +107,90 @@ class StateManagerGL : angle::NonCopyable void setClearDepth(float clearDepth); void setClearStencil(GLint clearStencil); + void setPixelUnpackState(const gl::PixelUnpackState &unpack); + void setPixelUnpackState(GLint alignment, + GLint rowLength, + GLint skipRows, + GLint skipPixels, + GLint imageHeight, + GLint skipImages, + GLuint unpackBuffer); + void setPixelPackState(const gl::PixelPackState &pack); + void setPixelPackState(GLint alignment, + GLint rowLength, + GLint skipRows, + GLint skipPixels, + GLuint packBuffer); + + void setFramebufferSRGBEnabled(bool enabled); + + void onDeleteQueryObject(QueryGL *query); + + gl::Error setDrawArraysState(const gl::Data &data, + GLint first, + GLsizei count, + GLsizei instanceCount); + gl::Error setDrawElementsState(const gl::Data &data, + GLsizei count, + GLenum type, + const GLvoid *indices, + GLsizei instanceCount, + const GLvoid **outIndices); + + gl::Error onMakeCurrent(const gl::Data &data); + + void syncState(const gl::State &state, const gl::State::DirtyBits &glDirtyBits); + + private: + gl::Error setGenericDrawState(const gl::Data &data); + + void setTextureCubemapSeamlessEnabled(bool enabled); + const FunctionsGL *mFunctions; GLuint mProgram; + GLuint mVAO; + std::vector mVertexAttribCurrentValues; + std::map mBuffers; + struct IndexedBufferBinding + { + IndexedBufferBinding(); + + size_t offset; + size_t size; + GLuint buffer; + }; + std::map> mIndexedBuffers; + size_t mTextureUnitIndex; std::map> mTextures; + std::vector mSamplers; + + GLuint mTransformFeedback; + + std::map mQueries; + + TransformFeedbackGL *mPrevDrawTransformFeedback; + std::set mCurrentQueries; + uintptr_t mPrevDrawContext; GLint mUnpackAlignment; GLint mUnpackRowLength; - - std::map mFramebuffers; + GLint mUnpackSkipRows; + GLint mUnpackSkipPixels; + GLint mUnpackImageHeight; + GLint mUnpackSkipImages; + + GLint mPackAlignment; + GLint mPackRowLength; + GLint mPackSkipRows; + GLint mPackSkipPixels; + + // TODO(jmadill): Convert to std::array when available + std::vector mFramebuffers; GLuint mRenderbuffer; bool mScissorTestEnabled; @@ -156,7 +242,6 @@ class StateManagerGL : angle::NonCopyable bool mPolygonOffsetFillEnabled; GLfloat mPolygonOffsetFactor; GLfloat mPolygonOffsetUnits; - bool mMultisampleEnabled; bool mRasterizerDiscardEnabled; float mLineWidth; @@ -165,6 +250,11 @@ class StateManagerGL : angle::NonCopyable gl::ColorF mClearColor; float mClearDepth; GLint mClearStencil; + + bool mFramebufferSRGBEnabled; + bool mTextureCubemapSeamlessEnabled; + + gl::State::DirtyBits mLocalDirtyBits; }; } diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/SurfaceGL.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/SurfaceGL.cpp index 592b1d2bfa90..46627847e6d7 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/SurfaceGL.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/SurfaceGL.cpp @@ -8,11 +8,13 @@ #include "libANGLE/renderer/gl/SurfaceGL.h" +#include "libANGLE/renderer/gl/FramebufferGL.h" +#include "libANGLE/renderer/gl/RendererGL.h" + namespace rx { -SurfaceGL::SurfaceGL() - : SurfaceImpl() +SurfaceGL::SurfaceGL(RendererGL *renderer) : SurfaceImpl(), mRenderer(renderer) { } @@ -20,4 +22,9 @@ SurfaceGL::~SurfaceGL() { } +FramebufferImpl *SurfaceGL::createDefaultFramebuffer(const gl::Framebuffer::Data &data) +{ + return new FramebufferGL(data, mRenderer->getFunctions(), mRenderer->getStateManager(), + mRenderer->getWorkarounds(), true); +} } diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/SurfaceGL.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/SurfaceGL.h index aa8c7ee81cf4..e056dd2a8728 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/SurfaceGL.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/SurfaceGL.h @@ -14,10 +14,12 @@ namespace rx { +class RendererGL; + class SurfaceGL : public SurfaceImpl { public: - SurfaceGL(); + SurfaceGL(RendererGL *renderer); ~SurfaceGL() override; gl::Error getAttachmentRenderTarget(const gl::FramebufferAttachment::Target &target, @@ -26,7 +28,12 @@ class SurfaceGL : public SurfaceImpl return gl::Error(GL_OUT_OF_MEMORY, "Not supported on OpenGL"); } + FramebufferImpl *createDefaultFramebuffer(const gl::Framebuffer::Data &data) override; + virtual egl::Error makeCurrent() = 0; + + private: + RendererGL *mRenderer; }; } diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/TextureGL.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/TextureGL.cpp index 1a9c6657c522..a30d70d70202 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/TextureGL.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/TextureGL.cpp @@ -13,28 +13,17 @@ #include "libANGLE/State.h" #include "libANGLE/angletypes.h" #include "libANGLE/formatutils.h" +#include "libANGLE/renderer/gl/BlitGL.h" #include "libANGLE/renderer/gl/BufferGL.h" #include "libANGLE/renderer/gl/FramebufferGL.h" #include "libANGLE/renderer/gl/FunctionsGL.h" #include "libANGLE/renderer/gl/StateManagerGL.h" +#include "libANGLE/renderer/gl/WorkaroundsGL.h" +#include "libANGLE/renderer/gl/formatutilsgl.h" namespace rx { -static void SetUnpackStateForTexImage(StateManagerGL *stateManager, const gl::PixelUnpackState &unpack) -{ - const gl::Buffer *unpackBuffer = unpack.pixelBuffer.get(); - if (unpackBuffer != nullptr) - { - UNIMPLEMENTED(); - } - if (unpack.skipRows != 0 || unpack.skipPixels != 0 || unpack.imageHeight != 0 || unpack.skipImages != 0) - { - UNIMPLEMENTED(); - } - stateManager->setPixelUnpackState(unpack.alignment, unpack.rowLength); -} - static bool UseTexImage2D(GLenum textureType) { return textureType == GL_TEXTURE_2D || textureType == GL_TEXTURE_CUBE_MAP; @@ -57,27 +46,93 @@ static bool CompatibleTextureTarget(GLenum textureType, GLenum textureTarget) } } -TextureGL::TextureGL(GLenum type, const FunctionsGL *functions, StateManagerGL *stateManager) +static bool IsLUMAFormat(GLenum format) +{ + return format == GL_LUMINANCE || format == GL_ALPHA || format == GL_LUMINANCE_ALPHA; +} + +static LUMAWorkaroundGL GetLUMAWorkaroundInfo(const gl::InternalFormat &originalFormatInfo, + GLenum destinationFormat) +{ + if (IsLUMAFormat(originalFormatInfo.format)) + { + const gl::InternalFormat &destinationFormatInfo = + gl::GetInternalFormatInfo(destinationFormat); + return LUMAWorkaroundGL(!IsLUMAFormat(destinationFormatInfo.format), + destinationFormatInfo.format); + } + else + { + return LUMAWorkaroundGL(false, GL_NONE); + } +} + +static bool IsDepthStencilFormat(GLenum format) +{ + return format == GL_DEPTH_COMPONENT || format == GL_DEPTH_STENCIL; +} + +static bool GetDepthStencilWorkaround(const gl::InternalFormat &originalFormatInfo) +{ + return IsDepthStencilFormat(originalFormatInfo.format); +} + +static LevelInfoGL GetLevelInfo(GLenum originalFormat, GLenum destinationFormat) +{ + const gl::InternalFormat &originalFormatInfo = gl::GetInternalFormatInfo(originalFormat); + return LevelInfoGL(originalFormat, GetDepthStencilWorkaround(originalFormatInfo), + GetLUMAWorkaroundInfo(originalFormatInfo, destinationFormat)); +} + +LUMAWorkaroundGL::LUMAWorkaroundGL() : LUMAWorkaroundGL(false, GL_NONE) +{ +} + +LUMAWorkaroundGL::LUMAWorkaroundGL(bool enabled_, GLenum workaroundFormat_) + : enabled(enabled_), workaroundFormat(workaroundFormat_) +{ +} + +LevelInfoGL::LevelInfoGL() : LevelInfoGL(GL_NONE, false, LUMAWorkaroundGL()) +{ +} + +LevelInfoGL::LevelInfoGL(GLenum sourceFormat_, + bool depthStencilWorkaround_, + const LUMAWorkaroundGL &lumaWorkaround_) + : sourceFormat(sourceFormat_), + depthStencilWorkaround(depthStencilWorkaround_), + lumaWorkaround(lumaWorkaround_) +{ +} + +TextureGL::TextureGL(GLenum type, + const FunctionsGL *functions, + const WorkaroundsGL &workarounds, + StateManagerGL *stateManager, + BlitGL *blitter) : TextureImpl(), mTextureType(type), mFunctions(functions), + mWorkarounds(workarounds), mStateManager(stateManager), - mAppliedSamplerState(), + mBlitter(blitter), + mLevelInfo(gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS), + mAppliedTextureState(), mTextureID(0) { ASSERT(mFunctions); ASSERT(mStateManager); + ASSERT(mBlitter); mFunctions->genTextures(1, &mTextureID); + mStateManager->bindTexture(mTextureType, mTextureID); } TextureGL::~TextureGL() { - if (mTextureID) - { - mFunctions->deleteTextures(1, &mTextureID); - mTextureID = 0; - } + mStateManager->deleteTexture(mTextureID); + mTextureID = 0; } void TextureGL::setUsage(GLenum usage) @@ -92,23 +147,30 @@ gl::Error TextureGL::setImage(GLenum target, size_t level, GLenum internalFormat UNUSED_ASSERTION_VARIABLE(&CompatibleTextureTarget); // Reference this function to avoid warnings. ASSERT(CompatibleTextureTarget(mTextureType, target)); - SetUnpackStateForTexImage(mStateManager, unpack); + nativegl::TexImageFormat texImageFormat = + nativegl::GetTexImageFormat(mFunctions, mWorkarounds, internalFormat, format, type); mStateManager->bindTexture(mTextureType, mTextureID); if (UseTexImage2D(mTextureType)) { ASSERT(size.depth == 1); - mFunctions->texImage2D(target, level, internalFormat, size.width, size.height, 0, format, type, pixels); + mFunctions->texImage2D(target, static_cast(level), texImageFormat.internalFormat, + size.width, size.height, 0, texImageFormat.format, + texImageFormat.type, pixels); } else if (UseTexImage3D(mTextureType)) { - mFunctions->texImage3D(target, level, internalFormat, size.width, size.height, size.depth, 0, format, type, pixels); + mFunctions->texImage3D(target, static_cast(level), texImageFormat.internalFormat, + size.width, size.height, size.depth, 0, texImageFormat.format, + texImageFormat.type, pixels); } else { UNREACHABLE(); } + mLevelInfo[level] = GetLevelInfo(internalFormat, texImageFormat.internalFormat); + return gl::Error(GL_NO_ERROR); } @@ -117,108 +179,140 @@ gl::Error TextureGL::setSubImage(GLenum target, size_t level, const gl::Box &are { ASSERT(CompatibleTextureTarget(mTextureType, target)); - SetUnpackStateForTexImage(mStateManager, unpack); + nativegl::TexSubImageFormat texSubImageFormat = + nativegl::GetTexSubImageFormat(mFunctions, mWorkarounds, format, type); mStateManager->bindTexture(mTextureType, mTextureID); if (UseTexImage2D(mTextureType)) { ASSERT(area.z == 0 && area.depth == 1); - mFunctions->texSubImage2D(target, level, area.x, area.y, area.width, area.height, format, type, pixels); + mFunctions->texSubImage2D(target, static_cast(level), area.x, area.y, area.width, + area.height, texSubImageFormat.format, texSubImageFormat.type, + pixels); } else if (UseTexImage3D(mTextureType)) { - mFunctions->texSubImage3D(target, level, area.x, area.y, area.z, area.width, area.height, area.depth, - format, type, pixels); + mFunctions->texSubImage3D(target, static_cast(level), area.x, area.y, area.z, + area.width, area.height, area.depth, texSubImageFormat.format, + texSubImageFormat.type, pixels); } else { UNREACHABLE(); } + ASSERT(mLevelInfo[level].lumaWorkaround.enabled == + GetLevelInfo(format, texSubImageFormat.format).lumaWorkaround.enabled); + return gl::Error(GL_NO_ERROR); } gl::Error TextureGL::setCompressedImage(GLenum target, size_t level, GLenum internalFormat, const gl::Extents &size, - const gl::PixelUnpackState &unpack, const uint8_t *pixels) + const gl::PixelUnpackState &unpack, size_t imageSize, const uint8_t *pixels) { ASSERT(CompatibleTextureTarget(mTextureType, target)); - SetUnpackStateForTexImage(mStateManager, unpack); - - const gl::InternalFormat &internalFormatInfo = gl::GetInternalFormatInfo(internalFormat); - size_t depthPitch = internalFormatInfo.computeDepthPitch(GL_UNSIGNED_BYTE, size.width, size.height, - unpack.alignment, unpack.rowLength); - size_t dataSize = internalFormatInfo.computeBlockSize(GL_UNSIGNED_BYTE, size.width, size.height) * depthPitch; + nativegl::CompressedTexImageFormat compressedTexImageFormat = + nativegl::GetCompressedTexImageFormat(mFunctions, mWorkarounds, internalFormat); mStateManager->bindTexture(mTextureType, mTextureID); if (UseTexImage2D(mTextureType)) { ASSERT(size.depth == 1); - mFunctions->compressedTexImage2D(target, level, internalFormat, size.width, size.height, 0, dataSize, pixels); + mFunctions->compressedTexImage2D(target, static_cast(level), + compressedTexImageFormat.internalFormat, size.width, + size.height, 0, static_cast(imageSize), pixels); } else if (UseTexImage3D(mTextureType)) { - mFunctions->compressedTexImage3D(target, level, internalFormat, size.width, size.height, size.depth, 0, - dataSize, pixels); + mFunctions->compressedTexImage3D( + target, static_cast(level), compressedTexImageFormat.internalFormat, size.width, + size.height, size.depth, 0, static_cast(imageSize), pixels); } else { UNREACHABLE(); } + mLevelInfo[level] = GetLevelInfo(internalFormat, compressedTexImageFormat.internalFormat); + ASSERT(!mLevelInfo[level].lumaWorkaround.enabled); + return gl::Error(GL_NO_ERROR); } gl::Error TextureGL::setCompressedSubImage(GLenum target, size_t level, const gl::Box &area, GLenum format, - const gl::PixelUnpackState &unpack, const uint8_t *pixels) + const gl::PixelUnpackState &unpack, size_t imageSize, const uint8_t *pixels) { ASSERT(CompatibleTextureTarget(mTextureType, target)); - SetUnpackStateForTexImage(mStateManager, unpack); - - const gl::InternalFormat &internalFormatInfo = gl::GetInternalFormatInfo(format); - size_t depthPitch = internalFormatInfo.computeDepthPitch(GL_UNSIGNED_BYTE, area.width, area.height, - unpack.alignment, unpack.rowLength); - size_t dataSize = internalFormatInfo.computeBlockSize(GL_UNSIGNED_BYTE, area.width, area.height) * depthPitch; + nativegl::CompressedTexSubImageFormat compressedTexSubImageFormat = + nativegl::GetCompressedSubTexImageFormat(mFunctions, mWorkarounds, format); mStateManager->bindTexture(mTextureType, mTextureID); if (UseTexImage2D(mTextureType)) { ASSERT(area.z == 0 && area.depth == 1); - mFunctions->compressedTexSubImage2D(target, level, area.x, area.y, area.width, area.height, format, dataSize, - pixels); + mFunctions->compressedTexSubImage2D( + target, static_cast(level), area.x, area.y, area.width, area.height, + compressedTexSubImageFormat.format, static_cast(imageSize), pixels); } else if (UseTexImage3D(mTextureType)) { - mFunctions->compressedTexSubImage3D(target, level, area.x, area.y, area.z, area.width, area.height, area.depth, - format, dataSize, pixels); + mFunctions->compressedTexSubImage3D(target, static_cast(level), area.x, area.y, + area.z, area.width, area.height, area.depth, + compressedTexSubImageFormat.format, + static_cast(imageSize), pixels); } else { UNREACHABLE(); } + ASSERT(!mLevelInfo[level].lumaWorkaround.enabled && + !GetLevelInfo(format, compressedTexSubImageFormat.format).lumaWorkaround.enabled); + return gl::Error(GL_NO_ERROR); } gl::Error TextureGL::copyImage(GLenum target, size_t level, const gl::Rectangle &sourceArea, GLenum internalFormat, const gl::Framebuffer *source) { - const FramebufferGL *sourceFramebufferGL = GetImplAs(source); + nativegl::CopyTexImageImageFormat copyTexImageFormat = nativegl::GetCopyTexImageImageFormat( + mFunctions, mWorkarounds, internalFormat, source->getImplementationColorReadType()); - mStateManager->bindTexture(mTextureType, mTextureID); - mStateManager->bindFramebuffer(GL_READ_FRAMEBUFFER, sourceFramebufferGL->getFramebufferID()); - - if (UseTexImage2D(mTextureType)) + LevelInfoGL levelInfo = GetLevelInfo(internalFormat, copyTexImageFormat.internalFormat); + if (levelInfo.lumaWorkaround.enabled) { - mFunctions->copyTexImage2D(target, level, internalFormat, sourceArea.x, sourceArea.y, - sourceArea.width, sourceArea.height, 0); + gl::Error error = mBlitter->copyImageToLUMAWorkaroundTexture( + mTextureID, mTextureType, target, levelInfo.sourceFormat, level, sourceArea, + copyTexImageFormat.internalFormat, source); + if (error.isError()) + { + return error; + } } else { - UNREACHABLE(); + const FramebufferGL *sourceFramebufferGL = GetImplAs(source); + + mStateManager->bindTexture(mTextureType, mTextureID); + mStateManager->bindFramebuffer(GL_READ_FRAMEBUFFER, + sourceFramebufferGL->getFramebufferID()); + + if (UseTexImage2D(mTextureType)) + { + mFunctions->copyTexImage2D(target, static_cast(level), + copyTexImageFormat.internalFormat, sourceArea.x, + sourceArea.y, sourceArea.width, sourceArea.height, 0); + } + else + { + UNREACHABLE(); + } } + mLevelInfo[level] = levelInfo; + return gl::Error(GL_NO_ERROR); } @@ -230,20 +324,36 @@ gl::Error TextureGL::copySubImage(GLenum target, size_t level, const gl::Offset mStateManager->bindTexture(mTextureType, mTextureID); mStateManager->bindFramebuffer(GL_READ_FRAMEBUFFER, sourceFramebufferGL->getFramebufferID()); - if (UseTexImage2D(mTextureType)) + const LevelInfoGL &levelInfo = mLevelInfo[level]; + if (levelInfo.lumaWorkaround.enabled) { - ASSERT(destOffset.z == 0); - mFunctions->copyTexSubImage2D(target, level, destOffset.x, destOffset.y, - sourceArea.x, sourceArea.y, sourceArea.width, sourceArea.height); - } - else if (UseTexImage3D(mTextureType)) - { - mFunctions->copyTexSubImage3D(target, level, destOffset.x, destOffset.y, destOffset.z, - sourceArea.x, sourceArea.y, sourceArea.width, sourceArea.height); + gl::Error error = mBlitter->copySubImageToLUMAWorkaroundTexture( + mTextureID, mTextureType, target, levelInfo.sourceFormat, level, destOffset, sourceArea, + source); + if (error.isError()) + { + return error; + } } else { - UNREACHABLE(); + if (UseTexImage2D(mTextureType)) + { + ASSERT(destOffset.z == 0); + mFunctions->copyTexSubImage2D(target, static_cast(level), destOffset.x, + destOffset.y, sourceArea.x, sourceArea.y, + sourceArea.width, sourceArea.height); + } + else if (UseTexImage3D(mTextureType)) + { + mFunctions->copyTexSubImage3D(target, static_cast(level), destOffset.x, + destOffset.y, destOffset.z, sourceArea.x, sourceArea.y, + sourceArea.width, sourceArea.height); + } + else + { + UNREACHABLE(); + } } return gl::Error(GL_NO_ERROR); @@ -254,13 +364,17 @@ gl::Error TextureGL::setStorage(GLenum target, size_t levels, GLenum internalFor // TODO: emulate texture storage with TexImage calls if on GL version <4.2 or the // ARB_texture_storage extension is not available. + nativegl::TexStorageFormat texStorageFormat = + nativegl::GetTexStorageFormat(mFunctions, mWorkarounds, internalFormat); + mStateManager->bindTexture(mTextureType, mTextureID); if (UseTexImage2D(mTextureType)) { ASSERT(size.depth == 1); if (mFunctions->texStorage2D) { - mFunctions->texStorage2D(target, levels, internalFormat, size.width, size.height); + mFunctions->texStorage2D(target, static_cast(levels), + texStorageFormat.internalFormat, size.width, size.height); } else { @@ -280,15 +394,41 @@ gl::Error TextureGL::setStorage(GLenum target, size_t levels, GLenum internalFor if (mTextureType == GL_TEXTURE_2D) { - mFunctions->texImage2D(target, level, internalFormat, levelSize.width, levelSize.height, - 0, internalFormatInfo.format, internalFormatInfo.type, nullptr); + if (internalFormatInfo.compressed) + { + size_t dataSize = internalFormatInfo.computeBlockSize(GL_UNSIGNED_BYTE, levelSize.width, levelSize.height); + mFunctions->compressedTexImage2D(target, static_cast(level), + texStorageFormat.internalFormat, + levelSize.width, levelSize.height, 0, + static_cast(dataSize), nullptr); + } + else + { + mFunctions->texImage2D(target, static_cast(level), + texStorageFormat.internalFormat, levelSize.width, + levelSize.height, 0, internalFormatInfo.format, + internalFormatInfo.type, nullptr); + } } else if (mTextureType == GL_TEXTURE_CUBE_MAP) { for (GLenum face = gl::FirstCubeMapTextureTarget; face <= gl::LastCubeMapTextureTarget; face++) { - mFunctions->texImage2D(face, level, internalFormat, levelSize.width, levelSize.height, - 0, internalFormatInfo.format, internalFormatInfo.type, nullptr); + if (internalFormatInfo.compressed) + { + size_t dataSize = internalFormatInfo.computeBlockSize(GL_UNSIGNED_BYTE, levelSize.width, levelSize.height); + mFunctions->compressedTexImage2D( + face, static_cast(level), texStorageFormat.internalFormat, + levelSize.width, levelSize.height, 0, + static_cast(dataSize), nullptr); + } + else + { + mFunctions->texImage2D(face, static_cast(level), + texStorageFormat.internalFormat, levelSize.width, + levelSize.height, 0, internalFormatInfo.format, + internalFormatInfo.type, nullptr); + } } } else @@ -302,7 +442,9 @@ gl::Error TextureGL::setStorage(GLenum target, size_t levels, GLenum internalFor { if (mFunctions->texStorage3D) { - mFunctions->texStorage3D(target, levels, internalFormat, size.width, size.height, size.depth); + mFunctions->texStorage3D(target, static_cast(levels), + texStorageFormat.internalFormat, size.width, size.height, + size.depth); } else { @@ -314,14 +456,28 @@ gl::Error TextureGL::setStorage(GLenum target, size_t levels, GLenum internalFor // Internal format must be sized ASSERT(internalFormatInfo.pixelBytes != 0); - for (size_t i = 0; i < levels; i++) + for (GLsizei i = 0; i < static_cast(levels); i++) { gl::Extents levelSize(std::max(size.width >> i, 1), std::max(size.height >> i, 1), mTextureType == GL_TEXTURE_3D ? std::max(size.depth >> i, 1) : size.depth); - mFunctions->texImage3D(target, i, internalFormat, levelSize.width, levelSize.height, levelSize.depth, - 0, internalFormatInfo.format, internalFormatInfo.type, nullptr); + if (internalFormatInfo.compressed) + { + GLsizei dataSize = static_cast(internalFormatInfo.computeBlockSize( + GL_UNSIGNED_BYTE, levelSize.width, levelSize.height)) * + levelSize.depth; + mFunctions->compressedTexImage3D(target, i, texStorageFormat.internalFormat, + levelSize.width, levelSize.height, + levelSize.depth, 0, dataSize, nullptr); + } + else + { + mFunctions->texImage3D(target, i, texStorageFormat.internalFormat, + levelSize.width, levelSize.height, levelSize.depth, 0, + internalFormatInfo.format, internalFormatInfo.type, + nullptr); + } } } } @@ -330,13 +486,25 @@ gl::Error TextureGL::setStorage(GLenum target, size_t levels, GLenum internalFor UNREACHABLE(); } + LevelInfoGL levelInfo = GetLevelInfo(internalFormat, texStorageFormat.internalFormat); + for (size_t level = 0; level < mLevelInfo.size(); level++) + { + mLevelInfo[level] = levelInfo; + } + return gl::Error(GL_NO_ERROR); } -gl::Error TextureGL::generateMipmaps(const gl::SamplerState &samplerState) +gl::Error TextureGL::generateMipmaps(const gl::TextureState &textureState) { mStateManager->bindTexture(mTextureType, mTextureID); mFunctions->generateMipmap(mTextureType); + + for (size_t level = textureState.baseLevel; level < mLevelInfo.size(); level++) + { + mLevelInfo[level] = mLevelInfo[textureState.baseLevel]; + } + return gl::Error(GL_NO_ERROR); } @@ -346,6 +514,8 @@ void TextureGL::bindTexImage(egl::Surface *surface) // Make sure this texture is bound mStateManager->bindTexture(mTextureType, mTextureID); + + mLevelInfo[0] = LevelInfoGL(); } void TextureGL::releaseTexImage() @@ -364,40 +534,214 @@ void TextureGL::releaseTexImage() } } -template -static inline void SyncSamplerStateMember(const FunctionsGL *functions, const gl::SamplerState &newState, - gl::SamplerState &curState, GLenum textureType, GLenum name, +gl::Error TextureGL::setEGLImageTarget(GLenum target, egl::Image *image) +{ + UNIMPLEMENTED(); + return gl::Error(GL_INVALID_OPERATION); +} + +template +static inline void SyncSamplerStateMember(const FunctionsGL *functions, + ApplyTextureFuncType applyTextureFunc, + const gl::SamplerState &newState, + gl::SamplerState &curState, + GLenum textureType, + GLenum name, T(gl::SamplerState::*samplerMember)) { if (curState.*samplerMember != newState.*samplerMember) { + applyTextureFunc(); curState.*samplerMember = newState.*samplerMember; functions->texParameterf(textureType, name, static_cast(curState.*samplerMember)); } } -void TextureGL::syncSamplerState(const gl::SamplerState &samplerState) const +template +static inline void SyncTextureStateMember(const FunctionsGL *functions, + ApplyTextureFuncType applyTextureFunc, + const gl::TextureState &newState, + gl::TextureState &curState, + GLenum textureType, + GLenum name, + T(gl::TextureState::*stateMember)) { - if (mAppliedSamplerState != samplerState) + if (curState.*stateMember != newState.*stateMember) { - mStateManager->bindTexture(mTextureType, mTextureID); - SyncSamplerStateMember(mFunctions, samplerState, mAppliedSamplerState, mTextureType, GL_TEXTURE_MIN_FILTER, &gl::SamplerState::minFilter); - SyncSamplerStateMember(mFunctions, samplerState, mAppliedSamplerState, mTextureType, GL_TEXTURE_MAG_FILTER, &gl::SamplerState::magFilter); - SyncSamplerStateMember(mFunctions, samplerState, mAppliedSamplerState, mTextureType, GL_TEXTURE_WRAP_S, &gl::SamplerState::wrapS); - SyncSamplerStateMember(mFunctions, samplerState, mAppliedSamplerState, mTextureType, GL_TEXTURE_WRAP_T, &gl::SamplerState::wrapT); - SyncSamplerStateMember(mFunctions, samplerState, mAppliedSamplerState, mTextureType, GL_TEXTURE_WRAP_R, &gl::SamplerState::wrapR); - SyncSamplerStateMember(mFunctions, samplerState, mAppliedSamplerState, mTextureType, GL_TEXTURE_MAX_ANISOTROPY_EXT, &gl::SamplerState::maxAnisotropy); - SyncSamplerStateMember(mFunctions, samplerState, mAppliedSamplerState, mTextureType, GL_TEXTURE_BASE_LEVEL, &gl::SamplerState::baseLevel); - SyncSamplerStateMember(mFunctions, samplerState, mAppliedSamplerState, mTextureType, GL_TEXTURE_MAX_LEVEL, &gl::SamplerState::maxLevel); - SyncSamplerStateMember(mFunctions, samplerState, mAppliedSamplerState, mTextureType, GL_TEXTURE_MIN_LOD, &gl::SamplerState::minLod); - SyncSamplerStateMember(mFunctions, samplerState, mAppliedSamplerState, mTextureType, GL_TEXTURE_MAX_LOD, &gl::SamplerState::maxLod); - SyncSamplerStateMember(mFunctions, samplerState, mAppliedSamplerState, mTextureType, GL_TEXTURE_COMPARE_MODE, &gl::SamplerState::compareMode); - SyncSamplerStateMember(mFunctions, samplerState, mAppliedSamplerState, mTextureType, GL_TEXTURE_COMPARE_FUNC, &gl::SamplerState::compareFunc); - SyncSamplerStateMember(mFunctions, samplerState, mAppliedSamplerState, mTextureType, GL_TEXTURE_SWIZZLE_R, &gl::SamplerState::swizzleRed); - SyncSamplerStateMember(mFunctions, samplerState, mAppliedSamplerState, mTextureType, GL_TEXTURE_SWIZZLE_G, &gl::SamplerState::swizzleGreen); - SyncSamplerStateMember(mFunctions, samplerState, mAppliedSamplerState, mTextureType, GL_TEXTURE_SWIZZLE_B, &gl::SamplerState::swizzleBlue); - SyncSamplerStateMember(mFunctions, samplerState, mAppliedSamplerState, mTextureType, GL_TEXTURE_SWIZZLE_A, &gl::SamplerState::swizzleAlpha); + applyTextureFunc(); + curState.*stateMember = newState.*stateMember; + functions->texParameterf(textureType, name, static_cast(curState.*stateMember)); + } +} + +template +static inline void SyncTextureStateSwizzle(const FunctionsGL *functions, + ApplyTextureFuncType applyTextureFunc, + const LevelInfoGL &levelInfo, + const gl::TextureState &newState, + gl::TextureState &curState, + GLenum textureType, + GLenum name, + T(gl::TextureState::*stateMember)) +{ + if (levelInfo.lumaWorkaround.enabled || levelInfo.depthStencilWorkaround) + { + GLenum resultSwizzle = GL_NONE; + if (levelInfo.lumaWorkaround.enabled) + { + UNUSED_ASSERTION_VARIABLE(levelInfo.lumaWorkaround.workaroundFormat); + + switch (newState.*stateMember) + { + case GL_RED: + case GL_GREEN: + case GL_BLUE: + if (levelInfo.sourceFormat == GL_LUMINANCE || + levelInfo.sourceFormat == GL_LUMINANCE_ALPHA) + { + // Texture is backed by a RED or RG texture, point all color channels at the red + // channel. + ASSERT(levelInfo.lumaWorkaround.workaroundFormat == GL_RED || + levelInfo.lumaWorkaround.workaroundFormat == GL_RG); + resultSwizzle = GL_RED; + } + else if (levelInfo.sourceFormat == GL_ALPHA) + { + // Color channels are not supposed to exist, make them always sample 0. + resultSwizzle = GL_ZERO; + } + else + { + UNREACHABLE(); + } + break; + + case GL_ALPHA: + if (levelInfo.sourceFormat == GL_LUMINANCE) + { + // Alpha channel is not supposed to exist, make it always sample 1. + resultSwizzle = GL_ONE; + } + else if (levelInfo.sourceFormat == GL_ALPHA) + { + // Texture is backed by a RED texture, point the alpha channel at the red + // channel. + ASSERT(levelInfo.lumaWorkaround.workaroundFormat == GL_RED); + resultSwizzle = GL_RED; + } + else if (levelInfo.sourceFormat == GL_LUMINANCE_ALPHA) + { + // Texture is backed by an RG texture, point the alpha channel at the green + // channel. + ASSERT(levelInfo.lumaWorkaround.workaroundFormat == GL_RG); + resultSwizzle = GL_GREEN; + } + else + { + UNREACHABLE(); + } + break; + + case GL_ZERO: + case GL_ONE: + // Don't modify the swizzle state when requesting ZERO or ONE. + resultSwizzle = newState.*stateMember; + break; + + default: + UNREACHABLE(); + break; + } + } + else if (levelInfo.depthStencilWorkaround) + { + switch (newState.*stateMember) + { + case GL_RED: + // Don't modify the swizzle state when requesting the red channel. + resultSwizzle = newState.*stateMember; + break; + + case GL_GREEN: + case GL_BLUE: + // Depth textures should sample 0 from the green and blue channels. + resultSwizzle = GL_ZERO; + break; + + case GL_ALPHA: + // Depth textures should sample 1 from the alpha channel. + resultSwizzle = GL_ONE; + break; + + case GL_ZERO: + case GL_ONE: + // Don't modify the swizzle state when requesting ZERO or ONE. + resultSwizzle = newState.*stateMember; + break; + + default: + UNREACHABLE(); + break; + } + } + else + { + UNREACHABLE(); + } + + // Apply the new swizzle state if needed + if (curState.*stateMember != resultSwizzle) + { + applyTextureFunc(); + curState.*stateMember = resultSwizzle; + functions->texParameterf(textureType, name, static_cast(resultSwizzle)); + } } + else + { + SyncTextureStateMember(functions, applyTextureFunc, newState, curState, textureType, name, + stateMember); + } +} + +void TextureGL::syncState(size_t textureUnit, const gl::TextureState &textureState) const +{ + // Callback lamdba to bind this texture only if needed. + bool textureApplied = false; + auto applyTextureFunc = [&]() + { + if (!textureApplied) + { + mStateManager->activeTexture(textureUnit); + mStateManager->bindTexture(mTextureType, mTextureID); + textureApplied = true; + } + }; + + // clang-format off + + // Sync texture state + SyncTextureStateMember(mFunctions, applyTextureFunc, textureState, mAppliedTextureState, mTextureType, GL_TEXTURE_BASE_LEVEL, &gl::TextureState::baseLevel); + SyncTextureStateMember(mFunctions, applyTextureFunc, textureState, mAppliedTextureState, mTextureType, GL_TEXTURE_MAX_LEVEL, &gl::TextureState::maxLevel); + + const LevelInfoGL &levelInfo = mLevelInfo[textureState.baseLevel]; + SyncTextureStateSwizzle(mFunctions, applyTextureFunc, levelInfo, textureState, mAppliedTextureState, mTextureType, GL_TEXTURE_SWIZZLE_R, &gl::TextureState::swizzleRed); + SyncTextureStateSwizzle(mFunctions, applyTextureFunc, levelInfo, textureState, mAppliedTextureState, mTextureType, GL_TEXTURE_SWIZZLE_G, &gl::TextureState::swizzleGreen); + SyncTextureStateSwizzle(mFunctions, applyTextureFunc, levelInfo, textureState, mAppliedTextureState, mTextureType, GL_TEXTURE_SWIZZLE_B, &gl::TextureState::swizzleBlue); + SyncTextureStateSwizzle(mFunctions, applyTextureFunc, levelInfo, textureState, mAppliedTextureState, mTextureType, GL_TEXTURE_SWIZZLE_A, &gl::TextureState::swizzleAlpha); + + // Sync sampler state + SyncSamplerStateMember(mFunctions, applyTextureFunc, textureState.samplerState, mAppliedTextureState.samplerState, mTextureType, GL_TEXTURE_MIN_FILTER, &gl::SamplerState::minFilter); + SyncSamplerStateMember(mFunctions, applyTextureFunc, textureState.samplerState, mAppliedTextureState.samplerState, mTextureType, GL_TEXTURE_MAG_FILTER, &gl::SamplerState::magFilter); + SyncSamplerStateMember(mFunctions, applyTextureFunc, textureState.samplerState, mAppliedTextureState.samplerState, mTextureType, GL_TEXTURE_WRAP_S, &gl::SamplerState::wrapS); + SyncSamplerStateMember(mFunctions, applyTextureFunc, textureState.samplerState, mAppliedTextureState.samplerState, mTextureType, GL_TEXTURE_WRAP_T, &gl::SamplerState::wrapT); + SyncSamplerStateMember(mFunctions, applyTextureFunc, textureState.samplerState, mAppliedTextureState.samplerState, mTextureType, GL_TEXTURE_WRAP_R, &gl::SamplerState::wrapR); + SyncSamplerStateMember(mFunctions, applyTextureFunc, textureState.samplerState, mAppliedTextureState.samplerState, mTextureType, GL_TEXTURE_MAX_ANISOTROPY_EXT, &gl::SamplerState::maxAnisotropy); + SyncSamplerStateMember(mFunctions, applyTextureFunc, textureState.samplerState, mAppliedTextureState.samplerState, mTextureType, GL_TEXTURE_MIN_LOD, &gl::SamplerState::minLod); + SyncSamplerStateMember(mFunctions, applyTextureFunc, textureState.samplerState, mAppliedTextureState.samplerState, mTextureType, GL_TEXTURE_MAX_LOD, &gl::SamplerState::maxLod); + SyncSamplerStateMember(mFunctions, applyTextureFunc, textureState.samplerState, mAppliedTextureState.samplerState, mTextureType, GL_TEXTURE_COMPARE_MODE, &gl::SamplerState::compareMode); + SyncSamplerStateMember(mFunctions, applyTextureFunc, textureState.samplerState, mAppliedTextureState.samplerState, mTextureType, GL_TEXTURE_COMPARE_FUNC, &gl::SamplerState::compareFunc); + // clang-format on } GLuint TextureGL::getTextureID() const diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/TextureGL.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/TextureGL.h index 73092b9155e3..6d64d9d1f368 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/TextureGL.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/TextureGL.h @@ -15,13 +15,47 @@ namespace rx { +class BlitGL; class FunctionsGL; class StateManagerGL; +struct WorkaroundsGL; + +struct LUMAWorkaroundGL +{ + bool enabled; + GLenum workaroundFormat; + + LUMAWorkaroundGL(); + LUMAWorkaroundGL(bool enabled, GLenum workaroundFormat); +}; + +// Structure containing information about format and workarounds for each mip level of the +// TextureGL. +struct LevelInfoGL +{ + // Format of the data used in this mip level. + GLenum sourceFormat; + + // If this mip level requires sampler-state re-writing so that only a red channel is exposed. + bool depthStencilWorkaround; + + // Information about luminance alpha texture workarounds in the core profile. + LUMAWorkaroundGL lumaWorkaround; + + LevelInfoGL(); + LevelInfoGL(GLenum sourceFormat, + bool depthStencilWorkaround, + const LUMAWorkaroundGL &lumaWorkaround); +}; class TextureGL : public TextureImpl { public: - TextureGL(GLenum type, const FunctionsGL *functions, StateManagerGL *stateManager); + TextureGL(GLenum type, + const FunctionsGL *functions, + const WorkaroundsGL &workarounds, + StateManagerGL *stateManager, + BlitGL *blitter); ~TextureGL() override; void setUsage(GLenum usage) override; @@ -32,9 +66,9 @@ class TextureGL : public TextureImpl const gl::PixelUnpackState &unpack, const uint8_t *pixels) override; gl::Error setCompressedImage(GLenum target, size_t level, GLenum internalFormat, const gl::Extents &size, - const gl::PixelUnpackState &unpack, const uint8_t *pixels) override; + const gl::PixelUnpackState &unpack, size_t imageSize, const uint8_t *pixels) override; gl::Error setCompressedSubImage(GLenum target, size_t level, const gl::Box &area, GLenum format, - const gl::PixelUnpackState &unpack, const uint8_t *pixels) override; + const gl::PixelUnpackState &unpack, size_t imageSize, const uint8_t *pixels) override; gl::Error copyImage(GLenum target, size_t level, const gl::Rectangle &sourceArea, GLenum internalFormat, const gl::Framebuffer *source) override; @@ -43,12 +77,14 @@ class TextureGL : public TextureImpl gl::Error setStorage(GLenum target, size_t levels, GLenum internalFormat, const gl::Extents &size) override; - gl::Error generateMipmaps(const gl::SamplerState &samplerState) override; + gl::Error generateMipmaps(const gl::TextureState &textureState) override; void bindTexImage(egl::Surface *surface) override; void releaseTexImage() override; - void syncSamplerState(const gl::SamplerState &samplerState) const; + gl::Error setEGLImageTarget(GLenum target, egl::Image *image) override; + + void syncState(size_t textureUnit, const gl::TextureState &textureState) const; GLuint getTextureID() const; gl::Error getAttachmentRenderTarget(const gl::FramebufferAttachment::Target &target, @@ -61,9 +97,13 @@ class TextureGL : public TextureImpl GLenum mTextureType; const FunctionsGL *mFunctions; + const WorkaroundsGL &mWorkarounds; StateManagerGL *mStateManager; + BlitGL *mBlitter; + + std::vector mLevelInfo; - mutable gl::SamplerState mAppliedSamplerState; + mutable gl::TextureState mAppliedTextureState; GLuint mTextureID; }; diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/TransformFeedbackGL.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/TransformFeedbackGL.cpp index c62a0b56f4ea..c325bb199a90 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/TransformFeedbackGL.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/TransformFeedbackGL.cpp @@ -9,45 +9,134 @@ #include "libANGLE/renderer/gl/TransformFeedbackGL.h" #include "common/debug.h" +#include "libANGLE/Data.h" +#include "libANGLE/renderer/gl/BufferGL.h" +#include "libANGLE/renderer/gl/FunctionsGL.h" +#include "libANGLE/renderer/gl/StateManagerGL.h" namespace rx { -TransformFeedbackGL::TransformFeedbackGL() - : TransformFeedbackImpl() -{} +TransformFeedbackGL::TransformFeedbackGL(const FunctionsGL *functions, + StateManagerGL *stateManager, + size_t maxTransformFeedbackBufferBindings) + : TransformFeedbackImpl(), + mFunctions(functions), + mStateManager(stateManager), + mTransformFeedbackID(0), + mIsActive(false), + mIsPaused(false), + mCurrentIndexedBuffers(maxTransformFeedbackBufferBindings) +{ + mFunctions->genTransformFeedbacks(1, &mTransformFeedbackID); +} TransformFeedbackGL::~TransformFeedbackGL() -{} +{ + mStateManager->deleteTransformFeedback(mTransformFeedbackID); + mTransformFeedbackID = 0; + + for (auto &bufferBinding : mCurrentIndexedBuffers) + { + bufferBinding.set(nullptr); + } +} void TransformFeedbackGL::begin(GLenum primitiveMode) { - UNIMPLEMENTED(); + // Do not begin directly, StateManagerGL will handle beginning and resuming transform feedback. } void TransformFeedbackGL::end() { - UNIMPLEMENTED(); + syncActiveState(false, GL_NONE); } void TransformFeedbackGL::pause() { - UNIMPLEMENTED(); + syncPausedState(true); } void TransformFeedbackGL::resume() { - UNIMPLEMENTED(); + // Do not resume directly, StateManagerGL will handle beginning and resuming transform feedback. } void TransformFeedbackGL::bindGenericBuffer(const BindingPointer &binding) { - UNIMPLEMENTED(); } void TransformFeedbackGL::bindIndexedBuffer(size_t index, const OffsetBindingPointer &binding) { - UNIMPLEMENTED(); + // Directly bind buffer (not through the StateManager methods) because the buffer bindings are + // tracked per transform feedback object + if (binding != mCurrentIndexedBuffers[index]) + { + mStateManager->bindTransformFeedback(GL_TRANSFORM_FEEDBACK, mTransformFeedbackID); + if (binding.get() != nullptr) + { + const BufferGL *bufferGL = GetImplAs(binding.get()); + if (binding.getSize() != 0) + { + mFunctions->bindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, + static_cast(index), bufferGL->getBufferID(), + binding.getOffset(), binding.getSize()); + } + else + { + mFunctions->bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, static_cast(index), + bufferGL->getBufferID()); + } + } + else + { + mFunctions->bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, static_cast(index), 0); + } + + mCurrentIndexedBuffers[index] = binding; + } +} + +GLuint TransformFeedbackGL::getTransformFeedbackID() const +{ + return mTransformFeedbackID; +} + +void TransformFeedbackGL::syncActiveState(bool active, GLenum primitiveMode) const +{ + if (mIsActive != active) + { + mIsActive = active; + mIsPaused = false; + + mStateManager->bindTransformFeedback(GL_TRANSFORM_FEEDBACK, mTransformFeedbackID); + if (mIsActive) + { + mFunctions->beginTransformFeedback(primitiveMode); + } + else + { + mFunctions->endTransformFeedback(); + } + } +} + +void TransformFeedbackGL::syncPausedState(bool paused) const +{ + if (mIsActive && mIsPaused != paused) + { + mIsPaused = paused; + + mStateManager->bindTransformFeedback(GL_TRANSFORM_FEEDBACK, mTransformFeedbackID); + if (mIsPaused) + { + mFunctions->pauseTransformFeedback(); + } + else + { + mFunctions->resumeTransformFeedback(); + } + } } } diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/TransformFeedbackGL.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/TransformFeedbackGL.h index 9008d4e5aeea..7f72077e83b7 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/TransformFeedbackGL.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/TransformFeedbackGL.h @@ -14,10 +14,15 @@ namespace rx { +class FunctionsGL; +class StateManagerGL; + class TransformFeedbackGL : public TransformFeedbackImpl { public: - TransformFeedbackGL(); + TransformFeedbackGL(const FunctionsGL *functions, + StateManagerGL *stateManager, + size_t maxTransformFeedbackBufferBindings); ~TransformFeedbackGL() override; void begin(GLenum primitiveMode) override; @@ -27,6 +32,22 @@ class TransformFeedbackGL : public TransformFeedbackImpl void bindGenericBuffer(const BindingPointer &binding) override; void bindIndexedBuffer(size_t index, const OffsetBindingPointer &binding) override; + + GLuint getTransformFeedbackID() const; + + void syncActiveState(bool active, GLenum primitiveMode) const; + void syncPausedState(bool paused) const; + + private: + const FunctionsGL *mFunctions; + StateManagerGL *mStateManager; + + GLuint mTransformFeedbackID; + + mutable bool mIsActive; + mutable bool mIsPaused; + + std::vector> mCurrentIndexedBuffers; }; } diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/VertexArrayGL.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/VertexArrayGL.cpp index 76635a066504..255b41f565b7 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/VertexArrayGL.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/VertexArrayGL.cpp @@ -8,8 +8,10 @@ #include "libANGLE/renderer/gl/VertexArrayGL.h" +#include "common/BitSetIterator.h" #include "common/debug.h" #include "common/mathutil.h" +#include "common/utilities.h" #include "libANGLE/Buffer.h" #include "libANGLE/angletypes.h" #include "libANGLE/formatutils.h" @@ -17,18 +19,27 @@ #include "libANGLE/renderer/gl/FunctionsGL.h" #include "libANGLE/renderer/gl/StateManagerGL.h" +using namespace gl; + namespace rx { +namespace +{ +bool AttributeNeedsStreaming(const VertexAttribute &attribute) +{ + return (attribute.enabled && attribute.buffer.get() == nullptr); +} + +} // anonymous namespace -VertexArrayGL::VertexArrayGL(const FunctionsGL *functions, StateManagerGL *stateManager) - : VertexArrayImpl(), +VertexArrayGL::VertexArrayGL(const VertexArray::Data &data, + const FunctionsGL *functions, + StateManagerGL *stateManager) + : VertexArrayImpl(data), mFunctions(functions), mStateManager(stateManager), mVertexArrayID(0), - mElementArrayBuffer(), - mAttributes(), - mAppliedElementArrayBuffer(0), - mAppliedAttributes(), + mAppliedElementArrayBuffer(), mStreamingElementArrayBufferSize(0), mStreamingElementArrayBuffer(0), mStreamingArrayBufferSize(0), @@ -39,88 +50,72 @@ VertexArrayGL::VertexArrayGL(const FunctionsGL *functions, StateManagerGL *state mFunctions->genVertexArrays(1, &mVertexArrayID); // Set the cached vertex attribute array size - GLint maxVertexAttribs; + GLint maxVertexAttribs = 0; mFunctions->getIntegerv(GL_MAX_VERTEX_ATTRIBS, &maxVertexAttribs); - mAttributes.resize(maxVertexAttribs); mAppliedAttributes.resize(maxVertexAttribs); } VertexArrayGL::~VertexArrayGL() { - if (mVertexArrayID != 0) - { - mFunctions->deleteVertexArrays(1, &mVertexArrayID); - mVertexArrayID = 0; - } + mStateManager->deleteVertexArray(mVertexArrayID); + mVertexArrayID = 0; - if (mStreamingElementArrayBuffer != 0) - { - mFunctions->deleteBuffers(1, &mStreamingElementArrayBuffer); - mStreamingElementArrayBufferSize = 0; - mStreamingElementArrayBuffer = 0; - } - - if (mStreamingArrayBuffer != 0) - { - mFunctions->deleteBuffers(1, &mStreamingArrayBuffer); - mStreamingArrayBufferSize = 0; - mStreamingArrayBuffer = 0; - } + mStateManager->deleteBuffer(mStreamingElementArrayBuffer); + mStreamingElementArrayBufferSize = 0; + mStreamingElementArrayBuffer = 0; - mElementArrayBuffer.set(nullptr); - for (size_t idx = 0; idx < mAttributes.size(); idx++) - { - mAttributes[idx].buffer.set(NULL); - } + mStateManager->deleteBuffer(mStreamingArrayBuffer); + mStreamingArrayBufferSize = 0; + mStreamingArrayBuffer = 0; + mAppliedElementArrayBuffer.set(nullptr); for (size_t idx = 0; idx < mAppliedAttributes.size(); idx++) { - mAppliedAttributes[idx].buffer.set(NULL); + mAppliedAttributes[idx].buffer.set(nullptr); } } -void VertexArrayGL::setElementArrayBuffer(const gl::Buffer *buffer) +gl::Error VertexArrayGL::syncDrawArraysState(const gl::AttributesMask &activeAttributesMask, + GLint first, + GLsizei count, + GLsizei instanceCount) const { - mElementArrayBuffer.set(buffer); + return syncDrawState(activeAttributesMask, first, count, GL_NONE, nullptr, instanceCount, false, + nullptr); } -void VertexArrayGL::setAttribute(size_t idx, const gl::VertexAttribute &attr) +gl::Error VertexArrayGL::syncDrawElementsState(const gl::AttributesMask &activeAttributesMask, + GLsizei count, + GLenum type, + const GLvoid *indices, + GLsizei instanceCount, + bool primitiveRestartEnabled, + const GLvoid **outIndices) const { - mAttributes[idx] = attr; + return syncDrawState(activeAttributesMask, 0, count, type, indices, instanceCount, + primitiveRestartEnabled, outIndices); } -void VertexArrayGL::setAttributeDivisor(size_t idx, GLuint divisor) +gl::Error VertexArrayGL::syncDrawState(const gl::AttributesMask &activeAttributesMask, + GLint first, + GLsizei count, + GLenum type, + const GLvoid *indices, + GLsizei instanceCount, + bool primitiveRestartEnabled, + const GLvoid **outIndices) const { - mAttributes[idx].divisor = divisor; -} - -void VertexArrayGL::enableAttribute(size_t idx, bool enabledState) -{ - mAttributes[idx].enabled = enabledState; -} - -gl::Error VertexArrayGL::syncDrawArraysState(GLint first, GLsizei count) const -{ - return syncDrawState(first, count, GL_NONE, nullptr, nullptr); -} - -gl::Error VertexArrayGL::syncDrawElementsState(GLsizei count, GLenum type, const GLvoid *indices, const GLvoid **outIndices) const -{ - return syncDrawState(0, count, type, indices, outIndices); -} - -gl::Error VertexArrayGL::syncDrawState(GLint first, GLsizei count, GLenum type, const GLvoid *indices, const GLvoid **outIndices) const -{ - mStateManager->bindVertexArray(mVertexArrayID); + mStateManager->bindVertexArray(mVertexArrayID, getAppliedElementArrayBufferID()); // Check if any attributes need to be streamed, determines if the index range needs to be computed - bool attributesNeedStreaming = doAttributesNeedStreaming(); + bool attributesNeedStreaming = mAttributesNeedStreaming.any(); // Determine if an index buffer needs to be streamed and the range of vertices that need to be copied - RangeUI indexRange(0, 0); + IndexRange indexRange; if (type != GL_NONE) { - gl::Error error = syncIndexData(count, type, indices, attributesNeedStreaming, &indexRange, outIndices); + Error error = syncIndexData(count, type, indices, primitiveRestartEnabled, + attributesNeedStreaming, &indexRange, outIndices); if (error.isError()) { return error; @@ -128,157 +123,54 @@ gl::Error VertexArrayGL::syncDrawState(GLint first, GLsizei count, GLenum type, } else { - // Not an indexed call, set the range to [first, first + count) + // Not an indexed call, set the range to [first, first + count - 1] indexRange.start = first; - indexRange.end = first + count; + indexRange.end = first + count - 1; } - // Sync the vertex attribute state and track what data needs to be streamed - size_t streamingDataSize = 0; - size_t maxAttributeDataSize = 0; - gl::Error error = syncAttributeState(attributesNeedStreaming, indexRange, &streamingDataSize, &maxAttributeDataSize); - if (error.isError()) + if (attributesNeedStreaming) { - return error; - } - - if (streamingDataSize > 0) - { - ASSERT(attributesNeedStreaming); - - gl::Error error = streamAttributes(streamingDataSize, maxAttributeDataSize, indexRange); + Error error = streamAttributes(activeAttributesMask, instanceCount, indexRange); if (error.isError()) { return error; } } - return gl::Error(GL_NO_ERROR); -} - -bool VertexArrayGL::doAttributesNeedStreaming() const -{ - // TODO: if GLES, nothing needs to be streamed - for (size_t idx = 0; idx < mAttributes.size(); idx++) - { - if (mAttributes[idx].enabled && mAttributes[idx].buffer.get() == nullptr) - { - return true; - } - } - - return false; -} - -gl::Error VertexArrayGL::syncAttributeState(bool attributesNeedStreaming, const RangeUI &indexRange, - size_t *outStreamingDataSize, size_t *outMaxAttributeDataSize) const -{ - *outStreamingDataSize = 0; - *outMaxAttributeDataSize = 0; - - for (size_t idx = 0; idx < mAttributes.size(); idx++) - { - // Always sync the enabled and divisor state, they are required for both streaming and buffered - // attributes - if (mAppliedAttributes[idx].enabled != mAttributes[idx].enabled) - { - if (mAttributes[idx].enabled) - { - mFunctions->enableVertexAttribArray(idx); - } - else - { - mFunctions->disableVertexAttribArray(idx); - } - mAppliedAttributes[idx].enabled = mAttributes[idx].enabled; - } - if (mAppliedAttributes[idx].divisor != mAttributes[idx].divisor) - { - mFunctions->vertexAttribDivisor(idx, mAttributes[idx].divisor); - mAppliedAttributes[idx].divisor = mAttributes[idx].divisor; - } - - if (mAttributes[idx].enabled && mAttributes[idx].buffer.get() == nullptr) - { - ASSERT(attributesNeedStreaming); - - const size_t streamedVertexCount = indexRange.end - indexRange.start + 1; - - // If streaming is going to be required, compute the size of the required buffer - // and how much slack space at the beginning of the buffer will be required by determining - // the attribute with the largest data size. - size_t typeSize = ComputeVertexAttributeTypeSize(mAttributes[idx]); - *outStreamingDataSize += typeSize * streamedVertexCount; - *outMaxAttributeDataSize = std::max(*outMaxAttributeDataSize, typeSize); - } - else - { - // Sync the attribute with no translation - if (mAppliedAttributes[idx] != mAttributes[idx]) - { - const gl::Buffer *arrayBuffer = mAttributes[idx].buffer.get(); - const BufferGL *arrayBufferGL = GetImplAs(arrayBuffer); - mStateManager->bindBuffer(GL_ARRAY_BUFFER, arrayBufferGL->getBufferID()); - - if (mAttributes[idx].pureInteger) - { - mFunctions->vertexAttribIPointer(idx, mAttributes[idx].size, mAttributes[idx].type, - mAttributes[idx].stride, mAttributes[idx].pointer); - } - else - { - mFunctions->vertexAttribPointer(idx, mAttributes[idx].size, mAttributes[idx].type, - mAttributes[idx].normalized, mAttributes[idx].stride, - mAttributes[idx].pointer); - } - - mAppliedAttributes[idx] = mAttributes[idx]; - } - } - } - - return gl::Error(GL_NO_ERROR); + return Error(GL_NO_ERROR); } -gl::Error VertexArrayGL::syncIndexData(GLsizei count, GLenum type, const GLvoid *indices, bool attributesNeedStreaming, - RangeUI *outIndexRange, const GLvoid **outIndices) const +Error VertexArrayGL::syncIndexData(GLsizei count, + GLenum type, + const GLvoid *indices, + bool primitiveRestartEnabled, + bool attributesNeedStreaming, + IndexRange *outIndexRange, + const GLvoid **outIndices) const { ASSERT(outIndices); + gl::Buffer *elementArrayBuffer = mData.getElementArrayBuffer().get(); + // Need to check the range of indices if attributes need to be streamed - if (mElementArrayBuffer.get() != nullptr) + if (elementArrayBuffer != nullptr) { - const BufferGL *bufferGL = GetImplAs(mElementArrayBuffer.get()); - GLuint elementArrayBufferID = bufferGL->getBufferID(); - if (elementArrayBufferID != mAppliedElementArrayBuffer) + if (elementArrayBuffer != mAppliedElementArrayBuffer.get()) { - mStateManager->bindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementArrayBufferID); - mAppliedElementArrayBuffer = elementArrayBufferID; + const BufferGL *bufferGL = GetImplAs(elementArrayBuffer); + mStateManager->bindBuffer(GL_ELEMENT_ARRAY_BUFFER, bufferGL->getBufferID()); + mAppliedElementArrayBuffer.set(elementArrayBuffer); } // Only compute the index range if the attributes also need to be streamed if (attributesNeedStreaming) { ptrdiff_t elementArrayBufferOffset = reinterpret_cast(indices); - - // Find the index range in the buffer - const IndexRangeCache *rangeCache = mElementArrayBuffer.get()->getIndexRangeCache(); - - if (!rangeCache->findRange(type, static_cast(elementArrayBufferOffset), count, outIndexRange)) + Error error = mData.getElementArrayBuffer()->getIndexRange( + type, elementArrayBufferOffset, count, primitiveRestartEnabled, outIndexRange); + if (error.isError()) { - // Need to compute the index range. - mStateManager->bindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementArrayBufferID); - uint8_t *elementArrayBufferPointer = reinterpret_cast(mFunctions->mapBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_READ_ONLY)); - - *outIndexRange = IndexRangeCache::ComputeRange(type, elementArrayBufferPointer + elementArrayBufferOffset, count); - - // TODO: Store the range cache at the impl level since the gl::Buffer object is supposed to remain constant - const_cast(rangeCache)->addRange(type, static_cast(elementArrayBufferOffset), count, *outIndexRange); - - if (!mFunctions->unmapBuffer(GL_ELEMENT_ARRAY_BUFFER)) - { - return gl::Error(GL_OUT_OF_MEMORY); - } + return error; } } @@ -293,7 +185,7 @@ gl::Error VertexArrayGL::syncIndexData(GLsizei count, GLenum type, const GLvoid // Only compute the index range if the attributes also need to be streamed if (attributesNeedStreaming) { - *outIndexRange = IndexRangeCache::ComputeRange(type, indices, count); + *outIndexRange = ComputeIndexRange(type, indices, count, primitiveRestartEnabled); } // Allocate the streaming element array buffer @@ -304,10 +196,10 @@ gl::Error VertexArrayGL::syncIndexData(GLsizei count, GLenum type, const GLvoid } mStateManager->bindBuffer(GL_ELEMENT_ARRAY_BUFFER, mStreamingElementArrayBuffer); - mAppliedElementArrayBuffer = mStreamingElementArrayBuffer; + mAppliedElementArrayBuffer.set(nullptr); // Make sure the element array buffer is large enough - const gl::Type &indexTypeInfo = gl::GetTypeInfo(type); + const Type &indexTypeInfo = GetTypeInfo(type); size_t requiredStreamingBufferSize = indexTypeInfo.bytes * count; if (requiredStreamingBufferSize > mStreamingElementArrayBufferSize) { @@ -325,11 +217,52 @@ gl::Error VertexArrayGL::syncIndexData(GLsizei count, GLenum type, const GLvoid *outIndices = nullptr; } - return gl::Error(GL_NO_ERROR); + return Error(GL_NO_ERROR); +} + +void VertexArrayGL::computeStreamingAttributeSizes(const gl::AttributesMask &activeAttributesMask, + GLsizei instanceCount, + const gl::IndexRange &indexRange, + size_t *outStreamingDataSize, + size_t *outMaxAttributeDataSize) const +{ + *outStreamingDataSize = 0; + *outMaxAttributeDataSize = 0; + + ASSERT(mAttributesNeedStreaming.any()); + + const auto &attribs = mData.getVertexAttributes(); + for (auto idx : angle::IterateBitSet(mAttributesNeedStreaming & activeAttributesMask)) + { + const auto &attrib = attribs[idx]; + ASSERT(AttributeNeedsStreaming(attrib)); + + // If streaming is going to be required, compute the size of the required buffer + // and how much slack space at the beginning of the buffer will be required by determining + // the attribute with the largest data size. + size_t typeSize = ComputeVertexAttributeTypeSize(attrib); + *outStreamingDataSize += typeSize * ComputeVertexAttributeElementCount( + attrib, indexRange.vertexCount(), instanceCount); + *outMaxAttributeDataSize = std::max(*outMaxAttributeDataSize, typeSize); + } } -gl::Error VertexArrayGL::streamAttributes(size_t streamingDataSize, size_t maxAttributeDataSize, const RangeUI &indexRange) const +gl::Error VertexArrayGL::streamAttributes(const gl::AttributesMask &activeAttributesMask, + GLsizei instanceCount, + const gl::IndexRange &indexRange) const { + // Sync the vertex attribute state and track what data needs to be streamed + size_t streamingDataSize = 0; + size_t maxAttributeDataSize = 0; + + computeStreamingAttributeSizes(activeAttributesMask, instanceCount, indexRange, + &streamingDataSize, &maxAttributeDataSize); + + if (streamingDataSize == 0) + { + return gl::Error(GL_NO_ERROR); + } + if (mStreamingArrayBuffer == 0) { mFunctions->genBuffers(1, &mStreamingArrayBuffer); @@ -358,50 +291,65 @@ gl::Error VertexArrayGL::streamAttributes(size_t streamingDataSize, size_t maxAt uint8_t *bufferPointer = reinterpret_cast(mFunctions->mapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY)); size_t curBufferOffset = bufferEmptySpace; - const size_t streamedVertexCount = indexRange.end - indexRange.start + 1; - - for (size_t idx = 0; idx < mAttributes.size(); idx++) + const auto &attribs = mData.getVertexAttributes(); + for (auto idx : angle::IterateBitSet(mAttributesNeedStreaming & activeAttributesMask)) { - if (mAttributes[idx].enabled && mAttributes[idx].buffer.get() == nullptr) - { - const size_t sourceStride = ComputeVertexAttributeStride(mAttributes[idx]); - const size_t destStride = ComputeVertexAttributeTypeSize(mAttributes[idx]); + const auto &attrib = attribs[idx]; + ASSERT(AttributeNeedsStreaming(attrib)); - const uint8_t *inputPointer = reinterpret_cast(mAttributes[idx].pointer); + const size_t streamedVertexCount = + ComputeVertexAttributeElementCount(attrib, indexRange.vertexCount(), instanceCount); - // Pack the data when copying it, user could have supplied a very large stride that would - // cause the buffer to be much larger than needed. - if (destStride == sourceStride) - { - // Can copy in one go, the data is packed - memcpy(bufferPointer + curBufferOffset, - inputPointer + (sourceStride * indexRange.start), - destStride * streamedVertexCount); - } - else + const size_t sourceStride = ComputeVertexAttributeStride(attrib); + const size_t destStride = ComputeVertexAttributeTypeSize(attrib); + + const uint8_t *inputPointer = reinterpret_cast(attrib.pointer); + + // Pack the data when copying it, user could have supplied a very large stride that + // would cause the buffer to be much larger than needed. + if (destStride == sourceStride) + { + // Can copy in one go, the data is packed + memcpy(bufferPointer + curBufferOffset, + inputPointer + (sourceStride * indexRange.start), + destStride * streamedVertexCount); + } + else + { + // Copy each vertex individually + for (size_t vertexIdx = 0; vertexIdx < streamedVertexCount; vertexIdx++) { - // Copy each vertex individually - for (size_t vertexIdx = indexRange.start; vertexIdx <= indexRange.end; vertexIdx++) - { - memcpy(bufferPointer + curBufferOffset + (destStride * vertexIdx), - inputPointer + (sourceStride * vertexIdx), - destStride); - } + uint8_t *out = bufferPointer + curBufferOffset + (destStride * vertexIdx); + const uint8_t *in = + inputPointer + sourceStride * (vertexIdx + indexRange.start); + memcpy(out, in, destStride); } + } - // Compute where the 0-index vertex would be. - const size_t vertexStartOffset = curBufferOffset - (indexRange.start * destStride); + // Compute where the 0-index vertex would be. + const size_t vertexStartOffset = curBufferOffset - (indexRange.start * destStride); - mFunctions->vertexAttribPointer(idx, mAttributes[idx].size, mAttributes[idx].type, - mAttributes[idx].normalized, destStride, - reinterpret_cast(vertexStartOffset)); + if (attrib.pureInteger) + { + ASSERT(!attrib.normalized); + mFunctions->vertexAttribIPointer( + static_cast(idx), attrib.size, attrib.type, + static_cast(destStride), + reinterpret_cast(vertexStartOffset)); + } + else + { + mFunctions->vertexAttribPointer( + static_cast(idx), attrib.size, attrib.type, attrib.normalized, + static_cast(destStride), + reinterpret_cast(vertexStartOffset)); + } - curBufferOffset += destStride * streamedVertexCount; + curBufferOffset += destStride * streamedVertexCount; - // Mark the applied attribute as dirty by setting an invalid size so that if it doesn't - // need to be streamed later, there is no chance that the caching will skip it. - mAppliedAttributes[idx].size = static_cast(-1); - } + // Mark the applied attribute as dirty by setting an invalid size so that if it doesn't + // need to be streamed later, there is no chance that the caching will skip it. + mAppliedAttributes[idx].size = static_cast(-1); } unmapResult = mFunctions->unmapBuffer(GL_ARRAY_BUFFER); @@ -409,10 +357,10 @@ gl::Error VertexArrayGL::streamAttributes(size_t streamingDataSize, size_t maxAt if (unmapResult != GL_TRUE) { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to unmap the client data streaming buffer."); + return Error(GL_OUT_OF_MEMORY, "Failed to unmap the client data streaming buffer."); } - return gl::Error(GL_NO_ERROR); + return Error(GL_NO_ERROR); } GLuint VertexArrayGL::getVertexArrayID() const @@ -420,4 +368,130 @@ GLuint VertexArrayGL::getVertexArrayID() const return mVertexArrayID; } +GLuint VertexArrayGL::getAppliedElementArrayBufferID() const +{ + if (mAppliedElementArrayBuffer.get() == nullptr) + { + return mStreamingElementArrayBuffer; + } + + return GetImplAs(mAppliedElementArrayBuffer.get())->getBufferID(); +} + +void VertexArrayGL::updateNeedsStreaming(size_t attribIndex) +{ + const VertexAttribute &attrib = mData.getVertexAttribute(attribIndex); + mAttributesNeedStreaming.set(attribIndex, AttributeNeedsStreaming(attrib)); +} + +void VertexArrayGL::updateAttribEnabled(size_t attribIndex) +{ + const VertexAttribute &attrib = mData.getVertexAttribute(attribIndex); + if (mAppliedAttributes[attribIndex].enabled == attrib.enabled) + { + return; + } + + updateNeedsStreaming(attribIndex); + + mStateManager->bindVertexArray(mVertexArrayID, getAppliedElementArrayBufferID()); + if (attrib.enabled) + { + mFunctions->enableVertexAttribArray(static_cast(attribIndex)); + } + else + { + mFunctions->disableVertexAttribArray(static_cast(attribIndex)); + } + mAppliedAttributes[attribIndex].enabled = attrib.enabled; +} + +void VertexArrayGL::updateAttribPointer(size_t attribIndex) +{ + const VertexAttribute &attrib = mData.getVertexAttribute(attribIndex); + if (mAppliedAttributes[attribIndex] == attrib) + { + return; + } + + updateNeedsStreaming(attribIndex); + + // If we need to stream, defer the attribPointer to the draw call. + if (mAttributesNeedStreaming[attribIndex]) + { + return; + } + + mStateManager->bindVertexArray(mVertexArrayID, getAppliedElementArrayBufferID()); + const Buffer *arrayBuffer = attrib.buffer.get(); + if (arrayBuffer != nullptr) + { + const BufferGL *arrayBufferGL = GetImplAs(arrayBuffer); + mStateManager->bindBuffer(GL_ARRAY_BUFFER, arrayBufferGL->getBufferID()); + } + else + { + mStateManager->bindBuffer(GL_ARRAY_BUFFER, 0); + } + mAppliedAttributes[attribIndex].buffer = attrib.buffer; + + if (attrib.pureInteger) + { + mFunctions->vertexAttribIPointer(static_cast(attribIndex), attrib.size, attrib.type, + attrib.stride, attrib.pointer); + } + else + { + mFunctions->vertexAttribPointer(static_cast(attribIndex), attrib.size, attrib.type, + attrib.normalized, attrib.stride, attrib.pointer); + } + mAppliedAttributes[attribIndex].size = attrib.size; + mAppliedAttributes[attribIndex].type = attrib.type; + mAppliedAttributes[attribIndex].normalized = attrib.normalized; + mAppliedAttributes[attribIndex].pureInteger = attrib.pureInteger; + mAppliedAttributes[attribIndex].stride = attrib.stride; + mAppliedAttributes[attribIndex].pointer = attrib.pointer; } + +void VertexArrayGL::syncState(const VertexArray::DirtyBits &dirtyBits) +{ + for (unsigned long dirtyBit : angle::IterateBitSet(dirtyBits)) + { + if (dirtyBit == VertexArray::DIRTY_BIT_ELEMENT_ARRAY_BUFFER) + { + // TODO(jmadill): Element array buffer bindings + } + else if (dirtyBit >= VertexArray::DIRTY_BIT_ATTRIB_0_ENABLED && + dirtyBit < VertexArray::DIRTY_BIT_ATTRIB_MAX_ENABLED) + { + size_t attribIndex = + static_cast(dirtyBit) - VertexArray::DIRTY_BIT_ATTRIB_0_ENABLED; + updateAttribEnabled(attribIndex); + } + else if (dirtyBit >= VertexArray::DIRTY_BIT_ATTRIB_0_POINTER && + dirtyBit < VertexArray::DIRTY_BIT_ATTRIB_MAX_POINTER) + { + size_t attribIndex = + static_cast(dirtyBit) - VertexArray::DIRTY_BIT_ATTRIB_0_POINTER; + updateAttribPointer(attribIndex); + } + else if (dirtyBit >= VertexArray::DIRTY_BIT_ATTRIB_0_DIVISOR && + dirtyBit < VertexArray::DIRTY_BIT_ATTRIB_MAX_DIVISOR) + { + size_t attribIndex = + static_cast(dirtyBit) - VertexArray::DIRTY_BIT_ATTRIB_0_DIVISOR; + const VertexAttribute &attrib = mData.getVertexAttribute(attribIndex); + + if (mAppliedAttributes[attribIndex].divisor != attrib.divisor) + { + mStateManager->bindVertexArray(mVertexArrayID, getAppliedElementArrayBufferID()); + mFunctions->vertexAttribDivisor(static_cast(attribIndex), attrib.divisor); + mAppliedAttributes[attribIndex].divisor = attrib.divisor; + } + } + else + UNREACHABLE(); + } +} + +} // rx diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/VertexArrayGL.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/VertexArrayGL.h index c88803fbbf40..304199965450 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/VertexArrayGL.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/VertexArrayGL.h @@ -20,46 +20,68 @@ class StateManagerGL; class VertexArrayGL : public VertexArrayImpl { public: - VertexArrayGL(const FunctionsGL *functions, StateManagerGL *stateManager); + VertexArrayGL(const gl::VertexArray::Data &data, const FunctionsGL *functions, StateManagerGL *stateManager); ~VertexArrayGL() override; - void setElementArrayBuffer(const gl::Buffer *buffer) override; - void setAttribute(size_t idx, const gl::VertexAttribute &attr) override; - void setAttributeDivisor(size_t idx, GLuint divisor) override; - void enableAttribute(size_t idx, bool enabledState) override; - - gl::Error syncDrawArraysState(GLint first, GLsizei count) const; - gl::Error syncDrawElementsState(GLsizei count, GLenum type, const GLvoid *indices, const GLvoid **outIndices) const; + gl::Error syncDrawArraysState(const gl::AttributesMask &activeAttributesMask, + GLint first, + GLsizei count, + GLsizei instanceCount) const; + gl::Error syncDrawElementsState(const gl::AttributesMask &activeAttributesMask, + GLsizei count, + GLenum type, + const GLvoid *indices, + GLsizei instanceCount, + bool primitiveRestartEnabled, + const GLvoid **outIndices) const; GLuint getVertexArrayID() const; + GLuint getAppliedElementArrayBufferID() const; - private: - gl::Error syncDrawState(GLint first, GLsizei count, GLenum type, const GLvoid *indices, const GLvoid **outIndices) const; - - // Check if any vertex attributes need to be streamed - bool doAttributesNeedStreaming() const; + void syncState(const gl::VertexArray::DirtyBits &dirtyBits) override; - // Apply attribute state, returns the amount of space needed to stream all attributes that need streaming - // and the data size of the largest attribute - gl::Error syncAttributeState(bool attributesNeedStreaming, const RangeUI &indexRange, size_t *outStreamingDataSize, - size_t *outMaxAttributeDataSize) const; + private: + gl::Error syncDrawState(const gl::AttributesMask &activeAttributesMask, + GLint first, + GLsizei count, + GLenum type, + const GLvoid *indices, + GLsizei instanceCount, + bool primitiveRestartEnabled, + const GLvoid **outIndices) const; // Apply index data, only sets outIndexRange if attributesNeedStreaming is true - gl::Error syncIndexData(GLsizei count, GLenum type, const GLvoid *indices, bool attributesNeedStreaming, - RangeUI *outIndexRange, const GLvoid **outIndices) const; + gl::Error syncIndexData(GLsizei count, + GLenum type, + const GLvoid *indices, + bool primitiveRestartEnabled, + bool attributesNeedStreaming, + gl::IndexRange *outIndexRange, + const GLvoid **outIndices) const; + + // Returns the amount of space needed to stream all attributes that need streaming + // and the data size of the largest attribute + void computeStreamingAttributeSizes(const gl::AttributesMask &activeAttributesMask, + GLsizei instanceCount, + const gl::IndexRange &indexRange, + size_t *outStreamingDataSize, + size_t *outMaxAttributeDataSize) const; // Stream attributes that have client data - gl::Error streamAttributes(size_t streamingDataSize, size_t maxAttributeDataSize, const RangeUI &indexRange) const; + gl::Error streamAttributes(const gl::AttributesMask &activeAttributesMask, + GLsizei instanceCount, + const gl::IndexRange &indexRange) const; + + void updateNeedsStreaming(size_t attribIndex); + void updateAttribEnabled(size_t attribIndex); + void updateAttribPointer(size_t attribIndex); const FunctionsGL *mFunctions; StateManagerGL *mStateManager; GLuint mVertexArrayID; - BindingPointer mElementArrayBuffer; - std::vector mAttributes; - - mutable GLuint mAppliedElementArrayBuffer; + mutable BindingPointer mAppliedElementArrayBuffer; mutable std::vector mAppliedAttributes; mutable size_t mStreamingElementArrayBufferSize; @@ -67,6 +89,8 @@ class VertexArrayGL : public VertexArrayImpl mutable size_t mStreamingArrayBufferSize; mutable GLuint mStreamingArrayBuffer; + + gl::AttributesMask mAttributesNeedStreaming; }; } diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/WorkaroundsGL.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/WorkaroundsGL.h new file mode 100644 index 000000000000..a79da25c6679 --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/WorkaroundsGL.h @@ -0,0 +1,69 @@ +// +// Copyright (c) 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. +// + +// WorkaroundsGL.h: Workarounds for GL driver bugs and other issues. + +#ifndef LIBANGLE_RENDERER_GL_WORKAROUNDSGL_H_ +#define LIBANGLE_RENDERER_GL_WORKAROUNDSGL_H_ + +namespace rx +{ + +struct WorkaroundsGL +{ + WorkaroundsGL() + : avoid1BitAlphaTextureFormats(false), + rgba4IsNotSupportedForColorRendering(false), + doesSRGBClearsOnLinearFramebufferAttachments(false), + doWhileGLSLCausesGPUHang(false), + finishDoesNotCauseQueriesToBeAvailable(false), + alwaysCallUseProgramAfterLink(false) + { + } + + // When writing a float to a normalized integer framebuffer, desktop OpenGL is allowed to write + // one of the two closest normalized integer representations (although round to nearest is + // preferred) (see section 2.3.5.2 of the GL 4.5 core specification). OpenGL ES requires that + // round-to-nearest is used (see "Conversion from Floating-Point to Framebuffer Fixed-Point" in + // section 2.1.2 of the OpenGL ES 2.0.25 spec). This issue only shows up on Intel and AMD + // drivers on framebuffer formats that have 1-bit alpha, work around this by using higher + // precision formats instead. + bool avoid1BitAlphaTextureFormats; + + // On some older Intel drivers, GL_RGBA4 is not color renderable, glCheckFramebufferStatus + // returns GL_FRAMEBUFFER_UNSUPPORTED. Work around this by using a known color-renderable + // format. + bool rgba4IsNotSupportedForColorRendering; + + // When clearing a framebuffer on Intel or AMD drivers, when GL_FRAMEBUFFER_SRGB is enabled, the + // driver clears to the linearized clear color despite the framebuffer not supporting SRGB + // blending. It only seems to do this when the framebuffer has only linear attachments, mixed + // attachments appear to get the correct clear color. + bool doesSRGBClearsOnLinearFramebufferAttachments; + + // On Mac some GLSL constructs involving do-while loops cause GPU hangs, such as the following: + // int i = 1; + // do { + // i --; + // continue; + // } while (i > 0) + // Work around this by rewriting the do-while to use another GLSL construct (block + while) + bool doWhileGLSLCausesGPUHang; + + // Calling glFinish doesn't cause all queries to report that the result is available on some + // (NVIDIA) drivers. It was found that enabling GL_DEBUG_OUTPUT_SYNCHRONOUS before the finish + // causes it to fully finish. + bool finishDoesNotCauseQueriesToBeAvailable; + + // Always call useProgram after a successful link to avoid a driver bug. + // This workaround is meant to reproduce the use_current_program_after_successful_link + // workaround in Chromium (http://crbug.com/110263). It has been shown that this workaround is + // not necessary for MacOSX 10.9 and higher (http://crrev.com/39eb535b). + bool alwaysCallUseProgramAfterLink; +}; +} + +#endif // LIBANGLE_RENDERER_GL_WORKAROUNDSGL_H_ diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/cgl/DisplayCGL.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/cgl/DisplayCGL.h new file mode 100644 index 000000000000..293111c83660 --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/cgl/DisplayCGL.h @@ -0,0 +1,73 @@ +// +// Copyright (c) 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. +// + +// DisplayCGL.h: CGL implementation of egl::Display + +#ifndef LIBANGLE_RENDERER_GL_CGL_DISPLAYCGL_H_ +#define LIBANGLE_RENDERER_GL_CGL_DISPLAYCGL_H_ + +#include "libANGLE/renderer/gl/DisplayGL.h" + +struct _CGLContextObject; +typedef _CGLContextObject *CGLContextObj; + +namespace rx +{ + +class DisplayCGL : public DisplayGL +{ + public: + DisplayCGL(); + ~DisplayCGL() override; + + egl::Error initialize(egl::Display *display) override; + void terminate() override; + + SurfaceImpl *createWindowSurface(const egl::Config *configuration, + EGLNativeWindowType window, + const egl::AttributeMap &attribs) override; + SurfaceImpl *createPbufferSurface(const egl::Config *configuration, + const egl::AttributeMap &attribs) override; + SurfaceImpl *createPbufferFromClientBuffer(const egl::Config *configuration, + EGLClientBuffer shareHandle, + const egl::AttributeMap &attribs) override; + SurfaceImpl *createPixmapSurface(const egl::Config *configuration, + NativePixmapType nativePixmap, + const egl::AttributeMap &attribs) override; + + egl::ConfigSet generateConfigs() const override; + + bool isDeviceLost() const override; + bool testDeviceLost() override; + egl::Error restoreLostDevice() override; + + bool isValidNativeWindow(EGLNativeWindowType window) const override; + + egl::Error getDevice(DeviceImpl **device) override; + + std::string getVendorString() const override; + + egl::Error waitClient() const override; + egl::Error waitNative(EGLint engine, + egl::Surface *drawSurface, + egl::Surface *readSurface) const override; + + egl::Error getDriverVersion(std::string *version) const override; + + private: + const FunctionsGL *getFunctionsGL() const override; + + void generateExtensions(egl::DisplayExtensions *outExtensions) const override; + void generateCaps(egl::Caps *outCaps) const override; + + egl::Display *mEGLDisplay; + FunctionsGL *mFunctions; + CGLContextObj mContext; +}; + +} + +#endif // LIBANGLE_RENDERER_GL_CGL_DISPLAYCGL_H_ diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/cgl/DisplayCGL.mm b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/cgl/DisplayCGL.mm new file mode 100644 index 000000000000..df1fa8c1660c --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/cgl/DisplayCGL.mm @@ -0,0 +1,278 @@ +// +// Copyright (c) 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. +// + +// DisplayCGL.mm: CGL implementation of egl::Display + +#include "libANGLE/renderer/gl/cgl/DisplayCGL.h" + +#import +#include +#include + +#include "common/debug.h" +#include "libANGLE/renderer/gl/cgl/PbufferSurfaceCGL.h" +#include "libANGLE/renderer/gl/cgl/WindowSurfaceCGL.h" + +namespace +{ + +const char *kDefaultOpenGLDylibName = + "/System/Library/Frameworks/OpenGL.framework/Libraries/libGL.dylib"; +const char *kFallbackOpenGLDylibName = "GL"; + +} + +namespace rx +{ + +class FunctionsGLCGL : public FunctionsGL +{ + public: + FunctionsGLCGL(void *dylibHandle) : mDylibHandle(dylibHandle) {} + + ~FunctionsGLCGL() override { dlclose(mDylibHandle); } + + private: + void *loadProcAddress(const std::string &function) override + { + return dlsym(mDylibHandle, function.c_str()); + } + + void *mDylibHandle; +}; + +DisplayCGL::DisplayCGL() : DisplayGL(), mEGLDisplay(nullptr), mFunctions(nullptr), mContext(nullptr) +{ +} + +DisplayCGL::~DisplayCGL() +{ +} + +egl::Error DisplayCGL::initialize(egl::Display *display) +{ + mEGLDisplay = display; + + CGLPixelFormatObj pixelFormat; + { + // TODO(cwallez) investigate which pixel format we want + CGLPixelFormatAttribute attribs[] = { + kCGLPFAOpenGLProfile, static_cast(kCGLOGLPVersion_3_2_Core), + static_cast(0)}; + GLint nVirtualScreens = 0; + CGLChoosePixelFormat(attribs, &pixelFormat, &nVirtualScreens); + + if (pixelFormat == nullptr) + { + return egl::Error(EGL_NOT_INITIALIZED, "Could not create the context's pixel format."); + } + } + + CGLCreateContext(pixelFormat, nullptr, &mContext); + if (mContext == nullptr) + { + return egl::Error(EGL_NOT_INITIALIZED, "Could not create the CGL context."); + } + CGLSetCurrentContext(mContext); + + // There is no equivalent getProcAddress in CGL so we open the dylib directly + void *handle = dlopen(kDefaultOpenGLDylibName, RTLD_NOW); + if (!handle) + { + handle = dlopen(kFallbackOpenGLDylibName, RTLD_NOW); + } + if (!handle) + { + return egl::Error(EGL_NOT_INITIALIZED, "Could not open the OpenGL Framework."); + } + + mFunctions = new FunctionsGLCGL(handle); + mFunctions->initialize(); + + return DisplayGL::initialize(display); +} + +void DisplayCGL::terminate() +{ + DisplayGL::terminate(); + + if (mContext != nullptr) + { + CGLSetCurrentContext(nullptr); + CGLReleaseContext(mContext); + mContext = nullptr; + } + + SafeDelete(mFunctions); +} + +SurfaceImpl *DisplayCGL::createWindowSurface(const egl::Config *configuration, + EGLNativeWindowType window, + const egl::AttributeMap &attribs) +{ + return new WindowSurfaceCGL(this->getRenderer(), window, mFunctions, mContext); +} + +SurfaceImpl *DisplayCGL::createPbufferSurface(const egl::Config *configuration, + const egl::AttributeMap &attribs) +{ + EGLint width = static_cast(attribs.get(EGL_WIDTH, 0)); + EGLint height = static_cast(attribs.get(EGL_HEIGHT, 0)); + return new PbufferSurfaceCGL(this->getRenderer(), width, height, mFunctions); +} + +SurfaceImpl* DisplayCGL::createPbufferFromClientBuffer(const egl::Config *configuration, + EGLClientBuffer shareHandle, + const egl::AttributeMap &attribs) +{ + UNIMPLEMENTED(); + return nullptr; +} + +SurfaceImpl *DisplayCGL::createPixmapSurface(const egl::Config *configuration, + NativePixmapType nativePixmap, + const egl::AttributeMap &attribs) +{ + UNIMPLEMENTED(); + return nullptr; +} + +egl::Error DisplayCGL::getDevice(DeviceImpl **device) +{ + UNIMPLEMENTED(); + return egl::Error(EGL_BAD_DISPLAY); +} + +egl::ConfigSet DisplayCGL::generateConfigs() const +{ + // TODO(cwallez): generate more config permutations + egl::ConfigSet configs; + + const gl::Version &maxVersion = getMaxSupportedESVersion(); + ASSERT(maxVersion >= gl::Version(2, 0)); + bool supportsES3 = maxVersion >= gl::Version(3, 0); + + egl::Config config; + + // Native stuff + config.nativeVisualID = 0; + config.nativeVisualType = 0; + config.nativeRenderable = EGL_TRUE; + + // Buffer sizes + config.redSize = 8; + config.greenSize = 8; + config.blueSize = 8; + config.alphaSize = 8; + config.depthSize = 24; + config.stencilSize = 8; + + config.colorBufferType = EGL_RGB_BUFFER; + config.luminanceSize = 0; + config.alphaMaskSize = 0; + + config.bufferSize = config.redSize + config.greenSize + config.blueSize + config.alphaSize; + + config.transparentType = EGL_NONE; + + // Pbuffer + config.maxPBufferWidth = 4096; + config.maxPBufferHeight = 4096; + config.maxPBufferPixels = 4096 * 4096; + + // Caveat + config.configCaveat = EGL_NONE; + + // Misc + config.sampleBuffers = 0; + config.samples = 0; + config.level = 0; + config.bindToTextureRGB = EGL_FALSE; + config.bindToTextureRGBA = EGL_FALSE; + + config.surfaceType = EGL_WINDOW_BIT | EGL_PBUFFER_BIT; + + config.minSwapInterval = 1; + config.maxSwapInterval = 1; + + config.renderTargetFormat = GL_RGBA8; + config.depthStencilFormat = GL_DEPTH24_STENCIL8; + + config.conformant = EGL_OPENGL_ES2_BIT | (supportsES3 ? EGL_OPENGL_ES3_BIT_KHR : 0); + config.renderableType = config.conformant; + + config.matchNativePixmap = EGL_NONE; + + configs.add(config); + return configs; +} + +bool DisplayCGL::isDeviceLost() const +{ + // TODO(cwallez) investigate implementing this + return false; +} + +bool DisplayCGL::testDeviceLost() +{ + // TODO(cwallez) investigate implementing this + return false; +} + +egl::Error DisplayCGL::restoreLostDevice() +{ + UNIMPLEMENTED(); + return egl::Error(EGL_BAD_DISPLAY); +} + +bool DisplayCGL::isValidNativeWindow(EGLNativeWindowType window) const +{ + // TODO(cwallez) investigate implementing this + return true; +} + +std::string DisplayCGL::getVendorString() const +{ + // TODO(cwallez) find a useful vendor string + return ""; +} + +const FunctionsGL *DisplayCGL::getFunctionsGL() const +{ + return mFunctions; +} + +void DisplayCGL::generateExtensions(egl::DisplayExtensions *outExtensions) const +{ + outExtensions->createContext = true; + outExtensions->createContextNoError = true; +} + +void DisplayCGL::generateCaps(egl::Caps *outCaps) const +{ + outCaps->textureNPOT = true; +} + +egl::Error DisplayCGL::waitClient() const +{ + // TODO(cwallez) UNIMPLEMENTED() + return egl::Error(EGL_SUCCESS); +} + +egl::Error DisplayCGL::waitNative(EGLint engine, + egl::Surface *drawSurface, + egl::Surface *readSurface) const +{ + // TODO(cwallez) UNIMPLEMENTED() + return egl::Error(EGL_SUCCESS); +} + +egl::Error DisplayCGL::getDriverVersion(std::string *version) const +{ + *version = ""; + return egl::Error(EGL_SUCCESS); +} +} diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/cgl/PbufferSurfaceCGL.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/cgl/PbufferSurfaceCGL.h new file mode 100644 index 000000000000..80b5f58ecde4 --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/cgl/PbufferSurfaceCGL.h @@ -0,0 +1,64 @@ +// +// Copyright (c) 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. +// + +// PBufferSurfaceCGL.h: an implementation of egl::Surface for PBuffers for the CLG backend, +// currently implemented using renderbuffers + +#ifndef LIBANGLE_RENDERER_GL_CGL_PBUFFERSURFACECGL_H_ +#define LIBANGLE_RENDERER_GL_CGL_PBUFFERSURFACECGL_H_ + +#include "libANGLE/renderer/gl/SurfaceGL.h" + +namespace rx +{ + +class FunctionsGL; +class StateManagerGL; +struct WorkaroundsGL; + +class PbufferSurfaceCGL : public SurfaceGL +{ + public: + PbufferSurfaceCGL(RendererGL *renderer, + EGLint width, + EGLint height, + const FunctionsGL *functions); + ~PbufferSurfaceCGL() override; + + egl::Error initialize() override; + egl::Error makeCurrent() override; + + egl::Error swap() override; + egl::Error postSubBuffer(EGLint x, EGLint y, EGLint width, EGLint height) override; + egl::Error querySurfacePointerANGLE(EGLint attribute, void **value) override; + egl::Error bindTexImage(gl::Texture *texture, EGLint buffer) override; + egl::Error releaseTexImage(EGLint buffer) override; + void setSwapInterval(EGLint interval) override; + + EGLint getWidth() const override; + EGLint getHeight() const override; + + EGLint isPostSubBufferSupported() const override; + EGLint getSwapBehavior() const override; + + FramebufferImpl *createDefaultFramebuffer(const gl::Framebuffer::Data &data) override; + + private: + unsigned mWidth; + unsigned mHeight; + + const FunctionsGL *mFunctions; + StateManagerGL *mStateManager; + const WorkaroundsGL &mWorkarounds; + + GLuint mFramebuffer; + GLuint mColorRenderbuffer; + GLuint mDSRenderbuffer; +}; + +} + +#endif // LIBANGLE_RENDERER_GL_CGL_PBUFFERSURFACECGL_H_ diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/cgl/PbufferSurfaceCGL.mm b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/cgl/PbufferSurfaceCGL.mm new file mode 100644 index 000000000000..ec936a60a481 --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/cgl/PbufferSurfaceCGL.mm @@ -0,0 +1,141 @@ +// +// Copyright (c) 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. +// + +// PBufferSurfaceCGL.cpp: an implementation of egl::Surface for PBuffers for the CLG backend, +// currently implemented using renderbuffers + +#include "libANGLE/renderer/gl/cgl/PbufferSurfaceCGL.h" + +#include "common/debug.h" +#include "libANGLE/renderer/gl/FunctionsGL.h" +#include "libANGLE/renderer/gl/FramebufferGL.h" +#include "libANGLE/renderer/gl/RendererGL.h" +#include "libANGLE/renderer/gl/StateManagerGL.h" + +namespace rx +{ + +PbufferSurfaceCGL::PbufferSurfaceCGL(RendererGL *renderer, + EGLint width, + EGLint height, + const FunctionsGL *functions) + : SurfaceGL(renderer), + mWidth(width), + mHeight(height), + mFunctions(functions), + mStateManager(renderer->getStateManager()), + mWorkarounds(renderer->getWorkarounds()), + mFramebuffer(0), + mColorRenderbuffer(0), + mDSRenderbuffer(0) +{ +} + +PbufferSurfaceCGL::~PbufferSurfaceCGL() +{ + if (mFramebuffer != 0) + { + mFunctions->deleteFramebuffers(1, &mFramebuffer); + mFramebuffer = 0; + } + + if (mColorRenderbuffer != 0) + { + mFunctions->deleteRenderbuffers(1, &mColorRenderbuffer); + mColorRenderbuffer = 0; + } + if (mDSRenderbuffer != 0) + { + mFunctions->deleteRenderbuffers(1, &mDSRenderbuffer); + mDSRenderbuffer = 0; + } +} + +egl::Error PbufferSurfaceCGL::initialize() +{ + mFunctions->genRenderbuffers(1, &mColorRenderbuffer); + mStateManager->bindRenderbuffer(GL_RENDERBUFFER, mColorRenderbuffer); + mFunctions->renderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, mWidth, mHeight); + + mFunctions->genRenderbuffers(1, &mDSRenderbuffer); + mStateManager->bindRenderbuffer(GL_RENDERBUFFER, mDSRenderbuffer); + mFunctions->renderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, mWidth, mHeight); + + mFunctions->genFramebuffers(1, &mFramebuffer); + mStateManager->bindFramebuffer(GL_FRAMEBUFFER, mFramebuffer); + mFunctions->framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, + mColorRenderbuffer); + mFunctions->framebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, + GL_RENDERBUFFER, mDSRenderbuffer); + + return egl::Error(EGL_SUCCESS); +} + +egl::Error PbufferSurfaceCGL::makeCurrent() +{ + return egl::Error(EGL_SUCCESS); +} + +egl::Error PbufferSurfaceCGL::swap() +{ + return egl::Error(EGL_SUCCESS); +} + +egl::Error PbufferSurfaceCGL::postSubBuffer(EGLint x, EGLint y, EGLint width, EGLint height) +{ + return egl::Error(EGL_SUCCESS); +} + +egl::Error PbufferSurfaceCGL::querySurfacePointerANGLE(EGLint attribute, void **value) +{ + UNIMPLEMENTED(); + return egl::Error(EGL_SUCCESS); +} + +egl::Error PbufferSurfaceCGL::bindTexImage(gl::Texture *texture, EGLint buffer) +{ + UNIMPLEMENTED(); + return egl::Error(EGL_SUCCESS); +} + +egl::Error PbufferSurfaceCGL::releaseTexImage(EGLint buffer) +{ + UNIMPLEMENTED(); + return egl::Error(EGL_SUCCESS); +} + +void PbufferSurfaceCGL::setSwapInterval(EGLint interval) +{ +} + +EGLint PbufferSurfaceCGL::getWidth() const +{ + return mWidth; +} + +EGLint PbufferSurfaceCGL::getHeight() const +{ + return mHeight; +} + +EGLint PbufferSurfaceCGL::isPostSubBufferSupported() const +{ + UNIMPLEMENTED(); + return EGL_FALSE; +} + +EGLint PbufferSurfaceCGL::getSwapBehavior() const +{ + return EGL_BUFFER_PRESERVED; +} + +FramebufferImpl *PbufferSurfaceCGL::createDefaultFramebuffer(const gl::Framebuffer::Data &data) +{ + // TODO(cwallez) assert it happens only once? + return new FramebufferGL(mFramebuffer, data, mFunctions, mWorkarounds, mStateManager); +} + +} diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/cgl/WindowSurfaceCGL.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/cgl/WindowSurfaceCGL.h new file mode 100644 index 000000000000..83cbe8f092cc --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/cgl/WindowSurfaceCGL.h @@ -0,0 +1,98 @@ +// +// Copyright (c) 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. +// + +// WindowSurfaceCGL.h: CGL implementation of egl::Surface for windows + +#ifndef LIBANGLE_RENDERER_GL_CGL_WINDOWSURFACECGL_H_ +#define LIBANGLE_RENDERER_GL_CGL_WINDOWSURFACECGL_H_ + +#include "libANGLE/renderer/gl/SurfaceGL.h" + +struct _CGLContextObject; +typedef _CGLContextObject *CGLContextObj; +@class CALayer; +struct __IOSurface; +typedef __IOSurface *IOSurfaceRef; + +@class SwapLayer; + +namespace rx +{ + +class DisplayCGL; +class FramebufferGL; +class FunctionsGL; +class StateManagerGL; +struct WorkaroundsGL; + +struct SharedSwapState +{ + struct SwapTexture + { + GLuint texture; + unsigned int width; + unsigned int height; + uint64_t swapId; + }; + + SwapTexture textures[3]; + + // This code path is not going to be used by Chrome so we take the liberty + // to use pthreads directly instead of using mutexes and condition variables + // via the Platform API. + pthread_mutex_t mutex; + // The following members should be accessed only when holding the mutex + // (or doing construction / destruction) + SwapTexture *beingRendered; + SwapTexture *lastRendered; + SwapTexture *beingPresented; +}; + +class WindowSurfaceCGL : public SurfaceGL +{ + public: + WindowSurfaceCGL(RendererGL *renderer, + CALayer *layer, + const FunctionsGL *functions, + CGLContextObj context); + ~WindowSurfaceCGL() override; + + egl::Error initialize() override; + egl::Error makeCurrent() override; + + egl::Error swap() override; + egl::Error postSubBuffer(EGLint x, EGLint y, EGLint width, EGLint height) override; + egl::Error querySurfacePointerANGLE(EGLint attribute, void **value) override; + egl::Error bindTexImage(gl::Texture *texture, EGLint buffer) override; + egl::Error releaseTexImage(EGLint buffer) override; + void setSwapInterval(EGLint interval) override; + + EGLint getWidth() const override; + EGLint getHeight() const override; + + EGLint isPostSubBufferSupported() const override; + EGLint getSwapBehavior() const override; + + FramebufferImpl *createDefaultFramebuffer(const gl::Framebuffer::Data &data) override; + + private: + SwapLayer *mSwapLayer; + SharedSwapState mSwapState; + uint64_t mCurrentSwapId; + + CALayer *mLayer; + CGLContextObj mContext; + const FunctionsGL *mFunctions; + StateManagerGL *mStateManager; + const WorkaroundsGL &mWorkarounds; + + GLuint mFramebuffer; + GLuint mDSRenderbuffer; +}; + +} + +#endif // LIBANGLE_RENDERER_GL_CGL_WINDOWSURFACECGL_H_ diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/cgl/WindowSurfaceCGL.mm b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/cgl/WindowSurfaceCGL.mm new file mode 100644 index 000000000000..0dc5770f297a --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/cgl/WindowSurfaceCGL.mm @@ -0,0 +1,329 @@ +// +// Copyright (c) 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. +// + +// WindowSurfaceCGL.cpp: CGL implementation of egl::Surface for windows + +#include "libANGLE/renderer/gl/cgl/WindowSurfaceCGL.h" + +#import +#include +#import + +#include "common/debug.h" +#include "libANGLE/renderer/gl/cgl/DisplayCGL.h" +#include "libANGLE/renderer/gl/FramebufferGL.h" +#include "libANGLE/renderer/gl/RendererGL.h" +#include "libANGLE/renderer/gl/StateManagerGL.h" + +@interface SwapLayer : CAOpenGLLayer +{ + CGLContextObj mDisplayContext; + + bool initialized; + rx::SharedSwapState *mSwapState; + const rx::FunctionsGL *mFunctions; + + GLuint mReadFramebuffer; +} +- (id)initWithSharedState:(rx::SharedSwapState *)swapState + withContext:(CGLContextObj)displayContext + withFunctions:(const rx::FunctionsGL *)functions; +@end + +@implementation SwapLayer +- (id)initWithSharedState:(rx::SharedSwapState *)swapState + withContext:(CGLContextObj)displayContext + withFunctions:(const rx::FunctionsGL *)functions + { + self = [super init]; + if (self != nil) + { + self.asynchronous = YES; + mDisplayContext = displayContext; + + initialized = false; + mSwapState = swapState; + mFunctions = functions; + + [self setFrame:CGRectMake(0, 0, mSwapState->textures[0].width, + mSwapState->textures[0].height)]; + } + return self; + } + + - (CGLPixelFormatObj)copyCGLPixelFormatForDisplayMask:(uint32_t)mask + { + CGLPixelFormatAttribute attribs[] = { + kCGLPFADisplayMask, static_cast(mask), kCGLPFAOpenGLProfile, + static_cast(kCGLOGLPVersion_3_2_Core), + static_cast(0)}; + + CGLPixelFormatObj pixelFormat = nullptr; + GLint numFormats = 0; + CGLChoosePixelFormat(attribs, &pixelFormat, &numFormats); + + return pixelFormat; + } + + - (CGLContextObj)copyCGLContextForPixelFormat:(CGLPixelFormatObj)pixelFormat + { + CGLContextObj context = nullptr; + CGLCreateContext(pixelFormat, mDisplayContext, &context); + return context; + } + + - (BOOL)canDrawInCGLContext:(CGLContextObj)glContext + pixelFormat:(CGLPixelFormatObj)pixelFormat + forLayerTime:(CFTimeInterval)timeInterval + displayTime:(const CVTimeStamp *)timeStamp + { + BOOL result = NO; + + pthread_mutex_lock(&mSwapState->mutex); + { + if (mSwapState->lastRendered->swapId > mSwapState->beingPresented->swapId) + { + std::swap(mSwapState->lastRendered, mSwapState->beingPresented); + result = YES; + } + } + pthread_mutex_unlock(&mSwapState->mutex); + + return result; + } + + - (void)drawInCGLContext:(CGLContextObj)glContext + pixelFormat:(CGLPixelFormatObj)pixelFormat + forLayerTime:(CFTimeInterval)timeInterval + displayTime:(const CVTimeStamp *)timeStamp + { + CGLSetCurrentContext(glContext); + if (!initialized) + { + initialized = true; + + mFunctions->genFramebuffers(1, &mReadFramebuffer); + } + + const auto &texture = *mSwapState->beingPresented; + if ([self frame].size.width != texture.width || [self frame].size.height != texture.height) + { + [self setFrame:CGRectMake(0, 0, texture.width, texture.height)]; + + // Without this, the OSX compositor / window system doesn't see the resize. + [self setNeedsDisplay]; + } + + // TODO(cwallez) support 2.1 contexts too that don't have blitFramebuffer nor the + // GL_DRAW_FRAMEBUFFER_BINDING query + GLint drawFBO; + mFunctions->getIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &drawFBO); + + mFunctions->bindFramebuffer(GL_FRAMEBUFFER, mReadFramebuffer); + mFunctions->framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, + texture.texture, 0); + + mFunctions->bindFramebuffer(GL_READ_FRAMEBUFFER, mReadFramebuffer); + mFunctions->bindFramebuffer(GL_DRAW_FRAMEBUFFER, drawFBO); + mFunctions->blitFramebuffer(0, 0, texture.width, texture.height, 0, 0, texture.width, + texture.height, GL_COLOR_BUFFER_BIT, GL_NEAREST); + + // Call the super method to flush the context + [super drawInCGLContext:glContext + pixelFormat:pixelFormat + forLayerTime:timeInterval + displayTime:timeStamp]; + } + @end + + namespace rx + { + + WindowSurfaceCGL::WindowSurfaceCGL(RendererGL *renderer, + CALayer *layer, + const FunctionsGL *functions, + CGLContextObj context) + : SurfaceGL(renderer), + mSwapLayer(nil), + mCurrentSwapId(0), + mLayer(layer), + mContext(context), + mFunctions(functions), + mStateManager(renderer->getStateManager()), + mWorkarounds(renderer->getWorkarounds()), + mFramebuffer(0), + mDSRenderbuffer(0) +{ + pthread_mutex_init(&mSwapState.mutex, nullptr); +} + +WindowSurfaceCGL::~WindowSurfaceCGL() +{ + pthread_mutex_destroy(&mSwapState.mutex); + if (mFramebuffer != 0) + { + mFunctions->deleteFramebuffers(1, &mFramebuffer); + mFramebuffer = 0; + } + + if (mDSRenderbuffer != 0) + { + mFunctions->deleteRenderbuffers(1, &mDSRenderbuffer); + mDSRenderbuffer = 0; + } + + if (mSwapLayer != nil) + { + [mSwapLayer removeFromSuperlayer]; + [mSwapLayer release]; + mSwapLayer = nil; + } + + for (size_t i = 0; i < ArraySize(mSwapState.textures); ++i) + { + if (mSwapState.textures[i].texture != 0) + { + mFunctions->deleteTextures(1, &mSwapState.textures[i].texture); + mSwapState.textures[i].texture = 0; + } + } +} + +egl::Error WindowSurfaceCGL::initialize() +{ + unsigned width = getWidth(); + unsigned height = getHeight(); + + for (size_t i = 0; i < ArraySize(mSwapState.textures); ++i) + { + mFunctions->genTextures(1, &mSwapState.textures[i].texture); + mStateManager->bindTexture(GL_TEXTURE_2D, mSwapState.textures[i].texture); + mFunctions->texImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, + GL_UNSIGNED_BYTE, nullptr); + mSwapState.textures[i].width = width; + mSwapState.textures[i].height = height; + mSwapState.textures[i].swapId = 0; + } + mSwapState.beingRendered = &mSwapState.textures[0]; + mSwapState.lastRendered = &mSwapState.textures[1]; + mSwapState.beingPresented = &mSwapState.textures[2]; + + mSwapLayer = [[SwapLayer alloc] initWithSharedState:&mSwapState + withContext:mContext + withFunctions:mFunctions]; + [mLayer addSublayer:mSwapLayer]; + + mFunctions->genRenderbuffers(1, &mDSRenderbuffer); + mStateManager->bindRenderbuffer(GL_RENDERBUFFER, mDSRenderbuffer); + mFunctions->renderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, width, height); + + mFunctions->genFramebuffers(1, &mFramebuffer); + mStateManager->bindFramebuffer(GL_FRAMEBUFFER, mFramebuffer); + mFunctions->framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, + mSwapState.beingRendered->texture, 0); + mFunctions->framebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, + mDSRenderbuffer); + + return egl::Error(EGL_SUCCESS); +} + +egl::Error WindowSurfaceCGL::makeCurrent() +{ + return egl::Error(EGL_SUCCESS); +} + +egl::Error WindowSurfaceCGL::swap() +{ + mFunctions->flush(); + mSwapState.beingRendered->swapId = ++mCurrentSwapId; + + pthread_mutex_lock(&mSwapState.mutex); + { + std::swap(mSwapState.beingRendered, mSwapState.lastRendered); + } + pthread_mutex_unlock(&mSwapState.mutex); + + unsigned width = getWidth(); + unsigned height = getHeight(); + auto &texture = *mSwapState.beingRendered; + + if (texture.width != width || texture.height != height) + { + mStateManager->bindTexture(GL_TEXTURE_2D, texture.texture); + mFunctions->texImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, + GL_UNSIGNED_BYTE, nullptr); + + mStateManager->bindRenderbuffer(GL_RENDERBUFFER, mDSRenderbuffer); + mFunctions->renderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, width, height); + + texture.width = width; + texture.height = height; + } + + mStateManager->bindFramebuffer(GL_FRAMEBUFFER, mFramebuffer); + mFunctions->framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, + mSwapState.beingRendered->texture, 0); + + return egl::Error(EGL_SUCCESS); +} + +egl::Error WindowSurfaceCGL::postSubBuffer(EGLint x, EGLint y, EGLint width, EGLint height) +{ + UNIMPLEMENTED(); + return egl::Error(EGL_SUCCESS); +} + +egl::Error WindowSurfaceCGL::querySurfacePointerANGLE(EGLint attribute, void **value) +{ + UNIMPLEMENTED(); + return egl::Error(EGL_SUCCESS); +} + +egl::Error WindowSurfaceCGL::bindTexImage(gl::Texture *texture, EGLint buffer) +{ + UNIMPLEMENTED(); + return egl::Error(EGL_SUCCESS); +} + +egl::Error WindowSurfaceCGL::releaseTexImage(EGLint buffer) +{ + UNIMPLEMENTED(); + return egl::Error(EGL_SUCCESS); +} + +void WindowSurfaceCGL::setSwapInterval(EGLint interval) +{ + // TODO(cwallez) investigate implementing swap intervals other than 0 +} + +EGLint WindowSurfaceCGL::getWidth() const +{ + return CGRectGetWidth([mLayer frame]); +} + +EGLint WindowSurfaceCGL::getHeight() const +{ + return CGRectGetHeight([mLayer frame]); +} + +EGLint WindowSurfaceCGL::isPostSubBufferSupported() const +{ + UNIMPLEMENTED(); + return EGL_FALSE; +} + +EGLint WindowSurfaceCGL::getSwapBehavior() const +{ + return EGL_BUFFER_DESTROYED; +} + +FramebufferImpl *WindowSurfaceCGL::createDefaultFramebuffer(const gl::Framebuffer::Data &data) +{ + // TODO(cwallez) assert it happens only once? + return new FramebufferGL(mFramebuffer, data, mFunctions, mWorkarounds, mStateManager); +} + +} diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/formatutilsgl.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/formatutilsgl.cpp index 299622e5ee43..d69d7389c53e 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/formatutilsgl.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/formatutilsgl.cpp @@ -9,7 +9,10 @@ #include "libANGLE/renderer/gl/formatutilsgl.h" -#include +#include + +#include "common/string_utils.h" +#include "libANGLE/formatutils.h" namespace rx { @@ -17,49 +20,105 @@ namespace rx namespace nativegl { -// Information about internal formats -static bool AlwaysSupported(GLuint, GLuint, const std::vector &) +SupportRequirement::SupportRequirement() + : version(std::numeric_limits::max(), std::numeric_limits::max()), + versionExtensions(), + requiredExtensions() { - return true; } -static bool UnimplementedSupport(GLuint, GLuint, const std::vector &) +InternalFormat::InternalFormat() + : texture(), + filter(), + renderbuffer(), + framebufferAttachment() { - return false; } -static bool NeverSupported(GLuint, GLuint, const std::vector &) +// supported = version || vertexExt +static inline SupportRequirement VersionOrExts(GLuint major, GLuint minor, const std::string &versionExt) { - return false; + SupportRequirement requirement; + requirement.version.major = major; + requirement.version.minor = minor; + angle::SplitStringAlongWhitespace(versionExt, &requirement.versionExtensions); + return requirement; } -template -static bool RequireGL(GLuint major, GLuint minor, const std::vector &) +// supported = (version || vertexExt) && requiredExt +static inline SupportRequirement VersionOrExtsAndExts(GLuint major, + GLuint minor, + const std::string &versionExt, + const std::string &requiredExt) { - return major > minMajorVersion || (major == minMajorVersion && minor >= minMinorVersion); + SupportRequirement requirement; + requirement.version.major = major; + requirement.version.minor = minor; + angle::SplitStringAlongWhitespace(versionExt, &requirement.versionExtensions); + angle::SplitStringAlongWhitespace(requiredExt, &requirement.requiredExtensions); + return requirement; } +// supported = version +static inline SupportRequirement VersionOnly(GLuint major, GLuint minor) +{ + SupportRequirement requirement; + requirement.version.major = major; + requirement.version.minor = minor; + return requirement; +} -InternalFormat::InternalFormat() - : textureSupport(NeverSupported), - renderSupport(NeverSupported), - filterSupport(NeverSupported) +// supported = ext +static inline SupportRequirement ExtsOnly(const std::string &ext) { + SupportRequirement requirement; + requirement.version.major = 0; + requirement.version.minor = 0; + angle::SplitStringAlongWhitespace(ext, &requirement.requiredExtensions); + return requirement; } -typedef std::pair InternalFormatInfoPair; -typedef std::map InternalFormatInfoMap; +// supported = true +static inline SupportRequirement Always() +{ + SupportRequirement requirement; + requirement.version.major = 0; + requirement.version.minor = 0; + return requirement; +} + +// supported = false +static inline SupportRequirement Never() +{ + SupportRequirement requirement; + requirement.version.major = std::numeric_limits::max(); + requirement.version.minor = std::numeric_limits::max(); + return requirement; +} + +struct InternalFormatInfo +{ + InternalFormat glesInfo; + InternalFormat glInfo; +}; + +typedef std::pair InternalFormatInfoPair; +typedef std::map InternalFormatInfoMap; // A helper function to insert data into the format map with fewer characters. static inline void InsertFormatMapping(InternalFormatInfoMap *map, GLenum internalFormat, - InternalFormat::SupportCheckFunction textureSupport, - InternalFormat::SupportCheckFunction renderSupport, - InternalFormat::SupportCheckFunction filterSupport) -{ - InternalFormat formatInfo; - formatInfo.textureSupport = textureSupport; - formatInfo.renderSupport = renderSupport; - formatInfo.filterSupport = filterSupport; + const SupportRequirement &desktopTexture, const SupportRequirement &desktopFilter, const SupportRequirement &desktopRender, + const SupportRequirement &esTexture, const SupportRequirement &esFilter, const SupportRequirement &esRender) +{ + InternalFormatInfo formatInfo; + formatInfo.glInfo.texture = desktopTexture; + formatInfo.glInfo.filter = desktopFilter; + formatInfo.glInfo.renderbuffer = desktopRender; + formatInfo.glInfo.framebufferAttachment = desktopRender; + formatInfo.glesInfo.texture = esTexture; + formatInfo.glesInfo.filter = esTexture; + formatInfo.glesInfo.renderbuffer = esFilter; + formatInfo.glesInfo.framebufferAttachment = esRender; map->insert(std::make_pair(internalFormat, formatInfo)); } @@ -67,129 +126,131 @@ static InternalFormatInfoMap BuildInternalFormatInfoMap() { InternalFormatInfoMap map; - // From ES 3.0.1 spec, table 3.12 - InsertFormatMapping(&map, GL_NONE, NeverSupported, NeverSupported, NeverSupported); - - // | Internal format | Texture support | Render support | Filter support | - InsertFormatMapping(&map, GL_R8, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport); - InsertFormatMapping(&map, GL_R8_SNORM, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport); - InsertFormatMapping(&map, GL_RG8, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport); - InsertFormatMapping(&map, GL_RG8_SNORM, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport); - InsertFormatMapping(&map, GL_RGB8, AlwaysSupported, AlwaysSupported, AlwaysSupported ); - InsertFormatMapping(&map, GL_RGB8_SNORM, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport); - InsertFormatMapping(&map, GL_RGB565, AlwaysSupported, AlwaysSupported, AlwaysSupported ); - InsertFormatMapping(&map, GL_RGBA4, AlwaysSupported, AlwaysSupported, AlwaysSupported ); - InsertFormatMapping(&map, GL_RGB5_A1, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport); - InsertFormatMapping(&map, GL_RGBA8, AlwaysSupported, AlwaysSupported, AlwaysSupported ); - InsertFormatMapping(&map, GL_RGBA8_SNORM, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport); - InsertFormatMapping(&map, GL_RGB10_A2, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport); - InsertFormatMapping(&map, GL_RGB10_A2UI, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport); - InsertFormatMapping(&map, GL_SRGB8, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport); - InsertFormatMapping(&map, GL_SRGB8_ALPHA8, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport); - InsertFormatMapping(&map, GL_R11F_G11F_B10F, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport); - InsertFormatMapping(&map, GL_RGB9_E5, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport); - InsertFormatMapping(&map, GL_R8I, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport); - InsertFormatMapping(&map, GL_R8UI, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport); - InsertFormatMapping(&map, GL_R16I, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport); - InsertFormatMapping(&map, GL_R16UI, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport); - InsertFormatMapping(&map, GL_R32I, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport); - InsertFormatMapping(&map, GL_R32UI, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport); - InsertFormatMapping(&map, GL_RG8I, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport); - InsertFormatMapping(&map, GL_RG8UI, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport); - InsertFormatMapping(&map, GL_RG16I, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport); - InsertFormatMapping(&map, GL_RG16UI, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport); - InsertFormatMapping(&map, GL_RG32I, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport); - InsertFormatMapping(&map, GL_RG32UI, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport); - InsertFormatMapping(&map, GL_RGB8I, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport); - InsertFormatMapping(&map, GL_RGB8UI, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport); - InsertFormatMapping(&map, GL_RGB16I, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport); - InsertFormatMapping(&map, GL_RGB16UI, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport); - InsertFormatMapping(&map, GL_RGB32I, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport); - InsertFormatMapping(&map, GL_RGB32UI, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport); - InsertFormatMapping(&map, GL_RGBA8I, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport); - InsertFormatMapping(&map, GL_RGBA8UI, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport); - InsertFormatMapping(&map, GL_RGBA16I, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport); - InsertFormatMapping(&map, GL_RGBA16UI, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport); - InsertFormatMapping(&map, GL_RGBA32I, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport); - InsertFormatMapping(&map, GL_RGBA32UI, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport); - - InsertFormatMapping(&map, GL_BGRA8_EXT, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport); + // clang-format off + // | Format | OpenGL texture support | Filter | OpenGL render support | OpenGL ES texture support | Filter | OpenGL ES render support | + InsertFormatMapping(&map, GL_R8, VersionOrExts(3, 0, "GL_ARB_texture_rg"), Always(), VersionOrExts(3, 0, "GL_ARB_texture_rg"), VersionOrExts(3, 0, "GL_EXT_texture_rg"), Always(), VersionOrExts(3, 0, "GL_EXT_texture_rg") ); + InsertFormatMapping(&map, GL_R8_SNORM, VersionOnly(3, 1), Always(), Never(), VersionOnly(3, 0), Always(), Never() ); + InsertFormatMapping(&map, GL_RG8, VersionOrExts(3, 0, "GL_ARB_texture_rg"), Always(), VersionOrExts(3, 0, "GL_ARB_texture_rg"), VersionOrExts(3, 0, "GL_EXT_texture_rg"), Always(), VersionOrExts(3, 0, "GL_ARB_texture_rg") ); + InsertFormatMapping(&map, GL_RG8_SNORM, VersionOnly(3, 1), Always(), Never(), VersionOnly(3, 0), Always(), Never() ); + InsertFormatMapping(&map, GL_RGB8, Always(), Always(), Always(), VersionOrExts(3, 0, "GL_OES_rgb8_rgba8"), Always(), Always() ); + InsertFormatMapping(&map, GL_RG8_SNORM, VersionOnly(3, 1), Always(), Never(), VersionOnly(3, 0), Always(), Never() ); + InsertFormatMapping(&map, GL_RGB565, Always(), Always(), Always(), Always(), Always(), Always() ); + InsertFormatMapping(&map, GL_RGBA4, Always(), Always(), Always(), Always(), Always(), Always() ); + InsertFormatMapping(&map, GL_RGB5_A1, Always(), Always(), Always(), Always(), Always(), Always() ); + InsertFormatMapping(&map, GL_RGBA8, Always(), Always(), Always(), VersionOrExts(3, 0, "GL_OES_rgb8_rgba8"), Always(), VersionOrExts(3, 0, "GL_OES_rgb8_rgba8") ); + InsertFormatMapping(&map, GL_RGBA8_SNORM, VersionOnly(3, 1), Always(), Never(), VersionOnly(3, 0), Always(), Never() ); + InsertFormatMapping(&map, GL_RGB10_A2, Always(), Always(), Always(), VersionOnly(3, 0), Always(), VersionOnly(3, 0) ); + InsertFormatMapping(&map, GL_RGB10_A2UI, VersionOrExts(3, 3, "GL_ARB_texture_rgb10_a2ui"), Never(), Always(), VersionOnly(3, 0), Never(), Always() ); + InsertFormatMapping(&map, GL_SRGB8, VersionOrExts(2, 1, "GL_EXT_texture_sRGB"), Always(), VersionOrExts(2, 1, "GL_EXT_texture_sRGB"), VersionOnly(3, 0), Always(), Never() ); + InsertFormatMapping(&map, GL_SRGB8_ALPHA8, VersionOrExts(2, 1, "GL_EXT_texture_sRGB"), Always(), VersionOrExts(2, 1, "GL_EXT_texture_sRGB"), VersionOnly(3, 0), Always(), VersionOrExts(3, 0, "GL_EXT_sRGB") ); + InsertFormatMapping(&map, GL_R8I, VersionOrExts(3, 0, "GL_ARB_texture_rg"), Never(), VersionOrExts(3, 0, "GL_ARB_texture_rg"), VersionOnly(3, 0), Never(), VersionOnly(3, 0) ); + InsertFormatMapping(&map, GL_R8UI, VersionOrExts(3, 0, "GL_ARB_texture_rg"), Never(), VersionOrExts(3, 0, "GL_ARB_texture_rg"), VersionOnly(3, 0), Never(), VersionOnly(3, 0) ); + InsertFormatMapping(&map, GL_R16I, VersionOrExts(3, 0, "GL_ARB_texture_rg"), Never(), VersionOrExts(3, 0, "GL_ARB_texture_rg"), VersionOnly(3, 0), Never(), VersionOnly(3, 0) ); + InsertFormatMapping(&map, GL_R16UI, VersionOrExts(3, 0, "GL_ARB_texture_rg"), Never(), VersionOrExts(3, 0, "GL_ARB_texture_rg"), VersionOnly(3, 0), Never(), VersionOnly(3, 0) ); + InsertFormatMapping(&map, GL_R32I, VersionOrExts(3, 0, "GL_ARB_texture_rg"), Never(), VersionOrExts(3, 0, "GL_ARB_texture_rg"), VersionOnly(3, 0), Never(), VersionOnly(3, 0) ); + InsertFormatMapping(&map, GL_R32UI, VersionOrExts(3, 0, "GL_ARB_texture_rg"), Never(), VersionOrExts(3, 0, "GL_ARB_texture_rg"), VersionOnly(3, 0), Never(), VersionOnly(3, 0) ); + InsertFormatMapping(&map, GL_RG8I, VersionOrExts(3, 0, "GL_ARB_texture_rg"), Never(), VersionOrExts(3, 0, "GL_ARB_texture_rg"), VersionOnly(3, 0), Never(), VersionOnly(3, 0) ); + InsertFormatMapping(&map, GL_RG8UI, VersionOrExts(3, 0, "GL_ARB_texture_rg"), Never(), VersionOrExts(3, 0, "GL_ARB_texture_rg"), VersionOnly(3, 0), Never(), VersionOnly(3, 0) ); + InsertFormatMapping(&map, GL_RG16I, VersionOrExts(3, 0, "GL_ARB_texture_rg"), Never(), VersionOrExts(3, 0, "GL_ARB_texture_rg"), VersionOnly(3, 0), Never(), VersionOnly(3, 0) ); + InsertFormatMapping(&map, GL_RG16UI, VersionOrExts(3, 0, "GL_ARB_texture_rg"), Never(), VersionOrExts(3, 0, "GL_ARB_texture_rg"), VersionOnly(3, 0), Never(), VersionOnly(3, 0) ); + InsertFormatMapping(&map, GL_RG32I, VersionOrExts(3, 0, "GL_ARB_texture_rg"), Never(), VersionOrExts(3, 0, "GL_ARB_texture_rg"), VersionOnly(3, 0), Never(), VersionOnly(3, 0) ); + InsertFormatMapping(&map, GL_RG32UI, VersionOrExts(3, 0, "GL_ARB_texture_rg"), Never(), VersionOrExts(3, 0, "GL_ARB_texture_rg"), VersionOnly(3, 0), Never(), VersionOnly(3, 0) ); + InsertFormatMapping(&map, GL_RGB8I, VersionOrExts(3, 0, "GL_EXT_texture_integer"), Never(), Never(), VersionOnly(3, 0), Never(), Never() ); + InsertFormatMapping(&map, GL_RGB8UI, VersionOrExts(3, 0, "GL_EXT_texture_integer"), Never(), Never(), VersionOnly(3, 0), Never(), Never() ); + InsertFormatMapping(&map, GL_RGB16I, VersionOrExts(3, 0, "GL_EXT_texture_integer"), Never(), Never(), VersionOnly(3, 0), Never(), Never() ); + InsertFormatMapping(&map, GL_RGB16UI, VersionOrExts(3, 0, "GL_EXT_texture_integer"), Never(), Never(), VersionOnly(3, 0), Never(), Never() ); + InsertFormatMapping(&map, GL_RGB32I, VersionOrExts(3, 0, "GL_EXT_texture_integer"), Never(), Never(), VersionOnly(3, 0), Never(), Never() ); + InsertFormatMapping(&map, GL_RGB32UI, VersionOrExts(3, 0, "GL_EXT_texture_integer"), Never(), Never(), VersionOnly(3, 0), Never(), Never() ); + InsertFormatMapping(&map, GL_RGBA8I, VersionOrExts(3, 0, "GL_EXT_texture_integer"), Never(), VersionOrExts(3, 0, "GL_EXT_texture_integer"), VersionOnly(3, 0), Never(), VersionOnly(3, 0) ); + InsertFormatMapping(&map, GL_RGBA8UI, VersionOrExts(3, 0, "GL_EXT_texture_integer"), Never(), VersionOrExts(3, 0, "GL_EXT_texture_integer"), VersionOnly(3, 0), Never(), VersionOnly(3, 0) ); + InsertFormatMapping(&map, GL_RGBA16I, VersionOrExts(3, 0, "GL_EXT_texture_integer"), Never(), VersionOrExts(3, 0, "GL_EXT_texture_integer"), VersionOnly(3, 0), Never(), VersionOnly(3, 0) ); + InsertFormatMapping(&map, GL_RGBA16UI, VersionOrExts(3, 0, "GL_EXT_texture_integer"), Never(), VersionOrExts(3, 0, "GL_EXT_texture_integer"), VersionOnly(3, 0), Never(), VersionOnly(3, 0) ); + InsertFormatMapping(&map, GL_RGBA32I, VersionOrExts(3, 0, "GL_EXT_texture_integer"), Never(), VersionOrExts(3, 0, "GL_EXT_texture_integer"), VersionOnly(3, 0), Never(), VersionOnly(3, 0) ); + InsertFormatMapping(&map, GL_RGBA32UI, VersionOrExts(3, 0, "GL_EXT_texture_integer"), Never(), VersionOrExts(3, 0, "GL_EXT_texture_integer"), VersionOnly(3, 0), Never(), VersionOnly(3, 0) ); + + // Unsized formats + InsertFormatMapping(&map, GL_ALPHA, Never(), Never(), Never(), Never(), Never(), Never() ); + InsertFormatMapping(&map, GL_LUMINANCE, Never(), Never(), Never(), Never(), Never(), Never() ); + InsertFormatMapping(&map, GL_LUMINANCE_ALPHA, Never(), Never(), Never(), Never(), Never(), Never() ); + InsertFormatMapping(&map, GL_RED, VersionOrExts(3, 0, "GL_ARB_texture_rg"), Always(), VersionOrExts(3, 0, "GL_ARB_texture_rg"), VersionOrExts(3, 0, "GL_EXT_texture_rg"), Always(), VersionOrExts(3, 0, "GL_ARB_texture_rg") ); + InsertFormatMapping(&map, GL_RG, VersionOrExts(3, 0, "GL_ARB_texture_rg"), Always(), VersionOrExts(3, 0, "GL_ARB_texture_rg"), VersionOrExts(3, 0, "GL_EXT_texture_rg"), Always(), VersionOrExts(3, 0, "GL_ARB_texture_rg") ); + InsertFormatMapping(&map, GL_RGB, Always(), Always(), Always(), Always(), Always(), Always() ); + InsertFormatMapping(&map, GL_RGBA, Always(), Always(), Always(), Always(), Always(), Always() ); + InsertFormatMapping(&map, GL_RED_INTEGER, VersionOrExts(3, 0, "GL_ARB_texture_rg"), Never(), VersionOrExts(3, 0, "GL_ARB_texture_rg"), VersionOnly(3, 0), Never(), VersionOnly(3, 0) ); + InsertFormatMapping(&map, GL_RG_INTEGER, VersionOrExts(3, 0, "GL_ARB_texture_rg"), Never(), VersionOrExts(3, 0, "GL_ARB_texture_rg"), VersionOnly(3, 0), Never(), VersionOnly(3, 0) ); + InsertFormatMapping(&map, GL_RGB_INTEGER, VersionOrExts(3, 0, "GL_EXT_texture_integer"), Never(), Never(), VersionOnly(3, 0), Never(), Never() ); + InsertFormatMapping(&map, GL_RGBA_INTEGER, VersionOrExts(3, 0, "GL_EXT_texture_integer"), Never(), VersionOrExts(3, 0, "GL_EXT_texture_integer"), VersionOnly(3, 0), Never(), VersionOnly(3, 0) ); + InsertFormatMapping(&map, GL_SRGB, VersionOrExts(2, 1, "GL_EXT_texture_sRGB"), Always(), VersionOrExts(2, 1, "GL_EXT_texture_sRGB"), ExtsOnly("GL_EXT_sRGB"), Always(), Never() ); + InsertFormatMapping(&map, GL_SRGB_ALPHA, VersionOrExts(2, 1, "GL_EXT_texture_sRGB"), Always(), VersionOrExts(2, 1, "GL_EXT_texture_sRGB"), ExtsOnly("GL_EXT_sRGB"), Always(), Never() ); + + // From GL_EXT_texture_format_BGRA8888 + InsertFormatMapping(&map, GL_BGRA8_EXT, VersionOrExts(1, 2, "GL_EXT_bgra"), Always(), VersionOrExts(1, 2, "GL_EXT_bgra"), ExtsOnly("GL_EXT_texture_format_BGRA8888"), Always(), Never() ); + InsertFormatMapping(&map, GL_BGRA_EXT, VersionOrExts(1, 2, "GL_EXT_bgra"), Always(), VersionOrExts(1, 2, "GL_EXT_bgra"), ExtsOnly("GL_EXT_texture_format_BGRA8888"), Always(), Never() ); // Floating point formats - // | Internal format | Texture support | Render support | Filter support | - InsertFormatMapping(&map, GL_R16F, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport); - InsertFormatMapping(&map, GL_RG16F, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport); - InsertFormatMapping(&map, GL_RGB16F, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport); - InsertFormatMapping(&map, GL_RGBA16F, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport); - InsertFormatMapping(&map, GL_R32F, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport); - InsertFormatMapping(&map, GL_RG32F, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport); - InsertFormatMapping(&map, GL_RGB32F, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport); - InsertFormatMapping(&map, GL_RGBA32F, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport); + // | Format | OpenGL texture support | Filter | OpenGL render support | OpenGL ES texture support | Filter | OpenGL ES render support | + InsertFormatMapping(&map, GL_R11F_G11F_B10F, VersionOrExts(3, 0, "GL_EXT_packed_float"), Always(), VersionOrExts(3, 0, "GL_EXT_packed_float GL_ARB_color_buffer_float"), VersionOnly(3, 0), Always(), ExtsOnly("GL_EXT_color_buffer_float") ); + InsertFormatMapping(&map, GL_RGB9_E5, VersionOrExts(3, 0, "GL_EXT_texture_shared_exponent"), Always(), VersionOrExts(3, 0, "GL_EXT_texture_shared_exponent GL_ARB_color_buffer_float"), VersionOnly(3, 0), Always(), Never() ); + InsertFormatMapping(&map, GL_R16F, VersionOrExts(3, 0, "GL_ARB_texture_rg ARB_texture_float"), Always(), VersionOrExts(3, 0, "GL_ARB_texture_rg GL_ARB_texture_float GL_ARB_color_buffer_float"), VersionOrExts(3, 0, "GL_OES_texture_half_float GL_EXT_texture_rg"), VersionOrExts(3, 0, "GL_OES_texture_half_float_linear"), VersionOrExtsAndExts(3, 0, "GL_EXT_texture_rg", "GL_EXT_color_buffer_half_float")); + InsertFormatMapping(&map, GL_RG16F, VersionOrExts(3, 0, "GL_ARB_texture_rg ARB_texture_float"), Always(), VersionOrExts(3, 0, "GL_ARB_texture_rg GL_ARB_texture_float GL_ARB_color_buffer_float"), VersionOrExts(3, 0, "GL_OES_texture_half_float GL_EXT_texture_rg"), VersionOrExts(3, 0, "GL_OES_texture_half_float_linear"), VersionOrExtsAndExts(3, 0, "GL_EXT_texture_rg", "GL_EXT_color_buffer_half_float")); + InsertFormatMapping(&map, GL_RGB16F, VersionOrExts(3, 0, "GL_ARB_texture_float"), Always(), VersionOrExts(3, 0, "GL_ARB_texture_float GL_ARB_color_buffer_float"), VersionOrExts(3, 0, "GL_OES_texture_half_float"), VersionOrExts(3, 0, "GL_OES_texture_half_float_linear"), ExtsOnly("GL_EXT_color_buffer_half_float") ); + InsertFormatMapping(&map, GL_RGBA16F, VersionOrExts(3, 0, "GL_ARB_texture_float"), Always(), VersionOrExts(3, 0, "GL_ARB_texture_float GL_ARB_color_buffer_float"), VersionOrExts(3, 0, "GL_OES_texture_half_float"), VersionOrExts(3, 0, "GL_OES_texture_half_float_linear"), ExtsOnly("GL_EXT_color_buffer_half_float") ); + InsertFormatMapping(&map, GL_R32F, VersionOrExts(3, 0, "GL_ARB_texture_rg GL_ARB_texture_float"), Always(), VersionOrExts(3, 0, "GL_ARB_texture_rg GL_ARB_texture_float GL_ARB_color_buffer_float"), VersionOrExts(3, 0, "GL_OES_texture_float GL_EXT_texture_rg"), VersionOrExts(3, 0, "GL_OES_texture_float_linear"), ExtsOnly("GL_EXT_color_buffer_float") ); + InsertFormatMapping(&map, GL_RG32F, VersionOrExts(3, 0, "GL_ARB_texture_rg GL_ARB_texture_float"), Always(), VersionOrExts(3, 0, "GL_ARB_texture_rg GL_ARB_texture_float GL_ARB_color_buffer_float"), VersionOrExts(3, 0, "GL_OES_texture_float GL_EXT_texture_rg"), VersionOrExts(3, 0, "GL_OES_texture_float_linear"), ExtsOnly("GL_EXT_color_buffer_float") ); + InsertFormatMapping(&map, GL_RGB32F, VersionOrExts(3, 0, "GL_ARB_texture_float"), Always(), VersionOrExts(3, 0, "GL_ARB_texture_float GL_ARB_color_buffer_float"), VersionOrExts(3, 0, "GL_OES_texture_float"), VersionOrExts(3, 0, "GL_OES_texture_float_linear"), Never() ); + InsertFormatMapping(&map, GL_RGBA32F, VersionOrExts(3, 0, "GL_ARB_texture_float"), Always(), VersionOrExts(3, 0, "GL_ARB_texture_float GL_ARB_color_buffer_float"), VersionOrExts(3, 0, "GL_OES_texture_float"), VersionOrExts(3, 0, "GL_OES_texture_float_linear"), ExtsOnly("GL_EXT_color_buffer_float") ); // Depth stencil formats - // | Internal format | Texture support | Render support | Filter support | - InsertFormatMapping(&map, GL_DEPTH_COMPONENT16, AlwaysSupported, AlwaysSupported, NeverSupported ); - InsertFormatMapping(&map, GL_DEPTH_COMPONENT24, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport); - InsertFormatMapping(&map, GL_DEPTH_COMPONENT32F, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport); - InsertFormatMapping(&map, GL_DEPTH_COMPONENT32_OES, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport); - InsertFormatMapping(&map, GL_DEPTH24_STENCIL8, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport); - InsertFormatMapping(&map, GL_DEPTH32F_STENCIL8, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport); - InsertFormatMapping(&map, GL_STENCIL_INDEX8, AlwaysSupported, AlwaysSupported, NeverSupported ); + // | Format | OpenGL texture support | Filter | OpenGL render support | OpenGL ES texture support | Filter | OpenGL ES render support | + InsertFormatMapping(&map, GL_DEPTH_COMPONENT16, VersionOnly(1, 5), VersionOrExts(1, 5, "GL_ARB_depth_texture"), VersionOnly(1, 5), VersionOnly(2, 0), VersionOrExts(3, 0, "GL_OES_depth_texture"), VersionOnly(2, 0) ); + InsertFormatMapping(&map, GL_DEPTH_COMPONENT24, VersionOnly(1, 5), VersionOrExts(1, 5, "GL_ARB_depth_texture"), VersionOnly(1, 5), VersionOnly(2, 0), VersionOrExts(3, 0, "GL_OES_depth_texture"), VersionOnly(2, 0) ); + InsertFormatMapping(&map, GL_DEPTH_COMPONENT32_OES, VersionOnly(1, 5), VersionOrExts(1, 5, "GL_ARB_depth_texture"), VersionOnly(1, 5), ExtsOnly("GL_OES_depth_texture"), Always(), ExtsOnly("GL_OES_depth32") ); + InsertFormatMapping(&map, GL_DEPTH_COMPONENT32F, VersionOrExts(3, 0, "GL_ARB_depth_buffer_float"), Always(), VersionOrExts(3, 0, "GL_ARB_depth_buffer_float"), VersionOnly(3, 0), VersionOrExts(3, 0, "GL_OES_depth_texture"), VersionOnly(3, 0) ); + InsertFormatMapping(&map, GL_STENCIL_INDEX8, VersionOrExts(3, 0, "GL_EXT_packed_depth_stencil"), Never(), VersionOrExts(3, 0, "GL_EXT_packed_depth_stencil"), VersionOnly(2, 0), Never(), VersionOnly(2, 0) ); + InsertFormatMapping(&map, GL_DEPTH24_STENCIL8, VersionOrExts(3, 0, "GL_ARB_framebuffer_object"), VersionOrExts(3, 0, "GL_ARB_depth_texture"), VersionOrExts(3, 0, "GL_ARB_framebuffer_object"), VersionOrExts(3, 0, "GL_OES_depth_texture"), Always(), VersionOrExts(3, 0, "GL_OES_depth_texture GL_OES_packed_depth_stencil")); + InsertFormatMapping(&map, GL_DEPTH32F_STENCIL8, VersionOrExts(3, 0, "GL_ARB_depth_buffer_float"), Always(), VersionOrExts(3, 0, "GL_ARB_depth_buffer_float"), VersionOnly(3, 0), Always(), VersionOnly(3, 0) ); + InsertFormatMapping(&map, GL_DEPTH_COMPONENT, VersionOnly(1, 5), VersionOrExts(1, 5, "GL_ARB_depth_texture"), VersionOnly(1, 5), VersionOnly(2, 0), VersionOrExts(3, 0, "GL_OES_depth_texture"), VersionOnly(2, 0) ); + InsertFormatMapping(&map, GL_DEPTH_STENCIL, VersionOnly(1, 5), VersionOrExts(1, 5, "GL_ARB_depth_texture"), VersionOnly(1, 5), VersionOnly(2, 0), VersionOrExts(3, 0, "GL_OES_depth_texture"), VersionOnly(2, 0) ); // Luminance alpha formats - // | Internal format | Texture support | Render support | Filter support | - InsertFormatMapping(&map, GL_ALPHA8_EXT, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport); - InsertFormatMapping(&map, GL_LUMINANCE8_EXT, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport); - InsertFormatMapping(&map, GL_ALPHA32F_EXT, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport); - InsertFormatMapping(&map, GL_LUMINANCE32F_EXT, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport); - InsertFormatMapping(&map, GL_ALPHA16F_EXT, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport); - InsertFormatMapping(&map, GL_LUMINANCE16F_EXT, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport); - InsertFormatMapping(&map, GL_LUMINANCE8_ALPHA8_EXT, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport); - InsertFormatMapping(&map, GL_LUMINANCE_ALPHA32F_EXT, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport); - InsertFormatMapping(&map, GL_LUMINANCE_ALPHA16F_EXT, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport); - - // Unsized formats - // | Internal format | Texture support | Render support | Filter support | - InsertFormatMapping(&map, GL_ALPHA, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport); - InsertFormatMapping(&map, GL_LUMINANCE, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport); - InsertFormatMapping(&map, GL_LUMINANCE_ALPHA, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport); - InsertFormatMapping(&map, GL_RED, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport); - InsertFormatMapping(&map, GL_RG, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport); - InsertFormatMapping(&map, GL_RGB, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport); - InsertFormatMapping(&map, GL_RGBA, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport); - InsertFormatMapping(&map, GL_RED_INTEGER, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport); - InsertFormatMapping(&map, GL_RG_INTEGER, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport); - InsertFormatMapping(&map, GL_RGB_INTEGER, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport); - InsertFormatMapping(&map, GL_RGBA_INTEGER, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport); - InsertFormatMapping(&map, GL_BGRA_EXT, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport); - InsertFormatMapping(&map, GL_DEPTH_COMPONENT, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport); - InsertFormatMapping(&map, GL_DEPTH_STENCIL, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport); - InsertFormatMapping(&map, GL_SRGB_EXT, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport); - InsertFormatMapping(&map, GL_SRGB_ALPHA_EXT, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport); + // | Format | OpenGL texture support | Filter | Render | OpenGL ES texture support | Filter | Render | + InsertFormatMapping(&map, GL_ALPHA8_EXT, Always(), Always(), Never(), ExtsOnly("GL_EXT_texture_storage"), Always(), Never()); + InsertFormatMapping(&map, GL_LUMINANCE8_EXT, Always(), Always(), Never(), ExtsOnly("GL_EXT_texture_storage"), Always(), Never()); + InsertFormatMapping(&map, GL_ALPHA32F_EXT, VersionOrExts(3, 0, "GL_ARB_texture_float"), Always(), Never(), ExtsOnly("GL_EXT_texture_storage"), Always(), Never()); + InsertFormatMapping(&map, GL_LUMINANCE32F_EXT, VersionOrExts(3, 0, "GL_ARB_texture_float"), Always(), Never(), ExtsOnly("GL_EXT_texture_storage"), Always(), Never()); + InsertFormatMapping(&map, GL_ALPHA16F_EXT, VersionOrExts(3, 0, "GL_ARB_texture_float"), Always(), Never(), ExtsOnly("GL_EXT_texture_storage"), Always(), Never()); + InsertFormatMapping(&map, GL_LUMINANCE16F_EXT, VersionOrExts(3, 0, "GL_ARB_texture_float"), Always(), Never(), ExtsOnly("GL_EXT_texture_storage"), Always(), Never()); + InsertFormatMapping(&map, GL_LUMINANCE8_ALPHA8_EXT, Always(), Always(), Never(), ExtsOnly("GL_EXT_texture_storage"), Always(), Never()); + InsertFormatMapping(&map, GL_LUMINANCE_ALPHA32F_EXT, VersionOrExts(3, 0, "GL_ARB_texture_float"), Always(), Never(), ExtsOnly("GL_EXT_texture_storage"), Always(), Never()); + InsertFormatMapping(&map, GL_LUMINANCE_ALPHA16F_EXT, VersionOrExts(3, 0, "GL_ARB_texture_float"), Always(), Never(), ExtsOnly("GL_EXT_texture_storage"), Always(), Never()); // Compressed formats, From ES 3.0.1 spec, table 3.16 - // | Internal format | Texture support | Render support | Filter support | - InsertFormatMapping(&map, GL_COMPRESSED_R11_EAC, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport); - InsertFormatMapping(&map, GL_COMPRESSED_SIGNED_R11_EAC, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport); - InsertFormatMapping(&map, GL_COMPRESSED_RG11_EAC, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport); - InsertFormatMapping(&map, GL_COMPRESSED_SIGNED_RG11_EAC, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport); - InsertFormatMapping(&map, GL_COMPRESSED_RGB8_ETC2, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport); - InsertFormatMapping(&map, GL_COMPRESSED_SRGB8_ETC2, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport); - InsertFormatMapping(&map, GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport); - InsertFormatMapping(&map, GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport); - InsertFormatMapping(&map, GL_COMPRESSED_RGBA8_ETC2_EAC, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport); - InsertFormatMapping(&map, GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport); + InsertFormatMapping(&map, GL_COMPRESSED_R11_EAC, VersionOrExts(4, 3, "GL_ARB_ES3_compatibility"), Always(), Never(), VersionOnly(3, 0), Always(), Never()); + InsertFormatMapping(&map, GL_COMPRESSED_SIGNED_R11_EAC, VersionOrExts(4, 3, "GL_ARB_ES3_compatibility"), Always(), Never(), VersionOnly(3, 0), Always(), Never()); + InsertFormatMapping(&map, GL_COMPRESSED_RG11_EAC, VersionOrExts(4, 3, "GL_ARB_ES3_compatibility"), Always(), Never(), VersionOnly(3, 0), Always(), Never()); + InsertFormatMapping(&map, GL_COMPRESSED_SIGNED_RG11_EAC, VersionOrExts(4, 3, "GL_ARB_ES3_compatibility"), Always(), Never(), VersionOnly(3, 0), Always(), Never()); + InsertFormatMapping(&map, GL_COMPRESSED_RGB8_ETC2, VersionOrExts(4, 3, "GL_ARB_ES3_compatibility"), Always(), Never(), VersionOnly(3, 0), Always(), Never()); + InsertFormatMapping(&map, GL_COMPRESSED_SRGB8_ETC2, VersionOrExts(4, 3, "GL_ARB_ES3_compatibility"), Always(), Never(), VersionOnly(3, 0), Always(), Never()); + InsertFormatMapping(&map, GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2, VersionOrExts(4, 3, "GL_ARB_ES3_compatibility"), Always(), Never(), VersionOnly(3, 0), Always(), Never()); + InsertFormatMapping(&map, GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, VersionOrExts(4, 3, "GL_ARB_ES3_compatibility"), Always(), Never(), VersionOnly(3, 0), Always(), Never()); + InsertFormatMapping(&map, GL_COMPRESSED_RGBA8_ETC2_EAC, VersionOrExts(4, 3, "GL_ARB_ES3_compatibility"), Always(), Never(), VersionOnly(3, 0), Always(), Never()); + InsertFormatMapping(&map, GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC, VersionOrExts(4, 3, "GL_ARB_ES3_compatibility"), Always(), Never(), VersionOnly(3, 0), Always(), Never()); // From GL_EXT_texture_compression_dxt1 - // | Internal format | Texture support | Render support | Filter support | - InsertFormatMapping(&map, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport); - InsertFormatMapping(&map, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport); + // | Format | OpenGL texture support | Filter | Render | OpenGL ES texture support | Filter | Render | + InsertFormatMapping(&map, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, ExtsOnly("GL_EXT_texture_compression_s3tc"), Always(), Never(), ExtsOnly("GL_EXT_texture_compression_dxt1"), Always(), Never()); + InsertFormatMapping(&map, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, ExtsOnly("GL_EXT_texture_compression_s3tc"), Always(), Never(), ExtsOnly("GL_EXT_texture_compression_dxt1"), Always(), Never()); // From GL_ANGLE_texture_compression_dxt3 - InsertFormatMapping(&map, GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport); + InsertFormatMapping(&map, GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, ExtsOnly("GL_EXT_texture_compression_s3tc"), Always(), Never(), ExtsOnly("GL_ANGLE_texture_compression_dxt3"), Always(), Never()); // From GL_ANGLE_texture_compression_dxt5 - InsertFormatMapping(&map, GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, UnimplementedSupport, UnimplementedSupport, UnimplementedSupport); + InsertFormatMapping(&map, GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, ExtsOnly("GL_EXT_texture_compression_s3tc"), Always(), Never(), ExtsOnly("GL_ANGLE_texture_compression_dxt5"), Always(), Never()); + + // From GL_ETC1_RGB8_OES + InsertFormatMapping(&map, GL_ETC1_RGB8_OES, VersionOrExts(4, 3, "GL_ARB_ES3_compatibility"), Always(), Never(), VersionOrExts(3, 0, "GL_ETC1_RGB8_OES"), Always(), Never()); + + // clang-format on return map; } @@ -200,21 +261,257 @@ static const InternalFormatInfoMap &GetInternalFormatMap() return formatMap; } -const InternalFormat &GetInternalFormatInfo(GLenum internalFormat) +const InternalFormat &GetInternalFormatInfo(GLenum internalFormat, StandardGL standard) { const InternalFormatInfoMap &formatMap = GetInternalFormatMap(); InternalFormatInfoMap::const_iterator iter = formatMap.find(internalFormat); if (iter != formatMap.end()) { - return iter->second; + const InternalFormatInfo &info = iter->second; + switch (standard) + { + case STANDARD_GL_ES: return info.glesInfo; + case STANDARD_GL_DESKTOP: return info.glInfo; + default: UNREACHABLE(); break; + } + } + + static const InternalFormat defaultInternalFormat; + return defaultInternalFormat; +} + +static GLenum GetNativeInternalFormat(const FunctionsGL *functions, + const WorkaroundsGL &workarounds, + GLenum internalFormat, + GLenum sizedInternalFormat) +{ + GLenum result = internalFormat; + + if (functions->standard == STANDARD_GL_DESKTOP) + { + // Use sized internal formats whenever possible to guarantee the requested precision. + // On Desktop GL, passing an internal format of GL_RGBA will generate a GL_RGBA8 texture + // even if the provided type is GL_FLOAT. + result = sizedInternalFormat; + + const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(sizedInternalFormat); + + if (workarounds.avoid1BitAlphaTextureFormats && formatInfo.alphaBits == 1) + { + // Use an 8-bit format instead + result = GL_RGBA8; + } + + if (workarounds.rgba4IsNotSupportedForColorRendering && sizedInternalFormat == GL_RGBA4) + { + // Use an 8-bit format instead + result = GL_RGBA8; + } + + if (sizedInternalFormat == GL_RGB565 && !functions->isAtLeastGL(gl::Version(4, 1)) && + !functions->hasGLExtension("GL_ARB_ES2_compatibility")) + { + // GL_RGB565 is required for basic ES2 functionality but was not added to desktop GL + // until 4.1. + // Work around this by using an 8-bit format instead. + result = GL_RGB8; + } + + if (sizedInternalFormat == GL_BGRA8_EXT) + { + // GLES accepts GL_BGRA as an internal format but desktop GL only accepts it as a type. + // Update the internal format to GL_RGBA. + result = GL_RGBA8; + } + + if ((functions->profile & GL_CONTEXT_CORE_PROFILE_BIT) != 0) + { + // Work around deprecated luminance alpha formats in the OpenGL core profile by backing + // them with R or RG textures. + if (formatInfo.format == GL_LUMINANCE || formatInfo.format == GL_ALPHA) + { + result = gl::GetSizedInternalFormat(GL_RED, formatInfo.type); + } + + if (formatInfo.format == GL_LUMINANCE_ALPHA) + { + result = gl::GetSizedInternalFormat(GL_RG, formatInfo.type); + } + } + } + + return result; +} + +static GLenum GetNativeFormat(const FunctionsGL *functions, + const WorkaroundsGL &workarounds, + GLenum format) +{ + GLenum result = format; + + if (functions->standard == STANDARD_GL_DESKTOP) + { + // The ES SRGB extensions require that the provided format is GL_SRGB or SRGB_ALPHA but + // the desktop GL extensions only accept GL_RGB or GL_RGBA. Convert them. + if (format == GL_SRGB) + { + result = GL_RGB; + } + + if (format == GL_SRGB_ALPHA) + { + result = GL_RGBA; + } + + if ((functions->profile & GL_CONTEXT_CORE_PROFILE_BIT) != 0) + { + // Work around deprecated luminance alpha formats in the OpenGL core profile by backing + // them with R or RG textures. + if (format == GL_LUMINANCE || format == GL_ALPHA) + { + result = GL_RED; + } + + if (format == GL_LUMINANCE_ALPHA) + { + result = GL_RG; + } + } } - else + + return result; +} + +static GLenum GetNativeCompressedFormat(const FunctionsGL *functions, + const WorkaroundsGL &workarounds, + GLenum format) +{ + GLenum result = format; + + if (functions->standard == STANDARD_GL_DESKTOP) + { + if (format == GL_ETC1_RGB8_OES) + { + // GL_ETC1_RGB8_OES is not available in any desktop GL extension but the compression + // format is forwards compatible so just use the ETC2 format. + result = GL_COMPRESSED_RGB8_ETC2; + } + } + + if (functions->isAtLeastGLES(gl::Version(3, 0))) + { + if (format == GL_ETC1_RGB8_OES) + { + // Pass GL_COMPRESSED_RGB8_ETC2 as the target format in ES3 and higher because it + // becomes a core format. + result = GL_COMPRESSED_RGB8_ETC2; + } + } + + return result; +} + +static GLenum GetNativeType(const FunctionsGL *functions, + const WorkaroundsGL &workarounds, + GLenum type) +{ + GLenum result = type; + + if (functions->standard == STANDARD_GL_DESKTOP) + { + if (type == GL_HALF_FLOAT_OES) + { + // The enums differ for the OES half float extensions and desktop GL spec. Update it. + result = GL_HALF_FLOAT; + } + } + + if (functions->isAtLeastGLES(gl::Version(3, 0))) { - static const InternalFormat defaultInternalFormat; - return defaultInternalFormat; + if (type == GL_HALF_FLOAT_OES) + { + // The enums differ for the OES half float extensions and ES 3 spec. Update it. + result = GL_HALF_FLOAT; + } } + + return result; +} + +TexImageFormat GetTexImageFormat(const FunctionsGL *functions, + const WorkaroundsGL &workarounds, + GLenum internalFormat, + GLenum format, + GLenum type) +{ + TexImageFormat result; + result.internalFormat = GetNativeInternalFormat( + functions, workarounds, internalFormat, gl::GetSizedInternalFormat(internalFormat, type)); + result.format = GetNativeFormat(functions, workarounds, format); + result.type = GetNativeType(functions, workarounds, type); + return result; } +TexSubImageFormat GetTexSubImageFormat(const FunctionsGL *functions, + const WorkaroundsGL &workarounds, + GLenum format, + GLenum type) +{ + TexSubImageFormat result; + result.format = GetNativeFormat(functions, workarounds, format); + result.type = GetNativeType(functions, workarounds, type); + return result; +} + +CompressedTexImageFormat GetCompressedTexImageFormat(const FunctionsGL *functions, + const WorkaroundsGL &workarounds, + GLenum internalFormat) +{ + CompressedTexImageFormat result; + result.internalFormat = GetNativeCompressedFormat(functions, workarounds, internalFormat); + return result; +} + +CompressedTexSubImageFormat GetCompressedSubTexImageFormat(const FunctionsGL *functions, + const WorkaroundsGL &workarounds, + GLenum format) +{ + CompressedTexSubImageFormat result; + result.format = GetNativeCompressedFormat(functions, workarounds, format); + return result; +} + +CopyTexImageImageFormat GetCopyTexImageImageFormat(const FunctionsGL *functions, + const WorkaroundsGL &workarounds, + GLenum internalFormat, + GLenum framebufferType) +{ + CopyTexImageImageFormat result; + result.internalFormat = + GetNativeInternalFormat(functions, workarounds, internalFormat, + gl::GetSizedInternalFormat(internalFormat, framebufferType)); + return result; +} + +TexStorageFormat GetTexStorageFormat(const FunctionsGL *functions, + const WorkaroundsGL &workarounds, + GLenum internalFormat) +{ + TexStorageFormat result; + result.internalFormat = + GetNativeInternalFormat(functions, workarounds, internalFormat, internalFormat); + return result; +} + +RenderbufferFormat GetRenderbufferFormat(const FunctionsGL *functions, + const WorkaroundsGL &workarounds, + GLenum internalFormat) +{ + RenderbufferFormat result; + result.internalFormat = + GetNativeInternalFormat(functions, workarounds, internalFormat, internalFormat); + return result; +} } } diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/formatutilsgl.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/formatutilsgl.h index 8e45673892e9..547d4783e7d5 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/formatutilsgl.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/formatutilsgl.h @@ -10,10 +10,14 @@ #ifndef LIBANGLE_RENDERER_GL_FORMATUTILSGL_H_ #define LIBANGLE_RENDERER_GL_FORMATUTILSGL_H_ +#include #include #include #include "angle_gl.h" +#include "libANGLE/Version.h" +#include "libANGLE/renderer/gl/FunctionsGL.h" +#include "libANGLE/renderer/gl/WorkaroundsGL.h" namespace rx { @@ -21,18 +25,93 @@ namespace rx namespace nativegl { +struct SupportRequirement +{ + SupportRequirement(); + + // Version that this format became supported without extensions + gl::Version version; + + // Extensions that are required if the minimum version is not met + std::vector versionExtensions; + + // Extensions that are always required to support this format + std::vector requiredExtensions; +}; + struct InternalFormat { InternalFormat(); - typedef bool(*SupportCheckFunction)(GLuint majorVersion, GLuint minorVersion, - const std::vector &extensions); - SupportCheckFunction textureSupport; - SupportCheckFunction renderSupport; - SupportCheckFunction filterSupport; + SupportRequirement texture; + SupportRequirement filter; + SupportRequirement renderbuffer; + SupportRequirement framebufferAttachment; +}; +const InternalFormat &GetInternalFormatInfo(GLenum internalFormat, StandardGL standard); + +struct TexImageFormat +{ + GLenum internalFormat; + GLenum format; + GLenum type; +}; +TexImageFormat GetTexImageFormat(const FunctionsGL *functions, + const WorkaroundsGL &workarounds, + GLenum internalFormat, + GLenum format, + GLenum type); + +struct TexSubImageFormat +{ + GLenum format; + GLenum type; +}; +TexSubImageFormat GetTexSubImageFormat(const FunctionsGL *functions, + const WorkaroundsGL &workarounds, + GLenum format, + GLenum type); + +struct CompressedTexImageFormat +{ + GLenum internalFormat; }; -const InternalFormat &GetInternalFormatInfo(GLenum internalFormat); +CompressedTexImageFormat GetCompressedTexImageFormat(const FunctionsGL *functions, + const WorkaroundsGL &workarounds, + GLenum internalFormat); +struct CompressedTexSubImageFormat +{ + GLenum format; +}; +CompressedTexSubImageFormat GetCompressedSubTexImageFormat(const FunctionsGL *functions, + const WorkaroundsGL &workarounds, + GLenum format); + +struct CopyTexImageImageFormat +{ + GLenum internalFormat; +}; +CopyTexImageImageFormat GetCopyTexImageImageFormat(const FunctionsGL *functions, + const WorkaroundsGL &workarounds, + GLenum internalFormat, + GLenum framebufferType); + +struct TexStorageFormat +{ + GLenum internalFormat; +}; +TexStorageFormat GetTexStorageFormat(const FunctionsGL *functions, + const WorkaroundsGL &workarounds, + GLenum internalFormat); + +struct RenderbufferFormat +{ + GLenum internalFormat; +}; +RenderbufferFormat GetRenderbufferFormat(const FunctionsGL *functions, + const WorkaroundsGL &workarounds, + GLenum internalFormat); } } diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/functionsgl_enums.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/functionsgl_enums.h index 42e5f38a1d3b..918a7a1e65ce 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/functionsgl_enums.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/functionsgl_enums.h @@ -429,6 +429,7 @@ #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 @@ -523,7 +524,7 @@ #define GL_DEPTH_STENCIL 0x84F9 #define GL_DEPTH_STENCIL_ATTACHMENT 0x821A #define GL_DRAW_FRAMEBUFFER 0x8CA9 -#define GL_DRAW_FRAMEBUFFER_BINDING GL_FRAMEBUFFER_BINDING +#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 @@ -974,8 +975,8 @@ #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 GL_COPY_READ_BUFFER -#define GL_COPY_WRITE_BUFFER_BINDING GL_COPY_WRITE_BUFFER +#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 diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/functionsgl_typedefs.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/functionsgl_typedefs.h index 82fb5d84ce51..50888e61e010 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/functionsgl_typedefs.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/functionsgl_typedefs.h @@ -595,6 +595,7 @@ typedef void (INTERNAL_GL_APIENTRY *PFNGLFRAMEBUFFERPARAMETERIPROC)(GLenum, GLen typedef GLuint (INTERNAL_GL_APIENTRY *PFNGLGETDEBUGMESSAGELOGPROC)(GLuint, GLsizei, GLenum *, GLenum *, GLuint *, GLenum *, GLsizei *, GLchar *); typedef void (INTERNAL_GL_APIENTRY *PFNGLGETFRAMEBUFFERPARAMETERIVPROC)(GLenum, GLenum, GLint *); typedef void (INTERNAL_GL_APIENTRY *PFNGLGETINTERNALFORMATI64VPROC)(GLenum, GLenum, GLenum, GLsizei, GLint64 *); +typedef void (INTERNAL_GL_APIENTRY *PFNGLGETPOINTERVPROC)(GLenum, void **); typedef void (INTERNAL_GL_APIENTRY *PFNGLGETOBJECTLABELPROC)(GLenum, GLuint, GLsizei, GLsizei *, GLchar *); typedef void (INTERNAL_GL_APIENTRY *PFNGLGETOBJECTPTRLABELPROC)(const void *, GLsizei, GLsizei *, GLchar *); typedef void (INTERNAL_GL_APIENTRY *PFNGLGETPROGRAMINTERFACEIVPROC)(GLuint, GLenum, GLenum, GLint *); diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/glx/DisplayGLX.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/glx/DisplayGLX.cpp new file mode 100644 index 000000000000..41ca358a8ff7 --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/glx/DisplayGLX.cpp @@ -0,0 +1,909 @@ +// +// Copyright (c) 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. +// + +// DisplayGLX.cpp: GLX implementation of egl::Display + +#include "libANGLE/renderer/gl/glx/DisplayGLX.h" + +#include +#include + +#include "common/debug.h" +#include "libANGLE/Config.h" +#include "libANGLE/Display.h" +#include "libANGLE/Surface.h" +#include "libANGLE/renderer/gl/glx/PbufferSurfaceGLX.h" +#include "libANGLE/renderer/gl/glx/WindowSurfaceGLX.h" +#include "libANGLE/renderer/gl/renderergl_utils.h" +#include "third_party/libXNVCtrl/NVCtrl.h" +#include "third_party/libXNVCtrl/NVCtrlLib.h" + +namespace rx +{ + +static int IgnoreX11Errors(Display *, XErrorEvent *) +{ + return 0; +} + +SwapControlData::SwapControlData() + : targetSwapInterval(0), + maxSwapInterval(-1), + currentSwapInterval(-1) +{ +} + +class FunctionsGLGLX : public FunctionsGL +{ + public: + FunctionsGLGLX(PFNGETPROCPROC getProc) + : mGetProc(getProc) + { + } + + ~FunctionsGLGLX() override {} + + private: + void *loadProcAddress(const std::string &function) override + { + return reinterpret_cast(mGetProc(function.c_str())); + } + + PFNGETPROCPROC mGetProc; +}; + +DisplayGLX::DisplayGLX() + : DisplayGL(), + mFunctionsGL(nullptr), + mRequestedVisual(-1), + mContextConfig(nullptr), + mContext(nullptr), + mDummyPbuffer(0), + mUsesNewXDisplay(false), + mIsMesa(false), + mHasMultisample(false), + mHasARBCreateContext(false), + mHasARBCreateContextProfile(false), + mHasEXTCreateContextES2Profile(false), + mSwapControl(SwapControl::Absent), + mMinSwapInterval(0), + mMaxSwapInterval(0), + mCurrentSwapInterval(-1), + mXDisplay(nullptr), + mEGLDisplay(nullptr) +{ +} + +DisplayGLX::~DisplayGLX() +{ +} + +egl::Error DisplayGLX::initialize(egl::Display *display) +{ + mEGLDisplay = display; + mXDisplay = display->getNativeDisplayId(); + const auto &attribMap = display->getAttributeMap(); + + // ANGLE_platform_angle allows the creation of a default display + // using EGL_DEFAULT_DISPLAY (= nullptr). In this case just open + // the display specified by the DISPLAY environment variable. + if (mXDisplay == EGL_DEFAULT_DISPLAY) + { + mUsesNewXDisplay = true; + mXDisplay = XOpenDisplay(NULL); + if (!mXDisplay) + { + return egl::Error(EGL_NOT_INITIALIZED, "Could not open the default X display."); + } + } + + std::string glxInitError; + if (!mGLX.initialize(mXDisplay, DefaultScreen(mXDisplay), &glxInitError)) + { + return egl::Error(EGL_NOT_INITIALIZED, glxInitError.c_str()); + } + + mHasMultisample = mGLX.minorVersion > 3 || mGLX.hasExtension("GLX_ARB_multisample"); + mHasARBCreateContext = mGLX.hasExtension("GLX_ARB_create_context"); + mHasARBCreateContextProfile = mGLX.hasExtension("GLX_ARB_create_context_profile"); + mHasEXTCreateContextES2Profile = mGLX.hasExtension("GLX_EXT_create_context_es2_profile"); + + // Choose the swap_control extension to use, if any. + // The EXT version is better as it allows glXSwapInterval to be called per + // window, while we'll potentially need to change the swap interval on each + // swap buffers when using the SGI or MESA versions. + if (mGLX.hasExtension("GLX_EXT_swap_control")) + { + mSwapControl = SwapControl::EXT; + + // In GLX_EXT_swap_control querying these is done on a GLXWindow so we just + // set default values. + mMinSwapInterval = 0; + mMaxSwapInterval = 4; + } + else if (mGLX.hasExtension("GLX_MESA_swap_control")) + { + // If we have the Mesa or SGI extension, assume that you can at least set + // a swap interval of 0 or 1. + mSwapControl = SwapControl::Mesa; + mMinSwapInterval = 0; + mMinSwapInterval = 1; + } + else if (mGLX.hasExtension("GLX_SGI_swap_control")) + { + mSwapControl = SwapControl::SGI; + mMinSwapInterval = 0; + mMinSwapInterval = 1; + } + else + { + mSwapControl = SwapControl::Absent; + mMinSwapInterval = 1; + mMinSwapInterval = 1; + } + + if (attribMap.contains(EGL_X11_VISUAL_ID_ANGLE)) + { + mRequestedVisual = static_cast(attribMap.get(EGL_X11_VISUAL_ID_ANGLE, -1)); + + // There is no direct way to get the GLXFBConfig matching an X11 visual ID + // so we have to iterate over all the GLXFBConfigs to find the right one. + int nConfigs; + int attribList[] = { + None, + }; + glx::FBConfig *allConfigs = mGLX.chooseFBConfig(attribList, &nConfigs); + + for (int i = 0; i < nConfigs; ++i) + { + if (getGLXFBConfigAttrib(allConfigs[i], GLX_VISUAL_ID) == mRequestedVisual) + { + mContextConfig = allConfigs[i]; + break; + } + } + XFree(allConfigs); + + if (mContextConfig == nullptr) + { + return egl::Error(EGL_NOT_INITIALIZED, "Invalid visual ID requested."); + } + } + else + { + // When glXMakeCurrent is called, the context and the surface must be + // compatible which in glX-speak means that their config have the same + // color buffer type, are both RGBA or ColorIndex, and their buffers have + // the same depth, if they exist. + // Since our whole EGL implementation is backed by only one GL context, this + // context must be compatible with all the GLXFBConfig corresponding to the + // EGLconfigs that we will be exposing. + int nConfigs; + int attribList[] = + { + // We want RGBA8 and DEPTH24_STENCIL8 + GLX_RED_SIZE, 8, + GLX_GREEN_SIZE, 8, + GLX_BLUE_SIZE, 8, + GLX_ALPHA_SIZE, 8, + GLX_DEPTH_SIZE, 24, + GLX_STENCIL_SIZE, 8, + // We want RGBA rendering (vs COLOR_INDEX) and doublebuffer + GLX_RENDER_TYPE, GLX_RGBA_BIT, + // Double buffer is not strictly required as a non-doublebuffer + // context can work with a doublebuffered surface, but it still + // flickers and all applications want doublebuffer anyway. + GLX_DOUBLEBUFFER, True, + // All of these must be supported for full EGL support + GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT | GLX_PBUFFER_BIT | GLX_PIXMAP_BIT, + // This makes sure the config have an associated visual Id + GLX_X_RENDERABLE, True, + GLX_CONFIG_CAVEAT, GLX_NONE, + None + }; + glx::FBConfig *candidates = mGLX.chooseFBConfig(attribList, &nConfigs); + if (nConfigs == 0) + { + XFree(candidates); + return egl::Error(EGL_NOT_INITIALIZED, "Could not find a decent GLX FBConfig to create the context."); + } + mContextConfig = candidates[0]; + XFree(candidates); + } + + const auto &eglAttributes = display->getAttributeMap(); + if (mHasARBCreateContext) + { + egl::Error error = initializeContext(mContextConfig, eglAttributes, &mContext); + if (error.isError()) + { + return error; + } + } + else + { + if (eglAttributes.get(EGL_PLATFORM_ANGLE_TYPE_ANGLE, + EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE) == + EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE) + { + return egl::Error(EGL_NOT_INITIALIZED, + "Cannot create an OpenGL ES platform on GLX without the " + "GLX_ARB_create_context extension."); + } + + XVisualInfo visualTemplate; + visualTemplate.visualid = getGLXFBConfigAttrib(mContextConfig, GLX_VISUAL_ID); + + int numVisuals = 0; + XVisualInfo *visuals = + XGetVisualInfo(mXDisplay, VisualIDMask, &visualTemplate, &numVisuals); + if (numVisuals <= 0) + { + return egl::Error(EGL_NOT_INITIALIZED, + "Could not get the visual info from the fb config"); + } + ASSERT(numVisuals == 1); + + mContext = mGLX.createContext(&visuals[0], nullptr, true); + XFree(visuals); + + if (!mContext) + { + return egl::Error(EGL_NOT_INITIALIZED, "Could not create GL context."); + } + } + ASSERT(mContext); + + // FunctionsGL and DisplayGL need to make a few GL calls, for example to + // query the version of the context so we need to make the context current. + // glXMakeCurrent requires a GLXDrawable so we create a temporary Pbuffer + // (of size 1, 1) for the duration of these calls. + // Ideally we would want to unset the current context and destroy the pbuffer + // before going back to the application but this is TODO + // We could use a pbuffer of size (0, 0) but it fails on the Intel Mesa driver + // as commented on https://bugs.freedesktop.org/show_bug.cgi?id=38869 so we + // use (1, 1) instead. + + int dummyPbufferAttribs[] = + { + GLX_PBUFFER_WIDTH, 1, + GLX_PBUFFER_HEIGHT, 1, + None, + }; + mDummyPbuffer = mGLX.createPbuffer(mContextConfig, dummyPbufferAttribs); + if (!mDummyPbuffer) + { + return egl::Error(EGL_NOT_INITIALIZED, "Could not create the dummy pbuffer."); + } + + if (!mGLX.makeCurrent(mDummyPbuffer, mContext)) + { + return egl::Error(EGL_NOT_INITIALIZED, "Could not make the dummy pbuffer current."); + } + + mFunctionsGL = new FunctionsGLGLX(mGLX.getProc); + mFunctionsGL->initialize(); + + // TODO(cwallez, angleproject:1303) Disable the OpenGL ES backend on Linux NVIDIA and Intel as + // it has problems on our automated testing. An OpenGL ES backend might not trigger this test if + // there is no Desktop OpenGL support, but that's not the case in our automated testing. + VendorID vendor = GetVendorID(mFunctionsGL); + bool isOpenGLES = + eglAttributes.get(EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE) == + EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE; + if (isOpenGLES && (vendor == VENDOR_ID_INTEL || vendor == VENDOR_ID_NVIDIA)) + { + return egl::Error(EGL_NOT_INITIALIZED, "Intel or NVIDIA OpenGL ES drivers are not supported."); + } + + syncXCommands(); + + std::string rendererString = + reinterpret_cast(mFunctionsGL->getString(GL_RENDERER)); + mIsMesa = rendererString.find("Mesa") != std::string::npos; + + std::string version; + getDriverVersion(&version); + + return DisplayGL::initialize(display); +} + +void DisplayGLX::terminate() +{ + DisplayGL::terminate(); + + if (mDummyPbuffer) + { + mGLX.destroyPbuffer(mDummyPbuffer); + mDummyPbuffer = 0; + } + + if (mContext) + { + mGLX.destroyContext(mContext); + mContext = nullptr; + } + + mGLX.terminate(); + + SafeDelete(mFunctionsGL); +} + +SurfaceImpl *DisplayGLX::createWindowSurface(const egl::Config *configuration, + EGLNativeWindowType window, + const egl::AttributeMap &attribs) +{ + ASSERT(configIdToGLXConfig.count(configuration->configID) > 0); + glx::FBConfig fbConfig = configIdToGLXConfig[configuration->configID]; + + return new WindowSurfaceGLX(mGLX, this, this->getRenderer(), window, mGLX.getDisplay(), + mContext, fbConfig); +} + +SurfaceImpl *DisplayGLX::createPbufferSurface(const egl::Config *configuration, + const egl::AttributeMap &attribs) +{ + ASSERT(configIdToGLXConfig.count(configuration->configID) > 0); + glx::FBConfig fbConfig = configIdToGLXConfig[configuration->configID]; + + EGLint width = static_cast(attribs.get(EGL_WIDTH, 0)); + EGLint height = static_cast(attribs.get(EGL_HEIGHT, 0)); + bool largest = (attribs.get(EGL_LARGEST_PBUFFER, EGL_FALSE) == EGL_TRUE); + + return new PbufferSurfaceGLX(this->getRenderer(), width, height, largest, mGLX, mContext, + fbConfig); +} + +SurfaceImpl* DisplayGLX::createPbufferFromClientBuffer(const egl::Config *configuration, + EGLClientBuffer shareHandle, + const egl::AttributeMap &attribs) +{ + UNIMPLEMENTED(); + return nullptr; +} + +SurfaceImpl *DisplayGLX::createPixmapSurface(const egl::Config *configuration, + NativePixmapType nativePixmap, + const egl::AttributeMap &attribs) +{ + UNIMPLEMENTED(); + return nullptr; +} + +egl::Error DisplayGLX::getDevice(DeviceImpl **device) +{ + UNIMPLEMENTED(); + return egl::Error(EGL_BAD_DISPLAY); +} + +egl::Error DisplayGLX::initializeContext(glx::FBConfig config, + const egl::AttributeMap &eglAttributes, + glx::Context *context) +{ + int profileMask = 0; + + EGLint requestedDisplayType = static_cast( + eglAttributes.get(EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE)); + if (requestedDisplayType == EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE) + { + if (!mHasEXTCreateContextES2Profile) + { + return egl::Error(EGL_NOT_INITIALIZED, + "Cannot create an OpenGL ES platform on GLX without the " + "GLX_EXT_create_context_es_profile extension."); + } + + ASSERT(mHasARBCreateContextProfile); + profileMask |= GLX_CONTEXT_ES2_PROFILE_BIT_EXT; + } + + // Create a context of the requested version, if any. + gl::Version requestedVersion(static_cast(eglAttributes.get( + EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE, EGL_DONT_CARE)), + static_cast(eglAttributes.get( + EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE, EGL_DONT_CARE))); + if (static_cast(requestedVersion.major) != EGL_DONT_CARE && + static_cast(requestedVersion.minor) != EGL_DONT_CARE) + { + if (!(profileMask & GLX_CONTEXT_ES2_PROFILE_BIT_EXT) && + requestedVersion >= gl::Version(3, 2)) + { + profileMask |= GLX_CONTEXT_CORE_PROFILE_BIT_ARB; + } + return createContextAttribs(config, requestedVersion, profileMask, context); + } + + // It is commonly assumed that glXCreateContextAttrib will create a context + // of the highest version possible but it is not specified in the spec and + // is not true on the Mesa drivers. Instead we try to create a context per + // GL version until we succeed, starting from newer version. When the default + // platform is selected, if no desktop context can be created, we fallback to + // an ES context. + // clang-format off + const gl::Version desktopVersionsFrom3_2[] = { + gl::Version(4, 5), + gl::Version(4, 4), + gl::Version(4, 3), + gl::Version(4, 2), + gl::Version(4, 1), + gl::Version(4, 0), + gl::Version(3, 3), + gl::Version(3, 2), + }; + const gl::Version desktopVersionsPre3_2[] = { + gl::Version(3, 1), + gl::Version(3, 0), + gl::Version(2, 0), + gl::Version(1, 5), + gl::Version(1, 4), + gl::Version(1, 3), + gl::Version(1, 2), + gl::Version(1, 1), + gl::Version(1, 0), + }; + const gl::Version esVersionsFrom2_0[] = { + gl::Version(3, 2), + gl::Version(3, 1), + gl::Version(3, 0), + gl::Version(2, 0), + }; + // clang-format on + + // NOTE: below we return as soon as we're able to create a context so the + // "error" variable is EGL_SUCCESS when returned contrary to the common idiom + // of returning "error" when there is an actual error. + if (requestedDisplayType != EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE) + { + for (auto &version : desktopVersionsFrom3_2) + { + egl::Error error = + createContextAttribs(config, version, GLX_CONTEXT_CORE_PROFILE_BIT_ARB, context); + if (!error.isError()) + { + return error; + } + } + for (auto &version : desktopVersionsPre3_2) + { + egl::Error error = createContextAttribs(config, version, 0, context); + if (!error.isError()) + { + return error; + } + } + } + + if (requestedDisplayType != EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE) + { + for (auto &version : esVersionsFrom2_0) + { + egl::Error error = + createContextAttribs(config, version, GLX_CONTEXT_ES2_PROFILE_BIT_EXT, context); + if (!error.isError()) + { + return error; + } + } + } + + return egl::Error(EGL_NOT_INITIALIZED, "Could not create a backing OpenGL context."); +} + +egl::ConfigSet DisplayGLX::generateConfigs() const +{ + egl::ConfigSet configs; + configIdToGLXConfig.clear(); + + const gl::Version &maxVersion = getMaxSupportedESVersion(); + ASSERT(maxVersion >= gl::Version(2, 0)); + bool supportsES3 = maxVersion >= gl::Version(3, 0); + + int contextRedSize = getGLXFBConfigAttrib(mContextConfig, GLX_RED_SIZE); + int contextGreenSize = getGLXFBConfigAttrib(mContextConfig, GLX_GREEN_SIZE); + int contextBlueSize = getGLXFBConfigAttrib(mContextConfig, GLX_BLUE_SIZE); + int contextAlphaSize = getGLXFBConfigAttrib(mContextConfig, GLX_ALPHA_SIZE); + + int contextDepthSize = getGLXFBConfigAttrib(mContextConfig, GLX_DEPTH_SIZE); + int contextStencilSize = getGLXFBConfigAttrib(mContextConfig, GLX_STENCIL_SIZE); + + int contextSamples = mHasMultisample ? getGLXFBConfigAttrib(mContextConfig, GLX_SAMPLES) : 0; + int contextSampleBuffers = + mHasMultisample ? getGLXFBConfigAttrib(mContextConfig, GLX_SAMPLE_BUFFERS) : 0; + + int contextAccumRedSize = getGLXFBConfigAttrib(mContextConfig, GLX_ACCUM_RED_SIZE); + int contextAccumGreenSize = getGLXFBConfigAttrib(mContextConfig, GLX_ACCUM_GREEN_SIZE); + int contextAccumBlueSize = getGLXFBConfigAttrib(mContextConfig, GLX_ACCUM_BLUE_SIZE); + int contextAccumAlphaSize = getGLXFBConfigAttrib(mContextConfig, GLX_ACCUM_ALPHA_SIZE); + + int attribList[] = + { + GLX_RENDER_TYPE, GLX_RGBA_BIT, + GLX_X_RENDERABLE, True, + GLX_DOUBLEBUFFER, True, + None, + }; + + int glxConfigCount; + glx::FBConfig *glxConfigs = mGLX.chooseFBConfig(attribList, &glxConfigCount); + + for (int i = 0; i < glxConfigCount; i++) + { + glx::FBConfig glxConfig = glxConfigs[i]; + egl::Config config; + + // Native stuff + config.nativeVisualID = getGLXFBConfigAttrib(glxConfig, GLX_VISUAL_ID); + config.nativeVisualType = getGLXFBConfigAttrib(glxConfig, GLX_X_VISUAL_TYPE); + config.nativeRenderable = EGL_TRUE; + + // When a visual ID has been specified with EGL_ANGLE_x11_visual we should + // only return configs with this visual: it will maximize performance by avoid + // blits in the driver when showing the window on the screen. + if (mRequestedVisual != -1 && config.nativeVisualID != mRequestedVisual) + { + continue; + } + + // Buffer sizes + config.redSize = getGLXFBConfigAttrib(glxConfig, GLX_RED_SIZE); + config.greenSize = getGLXFBConfigAttrib(glxConfig, GLX_GREEN_SIZE); + config.blueSize = getGLXFBConfigAttrib(glxConfig, GLX_BLUE_SIZE); + config.alphaSize = getGLXFBConfigAttrib(glxConfig, GLX_ALPHA_SIZE); + config.depthSize = getGLXFBConfigAttrib(glxConfig, GLX_DEPTH_SIZE); + config.stencilSize = getGLXFBConfigAttrib(glxConfig, GLX_STENCIL_SIZE); + + // We require RGBA8 and the D24S8 (or no DS buffer) + if (config.redSize != contextRedSize || config.greenSize != contextGreenSize || + config.blueSize != contextBlueSize || config.alphaSize != contextAlphaSize) + { + continue; + } + // The GLX spec says that it is ok for a whole buffer to not be present + // however the Mesa Intel driver (and probably on other Mesa drivers) + // fails to make current when the Depth stencil doesn't exactly match the + // configuration. + bool hasSameDepthStencil = + config.depthSize == contextDepthSize && config.stencilSize == contextStencilSize; + bool hasNoDepthStencil = config.depthSize == 0 && config.stencilSize == 0; + if (!hasSameDepthStencil && (mIsMesa || !hasNoDepthStencil)) + { + continue; + } + + config.colorBufferType = EGL_RGB_BUFFER; + config.luminanceSize = 0; + config.alphaMaskSize = 0; + + config.bufferSize = config.redSize + config.greenSize + config.blueSize + config.alphaSize; + + // Multisample and accumulation buffers + int samples = mHasMultisample ? getGLXFBConfigAttrib(glxConfig, GLX_SAMPLES) : 0; + int sampleBuffers = + mHasMultisample ? getGLXFBConfigAttrib(glxConfig, GLX_SAMPLE_BUFFERS) : 0; + + int accumRedSize = getGLXFBConfigAttrib(glxConfig, GLX_ACCUM_RED_SIZE); + int accumGreenSize = getGLXFBConfigAttrib(glxConfig, GLX_ACCUM_GREEN_SIZE); + int accumBlueSize = getGLXFBConfigAttrib(glxConfig, GLX_ACCUM_BLUE_SIZE); + int accumAlphaSize = getGLXFBConfigAttrib(glxConfig, GLX_ACCUM_ALPHA_SIZE); + + if (samples != contextSamples || + sampleBuffers != contextSampleBuffers || + accumRedSize != contextAccumRedSize || + accumGreenSize != contextAccumGreenSize || + accumBlueSize != contextAccumBlueSize || + accumAlphaSize != contextAccumAlphaSize) + { + continue; + } + + config.samples = samples; + config.sampleBuffers = sampleBuffers; + + // Transparency + if (getGLXFBConfigAttrib(glxConfig, GLX_TRANSPARENT_TYPE) == GLX_TRANSPARENT_RGB) + { + config.transparentType = EGL_TRANSPARENT_RGB; + config.transparentRedValue = getGLXFBConfigAttrib(glxConfig, GLX_TRANSPARENT_RED_VALUE); + config.transparentGreenValue = getGLXFBConfigAttrib(glxConfig, GLX_TRANSPARENT_GREEN_VALUE); + config.transparentBlueValue = getGLXFBConfigAttrib(glxConfig, GLX_TRANSPARENT_BLUE_VALUE); + } + else + { + config.transparentType = EGL_NONE; + } + + // Pbuffer + config.maxPBufferWidth = getGLXFBConfigAttrib(glxConfig, GLX_MAX_PBUFFER_WIDTH); + config.maxPBufferHeight = getGLXFBConfigAttrib(glxConfig, GLX_MAX_PBUFFER_HEIGHT); + config.maxPBufferPixels = getGLXFBConfigAttrib(glxConfig, GLX_MAX_PBUFFER_PIXELS); + + // Caveat + config.configCaveat = EGL_NONE; + + int caveat = getGLXFBConfigAttrib(glxConfig, GLX_CONFIG_CAVEAT); + if (caveat == GLX_SLOW_CONFIG) + { + config.configCaveat = EGL_SLOW_CONFIG; + } + else if (caveat == GLX_NON_CONFORMANT_CONFIG) + { + continue; + } + + // Misc + config.level = getGLXFBConfigAttrib(glxConfig, GLX_LEVEL); + + config.bindToTextureRGB = EGL_FALSE; + config.bindToTextureRGBA = EGL_FALSE; + + int glxDrawable = getGLXFBConfigAttrib(glxConfig, GLX_DRAWABLE_TYPE); + config.surfaceType = 0 | + (glxDrawable & GLX_WINDOW_BIT ? EGL_WINDOW_BIT : 0) | + (glxDrawable & GLX_PBUFFER_BIT ? EGL_PBUFFER_BIT : 0) | + (glxDrawable & GLX_PIXMAP_BIT ? EGL_PIXMAP_BIT : 0); + + config.minSwapInterval = mMinSwapInterval; + config.maxSwapInterval = mMaxSwapInterval; + + // TODO(cwallez) wildly guessing these formats, another TODO says they should be removed anyway + config.renderTargetFormat = GL_RGBA8; + config.depthStencilFormat = GL_DEPTH24_STENCIL8; + + config.conformant = EGL_OPENGL_ES2_BIT | (supportsES3 ? EGL_OPENGL_ES3_BIT_KHR : 0); + config.renderableType = config.conformant; + + // TODO(cwallez) I have no idea what this is + config.matchNativePixmap = EGL_NONE; + + int id = configs.add(config); + configIdToGLXConfig[id] = glxConfig; + } + + XFree(glxConfigs); + + return configs; +} + +bool DisplayGLX::isDeviceLost() const +{ + // UNIMPLEMENTED(); + return false; +} + +bool DisplayGLX::testDeviceLost() +{ + // UNIMPLEMENTED(); + return false; +} + +egl::Error DisplayGLX::restoreLostDevice() +{ + UNIMPLEMENTED(); + return egl::Error(EGL_BAD_DISPLAY); +} + +bool DisplayGLX::isValidNativeWindow(EGLNativeWindowType window) const +{ + // There is no function in Xlib to check the validity of a Window directly. + // However a small number of functions used to obtain window information + // return a status code (0 meaning failure) and guarantee that they will + // fail if the window doesn't exist (the rational is that these function + // are used by window managers). Out of these function we use XQueryTree + // as it seems to be the simplest; a drawback is that it will allocate + // memory for the list of children, becasue we use a child window for + // WindowSurface. + Window root; + Window parent; + Window *children = nullptr; + unsigned nChildren; + int status = XQueryTree(mGLX.getDisplay(), window, &root, &parent, &children, &nChildren); + if (children) + { + XFree(children); + } + return status != 0; +} + +std::string DisplayGLX::getVendorString() const +{ + // UNIMPLEMENTED(); + return ""; +} + +egl::Error DisplayGLX::waitClient() const +{ + mGLX.waitGL(); + return egl::Error(EGL_SUCCESS); +} + +egl::Error DisplayGLX::getDriverVersion(std::string *version) const +{ + VendorID vendor = GetVendorID(mFunctionsGL); + + switch (vendor) + { + case VENDOR_ID_NVIDIA: + return getNVIDIADriverVersion(version); + default: + *version = ""; + return egl::Error(EGL_SUCCESS); + } +} + +egl::Error DisplayGLX::waitNative(EGLint engine, + egl::Surface *drawSurface, + egl::Surface *readSurface) const +{ + // eglWaitNative is used to notice the driver of changes in X11 for the current surface, such as + // changes of the window size. We use this event to update the child window of WindowSurfaceGLX + // to match its parent window's size. + // Handling eglWaitNative this way helps the application control when resize happens. This is + // important because drivers have a tendency to clobber the back buffer when the windows are + // resized. See http://crbug.com/326995 + if (drawSurface != nullptr) + { + SurfaceGLX *glxDrawSurface = GetImplAs(drawSurface); + egl::Error error = glxDrawSurface->checkForResize(); + if (error.isError()) + { + return error; + } + } + + if (readSurface != drawSurface && readSurface != nullptr) + { + SurfaceGLX *glxReadSurface = GetImplAs(readSurface); + egl::Error error = glxReadSurface->checkForResize(); + if (error.isError()) + { + return error; + } + } + + // We still need to forward the resizing of the child window to the driver. + mGLX.waitX(); + return egl::Error(EGL_SUCCESS); +} + +void DisplayGLX::syncXCommands() const +{ + if (mUsesNewXDisplay) + { + XSync(mGLX.getDisplay(), False); + } +} + +void DisplayGLX::setSwapInterval(glx::Drawable drawable, SwapControlData *data) +{ + ASSERT(data != nullptr); + + // TODO(cwallez) error checking? + if (mSwapControl == SwapControl::EXT) + { + // Prefer the EXT extension, it gives per-drawable swap intervals, which will + // minimize the number of driver calls. + if (data->maxSwapInterval < 0) + { + unsigned int maxSwapInterval = 0; + mGLX.queryDrawable(drawable, GLX_MAX_SWAP_INTERVAL_EXT, &maxSwapInterval); + data->maxSwapInterval = static_cast(maxSwapInterval); + } + + // When the egl configs were generated we had to guess what the max swap interval + // was because we didn't have a window to query it one (and that this max could + // depend on the monitor). This means that the target interval might be higher + // than the max interval and needs to be clamped. + const int realInterval = std::min(data->targetSwapInterval, data->maxSwapInterval); + if (data->currentSwapInterval != realInterval) + { + mGLX.swapIntervalEXT(drawable, realInterval); + data->currentSwapInterval = realInterval; + } + } + else if (mCurrentSwapInterval != data->targetSwapInterval) + { + // With the Mesa or SGI extensions we can still do per-drawable swap control + // manually but it is more expensive in number of driver calls. + if (mSwapControl == SwapControl::Mesa) + { + mGLX.swapIntervalMESA(data->targetSwapInterval); + } + else if (mSwapControl == SwapControl::SGI) + { + mGLX.swapIntervalSGI(data->targetSwapInterval); + } + mCurrentSwapInterval = data->targetSwapInterval; + } +} + +bool DisplayGLX::isValidWindowVisualId(unsigned long visualId) const +{ + return mRequestedVisual == -1 || static_cast(mRequestedVisual) == visualId; +} + +const FunctionsGL *DisplayGLX::getFunctionsGL() const +{ + return mFunctionsGL; +} + +void DisplayGLX::generateExtensions(egl::DisplayExtensions *outExtensions) const +{ + outExtensions->createContext = true; + outExtensions->createContextNoError = true; +} + +void DisplayGLX::generateCaps(egl::Caps *outCaps) const +{ + // UNIMPLEMENTED(); + outCaps->textureNPOT = true; +} + +int DisplayGLX::getGLXFBConfigAttrib(glx::FBConfig config, int attrib) const +{ + int result; + mGLX.getFBConfigAttrib(config, attrib, &result); + return result; +} + +egl::Error DisplayGLX::createContextAttribs(glx::FBConfig, + gl::Version version, + int profileMask, + glx::Context *context) const +{ + std::vector attribs; + attribs.push_back(GLX_CONTEXT_MAJOR_VERSION_ARB); + attribs.push_back(version.major); + + attribs.push_back(GLX_CONTEXT_MINOR_VERSION_ARB); + attribs.push_back(version.minor); + + if (profileMask != 0 && mHasARBCreateContextProfile) + { + attribs.push_back(GLX_CONTEXT_PROFILE_MASK_ARB); + attribs.push_back(profileMask); + } + + attribs.push_back(None); + + // When creating a context with glXCreateContextAttribsARB, a variety of X11 errors can + // be generated. To prevent these errors from crashing our process, we simply ignore + // them and only look if GLXContext was created. + auto oldErrorHandler = XSetErrorHandler(IgnoreX11Errors); + *context = mGLX.createContextAttribsARB(mContextConfig, nullptr, True, attribs.data()); + XSetErrorHandler(oldErrorHandler); + + if (!*context) + { + return egl::Error(EGL_NOT_INITIALIZED, "Could not create GL context."); + } + return egl::Error(EGL_SUCCESS); +} + +egl::Error DisplayGLX::getNVIDIADriverVersion(std::string *version) const +{ + *version = ""; + + int eventBase = 0; + int errorBase = 0; + if (XNVCTRLQueryExtension(mXDisplay, &eventBase, &errorBase)) + { + int screenCount = ScreenCount(mXDisplay); + for (int screen = 0; screen < screenCount; ++screen) + { + char *buffer = nullptr; + if (XNVCTRLIsNvScreen(mXDisplay, screen) && + XNVCTRLQueryStringAttribute(mXDisplay, screen, 0, + NV_CTRL_STRING_NVIDIA_DRIVER_VERSION, &buffer)) + { + *version = buffer; + XFree(buffer); + } + } + } + + return egl::Error(EGL_SUCCESS); +} +} diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/glx/DisplayGLX.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/glx/DisplayGLX.h new file mode 100644 index 000000000000..cedf1a0c812c --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/glx/DisplayGLX.h @@ -0,0 +1,146 @@ +// +// Copyright (c) 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. +// + +// DisplayGLX.h: GLX implementation of egl::Display + +#ifndef LIBANGLE_RENDERER_GL_GLX_DISPLAYGLX_H_ +#define LIBANGLE_RENDERER_GL_GLX_DISPLAYGLX_H_ + +#include +#include + +#include "libANGLE/renderer/gl/DisplayGL.h" +#include "libANGLE/renderer/gl/glx/FunctionsGLX.h" + +namespace rx +{ + +class FunctionsGLX; + +// State-tracking data for the swap control to allow DisplayGLX to remember per +// drawable information for swap control. +struct SwapControlData +{ + SwapControlData(); + + // Set by the drawable + int targetSwapInterval; + + // DisplayGLX-side state-tracking + int maxSwapInterval; + int currentSwapInterval; +}; + +class DisplayGLX : public DisplayGL +{ + public: + DisplayGLX(); + ~DisplayGLX() override; + + egl::Error initialize(egl::Display *display) override; + void terminate() override; + + SurfaceImpl *createWindowSurface(const egl::Config *configuration, + EGLNativeWindowType window, + const egl::AttributeMap &attribs) override; + SurfaceImpl *createPbufferSurface(const egl::Config *configuration, + const egl::AttributeMap &attribs) override; + SurfaceImpl *createPbufferFromClientBuffer(const egl::Config *configuration, + EGLClientBuffer shareHandle, + const egl::AttributeMap &attribs) override; + SurfaceImpl *createPixmapSurface(const egl::Config *configuration, + NativePixmapType nativePixmap, + const egl::AttributeMap &attribs) override; + + egl::ConfigSet generateConfigs() const override; + + bool isDeviceLost() const override; + bool testDeviceLost() override; + egl::Error restoreLostDevice() override; + + bool isValidNativeWindow(EGLNativeWindowType window) const override; + + egl::Error getDevice(DeviceImpl **device) override; + + std::string getVendorString() const override; + + egl::Error waitClient() const override; + egl::Error waitNative(EGLint engine, + egl::Surface *drawSurface, + egl::Surface *readSurface) const override; + + egl::Error getDriverVersion(std::string *version) const override; + + // Synchronizes with the X server, if the display has been opened by ANGLE. + // Calling this is required at the end of every functions that does buffered + // X calls (not for glX calls) otherwise there might be race conditions + // between the application's display and ANGLE's one. + void syncXCommands() const; + + // Depending on the supported GLX extension, swap interval can be set + // globally or per drawable. This function will make sure the drawable's + // swap interval is the one required so that the subsequent swapBuffers + // acts as expected. + void setSwapInterval(glx::Drawable drawable, SwapControlData *data); + + bool isValidWindowVisualId(unsigned long visualId) const; + + private: + const FunctionsGL *getFunctionsGL() const override; + + egl::Error initializeContext(glx::FBConfig config, + const egl::AttributeMap &eglAttributes, + glx::Context *context); + + void generateExtensions(egl::DisplayExtensions *outExtensions) const override; + void generateCaps(egl::Caps *outCaps) const override; + + int getGLXFBConfigAttrib(glx::FBConfig config, int attrib) const; + egl::Error createContextAttribs(glx::FBConfig, + gl::Version version, + int profileMask, + glx::Context *context) const; + + egl::Error getNVIDIADriverVersion(std::string *version) const; + + FunctionsGL *mFunctionsGL; + + //TODO(cwallez) yuck, change generateConfigs to be non-const or add a userdata member to egl::Config? + mutable std::map configIdToGLXConfig; + + EGLint mRequestedVisual; + glx::FBConfig mContextConfig; + glx::Context mContext; + // A pbuffer the context is current on during ANGLE initialization + glx::Pbuffer mDummyPbuffer; + + bool mUsesNewXDisplay; + bool mIsMesa; + bool mHasMultisample; + bool mHasARBCreateContext; + bool mHasARBCreateContextProfile; + bool mHasEXTCreateContextES2Profile; + + enum class SwapControl + { + Absent, + EXT, + Mesa, + SGI, + }; + SwapControl mSwapControl; + int mMinSwapInterval; + int mMaxSwapInterval; + int mCurrentSwapInterval; + + FunctionsGLX mGLX; + Display *mXDisplay; + egl::Display *mEGLDisplay; +}; + +} + +#endif // LIBANGLE_RENDERER_GL_GLX_DISPLAYGLX_H_ diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/glx/FBConfigCompatibility.md b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/glx/FBConfigCompatibility.md new file mode 100644 index 000000000000..2343ad086b32 --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/glx/FBConfigCompatibility.md @@ -0,0 +1,204 @@ +GLX Framebuffer Compatibility investigation +=========================================== + +In GLX and EGL, contexts are created with respect to a config that +describes the type of surfaces they will be used to render to. +Likewise surfaces are created with respect to a config and for +a context to be able to render to a surface, both their configs +must be compatible. Compatibility is losely described in both +the GLX and EGL specs but the following is clear: + * In GLX the config's color buffer must have the same type, including +RGBA vs. ColorIndex and the buffers must have the same depth, if they +exist. + * In EGL the config's color buffer must have the same type and the +buffers must have the same depth (not clear if it is only if they exist) + +Obviously the EGLconfig we will expose will have a one-to-one +correspondance with GLXFBConfigs. + +Our EGL implementation uses a single OpenGL context to back all +the EGLcontexts created by the application. Since our GL context +and GLXContext are the same object but in two APIs, we will make +the confusion and call the GLX context our backing context. + +The problem we have is that the the GLX context is created before +the application can choose what type of context it wants to use, +that means we have to expose EGLconfigs whose respective GLXFBConfigs +are compatible with the GLXFBConfig of our GLX context; we also need +to choose the GLXFBConfig of our GLX context so that it matches the +most common needs of application. + +Choice of the GLX context GLXFBConfig +------------------------------------- + +We decided that our GLX context's configuration must satisfy the following: + * Have a RGBA8 color buffer and D24S8 depth-stencil buffer which is what +the vast majority of applications use. + * It must render in direct colors, i.e. not in a color indexed format. + * It must be double-buffered (see later) + * It must support rendering to all the types of GLX surfaces so that we can +use it for all types of EGL surfaces + * It must have an associated visual ID so that we can use it with X, it seems +like this would be strongly tied to it having the ```WINDOW_BIT``` set. + * We would like a conformant context. + +Study of compatible GLXFBConfigs +-------------------------------- + +When using the condition of compatibility defined in the GLX spec and filtering +out the non-conformant GLXFBConfig we got the following list (see function +```print_visual_attribs_short``` in [glxinfo's source code](http://cgit.freedesktop.org/mesa/demos/tree/src/xdemos/glxinfo.c) +to understand how to read the table): + +``` + visual x bf lv rg d st colorbuffer sr ax dp st accumbuffer ms cav + id dep cl sp sz l ci b ro r g b a F gb bf th cl r g b a ns b eat Result +---------------------------------------------------------------------------- +0x02e 24 tc 0 32 0 r . . 8 8 8 8 . s 4 0 0 16 16 16 16 0 0 None Fail +0x0e4 32 tc 0 32 0 r . . 8 8 8 8 . s 4 0 0 16 16 16 16 0 0 None BadMatch +0x02c 24 tc 0 32 0 r y . 8 8 8 8 . s 4 0 0 16 16 16 16 0 0 None Pass +0x0e2 32 tc 0 32 0 r y . 8 8 8 8 . s 4 0 0 16 16 16 16 0 0 None BadMatch +0x089 24 dc 0 32 0 r . . 8 8 8 8 . s 4 0 0 16 16 16 16 0 0 None Fail +0x087 24 dc 0 32 0 r y . 8 8 8 8 . s 4 0 0 16 16 16 16 0 0 None Pass +0x026 24 tc 0 32 0 r . . 8 8 8 8 . s 4 24 8 16 16 16 16 0 0 None Fail +0x0dc 32 tc 0 32 0 r . . 8 8 8 8 . s 4 24 8 16 16 16 16 0 0 None BadMatch +0x024 24 tc 0 32 0 r y . 8 8 8 8 . s 4 24 8 16 16 16 16 0 0 None Pass +0x0da 32 tc 0 32 0 r y . 8 8 8 8 . s 4 24 8 16 16 16 16 0 0 None BadMatch +0x081 24 dc 0 32 0 r . . 8 8 8 8 . s 4 24 8 16 16 16 16 0 0 None Fail +0x07f 24 dc 0 32 0 r y . 8 8 8 8 . s 4 24 8 16 16 16 16 0 0 None Pass +``` + +The last column shows the result of trying to render on a window using the config, +with a GLX context using config 0x024. The first thing we see is that BadMatch is +thrown by the X server when creating the subwindow for rendering. This was because +we didn't set the border pixel of the subwindow *shake fist at X11* (see this [StackOverflow question](http://stackoverflow.com/questions/3645632/how-to-create-a-window-with-a-bit-depth-of-32)). +The result updated with this fix give: + +``` + visual x bf lv rg d st colorbuffer sr ax dp st accumbuffer ms cav + id dep cl sp sz l ci b ro r g b a F gb bf th cl r g b a ns b eat +---------------------------------------------------------------------------- +0x02e 24 tc 0 32 0 r . . 8 8 8 8 . s 4 0 0 16 16 16 16 0 0 None Fail +0x0e4 32 tc 0 32 0 r . . 8 8 8 8 . s 4 0 0 16 16 16 16 0 0 None Fail +0x02c 24 tc 0 32 0 r y . 8 8 8 8 . s 4 0 0 16 16 16 16 0 0 None Pass +0x0e2 32 tc 0 32 0 r y . 8 8 8 8 . s 4 0 0 16 16 16 16 0 0 None Pass +0x089 24 dc 0 32 0 r . . 8 8 8 8 . s 4 0 0 16 16 16 16 0 0 None Fail +0x087 24 dc 0 32 0 r y . 8 8 8 8 . s 4 0 0 16 16 16 16 0 0 None Pass +0x026 24 tc 0 32 0 r . . 8 8 8 8 . s 4 24 8 16 16 16 16 0 0 None Fail +0x0dc 32 tc 0 32 0 r . . 8 8 8 8 . s 4 24 8 16 16 16 16 0 0 None Fail +0x024 24 tc 0 32 0 r y . 8 8 8 8 . s 4 24 8 16 16 16 16 0 0 None Pass +0x0da 32 tc 0 32 0 r y . 8 8 8 8 . s 4 24 8 16 16 16 16 0 0 None Pass +0x081 24 dc 0 32 0 r . . 8 8 8 8 . s 4 24 8 16 16 16 16 0 0 None Fail +0x07f 24 dc 0 32 0 r y . 8 8 8 8 . s 4 24 8 16 16 16 16 0 0 None Pass +``` + +From this we see that our rendering test passed if and only if the config was double +buffered like 0x024 which is our GLX context config. The compatible configs are then: + +``` + visual x bf lv rg d st colorbuffer sr ax dp st accumbuffer ms cav + id dep cl sp sz l ci b ro r g b a F gb bf th cl r g b a ns b eat +---------------------------------------------------------------------------- +0x02c 24 tc 0 32 0 r y . 8 8 8 8 . s 4 0 0 16 16 16 16 0 0 None +0x0e2 32 tc 0 32 0 r y . 8 8 8 8 . s 4 0 0 16 16 16 16 0 0 None +0x087 24 dc 0 32 0 r y . 8 8 8 8 . s 4 0 0 16 16 16 16 0 0 None +0x024 24 tc 0 32 0 r y . 8 8 8 8 . s 4 24 8 16 16 16 16 0 0 None +0x0da 32 tc 0 32 0 r y . 8 8 8 8 . s 4 24 8 16 16 16 16 0 0 None +0x07f 24 dc 0 32 0 r y . 8 8 8 8 . s 4 24 8 16 16 16 16 0 0 None +``` + +We can see two dimensions, with our without a depth-stencil buffer and with TrueColor +or DirectColor. The depth-stencil will be useful to expose to application. + +More on double buffering +------------------------ +The tests above show that double-buffered contexts are not compatible with single- +buffered surfaces; however other tests show that single-buffered contexts are +compatible with both single and double-buffered surfaces. The problem is that in +that case, we can see some flickering even with double-buffered surfaces. If we +can find a trick to avoid that flicker, then we would be able to expose single +and double-buffered surfaces at the EGL level. Not exposing them isn't too much +of a problem though as the vast majority of application want double-buffering. + +AMD and extra buffers +--------------------- +As can be seen above, NVIDIA does not expose conformant context with multisampled +buffers or non RGBA16 accumulation buffers. The behavior is different on AMD that +exposes them as conformant, which gives the following list after filtering as +explained above: + +``` + visual x bf lv rg d st colorbuffer sr ax dp st accumbuffer ms cav + id dep cl sp sz l ci b ro r g b a F gb bf th cl r g b a ns b eat +---------------------------------------------------------------------------- +0x023 24 tc 0 32 0 r y . 8 8 8 8 . . 0 24 8 16 16 16 16 0 0 None +0x027 24 tc 0 32 0 r y . 8 8 8 8 . . 0 24 8 0 0 0 0 0 0 None +0x02b 24 tc 0 32 0 r y . 8 8 8 8 . . 0 24 8 0 0 0 0 2 1 None +0x02f 24 tc 0 32 0 r y . 8 8 8 8 . . 0 24 8 0 0 0 0 4 1 None +0x03b 24 dc 0 32 0 r y . 8 8 8 8 . . 0 24 8 16 16 16 16 0 0 None +0x03f 24 dc 0 32 0 r y . 8 8 8 8 . . 0 24 8 0 0 0 0 0 0 None +0x043 24 dc 0 32 0 r y . 8 8 8 8 . . 0 24 8 0 0 0 0 2 1 None +0x047 24 dc 0 32 0 r y . 8 8 8 8 . . 0 24 8 0 0 0 0 4 1 None +``` + +ANGLE's context is created using 0x027 and experimentation shows it is only compatible +with 0x03f which is the only other config lacking both an accumulation buffer and a +multisample buffer. The GLX spec seems to hint it should still work ("should have the +same size, if they exist") but it doesn't work in this case. Filtering the configs to +have the same multisample and accumulation buffers gives the following: + +``` + visual x bf lv rg d st colorbuffer sr ax dp st accumbuffer ms cav + id dep cl sp sz l ci b ro r g b a F gb bf th cl r g b a ns b eat +---------------------------------------------------------------------------- +0x027 24 tc 0 32 0 r y . 8 8 8 8 . . 0 24 8 0 0 0 0 0 0 None +0x03f 24 dc 0 32 0 r y . 8 8 8 8 . . 0 24 8 0 0 0 0 0 0 None +``` + +Mesa Intel driver +----------------- +In GLX, a criterium for context and surface compatibility is that buffers +should have the same depth, if they exist at all in the surface. This means +that it should be possible to make a context with a D24S8 depth-stencil +buffer to a surface without a depth-stencil buffer. This doesn't work on the +Mesa Intel driver. The list before the workaround was the following, with +0x020 being the fbconfig chosen for the context: + +``` + visual x bf lv rg d st colorbuffer sr ax dp st accumbuffer ms cav + id dep cl sp sz l ci b ro r g b a F gb bf th cl r g b a ns b eat +---------------------------------------------------------------------------- +0x020 24 tc 0 32 0 r y . 8 8 8 8 . . 0 24 8 0 0 0 0 0 0 None +0x021 24 dc 0 32 0 r y . 8 8 8 8 . . 0 24 8 0 0 0 0 0 0 None +0x08f 32 tc 0 32 0 r y . 8 8 8 8 . . 0 24 8 0 0 0 0 0 0 None +0x0d0 24 tc 0 32 0 r y . 8 8 8 8 . . 0 0 0 0 0 0 0 0 0 None +0x0e2 24 dc 0 32 0 r y . 8 8 8 8 . . 0 0 0 0 0 0 0 0 0 None +0x0e9 24 dc 0 32 0 r y . 8 8 8 8 . . 0 24 8 0 0 0 0 0 0 None +``` + +After the workaround that list becomes the following: + +``` + visual x bf lv rg d st colorbuffer sr ax dp st accumbuffer ms cav + id dep cl sp sz l ci b ro r g b a F gb bf th cl r g b a ns b eat +---------------------------------------------------------------------------- +0x020 24 tc 0 32 0 r y . 8 8 8 8 . . 0 24 8 0 0 0 0 0 0 None +0x021 24 dc 0 32 0 r y . 8 8 8 8 . . 0 24 8 0 0 0 0 0 0 None +0x08f 32 tc 0 32 0 r y . 8 8 8 8 . . 0 24 8 0 0 0 0 0 0 None +0x0e9 24 dc 0 32 0 r y . 8 8 8 8 . . 0 24 8 0 0 0 0 0 0 None +``` + +Future investigation +-------------------- +All the non-conformant configs have a multisampled buffer, so it could be interesting +to see if we can use them to expose another EGL extension. + +Finally this document is written with respect to a small number of drivers, before +using the GLX EGL implementation in the wild it would be good to test it on other +drivers and hardware. + +The drivers tested were: + + - the proprietary NVIDIA driver + - the proprietary AMD driver + - the open source Intel (Broadwell) Mesa driver diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/glx/FunctionsGLX.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/glx/FunctionsGLX.cpp new file mode 100644 index 000000000000..a93cea2287c8 --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/glx/FunctionsGLX.cpp @@ -0,0 +1,390 @@ +// +// Copyright (c) 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. +// + +// FunctionsGLX.cpp: Implements the FunctionsGLX class. + +#define ANGLE_SKIP_GLX_DEFINES 1 +#include "libANGLE/renderer/gl/glx/FunctionsGLX.h" +#undef ANGLE_SKIP_GLX_DEFINES + +// We can only include glx.h in files which do not include ANGLE's GLES +// headers, to avoid doubly-defined GLenum macros, typedefs, etc. +#include + +#include +#include + +#include "common/string_utils.h" +#include "libANGLE/renderer/gl/glx/functionsglx_typedefs.h" + +namespace rx +{ + +void* FunctionsGLX::sLibHandle = nullptr; + +template +static bool GetProc(PFNGETPROCPROC getProc, T *member, const char *name) +{ + *member = reinterpret_cast(getProc(name)); + return *member != nullptr; +} + +struct FunctionsGLX::GLXFunctionTable +{ + GLXFunctionTable() + : createContextPtr(nullptr), + destroyContextPtr(nullptr), + makeCurrentPtr(nullptr), + swapBuffersPtr(nullptr), + queryExtensionPtr(nullptr), + queryVersionPtr(nullptr), + getCurrentContextPtr(nullptr), + getCurrentDrawablePtr(nullptr), + waitXPtr(nullptr), + waitGLPtr(nullptr), + queryExtensionsStringPtr(nullptr), + getFBConfigsPtr(nullptr), + chooseFBConfigPtr(nullptr), + getFBConfigAttribPtr(nullptr), + getVisualFromFBConfigPtr(nullptr), + createWindowPtr(nullptr), + destroyWindowPtr(nullptr), + createPbufferPtr(nullptr), + destroyPbufferPtr(nullptr), + queryDrawablePtr(nullptr), + createContextAttribsARBPtr(nullptr), + swapIntervalEXTPtr(nullptr), + swapIntervalMESAPtr(nullptr), + swapIntervalSGIPtr(nullptr) + { + } + + // GLX 1.0 + PFNGLXCREATECONTEXTPROC createContextPtr; + PFNGLXDESTROYCONTEXTPROC destroyContextPtr; + PFNGLXMAKECURRENTPROC makeCurrentPtr; + PFNGLXSWAPBUFFERSPROC swapBuffersPtr; + PFNGLXQUERYEXTENSIONPROC queryExtensionPtr; + PFNGLXQUERYVERSIONPROC queryVersionPtr; + PFNGLXGETCURRENTCONTEXTPROC getCurrentContextPtr; + PFNGLXGETCURRENTDRAWABLEPROC getCurrentDrawablePtr; + PFNGLXWAITXPROC waitXPtr; + PFNGLXWAITGLPROC waitGLPtr; + + // GLX 1.1 + PFNGLXQUERYEXTENSIONSSTRINGPROC queryExtensionsStringPtr; + + //GLX 1.3 + PFNGLXGETFBCONFIGSPROC getFBConfigsPtr; + PFNGLXCHOOSEFBCONFIGPROC chooseFBConfigPtr; + PFNGLXGETFBCONFIGATTRIBPROC getFBConfigAttribPtr; + PFNGLXGETVISUALFROMFBCONFIGPROC getVisualFromFBConfigPtr; + PFNGLXCREATEWINDOWPROC createWindowPtr; + PFNGLXDESTROYWINDOWPROC destroyWindowPtr; + PFNGLXCREATEPBUFFERPROC createPbufferPtr; + PFNGLXDESTROYPBUFFERPROC destroyPbufferPtr; + PFNGLXQUERYDRAWABLEPROC queryDrawablePtr; + + // GLX_ARB_create_context + PFNGLXCREATECONTEXTATTRIBSARBPROC createContextAttribsARBPtr; + + // GLX_EXT_swap_control + PFNGLXSWAPINTERVALEXTPROC swapIntervalEXTPtr; + + // GLX_MESA_swap_control + PFNGLXSWAPINTERVALMESAPROC swapIntervalMESAPtr; + + // GLX_SGI_swap_control + PFNGLXSWAPINTERVALSGIPROC swapIntervalSGIPtr; +}; + +FunctionsGLX::FunctionsGLX() + : majorVersion(0), + minorVersion(0), + mXDisplay(nullptr), + mXScreen(-1), + mFnPtrs(new GLXFunctionTable()) +{ +} + +FunctionsGLX::~FunctionsGLX() +{ + delete mFnPtrs; + terminate(); +} + +bool FunctionsGLX::initialize(Display *xDisplay, int screen, std::string *errorString) +{ + terminate(); + mXDisplay = xDisplay; + mXScreen = screen; + +#if !defined(ANGLE_LINK_GLX) + // Some OpenGL implementations can't handle having this library + // handle closed while there's any X window still open against + // which a GLXWindow was ever created. + if (!sLibHandle) + { + sLibHandle = dlopen("libGL.so.1", RTLD_NOW); + if (!sLibHandle) + { + *errorString = std::string("Could not dlopen libGL.so.1: ") + dlerror(); + return false; + } + } + + getProc = reinterpret_cast(dlsym(sLibHandle, "glXGetProcAddress")); + if (!getProc) + { + getProc = reinterpret_cast(dlsym(sLibHandle, "glXGetProcAddressARB")); + } + if (!getProc) + { + *errorString = "Could not retrieve glXGetProcAddress"; + return false; + } +#else + getProc = reinterpret_cast(glXGetProcAddress); +#endif + +#define GET_PROC_OR_ERROR(MEMBER, NAME) \ + if (!GetProc(getProc, MEMBER, #NAME)) \ + { \ + *errorString = "Could not load GLX entry point " #NAME; \ + return false; \ + } +#if !defined(ANGLE_LINK_GLX) +#define GET_FNPTR_OR_ERROR(MEMBER, NAME) GET_PROC_OR_ERROR(MEMBER, NAME) +#else +#define GET_FNPTR_OR_ERROR(MEMBER, NAME) *MEMBER = NAME; +#endif + + // GLX 1.0 + GET_FNPTR_OR_ERROR(&mFnPtrs->createContextPtr, glXCreateContext); + GET_FNPTR_OR_ERROR(&mFnPtrs->destroyContextPtr, glXDestroyContext); + GET_FNPTR_OR_ERROR(&mFnPtrs->makeCurrentPtr, glXMakeCurrent); + GET_FNPTR_OR_ERROR(&mFnPtrs->swapBuffersPtr, glXSwapBuffers); + GET_FNPTR_OR_ERROR(&mFnPtrs->queryExtensionPtr, glXQueryExtension); + GET_FNPTR_OR_ERROR(&mFnPtrs->queryVersionPtr, glXQueryVersion); + GET_FNPTR_OR_ERROR(&mFnPtrs->getCurrentContextPtr, glXGetCurrentContext); + GET_FNPTR_OR_ERROR(&mFnPtrs->getCurrentDrawablePtr, glXGetCurrentDrawable); + GET_FNPTR_OR_ERROR(&mFnPtrs->waitXPtr, glXWaitX); + GET_FNPTR_OR_ERROR(&mFnPtrs->waitGLPtr, glXWaitGL); + + // GLX 1.1 + GET_FNPTR_OR_ERROR(&mFnPtrs->queryExtensionsStringPtr, glXQueryExtensionsString); + + // Check we have a working GLX + { + int errorBase; + int eventBase; + if (!queryExtension(&errorBase, &eventBase)) + { + *errorString = "GLX is not present."; + return false; + } + } + + // Check we have a supported version of GLX + if (!queryVersion(&majorVersion, &minorVersion)) + { + *errorString = "Could not query the GLX version."; + return false; + } + if (majorVersion != 1 || minorVersion < 3) + { + *errorString = "Unsupported GLX version (requires at least 1.3)."; + return false; + } + + const char *extensions = queryExtensionsString(); + if (!extensions) + { + *errorString = "glXQueryExtensionsString returned NULL"; + return false; + } + angle::SplitStringAlongWhitespace(extensions, &mExtensions); + + // GLX 1.3 + GET_FNPTR_OR_ERROR(&mFnPtrs->getFBConfigsPtr, glXGetFBConfigs); + GET_FNPTR_OR_ERROR(&mFnPtrs->chooseFBConfigPtr, glXChooseFBConfig); + GET_FNPTR_OR_ERROR(&mFnPtrs->getFBConfigAttribPtr, glXGetFBConfigAttrib); + GET_FNPTR_OR_ERROR(&mFnPtrs->getVisualFromFBConfigPtr, glXGetVisualFromFBConfig); + GET_FNPTR_OR_ERROR(&mFnPtrs->createWindowPtr, glXCreateWindow); + GET_FNPTR_OR_ERROR(&mFnPtrs->destroyWindowPtr, glXDestroyWindow); + GET_FNPTR_OR_ERROR(&mFnPtrs->createPbufferPtr, glXCreatePbuffer); + GET_FNPTR_OR_ERROR(&mFnPtrs->destroyPbufferPtr, glXDestroyPbuffer); + GET_FNPTR_OR_ERROR(&mFnPtrs->queryDrawablePtr, glXQueryDrawable); + + // Extensions + if (hasExtension("GLX_ARB_create_context")) + { + GET_PROC_OR_ERROR(&mFnPtrs->createContextAttribsARBPtr, glXCreateContextAttribsARB); + } + if (hasExtension("GLX_EXT_swap_control")) + { + GET_PROC_OR_ERROR(&mFnPtrs->swapIntervalEXTPtr, glXSwapIntervalEXT); + } + if (hasExtension("GLX_MESA_swap_control")) + { + GET_PROC_OR_ERROR(&mFnPtrs->swapIntervalMESAPtr, glXSwapIntervalMESA); + } + if (hasExtension("GLX_SGI_swap_control")) + { + GET_PROC_OR_ERROR(&mFnPtrs->swapIntervalSGIPtr, glXSwapIntervalSGI); + } + +#undef GET_FNPTR_OR_ERROR +#undef GET_PROC_OR_ERROR + + *errorString = ""; + return true; +} + +void FunctionsGLX::terminate() +{ +} + +bool FunctionsGLX::hasExtension(const char *extension) const +{ + return std::find(mExtensions.begin(), mExtensions.end(), extension) != mExtensions.end(); +} + +Display *FunctionsGLX::getDisplay() const +{ + return mXDisplay; +} + +int FunctionsGLX::getScreen() const +{ + return mXScreen; +} + +// GLX functions + +// GLX 1.0 +glx::Context FunctionsGLX::createContext(XVisualInfo *visual, glx::Context share, bool direct) const +{ + GLXContext shareCtx = reinterpret_cast(share); + GLXContext context = mFnPtrs->createContextPtr(mXDisplay, visual, shareCtx, direct); + return reinterpret_cast(context); +} +void FunctionsGLX::destroyContext(glx::Context context) const +{ + GLXContext ctx = reinterpret_cast(context); + mFnPtrs->destroyContextPtr(mXDisplay, ctx); +} +Bool FunctionsGLX::makeCurrent(glx::Drawable drawable, glx::Context context) const +{ + GLXContext ctx = reinterpret_cast(context); + return mFnPtrs->makeCurrentPtr(mXDisplay, drawable, ctx); +} +void FunctionsGLX::swapBuffers(glx::Drawable drawable) const +{ + mFnPtrs->swapBuffersPtr(mXDisplay, drawable); +} +Bool FunctionsGLX::queryExtension(int *errorBase, int *event) const +{ + return mFnPtrs->queryExtensionPtr(mXDisplay, errorBase, event); +} +Bool FunctionsGLX::queryVersion(int *major, int *minor) const +{ + return mFnPtrs->queryVersionPtr(mXDisplay, major, minor); +} +glx::Context FunctionsGLX::getCurrentContext() const +{ + GLXContext context = mFnPtrs->getCurrentContextPtr(); + return reinterpret_cast(context); +} +glx::Drawable FunctionsGLX::getCurrentDrawable() const +{ + GLXDrawable drawable = mFnPtrs->getCurrentDrawablePtr(); + return reinterpret_cast(drawable); +} +void FunctionsGLX::waitX() const +{ + mFnPtrs->waitXPtr(); +} +void FunctionsGLX::waitGL() const +{ + mFnPtrs->waitGLPtr(); +} + +// GLX 1.1 +const char *FunctionsGLX::queryExtensionsString() const +{ + return mFnPtrs->queryExtensionsStringPtr(mXDisplay, mXScreen); +} + +// GLX 1.4 +glx::FBConfig *FunctionsGLX::getFBConfigs(int *nElements) const +{ + GLXFBConfig *configs = mFnPtrs->getFBConfigsPtr(mXDisplay, mXScreen, nElements); + return reinterpret_cast(configs); +} +glx::FBConfig *FunctionsGLX::chooseFBConfig(const int *attribList, int *nElements) const +{ + GLXFBConfig *configs = mFnPtrs->chooseFBConfigPtr(mXDisplay, mXScreen, attribList, nElements); + return reinterpret_cast(configs); +} +int FunctionsGLX::getFBConfigAttrib(glx::FBConfig config, int attribute, int *value) const +{ + GLXFBConfig cfg = reinterpret_cast(config); + return mFnPtrs->getFBConfigAttribPtr(mXDisplay, cfg, attribute, value); +} +XVisualInfo *FunctionsGLX::getVisualFromFBConfig(glx::FBConfig config) const +{ + GLXFBConfig cfg = reinterpret_cast(config); + return mFnPtrs->getVisualFromFBConfigPtr(mXDisplay, cfg); +} +GLXWindow FunctionsGLX::createWindow(glx::FBConfig config, Window window, const int *attribList) const +{ + GLXFBConfig cfg = reinterpret_cast(config); + return mFnPtrs->createWindowPtr(mXDisplay, cfg, window, attribList); +} +void FunctionsGLX::destroyWindow(glx::Window window) const +{ + mFnPtrs->destroyWindowPtr(mXDisplay, window); +} +glx::Pbuffer FunctionsGLX::createPbuffer(glx::FBConfig config, const int *attribList) const +{ + GLXFBConfig cfg = reinterpret_cast(config); + return mFnPtrs->createPbufferPtr(mXDisplay, cfg, attribList); +} +void FunctionsGLX::destroyPbuffer(glx::Pbuffer pbuffer) const +{ + mFnPtrs->destroyPbufferPtr(mXDisplay, pbuffer); +} +void FunctionsGLX::queryDrawable(glx::Drawable drawable, int attribute, unsigned int *value) const +{ + mFnPtrs->queryDrawablePtr(mXDisplay, drawable, attribute, value); +} + +// GLX_ARB_create_context +glx::Context FunctionsGLX::createContextAttribsARB(glx::FBConfig config, glx::Context shareContext, Bool direct, const int *attribList) const +{ + GLXContext shareCtx = reinterpret_cast(shareContext); + GLXFBConfig cfg = reinterpret_cast(config); + GLXContext ctx = mFnPtrs->createContextAttribsARBPtr(mXDisplay, cfg, shareCtx, direct, attribList); + return reinterpret_cast(ctx); +} + +void FunctionsGLX::swapIntervalEXT(glx::Drawable drawable, int intervals) const +{ + mFnPtrs->swapIntervalEXTPtr(mXDisplay, drawable, intervals); +} + +int FunctionsGLX::swapIntervalMESA(int intervals) const +{ + return mFnPtrs->swapIntervalMESAPtr(intervals); +} + +int FunctionsGLX::swapIntervalSGI(int intervals) const +{ + return mFnPtrs->swapIntervalSGIPtr(intervals); +} + +} diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/glx/FunctionsGLX.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/glx/FunctionsGLX.h new file mode 100644 index 000000000000..a919f4c88b04 --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/glx/FunctionsGLX.h @@ -0,0 +1,95 @@ +// +// Copyright (c) 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. +// + +// FunctionsGLX.h: Defines the FunctionsGLX class to load functions and data from GLX + +#ifndef LIBANGLE_RENDERER_GL_GLX_FUNCTIONSGLX_H_ +#define LIBANGLE_RENDERER_GL_GLX_FUNCTIONSGLX_H_ + +#include +#include + +#include "libANGLE/renderer/gl/glx/platform_glx.h" + +namespace rx +{ + +class FunctionsGLX +{ + public: + FunctionsGLX(); + ~FunctionsGLX(); + + // Load data from GLX, can be called multiple times + bool initialize(Display *xDisplay, int screen, std::string *errorString); + void terminate(); + + bool hasExtension(const char *extension) const; + int majorVersion; + int minorVersion; + + Display *getDisplay() const; + int getScreen() const; + + PFNGETPROCPROC getProc; + + // GLX 1.0 + glx::Context createContext(XVisualInfo *visual, glx::Context share, bool direct) const; + void destroyContext(glx::Context context) const; + Bool makeCurrent(glx::Drawable drawable, glx::Context context) const; + void swapBuffers(glx::Drawable drawable) const; + Bool queryExtension(int *errorBase, int *event) const; + Bool queryVersion(int *major, int *minor) const; + glx::Context getCurrentContext() const; + glx::Drawable getCurrentDrawable() const; + void waitX() const; + void waitGL() const; + + // GLX 1.1 + const char *queryExtensionsString() const; + + // GLX 1.3 + glx::FBConfig *getFBConfigs(int *nElements) const; + glx::FBConfig *chooseFBConfig(const int *attribList, int *nElements) const; + int getFBConfigAttrib(glx::FBConfig config, int attribute, int *value) const; + XVisualInfo *getVisualFromFBConfig(glx::FBConfig config) const; + glx::Window createWindow(glx::FBConfig config, Window window, const int *attribList) const; + void destroyWindow(glx::Window window) const; + glx::Pbuffer createPbuffer(glx::FBConfig config, const int *attribList) const; + void destroyPbuffer(glx::Pbuffer pbuffer) const; + void queryDrawable(glx::Drawable drawable, int attribute, unsigned int *value) const; + + // GLX_ARB_create_context + glx::Context createContextAttribsARB(glx::FBConfig config, glx::Context shareContext, Bool direct, const int *attribList) const; + + // GLX_EXT_swap_control + void swapIntervalEXT(glx::Drawable drawable, int interval) const; + + // GLX_MESA_swap_control + int swapIntervalMESA(int interval) const; + + // GLX_SGI_swap_control + int swapIntervalSGI(int interval) const; + + private: + // So as to isolate GLX from angle we do not include angleutils.h and cannot + // use angle::NonCopyable so we replicated it here instead. + FunctionsGLX(const FunctionsGLX&) = delete; + void operator=(const FunctionsGLX&) = delete; + + struct GLXFunctionTable; + + static void *sLibHandle; + Display *mXDisplay; + int mXScreen; + + GLXFunctionTable *mFnPtrs; + std::vector mExtensions; +}; + +} + +#endif // LIBANGLE_RENDERER_GL_GLX_FUNCTIONSGLX_H_ diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/glx/PbufferSurfaceGLX.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/glx/PbufferSurfaceGLX.cpp new file mode 100644 index 000000000000..15e882bf0568 --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/glx/PbufferSurfaceGLX.cpp @@ -0,0 +1,142 @@ +// +// Copyright (c) 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. +// + +// PbufferSurfaceGLX.cpp: GLX implementation of egl::Surface for PBuffers + +#include "libANGLE/renderer/gl/glx/PbufferSurfaceGLX.h" + +#include "common/debug.h" +#include "libANGLE/renderer/gl/glx/DisplayGLX.h" +#include "libANGLE/renderer/gl/glx/FunctionsGLX.h" + +namespace rx +{ + +PbufferSurfaceGLX::PbufferSurfaceGLX(RendererGL *renderer, + EGLint width, + EGLint height, + bool largest, + const FunctionsGLX &glx, + glx::Context context, + glx::FBConfig fbConfig) + : SurfaceGLX(renderer), + mWidth(width), + mHeight(height), + mLargest(largest), + mGLX(glx), + mContext(context), + mFBConfig(fbConfig), + mPbuffer(0) +{ +} + +PbufferSurfaceGLX::~PbufferSurfaceGLX() +{ + if (mPbuffer) + { + mGLX.destroyPbuffer(mPbuffer); + } +} + +egl::Error PbufferSurfaceGLX::initialize() +{ + // Avoid creating 0-sized PBuffers as it fails on the Intel Mesa driver + // as commented on https://bugs.freedesktop.org/show_bug.cgi?id=38869 so we + // use (w, 1) or (1, h) instead. + int width = std::max(1, static_cast(mWidth)); + int height = std::max(1, static_cast(mHeight)); + + const int attribs[] = + { + GLX_PBUFFER_WIDTH, width, + GLX_PBUFFER_HEIGHT, height, + GLX_LARGEST_PBUFFER, mLargest, + None + }; + + mPbuffer = mGLX.createPbuffer(mFBConfig, attribs); + if (!mPbuffer) + { + return egl::Error(EGL_BAD_ALLOC, "Failed to create a native GLX pbuffer."); + } + + if (mLargest) + { + mGLX.queryDrawable(mPbuffer, GLX_WIDTH, &mWidth); + mGLX.queryDrawable(mPbuffer, GLX_HEIGHT, &mHeight); + } + + return egl::Error(EGL_SUCCESS); +} + +egl::Error PbufferSurfaceGLX::makeCurrent() +{ + if (mGLX.makeCurrent(mPbuffer, mContext) != True) + { + return egl::Error(EGL_BAD_DISPLAY); + } + return egl::Error(EGL_SUCCESS); +} + +egl::Error PbufferSurfaceGLX::swap() +{ + return egl::Error(EGL_SUCCESS); +} + +egl::Error PbufferSurfaceGLX::postSubBuffer(EGLint x, EGLint y, EGLint width, EGLint height) +{ + return egl::Error(EGL_SUCCESS); +} + +egl::Error PbufferSurfaceGLX::querySurfacePointerANGLE(EGLint attribute, void **value) +{ + UNIMPLEMENTED(); + return egl::Error(EGL_SUCCESS); +} + +egl::Error PbufferSurfaceGLX::bindTexImage(gl::Texture *texture, EGLint buffer) +{ + UNIMPLEMENTED(); + return egl::Error(EGL_SUCCESS); +} + +egl::Error PbufferSurfaceGLX::releaseTexImage(EGLint buffer) +{ + UNIMPLEMENTED(); + return egl::Error(EGL_SUCCESS); +} + +void PbufferSurfaceGLX::setSwapInterval(EGLint interval) +{ +} + +EGLint PbufferSurfaceGLX::getWidth() const +{ + return mWidth; +} + +EGLint PbufferSurfaceGLX::getHeight() const +{ + return mHeight; +} + +EGLint PbufferSurfaceGLX::isPostSubBufferSupported() const +{ + UNIMPLEMENTED(); + return EGL_FALSE; +} + +EGLint PbufferSurfaceGLX::getSwapBehavior() const +{ + return EGL_BUFFER_PRESERVED; +} + +egl::Error PbufferSurfaceGLX::checkForResize() +{ + // The size of pbuffers never change + return egl::Error(EGL_SUCCESS); +} +} diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/glx/PbufferSurfaceGLX.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/glx/PbufferSurfaceGLX.h new file mode 100644 index 000000000000..67fb50a31856 --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/glx/PbufferSurfaceGLX.h @@ -0,0 +1,63 @@ +// +// Copyright (c) 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. +// + +// PBufferSurfaceGLX.h: GLX implementation of egl::Surface for PBuffers + +#ifndef LIBANGLE_RENDERER_GL_GLX_PBUFFERSURFACEGLX_H_ +#define LIBANGLE_RENDERER_GL_GLX_PBUFFERSURFACEGLX_H_ + +#include "libANGLE/renderer/gl/glx/platform_glx.h" +#include "libANGLE/renderer/gl/glx/SurfaceGLX.h" + +namespace rx +{ + +class FunctionsGLX; + +class PbufferSurfaceGLX : public SurfaceGLX +{ + public: + PbufferSurfaceGLX(RendererGL *renderer, + EGLint width, + EGLint height, + bool largest, + const FunctionsGLX &glx, + glx::Context context, + glx::FBConfig fbConfig); + ~PbufferSurfaceGLX() override; + + egl::Error initialize() override; + egl::Error makeCurrent() override; + + egl::Error swap() override; + egl::Error postSubBuffer(EGLint x, EGLint y, EGLint width, EGLint height) override; + egl::Error querySurfacePointerANGLE(EGLint attribute, void **value) override; + egl::Error bindTexImage(gl::Texture *texture, EGLint buffer) override; + egl::Error releaseTexImage(EGLint buffer) override; + void setSwapInterval(EGLint interval) override; + + EGLint getWidth() const override; + EGLint getHeight() const override; + + EGLint isPostSubBufferSupported() const override; + EGLint getSwapBehavior() const override; + + egl::Error checkForResize() override; + + private: + unsigned mWidth; + unsigned mHeight; + bool mLargest; + + const FunctionsGLX &mGLX; + glx::Context mContext; + glx::FBConfig mFBConfig; + glx::Pbuffer mPbuffer; +}; + +} + +#endif // LIBANGLE_RENDERER_GL_GLX_PBUFFERSURFACEGLX_H_ diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/glx/SurfaceGLX.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/glx/SurfaceGLX.h new file mode 100644 index 000000000000..cccc01e50378 --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/glx/SurfaceGLX.h @@ -0,0 +1,26 @@ +// +// Copyright (c) 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. +// + +// SurfaceGLX.h: common interface for GLX surfaces + +#ifndef LIBANGLE_RENDERER_GL_GLX_SURFACEGLX_H_ +#define LIBANGLE_RENDERER_GL_GLX_SURFACEGLX_H_ + +#include "libANGLE/renderer/gl/SurfaceGL.h" + +namespace rx +{ + +class SurfaceGLX : public SurfaceGL +{ + public: + SurfaceGLX(RendererGL *renderer) : SurfaceGL(renderer) {} + + virtual egl::Error checkForResize() = 0; +}; +} + +#endif // LIBANGLE_RENDERER_GL_GLX_SURFACEGLX_H_ diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/glx/WindowSurfaceGLX.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/glx/WindowSurfaceGLX.cpp new file mode 100644 index 000000000000..0ef6aa6b9cd6 --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/glx/WindowSurfaceGLX.cpp @@ -0,0 +1,243 @@ +// +// Copyright (c) 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. +// + +// WindowSurfaceGLX.cpp: GLX implementation of egl::Surface for windows + +#include "libANGLE/renderer/gl/glx/WindowSurfaceGLX.h" + +#include "common/debug.h" + +#include "libANGLE/renderer/gl/glx/DisplayGLX.h" +#include "libANGLE/renderer/gl/glx/FunctionsGLX.h" + +namespace rx +{ + +static int IgnoreX11Errors(Display *, XErrorEvent *) +{ + return 0; +} + +WindowSurfaceGLX::WindowSurfaceGLX(const FunctionsGLX &glx, + DisplayGLX *glxDisplay, + RendererGL *renderer, + Window window, + Display *display, + glx::Context context, + glx::FBConfig fbConfig) + : SurfaceGLX(renderer), + mParent(window), + mWindow(0), + mDisplay(display), + mGLX(glx), + mGLXDisplay(glxDisplay), + mContext(context), + mFBConfig(fbConfig), + mGLXWindow(0) +{ +} + +WindowSurfaceGLX::~WindowSurfaceGLX() +{ + if (mGLXWindow) + { + mGLX.destroyWindow(mGLXWindow); + } + + if (mWindow) + { + // When destroying the window, it may happen that the window has already been + // destroyed by the application (this happens in Chromium). There is no way to + // atomically check that a window exists and to destroy it so instead we call + // XDestroyWindow, ignoring any errors. + auto oldErrorHandler = XSetErrorHandler(IgnoreX11Errors); + XDestroyWindow(mDisplay, mWindow); + XSync(mDisplay, False); + XSetErrorHandler(oldErrorHandler); + } + + mGLXDisplay->syncXCommands(); +} + +egl::Error WindowSurfaceGLX::initialize() +{ + // Check that the window's visual ID is valid, as part of the AMGLE_x11_visual + // extension. + { + XWindowAttributes windowAttributes; + XGetWindowAttributes(mDisplay, mParent, &windowAttributes); + unsigned long visualId = windowAttributes.visual->visualid; + + if (!mGLXDisplay->isValidWindowVisualId(visualId)) + { + return egl::Error(EGL_BAD_MATCH, + "The visual of native_window doesn't match the visual given with " + "ANGLE_X11_VISUAL_ID"); + } + } + + // The visual of the X window, GLX window and GLX context must match, + // however we received a user-created window that can have any visual + // and wouldn't work with our GLX context. To work in all cases, we + // create a child window with the right visual that covers all of its + // parent. + XVisualInfo *visualInfo = mGLX.getVisualFromFBConfig(mFBConfig); + if (!visualInfo) + { + return egl::Error(EGL_BAD_NATIVE_WINDOW, "Failed to get the XVisualInfo for the child window."); + } + Visual* visual = visualInfo->visual; + + if (!getWindowDimensions(mParent, &mParentWidth, &mParentHeight)) + { + return egl::Error(EGL_BAD_NATIVE_WINDOW, "Failed to get the parent window's dimensions."); + } + + // The depth, colormap and visual must match otherwise we get a X error + // so we specify the colormap attribute. Also we do not want the window + // to be taken into account for input so we specify the event and + // do-not-propagate masks to 0 (the defaults). Finally we specify the + // border pixel attribute so that we can use a different visual depth + // than our parent (seems like X uses that as a condition to render + // the subwindow in a different buffer) + XSetWindowAttributes attributes; + unsigned long attributeMask = CWColormap | CWBorderPixel; + + Colormap colormap = XCreateColormap(mDisplay, mParent, visual, AllocNone); + if(!colormap) + { + XFree(visualInfo); + return egl::Error(EGL_BAD_NATIVE_WINDOW, "Failed to create the Colormap for the child window."); + } + attributes.colormap = colormap; + attributes.border_pixel = 0; + + //TODO(cwallez) set up our own error handler to see if the call failed + mWindow = XCreateWindow(mDisplay, mParent, 0, 0, mParentWidth, mParentHeight, + 0, visualInfo->depth, InputOutput, visual, attributeMask, &attributes); + mGLXWindow = mGLX.createWindow(mFBConfig, mWindow, nullptr); + + XMapWindow(mDisplay, mWindow); + XFlush(mDisplay); + + XFree(visualInfo); + XFreeColormap(mDisplay, colormap); + + mGLXDisplay->syncXCommands(); + + return egl::Error(EGL_SUCCESS); +} + +egl::Error WindowSurfaceGLX::makeCurrent() +{ + if (mGLX.makeCurrent(mGLXWindow, mContext) != True) + { + return egl::Error(EGL_BAD_DISPLAY); + } + return egl::Error(EGL_SUCCESS); +} + +egl::Error WindowSurfaceGLX::swap() +{ + // We need to swap before resizing as some drivers clobber the back buffer + // when the window is resized. + mGLXDisplay->setSwapInterval(mGLXWindow, &mSwapControl); + mGLX.swapBuffers(mGLXWindow); + + egl::Error error = checkForResize(); + if (error.isError()) + { + return error; + } + + return egl::Error(EGL_SUCCESS); +} + +egl::Error WindowSurfaceGLX::postSubBuffer(EGLint x, EGLint y, EGLint width, EGLint height) +{ + UNIMPLEMENTED(); + return egl::Error(EGL_SUCCESS); +} + +egl::Error WindowSurfaceGLX::querySurfacePointerANGLE(EGLint attribute, void **value) +{ + UNIMPLEMENTED(); + return egl::Error(EGL_SUCCESS); +} + +egl::Error WindowSurfaceGLX::bindTexImage(gl::Texture *texture, EGLint buffer) +{ + UNIMPLEMENTED(); + return egl::Error(EGL_SUCCESS); +} + +egl::Error WindowSurfaceGLX::releaseTexImage(EGLint buffer) +{ + UNIMPLEMENTED(); + return egl::Error(EGL_SUCCESS); +} + +void WindowSurfaceGLX::setSwapInterval(EGLint interval) +{ + mSwapControl.targetSwapInterval = interval; +} + +EGLint WindowSurfaceGLX::getWidth() const +{ + // The size of the window is always the same as the cached size of its parent. + return mParentWidth; +} + +EGLint WindowSurfaceGLX::getHeight() const +{ + // The size of the window is always the same as the cached size of its parent. + return mParentHeight; +} + +EGLint WindowSurfaceGLX::isPostSubBufferSupported() const +{ + UNIMPLEMENTED(); + return EGL_FALSE; +} + +EGLint WindowSurfaceGLX::getSwapBehavior() const +{ + return EGL_BUFFER_PRESERVED; +} + +egl::Error WindowSurfaceGLX::checkForResize() +{ + // TODO(cwallez) set up our own error handler to see if the call failed + unsigned int newParentWidth, newParentHeight; + if (!getWindowDimensions(mParent, &newParentWidth, &newParentHeight)) + { + return egl::Error(EGL_BAD_CURRENT_SURFACE, + "Failed to retrieve the size of the parent window."); + } + + if (mParentWidth != newParentWidth || mParentHeight != newParentHeight) + { + mParentWidth = newParentWidth; + mParentHeight = newParentHeight; + + mGLX.waitGL(); + XResizeWindow(mDisplay, mWindow, mParentWidth, mParentHeight); + mGLX.waitX(); + XSync(mDisplay, False); + } + + return egl::Error(EGL_SUCCESS); +} + +bool WindowSurfaceGLX::getWindowDimensions(Window window, unsigned int *width, unsigned int *height) const +{ + Window root; + int x, y; + unsigned int border, depth; + return XGetGeometry(mDisplay, window, &root, &x, &y, width, height, &border, &depth) != 0; +} + +} diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/glx/WindowSurfaceGLX.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/glx/WindowSurfaceGLX.h new file mode 100644 index 000000000000..6eaf308a6737 --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/glx/WindowSurfaceGLX.h @@ -0,0 +1,72 @@ +// +// Copyright (c) 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. +// + +// WindowSurfaceGLX.h: GLX implementation of egl::Surface for windows + +#ifndef LIBANGLE_RENDERER_GL_GLX_WINDOWSURFACEGLX_H_ +#define LIBANGLE_RENDERER_GL_GLX_WINDOWSURFACEGLX_H_ + +#include "libANGLE/renderer/gl/glx/DisplayGLX.h" +#include "libANGLE/renderer/gl/glx/platform_glx.h" +#include "libANGLE/renderer/gl/glx/SurfaceGLX.h" + +namespace rx +{ + +class DisplayGLX; +class FunctionsGLX; + +class WindowSurfaceGLX : public SurfaceGLX +{ + public: + WindowSurfaceGLX(const FunctionsGLX &glx, + DisplayGLX *glxDisplay, + RendererGL *renderer, + Window window, + Display *display, + glx::Context context, + glx::FBConfig fbConfig); + ~WindowSurfaceGLX() override; + + egl::Error initialize() override; + egl::Error makeCurrent() override; + + egl::Error swap() override; + egl::Error postSubBuffer(EGLint x, EGLint y, EGLint width, EGLint height) override; + egl::Error querySurfacePointerANGLE(EGLint attribute, void **value) override; + egl::Error bindTexImage(gl::Texture *texture, EGLint buffer) override; + egl::Error releaseTexImage(EGLint buffer) override; + void setSwapInterval(EGLint interval) override; + + EGLint getWidth() const override; + EGLint getHeight() const override; + + EGLint isPostSubBufferSupported() const override; + EGLint getSwapBehavior() const override; + + egl::Error checkForResize() override; + + private: + bool getWindowDimensions(Window window, unsigned int *width, unsigned int *height) const; + + Window mParent; + unsigned int mParentWidth, mParentHeight; + Window mWindow; + Display *mDisplay; + + const FunctionsGLX &mGLX; + DisplayGLX *mGLXDisplay; + + glx::Context mContext; + glx::FBConfig mFBConfig; + glx::Window mGLXWindow; + + SwapControlData mSwapControl; +}; + +} + +#endif // LIBANGLE_RENDERER_GL_GLX_WINDOWSURFACEGLX_H_ diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/glx/functionsglx_typedefs.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/glx/functionsglx_typedefs.h new file mode 100644 index 000000000000..b0ba033c78cd --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/glx/functionsglx_typedefs.h @@ -0,0 +1,52 @@ +// +// Copyright (c) 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. +// + +// functionsglx_typedefs.h: Typedefs of GLX functions. + +#ifndef LIBANGLE_RENDERER_GL_GLX_FUNCTIONSGLXTYPEDEFS_H_ +#define LIBANGLE_RENDERER_GL_GLX_FUNCTIONSGLXTYPEDEFS_H_ + +#include "libANGLE/renderer/gl/glx/platform_glx.h" + +namespace rx +{ + +// Only the functions of GLX 1.2 and earlier need to be typdefed; the other +// functions are already typedefed in glx.h + +// GLX 1.0 +typedef XVisualInfo *(*PFNGLXCHOOSEVISUALPROC) (Display *dpy, int screen, int *attribList); +typedef GLXContext (*PFNGLXCREATECONTEXTPROC) (Display *dpy, XVisualInfo *vis, GLXContext shareList, Bool direct); +typedef void (*PFNGLXDESTROYCONTEXTPROC) (Display *dpy, GLXContext ctx); +typedef Bool (*PFNGLXMAKECURRENTPROC) (Display *dpy, GLXDrawable drawable, GLXContext ctx); +typedef void (*PFNGLXCOPYCONTEXTPROC) (Display *dpy, GLXContext src, GLXContext dst, unsigned long mask); +typedef void (*PFNGLXSWAPBUFFERSPROC) (Display *dpy, GLXDrawable drawable); +typedef GLXPixmap (*PFNGLXCREATEGLXPIXMAPPROC) (Display *dpy, XVisualInfo *visual, Pixmap pixmap); +typedef void (*PFNGLXDESTROYGLXPIXMAPPROC) (Display *dpy, GLXPixmap pixmap); +typedef Bool (*PFNGLXQUERYEXTENSIONPROC) (Display *dpy, int *errorb, int *event); +typedef Bool (*PFNGLXQUERYVERSIONPROC) (Display *dpy, int *maj, int *min); +typedef Bool (*PFNGLXISDIRECTPROC) (Display *dpy, GLXContext ctx); +typedef int (*PFNGLXGETCONFIGPROC) (Display *dpy, XVisualInfo *visual, int attrib, int *value); +typedef GLXContext (*PFNGLXGETCURRENTCONTEXTPROC) (); +typedef GLXDrawable (*PFNGLXGETCURRENTDRAWABLEPROC) (); +typedef GLXContext (*PFNGLXGETCURRENTCONTEXTPROC) (); +typedef GLXDrawable (*PFNGLXGETCURRENTDRAWABLEPROC) (); +typedef void (*PFNGLXWAITGLPROC) (); +typedef void (*PFNGLXWAITXPROC) (); +typedef void (*PFNGLXUSEXFONT) (Font font, int first, int count, int list); + +// GLX 1.1 +typedef const char *(*PFNGLXQUERYEXTENSIONSSTRINGPROC) (Display *dpy, int screen); +typedef const char *(*PFNGLXQUERYSERVERSTRINGPROC) (Display *dpy, int screen, int name); +typedef const char *(*PFNGLXGETCLIENTSTRINGPROC) (Display *dpy, int name); + + +// GLX 1.2 +typedef Display *(*PFNGLXGETCURRENTDISPLAYPROC) (); + +} + +#endif // LIBANGLE_RENDERER_GL_GLX_FUNCTIONSGLXTYPEDEFS_H_ diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/glx/platform_glx.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/glx/platform_glx.h new file mode 100644 index 000000000000..ee3a7ac551f3 --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/glx/platform_glx.h @@ -0,0 +1,184 @@ +// +// Copyright (c) 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_glx.h: Includes specific to GLX. + +#ifndef LIBANGLE_RENDERER_GL_GLX_PLATFORMGLX_H_ +#define LIBANGLE_RENDERER_GL_GLX_PLATFORMGLX_H_ + +#if !defined(ANGLE_SKIP_GLX_DEFINES) +// GLX 1.0 +#define GLX_USE_GL 1 +#define GLX_BUFFER_SIZE 2 +#define GLX_LEVEL 3 +#define GLX_RGBA 4 +#define GLX_DOUBLEBUFFER 5 +#define GLX_STEREO 6 +#define GLX_AUX_BUFFERS 7 +#define GLX_RED_SIZE 8 +#define GLX_GREEN_SIZE 9 +#define GLX_BLUE_SIZE 10 +#define GLX_ALPHA_SIZE 11 +#define GLX_DEPTH_SIZE 12 +#define GLX_STENCIL_SIZE 13 +#define GLX_ACCUM_RED_SIZE 14 +#define GLX_ACCUM_GREEN_SIZE 15 +#define GLX_ACCUM_BLUE_SIZE 16 +#define GLX_ACCUM_ALPHA_SIZE 17 + +#define GLX_BAD_SCREEN 1 +#define GLX_BAD_ATTRIBUTE 2 +#define GLX_NO_EXTENSION 3 +#define GLX_BAD_VISUAL 4 +#define GLX_BAD_CONTEXT 5 +#define GLX_BAD_VALUE 6 +#define GLX_BAD_ENUM 7 + +// GLX 1.1 +#define GLX_VENDOR 1 +#define GLX_VERSION 2 +#define GLX_EXTENSIONS 3 + +// GLX 1.3 +#define GLX_CONFIG_CAVEAT 0x20 +#define GLX_DONT_CARE 0xFFFFFFFF +#define GLX_X_VISUAL_TYPE 0x22 +#define GLX_TRANSPARENT_TYPE 0x23 +#define GLX_TRANSPARENT_INDEX_VALUE 0x24 +#define GLX_TRANSPARENT_RED_VALUE 0x25 +#define GLX_TRANSPARENT_GREEN_VALUE 0x26 +#define GLX_TRANSPARENT_BLUE_VALUE 0x27 +#define GLX_TRANSPARENT_ALPHA_VALUE 0x28 +#define GLX_WINDOW_BIT 0x00000001 +#define GLX_PIXMAP_BIT 0x00000002 +#define GLX_PBUFFER_BIT 0x00000004 +#define GLX_AUX_BUFFERS_BIT 0x00000010 +#define GLX_FRONT_LEFT_BUFFER_BIT 0x00000001 +#define GLX_FRONT_RIGHT_BUFFER_BIT 0x00000002 +#define GLX_BACK_LEFT_BUFFER_BIT 0x00000004 +#define GLX_BACK_RIGHT_BUFFER_BIT 0x00000008 +#define GLX_DEPTH_BUFFER_BIT 0x00000020 +#define GLX_STENCIL_BUFFER_BIT 0x00000040 +#define GLX_ACCUM_BUFFER_BIT 0x00000080 +#define GLX_NONE 0x8000 +#define GLX_SLOW_CONFIG 0x8001 +#define GLX_TRUE_COLOR 0x8002 +#define GLX_DIRECT_COLOR 0x8003 +#define GLX_PSEUDO_COLOR 0x8004 +#define GLX_STATIC_COLOR 0x8005 +#define GLX_GRAY_SCALE 0x8006 +#define GLX_STATIC_GRAY 0x8007 +#define GLX_TRANSPARENT_RGB 0x8008 +#define GLX_TRANSPARENT_INDEX 0x8009 +#define GLX_VISUAL_ID 0x800B +#define GLX_SCREEN 0x800C +#define GLX_NON_CONFORMANT_CONFIG 0x800D +#define GLX_DRAWABLE_TYPE 0x8010 +#define GLX_RENDER_TYPE 0x8011 +#define GLX_X_RENDERABLE 0x8012 +#define GLX_FBCONFIG_ID 0x8013 +#define GLX_RGBA_TYPE 0x8014 +#define GLX_COLOR_INDEX_TYPE 0x8015 +#define GLX_MAX_PBUFFER_WIDTH 0x8016 +#define GLX_MAX_PBUFFER_HEIGHT 0x8017 +#define GLX_MAX_PBUFFER_PIXELS 0x8018 +#define GLX_PRESERVED_CONTENTS 0x801B +#define GLX_LARGEST_PBUFFER 0x801C +#define GLX_WIDTH 0x801D +#define GLX_HEIGHT 0x801E +#define GLX_EVENT_MASK 0x801F +#define GLX_DAMAGED 0x8020 +#define GLX_SAVED 0x8021 +#define GLX_WINDOW 0x8022 +#define GLX_PBUFFER 0x8023 +#define GLX_PBUFFER_HEIGHT 0x8040 +#define GLX_PBUFFER_WIDTH 0x8041 +#define GLX_RGBA_BIT 0x00000001 +#define GLX_COLOR_INDEX_BIT 0x00000002 +#define GLX_PBUFFER_CLOBBER_MASK 0x08000000 + +// GLX 1.4 +#define GLX_SAMPLE_BUFFERS 0x186a0 +#define GLX_SAMPLES 0x186a1 + +// GLX_ARB_create_context +#define GLX_CONTEXT_DEBUG_BIT_ARB 0x00000001 +#define GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x00000002 +#define GLX_CONTEXT_MAJOR_VERSION_ARB 0x2091 +#define GLX_CONTEXT_MINOR_VERSION_ARB 0x2092 +#define GLX_CONTEXT_FLAGS_ARB 0x2094 + +// GLX_ARB_create_context_profile +#define GLX_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001 +#define GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002 +#define GLX_CONTEXT_PROFILE_MASK_ARB 0x9126 + +// GLX_EXT_create_context_es2_profile +#define GLX_CONTEXT_ES2_PROFILE_BIT_EXT 0x00000004 + +// GLX_EXT_texture_from_pixmap +#define GLX_TEXTURE_1D_BIT_EXT 0x00000001 +#define GLX_TEXTURE_2D_BIT_EXT 0x00000002 +#define GLX_TEXTURE_RECTANGLE_BIT_EXT 0x00000004 +#define GLX_BIND_TO_TEXTURE_RGB_EXT 0x20D0 +#define GLX_BIND_TO_TEXTURE_RGBA_EXT 0x20D1 +#define GLX_BIND_TO_MIPMAP_TEXTURE_EXT 0x20D2 +#define GLX_BIND_TO_TEXTURE_TARGETS_EXT 0x20D3 +#define GLX_Y_INVERTED_EXT 0x20D4 +#define GLX_TEXTURE_FORMAT_EXT 0x20D5 +#define GLX_TEXTURE_TARGET_EXT 0x20D6 +#define GLX_MIPMAP_TEXTURE_EXT 0x20D7 +#define GLX_TEXTURE_FORMAT_NONE_EXT 0x20D8 +#define GLX_TEXTURE_FORMAT_RGB_EXT 0x20D9 +#define GLX_TEXTURE_FORMAT_RGBA_EXT 0x20DA +#define GLX_TEXTURE_1D_EXT 0x20DB +#define GLX_TEXTURE_2D_EXT 0x20DC +#define GLX_TEXTURE_RECTANGLE_EXT 0x20DD +#define GLX_FRONT_LEFT_EXT 0x20DE +#define GLX_FRONT_RIGHT_EXT 0x20DF +#define GLX_BACK_LEFT_EXT 0x20E0 +#define GLX_BACK_RIGHT_EXT 0x20E1 +#define GLX_FRONT_EXT 0x20DE +#define GLX_BACK_EXT 0x20E0 +#define GLX_AUX0_EXT 0x20E2 +#define GLX_AUX1_EXT 0x20E3 +#define GLX_AUX2_EXT 0x20E4 +#define GLX_AUX3_EXT 0x20E5 +#define GLX_AUX4_EXT 0x20E6 +#define GLX_AUX5_EXT 0x20E7 +#define GLX_AUX6_EXT 0x20E8 +#define GLX_AUX7_EXT 0x20E9 +#define GLX_AUX8_EXT 0x20EA +#define GLX_AUX9_EXT 0x20EB + +// GLX_EXT_swap_control +#define GLX_SWAP_INTERVAL_EXT 0x20F1 +#define GLX_MAX_SWAP_INTERVAL_EXT 0x20F2 +#endif // !defined(ANGLE_SKIP_GLX_DEFINES) + +// GLX typedefs depend on the X headers +#include +#include +#include + +// GLX typedefs +namespace glx +{ + +typedef void *Context; +typedef void *FBConfig; +typedef XID FBConfigID; +typedef XID ContextID; +typedef XID Window; +typedef XID Pbuffer; +typedef XID Pixmap; +typedef XID Drawable; + +} + +typedef void* (*PFNGETPROCPROC) (const char *name); + +#endif // LIBANGLE_RENDERER_GL_GLX_PLATFORMGLX_H_ diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/renderergl_utils.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/renderergl_utils.cpp index f395ff4c8d8e..ea75bd47729f 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/renderergl_utils.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/renderergl_utils.cpp @@ -4,7 +4,7 @@ // found in the LICENSE file. // -// renderer11_utils.cpp: Conversion functions and other utility routines +// renderergl_utils.cpp: Conversion functions and other utility routines // specific to the OpenGL renderer. #include "libANGLE/renderer/gl/renderergl_utils.h" @@ -14,24 +14,78 @@ #include "libANGLE/Caps.h" #include "libANGLE/formatutils.h" #include "libANGLE/renderer/gl/FunctionsGL.h" +#include "libANGLE/renderer/gl/WorkaroundsGL.h" #include "libANGLE/renderer/gl/formatutilsgl.h" #include +#include namespace rx { +VendorID GetVendorID(const FunctionsGL *functions) +{ + std::string nativeVendorString(reinterpret_cast(functions->getString(GL_VENDOR))); + if (nativeVendorString.find("Intel") != std::string::npos) + { + return VENDOR_ID_INTEL; + } + else if (nativeVendorString.find("NVIDIA") != std::string::npos) + { + return VENDOR_ID_NVIDIA; + } + else if (nativeVendorString.find("ATI") != std::string::npos || + nativeVendorString.find("AMD") != std::string::npos) + { + return VENDOR_ID_AMD; + } + else + { + return VENDOR_ID_UNKNOWN; + } +} namespace nativegl_gl { +static bool MeetsRequirements(const FunctionsGL *functions, const nativegl::SupportRequirement &requirements) +{ + for (const std::string &extension : requirements.requiredExtensions) + { + if (!functions->hasExtension(extension)) + { + return false; + } + } + + if (functions->version >= requirements.version) + { + return true; + } + else if (!requirements.versionExtensions.empty()) + { + for (const std::string &extension : requirements.versionExtensions) + { + if (!functions->hasExtension(extension)) + { + return false; + } + } + return true; + } + else + { + return false; + } +} + static gl::TextureCaps GenerateTextureFormatCaps(const FunctionsGL *functions, GLenum internalFormat) { gl::TextureCaps textureCaps; - const nativegl::InternalFormat &formatInfo = nativegl::GetInternalFormatInfo(internalFormat); - textureCaps.texturable = formatInfo.textureSupport(functions->majorVersion, functions->minorVersion, functions->extensions); - textureCaps.renderable = formatInfo.renderSupport(functions->majorVersion, functions->minorVersion, functions->extensions); - textureCaps.filterable = formatInfo.filterSupport(functions->majorVersion, functions->minorVersion, functions->extensions); + const nativegl::InternalFormat &formatInfo = nativegl::GetInternalFormatInfo(internalFormat, functions->standard); + textureCaps.texturable = MeetsRequirements(functions, formatInfo.texture); + textureCaps.filterable = textureCaps.texturable && MeetsRequirements(functions, formatInfo.filter); + textureCaps.renderable = MeetsRequirements(functions, formatInfo.framebufferAttachment); // glGetInternalformativ is not available until version 4.2 but may be available through the 3.0 // extension GL_ARB_internalformat_query @@ -43,7 +97,8 @@ static gl::TextureCaps GenerateTextureFormatCaps(const FunctionsGL *functions, G if (numSamples > 0) { std::vector samples(numSamples); - functions->getInternalformativ(GL_RENDERBUFFER, internalFormat, GL_SAMPLES, samples.size(), &samples[0]); + functions->getInternalformativ(GL_RENDERBUFFER, internalFormat, GL_SAMPLES, + static_cast(samples.size()), &samples[0]); for (size_t sampleIndex = 0; sampleIndex < samples.size(); sampleIndex++) { textureCaps.sampleCounts.insert(samples[sampleIndex]); @@ -56,13 +111,63 @@ static gl::TextureCaps GenerateTextureFormatCaps(const FunctionsGL *functions, G static GLint QuerySingleGLInt(const FunctionsGL *functions, GLenum name) { - GLint result; + GLint result = 0; functions->getIntegerv(name, &result); return result; } +static GLint QueryGLIntRange(const FunctionsGL *functions, GLenum name, size_t index) +{ + GLint result[2] = {}; + functions->getIntegerv(name, result); + return result[index]; +} + +static GLint64 QuerySingleGLInt64(const FunctionsGL *functions, GLenum name) +{ + GLint64 result = 0; + functions->getInteger64v(name, &result); + return result; +} + +static GLfloat QuerySingleGLFloat(const FunctionsGL *functions, GLenum name) +{ + GLfloat result = 0.0f; + functions->getFloatv(name, &result); + return result; +} + +static GLfloat QueryGLFloatRange(const FunctionsGL *functions, GLenum name, size_t index) +{ + GLfloat result[2] = {}; + functions->getFloatv(name, result); + return result[index]; +} + +static gl::TypePrecision QueryTypePrecision(const FunctionsGL *functions, GLenum shaderType, GLenum precisionType) +{ + gl::TypePrecision precision; + functions->getShaderPrecisionFormat(shaderType, precisionType, precision.range, &precision.precision); + return precision; +} + +static GLint QueryQueryValue(const FunctionsGL *functions, GLenum target, GLenum name) +{ + GLint result; + functions->getQueryiv(target, name, &result); + return result; +} + +static void LimitVersion(gl::Version *curVersion, const gl::Version &maxVersion) +{ + if (*curVersion >= maxVersion) + { + *curVersion = maxVersion; + } +} + void GenerateCaps(const FunctionsGL *functions, gl::Caps *caps, gl::TextureCapsMap *textureCapsMap, - gl::Extensions *extensions) + gl::Extensions *extensions, gl::Version *maxSupportedESVersion) { // Texture format support checks const gl::FormatSet &allFormats = gl::GetAllSizedInternalFormats(); @@ -77,87 +182,546 @@ void GenerateCaps(const FunctionsGL *functions, gl::Caps *caps, gl::TextureCapsM } } - // Set some minimum GLES2 caps, TODO: query for real GL caps + // Start by assuming ES3 support and work down + *maxSupportedESVersion = gl::Version(3, 0); // Table 6.28, implementation dependent values - caps->maxElementIndex = static_cast(std::numeric_limits::max()); - caps->max3DTextureSize = QuerySingleGLInt(functions, GL_MAX_3D_TEXTURE_SIZE); - caps->max2DTextureSize = QuerySingleGLInt(functions, GL_MAX_TEXTURE_SIZE); - caps->maxCubeMapTextureSize = QuerySingleGLInt(functions, GL_MAX_CUBE_MAP_TEXTURE_SIZE); - caps->maxArrayTextureLayers = QuerySingleGLInt(functions, GL_MAX_ARRAY_TEXTURE_LAYERS); - caps->maxLODBias = 2.0f; - caps->maxRenderbufferSize = QuerySingleGLInt(functions, GL_MAX_RENDERBUFFER_SIZE); - caps->maxDrawBuffers = QuerySingleGLInt(functions, GL_MAX_DRAW_BUFFERS); - caps->maxColorAttachments = QuerySingleGLInt(functions, GL_MAX_COLOR_ATTACHMENTS); - caps->maxViewportWidth = caps->max2DTextureSize; - caps->maxViewportHeight = caps->maxViewportWidth; - caps->minAliasedPointSize = 1.0f; - caps->maxAliasedPointSize = 1.0f; - caps->minAliasedLineWidth = 1.0f; - caps->maxAliasedLineWidth = 1.0f; + if (functions->isAtLeastGL(gl::Version(4, 3)) || functions->hasGLExtension("GL_ARB_ES3_compatibility") || + functions->isAtLeastGLES(gl::Version(3, 0))) + { + caps->maxElementIndex = QuerySingleGLInt64(functions, GL_MAX_ELEMENT_INDEX); + } + else + { + // Doesn't affect ES3 support, can use a pre-defined limit + caps->maxElementIndex = static_cast(std::numeric_limits::max()); + } + + if (functions->isAtLeastGL(gl::Version(1, 2)) || + functions->isAtLeastGLES(gl::Version(3, 0)) || functions->hasGLESExtension("GL_OES_texture_3D")) + { + caps->max3DTextureSize = QuerySingleGLInt(functions, GL_MAX_3D_TEXTURE_SIZE); + } + else + { + // Can't support ES3 without 3D textures + LimitVersion(maxSupportedESVersion, gl::Version(2, 0)); + } + + caps->max2DTextureSize = QuerySingleGLInt(functions, GL_MAX_TEXTURE_SIZE); // GL 1.0 / ES 2.0 + caps->maxCubeMapTextureSize = QuerySingleGLInt(functions, GL_MAX_CUBE_MAP_TEXTURE_SIZE); // GL 1.3 / ES 2.0 + + if (functions->isAtLeastGL(gl::Version(3, 0)) || functions->hasGLExtension("GL_EXT_texture_array") || + functions->isAtLeastGLES(gl::Version(3, 0))) + { + caps->maxArrayTextureLayers = QuerySingleGLInt(functions, GL_MAX_ARRAY_TEXTURE_LAYERS); + } + else + { + // Can't support ES3 without array textures + LimitVersion(maxSupportedESVersion, gl::Version(2, 0)); + } + + if (functions->isAtLeastGL(gl::Version(1, 5)) || functions->hasGLExtension("GL_EXT_texture_lod_bias") || + functions->isAtLeastGLES(gl::Version(3, 0))) + { + caps->maxLODBias = QuerySingleGLFloat(functions, GL_MAX_TEXTURE_LOD_BIAS); + } + else + { + LimitVersion(maxSupportedESVersion, gl::Version(2, 0)); + } + + if (functions->isAtLeastGL(gl::Version(3, 0)) || functions->hasGLExtension("GL_EXT_framebuffer_object") || + functions->isAtLeastGLES(gl::Version(2, 0))) + { + caps->maxRenderbufferSize = QuerySingleGLInt(functions, GL_MAX_RENDERBUFFER_SIZE); + caps->maxColorAttachments = QuerySingleGLInt(functions, GL_MAX_COLOR_ATTACHMENTS); + } + else + { + // Can't support ES2 without framebuffers and renderbuffers + LimitVersion(maxSupportedESVersion, gl::Version(0, 0)); + } + + if (functions->isAtLeastGL(gl::Version(2, 0)) || functions->hasGLExtension("ARB_draw_buffers") || + functions->isAtLeastGLES(gl::Version(3, 0)) || functions->hasGLESExtension("GL_EXT_draw_buffers")) + { + caps->maxDrawBuffers = QuerySingleGLInt(functions, GL_MAX_DRAW_BUFFERS); + } + else + { + // Framebuffer is required to have at least one drawbuffer even if the extension is not + // supported + caps->maxDrawBuffers = 1; + LimitVersion(maxSupportedESVersion, gl::Version(2, 0)); + } + + caps->maxViewportWidth = QueryGLIntRange(functions, GL_MAX_VIEWPORT_DIMS, 0); // GL 1.0 / ES 2.0 + caps->maxViewportHeight = QueryGLIntRange(functions, GL_MAX_VIEWPORT_DIMS, 1); // GL 1.0 / ES 2.0 + + if (functions->standard == STANDARD_GL_DESKTOP && + (functions->profile & GL_CONTEXT_CORE_PROFILE_BIT) != 0) + { + // Desktop GL core profile deprecated the GL_ALIASED_POINT_SIZE_RANGE query. Use + // GL_POINT_SIZE_RANGE instead. + caps->minAliasedPointSize = QueryGLFloatRange(functions, GL_POINT_SIZE_RANGE, 0); + caps->maxAliasedPointSize = QueryGLFloatRange(functions, GL_POINT_SIZE_RANGE, 1); + } + else + { + caps->minAliasedPointSize = QueryGLFloatRange(functions, GL_ALIASED_POINT_SIZE_RANGE, 0); + caps->maxAliasedPointSize = QueryGLFloatRange(functions, GL_ALIASED_POINT_SIZE_RANGE, 1); + } + + caps->minAliasedLineWidth = QueryGLFloatRange(functions, GL_ALIASED_LINE_WIDTH_RANGE, 0); // GL 1.2 / ES 2.0 + caps->maxAliasedLineWidth = QueryGLFloatRange(functions, GL_ALIASED_LINE_WIDTH_RANGE, 1); // GL 1.2 / ES 2.0 // Table 6.29, implementation dependent values (cont.) - caps->maxElementsIndices = 0; - caps->maxElementsVertices = 0; - caps->vertexHighpFloat.setIEEEFloat(); - caps->vertexMediumpFloat.setIEEEFloat(); - caps->vertexLowpFloat.setIEEEFloat(); - caps->fragmentHighpFloat.setIEEEFloat(); - caps->fragmentMediumpFloat.setIEEEFloat(); - caps->fragmentLowpFloat.setIEEEFloat(); - caps->vertexHighpInt.setTwosComplementInt(32); - caps->vertexMediumpInt.setTwosComplementInt(32); - caps->vertexLowpInt.setTwosComplementInt(32); - caps->fragmentHighpInt.setTwosComplementInt(32); - caps->fragmentMediumpInt.setTwosComplementInt(32); - caps->fragmentLowpInt.setTwosComplementInt(32); - caps->maxServerWaitTimeout = 0; + if (functions->isAtLeastGL(gl::Version(1, 2)) || + functions->isAtLeastGLES(gl::Version(3, 0))) + { + caps->maxElementsIndices = QuerySingleGLInt(functions, GL_MAX_ELEMENTS_INDICES); + caps->maxElementsVertices = QuerySingleGLInt(functions, GL_MAX_ELEMENTS_VERTICES); + } + else + { + // Doesn't impact supported version + } + + // glGetShaderPrecisionFormat is not available until desktop GL version 4.1 or GL_ARB_ES2_compatibility exists + if (functions->isAtLeastGL(gl::Version(4, 1)) || functions->hasGLExtension("GL_ARB_ES2_compatibility") || + functions->isAtLeastGLES(gl::Version(2, 0))) + { + caps->vertexHighpFloat = QueryTypePrecision(functions, GL_VERTEX_SHADER, GL_HIGH_FLOAT); + caps->vertexMediumpFloat = QueryTypePrecision(functions, GL_VERTEX_SHADER, GL_MEDIUM_FLOAT); + caps->vertexLowpFloat = QueryTypePrecision(functions, GL_VERTEX_SHADER, GL_LOW_FLOAT); + caps->fragmentHighpFloat = QueryTypePrecision(functions, GL_FRAGMENT_SHADER, GL_HIGH_FLOAT); + caps->fragmentMediumpFloat = QueryTypePrecision(functions, GL_FRAGMENT_SHADER, GL_MEDIUM_FLOAT); + caps->fragmentLowpFloat = QueryTypePrecision(functions, GL_FRAGMENT_SHADER, GL_LOW_FLOAT); + caps->vertexHighpInt = QueryTypePrecision(functions, GL_VERTEX_SHADER, GL_HIGH_INT); + caps->vertexMediumpInt = QueryTypePrecision(functions, GL_VERTEX_SHADER, GL_MEDIUM_INT); + caps->vertexLowpInt = QueryTypePrecision(functions, GL_VERTEX_SHADER, GL_LOW_INT); + caps->fragmentHighpInt = QueryTypePrecision(functions, GL_FRAGMENT_SHADER, GL_HIGH_INT); + caps->fragmentMediumpInt = QueryTypePrecision(functions, GL_FRAGMENT_SHADER, GL_MEDIUM_INT); + caps->fragmentLowpInt = QueryTypePrecision(functions, GL_FRAGMENT_SHADER, GL_LOW_INT); + } + else + { + // Doesn't impact supported version, set some default values + caps->vertexHighpFloat.setIEEEFloat(); + caps->vertexMediumpFloat.setIEEEFloat(); + caps->vertexLowpFloat.setIEEEFloat(); + caps->fragmentHighpFloat.setIEEEFloat(); + caps->fragmentMediumpFloat.setIEEEFloat(); + caps->fragmentLowpFloat.setIEEEFloat(); + caps->vertexHighpInt.setTwosComplementInt(32); + caps->vertexMediumpInt.setTwosComplementInt(32); + caps->vertexLowpInt.setTwosComplementInt(32); + caps->fragmentHighpInt.setTwosComplementInt(32); + caps->fragmentMediumpInt.setTwosComplementInt(32); + caps->fragmentLowpInt.setTwosComplementInt(32); + } + + if (functions->isAtLeastGL(gl::Version(3, 2)) || functions->hasGLExtension("GL_ARB_sync") || + functions->isAtLeastGLES(gl::Version(3, 0))) + { + caps->maxServerWaitTimeout = QuerySingleGLInt64(functions, GL_MAX_SERVER_WAIT_TIMEOUT); + } + else + { + LimitVersion(maxSupportedESVersion, gl::Version(2, 0)); + } // Table 6.31, implementation dependent vertex shader limits - caps->maxVertexAttributes = 16; - caps->maxVertexUniformComponents = 1024; - caps->maxVertexUniformVectors = 256; - caps->maxVertexUniformBlocks = 12; - caps->maxVertexOutputComponents = 64; - caps->maxVertexTextureImageUnits = QuerySingleGLInt(functions, GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS); + if (functions->isAtLeastGL(gl::Version(2, 0)) || + functions->isAtLeastGLES(gl::Version(2, 0))) + { + caps->maxVertexAttributes = QuerySingleGLInt(functions, GL_MAX_VERTEX_ATTRIBS); + caps->maxVertexUniformComponents = QuerySingleGLInt(functions, GL_MAX_VERTEX_UNIFORM_COMPONENTS); + caps->maxVertexTextureImageUnits = QuerySingleGLInt(functions, GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS); + } + else + { + // Can't support ES2 version without these caps + LimitVersion(maxSupportedESVersion, gl::Version(0, 0)); + } + + if (functions->isAtLeastGL(gl::Version(4, 1)) || functions->hasGLExtension("GL_ARB_ES2_compatibility") || + functions->isAtLeastGLES(gl::Version(2, 0))) + { + caps->maxVertexUniformVectors = QuerySingleGLInt(functions, GL_MAX_VERTEX_UNIFORM_VECTORS); + } + else + { + // Doesn't limit ES version, GL_MAX_VERTEX_UNIFORM_COMPONENTS / 4 is acceptable. + caps->maxVertexUniformVectors = caps->maxVertexUniformComponents / 4; + } + + if (functions->isAtLeastGL(gl::Version(3, 1)) || functions->hasGLExtension("GL_ARB_uniform_buffer_object") || + functions->isAtLeastGLES(gl::Version(3, 0))) + { + caps->maxVertexUniformBlocks = QuerySingleGLInt(functions, GL_MAX_VERTEX_UNIFORM_BLOCKS); + } + else + { + // Can't support ES3 without uniform blocks + LimitVersion(maxSupportedESVersion, gl::Version(2, 0)); + } + + if (functions->isAtLeastGL(gl::Version(3, 2)) || + functions->isAtLeastGLES(gl::Version(3, 0))) + { + caps->maxVertexOutputComponents = QuerySingleGLInt(functions, GL_MAX_VERTEX_OUTPUT_COMPONENTS); + } + else + { + // There doesn't seem, to be a desktop extension to add this cap, maybe it could be given a safe limit + // instead of limiting the supported ES version. + LimitVersion(maxSupportedESVersion, gl::Version(2, 0)); + } // Table 6.32, implementation dependent fragment shader limits - caps->maxFragmentUniformComponents = 896; - caps->maxFragmentUniformVectors = 224; - caps->maxFragmentUniformBlocks = 12; - caps->maxFragmentInputComponents = 60; - caps->maxTextureImageUnits = QuerySingleGLInt(functions, GL_MAX_TEXTURE_IMAGE_UNITS); - caps->minProgramTexelOffset = -8; - caps->maxProgramTexelOffset = 7; + if (functions->isAtLeastGL(gl::Version(2, 0)) || + functions->isAtLeastGLES(gl::Version(2, 0))) + { + caps->maxFragmentUniformComponents = QuerySingleGLInt(functions, GL_MAX_FRAGMENT_UNIFORM_COMPONENTS); + caps->maxTextureImageUnits = QuerySingleGLInt(functions, GL_MAX_TEXTURE_IMAGE_UNITS); + } + else + { + // Can't support ES2 version without these caps + LimitVersion(maxSupportedESVersion, gl::Version(0, 0)); + } + + if (functions->isAtLeastGL(gl::Version(4, 1)) || functions->hasGLExtension("GL_ARB_ES2_compatibility") || + functions->isAtLeastGLES(gl::Version(2, 0))) + { + caps->maxFragmentUniformVectors = QuerySingleGLInt(functions, GL_MAX_FRAGMENT_UNIFORM_VECTORS); + } + else + { + // Doesn't limit ES version, GL_MAX_FRAGMENT_UNIFORM_COMPONENTS / 4 is acceptable. + caps->maxFragmentUniformVectors = caps->maxFragmentUniformComponents / 4; + } + + if (functions->isAtLeastGL(gl::Version(3, 1)) || functions->hasGLExtension("GL_ARB_uniform_buffer_object") || + functions->isAtLeastGLES(gl::Version(3, 0))) + { + caps->maxFragmentUniformBlocks = QuerySingleGLInt(functions, GL_MAX_FRAGMENT_UNIFORM_BLOCKS); + } + else + { + // Can't support ES3 without uniform blocks + LimitVersion(maxSupportedESVersion, gl::Version(2, 0)); + } + + if (functions->isAtLeastGL(gl::Version(3, 2)) || + functions->isAtLeastGLES(gl::Version(3, 0))) + { + caps->maxFragmentInputComponents = QuerySingleGLInt(functions, GL_MAX_FRAGMENT_INPUT_COMPONENTS); + } + else + { + // There doesn't seem, to be a desktop extension to add this cap, maybe it could be given a safe limit + // instead of limiting the supported ES version. + LimitVersion(maxSupportedESVersion, gl::Version(2, 0)); + } + + if (functions->isAtLeastGL(gl::Version(3, 0)) || + functions->isAtLeastGLES(gl::Version(3, 0))) + { + caps->minProgramTexelOffset = QuerySingleGLInt(functions, GL_MIN_PROGRAM_TEXEL_OFFSET); + caps->maxProgramTexelOffset = QuerySingleGLInt(functions, GL_MAX_PROGRAM_TEXEL_OFFSET); + } + else + { + // Can't support ES3 without texel offset, could possibly be emulated in the shader + LimitVersion(maxSupportedESVersion, gl::Version(2, 0)); + } // Table 6.33, implementation dependent aggregate shader limits - caps->maxUniformBufferBindings = 24; - caps->maxUniformBlockSize = 16384; - caps->uniformBufferOffsetAlignment = 1; - caps->maxCombinedUniformBlocks = 24; - caps->maxCombinedVertexUniformComponents = (caps->maxVertexUniformBlocks * (caps->maxUniformBlockSize / 4)) + caps->maxVertexUniformComponents; - caps->maxCombinedFragmentUniformComponents = (caps->maxFragmentUniformBlocks * (caps->maxUniformBlockSize / 4)) + caps->maxFragmentUniformComponents; - caps->maxVaryingComponents = 60; - caps->maxVaryingVectors = 15; + if (functions->isAtLeastGL(gl::Version(3, 1)) || functions->hasGLExtension("GL_ARB_uniform_buffer_object") || + functions->isAtLeastGLES(gl::Version(3, 0))) + { + caps->maxUniformBufferBindings = QuerySingleGLInt(functions, GL_MAX_UNIFORM_BUFFER_BINDINGS); + caps->maxUniformBlockSize = QuerySingleGLInt64(functions, GL_MAX_UNIFORM_BLOCK_SIZE); + caps->uniformBufferOffsetAlignment = QuerySingleGLInt(functions, GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT); + caps->maxCombinedUniformBlocks = caps->maxVertexUniformBlocks + caps->maxFragmentInputComponents; + caps->maxCombinedVertexUniformComponents = QuerySingleGLInt64(functions, GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS); + caps->maxCombinedFragmentUniformComponents = QuerySingleGLInt64(functions, GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS); + } + else + { + // Can't support ES3 without uniform blocks + LimitVersion(maxSupportedESVersion, gl::Version(2, 0)); + } + + if (functions->isAtLeastGL(gl::Version(3, 0)) || + functions->hasGLExtension("GL_ARB_ES2_compatibility") || + functions->isAtLeastGLES(gl::Version(2, 0))) + { + caps->maxVaryingComponents = QuerySingleGLInt(functions, GL_MAX_VARYING_COMPONENTS); + } + else if (functions->isAtLeastGL(gl::Version(2, 0))) + { + caps->maxVaryingComponents = QuerySingleGLInt(functions, GL_MAX_VARYING_FLOATS); + LimitVersion(maxSupportedESVersion, gl::Version(2, 0)); + } + else + { + LimitVersion(maxSupportedESVersion, gl::Version(0, 0)); + } + + if (functions->isAtLeastGL(gl::Version(4, 1)) || functions->hasGLExtension("GL_ARB_ES2_compatibility") || + functions->isAtLeastGLES(gl::Version(2, 0))) + { + caps->maxVaryingVectors = QuerySingleGLInt(functions, GL_MAX_VARYING_VECTORS); + } + else + { + // Doesn't limit ES version, GL_MAX_VARYING_COMPONENTS / 4 is acceptable. + caps->maxVaryingVectors = caps->maxVaryingComponents / 4; + } + + // Determine the max combined texture image units by adding the vertex and fragment limits. If + // the real cap is queried, it would contain the limits for shader types that are not available to ES. caps->maxCombinedTextureImageUnits = caps->maxVertexTextureImageUnits + caps->maxTextureImageUnits; // Table 6.34, implementation dependent transform feedback limits - caps->maxTransformFeedbackInterleavedComponents = 64; - caps->maxTransformFeedbackSeparateAttributes = 4; - caps->maxTransformFeedbackSeparateComponents = 4; + if (functions->isAtLeastGL(gl::Version(4, 0)) || + functions->hasGLExtension("GL_ARB_transform_feedback2") || + functions->isAtLeastGLES(gl::Version(3, 0))) + { + caps->maxTransformFeedbackInterleavedComponents = QuerySingleGLInt(functions, GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS); + caps->maxTransformFeedbackSeparateAttributes = QuerySingleGLInt(functions, GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS); + caps->maxTransformFeedbackSeparateComponents = QuerySingleGLInt(functions, GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS); + } + else + { + // Can't support ES3 without transform feedback + LimitVersion(maxSupportedESVersion, gl::Version(2, 0)); + } // Table 6.35, Framebuffer Dependent Values - caps->maxSamples = QuerySingleGLInt(functions, GL_MAX_SAMPLES); + if (functions->isAtLeastGL(gl::Version(3, 0)) || functions->hasGLExtension("GL_EXT_framebuffer_multisample") || + functions->isAtLeastGLES(gl::Version(3, 0)) || functions->hasGLESExtension("GL_EXT_multisampled_render_to_texture")) + { + caps->maxSamples = QuerySingleGLInt(functions, GL_MAX_SAMPLES); + } + else + { + LimitVersion(maxSupportedESVersion, gl::Version(2, 0)); + } + + // Check if sampler objects are supported + if (!functions->isAtLeastGL(gl::Version(3, 3)) && + !functions->hasGLExtension("GL_ARB_sampler_objects") && + !functions->isAtLeastGLES(gl::Version(3, 0))) + { + // Can't support ES3 without sampler objects + LimitVersion(maxSupportedESVersion, gl::Version(2, 0)); + } + + // Can't support ES3 without texture swizzling + if (!functions->isAtLeastGL(gl::Version(3, 3)) && + !functions->hasGLExtension("GL_ARB_texture_swizzle") && + !functions->hasGLExtension("GL_EXT_texture_swizzle") && + !functions->isAtLeastGLES(gl::Version(3, 0))) + { + LimitVersion(maxSupportedESVersion, gl::Version(2, 0)); + + // Texture swizzling is required to work around the luminance texture format not being + // present in the core profile + if (functions->profile & GL_CONTEXT_CORE_PROFILE_BIT) + { + LimitVersion(maxSupportedESVersion, gl::Version(0, 0)); + } + } + + // Can't support ES3 without the GLSL packing builtins. We have a workaround for all + // desktop OpenGL versions starting from 3.3 with the bit packing extension. + if (!functions->isAtLeastGL(gl::Version(4, 2)) && + !(functions->isAtLeastGL(gl::Version(3, 2)) && + functions->hasGLExtension("GL_ARB_shader_bit_encoding")) && + !functions->hasGLExtension("GL_ARB_shading_language_packing") && + !functions->isAtLeastGLES(gl::Version(3, 0))) + { + LimitVersion(maxSupportedESVersion, gl::Version(2, 0)); + } + + // ES3 needs to support explicit layout location qualifiers, while it might be possible to + // fake them in our side, we currently don't support that. + if (!functions->isAtLeastGL(gl::Version(3, 3)) && + !functions->hasGLExtension("GL_ARB_explicit_attrib_location") && + !functions->isAtLeastGLES(gl::Version(3, 0))) + { + LimitVersion(maxSupportedESVersion, gl::Version(2, 0)); + } + + // TODO(geofflang): The gl-uniform-arrays WebGL conformance test struggles to complete on time + // if the max uniform vectors is too large. Artificially limit the maximum until the test is + // updated. + caps->maxVertexUniformVectors = std::min(1024u, caps->maxVertexUniformVectors); + caps->maxVertexUniformComponents = + std::min(caps->maxVertexUniformVectors / 4, caps->maxVertexUniformComponents); + caps->maxFragmentUniformVectors = std::min(1024u, caps->maxFragmentUniformVectors); + caps->maxFragmentUniformComponents = + std::min(caps->maxFragmentUniformVectors / 4, caps->maxFragmentUniformComponents); + + // If it is not possible to support reading buffer data back, a shadow copy of the buffers must + // be held. This disallows writing to buffers indirectly through transform feedback, thus + // disallowing ES3. + if (!CanMapBufferForRead(functions)) + { + LimitVersion(maxSupportedESVersion, gl::Version(2, 0)); + } // Extension support extensions->setTextureExtensionSupport(*textureCapsMap); - extensions->textureNPOT = true; + extensions->elementIndexUint = functions->standard == STANDARD_GL_DESKTOP || + functions->isAtLeastGLES(gl::Version(3, 0)) || functions->hasGLESExtension("GL_OES_element_index_uint"); + extensions->readFormatBGRA = functions->isAtLeastGL(gl::Version(1, 2)) || functions->hasGLExtension("GL_EXT_bgra") || + functions->hasGLESExtension("GL_EXT_read_format_bgra"); + extensions->mapBuffer = functions->isAtLeastGL(gl::Version(1, 5)) || + functions->hasGLESExtension("GL_OES_mapbuffer"); + extensions->mapBufferRange = functions->isAtLeastGL(gl::Version(3, 0)) || functions->hasGLExtension("GL_ARB_map_buffer_range") || + functions->isAtLeastGLES(gl::Version(3, 0)) || functions->hasGLESExtension("GL_EXT_map_buffer_range"); + extensions->textureNPOT = functions->standard == STANDARD_GL_DESKTOP || + functions->isAtLeastGLES(gl::Version(3, 0)) || functions->hasGLESExtension("GL_OES_texture_npot"); + extensions->drawBuffers = functions->isAtLeastGL(gl::Version(2, 0)) || functions->hasGLExtension("ARB_draw_buffers") || + functions->isAtLeastGLES(gl::Version(3, 0)) || functions->hasGLESExtension("GL_EXT_draw_buffers"); extensions->textureStorage = true; - extensions->fboRenderMipmap = true; + extensions->textureFilterAnisotropic = functions->hasGLExtension("GL_EXT_texture_filter_anisotropic") || functions->hasGLESExtension("GL_EXT_texture_filter_anisotropic"); + extensions->occlusionQueryBoolean = + functions->isAtLeastGL(gl::Version(1, 5)) || + functions->hasGLExtension("GL_ARB_occlusion_query2") || + functions->isAtLeastGLES(gl::Version(3, 0)) || + functions->hasGLESExtension("GL_EXT_occlusion_query_boolean"); + extensions->maxTextureAnisotropy = extensions->textureFilterAnisotropic ? QuerySingleGLFloat(functions, GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT) : 0.0f; + extensions->fence = functions->hasGLExtension("GL_NV_fence") || functions->hasGLESExtension("GL_NV_fence"); + extensions->blendMinMax = functions->isAtLeastGL(gl::Version(1, 5)) || functions->hasGLExtension("GL_EXT_blend_minmax") || + functions->isAtLeastGLES(gl::Version(3, 0)) || functions->hasGLESExtension("GL_EXT_blend_minmax"); + extensions->framebufferBlit = (functions->blitFramebuffer != nullptr); extensions->framebufferMultisample = caps->maxSamples > 0; - extensions->fence = std::find(functions->extensions.begin(), functions->extensions.end(), "GL_NV_fence") != functions->extensions.end(); + extensions->standardDerivatives = functions->isAtLeastGL(gl::Version(2, 0)) || functions->hasGLExtension("GL_ARB_fragment_shader") || + functions->isAtLeastGLES(gl::Version(3, 0)) || functions->hasGLESExtension("GL_OES_standard_derivatives"); + extensions->shaderTextureLOD = functions->isAtLeastGL(gl::Version(3, 0)) || functions->hasGLExtension("GL_ARB_shader_texture_lod") || + functions->isAtLeastGLES(gl::Version(3, 0)) || functions->hasGLESExtension("GL_EXT_shader_texture_lod"); + extensions->fragDepth = functions->standard == STANDARD_GL_DESKTOP || + functions->isAtLeastGLES(gl::Version(3, 0)) || functions->hasGLESExtension("GL_EXT_frag_depth"); + extensions->fboRenderMipmap = functions->isAtLeastGL(gl::Version(3, 0)) || functions->hasGLExtension("GL_EXT_framebuffer_object") || + functions->isAtLeastGLES(gl::Version(3, 0)) || functions->hasGLESExtension("GL_OES_fbo_render_mipmap"); + extensions->instancedArrays = functions->isAtLeastGL(gl::Version(3, 1)) || + (functions->hasGLExtension("GL_ARB_instanced_arrays") && + (functions->hasGLExtension("GL_ARB_draw_instanced") || + functions->hasGLExtension("GL_EXT_draw_instanced"))) || + functions->isAtLeastGLES(gl::Version(3, 0)) || + functions->hasGLESExtension("GL_EXT_instanced_arrays"); + extensions->unpackSubimage = functions->standard == STANDARD_GL_DESKTOP || + functions->isAtLeastGLES(gl::Version(3, 0)) || + functions->hasGLESExtension("GL_EXT_unpack_subimage"); + extensions->packSubimage = functions->standard == STANDARD_GL_DESKTOP || + functions->isAtLeastGLES(gl::Version(3, 0)) || + functions->hasGLESExtension("GL_NV_pack_subimage"); + extensions->debugMarker = + functions->isAtLeastGL(gl::Version(4, 3)) || functions->hasGLExtension("GL_KHR_debug") || + functions->isAtLeastGLES(gl::Version(3, 2)) || functions->hasGLESExtension("GL_KHR_debug"); + if (functions->isAtLeastGL(gl::Version(3, 3)) || + functions->hasGLExtension("GL_ARB_timer_query") || + functions->hasGLESExtension("GL_EXT_disjoint_timer_query")) + { + extensions->disjointTimerQuery = true; + extensions->queryCounterBitsTimeElapsed = + QueryQueryValue(functions, GL_TIME_ELAPSED, GL_QUERY_COUNTER_BITS); + extensions->queryCounterBitsTimestamp = + QueryQueryValue(functions, GL_TIMESTAMP, GL_QUERY_COUNTER_BITS); + } + + // ANGLE emulates vertex array objects in its GL layer + extensions->vertexArrayObject = true; + + extensions->noError = true; +} + +void GenerateWorkarounds(const FunctionsGL *functions, WorkaroundsGL *workarounds) +{ + VendorID vendor = GetVendorID(functions); + + // Don't use 1-bit alpha formats on desktop GL with AMD or Intel drivers. + workarounds->avoid1BitAlphaTextureFormats = + functions->standard == STANDARD_GL_DESKTOP && + (vendor == VENDOR_ID_AMD || vendor == VENDOR_ID_INTEL); + + workarounds->rgba4IsNotSupportedForColorRendering = + functions->standard == STANDARD_GL_DESKTOP && vendor == VENDOR_ID_INTEL; + + workarounds->doesSRGBClearsOnLinearFramebufferAttachments = + functions->standard == STANDARD_GL_DESKTOP && + (vendor == VENDOR_ID_INTEL || vendor == VENDOR_ID_AMD); + +#if defined(ANGLE_PLATFORM_APPLE) + workarounds->doWhileGLSLCausesGPUHang = true; +#endif + + workarounds->finishDoesNotCauseQueriesToBeAvailable = + functions->standard == STANDARD_GL_DESKTOP && vendor == VENDOR_ID_NVIDIA; + + // TODO(cwallez): Disable this workaround for MacOSX versions 10.9 or later. + workarounds->alwaysCallUseProgramAfterLink = true; } } +bool CanMapBufferForRead(const FunctionsGL *functions) +{ + return (functions->mapBufferRange != nullptr) || + (functions->mapBuffer != nullptr && functions->standard == STANDARD_GL_DESKTOP); +} + +uint8_t *MapBufferRangeWithFallback(const FunctionsGL *functions, + GLenum target, + size_t offset, + size_t length, + GLbitfield access) +{ + if (functions->mapBufferRange != nullptr) + { + return reinterpret_cast( + functions->mapBufferRange(target, offset, length, access)); + } + else if (functions->mapBuffer != nullptr && + (functions->standard == STANDARD_GL_DESKTOP || access == GL_MAP_WRITE_BIT)) + { + // Only the read and write bits are supported + ASSERT((access & (GL_MAP_READ_BIT | GL_MAP_WRITE_BIT)) != 0); + + GLenum accessEnum = 0; + if (access == (GL_MAP_READ_BIT | GL_MAP_WRITE_BIT)) + { + accessEnum = GL_READ_WRITE; + } + else if (access == GL_MAP_READ_BIT) + { + accessEnum = GL_READ_ONLY; + } + else if (access == GL_MAP_WRITE_BIT) + { + accessEnum = GL_WRITE_ONLY; + } + else + { + UNREACHABLE(); + return nullptr; + } + + return reinterpret_cast(functions->mapBuffer(target, accessEnum)) + offset; + } + else + { + // No options available + UNREACHABLE(); + return nullptr; + } +} } diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/renderergl_utils.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/renderergl_utils.h index 3a6fa4dc83d4..3b0cab27e7b3 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/renderergl_utils.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/renderergl_utils.h @@ -4,14 +4,16 @@ // found in the LICENSE file. // -// renderer11_utils.h: Conversion functions and other utility routines +// renderergl_utils.h: Conversion functions and other utility routines // specific to the OpenGL renderer. #ifndef LIBANGLE_RENDERER_GL_RENDERERGLUTILS_H_ #define LIBANGLE_RENDERER_GL_RENDERERGLUTILS_H_ +#include "libANGLE/angletypes.h" #include "libANGLE/renderer/gl/functionsgl_typedefs.h" +#include #include namespace gl @@ -19,20 +21,32 @@ namespace gl struct Caps; class TextureCapsMap; struct Extensions; +struct Version; } namespace rx { class FunctionsGL; +struct WorkaroundsGL; + +VendorID GetVendorID(const FunctionsGL *functions); +std::string GetDriverVersion(const FunctionsGL *functions); namespace nativegl_gl { void GenerateCaps(const FunctionsGL *functions, gl::Caps *caps, gl::TextureCapsMap *textureCapsMap, - gl::Extensions *extensions); + gl::Extensions *extensions, gl::Version *maxSupportedESVersion); +void GenerateWorkarounds(const FunctionsGL *functions, WorkaroundsGL *workarounds); } +bool CanMapBufferForRead(const FunctionsGL *functions); +uint8_t *MapBufferRangeWithFallback(const FunctionsGL *functions, + GLenum target, + size_t offset, + size_t length, + GLbitfield access); } #endif // LIBANGLE_RENDERER_GL_RENDERERGLUTILS_H_ diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/wgl/DXGISwapChainWindowSurfaceWGL.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/wgl/DXGISwapChainWindowSurfaceWGL.cpp new file mode 100644 index 000000000000..bd705a89e645 --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/wgl/DXGISwapChainWindowSurfaceWGL.cpp @@ -0,0 +1,550 @@ +// +// Copyright (c) 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. +// + +// DXGISwapChainWindowSurfaceWGL.cpp: WGL implementation of egl::Surface for windows using a DXGI +// swapchain. + +#include "libANGLE/renderer/gl/wgl/DXGISwapChainWindowSurfaceWGL.h" + +#include "libANGLE/formatutils.h" +#include "libANGLE/renderer/gl/FramebufferGL.h" +#include "libANGLE/renderer/gl/TextureGL.h" +#include "libANGLE/renderer/gl/RendererGL.h" +#include "libANGLE/renderer/gl/StateManagerGL.h" +#include "libANGLE/renderer/gl/wgl/DisplayWGL.h" +#include "libANGLE/renderer/gl/wgl/FunctionsWGL.h" + +#include + +namespace rx +{ + +DXGISwapChainWindowSurfaceWGL::DXGISwapChainWindowSurfaceWGL(RendererGL *renderer, + EGLNativeWindowType window, + ID3D11Device *device, + HANDLE deviceHandle, + HGLRC wglContext, + HDC deviceContext, + const FunctionsGL *functionsGL, + const FunctionsWGL *functionsWGL, + EGLint orientation) + : SurfaceGL(renderer), + mWindow(window), + mStateManager(renderer->getStateManager()), + mWorkarounds(renderer->getWorkarounds()), + mFunctionsGL(functionsGL), + mFunctionsWGL(functionsWGL), + mDevice(device), + mDeviceHandle(deviceHandle), + mWGLDevice(deviceContext), + mWGLContext(wglContext), + mSwapChainFormat(DXGI_FORMAT_UNKNOWN), + mSwapChainFlags(0), + mDepthBufferFormat(GL_NONE), + mFirstSwap(true), + mSwapChain(nullptr), + mSwapChain1(nullptr), + mColorRenderbufferID(0), + mRenderbufferBufferHandle(nullptr), + mDepthRenderbufferID(0), + mFramebufferID(0), + mTextureID(0), + mTextureHandle(nullptr), + mWidth(0), + mHeight(0), + mSwapInterval(1), + mOrientation(orientation) +{ +} + +DXGISwapChainWindowSurfaceWGL::~DXGISwapChainWindowSurfaceWGL() +{ + if (mRenderbufferBufferHandle != nullptr) + { + mFunctionsWGL->dxUnlockObjectsNV(mDeviceHandle, 1, &mRenderbufferBufferHandle); + mFunctionsWGL->dxUnregisterObjectNV(mDeviceHandle, mRenderbufferBufferHandle); + } + + if (mColorRenderbufferID != 0) + { + mStateManager->deleteRenderbuffer(mColorRenderbufferID); + mColorRenderbufferID = 0; + } + + if (mDepthRenderbufferID != 0) + { + mStateManager->deleteRenderbuffer(mDepthRenderbufferID); + mDepthRenderbufferID = 0; + } + + SafeRelease(mSwapChain); + SafeRelease(mSwapChain1); +} + +egl::Error DXGISwapChainWindowSurfaceWGL::initialize() +{ + if (mOrientation != EGL_SURFACE_ORIENTATION_INVERT_Y_ANGLE) + { + // TODO(geofflang): Support the orientation extensions fully. Currently only inverting Y is + // supported. To support all orientations, an intermediate framebuffer will be needed with + // a blit before swap. + return egl::Error(EGL_BAD_ATTRIBUTE, + "DXGISwapChainWindowSurfaceWGL requires an orientation of " + "EGL_SURFACE_ORIENTATION_INVERT_Y_ANGLE."); + } + + RECT rect; + if (!GetClientRect(mWindow, &rect)) + { + return egl::Error(EGL_BAD_NATIVE_WINDOW, "Failed to query the window size."); + } + mWidth = rect.right - rect.left; + mHeight = rect.bottom - rect.top; + + mSwapChainFormat = DXGI_FORMAT_R8G8B8A8_UNORM; + mSwapChainFlags = 0; + mDepthBufferFormat = GL_DEPTH24_STENCIL8; + + mFunctionsGL->genFramebuffers(1, &mFramebufferID); + mFunctionsGL->genRenderbuffers(1, &mColorRenderbufferID); + mFunctionsGL->genRenderbuffers(1, &mDepthRenderbufferID); + + return createSwapChain(); +} + +egl::Error DXGISwapChainWindowSurfaceWGL::makeCurrent() +{ + if (!mFunctionsWGL->makeCurrent(mWGLDevice, mWGLContext)) + { + // TODO: What error type here? + return egl::Error(EGL_CONTEXT_LOST, "Failed to make the WGL context current."); + } + + return egl::Error(EGL_SUCCESS); +} + +egl::Error DXGISwapChainWindowSurfaceWGL::swap() +{ + mFunctionsGL->flush(); + + egl::Error error = setObjectsLocked(false); + if (error.isError()) + { + return error; + } + + HRESULT result = mSwapChain->Present(mSwapInterval, 0); + mFirstSwap = false; + + error = setObjectsLocked(true); + if (error.isError()) + { + return error; + } + + if (FAILED(result)) + { + return egl::Error(EGL_BAD_ALLOC, "Failed to present swap chain, result: 0x%X", result); + } + + return checkForResize(); +} + +egl::Error DXGISwapChainWindowSurfaceWGL::postSubBuffer(EGLint x, + EGLint y, + EGLint width, + EGLint height) +{ + ASSERT(mSwapChain1 != nullptr); + + mFunctionsGL->flush(); + + egl::Error error = setObjectsLocked(false); + if (error.isError()) + { + return error; + } + + HRESULT result = S_OK; + if (mFirstSwap) + { + result = mSwapChain1->Present(mSwapInterval, 0); + mFirstSwap = false; + } + 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(mSwapInterval, 0, ¶ms); + } + + error = setObjectsLocked(true); + if (error.isError()) + { + return error; + } + + if (FAILED(result)) + { + return egl::Error(EGL_BAD_ALLOC, "Failed to present swap chain, result: 0x%X", result); + } + + return checkForResize(); +} + +egl::Error DXGISwapChainWindowSurfaceWGL::querySurfacePointerANGLE(EGLint attribute, void **value) +{ + UNREACHABLE(); + return egl::Error(EGL_SUCCESS); +} + +egl::Error DXGISwapChainWindowSurfaceWGL::bindTexImage(gl::Texture *texture, EGLint buffer) +{ + ASSERT(mTextureHandle == nullptr); + + const TextureGL *textureGL = GetImplAs(texture); + GLuint textureID = textureGL->getTextureID(); + + ID3D11Texture2D *colorBuffer = nullptr; + HRESULT result = mSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), + reinterpret_cast(&colorBuffer)); + if (FAILED(result)) + { + return egl::Error(EGL_BAD_ALLOC, "Failed to query texture from swap chain, result: 0x%X", + result); + } + + mTextureHandle = mFunctionsWGL->dxRegisterObjectNV(mDeviceHandle, colorBuffer, textureID, + GL_TEXTURE_2D, WGL_ACCESS_READ_WRITE_NV); + SafeRelease(colorBuffer); + if (mTextureHandle == nullptr) + { + return egl::Error(EGL_BAD_ALLOC, "Failed to register D3D object, error: 0x%08x.", + HRESULT_CODE(GetLastError())); + } + + if (!mFunctionsWGL->dxLockObjectsNV(mDeviceHandle, 1, &mTextureHandle)) + { + mFunctionsWGL->dxUnregisterObjectNV(mDeviceHandle, mTextureHandle); + mTextureHandle = nullptr; + + return egl::Error(EGL_BAD_ALLOC, "Failed to lock D3D object, error: 0x%08x.", + HRESULT_CODE(GetLastError())); + } + + mTextureID = textureID; + + return egl::Error(EGL_SUCCESS); +} + +egl::Error DXGISwapChainWindowSurfaceWGL::releaseTexImage(EGLint buffer) +{ + ASSERT(mTextureHandle != nullptr); + + if (!mFunctionsWGL->dxUnlockObjectsNV(mDeviceHandle, 1, &mTextureHandle)) + { + return egl::Error(EGL_BAD_ALLOC, "Failed to unlock D3D object, error: 0x%08x.", + HRESULT_CODE(GetLastError())); + } + + if (!mFunctionsWGL->dxUnregisterObjectNV(mDeviceHandle, mTextureHandle)) + { + return egl::Error(EGL_BAD_ALLOC, "Failed to unregister D3D object, error: 0x%08x.", + HRESULT_CODE(GetLastError())); + } + + mTextureID = 0; + mTextureHandle = nullptr; + + return egl::Error(EGL_SUCCESS); +} + +void DXGISwapChainWindowSurfaceWGL::setSwapInterval(EGLint interval) +{ + mSwapInterval = interval; +} + +EGLint DXGISwapChainWindowSurfaceWGL::getWidth() const +{ + return static_cast(mWidth); +} + +EGLint DXGISwapChainWindowSurfaceWGL::getHeight() const +{ + return static_cast(mHeight); +} + +EGLint DXGISwapChainWindowSurfaceWGL::isPostSubBufferSupported() const +{ + return mSwapChain1 != nullptr; +} + +EGLint DXGISwapChainWindowSurfaceWGL::getSwapBehavior() const +{ + return EGL_BUFFER_DESTROYED; +} + +FramebufferImpl *DXGISwapChainWindowSurfaceWGL::createDefaultFramebuffer( + const gl::Framebuffer::Data &data) +{ + return new FramebufferGL(mFramebufferID, data, mFunctionsGL, mWorkarounds, mStateManager); +} + +egl::Error DXGISwapChainWindowSurfaceWGL::setObjectsLocked(bool locked) +{ + if (mRenderbufferBufferHandle == nullptr) + { + ASSERT(mTextureHandle == nullptr); + return egl::Error(EGL_SUCCESS); + } + + HANDLE resources[] = { + mRenderbufferBufferHandle, mTextureHandle, + }; + GLint count = (mTextureHandle != nullptr) ? 2 : 1; + + if (locked) + { + if (!mFunctionsWGL->dxLockObjectsNV(mDeviceHandle, count, resources)) + { + return egl::Error(EGL_BAD_ALLOC, "Failed to lock object, error: 0x%08x.", + HRESULT_CODE(GetLastError())); + } + } + else + { + if (!mFunctionsWGL->dxUnlockObjectsNV(mDeviceHandle, count, resources)) + { + return egl::Error(EGL_BAD_ALLOC, "Failed to lock object, error: 0x%08x.", + HRESULT_CODE(GetLastError())); + } + } + + return egl::Error(EGL_SUCCESS); +} + +egl::Error DXGISwapChainWindowSurfaceWGL::checkForResize() +{ + RECT rect; + if (!GetClientRect(mWindow, &rect)) + { + return egl::Error(EGL_BAD_NATIVE_WINDOW, "Failed to query the window size."); + } + + size_t newWidth = rect.right - rect.left; + size_t newHeight = rect.bottom - rect.top; + if (newWidth != mWidth || newHeight != mHeight) + { + mWidth = newWidth; + mHeight = newHeight; + + // TODO(geofflang): Handle resize by resizing the swap chain instead of re-creating it. + egl::Error error = createSwapChain(); + if (error.isError()) + { + return error; + } + } + + return egl::Error(EGL_SUCCESS); +} + +static IDXGIFactory *GetDXGIFactoryFromDevice(ID3D11Device *device) +{ + IDXGIDevice *dxgiDevice = nullptr; + HRESULT result = + device->QueryInterface(__uuidof(IDXGIDevice), reinterpret_cast(&dxgiDevice)); + if (FAILED(result)) + { + return nullptr; + } + + IDXGIAdapter *dxgiAdapter = nullptr; + result = dxgiDevice->GetParent(__uuidof(IDXGIAdapter), reinterpret_cast(&dxgiAdapter)); + SafeRelease(dxgiDevice); + if (FAILED(result)) + { + return nullptr; + } + + IDXGIFactory *dxgiFactory = nullptr; + result = + dxgiAdapter->GetParent(__uuidof(IDXGIFactory), reinterpret_cast(&dxgiFactory)); + SafeRelease(dxgiAdapter); + if (FAILED(result)) + { + return nullptr; + } + + return dxgiFactory; +} + +egl::Error DXGISwapChainWindowSurfaceWGL::createSwapChain() +{ + egl::Error error = setObjectsLocked(false); + if (error.isError()) + { + return error; + } + + if (mRenderbufferBufferHandle) + { + mFunctionsWGL->dxUnregisterObjectNV(mDeviceHandle, mRenderbufferBufferHandle); + mRenderbufferBufferHandle = nullptr; + } + + // If this surface is bound to a texture, unregister it. + bool hadBoundSurface = (mTextureHandle != nullptr); + if (hadBoundSurface) + { + mFunctionsWGL->dxUnregisterObjectNV(mDeviceHandle, mTextureHandle); + mTextureHandle = nullptr; + } + + IDXGIFactory *dxgiFactory = GetDXGIFactoryFromDevice(mDevice); + if (dxgiFactory == nullptr) + { + return egl::Error(EGL_BAD_NATIVE_WINDOW, "Failed to query the DXGIFactory."); + } + + IDXGIFactory2 *dxgiFactory2 = nullptr; + HRESULT result = dxgiFactory->QueryInterface(__uuidof(IDXGIFactory2), + reinterpret_cast(&dxgiFactory2)); + if (SUCCEEDED(result)) + { + ASSERT(dxgiFactory2 != nullptr); + + DXGI_SWAP_CHAIN_DESC1 swapChainDesc = {0}; + swapChainDesc.BufferCount = 1; + swapChainDesc.Format = mSwapChainFormat; + swapChainDesc.Width = static_cast(mWidth); + swapChainDesc.Height = static_cast(mHeight); + swapChainDesc.Format = mSwapChainFormat; + swapChainDesc.Stereo = FALSE; + swapChainDesc.SampleDesc.Count = 1; + 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 = mSwapChainFlags; + + result = dxgiFactory2->CreateSwapChainForHwnd(mDevice, mWindow, &swapChainDesc, nullptr, + nullptr, &mSwapChain1); + SafeRelease(dxgiFactory2); + SafeRelease(dxgiFactory); + if (FAILED(result)) + { + return egl::Error(EGL_BAD_ALLOC, "Failed to create swap chain for window, result: 0x%X", + result); + } + + mSwapChain = mSwapChain1; + mSwapChain->AddRef(); + } + else + { + DXGI_SWAP_CHAIN_DESC swapChainDesc = {}; + swapChainDesc.BufferCount = 1; + swapChainDesc.BufferDesc.Format = mSwapChainFormat; + swapChainDesc.BufferDesc.Width = static_cast(mWidth); + swapChainDesc.BufferDesc.Height = static_cast(mHeight); + 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 = mSwapChainFlags; + swapChainDesc.OutputWindow = mWindow; + swapChainDesc.SampleDesc.Count = 1; + swapChainDesc.SampleDesc.Quality = 0; + swapChainDesc.Windowed = TRUE; + swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; + + result = dxgiFactory->CreateSwapChain(mDevice, &swapChainDesc, &mSwapChain); + SafeRelease(dxgiFactory); + if (FAILED(result)) + { + return egl::Error(EGL_BAD_ALLOC, "Failed to create swap chain for window, result: 0x%X", + result); + } + } + + ID3D11Texture2D *colorBuffer = nullptr; + result = mSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), + reinterpret_cast(&colorBuffer)); + if (FAILED(result)) + { + return egl::Error(EGL_BAD_ALLOC, "Failed to query texture from swap chain, result: 0x%X", + result); + } + + mFunctionsGL->genRenderbuffers(1, &mColorRenderbufferID); + mStateManager->bindRenderbuffer(GL_RENDERBUFFER, mColorRenderbufferID); + mRenderbufferBufferHandle = + mFunctionsWGL->dxRegisterObjectNV(mDeviceHandle, colorBuffer, mColorRenderbufferID, + GL_RENDERBUFFER, WGL_ACCESS_READ_WRITE_NV); + SafeRelease(colorBuffer); + if (mRenderbufferBufferHandle == nullptr) + { + return egl::Error(EGL_BAD_ALLOC, "Failed to register D3D object, error: 0x%X.", + HRESULT_CODE(GetLastError())); + } + + // Rebind the surface to the texture if needed. + if (hadBoundSurface) + { + mTextureHandle = mFunctionsWGL->dxRegisterObjectNV(mDeviceHandle, colorBuffer, mTextureID, + GL_TEXTURE_2D, WGL_ACCESS_READ_WRITE_NV); + if (mTextureHandle == nullptr) + { + return egl::Error(EGL_BAD_ALLOC, "Failed to register D3D object, error: 0x%X.", + HRESULT_CODE(GetLastError())); + } + } + + error = setObjectsLocked(true); + if (error.isError()) + { + return error; + } + + ASSERT(mFramebufferID != 0); + mStateManager->bindFramebuffer(GL_FRAMEBUFFER, mFramebufferID); + mFunctionsGL->framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, + mColorRenderbufferID); + + if (mDepthBufferFormat != GL_NONE) + { + ASSERT(mDepthRenderbufferID != 0); + mStateManager->bindRenderbuffer(GL_RENDERBUFFER, mDepthRenderbufferID); + mFunctionsGL->renderbufferStorage(GL_RENDERBUFFER, mDepthBufferFormat, + static_cast(mWidth), + static_cast(mHeight)); + + const gl::InternalFormat &depthStencilFormatInfo = + gl::GetInternalFormatInfo(mDepthBufferFormat); + if (depthStencilFormatInfo.depthBits > 0) + { + mFunctionsGL->framebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, + GL_RENDERBUFFER, mDepthRenderbufferID); + } + if (depthStencilFormatInfo.stencilBits > 0) + { + mFunctionsGL->framebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, + GL_RENDERBUFFER, mDepthRenderbufferID); + } + } + + mFirstSwap = true; + + return egl::Error(EGL_SUCCESS); +} +} // namespace rx diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/wgl/DXGISwapChainWindowSurfaceWGL.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/wgl/DXGISwapChainWindowSurfaceWGL.h new file mode 100644 index 000000000000..a4549c6e25f8 --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/wgl/DXGISwapChainWindowSurfaceWGL.h @@ -0,0 +1,104 @@ +// +// Copyright (c) 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. +// + +// DXGISwapChainWindowSurfaceWGL.h: WGL implementation of egl::Surface for windows using a DXGI +// swapchain. + +#ifndef LIBANGLE_RENDERER_GL_WGL_DXGISWAPCHAINSURFACEWGL_H_ +#define LIBANGLE_RENDERER_GL_WGL_DXGISWAPCHAINSURFACEWGL_H_ + +#include "libANGLE/renderer/gl/SurfaceGL.h" + +#include + +namespace rx +{ + +class FunctionsGL; +class FunctionsWGL; +class DisplayWGL; +class StateManagerGL; +struct WorkaroundsGL; + +class DXGISwapChainWindowSurfaceWGL : public SurfaceGL +{ + public: + DXGISwapChainWindowSurfaceWGL(RendererGL *renderer, + EGLNativeWindowType window, + ID3D11Device *device, + HANDLE deviceHandle, + HGLRC wglContext, + HDC deviceContext, + const FunctionsGL *functionsGL, + const FunctionsWGL *functionsWGL, + EGLint orientation); + ~DXGISwapChainWindowSurfaceWGL() override; + + egl::Error initialize() override; + egl::Error makeCurrent() override; + + egl::Error swap() override; + egl::Error postSubBuffer(EGLint x, EGLint y, EGLint width, EGLint height) override; + egl::Error querySurfacePointerANGLE(EGLint attribute, void **value) override; + egl::Error bindTexImage(gl::Texture *texture, EGLint buffer) override; + egl::Error releaseTexImage(EGLint buffer) override; + void setSwapInterval(EGLint interval) override; + + EGLint getWidth() const override; + EGLint getHeight() const override; + + EGLint isPostSubBufferSupported() const override; + EGLint getSwapBehavior() const override; + + FramebufferImpl *createDefaultFramebuffer(const gl::Framebuffer::Data &data) override; + + private: + egl::Error setObjectsLocked(bool locked); + egl::Error checkForResize(); + + egl::Error createSwapChain(); + + EGLNativeWindowType mWindow; + + StateManagerGL *mStateManager; + const WorkaroundsGL &mWorkarounds; + const FunctionsGL *mFunctionsGL; + const FunctionsWGL *mFunctionsWGL; + + ID3D11Device *mDevice; + HANDLE mDeviceHandle; + + HDC mWGLDevice; + HGLRC mWGLContext; + + DXGI_FORMAT mSwapChainFormat; + UINT mSwapChainFlags; + GLenum mDepthBufferFormat; + + bool mFirstSwap; + IDXGISwapChain *mSwapChain; + IDXGISwapChain1 *mSwapChain1; + + GLuint mColorRenderbufferID; + HANDLE mRenderbufferBufferHandle; + + GLuint mDepthRenderbufferID; + + GLuint mFramebufferID; + + GLuint mTextureID; + HANDLE mTextureHandle; + + size_t mWidth; + size_t mHeight; + + EGLint mSwapInterval; + + EGLint mOrientation; +}; +} // namespace rx + +#endif // LIBANGLE_RENDERER_GL_WGL_DXGISWAPCHAINSURFACEWGL_H_ diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/wgl/DisplayWGL.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/wgl/DisplayWGL.cpp index 5fe9374e4a33..6cb4f4fd1212 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/wgl/DisplayWGL.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/wgl/DisplayWGL.cpp @@ -13,6 +13,7 @@ #include "libANGLE/Display.h" #include "libANGLE/Surface.h" #include "libANGLE/renderer/gl/renderergl_utils.h" +#include "libANGLE/renderer/gl/wgl/DXGISwapChainWindowSurfaceWGL.h" #include "libANGLE/renderer/gl/wgl/FunctionsWGL.h" #include "libANGLE/renderer/gl/wgl/PbufferSurfaceWGL.h" #include "libANGLE/renderer/gl/wgl/WindowSurfaceWGL.h" @@ -36,9 +37,7 @@ class FunctionsGLWindows : public FunctionsGL ASSERT(mGetProcAddressWGL); } - virtual ~FunctionsGLWindows() - { - } + ~FunctionsGLWindows() override {} private: void *loadProcAddress(const std::string &function) override @@ -65,6 +64,11 @@ DisplayWGL::DisplayWGL() mDeviceContext(nullptr), mPixelFormat(0), mWGLContext(nullptr), + mUseDXGISwapChains(false), + mDxgiModule(nullptr), + mD3d11Module(nullptr), + mD3D11DeviceHandle(nullptr), + mD3D11Device(nullptr), mDisplay(nullptr) { } @@ -73,26 +77,6 @@ DisplayWGL::~DisplayWGL() { } -static LRESULT CALLBACK IntermediateWindowProc(HWND window, UINT message, WPARAM wParam, LPARAM lParam) -{ - switch (message) - { - case WM_ERASEBKGND: - // Prevent windows from erasing the background. - return 1; - case WM_PAINT: - // Do not paint anything. - PAINTSTRUCT paint; - if (BeginPaint(window, &paint)) - { - EndPaint(window, &paint); - } - return 0; - } - - return DefWindowProc(window, message, wParam, lParam); -} - egl::Error DisplayWGL::initialize(egl::Display *display) { mDisplay = display; @@ -112,24 +96,26 @@ egl::Error DisplayWGL::initialize(egl::Display *display) // Work around compile error from not defining "UNICODE" while Chromium does const LPSTR idcArrow = MAKEINTRESOURCEA(32512); + std::string className = FormatString("ANGLE DisplayWGL 0x%0.8p Intermediate Window Class", mDisplay); + WNDCLASSA intermediateClassDesc = { 0 }; intermediateClassDesc.style = CS_OWNDC; - intermediateClassDesc.lpfnWndProc = IntermediateWindowProc; + intermediateClassDesc.lpfnWndProc = DefWindowProc; intermediateClassDesc.cbClsExtra = 0; intermediateClassDesc.cbWndExtra = 0; - intermediateClassDesc.hInstance = GetModuleHandle(NULL); - intermediateClassDesc.hIcon = NULL; - intermediateClassDesc.hCursor = LoadCursorA(NULL, idcArrow); + intermediateClassDesc.hInstance = GetModuleHandle(nullptr); + intermediateClassDesc.hIcon = nullptr; + intermediateClassDesc.hCursor = LoadCursorA(nullptr, idcArrow); intermediateClassDesc.hbrBackground = 0; - intermediateClassDesc.lpszMenuName = NULL; - intermediateClassDesc.lpszClassName = "ANGLE Intermediate Window"; + intermediateClassDesc.lpszMenuName = nullptr; + intermediateClassDesc.lpszClassName = className.c_str(); mWindowClass = RegisterClassA(&intermediateClassDesc); if (!mWindowClass) { return egl::Error(EGL_NOT_INITIALIZED, "Failed to register intermediate OpenGL window class."); } - HWND dummyWindow = CreateWindowExA(WS_EX_NOPARENTNOTIFY, + HWND dummyWindow = CreateWindowExA(0, reinterpret_cast(mWindowClass), "ANGLE Dummy Window", WS_OVERLAPPEDWINDOW, @@ -137,10 +123,10 @@ egl::Error DisplayWGL::initialize(egl::Display *display) CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, - NULL, - NULL, - NULL, - NULL); + nullptr, + nullptr, + nullptr, + nullptr); if (!dummyWindow) { return egl::Error(EGL_NOT_INITIALIZED, "Failed to create dummy OpenGL window."); @@ -188,16 +174,25 @@ egl::Error DisplayWGL::initialize(egl::Display *display) mFunctionsWGL->initialize(mOpenGLModule, dummyDeviceContext); // Destroy the dummy window and context - mFunctionsWGL->makeCurrent(dummyDeviceContext, NULL); + mFunctionsWGL->makeCurrent(dummyDeviceContext, nullptr); mFunctionsWGL->deleteContext(dummyWGLContext); ReleaseDC(dummyWindow, dummyDeviceContext); DestroyWindow(dummyWindow); - // Create the real intermediate context and windows - HDC parentHDC = display->getNativeDisplayId(); - HWND parentWindow = WindowFromDC(parentHDC); + const egl::AttributeMap &displayAttributes = display->getAttributeMap(); + EGLint requestedDisplayType = static_cast(displayAttributes.get( + EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE)); + if (requestedDisplayType == EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE && + !mFunctionsWGL->hasExtension("WGL_EXT_create_context_es2_profile") && + !mFunctionsWGL->hasExtension("WGL_EXT_create_context_es_profile")) + { + return egl::Error(EGL_NOT_INITIALIZED, + "Cannot create an OpenGL ES platform on Windows without " + "the WGL_EXT_create_context_es(2)_profile extension."); + } - mWindow = CreateWindowExA(WS_EX_NOPARENTNOTIFY, + // Create the real intermediate context and windows + mWindow = CreateWindowExA(0, reinterpret_cast(mWindowClass), "ANGLE Intermediate Window", WS_OVERLAPPEDWINDOW, @@ -205,10 +200,10 @@ egl::Error DisplayWGL::initialize(egl::Display *display) CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, - parentWindow, - NULL, - NULL, - NULL); + nullptr, + nullptr, + nullptr, + nullptr); if (!mWindow) { return egl::Error(EGL_NOT_INITIALIZED, "Failed to create intermediate OpenGL window."); @@ -220,7 +215,20 @@ egl::Error DisplayWGL::initialize(egl::Display *display) return egl::Error(EGL_NOT_INITIALIZED, "Failed to get the device context of the intermediate OpenGL window."); } - mPixelFormat = ChoosePixelFormat(mDeviceContext, &pixelFormatDescriptor); + if (mFunctionsWGL->choosePixelFormatARB) + { + std::vector attribs = wgl::GetDefaultPixelFormatAttributes(false); + + UINT matchingFormats = 0; + mFunctionsWGL->choosePixelFormatARB(mDeviceContext, &attribs[0], nullptr, 1u, &mPixelFormat, + &matchingFormats); + } + + if (mPixelFormat == 0) + { + mPixelFormat = ChoosePixelFormat(mDeviceContext, &pixelFormatDescriptor); + } + if (mPixelFormat == 0) { return egl::Error(EGL_NOT_INITIALIZED, "Could not find a compatible pixel format for the intermediate OpenGL window."); @@ -238,37 +246,67 @@ egl::Error DisplayWGL::initialize(egl::Display *display) // TODO: handle robustness int mask = 0; - // Request core profile, TODO: Don't request core if requested GL version is less than 3.0 - mask |= WGL_CONTEXT_CORE_PROFILE_BIT_ARB; - std::vector contextCreationAttibutes; + if (requestedDisplayType == EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE) + { + mask |= WGL_CONTEXT_ES_PROFILE_BIT_EXT; + } + else + { + // Request core profile + mask |= WGL_CONTEXT_CORE_PROFILE_BIT_ARB; + } + + std::vector contextCreationAttributes; - // TODO: create a context version based on the requested version and validate the version numbers - contextCreationAttibutes.push_back(WGL_CONTEXT_MAJOR_VERSION_ARB); - contextCreationAttibutes.push_back(3); + // Don't request a specific version unless the user wants one. WGL will return the highest version + // that the driver supports if no version is requested. + EGLint requestedMajorVersion = static_cast( + displayAttributes.get(EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE, EGL_DONT_CARE)); + EGLint requestedMinorVersion = static_cast( + displayAttributes.get(EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE, EGL_DONT_CARE)); + if (requestedMajorVersion != EGL_DONT_CARE && requestedMinorVersion != EGL_DONT_CARE) + { + contextCreationAttributes.push_back(WGL_CONTEXT_MAJOR_VERSION_ARB); + contextCreationAttributes.push_back(requestedMajorVersion); - contextCreationAttibutes.push_back(WGL_CONTEXT_MINOR_VERSION_ARB); - contextCreationAttibutes.push_back(1); + contextCreationAttributes.push_back(WGL_CONTEXT_MINOR_VERSION_ARB); + contextCreationAttributes.push_back(requestedMinorVersion); + } + else + { + // the ES profile will give us ES version 1.1 unless a higher version is requested. + // Requesting version 2.0 will give us the highest compatible version available (2.0, + // 3.0, 3.1, etc). + if (requestedDisplayType == EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE) + { + contextCreationAttributes.push_back(WGL_CONTEXT_MAJOR_VERSION_ARB); + contextCreationAttributes.push_back(2); + + contextCreationAttributes.push_back(WGL_CONTEXT_MINOR_VERSION_ARB); + contextCreationAttributes.push_back(0); + } + } // Set the flag attributes if (flags != 0) { - contextCreationAttibutes.push_back(WGL_CONTEXT_FLAGS_ARB); - contextCreationAttibutes.push_back(flags); + contextCreationAttributes.push_back(WGL_CONTEXT_FLAGS_ARB); + contextCreationAttributes.push_back(flags); } // Set the mask attribute if (mask != 0) { - contextCreationAttibutes.push_back(WGL_CONTEXT_PROFILE_MASK_ARB); - contextCreationAttibutes.push_back(mask); + contextCreationAttributes.push_back(WGL_CONTEXT_PROFILE_MASK_ARB); + contextCreationAttributes.push_back(mask); } // Signal the end of the attributes - contextCreationAttibutes.push_back(0); - contextCreationAttibutes.push_back(0); + contextCreationAttributes.push_back(0); + contextCreationAttributes.push_back(0); - mWGLContext = mFunctionsWGL->createContextAttribsARB(mDeviceContext, NULL, &contextCreationAttibutes[0]); + mWGLContext = mFunctionsWGL->createContextAttribsARB(mDeviceContext, NULL, &contextCreationAttributes[0]); } // If wglCreateContextAttribsARB is unavailable or failed, try the standard wglCreateContext @@ -291,6 +329,38 @@ egl::Error DisplayWGL::initialize(egl::Display *display) mFunctionsGL = new FunctionsGLWindows(mOpenGLModule, mFunctionsWGL->getProcAddress); mFunctionsGL->initialize(); + // Intel OpenGL ES drivers are not currently supported due to bugs in the driver and ANGLE + VendorID vendor = GetVendorID(mFunctionsGL); + if (requestedDisplayType == EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE && vendor == VENDOR_ID_INTEL) + { + return egl::Error(EGL_NOT_INITIALIZED, "Intel OpenGL ES drivers are not supported."); + } + + // Create DXGI swap chains for windows that come from other processes. Windows is unable to + // SetPixelFormat on windows from other processes when a sandbox is enabled. + HDC nativeDisplay = display->getNativeDisplayId(); + HWND nativeWindow = WindowFromDC(nativeDisplay); + if (nativeWindow != nullptr) + { + DWORD currentProcessId = GetCurrentProcessId(); + DWORD windowProcessId; + GetWindowThreadProcessId(nativeWindow, &windowProcessId); + mUseDXGISwapChains = (currentProcessId != windowProcessId); + } + else + { + mUseDXGISwapChains = false; + } + + if (mUseDXGISwapChains) + { + egl::Error error = initializeD3DDevice(); + if (error.isError()) + { + return error; + } + } + return DisplayGL::initialize(display); } @@ -298,6 +368,8 @@ void DisplayWGL::terminate() { DisplayGL::terminate(); + releaseD3DDevice(mD3D11DeviceHandle); + mFunctionsWGL->makeCurrent(mDeviceContext, NULL); mFunctionsWGL->deleteContext(mWGLContext); mWGLContext = NULL; @@ -316,68 +388,69 @@ void DisplayWGL::terminate() FreeLibrary(mOpenGLModule); mOpenGLModule = nullptr; -} -egl::Error DisplayWGL::createWindowSurface(const egl::Config *configuration, EGLNativeWindowType window, - const egl::AttributeMap &attribs, SurfaceImpl **outSurface) -{ - WindowSurfaceWGL *surface = new WindowSurfaceWGL(window, mWindowClass, mPixelFormat, mWGLContext, mFunctionsWGL); - egl::Error error = surface->initialize(); - if (error.isError()) + SafeRelease(mD3D11Device); + + if (mDxgiModule) { - SafeDelete(surface); - return error; + FreeLibrary(mDxgiModule); + mDxgiModule = nullptr; } - *outSurface = surface; - return egl::Error(EGL_SUCCESS); + if (mD3d11Module) + { + FreeLibrary(mD3d11Module); + mD3d11Module = nullptr; + } + + ASSERT(mRegisteredD3DDevices.empty()); } -egl::Error DisplayWGL::createPbufferSurface(const egl::Config *configuration, const egl::AttributeMap &attribs, - SurfaceImpl **outSurface) +SurfaceImpl *DisplayWGL::createWindowSurface(const egl::Config *configuration, + EGLNativeWindowType window, + const egl::AttributeMap &attribs) { - EGLint width = attribs.get(EGL_WIDTH, 0); - EGLint height = attribs.get(EGL_HEIGHT, 0); - bool largest = (attribs.get(EGL_LARGEST_PBUFFER, EGL_FALSE) == EGL_TRUE); - EGLenum textureFormat = attribs.get(EGL_TEXTURE_FORMAT, EGL_NO_TEXTURE); - EGLenum textureTarget = attribs.get(EGL_TEXTURE_TARGET, EGL_NO_TEXTURE); - - PbufferSurfaceWGL *surface = new PbufferSurfaceWGL(width, height, textureFormat, textureTarget, largest, - mPixelFormat, mDeviceContext, mWGLContext, mFunctionsWGL); - egl::Error error = surface->initialize(); - if (error.isError()) + EGLint orientation = static_cast(attribs.get(EGL_SURFACE_ORIENTATION_ANGLE, 0)); + if (mUseDXGISwapChains) { - SafeDelete(surface); - return error; + return new DXGISwapChainWindowSurfaceWGL(this->getRenderer(), window, mD3D11Device, + mD3D11DeviceHandle, mWGLContext, mDeviceContext, + mFunctionsGL, mFunctionsWGL, orientation); + } + else + { + return new WindowSurfaceWGL(this->getRenderer(), window, mPixelFormat, mWGLContext, + mFunctionsWGL, orientation); } - - *outSurface = surface; - return egl::Error(EGL_SUCCESS); } -egl::Error DisplayWGL::createPbufferFromClientBuffer(const egl::Config *configuration, EGLClientBuffer shareHandle, - const egl::AttributeMap &attribs, SurfaceImpl **outSurface) +SurfaceImpl *DisplayWGL::createPbufferSurface(const egl::Config *configuration, + const egl::AttributeMap &attribs) { - UNIMPLEMENTED(); - return egl::Error(EGL_BAD_DISPLAY); + EGLint width = static_cast(attribs.get(EGL_WIDTH, 0)); + EGLint height = static_cast(attribs.get(EGL_HEIGHT, 0)); + bool largest = (attribs.get(EGL_LARGEST_PBUFFER, EGL_FALSE) == EGL_TRUE); + EGLenum textureFormat = static_cast(attribs.get(EGL_TEXTURE_FORMAT, EGL_NO_TEXTURE)); + EGLenum textureTarget = static_cast(attribs.get(EGL_TEXTURE_TARGET, EGL_NO_TEXTURE)); + + return new PbufferSurfaceWGL(this->getRenderer(), width, height, textureFormat, textureTarget, + largest, mPixelFormat, mDeviceContext, mWGLContext, mFunctionsWGL); } -egl::Error DisplayWGL::createPixmapSurface(const egl::Config *configuration, NativePixmapType nativePixmap, - const egl::AttributeMap &attribs, SurfaceImpl **outSurface) +SurfaceImpl *DisplayWGL::createPbufferFromClientBuffer(const egl::Config *configuration, + EGLClientBuffer shareHandle, + const egl::AttributeMap &attribs) { UNIMPLEMENTED(); - return egl::Error(EGL_BAD_DISPLAY); + return nullptr; } -static int QueryWGLFormatAttrib(HDC dc, int format, int attribName, const FunctionsWGL *functions) +SurfaceImpl *DisplayWGL::createPixmapSurface(const egl::Config *configuration, + NativePixmapType nativePixmap, + const egl::AttributeMap &attribs) { - int result = 0; - if (functions->getPixelFormatAttribivARB == nullptr || - !functions->getPixelFormatAttribivARB(dc, format, 0, 1, &attribName, &result)) - { - return 0; - } - return result; + UNIMPLEMENTED(); + return nullptr; } egl::Error DisplayWGL::getDevice(DeviceImpl **device) @@ -399,9 +472,21 @@ egl::ConfigSet DisplayWGL::generateConfigs() const maxSwapInterval = 8; } + const gl::Version &maxVersion = getMaxSupportedESVersion(); + ASSERT(maxVersion >= gl::Version(2, 0)); + bool supportsES3 = maxVersion >= gl::Version(3, 0); + PIXELFORMATDESCRIPTOR pixelFormatDescriptor; DescribePixelFormat(mDeviceContext, mPixelFormat, sizeof(pixelFormatDescriptor), &pixelFormatDescriptor); + auto getAttrib = [this](int attrib) + { + return wgl::QueryWGLFormatAttrib(mDeviceContext, mPixelFormat, attrib, mFunctionsWGL); + }; + + const EGLint optimalSurfaceOrientation = + mUseDXGISwapChains ? EGL_SURFACE_ORIENTATION_INVERT_Y_ANGLE : 0; + egl::Config config; config.renderTargetFormat = GL_RGBA8; // TODO: use the bit counts to determine the format config.depthStencilFormat = GL_DEPTH24_STENCIL8; // TODO: use the bit counts to determine the format @@ -412,30 +497,33 @@ egl::ConfigSet DisplayWGL::generateConfigs() const config.luminanceSize = 0; config.alphaSize = pixelFormatDescriptor.cAlphaBits; config.alphaMaskSize = 0; - config.bindToTextureRGB = (QueryWGLFormatAttrib(mDeviceContext, mPixelFormat, WGL_BIND_TO_TEXTURE_RGB_ARB, mFunctionsWGL) == TRUE); - config.bindToTextureRGBA = (QueryWGLFormatAttrib(mDeviceContext, mPixelFormat, WGL_BIND_TO_TEXTURE_RGBA_ARB, mFunctionsWGL) == TRUE); + config.bindToTextureRGB = (getAttrib(WGL_BIND_TO_TEXTURE_RGB_ARB) == TRUE); + config.bindToTextureRGBA = (getAttrib(WGL_BIND_TO_TEXTURE_RGBA_ARB) == TRUE); config.colorBufferType = EGL_RGB_BUFFER; config.configCaveat = EGL_NONE; - config.configID = mPixelFormat; - config.conformant = EGL_OPENGL_ES2_BIT | EGL_OPENGL_ES3_BIT_KHR; // TODO: determine the GL version and what ES versions it supports + config.conformant = EGL_OPENGL_ES2_BIT | (supportsES3 ? EGL_OPENGL_ES3_BIT_KHR : 0); config.depthSize = pixelFormatDescriptor.cDepthBits; config.level = 0; config.matchNativePixmap = EGL_NONE; - config.maxPBufferWidth = QueryWGLFormatAttrib(mDeviceContext, mPixelFormat, WGL_MAX_PBUFFER_WIDTH_ARB, mFunctionsWGL); - config.maxPBufferHeight = QueryWGLFormatAttrib(mDeviceContext, mPixelFormat, WGL_MAX_PBUFFER_HEIGHT_ARB, mFunctionsWGL); - config.maxPBufferPixels = QueryWGLFormatAttrib(mDeviceContext, mPixelFormat, WGL_MAX_PBUFFER_PIXELS_ARB, mFunctionsWGL); + config.maxPBufferWidth = getAttrib(WGL_MAX_PBUFFER_WIDTH_ARB); + config.maxPBufferHeight = getAttrib(WGL_MAX_PBUFFER_HEIGHT_ARB); + config.maxPBufferPixels = getAttrib(WGL_MAX_PBUFFER_PIXELS_ARB); config.maxSwapInterval = maxSwapInterval; config.minSwapInterval = minSwapInterval; config.nativeRenderable = EGL_TRUE; // Direct rendering config.nativeVisualID = 0; config.nativeVisualType = EGL_NONE; - config.renderableType = EGL_OPENGL_ES2_BIT | EGL_OPENGL_ES3_BIT_KHR; // TODO + config.renderableType = EGL_OPENGL_ES2_BIT | (supportsES3 ? EGL_OPENGL_ES3_BIT_KHR : 0); config.sampleBuffers = 0; // FIXME: enumerate multi-sampling config.samples = 0; config.stencilSize = pixelFormatDescriptor.cStencilBits; - config.surfaceType = ((pixelFormatDescriptor.dwFlags & PFD_DRAW_TO_WINDOW) ? EGL_WINDOW_BIT : 0) | - ((QueryWGLFormatAttrib(mDeviceContext, mPixelFormat, WGL_DRAW_TO_PBUFFER_ARB, mFunctionsWGL) == TRUE) ? EGL_PBUFFER_BIT : 0) | - EGL_SWAP_BEHAVIOR_PRESERVED_BIT; + config.surfaceType = + ((pixelFormatDescriptor.dwFlags & PFD_DRAW_TO_WINDOW) ? EGL_WINDOW_BIT : 0) | + ((getAttrib(WGL_DRAW_TO_PBUFFER_ARB) == TRUE) ? EGL_PBUFFER_BIT : 0) | + ((getAttrib(WGL_SWAP_METHOD_ARB) == WGL_SWAP_COPY_ARB) ? EGL_SWAP_BEHAVIOR_PRESERVED_BIT + : 0); + config.optimalOrientation = optimalSurfaceOrientation; + config.transparentType = EGL_NONE; config.transparentRedValue = 0; config.transparentGreenValue = 0; @@ -480,9 +568,60 @@ const FunctionsGL *DisplayWGL::getFunctionsGL() const return mFunctionsGL; } +egl::Error DisplayWGL::initializeD3DDevice() +{ + if (mD3D11Device != nullptr) + { + return egl::Error(EGL_SUCCESS); + } + + mDxgiModule = LoadLibrary(TEXT("dxgi.dll")); + if (!mDxgiModule) + { + return egl::Error(EGL_NOT_INITIALIZED, "Failed to load DXGI library."); + } + + mD3d11Module = LoadLibrary(TEXT("d3d11.dll")); + if (!mD3d11Module) + { + return egl::Error(EGL_NOT_INITIALIZED, "Failed to load d3d11 library."); + } + + PFN_D3D11_CREATE_DEVICE d3d11CreateDevice = nullptr; + d3d11CreateDevice = reinterpret_cast( + GetProcAddress(mD3d11Module, "D3D11CreateDevice")); + if (d3d11CreateDevice == nullptr) + { + return egl::Error(EGL_NOT_INITIALIZED, "Could not retrieve D3D11CreateDevice address."); + } + + HRESULT result = d3d11CreateDevice(nullptr, D3D_DRIVER_TYPE_HARDWARE, nullptr, 0, nullptr, 0, + D3D11_SDK_VERSION, &mD3D11Device, nullptr, nullptr); + if (FAILED(result)) + { + return egl::Error(EGL_NOT_INITIALIZED, "Could not create D3D11 device, error: 0x%X", + result); + } + + egl::Error error = registerD3DDevice(mD3D11Device, &mD3D11DeviceHandle); + if (error.isError()) + { + return error; + } + + return egl::Error(EGL_SUCCESS); +} + void DisplayWGL::generateExtensions(egl::DisplayExtensions *outExtensions) const { - //UNIMPLEMENTED(); + outExtensions->createContext = true; + outExtensions->createContextNoError = true; + + // Only enable the surface orientation and post sub buffer for DXGI swap chain surfaces, they + // prefer to swap with + // inverted Y. + outExtensions->postSubBuffer = mUseDXGISwapChains; + outExtensions->surfaceOrientation = mUseDXGISwapChains; } void DisplayWGL::generateCaps(egl::Caps *outCaps) const @@ -490,4 +629,71 @@ void DisplayWGL::generateCaps(egl::Caps *outCaps) const outCaps->textureNPOT = true; } +egl::Error DisplayWGL::waitClient() const +{ + // Unimplemented as this is not needed for WGL + return egl::Error(EGL_SUCCESS); +} + +egl::Error DisplayWGL::waitNative(EGLint engine, + egl::Surface *drawSurface, + egl::Surface *readSurface) const +{ + // Unimplemented as this is not needed for WGL + return egl::Error(EGL_SUCCESS); +} + +egl::Error DisplayWGL::getDriverVersion(std::string *version) const +{ + *version = ""; + return egl::Error(EGL_SUCCESS); +} + +egl::Error DisplayWGL::registerD3DDevice(IUnknown *device, HANDLE *outHandle) +{ + ASSERT(device != nullptr); + ASSERT(outHandle != nullptr); + + auto iter = mRegisteredD3DDevices.find(device); + if (iter != mRegisteredD3DDevices.end()) + { + iter->second.refCount++; + *outHandle = iter->second.handle; + return egl::Error(EGL_SUCCESS); + } + + HANDLE handle = mFunctionsWGL->dxOpenDeviceNV(device); + if (!handle) + { + return egl::Error(EGL_BAD_PARAMETER, "Failed to open D3D device."); + } + + device->AddRef(); + + D3DObjectHandle newDeviceInfo; + newDeviceInfo.handle = handle; + newDeviceInfo.refCount = 1; + mRegisteredD3DDevices[device] = newDeviceInfo; + + *outHandle = handle; + return egl::Error(EGL_SUCCESS); +} + +void DisplayWGL::releaseD3DDevice(HANDLE deviceHandle) +{ + for (auto iter = mRegisteredD3DDevices.begin(); iter != mRegisteredD3DDevices.end(); iter++) + { + if (iter->second.handle == deviceHandle) + { + iter->second.refCount--; + if (iter->second.refCount == 0) + { + mFunctionsWGL->dxCloseDeviceNV(iter->second.handle); + iter->first->Release(); + mRegisteredD3DDevices.erase(iter); + break; + } + } + } +} } diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/wgl/DisplayWGL.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/wgl/DisplayWGL.h index 75de2a2676d7..08e3e91f668f 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/wgl/DisplayWGL.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/wgl/DisplayWGL.h @@ -27,14 +27,18 @@ class DisplayWGL : public DisplayGL egl::Error initialize(egl::Display *display) override; void terminate() override; - egl::Error createWindowSurface(const egl::Config *configuration, EGLNativeWindowType window, const egl::AttributeMap &attribs, - SurfaceImpl **outSurface) override; - egl::Error createPbufferSurface(const egl::Config *configuration, const egl::AttributeMap &attribs, - SurfaceImpl **outSurface) override; - egl::Error createPbufferFromClientBuffer(const egl::Config *configuration, EGLClientBuffer shareHandle, - const egl::AttributeMap &attribs, SurfaceImpl **outSurface) override; - egl::Error createPixmapSurface(const egl::Config *configuration, NativePixmapType nativePixmap, - const egl::AttributeMap &attribs, SurfaceImpl **outSurface) override; + // Surface creation + SurfaceImpl *createWindowSurface(const egl::Config *configuration, + EGLNativeWindowType window, + const egl::AttributeMap &attribs) override; + SurfaceImpl *createPbufferSurface(const egl::Config *configuration, + const egl::AttributeMap &attribs) override; + SurfaceImpl *createPbufferFromClientBuffer(const egl::Config *configuration, + EGLClientBuffer shareHandle, + const egl::AttributeMap &attribs) override; + SurfaceImpl *createPixmapSurface(const egl::Config *configuration, + NativePixmapType nativePixmap, + const egl::AttributeMap &attribs) override; egl::ConfigSet generateConfigs() const override; @@ -48,9 +52,21 @@ class DisplayWGL : public DisplayGL std::string getVendorString() const override; + egl::Error waitClient() const override; + egl::Error waitNative(EGLint engine, + egl::Surface *drawSurface, + egl::Surface *readSurface) const override; + + egl::Error getDriverVersion(std::string *version) const override; + + egl::Error registerD3DDevice(IUnknown *device, HANDLE *outHandle); + void releaseD3DDevice(HANDLE handle); + private: const FunctionsGL *getFunctionsGL() const override; + egl::Error initializeD3DDevice(); + void generateExtensions(egl::DisplayExtensions *outExtensions) const override; void generateCaps(egl::Caps *outCaps) const override; @@ -65,6 +81,19 @@ class DisplayWGL : public DisplayGL int mPixelFormat; HGLRC mWGLContext; + bool mUseDXGISwapChains; + HMODULE mDxgiModule; + HMODULE mD3d11Module; + HANDLE mD3D11DeviceHandle; + ID3D11Device *mD3D11Device; + + struct D3DObjectHandle + { + HANDLE handle; + size_t refCount; + }; + std::map mRegisteredD3DDevices; + egl::Display *mDisplay; }; diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/wgl/FunctionsWGL.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/wgl/FunctionsWGL.cpp index e2e7b378aeeb..2cfe6e9eb951 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/wgl/FunctionsWGL.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/wgl/FunctionsWGL.cpp @@ -8,6 +8,10 @@ #include "libANGLE/renderer/gl/wgl/FunctionsWGL.h" +#include + +#include "common/string_utils.h" + namespace rx { @@ -30,12 +34,15 @@ static void GetWGLProcAddress(HMODULE glModule, PFNWGLGETPROCADDRESSPROC getProc } template -static void GetWGLExtensionProcAddress(HMODULE glModule, PFNWGLGETPROCADDRESSPROC getProcAddressWGL, - const std::string &extensions, const std::string &extensionName, - const std::string &procName, T *outProcAddress) +static void GetWGLExtensionProcAddress(HMODULE glModule, + PFNWGLGETPROCADDRESSPROC getProcAddressWGL, + const std::vector &extensions, + const std::string &extensionName, + const std::string &procName, + T *outProcAddress) { T proc = nullptr; - if (extensions.find(extensionName) != std::string::npos) + if (std::find(extensions.begin(), extensions.end(), extensionName) != extensions.end()) { GetWGLProcAddress(glModule, getProcAddressWGL, procName, &proc); } @@ -64,10 +71,12 @@ FunctionsWGL::FunctionsWGL() realizeLayerPalette(nullptr), swapLayerBuffers(nullptr), swapMultipleBuffers(nullptr), - createContextAttribsARB(nullptr), - getPixelFormatAttribivARB(nullptr), getExtensionStringEXT(nullptr), getExtensionStringARB(nullptr), + createContextAttribsARB(nullptr), + getPixelFormatAttribivARB(nullptr), + getPixelFormatAttribfvARB(nullptr), + choosePixelFormatARB(nullptr), swapIntervalEXT(nullptr), createPbufferARB(nullptr), getPbufferDCARB(nullptr), @@ -76,7 +85,15 @@ FunctionsWGL::FunctionsWGL() queryPbufferARB(nullptr), bindTexImageARB(nullptr), releaseTexImageARB(nullptr), - setPbufferAttribARB(nullptr) + setPbufferAttribARB(nullptr), + dxSetResourceShareHandleNV(nullptr), + dxOpenDeviceNV(nullptr), + dxCloseDeviceNV(nullptr), + dxRegisterObjectNV(nullptr), + dxUnregisterObjectNV(nullptr), + dxObjectAccessNV(nullptr), + dxLockObjectsNV(nullptr), + dxUnlockObjectsNV(nullptr) { } @@ -110,19 +127,28 @@ void FunctionsWGL::initialize(HMODULE glModule, HDC context) GetWGLProcAddress(glModule, getProcAddress, "wglGetExtensionsStringEXT", &getExtensionStringEXT); GetWGLProcAddress(glModule, getProcAddress, "wglGetExtensionsStringARB", &getExtensionStringARB); - std::string extensions = ""; + std::string extensionString = ""; if (getExtensionStringEXT) { - extensions = getExtensionStringEXT(); + extensionString = getExtensionStringEXT(); } else if (getExtensionStringARB && context) { - extensions = getExtensionStringARB(context); + extensionString = getExtensionStringARB(context); } + angle::SplitStringAlongWhitespace(extensionString, &extensions); // Load the wgl extension functions by checking if the context supports the extension first + + // WGL_ARB_create_context GetWGLExtensionProcAddress(glModule, getProcAddress, extensions, "WGL_ARB_create_context", "wglCreateContextAttribsARB", &createContextAttribsARB); + + // WGL_ARB_pixel_format GetWGLExtensionProcAddress(glModule, getProcAddress, extensions, "WGL_ARB_pixel_format", "wglGetPixelFormatAttribivARB", &getPixelFormatAttribivARB); + GetWGLExtensionProcAddress(glModule, getProcAddress, extensions, "WGL_ARB_pixel_format", "wglGetPixelFormatAttribfvARB", &getPixelFormatAttribfvARB); + GetWGLExtensionProcAddress(glModule, getProcAddress, extensions, "WGL_ARB_pixel_format", "wglChoosePixelFormatARB", &choosePixelFormatARB); + + // WGL_EXT_swap_control GetWGLExtensionProcAddress(glModule, getProcAddress, extensions, "WGL_EXT_swap_control", "wglSwapIntervalEXT", &swapIntervalEXT); // WGL_ARB_pbuffer @@ -136,6 +162,20 @@ void FunctionsWGL::initialize(HMODULE glModule, HDC context) GetWGLExtensionProcAddress(glModule, getProcAddress, extensions, "WGL_ARB_render_texture", "wglBindTexImageARB", &bindTexImageARB); GetWGLExtensionProcAddress(glModule, getProcAddress, extensions, "WGL_ARB_render_texture", "wglReleaseTexImageARB", &releaseTexImageARB); GetWGLExtensionProcAddress(glModule, getProcAddress, extensions, "WGL_ARB_render_texture", "wglSetPbufferAttribARB", &setPbufferAttribARB); + + // WGL_NV_DX_interop + GetWGLExtensionProcAddress(glModule, getProcAddress, extensions, "WGL_NV_DX_interop", "wglDXSetResourceShareHandleNV", &dxSetResourceShareHandleNV); + GetWGLExtensionProcAddress(glModule, getProcAddress, extensions, "WGL_NV_DX_interop", "wglDXOpenDeviceNV", &dxOpenDeviceNV); + GetWGLExtensionProcAddress(glModule, getProcAddress, extensions, "WGL_NV_DX_interop", "wglDXCloseDeviceNV", &dxCloseDeviceNV); + GetWGLExtensionProcAddress(glModule, getProcAddress, extensions, "WGL_NV_DX_interop", "wglDXRegisterObjectNV", &dxRegisterObjectNV); + GetWGLExtensionProcAddress(glModule, getProcAddress, extensions, "WGL_NV_DX_interop", "wglDXUnregisterObjectNV", &dxUnregisterObjectNV); + GetWGLExtensionProcAddress(glModule, getProcAddress, extensions, "WGL_NV_DX_interop", "wglDXObjectAccessNV", &dxObjectAccessNV); + GetWGLExtensionProcAddress(glModule, getProcAddress, extensions, "WGL_NV_DX_interop", "wglDXLockObjectsNV", &dxLockObjectsNV); + GetWGLExtensionProcAddress(glModule, getProcAddress, extensions, "WGL_NV_DX_interop", "wglDXUnlockObjectsNV", &dxUnlockObjectsNV); } +bool FunctionsWGL::hasExtension(const std::string &ext) const +{ + return std::find(extensions.begin(), extensions.end(), ext) != extensions.end(); +} } diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/wgl/FunctionsWGL.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/wgl/FunctionsWGL.h index e869e923d1d4..30cf9ebc0b0c 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/wgl/FunctionsWGL.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/wgl/FunctionsWGL.h @@ -6,6 +6,9 @@ // FunctionsWGL.h: Defines the FuntionsWGL class to contain loaded WGL functions +#ifndef LIBANGLE_RENDERER_GL_WGL_FUNCTIONS_WGL +#define LIBANGLE_RENDERER_GL_WGL_FUNCTIONS_WGL + #include "common/angleutils.h" #include "libANGLE/renderer/gl/wgl/functionswgl_typedefs.h" @@ -20,6 +23,10 @@ class FunctionsWGL : angle::NonCopyable // Loads all available wgl functions, may be called multiple times void initialize(HMODULE glModule, HDC context); + // Extension information + std::vector extensions; + bool hasExtension(const std::string &ext) const; + // Base WGL functions PFNWGLCOPYCONTEXTPROC copyContext; PFNWGLCREATECONTEXTPROC createContext; @@ -42,11 +49,21 @@ class FunctionsWGL : angle::NonCopyable PFNWGLSWAPLAYERBUFFERSPROC swapLayerBuffers; PFNWGLSWAPMULTIPLEBUFFERSPROC swapMultipleBuffers; - // Extension functions, may be NULL - PFNWGLCREATECONTEXTATTRIBSARBPROC createContextAttribsARB; - PFNWGLGETPIXELFORMATATTRIBIVARBPROC getPixelFormatAttribivARB; + // WGL_EXT_extensions_string PFNWGLGETEXTENSIONSSTRINGEXTPROC getExtensionStringEXT; + + // WGL_ARB_extensions_string PFNWGLGETEXTENSIONSSTRINGARBPROC getExtensionStringARB; + + // WGL_ARB_create_context + PFNWGLCREATECONTEXTATTRIBSARBPROC createContextAttribsARB; + + // WGL_ARB_pixel_format + PFNWGLGETPIXELFORMATATTRIBIVARBPROC getPixelFormatAttribivARB; + PFNWGLGETPIXELFORMATATTRIBFVARBPROC getPixelFormatAttribfvARB; + PFNWGLCHOOSEPIXELFORMATARBPROC choosePixelFormatARB; + + // WGL_EXT_swap_control PFNWGLSWAPINTERVALEXTPROC swapIntervalEXT; // WGL_ARB_pbuffer @@ -60,6 +77,18 @@ class FunctionsWGL : angle::NonCopyable PFNWGLBINDTEXIMAGEARBPROC bindTexImageARB; PFNWGLRELEASETEXIMAGEARBPROC releaseTexImageARB; PFNWGLSETPBUFFERATTRIBARBPROC setPbufferAttribARB; + + // WGL_NV_DX_interop + PFNWGLDXSETRESOURCESHAREHANDLENVPROC dxSetResourceShareHandleNV; + PFNWGLDXOPENDEVICENVPROC dxOpenDeviceNV; + PFNWGLDXCLOSEDEVICENVPROC dxCloseDeviceNV; + PFNWGLDXREGISTEROBJECTNVPROC dxRegisterObjectNV; + PFNWGLDXUNREGISTEROBJECTNVPROC dxUnregisterObjectNV; + PFNWGLDXOBJECTACCESSNVPROC dxObjectAccessNV; + PFNWGLDXLOCKOBJECTSNVPROC dxLockObjectsNV; + PFNWGLDXUNLOCKOBJECTSNVPROC dxUnlockObjectsNV; }; } + +#endif // LIBANGLE_RENDERER_GL_WGL_FUNCTIONS_WGL diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/wgl/PbufferSurfaceWGL.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/wgl/PbufferSurfaceWGL.cpp index d1f19e3bf06d..440b9934c474 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/wgl/PbufferSurfaceWGL.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/wgl/PbufferSurfaceWGL.cpp @@ -9,24 +9,32 @@ #include "libANGLE/renderer/gl/wgl/PbufferSurfaceWGL.h" #include "common/debug.h" +#include "libANGLE/renderer/gl/RendererGL.h" #include "libANGLE/renderer/gl/wgl/FunctionsWGL.h" #include "libANGLE/renderer/gl/wgl/wgl_utils.h" namespace rx { -PbufferSurfaceWGL::PbufferSurfaceWGL(EGLint width, EGLint height, EGLenum textureFormat, EGLenum textureTarget, - bool largest, int pixelFormat, HDC deviceContext, HGLRC wglContext, +PbufferSurfaceWGL::PbufferSurfaceWGL(RendererGL *renderer, + EGLint width, + EGLint height, + EGLenum textureFormat, + EGLenum textureTarget, + bool largest, + int pixelFormat, + HDC deviceContext, + HGLRC wglContext, const FunctionsWGL *functions) - : SurfaceGL(), + : SurfaceGL(renderer), mWidth(width), mHeight(height), mLargest(largest), mTextureFormat(textureFormat), mTextureTarget(textureTarget), mPixelFormat(pixelFormat), - mParentDeviceContext(deviceContext), mShareWGLContext(wglContext), + mParentDeviceContext(deviceContext), mPbuffer(nullptr), mPbufferDeviceContext(nullptr), mFunctionsWGL(functions) @@ -138,7 +146,7 @@ static int GetWGLBufferBindTarget(EGLint buffer) } } -egl::Error PbufferSurfaceWGL::bindTexImage(EGLint buffer) +egl::Error PbufferSurfaceWGL::bindTexImage(gl::Texture *texture, EGLint buffer) { if (!mFunctionsWGL->bindTexImageARB(mPbuffer, GetWGLBufferBindTarget(buffer))) { @@ -179,4 +187,9 @@ EGLint PbufferSurfaceWGL::isPostSubBufferSupported() const return EGL_FALSE; } +EGLint PbufferSurfaceWGL::getSwapBehavior() const +{ + return EGL_BUFFER_PRESERVED; +} + } diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/wgl/PbufferSurfaceWGL.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/wgl/PbufferSurfaceWGL.h index dd8659a160f6..64e4de16c6d5 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/wgl/PbufferSurfaceWGL.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/wgl/PbufferSurfaceWGL.h @@ -21,18 +21,25 @@ class FunctionsWGL; class PbufferSurfaceWGL : public SurfaceGL { public: - PbufferSurfaceWGL(EGLint width, EGLint height, EGLenum textureFormat, EGLenum textureTarget, - bool largest, int pixelFormat, HDC deviceContext, HGLRC wglContext, + PbufferSurfaceWGL(RendererGL *renderer, + EGLint width, + EGLint height, + EGLenum textureFormat, + EGLenum textureTarget, + bool largest, + int pixelFormat, + HDC deviceContext, + HGLRC wglContext, const FunctionsWGL *functions); ~PbufferSurfaceWGL() override; - egl::Error initialize(); + egl::Error initialize() override; egl::Error makeCurrent() override; egl::Error swap() override; egl::Error postSubBuffer(EGLint x, EGLint y, EGLint width, EGLint height) override; egl::Error querySurfacePointerANGLE(EGLint attribute, void **value) override; - egl::Error bindTexImage(EGLint buffer) override; + egl::Error bindTexImage(gl::Texture *texture, EGLint buffer) override; egl::Error releaseTexImage(EGLint buffer) override; void setSwapInterval(EGLint interval) override; @@ -40,6 +47,7 @@ class PbufferSurfaceWGL : public SurfaceGL EGLint getHeight() const override; EGLint isPostSubBufferSupported() const override; + EGLint getSwapBehavior() const override; private: EGLint mWidth; diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/wgl/WindowSurfaceWGL.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/wgl/WindowSurfaceWGL.cpp index 6f912c2d589b..1858dabd8af3 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/wgl/WindowSurfaceWGL.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/wgl/WindowSurfaceWGL.cpp @@ -9,74 +9,80 @@ #include "libANGLE/renderer/gl/wgl/WindowSurfaceWGL.h" #include "common/debug.h" +#include "libANGLE/renderer/gl/RendererGL.h" #include "libANGLE/renderer/gl/wgl/FunctionsWGL.h" #include "libANGLE/renderer/gl/wgl/wgl_utils.h" namespace rx { -WindowSurfaceWGL::WindowSurfaceWGL(EGLNativeWindowType window, ATOM windowClass, int pixelFormat, HGLRC wglContext, const FunctionsWGL *functions) - : SurfaceGL(), - mWindowClass(windowClass), +WindowSurfaceWGL::WindowSurfaceWGL(RendererGL *renderer, + EGLNativeWindowType window, + int pixelFormat, + HGLRC wglContext, + const FunctionsWGL *functions, + EGLint orientation) + : SurfaceGL(renderer), mPixelFormat(pixelFormat), - mShareWGLContext(wglContext), - mParentWindow(window), - mChildWindow(nullptr), - mChildDeviceContext(nullptr), - mFunctionsWGL(functions) + mWGLContext(wglContext), + mWindow(window), + mDeviceContext(nullptr), + mFunctionsWGL(functions), + mSwapBehavior(0) { + // EGL_ANGLE_surface_orientation is not supported for regular WGL window surfaces + ASSERT(orientation == 0); } WindowSurfaceWGL::~WindowSurfaceWGL() { - mWindowClass = 0; - mPixelFormat = 0; - mShareWGLContext = nullptr; - - ReleaseDC(mChildWindow, mChildDeviceContext); - mChildDeviceContext = nullptr; - - DestroyWindow(mChildWindow); - mChildWindow = nullptr; + ReleaseDC(mWindow, mDeviceContext); + mDeviceContext = nullptr; } egl::Error WindowSurfaceWGL::initialize() { - // Create a child window of the supplied window to draw to. - RECT rect; - if (!GetClientRect(mParentWindow, &rect)) + mDeviceContext = GetDC(mWindow); + if (!mDeviceContext) { - return egl::Error(EGL_BAD_NATIVE_WINDOW, "Failed to get the size of the native window."); + return egl::Error(EGL_BAD_NATIVE_WINDOW, "Failed to get the device context from the native window, " + "error: 0x%X.", GetLastError()); } - mChildWindow = CreateWindowExA(WS_EX_NOPARENTNOTIFY, - reinterpret_cast(mWindowClass), - "ANGLE Intermediate Surface Window", - WS_CHILDWINDOW | WS_DISABLED | WS_VISIBLE, - 0, - 0, - rect.right - rect.left, - rect.bottom - rect.top, - mParentWindow, - NULL, - NULL, - NULL); - if (!mChildWindow) + // Require that the pixel format for this window has not been set yet or is equal to the Display's pixel format. + int windowPixelFormat = GetPixelFormat(mDeviceContext); + if (windowPixelFormat == 0) { - return egl::Error(EGL_BAD_NATIVE_WINDOW, "Failed to create a child window."); + PIXELFORMATDESCRIPTOR pixelFormatDescriptor = { 0 }; + if (!DescribePixelFormat(mDeviceContext, mPixelFormat, sizeof(pixelFormatDescriptor), &pixelFormatDescriptor)) + { + return egl::Error(EGL_BAD_NATIVE_WINDOW, "Failed to DescribePixelFormat, error: 0x%X.", GetLastError()); + } + + if (!SetPixelFormat(mDeviceContext, mPixelFormat, &pixelFormatDescriptor)) + { + return egl::Error(EGL_NOT_INITIALIZED, "Failed to set the pixel format on the device context, " + "error: 0x%X.", GetLastError()); + } } - - mChildDeviceContext = GetDC(mChildWindow); - if (!mChildDeviceContext) + else if (windowPixelFormat != mPixelFormat) { - return egl::Error(EGL_BAD_NATIVE_WINDOW, "Failed to get the device context of the child window."); + return egl::Error(EGL_NOT_INITIALIZED, "Pixel format of the NativeWindow and NativeDisplayType must match."); } - const PIXELFORMATDESCRIPTOR pixelFormatDescriptor = wgl::GetDefaultPixelFormatDescriptor(); - - if (!SetPixelFormat(mChildDeviceContext, mPixelFormat, &pixelFormatDescriptor)) + // Check for the swap behavior of this pixel format + switch ( + wgl::QueryWGLFormatAttrib(mDeviceContext, mPixelFormat, WGL_SWAP_METHOD_ARB, mFunctionsWGL)) { - return egl::Error(EGL_BAD_NATIVE_WINDOW, "Failed to set the pixel format on the child window."); + case WGL_SWAP_COPY_ARB: + mSwapBehavior = EGL_BUFFER_PRESERVED; + break; + + case WGL_SWAP_EXCHANGE_ARB: + case WGL_SWAP_UNDEFINED_ARB: + default: + mSwapBehavior = EGL_BUFFER_DESTROYED; + break; } return egl::Error(EGL_SUCCESS); @@ -84,7 +90,7 @@ egl::Error WindowSurfaceWGL::initialize() egl::Error WindowSurfaceWGL::makeCurrent() { - if (!mFunctionsWGL->makeCurrent(mChildDeviceContext, mShareWGLContext)) + if (!mFunctionsWGL->makeCurrent(mDeviceContext, mWGLContext)) { // TODO: What error type here? return egl::Error(EGL_CONTEXT_LOST, "Failed to make the WGL context current."); @@ -95,21 +101,7 @@ egl::Error WindowSurfaceWGL::makeCurrent() egl::Error WindowSurfaceWGL::swap() { - // Resize the child window to the interior of the parent window. - RECT rect; - if (!GetClientRect(mParentWindow, &rect)) - { - // TODO: What error type here? - return egl::Error(EGL_CONTEXT_LOST, "Failed to get the size of the native window."); - } - - if (!MoveWindow(mChildWindow, 0, 0, rect.right - rect.left, rect.bottom - rect.top, FALSE)) - { - // TODO: What error type here? - return egl::Error(EGL_CONTEXT_LOST, "Failed to move the child window."); - } - - if (!mFunctionsWGL->swapBuffers(mChildDeviceContext)) + if (!mFunctionsWGL->swapBuffers(mDeviceContext)) { // TODO: What error type here? return egl::Error(EGL_CONTEXT_LOST, "Failed to swap buffers on the child window."); @@ -130,7 +122,7 @@ egl::Error WindowSurfaceWGL::querySurfacePointerANGLE(EGLint attribute, void **v return egl::Error(EGL_SUCCESS); } -egl::Error WindowSurfaceWGL::bindTexImage(EGLint buffer) +egl::Error WindowSurfaceWGL::bindTexImage(gl::Texture *texture, EGLint buffer) { UNIMPLEMENTED(); return egl::Error(EGL_SUCCESS); @@ -153,7 +145,7 @@ void WindowSurfaceWGL::setSwapInterval(EGLint interval) EGLint WindowSurfaceWGL::getWidth() const { RECT rect; - if (!GetClientRect(mParentWindow, &rect)) + if (!GetClientRect(mWindow, &rect)) { return 0; } @@ -163,7 +155,7 @@ EGLint WindowSurfaceWGL::getWidth() const EGLint WindowSurfaceWGL::getHeight() const { RECT rect; - if (!GetClientRect(mParentWindow, &rect)) + if (!GetClientRect(mWindow, &rect)) { return 0; } @@ -177,4 +169,9 @@ EGLint WindowSurfaceWGL::isPostSubBufferSupported() const return EGL_FALSE; } +EGLint WindowSurfaceWGL::getSwapBehavior() const +{ + return mSwapBehavior; +} + } diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/wgl/WindowSurfaceWGL.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/wgl/WindowSurfaceWGL.h index a1ec18b738f8..e7051b77e99e 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/wgl/WindowSurfaceWGL.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/wgl/WindowSurfaceWGL.h @@ -21,16 +21,21 @@ class FunctionsWGL; class WindowSurfaceWGL : public SurfaceGL { public: - WindowSurfaceWGL(EGLNativeWindowType window, ATOM windowClass, int pixelFormat, HGLRC wglContext, const FunctionsWGL *functions); + WindowSurfaceWGL(RendererGL *renderer, + EGLNativeWindowType window, + int pixelFormat, + HGLRC wglContext, + const FunctionsWGL *functions, + EGLint orientation); ~WindowSurfaceWGL() override; - egl::Error initialize(); + egl::Error initialize() override; egl::Error makeCurrent() override; egl::Error swap() override; egl::Error postSubBuffer(EGLint x, EGLint y, EGLint width, EGLint height) override; egl::Error querySurfacePointerANGLE(EGLint attribute, void **value) override; - egl::Error bindTexImage(EGLint buffer) override; + egl::Error bindTexImage(gl::Texture *texture, EGLint buffer) override; egl::Error releaseTexImage(EGLint buffer) override; void setSwapInterval(EGLint interval) override; @@ -38,18 +43,19 @@ class WindowSurfaceWGL : public SurfaceGL EGLint getHeight() const override; EGLint isPostSubBufferSupported() const override; + EGLint getSwapBehavior() const override; private: - ATOM mWindowClass; int mPixelFormat; - HGLRC mShareWGLContext; + HGLRC mWGLContext; - HWND mParentWindow; - HWND mChildWindow; - HDC mChildDeviceContext; + HWND mWindow; + HDC mDeviceContext; const FunctionsWGL *mFunctionsWGL; + + EGLint mSwapBehavior; }; } diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/wgl/wgl_utils.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/wgl/wgl_utils.cpp index b1dc7ad46ec2..641c3fbc4292 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/wgl/wgl_utils.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/wgl/wgl_utils.cpp @@ -8,6 +8,8 @@ #include "libANGLE/renderer/gl/wgl/wgl_utils.h" +#include "libANGLE/renderer/gl/wgl/FunctionsWGL.h" + namespace rx { @@ -30,6 +32,54 @@ PIXELFORMATDESCRIPTOR GetDefaultPixelFormatDescriptor() return pixelFormatDescriptor; } +std::vector GetDefaultPixelFormatAttributes(bool preservedSwap) +{ + std::vector attribs; + attribs.push_back(WGL_DRAW_TO_WINDOW_ARB); + attribs.push_back(TRUE); + + attribs.push_back(WGL_ACCELERATION_ARB); + attribs.push_back(WGL_FULL_ACCELERATION_ARB); + + attribs.push_back(WGL_SUPPORT_OPENGL_ARB); + attribs.push_back(TRUE); + + attribs.push_back(WGL_DOUBLE_BUFFER_ARB); + attribs.push_back(TRUE); + + attribs.push_back(WGL_PIXEL_TYPE_ARB); + attribs.push_back(WGL_TYPE_RGBA_ARB); + + attribs.push_back(WGL_COLOR_BITS_ARB); + attribs.push_back(24); + + attribs.push_back(WGL_ALPHA_BITS_ARB); + attribs.push_back(8); + + attribs.push_back(WGL_DEPTH_BITS_ARB); + attribs.push_back(24); + + attribs.push_back(WGL_STENCIL_BITS_ARB); + attribs.push_back(8); + + attribs.push_back(WGL_SWAP_METHOD_ARB); + attribs.push_back(preservedSwap ? WGL_SWAP_COPY_ARB : WGL_SWAP_UNDEFINED_ARB); + + attribs.push_back(0); + + return attribs; +} + +int QueryWGLFormatAttrib(HDC dc, int format, int attribName, const FunctionsWGL *functions) +{ + int result = 0; + if (functions->getPixelFormatAttribivARB == nullptr || + !functions->getPixelFormatAttribivARB(dc, format, 0, 1, &attribName, &result)) + { + return 0; + } + return result; +} } } diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/wgl/wgl_utils.h b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/wgl/wgl_utils.h index fba1919868c7..d4914b5d399b 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/wgl/wgl_utils.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/wgl/wgl_utils.h @@ -9,16 +9,22 @@ #ifndef LIBANGLE_RENDERER_GL_WGL_WGLUTILS_H_ #define LIBANGLE_RENDERER_GL_WGL_WGLUTILS_H_ +#include + #include "common/platform.h" namespace rx { +class FunctionsWGL; + namespace wgl { PIXELFORMATDESCRIPTOR GetDefaultPixelFormatDescriptor(); +std::vector GetDefaultPixelFormatAttributes(bool preservedSwap); +int QueryWGLFormatAttrib(HDC dc, int format, int attribName, const FunctionsWGL *functions); } } diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/validationEGL.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/validationEGL.cpp index 4e3b44b92f1e..1e0ff6676afe 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/validationEGL.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/validationEGL.cpp @@ -1,5 +1,5 @@ // -// Copyright (c) 2015 The ANGLE Project Authors. All rights reserved. +// Copyright (c) 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. // @@ -8,13 +8,122 @@ #include "libANGLE/validationEGL.h" +#include "common/utilities.h" #include "libANGLE/Config.h" #include "libANGLE/Context.h" +#include "libANGLE/Device.h" #include "libANGLE/Display.h" +#include "libANGLE/Image.h" +#include "libANGLE/Stream.h" #include "libANGLE/Surface.h" #include +namespace +{ +size_t GetMaximumMipLevel(const gl::Context *context, GLenum target) +{ + const gl::Caps &caps = context->getCaps(); + + size_t maxDimension = 0; + switch (target) + { + case GL_TEXTURE_2D: + maxDimension = caps.max2DTextureSize; + break; + case GL_TEXTURE_CUBE_MAP: + maxDimension = caps.maxCubeMapTextureSize; + break; + case GL_TEXTURE_3D: + maxDimension = caps.max3DTextureSize; + break; + case GL_TEXTURE_2D_ARRAY: + maxDimension = caps.max2DTextureSize; + break; + default: + UNREACHABLE(); + } + + return gl::log2(static_cast(maxDimension)); +} + +bool TextureHasNonZeroMipLevelsSpecified(const gl::Context *context, const gl::Texture *texture) +{ + size_t maxMip = GetMaximumMipLevel(context, texture->getTarget()); + for (size_t level = 1; level < maxMip; level++) + { + if (texture->getTarget() == GL_TEXTURE_CUBE_MAP) + { + for (GLenum face = gl::FirstCubeMapTextureTarget; face <= gl::LastCubeMapTextureTarget; + face++) + { + if (texture->getInternalFormat(face, level) != GL_NONE) + { + return true; + } + } + } + else + { + if (texture->getInternalFormat(texture->getTarget(), level) != GL_NONE) + { + return true; + } + } + } + + return false; +} + +bool CubeTextureHasUnspecifiedLevel0Face(const gl::Texture *texture) +{ + ASSERT(texture->getTarget() == GL_TEXTURE_CUBE_MAP); + for (GLenum face = gl::FirstCubeMapTextureTarget; face <= gl::LastCubeMapTextureTarget; face++) + { + if (texture->getInternalFormat(face, 0) == GL_NONE) + { + return true; + } + } + + return false; +} + +egl::Error ValidateStreamAttribute(const EGLAttrib attribute, + const EGLAttrib value, + const egl::DisplayExtensions &extensions) +{ + switch (attribute) + { + case EGL_STREAM_STATE_KHR: + case EGL_PRODUCER_FRAME_KHR: + case EGL_CONSUMER_FRAME_KHR: + return egl::Error(EGL_BAD_ACCESS, "Attempt to initialize readonly parameter"); + case EGL_CONSUMER_LATENCY_USEC_KHR: + // Technically not in spec but a latency < 0 makes no sense so we check it + if (value < 0) + { + return egl::Error(EGL_BAD_PARAMETER, "Latency must be positive"); + } + break; + case EGL_CONSUMER_ACQUIRE_TIMEOUT_USEC_KHR: + if (!extensions.streamConsumerGLTexture) + { + return egl::Error(EGL_BAD_ATTRIBUTE, "Consumer GL extension not enabled"); + } + // Again not in spec but it should be positive anyways + if (value < 0) + { + return egl::Error(EGL_BAD_PARAMETER, "Timeout must be positive"); + } + break; + default: + return egl::Error(EGL_BAD_ATTRIBUTE, "Invalid stream attribute"); + } + return egl::Error(EGL_SUCCESS); +} +} // namespace + namespace egl { @@ -22,12 +131,17 @@ Error ValidateDisplay(const Display *display) { if (display == EGL_NO_DISPLAY) { - return Error(EGL_BAD_DISPLAY); + return Error(EGL_BAD_DISPLAY, "display is EGL_NO_DISPLAY."); + } + + if (!Display::isValidDisplay(display)) + { + return Error(EGL_BAD_DISPLAY, "display is not a valid display."); } if (!display->isInitialized()) { - return Error(EGL_NOT_INITIALIZED); + return Error(EGL_NOT_INITIALIZED, "display is not initialized."); } return Error(EGL_SUCCESS); @@ -81,6 +195,44 @@ Error ValidateContext(const Display *display, gl::Context *context) return Error(EGL_SUCCESS); } +Error ValidateImage(const Display *display, const Image *image) +{ + Error error = ValidateDisplay(display); + if (error.isError()) + { + return error; + } + + if (!display->isValidImage(image)) + { + return Error(EGL_BAD_PARAMETER, "image is not valid."); + } + + return Error(EGL_SUCCESS); +} + +Error ValidateStream(const Display *display, const Stream *stream) +{ + Error error = ValidateDisplay(display); + if (error.isError()) + { + return error; + } + + const DisplayExtensions &displayExtensions = display->getExtensions(); + if (!displayExtensions.stream) + { + return Error(EGL_BAD_ACCESS, "Stream extension not active"); + } + + if (stream == EGL_NO_STREAM_KHR || !display->isValidStream(stream)) + { + return Error(EGL_BAD_STREAM_KHR, "Invalid stream"); + } + + return Error(EGL_SUCCESS); +} + Error ValidateCreateContext(Display *display, Config *configuration, gl::Context *shareContext, const AttributeMap& attributes) { @@ -91,15 +243,15 @@ Error ValidateCreateContext(Display *display, Config *configuration, gl::Context } // Get the requested client version (default is 1) and check it is 2 or 3. - EGLint clientMajorVersion = 1; - EGLint clientMinorVersion = 0; - EGLint contextFlags = 0; + EGLAttrib clientMajorVersion = 1; + EGLAttrib clientMinorVersion = 0; + EGLAttrib contextFlags = 0; bool resetNotification = false; bool robustAccess = false; for (AttributeMap::const_iterator attributeIter = attributes.begin(); attributeIter != attributes.end(); attributeIter++) { - EGLint attribute = attributeIter->first; - EGLint value = attributeIter->second; + EGLAttrib attribute = attributeIter->first; + EGLAttrib value = attributeIter->second; switch (attribute) { @@ -115,6 +267,9 @@ Error ValidateCreateContext(Display *display, Config *configuration, gl::Context contextFlags = value; break; + case EGL_CONTEXT_OPENGL_DEBUG: + break; + case EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR: // Only valid for OpenGL (non-ES) contexts return Error(EGL_BAD_ATTRIBUTE); @@ -150,6 +305,17 @@ Error ValidateCreateContext(Display *display, Config *configuration, gl::Context } break; + case EGL_CONTEXT_OPENGL_NO_ERROR_KHR: + if (!display->getExtensions().createContextNoError) + { + return Error(EGL_BAD_ATTRIBUTE, "Invalid Context attribute."); + } + if (value != EGL_TRUE && value != EGL_FALSE) + { + return Error(EGL_BAD_ATTRIBUTE, "Attribute must be EGL_TRUE or EGL_FALSE."); + } + break; + default: return Error(EGL_BAD_ATTRIBUTE); } @@ -224,8 +390,8 @@ Error ValidateCreateWindowSurface(Display *display, Config *config, EGLNativeWin for (AttributeMap::const_iterator attributeIter = attributes.begin(); attributeIter != attributes.end(); attributeIter++) { - EGLint attribute = attributeIter->first; - EGLint value = attributeIter->second; + EGLAttrib attribute = attributeIter->first; + EGLAttrib value = attributeIter->second; switch (attribute) { @@ -248,6 +414,13 @@ Error ValidateCreateWindowSurface(Display *display, Config *config, EGLNativeWin } break; + case EGL_FLEXIBLE_SURFACE_COMPATIBILITY_SUPPORTED_ANGLE: + if (!displayExtensions.flexibleSurfaceCompatibility) + { + return Error(EGL_BAD_ATTRIBUTE); + } + break; + case EGL_WIDTH: case EGL_HEIGHT: if (!displayExtensions.windowFixedSize) @@ -267,12 +440,26 @@ Error ValidateCreateWindowSurface(Display *display, Config *config, EGLNativeWin } break; + case EGL_SURFACE_ORIENTATION_ANGLE: + if (!displayExtensions.surfaceOrientation) + { + return Error(EGL_BAD_ATTRIBUTE, "EGL_ANGLE_surface_orientation is not enabled."); + } + break; + case EGL_VG_COLORSPACE: return Error(EGL_BAD_MATCH); case EGL_VG_ALPHA_FORMAT: return Error(EGL_BAD_MATCH); + case EGL_DIRECT_COMPOSITION_ANGLE: + if (!displayExtensions.directComposition) + { + return Error(EGL_BAD_ATTRIBUTE); + } + break; + default: return Error(EGL_BAD_ATTRIBUTE); } @@ -293,11 +480,13 @@ Error ValidateCreatePbufferSurface(Display *display, Config *config, const Attri { return error; } - + + const DisplayExtensions &displayExtensions = display->getExtensions(); + for (AttributeMap::const_iterator attributeIter = attributes.begin(); attributeIter != attributes.end(); attributeIter++) { - EGLint attribute = attributeIter->first; - EGLint value = attributeIter->second; + EGLAttrib attribute = attributeIter->first; + EGLAttrib value = attributeIter->second; switch (attribute) { @@ -344,6 +533,16 @@ Error ValidateCreatePbufferSurface(Display *display, Config *config, const Attri case EGL_VG_ALPHA_FORMAT: break; + case EGL_FLEXIBLE_SURFACE_COMPATIBILITY_SUPPORTED_ANGLE: + if (!displayExtensions.flexibleSurfaceCompatibility) + { + return Error( + EGL_BAD_ATTRIBUTE, + "EGL_FLEXIBLE_SURFACE_COMPATIBILITY_SUPPORTED_ANGLE cannot be used without " + "EGL_ANGLE_flexible_surface_compatibility support."); + } + break; + default: return Error(EGL_BAD_ATTRIBUTE); } @@ -356,8 +555,8 @@ Error ValidateCreatePbufferSurface(Display *display, Config *config, const Attri const Caps &caps = display->getCaps(); - EGLenum textureFormat = attributes.get(EGL_TEXTURE_FORMAT, EGL_NO_TEXTURE); - EGLenum textureTarget = attributes.get(EGL_TEXTURE_TARGET, EGL_NO_TEXTURE); + 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)) @@ -371,8 +570,8 @@ Error ValidateCreatePbufferSurface(Display *display, Config *config, const Attri return Error(EGL_BAD_ATTRIBUTE); } - EGLint width = attributes.get(EGL_WIDTH, 0); - EGLint height = attributes.get(EGL_HEIGHT, 0); + 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))) { return Error(EGL_BAD_MATCH); @@ -411,8 +610,8 @@ Error ValidateCreatePbufferFromClientBuffer(Display *display, EGLenum buftype, E for (AttributeMap::const_iterator attributeIter = attributes.begin(); attributeIter != attributes.end(); attributeIter++) { - EGLint attribute = attributeIter->first; - EGLint value = attributeIter->second; + EGLAttrib attribute = attributeIter->first; + EGLAttrib value = attributeIter->second; switch (attribute) { @@ -454,6 +653,16 @@ Error ValidateCreatePbufferFromClientBuffer(Display *display, EGLenum buftype, E case EGL_MIPMAP_TEXTURE: break; + case EGL_FLEXIBLE_SURFACE_COMPATIBILITY_SUPPORTED_ANGLE: + if (!displayExtensions.flexibleSurfaceCompatibility) + { + return Error( + EGL_BAD_ATTRIBUTE, + "EGL_FLEXIBLE_SURFACE_COMPATIBILITY_SUPPORTED_ANGLE cannot be used without " + "EGL_ANGLE_flexible_surface_compatibility support."); + } + break; + default: return Error(EGL_BAD_ATTRIBUTE); } @@ -464,8 +673,8 @@ Error ValidateCreatePbufferFromClientBuffer(Display *display, EGLenum buftype, E return Error(EGL_BAD_MATCH); } - EGLenum textureFormat = attributes.get(EGL_TEXTURE_FORMAT, EGL_NO_TEXTURE); - EGLenum textureTarget = attributes.get(EGL_TEXTURE_TARGET, EGL_NO_TEXTURE); + 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)) { @@ -480,8 +689,8 @@ Error ValidateCreatePbufferFromClientBuffer(Display *display, EGLenum buftype, E if (buftype == EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE) { - EGLint width = attributes.get(EGL_WIDTH, 0); - EGLint height = attributes.get(EGL_HEIGHT, 0); + EGLint width = static_cast(attributes.get(EGL_WIDTH, 0)); + EGLint height = static_cast(attributes.get(EGL_HEIGHT, 0)); if (width == 0 || height == 0) { @@ -498,4 +707,829 @@ Error ValidateCreatePbufferFromClientBuffer(Display *display, EGLenum buftype, E return Error(EGL_SUCCESS); } +Error ValidateCompatibleConfigs(const Display *display, + const Config *config1, + const Surface *surface, + const Config *config2, + EGLint surfaceType) +{ + + if (!surface->flexibleSurfaceCompatibilityRequested()) + { + // Config compatibility is defined in section 2.2 of the EGL 1.5 spec + + bool colorBufferCompat = config1->colorBufferType == config2->colorBufferType; + if (!colorBufferCompat) + { + return Error(EGL_BAD_MATCH, "Color buffer types are not compatible."); + } + + bool colorCompat = + config1->redSize == config2->redSize && config1->greenSize == config2->greenSize && + config1->blueSize == config2->blueSize && config1->alphaSize == config2->alphaSize && + config1->luminanceSize == config2->luminanceSize; + if (!colorCompat) + { + return Error(EGL_BAD_MATCH, "Color buffer sizes are not compatible."); + } + + bool dsCompat = config1->depthSize == config2->depthSize && + config1->stencilSize == config2->stencilSize; + if (!dsCompat) + { + return Error(EGL_BAD_MATCH, "Depth-stencil buffer types are not compatible."); + } + } + + bool surfaceTypeCompat = (config1->surfaceType & config2->surfaceType & surfaceType) != 0; + if (!surfaceTypeCompat) + { + return Error(EGL_BAD_MATCH, "Surface types are not compatible."); + } + + return Error(EGL_SUCCESS); +} + +Error ValidateCreateImageKHR(const Display *display, + gl::Context *context, + EGLenum target, + EGLClientBuffer buffer, + const AttributeMap &attributes) +{ + Error error = ValidateContext(display, context); + if (error.isError()) + { + return error; + } + + const DisplayExtensions &displayExtensions = display->getExtensions(); + + if (!displayExtensions.imageBase && !displayExtensions.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. + return Error(EGL_BAD_DISPLAY, "EGL_KHR_image not supported."); + } + + // 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_KHR: + switch (value) + { + case EGL_TRUE: + case EGL_FALSE: + break; + + default: + return Error(EGL_BAD_PARAMETER, + "EGL_IMAGE_PRESERVED_KHR must be EGL_TRUE or EGL_FALSE."); + } + break; + + case EGL_GL_TEXTURE_LEVEL_KHR: + if (!displayExtensions.glTexture2DImage && + !displayExtensions.glTextureCubemapImage && !displayExtensions.glTexture3DImage) + { + return Error(EGL_BAD_PARAMETER, + "EGL_GL_TEXTURE_LEVEL_KHR cannot be used without " + "KHR_gl_texture_*_image support."); + } + + if (value < 0) + { + return Error(EGL_BAD_PARAMETER, "EGL_GL_TEXTURE_LEVEL_KHR cannot be negative."); + } + break; + + case EGL_GL_TEXTURE_ZOFFSET_KHR: + if (!displayExtensions.glTexture3DImage) + { + return Error(EGL_BAD_PARAMETER, + "EGL_GL_TEXTURE_ZOFFSET_KHR cannot be used without " + "KHR_gl_texture_3D_image support."); + } + break; + + default: + return Error(EGL_BAD_PARAMETER, "invalid attribute: 0x%X", attribute); + } + } + + switch (target) + { + case EGL_GL_TEXTURE_2D_KHR: + { + if (!displayExtensions.glTexture2DImage) + { + return Error(EGL_BAD_PARAMETER, "KHR_gl_texture_2D_image not supported."); + } + + if (buffer == 0) + { + return Error(EGL_BAD_PARAMETER, + "buffer cannot reference a 2D texture with the name 0."); + } + + const gl::Texture *texture = + context->getTexture(egl_gl::EGLClientBufferToGLObjectHandle(buffer)); + if (texture == nullptr || texture->getTarget() != GL_TEXTURE_2D) + { + return Error(EGL_BAD_PARAMETER, "target is not a 2D texture."); + } + + if (texture->getBoundSurface() != nullptr) + { + return Error(EGL_BAD_ACCESS, "texture has a surface bound to it."); + } + + EGLAttrib level = attributes.get(EGL_GL_TEXTURE_LEVEL_KHR, 0); + if (texture->getWidth(GL_TEXTURE_2D, static_cast(level)) == 0 || + texture->getHeight(GL_TEXTURE_2D, static_cast(level)) == 0) + { + return Error(EGL_BAD_PARAMETER, + "target 2D texture does not have a valid size at specified level."); + } + + if (level > 0 && (!texture->isMipmapComplete() || + static_cast(level) >= texture->getMipCompleteLevels())) + { + return Error(EGL_BAD_PARAMETER, "texture must be complete if level is non-zero."); + } + + if (level == 0 && !texture->isMipmapComplete() && + TextureHasNonZeroMipLevelsSpecified(context, texture)) + { + return Error(EGL_BAD_PARAMETER, + "if level is zero and the texture is incomplete, it must have no mip " + "levels specified except zero."); + } + } + break; + + case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR: + case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR: + case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR: + case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR: + case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR: + case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR: + { + if (!displayExtensions.glTextureCubemapImage) + { + return Error(EGL_BAD_PARAMETER, "KHR_gl_texture_cubemap_image not supported."); + } + + if (buffer == 0) + { + return Error(EGL_BAD_PARAMETER, + "buffer cannot reference a cubemap texture with the name 0."); + } + + const gl::Texture *texture = + context->getTexture(egl_gl::EGLClientBufferToGLObjectHandle(buffer)); + if (texture == nullptr || texture->getTarget() != GL_TEXTURE_CUBE_MAP) + { + return Error(EGL_BAD_PARAMETER, "target is not a cubemap texture."); + } + + if (texture->getBoundSurface() != nullptr) + { + return Error(EGL_BAD_ACCESS, "texture has a surface bound to it."); + } + + EGLAttrib level = attributes.get(EGL_GL_TEXTURE_LEVEL_KHR, 0); + GLenum cubeMapFace = egl_gl::EGLCubeMapTargetToGLCubeMapTarget(target); + if (texture->getWidth(cubeMapFace, static_cast(level)) == 0 || + texture->getHeight(cubeMapFace, static_cast(level)) == 0) + { + return Error(EGL_BAD_PARAMETER, + "target cubemap texture does not have a valid size at specified level " + "and face."); + } + + if (level > 0 && (!texture->isMipmapComplete() || + static_cast(level) >= texture->getMipCompleteLevels())) + { + return Error(EGL_BAD_PARAMETER, "texture must be complete if level is non-zero."); + } + + if (level == 0 && !texture->isMipmapComplete() && + TextureHasNonZeroMipLevelsSpecified(context, texture)) + { + return Error(EGL_BAD_PARAMETER, + "if level is zero and the texture is incomplete, it must have no mip " + "levels specified except zero."); + } + + if (level == 0 && !texture->isMipmapComplete() && + CubeTextureHasUnspecifiedLevel0Face(texture)) + { + return Error(EGL_BAD_PARAMETER, + "if level is zero and the texture is incomplete, it must have all of " + "its faces specified at level zero."); + } + } + break; + + case EGL_GL_TEXTURE_3D_KHR: + { + if (!displayExtensions.glTexture3DImage) + { + return Error(EGL_BAD_PARAMETER, "KHR_gl_texture_3D_image not supported."); + } + + if (buffer == 0) + { + return Error(EGL_BAD_PARAMETER, + "buffer cannot reference a 3D texture with the name 0."); + } + + const gl::Texture *texture = + context->getTexture(egl_gl::EGLClientBufferToGLObjectHandle(buffer)); + if (texture == nullptr || texture->getTarget() != GL_TEXTURE_3D) + { + return Error(EGL_BAD_PARAMETER, "target is not a 3D texture."); + } + + if (texture->getBoundSurface() != nullptr) + { + return Error(EGL_BAD_ACCESS, "texture has a surface bound to it."); + } + + EGLAttrib level = attributes.get(EGL_GL_TEXTURE_LEVEL_KHR, 0); + EGLAttrib zOffset = attributes.get(EGL_GL_TEXTURE_ZOFFSET_KHR, 0); + if (texture->getWidth(GL_TEXTURE_3D, static_cast(level)) == 0 || + texture->getHeight(GL_TEXTURE_3D, static_cast(level)) == 0 || + texture->getDepth(GL_TEXTURE_3D, static_cast(level)) == 0) + { + return Error(EGL_BAD_PARAMETER, + "target 3D texture does not have a valid size at specified level."); + } + + if (static_cast(zOffset) >= + texture->getDepth(GL_TEXTURE_3D, static_cast(level))) + { + return Error(EGL_BAD_PARAMETER, + "target 3D texture does not have enough layers for the specified Z " + "offset at the specified level."); + } + + if (level > 0 && (!texture->isMipmapComplete() || + static_cast(level) >= texture->getMipCompleteLevels())) + { + return Error(EGL_BAD_PARAMETER, "texture must be complete if level is non-zero."); + } + + if (level == 0 && !texture->isMipmapComplete() && + TextureHasNonZeroMipLevelsSpecified(context, texture)) + { + return Error(EGL_BAD_PARAMETER, + "if level is zero and the texture is incomplete, it must have no mip " + "levels specified except zero."); + } + } + break; + + case EGL_GL_RENDERBUFFER_KHR: + { + if (!displayExtensions.glRenderbufferImage) + { + return Error(EGL_BAD_PARAMETER, "KHR_gl_renderbuffer_image not supported."); + } + + if (attributes.contains(EGL_GL_TEXTURE_LEVEL_KHR)) + { + return Error(EGL_BAD_PARAMETER, + "EGL_GL_TEXTURE_LEVEL_KHR cannot be used in conjunction with a " + "renderbuffer target."); + } + + if (buffer == 0) + { + return Error(EGL_BAD_PARAMETER, + "buffer cannot reference a renderbuffer with the name 0."); + } + + const gl::Renderbuffer *renderbuffer = + context->getRenderbuffer(egl_gl::EGLClientBufferToGLObjectHandle(buffer)); + if (renderbuffer == nullptr) + { + return Error(EGL_BAD_PARAMETER, "target is not a renderbuffer."); + } + + if (renderbuffer->getSamples() > 0) + { + return Error(EGL_BAD_PARAMETER, "target renderbuffer cannot be multisampled."); + } + } + break; + + default: + return Error(EGL_BAD_PARAMETER, "invalid target: 0x%X", target); + } + + return Error(EGL_SUCCESS); +} + +Error ValidateDestroyImageKHR(const Display *display, const Image *image) +{ + Error error = ValidateImage(display, image); + if (error.isError()) + { + return error; + } + + 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. + return Error(EGL_BAD_DISPLAY); + } + + return Error(EGL_SUCCESS); +} + +Error ValidateCreateDeviceANGLE(EGLint device_type, + void *native_device, + const EGLAttrib *attrib_list) +{ + const ClientExtensions &clientExtensions = Display::getClientExtensions(); + if (!clientExtensions.deviceCreation) + { + return Error(EGL_BAD_ACCESS, "Device creation extension not active"); + } + + if (attrib_list != nullptr && attrib_list[0] != EGL_NONE) + { + return Error(EGL_BAD_ATTRIBUTE, "Invalid attrib_list parameter"); + } + + switch (device_type) + { + case EGL_D3D11_DEVICE_ANGLE: + if (!clientExtensions.deviceCreationD3D11) + { + return Error(EGL_BAD_ATTRIBUTE, "D3D11 device creation extension not active"); + } + break; + default: + return Error(EGL_BAD_ATTRIBUTE, "Invalid device_type parameter"); + } + + return Error(EGL_SUCCESS); +} + +Error ValidateReleaseDeviceANGLE(Device *device) +{ + const ClientExtensions &clientExtensions = Display::getClientExtensions(); + if (!clientExtensions.deviceCreation) + { + return Error(EGL_BAD_ACCESS, "Device creation extension not active"); + } + + if (device == EGL_NO_DEVICE_EXT || !Device::IsValidDevice(device)) + { + return Error(EGL_BAD_DEVICE_EXT, "Invalid device parameter"); + } + + Display *owningDisplay = device->getOwningDisplay(); + if (owningDisplay != nullptr) + { + return Error(EGL_BAD_DEVICE_EXT, "Device must have been created using eglCreateDevice"); + } + + return Error(EGL_SUCCESS); +} + +Error ValidateCreateStreamKHR(const Display *display, const AttributeMap &attributes) +{ + Error error = ValidateDisplay(display); + if (error.isError()) + { + return error; + } + + const DisplayExtensions &displayExtensions = display->getExtensions(); + if (!displayExtensions.stream) + { + return Error(EGL_BAD_ALLOC, "Stream extension not active"); + } + + for (const auto &attributeIter : attributes) + { + EGLAttrib attribute = attributeIter.first; + EGLAttrib value = attributeIter.second; + + error = ValidateStreamAttribute(attribute, value, displayExtensions); + if (error.isError()) + { + return error; + } + } + + return Error(EGL_SUCCESS); +} + +Error ValidateDestroyStreamKHR(const Display *display, const Stream *stream) +{ + Error error = ValidateStream(display, stream); + if (error.isError()) + { + return error; + } + + return Error(EGL_SUCCESS); +} + +Error ValidateStreamAttribKHR(const Display *display, + const Stream *stream, + EGLint attribute, + EGLint value) +{ + Error error = ValidateStream(display, stream); + if (error.isError()) + { + return error; + } + + if (stream->getState() == EGL_STREAM_STATE_DISCONNECTED_KHR) + { + return Error(EGL_BAD_STATE_KHR, "Bad stream state"); + } + + return ValidateStreamAttribute(attribute, value, display->getExtensions()); +} + +Error ValidateQueryStreamKHR(const Display *display, + const Stream *stream, + EGLenum attribute, + EGLint *value) +{ + Error error = ValidateStream(display, stream); + if (error.isError()) + { + return error; + } + + 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) + { + return Error(EGL_BAD_ATTRIBUTE, "Consumer GLTexture extension not active"); + } + break; + default: + return Error(EGL_BAD_ATTRIBUTE, "Invalid attribute"); + } + + return Error(EGL_SUCCESS); +} + +Error ValidateQueryStreamu64KHR(const Display *display, + const Stream *stream, + EGLenum attribute, + EGLuint64KHR *value) +{ + Error error = ValidateStream(display, stream); + if (error.isError()) + { + return error; + } + + switch (attribute) + { + case EGL_CONSUMER_FRAME_KHR: + case EGL_PRODUCER_FRAME_KHR: + break; + default: + return Error(EGL_BAD_ATTRIBUTE, "Invalid attribute"); + } + + return Error(EGL_SUCCESS); +} + +Error ValidateStreamConsumerGLTextureExternalKHR(const Display *display, + gl::Context *context, + const Stream *stream) +{ + Error error = ValidateDisplay(display); + if (error.isError()) + { + return error; + } + + error = ValidateContext(display, context); + if (error.isError()) + { + return error; + } + + const DisplayExtensions &displayExtensions = display->getExtensions(); + if (!displayExtensions.streamConsumerGLTexture) + { + return Error(EGL_BAD_ACCESS, "Stream consumer extension not active"); + } + + if (stream == EGL_NO_STREAM_KHR || !display->isValidStream(stream)) + { + return Error(EGL_BAD_STREAM_KHR, "Invalid stream"); + } + + if (stream->getState() != EGL_STREAM_STATE_CREATED_KHR) + { + return Error(EGL_BAD_STATE_KHR, "Invalid stream state"); + } + + return Error(EGL_SUCCESS); +} + +Error ValidateStreamConsumerAcquireKHR(const Display *display, + gl::Context *context, + const Stream *stream) +{ + Error error = ValidateDisplay(display); + if (error.isError()) + { + return error; + } + + error = ValidateContext(display, context); + if (error.isError()) + { + return error; + } + + const DisplayExtensions &displayExtensions = display->getExtensions(); + if (!displayExtensions.streamConsumerGLTexture) + { + return Error(EGL_BAD_ACCESS, "Stream consumer extension not active"); + } + + if (stream == EGL_NO_STREAM_KHR || !display->isValidStream(stream)) + { + return Error(EGL_BAD_STREAM_KHR, "Invalid stream"); + } + + if (stream->getState() != EGL_STREAM_STATE_NEW_FRAME_AVAILABLE_KHR && + stream->getState() != EGL_STREAM_STATE_OLD_FRAME_AVAILABLE_KHR) + { + return Error(EGL_BAD_STATE_KHR, "Invalid stream state"); + } + + return Error(EGL_SUCCESS); +} + +Error ValidateStreamConsumerReleaseKHR(const Display *display, + gl::Context *context, + const Stream *stream) +{ + Error error = ValidateDisplay(display); + if (error.isError()) + { + return error; + } + + error = ValidateContext(display, context); + if (error.isError()) + { + return error; + } + + const DisplayExtensions &displayExtensions = display->getExtensions(); + if (!displayExtensions.streamConsumerGLTexture) + { + return Error(EGL_BAD_ACCESS, "Stream consumer extension not active"); + } + + if (stream == EGL_NO_STREAM_KHR || !display->isValidStream(stream)) + { + return Error(EGL_BAD_STREAM_KHR, "Invalid stream"); + } + + if (stream->getState() != EGL_STREAM_STATE_NEW_FRAME_AVAILABLE_KHR && + stream->getState() != EGL_STREAM_STATE_OLD_FRAME_AVAILABLE_KHR) + { + return Error(EGL_BAD_STATE_KHR, "Invalid stream state"); + } + + return Error(EGL_SUCCESS); +} + +Error ValidateStreamConsumerGLTextureExternalAttribsNV(const Display *display, + gl::Context *context, + const Stream *stream, + const AttributeMap &attribs) +{ + Error error = ValidateDisplay(display); + if (error.isError()) + { + return error; + } + + error = ValidateContext(display, context); + if (error.isError()) + { + return Error(EGL_BAD_ACCESS, "Invalid context"); + } + + const DisplayExtensions &displayExtensions = display->getExtensions(); + if (!displayExtensions.streamConsumerGLTexture) + { + return Error(EGL_BAD_ACCESS, "Stream consumer extension not active"); + } + + if (stream == EGL_NO_STREAM_KHR || !display->isValidStream(stream)) + { + return Error(EGL_BAD_STREAM_KHR, "Invalid stream"); + } + + if (stream->getState() != EGL_STREAM_STATE_CREATED_KHR) + { + return Error(EGL_BAD_STATE_KHR, "Invalid stream state"); + } + + EGLAttrib colorBufferType = EGL_RGB_BUFFER; + EGLAttrib planeCount = -1; + EGLAttrib plane[3]; + for (int i = 0; i < 3; i++) + { + plane[i] = -1; + } + 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) + { + return Error(EGL_BAD_PARAMETER, "Invalid color buffer type"); + } + 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) + { + return Error(EGL_BAD_MATCH, "Invalid plane count"); + } + planeCount = value; + break; + default: + if (attribute >= EGL_YUV_PLANE0_TEXTURE_UNIT_NV && + attribute <= EGL_YUV_PLANE2_TEXTURE_UNIT_NV) + { + if (value < 0) + { + return Error(EGL_BAD_ACCESS, "Invalid texture unit"); + } + plane[attribute - EGL_YUV_PLANE0_TEXTURE_UNIT_NV] = value; + } + else + { + return Error(EGL_BAD_ATTRIBUTE, "Invalid attribute"); + } + } + } + + if (colorBufferType == EGL_RGB_BUFFER) + { + if (planeCount > 0) + { + return Error(EGL_BAD_MATCH, "Plane count must be 0 for RGB buffer"); + } + for (int i = 0; i < 3; i++) + { + if (plane[i] != -1) + { + return Error(EGL_BAD_MATCH, "Planes cannot be specified"); + } + } + } + else + { + if (planeCount == -1) + { + planeCount = 2; + } + if (planeCount < 1 || planeCount > 3) + { + return Error(EGL_BAD_MATCH, "Invalid YUV plane count"); + } + for (EGLAttrib i = 0; i < planeCount; i++) + { + if (plane[i] == -1) + { + return Error(EGL_BAD_MATCH, "Not all planes specified"); + } + } + for (EGLAttrib i = planeCount; i < 3; i++) + { + if (plane[i] != -1) + { + return Error(EGL_BAD_MATCH, "Invalid plane specified"); + } + } + } + + return Error(EGL_SUCCESS); +} + +Error ValidateCreateStreamProducerD3DTextureNV12ANGLE(const Display *display, + const Stream *stream, + const AttributeMap &attribs) +{ + const DisplayExtensions &displayExtensions = display->getExtensions(); + if (!displayExtensions.streamProducerD3DTextureNV12) + { + return Error(EGL_BAD_ACCESS, "Stream producer extension not active"); + } + + Error error = ValidateStream(display, stream); + if (error.isError()) + { + return error; + } + + if (!attribs.isEmpty()) + { + return Error(EGL_BAD_ATTRIBUTE, "Invalid attribute"); + } + + if (stream->getState() != EGL_STREAM_STATE_CONNECTING_KHR) + { + return Error(EGL_BAD_STATE_KHR, "Stream not in connecting state"); + } + + return Error(EGL_SUCCESS); +} + +Error ValidateStreamPostD3DTextureNV12ANGLE(const Display *display, + const Stream *stream, + const void *texture, + const AttributeMap &attribs) +{ + const DisplayExtensions &displayExtensions = display->getExtensions(); + if (!displayExtensions.streamProducerD3DTextureNV12) + { + return Error(EGL_BAD_ACCESS, "Stream producer extension not active"); + } + + Error error = ValidateStream(display, stream); + if (error.isError()) + { + return error; + } + + for (auto &attributeIter : attribs) + { + EGLAttrib attribute = attributeIter.first; + EGLAttrib value = attributeIter.second; + + switch (attribute) + { + case EGL_D3D_TEXTURE_SUBRESOURCE_ID_ANGLE: + if (value < 0) + { + return Error(EGL_BAD_PARAMETER, "Invalid subresource index"); + } + break; + default: + return Error(EGL_BAD_ATTRIBUTE, "Invalid attribute"); + } + } + + 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) + { + return Error(EGL_BAD_STATE_KHR, "Stream not fully configured"); + } + + if (texture == nullptr) + { + return Error(EGL_BAD_PARAMETER, "Texture must not be null"); + } + + return Error(EGL_SUCCESS); +} } diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/validationEGL.h b/Source/ThirdParty/ANGLE/src/libANGLE/validationEGL.h index 4daff791fd11..57c6fa11fc44 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/validationEGL.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/validationEGL.h @@ -12,6 +12,7 @@ #include "libANGLE/Error.h" #include +#include namespace gl { @@ -23,7 +24,10 @@ namespace egl class AttributeMap; struct Config; +class Device; class Display; +class Image; +class Stream; class Surface; // Object validation @@ -31,6 +35,7 @@ Error ValidateDisplay(const Display *display); Error ValidateSurface(const Display *display, Surface *surface); Error ValidateConfig(const Display *display, const Config *config); Error ValidateContext(const Display *display, gl::Context *context); +Error ValidateImage(const Display *display, const Image *image); // Entry point validation Error ValidateCreateContext(Display *display, Config *configuration, gl::Context *shareContext, @@ -43,7 +48,59 @@ Error ValidateCreatePbufferSurface(Display *display, Config *config, const Attri Error ValidateCreatePbufferFromClientBuffer(Display *display, EGLenum buftype, EGLClientBuffer buffer, Config *config, const AttributeMap& attributes); +Error ValidateCreateImageKHR(const Display *display, + gl::Context *context, + EGLenum target, + EGLClientBuffer buffer, + const AttributeMap &attributes); +Error ValidateDestroyImageKHR(const Display *display, const Image *image); +Error ValidateCreateDeviceANGLE(EGLint device_type, + void *native_device, + const EGLAttrib *attrib_list); +Error ValidateReleaseDeviceANGLE(Device *device); + +Error ValidateCreateStreamKHR(const Display *display, const AttributeMap &attributes); +Error ValidateDestroyStreamKHR(const Display *display, const Stream *stream); +Error ValidateStreamAttribKHR(const Display *display, + const Stream *stream, + EGLint attribute, + EGLint value); +Error ValidateQueryStreamKHR(const Display *display, + const Stream *stream, + EGLenum attribute, + EGLint *value); +Error ValidateQueryStreamu64KHR(const Display *display, + const Stream *stream, + EGLenum attribute, + EGLuint64KHR *value); +Error ValidateStreamConsumerGLTextureExternalKHR(const Display *display, + gl::Context *context, + const Stream *stream); +Error ValidateStreamConsumerAcquireKHR(const Display *display, + gl::Context *context, + const Stream *stream); +Error ValidateStreamConsumerReleaseKHR(const Display *display, + gl::Context *context, + const Stream *stream); +Error ValidateStreamConsumerGLTextureExternalAttribsNV(const Display *display, + gl::Context *context, + const Stream *stream, + const AttributeMap &attribs); +Error ValidateCreateStreamProducerD3DTextureNV12ANGLE(const Display *display, + const Stream *stream, + const AttributeMap &attribs); +Error ValidateStreamPostD3DTextureNV12ANGLE(const Display *display, + const Stream *stream, + const void *texture, + const AttributeMap &attribs); + +// Other validation +Error ValidateCompatibleConfigs(const Display *display, + const Config *config1, + const Surface *surface, + const Config *config2, + EGLint surfaceType); } #endif // LIBANGLE_VALIDATIONEGL_H_ diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/validationES.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/validationES.cpp index 2a288a27b698..d3efd9180977 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/validationES.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/validationES.cpp @@ -10,22 +10,93 @@ #include "libANGLE/validationES2.h" #include "libANGLE/validationES3.h" #include "libANGLE/Context.h" +#include "libANGLE/Display.h" #include "libANGLE/Texture.h" #include "libANGLE/Framebuffer.h" #include "libANGLE/FramebufferAttachment.h" #include "libANGLE/formatutils.h" +#include "libANGLE/Image.h" #include "libANGLE/Query.h" #include "libANGLE/Program.h" #include "libANGLE/Uniform.h" #include "libANGLE/TransformFeedback.h" #include "libANGLE/VertexArray.h" -#include "libANGLE/renderer/BufferImpl.h" #include "common/mathutil.h" #include "common/utilities.h" namespace gl { +const char *g_ExceedsMaxElementErrorMessage = "Element value exceeds maximum element index."; + +namespace +{ +bool ValidateDrawAttribs(ValidationContext *context, GLint primcount, GLint maxVertex) +{ + const gl::State &state = context->getState(); + const gl::Program *program = state.getProgram(); + + const VertexArray *vao = state.getVertexArray(); + const auto &vertexAttribs = vao->getVertexAttributes(); + size_t maxEnabledAttrib = vao->getMaxEnabledAttribute(); + for (size_t attributeIndex = 0; attributeIndex < maxEnabledAttrib; ++attributeIndex) + { + const VertexAttribute &attrib = vertexAttribs[attributeIndex]; + if (program->isAttribLocationActive(attributeIndex) && attrib.enabled) + { + gl::Buffer *buffer = attrib.buffer.get(); + + if (buffer) + { + GLint64 attribStride = static_cast(ComputeVertexAttributeStride(attrib)); + GLint64 maxVertexElement = 0; + + if (attrib.divisor > 0) + { + maxVertexElement = + static_cast(primcount) / static_cast(attrib.divisor); + } + else + { + maxVertexElement = static_cast(maxVertex); + } + + // If we're drawing zero vertices, we have enough data. + if (maxVertexElement > 0) + { + // Note: Last vertex element does not take the full stride! + GLint64 attribSize = + static_cast(ComputeVertexAttributeTypeSize(attrib)); + GLint64 attribDataSize = (maxVertexElement - 1) * attribStride + attribSize; + GLint64 attribOffset = static_cast(attrib.offset); + + // [OpenGL ES 3.0.2] section 2.9.4 page 40: + // We can return INVALID_OPERATION if our vertex attribute does not have + // enough backing data. + if (attribDataSize + attribOffset > buffer->getSize()) + { + context->recordError( + Error(GL_INVALID_OPERATION, + "Vertex buffer is not big enough for the draw call")); + return false; + } + } + } + else if (attrib.pointer == NULL) + { + // This is an application error that would normally result in a crash, + // but we catch it and return an error + context->recordError(Error( + GL_INVALID_OPERATION, "An enabled vertex array has no buffer and no pointer.")); + return false; + } + } + } + + return true; +} + +} // anonymous namespace bool ValidCap(const Context *context, GLenum cap) { @@ -41,15 +112,21 @@ bool ValidCap(const Context *context, GLenum cap) case GL_BLEND: case GL_DITHER: return true; + case GL_PRIMITIVE_RESTART_FIXED_INDEX: case GL_RASTERIZER_DISCARD: return (context->getClientVersion() >= 3); + + case GL_DEBUG_OUTPUT_SYNCHRONOUS: + case GL_DEBUG_OUTPUT: + return context->getExtensions().debug; + default: return false; } } -bool ValidTextureTarget(const Context *context, GLenum target) +bool ValidTextureTarget(const ValidationContext *context, GLenum target) { switch (target) { @@ -66,11 +143,37 @@ bool ValidTextureTarget(const Context *context, GLenum target) } } +bool ValidTexture2DTarget(const ValidationContext *context, GLenum target) +{ + switch (target) + { + case GL_TEXTURE_2D: + case GL_TEXTURE_CUBE_MAP: + return true; + + default: + return false; + } +} + +bool ValidTexture3DTarget(const ValidationContext *context, GLenum target) +{ + switch (target) + { + case GL_TEXTURE_3D: + case GL_TEXTURE_2D_ARRAY: + return (context->getClientVersion() >= 3); + + default: + return false; + } +} + // 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, GLenum target) +bool ValidTexture2DDestinationTarget(const ValidationContext *context, GLenum target) { switch (target) { @@ -82,9 +185,18 @@ bool ValidTexture2DDestinationTarget(const Context *context, GLenum target) case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: return true; - case GL_TEXTURE_2D_ARRAY: + default: + return false; + } +} + +bool ValidTexture3DDestinationTarget(const ValidationContext *context, GLenum target) +{ + switch (target) + { case GL_TEXTURE_3D: - return (context->getClientVersion() >= 3); + case GL_TEXTURE_2D_ARRAY: + return true; default: return false; } @@ -114,7 +226,7 @@ bool ValidBufferTarget(const Context *context, GLenum target) case GL_PIXEL_PACK_BUFFER: case GL_PIXEL_UNPACK_BUFFER: - return context->getExtensions().pixelBufferObject; + return (context->getExtensions().pixelBufferObject || context->getClientVersion() >= 3); case GL_COPY_READ_BUFFER: case GL_COPY_WRITE_BUFFER: @@ -156,36 +268,52 @@ bool ValidBufferParameter(const Context *context, GLenum pname) } } -bool ValidMipLevel(const Context *context, GLenum target, GLint level) +bool ValidMipLevel(const ValidationContext *context, GLenum target, GLint level) { + const auto &caps = context->getCaps(); size_t maxDimension = 0; switch (target) { - case GL_TEXTURE_2D: maxDimension = context->getCaps().max2DTextureSize; break; + case GL_TEXTURE_2D: + maxDimension = caps.max2DTextureSize; + break; case GL_TEXTURE_CUBE_MAP: case GL_TEXTURE_CUBE_MAP_POSITIVE_X: case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: - case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: maxDimension = context->getCaps().maxCubeMapTextureSize; break; - case GL_TEXTURE_3D: maxDimension = context->getCaps().max3DTextureSize; break; - case GL_TEXTURE_2D_ARRAY: maxDimension = context->getCaps().max2DTextureSize; break; + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: + maxDimension = caps.maxCubeMapTextureSize; + break; + case GL_TEXTURE_3D: + maxDimension = caps.max3DTextureSize; + break; + case GL_TEXTURE_2D_ARRAY: + maxDimension = caps.max2DTextureSize; + break; default: UNREACHABLE(); } return level <= gl::log2(static_cast(maxDimension)); } -bool ValidImageSize(const Context *context, GLenum target, GLint level, - GLsizei width, GLsizei height, GLsizei depth) +bool ValidImageSizeParameters(const Context *context, + GLenum target, + GLint level, + GLsizei width, + GLsizei height, + GLsizei depth, + bool isSubImage) { if (level < 0 || width < 0 || height < 0 || depth < 0) { return false; } - if (!context->getExtensions().textureNPOT && + // TexSubImage parameters can be NPOT without textureNPOT extension, + // as long as the destination texture is POT. + if (!isSubImage && !context->getExtensions().textureNPOT && (level != 0 && (!gl::isPow2(width) || !gl::isPow2(height) || !gl::isPow2(depth)))) { return false; @@ -199,7 +327,28 @@ bool ValidImageSize(const Context *context, GLenum target, GLint level, return true; } -bool ValidCompressedImageSize(const Context *context, GLenum internalFormat, GLsizei width, GLsizei height) +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_ETC1_RGB8_LOSSY_DECODE_ANGLE: + return true; + + default: + return false; + } +} + +bool ValidCompressedImageSize(const ValidationContext *context, + GLenum internalFormat, + GLsizei width, + GLsizei height) { const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalFormat); if (!formatInfo.compressed) @@ -207,12 +356,22 @@ bool ValidCompressedImageSize(const Context *context, GLenum internalFormat, GLs return false; } - if (width < 0 || (static_cast(width) > formatInfo.compressedBlockWidth && width % formatInfo.compressedBlockWidth != 0) || - height < 0 || (static_cast(height) > formatInfo.compressedBlockHeight && height % formatInfo.compressedBlockHeight != 0)) + if (width < 0 || height < 0) { return false; } + if (CompressedTextureFormatRequiresExactSize(internalFormat)) + { + if ((static_cast(width) > formatInfo.compressedBlockWidth && + width % formatInfo.compressedBlockWidth != 0) || + (static_cast(height) > formatInfo.compressedBlockHeight && + height % formatInfo.compressedBlockHeight != 0)) + { + return false; + } + } + return true; } @@ -228,33 +387,57 @@ bool ValidQueryType(const Context *context, GLenum queryType) return true; case GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN: return (context->getClientVersion() >= 3); + case GL_TIME_ELAPSED_EXT: + return context->getExtensions().disjointTimerQuery; default: return false; } } -bool ValidProgram(Context *context, GLuint id) +Program *GetValidProgram(Context *context, GLuint 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." - if (context->getProgram(id) != NULL) - { - return true; - } - else if (context->getShader(id) != NULL) + Program *validProgram = context->getProgram(id); + + if (!validProgram) { - // ID is the wrong type - context->recordError(Error(GL_INVALID_OPERATION)); - return false; + if (context->getShader(id)) + { + context->recordError( + Error(GL_INVALID_OPERATION, "Expected a program name, but found a shader name")); + } + else + { + context->recordError(Error(GL_INVALID_VALUE, "Program name is not valid")); + } } - else + + return validProgram; +} + +Shader *GetValidShader(Context *context, GLuint id) +{ + // See ValidProgram for spec details. + + Shader *validShader = context->getShader(id); + + if (!validShader) { - // No shader/program object has this ID - context->recordError(Error(GL_INVALID_VALUE)); - return false; + if (context->getProgram(id)) + { + context->recordError( + Error(GL_INVALID_OPERATION, "Expected a shader name, but found a program name")); + } + else + { + context->recordError(Error(GL_INVALID_VALUE, "Shader name is invalid")); + } } + + return validShader; } bool ValidateAttachmentTarget(gl::Context *context, GLenum attachment) @@ -415,44 +598,23 @@ bool ValidateFramebufferRenderbufferParameters(gl::Context *context, GLenum targ return true; } -static bool IsPartialBlit(gl::Context *context, const gl::FramebufferAttachment *readBuffer, const gl::FramebufferAttachment *writeBuffer, - GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, - GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1) -{ - if (srcX0 != 0 || srcY0 != 0 || dstX0 != 0 || dstY0 != 0 || - dstX1 != writeBuffer->getWidth() || dstY1 != writeBuffer->getHeight() || - srcX1 != readBuffer->getWidth() || srcY1 != readBuffer->getHeight()) - { - return true; - } - else if (context->getState().isScissorTestEnabled()) - { - const Rectangle &scissor = context->getState().getScissor(); - - return scissor.x > 0 || scissor.y > 0 || - scissor.width < writeBuffer->getWidth() || - scissor.height < writeBuffer->getHeight(); - } - else - { - return false; - } -} - -bool ValidateBlitFramebufferParameters(gl::Context *context, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, - GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, - GLenum filter, bool fromAngleExtension) +bool ValidateBlitFramebufferParameters(gl::Context *context, + 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: - if (fromAngleExtension) - { - context->recordError(Error(GL_INVALID_ENUM)); - return false; - } break; default: context->recordError(Error(GL_INVALID_ENUM)); @@ -472,13 +634,6 @@ bool ValidateBlitFramebufferParameters(gl::Context *context, GLint srcX0, GLint return false; } - if (fromAngleExtension && (srcX1 - srcX0 != dstX1 - dstX0 || srcY1 - srcY0 != dstY1 - dstY0)) - { - ERR("Scaling and flipping in BlitFramebufferANGLE not supported by this implementation."); - context->recordError(Error(GL_INVALID_OPERATION)); - 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) @@ -489,11 +644,6 @@ bool ValidateBlitFramebufferParameters(gl::Context *context, GLint srcX0, GLint if (context->getState().getReadFramebuffer()->id() == context->getState().getDrawFramebuffer()->id()) { - if (fromAngleExtension) - { - ERR("Blits with the same source and destination framebuffer are not supported by this " - "implementation."); - } context->recordError(Error(GL_INVALID_OPERATION)); return false; } @@ -531,37 +681,66 @@ bool ValidateBlitFramebufferParameters(gl::Context *context, GLint srcX0, GLint { const gl::FramebufferAttachment *readColorBuffer = readFramebuffer->getReadColorbuffer(); const gl::FramebufferAttachment *drawColorBuffer = drawFramebuffer->getFirstColorbuffer(); + const Extensions &extensions = context->getExtensions(); if (readColorBuffer && drawColorBuffer) { GLenum readInternalFormat = readColorBuffer->getInternalFormat(); const InternalFormat &readFormatInfo = GetInternalFormatInfo(readInternalFormat); - for (GLuint i = 0; i < context->getCaps().maxColorAttachments; i++) + for (size_t drawbufferIdx = 0; + drawbufferIdx < drawFramebuffer->getDrawbufferStateCount(); ++drawbufferIdx) { - if (drawFramebuffer->isEnabledColorAttachment(i)) + const FramebufferAttachment *attachment = + drawFramebuffer->getDrawBuffer(drawbufferIdx); + if (attachment) { - GLenum drawInternalFormat = drawFramebuffer->getColorbuffer(i)->getInternalFormat(); + GLenum drawInternalFormat = attachment->getInternalFormat(); const InternalFormat &drawFormatInfo = GetInternalFormatInfo(drawInternalFormat); // 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 - if ( (readFormatInfo.componentType == GL_UNSIGNED_NORMALIZED || readFormatInfo.componentType == GL_SIGNED_NORMALIZED) && - !(drawFormatInfo.componentType == GL_UNSIGNED_NORMALIZED || drawFormatInfo.componentType == GL_SIGNED_NORMALIZED)) + // Changes with EXT_color_buffer_float: + // Case 1) is changed to fixed point OR floating point + GLenum readComponentType = readFormatInfo.componentType; + GLenum drawComponentType = drawFormatInfo.componentType; + bool readFixedPoint = (readComponentType == GL_UNSIGNED_NORMALIZED || + readComponentType == GL_SIGNED_NORMALIZED); + bool drawFixedPoint = (drawComponentType == GL_UNSIGNED_NORMALIZED || + drawComponentType == GL_SIGNED_NORMALIZED); + + if (extensions.colorBufferFloat) { - context->recordError(Error(GL_INVALID_OPERATION)); + bool readFixedOrFloat = (readFixedPoint || readComponentType == GL_FLOAT); + bool drawFixedOrFloat = (drawFixedPoint || drawComponentType == GL_FLOAT); + + if (readFixedOrFloat != drawFixedOrFloat) + { + context->recordError(Error(GL_INVALID_OPERATION, + "If the read buffer contains fixed-point or " + "floating-point values, the draw buffer " + "must as well.")); + return false; + } + } + else if (readFixedPoint != drawFixedPoint) + { + context->recordError(Error(GL_INVALID_OPERATION, + "If the read buffer contains fixed-point " + "values, the draw buffer must as well.")); return false; } - if (readFormatInfo.componentType == GL_UNSIGNED_INT && drawFormatInfo.componentType != GL_UNSIGNED_INT) + if (readComponentType == GL_UNSIGNED_INT && + drawComponentType != GL_UNSIGNED_INT) { context->recordError(Error(GL_INVALID_OPERATION)); return false; } - if (readFormatInfo.componentType == GL_INT && drawFormatInfo.componentType != GL_INT) + if (readComponentType == GL_INT && drawComponentType != GL_INT) { context->recordError(Error(GL_INVALID_OPERATION)); return false; @@ -580,53 +759,6 @@ bool ValidateBlitFramebufferParameters(gl::Context *context, GLint srcX0, GLint context->recordError(Error(GL_INVALID_OPERATION)); return false; } - - if (fromAngleExtension) - { - const FramebufferAttachment *readColorAttachment = readFramebuffer->getReadColorbuffer(); - if (!readColorAttachment || - (!(readColorAttachment->type() == GL_TEXTURE && readColorAttachment->getTextureImageIndex().type == GL_TEXTURE_2D) && - readColorAttachment->type() != GL_RENDERBUFFER && - readColorAttachment->type() != GL_FRAMEBUFFER_DEFAULT)) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return false; - } - - for (GLuint colorAttachment = 0; colorAttachment < context->getCaps().maxColorAttachments; ++colorAttachment) - { - if (drawFramebuffer->isEnabledColorAttachment(colorAttachment)) - { - const FramebufferAttachment *attachment = drawFramebuffer->getColorbuffer(colorAttachment); - ASSERT(attachment); - - if (!(attachment->type() == GL_TEXTURE && attachment->getTextureImageIndex().type == GL_TEXTURE_2D) && - attachment->type() != GL_RENDERBUFFER && - attachment->type() != GL_FRAMEBUFFER_DEFAULT) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return false; - } - - // Return an error if the destination formats do not match - if (attachment->getInternalFormat() != readColorBuffer->getInternalFormat()) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return false; - } - } - } - - int readSamples = readFramebuffer->getSamples(context->getData()); - - if (readSamples != 0 && IsPartialBlit(context, readColorBuffer, drawColorBuffer, - srcX0, srcY0, srcX1, srcY1, - dstX0, dstY0, dstX1, dstY1)) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return false; - } - } } } @@ -652,23 +784,6 @@ bool ValidateBlitFramebufferParameters(gl::Context *context, GLint srcX0, GLint context->recordError(Error(GL_INVALID_OPERATION)); return false; } - - if (fromAngleExtension) - { - if (IsPartialBlit(context, readBuffer, drawBuffer, - srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1)) - { - ERR("Only whole-buffer depth and stencil blits are supported by this implementation."); - context->recordError(Error(GL_INVALID_OPERATION)); // only whole-buffer copies are permitted - return false; - } - - if (readBuffer->getSamples() != 0 || drawBuffer->getSamples() != 0) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return false; - } - } } } } @@ -898,10 +1013,22 @@ bool ValidateSamplerObjectParameter(gl::Context *context, GLenum pname) } } -bool ValidateReadPixelsParameters(gl::Context *context, GLint x, GLint y, GLsizei width, GLsizei height, - GLenum format, GLenum type, GLsizei *bufSize, GLvoid *pixels) +bool ValidateReadPixels(Context *context, + GLint x, + GLint y, + GLsizei width, + GLsizei height, + GLenum format, + GLenum type, + GLvoid *pixels) { - gl::Framebuffer *framebuffer = context->getState().getReadFramebuffer(); + if (width < 0 || height < 0) + { + context->recordError(Error(GL_INVALID_VALUE, "width and height must be positive")); + return false; + } + + Framebuffer *framebuffer = context->getState().getReadFramebuffer(); ASSERT(framebuffer); if (framebuffer->checkStatus(context->getData()) != GL_FRAMEBUFFER_COMPLETE) @@ -938,35 +1065,77 @@ bool ValidateReadPixelsParameters(gl::Context *context, GLint x, GLint y, GLsize return false; } + return true; +} + +bool ValidateReadnPixelsEXT(Context *context, + GLint x, + GLint y, + GLsizei width, + GLsizei height, + GLenum format, + GLenum type, + GLsizei bufSize, + GLvoid *pixels) +{ + if (bufSize < 0) + { + context->recordError(Error(GL_INVALID_VALUE, "bufSize must be a positive number")); + return false; + } + GLenum sizedInternalFormat = GetSizedInternalFormat(format, type); const InternalFormat &sizedFormatInfo = GetInternalFormatInfo(sizedInternalFormat); - GLsizei outputPitch = sizedFormatInfo.computeRowPitch(type, width, context->getState().getPackAlignment(), 0); + GLsizei outputPitch = + sizedFormatInfo.computeRowPitch(type, width, context->getState().getPackAlignment(), + context->getState().getPackRowLength()); // sized query sanity check - if (bufSize) + int requiredSize = outputPitch * height; + if (requiredSize > bufSize) { - int requiredSize = outputPitch * height; - if (requiredSize > *bufSize) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return false; - } + context->recordError(Error(GL_INVALID_OPERATION)); + return false; } - return true; + return ValidateReadPixels(context, x, y, width, height, format, type, pixels); +} + +bool ValidateGenQueriesEXT(gl::Context *context, GLsizei n) +{ + if (!context->getExtensions().occlusionQueryBoolean && + !context->getExtensions().disjointTimerQuery) + { + context->recordError(Error(GL_INVALID_OPERATION, "Query extension not enabled")); + return false; + } + + return ValidateGenOrDelete(context, n); +} + +bool ValidateDeleteQueriesEXT(gl::Context *context, GLsizei n) +{ + if (!context->getExtensions().occlusionQueryBoolean && + !context->getExtensions().disjointTimerQuery) + { + context->recordError(Error(GL_INVALID_OPERATION, "Query extension not enabled")); + return false; + } + + return ValidateGenOrDelete(context, n); } -bool ValidateBeginQuery(gl::Context *context, GLenum target, GLuint id) +bool ValidateBeginQueryBase(gl::Context *context, GLenum target, GLuint id) { if (!ValidQueryType(context, target)) { - context->recordError(Error(GL_INVALID_ENUM)); + context->recordError(Error(GL_INVALID_ENUM, "Invalid query target")); return false; } if (id == 0) { - context->recordError(Error(GL_INVALID_OPERATION)); + context->recordError(Error(GL_INVALID_OPERATION, "Query id is 0")); return false; } @@ -985,9 +1154,12 @@ bool ValidateBeginQuery(gl::Context *context, GLenum target, GLuint id) // 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. + + // TODO(ewell): I think this needs to be changed for timer and occlusion queries to work at the + // same time if (context->getState().isQueryActive()) { - context->recordError(Error(GL_INVALID_OPERATION)); + context->recordError(Error(GL_INVALID_OPERATION, "Other query is active")); return false; } @@ -996,98 +1168,272 @@ bool ValidateBeginQuery(gl::Context *context, GLenum target, GLuint id) // check that name was obtained with glGenQueries if (!queryObject) { - context->recordError(Error(GL_INVALID_OPERATION)); + context->recordError(Error(GL_INVALID_OPERATION, "Invalid query id")); return false; } // check for type mismatch if (queryObject->getType() != target) { - context->recordError(Error(GL_INVALID_OPERATION)); + context->recordError(Error(GL_INVALID_OPERATION, "Query type does not match target")); return false; } return true; } -bool ValidateEndQuery(gl::Context *context, GLenum target) +bool ValidateBeginQueryEXT(gl::Context *context, GLenum target, GLuint id) +{ + if (!context->getExtensions().occlusionQueryBoolean && + !context->getExtensions().disjointTimerQuery) + { + context->recordError(Error(GL_INVALID_OPERATION, "Query extension not enabled")); + return false; + } + + return ValidateBeginQueryBase(context, target, id); +} + +bool ValidateEndQueryBase(gl::Context *context, GLenum target) { if (!ValidQueryType(context, target)) { - context->recordError(Error(GL_INVALID_ENUM)); + context->recordError(Error(GL_INVALID_ENUM, "Invalid query target")); return false; } const Query *queryObject = context->getState().getActiveQuery(target); - if (queryObject == NULL) + if (queryObject == nullptr) { - context->recordError(Error(GL_INVALID_OPERATION)); + context->recordError(Error(GL_INVALID_OPERATION, "Query target not active")); return false; } return true; } -static bool ValidateUniformCommonBase(gl::Context *context, GLenum targetUniformType, - GLint location, GLsizei count, LinkedUniform **uniformOut) +bool ValidateEndQueryEXT(gl::Context *context, GLenum target) { - if (count < 0) + if (!context->getExtensions().occlusionQueryBoolean && + !context->getExtensions().disjointTimerQuery) { - context->recordError(Error(GL_INVALID_VALUE)); + context->recordError(Error(GL_INVALID_OPERATION, "Query extension not enabled")); return false; } - gl::Program *program = context->getState().getProgram(); - if (!program) + return ValidateEndQueryBase(context, target); +} + +bool ValidateQueryCounterEXT(Context *context, GLuint id, GLenum target) +{ + if (!context->getExtensions().disjointTimerQuery) { - context->recordError(Error(GL_INVALID_OPERATION)); + context->recordError(Error(GL_INVALID_OPERATION, "Disjoint timer query not enabled")); return false; } - if (location == -1) + if (target != GL_TIMESTAMP_EXT) { - // Silently ignore the uniform command + context->recordError(Error(GL_INVALID_ENUM, "Invalid query target")); return false; } - if (!program->isValidUniformLocation(location)) + Query *queryObject = context->getQuery(id, true, target); + if (queryObject == nullptr) { - context->recordError(Error(GL_INVALID_OPERATION)); + context->recordError(Error(GL_INVALID_OPERATION, "Invalid query id")); return false; } - LinkedUniform *uniform = program->getUniformByLocation(location); - - // attempting to write an array to a non-array uniform is an INVALID_OPERATION - if (uniform->elementCount() == 1 && count > 1) + if (context->getState().isQueryActive(queryObject)) { - context->recordError(Error(GL_INVALID_OPERATION)); + context->recordError(Error(GL_INVALID_OPERATION, "Query is active")); return false; } - *uniformOut = uniform; return true; } -bool ValidateUniform(gl::Context *context, GLenum uniformType, GLint location, GLsizei count) +bool ValidateGetQueryivBase(Context *context, GLenum target, GLenum pname) { - // Check for ES3 uniform entry points - if (VariableComponentType(uniformType) == GL_UNSIGNED_INT && context->getClientVersion() < 3) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return false; - } - - LinkedUniform *uniform = NULL; - if (!ValidateUniformCommonBase(context, uniformType, location, count, &uniform)) + if (!ValidQueryType(context, target) && target != GL_TIMESTAMP_EXT) { + context->recordError(Error(GL_INVALID_ENUM, "Invalid query type")); return false; } - GLenum targetBoolType = VariableBoolVectorType(uniformType); - bool samplerUniformCheck = (IsSamplerType(uniform->type) && uniformType == GL_INT); - if (!samplerUniformCheck && uniformType != uniform->type && targetBoolType != uniform->type) + switch (pname) + { + case GL_CURRENT_QUERY_EXT: + if (target == GL_TIMESTAMP_EXT) + { + context->recordError( + Error(GL_INVALID_ENUM, "Cannot use current query for timestamp")); + return false; + } + break; + case GL_QUERY_COUNTER_BITS_EXT: + if (!context->getExtensions().disjointTimerQuery || + (target != GL_TIMESTAMP_EXT && target != GL_TIME_ELAPSED_EXT)) + { + context->recordError(Error(GL_INVALID_ENUM, "Invalid pname")); + return false; + } + break; + default: + context->recordError(Error(GL_INVALID_ENUM, "Invalid pname")); + return false; + } + + return true; +} + +bool ValidateGetQueryivEXT(Context *context, GLenum target, GLenum pname, GLint *params) +{ + if (!context->getExtensions().occlusionQueryBoolean && + !context->getExtensions().disjointTimerQuery) + { + context->recordError(Error(GL_INVALID_OPERATION, "Query extension not enabled")); + return false; + } + + return ValidateGetQueryivBase(context, target, pname); +} + +bool ValidateGetQueryObjectValueBase(Context *context, GLuint id, GLenum pname) +{ + Query *queryObject = context->getQuery(id, false, GL_NONE); + + if (!queryObject) + { + context->recordError(Error(GL_INVALID_OPERATION, "Query does not exist")); + return false; + } + + if (context->getState().isQueryActive(queryObject)) + { + context->recordError(Error(GL_INVALID_OPERATION, "Query currently active")); + return false; + } + + switch (pname) + { + case GL_QUERY_RESULT_EXT: + case GL_QUERY_RESULT_AVAILABLE_EXT: + break; + + default: + context->recordError(Error(GL_INVALID_ENUM, "Invalid pname enum")); + return false; + } + + return true; +} + +bool ValidateGetQueryObjectivEXT(Context *context, GLuint id, GLenum pname, GLint *params) +{ + if (!context->getExtensions().disjointTimerQuery) + { + context->recordError(Error(GL_INVALID_OPERATION, "Timer query extension not enabled")); + return false; + } + return ValidateGetQueryObjectValueBase(context, id, pname); +} + +bool ValidateGetQueryObjectuivEXT(Context *context, GLuint id, GLenum pname, GLuint *params) +{ + if (!context->getExtensions().disjointTimerQuery && + !context->getExtensions().occlusionQueryBoolean) + { + context->recordError(Error(GL_INVALID_OPERATION, "Query extension not enabled")); + return false; + } + return ValidateGetQueryObjectValueBase(context, id, pname); +} + +bool ValidateGetQueryObjecti64vEXT(Context *context, GLuint id, GLenum pname, GLint64 *params) +{ + if (!context->getExtensions().disjointTimerQuery) + { + context->recordError(Error(GL_INVALID_OPERATION, "Timer query extension not enabled")); + return false; + } + return ValidateGetQueryObjectValueBase(context, id, pname); +} + +bool ValidateGetQueryObjectui64vEXT(Context *context, GLuint id, GLenum pname, GLuint64 *params) +{ + if (!context->getExtensions().disjointTimerQuery) + { + context->recordError(Error(GL_INVALID_OPERATION, "Timer query extension not enabled")); + return false; + } + return ValidateGetQueryObjectValueBase(context, id, pname); +} + +static bool ValidateUniformCommonBase(gl::Context *context, + GLenum targetUniformType, + GLint location, + GLsizei count, + const LinkedUniform **uniformOut) +{ + if (count < 0) + { + context->recordError(Error(GL_INVALID_VALUE)); + return false; + } + + gl::Program *program = context->getState().getProgram(); + if (!program) + { + context->recordError(Error(GL_INVALID_OPERATION)); + return false; + } + + if (location == -1) + { + // Silently ignore the uniform command + return false; + } + + if (!program->isValidUniformLocation(location)) + { + context->recordError(Error(GL_INVALID_OPERATION)); + return false; + } + + const LinkedUniform &uniform = program->getUniformByLocation(location); + + // attempting to write an array to a non-array uniform is an INVALID_OPERATION + if (!uniform.isArray() && count > 1) + { + context->recordError(Error(GL_INVALID_OPERATION)); + return false; + } + + *uniformOut = &uniform; + return true; +} + +bool ValidateUniform(gl::Context *context, GLenum uniformType, GLint location, GLsizei count) +{ + // Check for ES3 uniform entry points + if (VariableComponentType(uniformType) == GL_UNSIGNED_INT && context->getClientVersion() < 3) + { + context->recordError(Error(GL_INVALID_OPERATION)); + return false; + } + + const LinkedUniform *uniform = nullptr; + if (!ValidateUniformCommonBase(context, uniformType, location, count, &uniform)) + { + return false; + } + + GLenum targetBoolType = VariableBoolVectorType(uniformType); + bool samplerUniformCheck = (IsSamplerType(uniform->type) && uniformType == GL_INT); + if (!samplerUniformCheck && uniformType != uniform->type && targetBoolType != uniform->type) { context->recordError(Error(GL_INVALID_OPERATION)); return false; @@ -1114,7 +1460,7 @@ bool ValidateUniformMatrix(gl::Context *context, GLenum matrixType, GLint locati return false; } - LinkedUniform *uniform = NULL; + const LinkedUniform *uniform = nullptr; if (!ValidateUniformCommonBase(context, matrixType, location, count, &uniform)) { return false; @@ -1156,12 +1502,15 @@ bool ValidateStateQuery(gl::Context *context, GLenum pname, GLenum *nativeType, case GL_TEXTURE_BINDING_CUBE_MAP: case GL_TEXTURE_BINDING_3D: case GL_TEXTURE_BINDING_2D_ARRAY: - if (context->getState().getActiveSampler() >= caps.maxCombinedTextureImageUnits) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return false; - } break; + case GL_TEXTURE_BINDING_EXTERNAL_OES: + if (!context->getExtensions().eglStreamConsumerExternal) + { + context->recordError( + Error(GL_INVALID_ENUM, "NV_EGL_stream_consumer_external extension not enabled")); + return false; + } + break; case GL_IMPLEMENTATION_COLOR_READ_TYPE: case GL_IMPLEMENTATION_COLOR_READ_FORMAT: @@ -1196,17 +1545,21 @@ bool ValidateStateQuery(gl::Context *context, GLenum pname, GLenum *nativeType, return true; } -bool ValidateCopyTexImageParametersBase(gl::Context* context, GLenum target, GLint level, GLenum internalformat, bool isSubImage, - GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, - GLint border, GLenum *textureFormatOut) +bool ValidateCopyTexImageParametersBase(ValidationContext *context, + GLenum target, + GLint level, + GLenum internalformat, + bool isSubImage, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLint x, + GLint y, + GLsizei width, + GLsizei height, + GLint border, + GLenum *textureFormatOut) { - - if (!ValidTexture2DDestinationTarget(context, target)) - { - context->recordError(Error(GL_INVALID_ENUM)); - return false; - } - if (level < 0 || xoffset < 0 || yoffset < 0 || zoffset < 0 || width < 0 || height < 0) { context->recordError(Error(GL_INVALID_VALUE)); @@ -1231,14 +1584,15 @@ bool ValidateCopyTexImageParametersBase(gl::Context* context, GLenum target, GLi return false; } - gl::Framebuffer *framebuffer = context->getState().getReadFramebuffer(); + const gl::Framebuffer *framebuffer = context->getState().getReadFramebuffer(); if (framebuffer->checkStatus(context->getData()) != GL_FRAMEBUFFER_COMPLETE) { context->recordError(Error(GL_INVALID_FRAMEBUFFER_OPERATION)); return false; } - if (context->getState().getReadFramebuffer()->id() != 0 && framebuffer->getSamples(context->getData()) != 0) + const auto &state = context->getState(); + if (state.getReadFramebuffer()->id() != 0 && framebuffer->getSamples(context->getData()) != 0) { context->recordError(Error(GL_INVALID_OPERATION)); return false; @@ -1275,14 +1629,15 @@ bool ValidateCopyTexImageParametersBase(gl::Context* context, GLenum target, GLi return false; } - gl::Texture *texture = context->getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target); + gl::Texture *texture = + state.getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target); if (!texture) { context->recordError(Error(GL_INVALID_OPERATION)); return false; } - if (texture->isImmutable() && !isSubImage) + if (texture->getImmutableFormat() && !isSubImage) { context->recordError(Error(GL_INVALID_OPERATION)); return false; @@ -1338,7 +1693,10 @@ bool ValidateCopyTexImageParametersBase(gl::Context* context, GLenum target, GLi return true; } -static bool ValidateDrawBase(Context *context, GLenum mode, GLsizei count, GLsizei maxVertex, GLsizei primcount) +static bool ValidateDrawBase(ValidationContext *context, + GLenum mode, + GLsizei count, + GLsizei primcount) { switch (mode) { @@ -1370,17 +1728,27 @@ static bool ValidateDrawBase(Context *context, GLenum mode, GLsizei count, GLsiz return false; } - const gl::DepthStencilState &depthStencilState = state.getDepthStencilState(); - if (depthStencilState.stencilWritemask != depthStencilState.stencilBackWritemask || - state.getStencilRef() != state.getStencilBackRef() || - depthStencilState.stencilMask != depthStencilState.stencilBackMask) + if (context->getLimitations().noSeparateStencilRefsAndMasks) { - // Note: these separate values are not supported in WebGL, due to D3D's limitations. - // See Section 6.10 of the WebGL 1.0 spec - ERR("This ANGLE implementation does not support separate front/back stencil " - "writemasks, reference values, or stencil mask values."); - context->recordError(Error(GL_INVALID_OPERATION)); - return false; + const Framebuffer *framebuffer = context->getState().getDrawFramebuffer(); + const FramebufferAttachment *stencilBuffer = framebuffer->getStencilbuffer(); + GLuint stencilBits = stencilBuffer ? stencilBuffer->getStencilSize() : 0; + GLuint minimumRequiredStencilMask = (1 << stencilBits) - 1; + const DepthStencilState &depthStencilState = state.getDepthStencilState(); + if ((depthStencilState.stencilWritemask & minimumRequiredStencilMask) != + (depthStencilState.stencilBackWritemask & minimumRequiredStencilMask) || + state.getStencilRef() != state.getStencilBackRef() || + (depthStencilState.stencilMask & minimumRequiredStencilMask) != + (depthStencilState.stencilBackMask & minimumRequiredStencilMask)) + { + // Note: these separate values are not supported in WebGL, due to D3D's limitations. See + // Section 6.10 of the WebGL 1.0 spec + ERR( + "This ANGLE implementation does not support separate front/back stencil " + "writemasks, reference values, or stencil mask values."); + context->recordError(Error(GL_INVALID_OPERATION)); + return false; + } } const gl::Framebuffer *fbo = state.getDrawFramebuffer(); @@ -1403,77 +1771,29 @@ static bool ValidateDrawBase(Context *context, GLenum mode, GLsizei count, GLsiz return false; } - // Buffer validations - const VertexArray *vao = state.getVertexArray(); - const auto &vertexAttribs = vao->getVertexAttributes(); - const int *semanticIndexes = program->getSemanticIndexes(); - unsigned int maxEnabledAttrib = vao->getMaxEnabledAttribute(); - for (size_t attributeIndex = 0; attributeIndex < maxEnabledAttrib; ++attributeIndex) - { - const VertexAttribute &attrib = vertexAttribs[attributeIndex]; - bool attribActive = (semanticIndexes[attributeIndex] != -1); - if (attribActive && attrib.enabled) - { - gl::Buffer *buffer = attrib.buffer.get(); - - if (buffer) - { - GLint64 attribStride = static_cast(ComputeVertexAttributeStride(attrib)); - GLint64 maxVertexElement = 0; - - if (attrib.divisor > 0) - { - maxVertexElement = static_cast(primcount) / static_cast(attrib.divisor); - } - else - { - maxVertexElement = static_cast(maxVertex); - } - - GLint64 attribDataSize = maxVertexElement * attribStride; - - // [OpenGL ES 3.0.2] section 2.9.4 page 40: - // We can return INVALID_OPERATION if our vertex attribute does not have - // enough backing data. - if (attribDataSize > buffer->getSize()) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return false; - } - } - else if (attrib.pointer == NULL) - { - // This is an application error that would normally result in a crash, - // but we catch it and return an error - context->recordError(Error(GL_INVALID_OPERATION, "An enabled vertex array has no buffer and no pointer.")); - return false; - } - } - } - // Uniform buffer validation for (unsigned int uniformBlockIndex = 0; uniformBlockIndex < program->getActiveUniformBlockCount(); uniformBlockIndex++) { - const gl::UniformBlock *uniformBlock = program->getUniformBlockByIndex(uniformBlockIndex); + const gl::UniformBlock &uniformBlock = program->getUniformBlockByIndex(uniformBlockIndex); GLuint blockBinding = program->getUniformBlockBinding(uniformBlockIndex); - const gl::Buffer *uniformBuffer = state.getIndexedUniformBuffer(blockBinding); + const OffsetBindingPointer &uniformBuffer = + state.getIndexedUniformBuffer(blockBinding); - if (!uniformBuffer) + if (uniformBuffer.get() == nullptr) { // undefined behaviour context->recordError(Error(GL_INVALID_OPERATION, "It is undefined behaviour to have a used but unbound uniform buffer.")); return false; } - size_t uniformBufferSize = state.getIndexedUniformBufferSize(blockBinding); - + size_t uniformBufferSize = uniformBuffer.getSize(); if (uniformBufferSize == 0) { // Bind the whole buffer. uniformBufferSize = static_cast(uniformBuffer->getSize()); } - if (uniformBufferSize < uniformBlock->dataSize) + if (uniformBufferSize < uniformBlock.dataSize) { // undefined behaviour context->recordError(Error(GL_INVALID_OPERATION, "It is undefined behaviour to use a uniform buffer that is too small.")); @@ -1505,7 +1825,12 @@ bool ValidateDrawArrays(Context *context, GLenum mode, GLint first, GLsizei coun return false; } - if (!ValidateDrawBase(context, mode, count, count, primcount)) + if (!ValidateDrawBase(context, mode, count, primcount)) + { + return false; + } + + if (!ValidateDrawAttribs(context, primcount, count)) { return false; } @@ -1538,11 +1863,10 @@ static bool ValidateDrawInstancedANGLE(Context *context) gl::Program *program = state.getProgram(); const VertexArray *vao = state.getVertexArray(); - for (int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; attributeIndex++) + for (size_t attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; attributeIndex++) { const VertexAttribute &attrib = vao->getVertexAttribute(attributeIndex); - bool active = (program->getSemanticIndex(attributeIndex) != -1); - if (active && attrib.divisor == 0) + if (program->isAttribLocationActive(attributeIndex) && attrib.divisor == 0) { return true; } @@ -1563,8 +1887,13 @@ bool ValidateDrawArraysInstancedANGLE(Context *context, GLenum mode, GLint first return ValidateDrawArraysInstanced(context, mode, first, count, primcount); } -bool ValidateDrawElements(Context *context, GLenum mode, GLsizei count, GLenum type, - const GLvoid* indices, GLsizei primcount, rx::RangeUI *indexRangeOut) +bool ValidateDrawElements(ValidationContext *context, + GLenum mode, + GLsizei count, + GLenum type, + const GLvoid *indices, + GLsizei primcount, + IndexRange *indexRangeOut) { switch (type) { @@ -1572,7 +1901,7 @@ bool ValidateDrawElements(Context *context, GLenum mode, GLsizei count, GLenum t case GL_UNSIGNED_SHORT: break; case GL_UNSIGNED_INT: - if (!context->getExtensions().elementIndexUint) + if (context->getClientVersion() < 3 && !context->getExtensions().elementIndexUint) { context->recordError(Error(GL_INVALID_ENUM)); return false; @@ -1602,7 +1931,7 @@ bool ValidateDrawElements(Context *context, GLenum mode, GLsizei count, GLenum t } const gl::VertexArray *vao = state.getVertexArray(); - gl::Buffer *elementArrayBuffer = vao->getElementArrayBuffer(); + gl::Buffer *elementArrayBuffer = vao->getElementArrayBuffer().get(); if (!indices && !elementArrayBuffer) { context->recordError(Error(GL_INVALID_OPERATION)); @@ -1638,45 +1967,56 @@ bool ValidateDrawElements(Context *context, GLenum mode, GLsizei count, GLenum t return false; } + if (!ValidateDrawBase(context, mode, count, primcount)) + { + return false; + } + // Use max index to validate if our vertex buffers are large enough for the pull. // TODO: offer fast path, with disabled index validation. // TODO: also disable index checking on back-ends that are robust to out-of-range accesses. if (elementArrayBuffer) { uintptr_t offset = reinterpret_cast(indices); - if (!elementArrayBuffer->getIndexRangeCache()->findRange(type, static_cast(offset), count, indexRangeOut)) + Error error = + elementArrayBuffer->getIndexRange(type, static_cast(offset), count, + state.isPrimitiveRestartEnabled(), indexRangeOut); + if (error.isError()) { - rx::BufferImpl *bufferImpl = elementArrayBuffer->getImplementation(); - const uint8_t *dataPointer = NULL; - Error error = bufferImpl->getData(&dataPointer); - if (error.isError()) - { - context->recordError(error); - return false; - } - - const uint8_t *offsetPointer = dataPointer + offset; - *indexRangeOut = rx::IndexRangeCache::ComputeRange(type, offsetPointer, count); - elementArrayBuffer->getIndexRangeCache()->addRange(type, static_cast(offset), count, *indexRangeOut); + context->recordError(error); + return false; } } else { - *indexRangeOut = rx::IndexRangeCache::ComputeRange(type, indices, count); + *indexRangeOut = ComputeIndexRange(type, indices, count, state.isPrimitiveRestartEnabled()); } - if (!ValidateDrawBase(context, mode, count, static_cast(indexRangeOut->end), primcount)) + // 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(indexRangeOut->end) >= context->getCaps().maxElementIndex) { + context->recordError(Error(GL_INVALID_OPERATION, g_ExceedsMaxElementErrorMessage)); return false; } - return true; + if (!ValidateDrawAttribs(context, primcount, static_cast(indexRangeOut->vertexCount()))) + { + return false; + } + + // No op if there are no real indices in the index data (all are primitive restart). + return (indexRangeOut->vertexIndexCount > 0); } bool ValidateDrawElementsInstanced(Context *context, - GLenum mode, GLsizei count, GLenum type, - const GLvoid *indices, GLsizei primcount, - rx::RangeUI *indexRangeOut) + GLenum mode, + GLsizei count, + GLenum type, + const GLvoid *indices, + GLsizei primcount, + IndexRange *indexRangeOut) { if (primcount < 0) { @@ -1693,8 +2033,13 @@ bool ValidateDrawElementsInstanced(Context *context, return (primcount > 0); } -bool ValidateDrawElementsInstancedANGLE(Context *context, GLenum mode, GLsizei count, GLenum type, - const GLvoid *indices, GLsizei primcount, rx::RangeUI *indexRangeOut) +bool ValidateDrawElementsInstancedANGLE(Context *context, + GLenum mode, + GLsizei count, + GLenum type, + const GLvoid *indices, + GLsizei primcount, + IndexRange *indexRangeOut) { if (!ValidateDrawInstancedANGLE(context)) { @@ -1830,13 +2175,12 @@ bool ValidateGetUniformBase(Context *context, GLuint program, GLint location) return false; } - if (!ValidProgram(context, program)) + gl::Program *programObject = GetValidProgram(context, program); + if (!programObject) { return false; } - gl::Program *programObject = context->getProgram(program); - if (!programObject || !programObject->isLinked()) { context->recordError(Error(GL_INVALID_OPERATION)); @@ -1873,8 +2217,8 @@ static bool ValidateSizedGetUniform(Context *context, GLuint program, GLint loca ASSERT(programObject); // sized queries -- ensure the provided buffer is large enough - LinkedUniform *uniform = programObject->getUniformByLocation(location); - size_t requiredBytes = VariableExternalSize(uniform->type); + const LinkedUniform &uniform = programObject->getUniformByLocation(location); + size_t requiredBytes = VariableExternalSize(uniform.type); if (static_cast(bufSize) < requiredBytes) { context->recordError(Error(GL_INVALID_OPERATION)); @@ -1894,4 +2238,664 @@ bool ValidateGetnUniformivEXT(Context *context, GLuint program, GLint location, return ValidateSizedGetUniform(context, program, location, bufSize); } +bool ValidateDiscardFramebufferBase(Context *context, GLenum target, GLsizei numAttachments, + const GLenum *attachments, bool defaultFramebuffer) +{ + if (numAttachments < 0) + { + context->recordError(Error(GL_INVALID_VALUE, "numAttachments must not be less than zero")); + return false; + } + + for (GLsizei i = 0; i < numAttachments; ++i) + { + if (attachments[i] >= GL_COLOR_ATTACHMENT0 && attachments[i] <= GL_COLOR_ATTACHMENT31) + { + if (defaultFramebuffer) + { + context->recordError(Error(GL_INVALID_ENUM, "Invalid attachment when the default framebuffer is bound")); + return false; + } + + if (attachments[i] >= GL_COLOR_ATTACHMENT0 + context->getCaps().maxColorAttachments) + { + context->recordError(Error(GL_INVALID_OPERATION, + "Requested color attachment is greater than the maximum supported color attachments")); + return false; + } + } + else + { + switch (attachments[i]) + { + case GL_DEPTH_ATTACHMENT: + case GL_STENCIL_ATTACHMENT: + case GL_DEPTH_STENCIL_ATTACHMENT: + if (defaultFramebuffer) + { + context->recordError(Error(GL_INVALID_ENUM, "Invalid attachment when the default framebuffer is bound")); + return false; + } + break; + case GL_COLOR: + case GL_DEPTH: + case GL_STENCIL: + if (!defaultFramebuffer) + { + context->recordError(Error(GL_INVALID_ENUM, "Invalid attachment when the default framebuffer is not bound")); + return false; + } + break; + default: + context->recordError(Error(GL_INVALID_ENUM, "Invalid attachment")); + return false; + } + } + } + + return true; +} + +bool ValidateInsertEventMarkerEXT(Context *context, GLsizei length, const char *marker) +{ + // Note that debug marker calls must not set error state + + if (length < 0) + { + return false; + } + + if (marker == nullptr) + { + return false; + } + + return true; +} + +bool ValidatePushGroupMarkerEXT(Context *context, GLsizei length, const char *marker) +{ + // 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 ValidateEGLImageTargetTexture2DOES(Context *context, + egl::Display *display, + GLenum target, + egl::Image *image) +{ + if (!context->getExtensions().eglImage && !context->getExtensions().eglImageExternal) + { + context->recordError(Error(GL_INVALID_OPERATION)); + return false; + } + + switch (target) + { + case GL_TEXTURE_2D: + break; + + default: + context->recordError(Error(GL_INVALID_ENUM, "invalid texture target.")); + return false; + } + + if (!display->isValidImage(image)) + { + context->recordError(Error(GL_INVALID_VALUE, "EGL image is not valid.")); + return false; + } + + if (image->getSamples() > 0) + { + context->recordError(Error(GL_INVALID_OPERATION, + "cannot create a 2D texture from a multisampled EGL image.")); + return false; + } + + const TextureCaps &textureCaps = context->getTextureCaps().get(image->getInternalFormat()); + if (!textureCaps.texturable) + { + context->recordError(Error(GL_INVALID_OPERATION, + "EGL image internal format is not supported as a texture.")); + return false; + } + + return true; +} + +bool ValidateEGLImageTargetRenderbufferStorageOES(Context *context, + egl::Display *display, + GLenum target, + egl::Image *image) +{ + if (!context->getExtensions().eglImage) + { + context->recordError(Error(GL_INVALID_OPERATION)); + return false; + } + + switch (target) + { + case GL_RENDERBUFFER: + break; + + default: + context->recordError(Error(GL_INVALID_ENUM, "invalid renderbuffer target.")); + return false; + } + + if (!display->isValidImage(image)) + { + context->recordError(Error(GL_INVALID_VALUE, "EGL image is not valid.")); + return false; + } + + const TextureCaps &textureCaps = context->getTextureCaps().get(image->getInternalFormat()); + if (!textureCaps.renderable) + { + context->recordError(Error( + GL_INVALID_OPERATION, "EGL image internal format is not supported as a renderbuffer.")); + return false; + } + + return true; +} + +bool ValidateBindVertexArrayBase(Context *context, GLuint array) +{ + if (!context->isVertexArrayGenerated(array)) + { + // The default VAO should always exist + ASSERT(array != 0); + context->recordError(Error(GL_INVALID_OPERATION)); + return false; + } + + return true; +} + +bool ValidateLinkProgram(Context *context, GLuint program) +{ + if (context->hasActiveTransformFeedback(program)) + { + // ES 3.0.4 section 2.15 page 91 + context->recordError(Error(GL_INVALID_OPERATION, + "Cannot link program while program is associated with an active " + "transform feedback object.")); + return false; + } + return true; +} + +bool ValidateProgramBinaryBase(Context *context, + GLuint program, + GLenum binaryFormat, + const void *binary, + GLint length) +{ + Program *programObject = GetValidProgram(context, program); + if (programObject == nullptr) + { + return false; + } + + const std::vector &programBinaryFormats = context->getCaps().programBinaryFormats; + if (std::find(programBinaryFormats.begin(), programBinaryFormats.end(), binaryFormat) == + programBinaryFormats.end()) + { + context->recordError(Error(GL_INVALID_ENUM, "Program binary format is not valid.")); + return false; + } + + if (context->hasActiveTransformFeedback(program)) + { + // ES 3.0.4 section 2.15 page 91 + context->recordError(Error(GL_INVALID_OPERATION, + "Cannot change program binary while program is associated with " + "an active transform feedback object.")); + return false; + } + + return true; +} + +bool ValidateGetProgramBinaryBase(Context *context, + GLuint program, + GLsizei bufSize, + GLsizei *length, + GLenum *binaryFormat, + void *binary) +{ + Program *programObject = GetValidProgram(context, program); + if (programObject == nullptr) + { + return false; + } + + if (!programObject->isLinked()) + { + context->recordError(Error(GL_INVALID_OPERATION, "Program is not linked.")); + return false; + } + + return true; +} + +bool ValidateUseProgram(Context *context, GLuint program) +{ + if (program != 0) + { + Program *programObject = context->getProgram(program); + if (!programObject) + { + // ES 3.1.0 section 7.3 page 72 + if (context->getShader(program)) + { + context->recordError( + Error(GL_INVALID_OPERATION, + "Attempted to use a single shader instead of a shader program.")); + return false; + } + else + { + context->recordError(Error(GL_INVALID_VALUE, "Program invalid.")); + return false; + } + } + if (!programObject->isLinked()) + { + context->recordError(Error(GL_INVALID_OPERATION, "Program not linked.")); + return false; + } + } + if (context->getState().isTransformFeedbackActiveUnpaused()) + { + // ES 3.0.4 section 2.15 page 91 + context->recordError( + Error(GL_INVALID_OPERATION, + "Cannot change active program while transform feedback is unpaused.")); + return false; + } + + return true; +} + +bool ValidateCopyTexImage2D(ValidationContext *context, + GLenum target, + GLint level, + GLenum internalformat, + GLint x, + GLint y, + GLsizei width, + GLsizei height, + GLint border) +{ + if (context->getClientVersion() < 3) + { + return ValidateES2CopyTexImageParameters(context, target, level, internalformat, false, 0, + 0, x, y, width, height, border); + } + + ASSERT(context->getClientVersion() == 3); + return ValidateES3CopyTexImage2DParameters(context, target, level, internalformat, false, 0, 0, + 0, x, y, width, height, border); +} + +bool ValidateFramebufferRenderbuffer(Context *context, + GLenum target, + GLenum attachment, + GLenum renderbuffertarget, + GLuint renderbuffer) +{ + if (!ValidFramebufferTarget(target) || + (renderbuffertarget != GL_RENDERBUFFER && renderbuffer != 0)) + { + context->recordError(Error(GL_INVALID_ENUM)); + return false; + } + + return ValidateFramebufferRenderbufferParameters(context, target, attachment, + renderbuffertarget, renderbuffer); +} + +bool ValidateDrawBuffersBase(ValidationContext *context, GLsizei n, const GLenum *bufs) +{ + // INVALID_VALUE is generated if n is negative or greater than value of MAX_DRAW_BUFFERS + if (n < 0 || static_cast(n) > context->getCaps().maxDrawBuffers) + { + context->recordError( + Error(GL_INVALID_VALUE, "n must be non-negative and no greater than MAX_DRAW_BUFFERS")); + return false; + } + + ASSERT(context->getState().getDrawFramebuffer()); + GLuint 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->recordError(Error(GL_INVALID_ENUM, "Invalid buffer value")); + return false; + } + else if (bufs[colorAttachment] >= maxColorAttachment) + { + context->recordError( + Error(GL_INVALID_OPERATION, "Buffer value is greater than MAX_DRAW_BUFFERS")); + return false; + } + else if (bufs[colorAttachment] != GL_NONE && bufs[colorAttachment] != attachment && + frameBufferId != 0) + { + // INVALID_OPERATION-GL is bound to buffer and ith argument + // is not COLOR_ATTACHMENTi or NONE + context->recordError( + Error(GL_INVALID_OPERATION, "Ith value does not match COLOR_ATTACHMENTi or NONE")); + 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 == 0) + { + if (n != 1) + { + context->recordError(Error(GL_INVALID_OPERATION, + "n must be 1 when GL is bound to the default framebuffer")); + return false; + } + + if (bufs[0] != GL_NONE && bufs[0] != GL_BACK) + { + context->recordError(Error( + GL_INVALID_OPERATION, + "Only NONE or BACK are valid values when drawing to the default framebuffer")); + return false; + } + } + + return true; +} + +bool ValidateCopyTexSubImage2D(Context *context, + GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLint x, + GLint y, + GLsizei width, + GLsizei height) +{ + if (context->getClientVersion() < 3) + { + return ValidateES2CopyTexImageParameters(context, target, level, GL_NONE, true, xoffset, + yoffset, x, y, width, height, 0); + } + + return ValidateES3CopyTexImage2DParameters(context, target, level, GL_NONE, true, xoffset, + yoffset, 0, x, y, width, height, 0); +} + +bool ValidateGetBufferPointervBase(Context *context, GLenum target, GLenum pname, void **params) +{ + if (!ValidBufferTarget(context, target)) + { + context->recordError(Error(GL_INVALID_ENUM, "Buffer target not valid: 0x%X", target)); + return false; + } + + if (pname != GL_BUFFER_MAP_POINTER) + { + context->recordError(Error(GL_INVALID_ENUM, "pname not valid: 0x%X", pname)); + return false; + } + + Buffer *buffer = context->getState().getTargetBuffer(target); + + // 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 (!buffer) + { + context->recordError( + Error(GL_INVALID_OPERATION, "Can not get pointer for reserved buffer name zero.")); + return false; + } + + return true; +} + +bool ValidateUnmapBufferBase(Context *context, GLenum target) +{ + if (!ValidBufferTarget(context, target)) + { + context->recordError(Error(GL_INVALID_ENUM, "Invalid buffer target.")); + return false; + } + + Buffer *buffer = context->getState().getTargetBuffer(target); + + if (buffer == nullptr || !buffer->isMapped()) + { + context->recordError(Error(GL_INVALID_OPERATION, "Buffer not mapped.")); + return false; + } + + return true; +} + +bool ValidateMapBufferRangeBase(Context *context, + GLenum target, + GLintptr offset, + GLsizeiptr length, + GLbitfield access) +{ + if (!ValidBufferTarget(context, target)) + { + context->recordError(Error(GL_INVALID_ENUM, "Invalid buffer target.")); + return false; + } + + if (offset < 0 || length < 0) + { + context->recordError(Error(GL_INVALID_VALUE, "Invalid offset or length.")); + return false; + } + + Buffer *buffer = context->getState().getTargetBuffer(target); + + if (!buffer) + { + context->recordError(Error(GL_INVALID_OPERATION, "Attempted to map buffer object zero.")); + return false; + } + + // Check for buffer overflow + size_t offsetSize = static_cast(offset); + size_t lengthSize = static_cast(length); + + if (!rx::IsUnsignedAdditionSafe(offsetSize, lengthSize) || + offsetSize + lengthSize > static_cast(buffer->getSize())) + { + context->recordError( + Error(GL_INVALID_VALUE, "Mapped range does not fit into buffer dimensions.")); + return false; + } + + // Check for invalid bits in the mask + GLbitfield allAccessBits = 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 (access & ~(allAccessBits)) + { + context->recordError(Error(GL_INVALID_VALUE, "Invalid access bits: 0x%X.", access)); + return false; + } + + if (length == 0) + { + context->recordError(Error(GL_INVALID_OPERATION, "Buffer mapping length is zero.")); + return false; + } + + if (buffer->isMapped()) + { + context->recordError(Error(GL_INVALID_OPERATION, "Buffer is already mapped.")); + return false; + } + + // Check for invalid bit combinations + if ((access & (GL_MAP_READ_BIT | GL_MAP_WRITE_BIT)) == 0) + { + context->recordError( + Error(GL_INVALID_OPERATION, "Need to map buffer for either reading or writing.")); + 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->recordError(Error(GL_INVALID_OPERATION, + "Invalid access bits when mapping buffer for reading: 0x%X.", + access)); + return false; + } + + if ((access & GL_MAP_WRITE_BIT) == 0 && (access & GL_MAP_FLUSH_EXPLICIT_BIT) != 0) + { + context->recordError(Error( + GL_INVALID_OPERATION, + "The explicit flushing bit may only be set if the buffer is mapped for writing.")); + return false; + } + return true; +} + +bool ValidateFlushMappedBufferRangeBase(Context *context, + GLenum target, + GLintptr offset, + GLsizeiptr length) +{ + if (offset < 0 || length < 0) + { + context->recordError(Error(GL_INVALID_VALUE, "Invalid offset/length parameters.")); + return false; + } + + if (!ValidBufferTarget(context, target)) + { + context->recordError(Error(GL_INVALID_ENUM, "Invalid buffer target.")); + return false; + } + + Buffer *buffer = context->getState().getTargetBuffer(target); + + if (buffer == nullptr) + { + context->recordError(Error(GL_INVALID_OPERATION, "Attempted to flush buffer object zero.")); + return false; + } + + if (!buffer->isMapped() || (buffer->getAccessFlags() & GL_MAP_FLUSH_EXPLICIT_BIT) == 0) + { + context->recordError(Error( + GL_INVALID_OPERATION, "Attempted to flush a buffer not mapped for explicit flushing.")); + return false; + } + + // Check for buffer overflow + size_t offsetSize = static_cast(offset); + size_t lengthSize = static_cast(length); + + if (!rx::IsUnsignedAdditionSafe(offsetSize, lengthSize) || + offsetSize + lengthSize > static_cast(buffer->getMapLength())) + { + context->recordError( + Error(GL_INVALID_VALUE, "Flushed range does not fit into buffer mapping dimensions.")); + return false; + } + + return true; +} + +bool ValidateGenBuffers(Context *context, GLint n, GLuint *) +{ + return ValidateGenOrDelete(context, n); +} + +bool ValidateDeleteBuffers(Context *context, GLint n, const GLuint *) +{ + return ValidateGenOrDelete(context, n); +} + +bool ValidateGenFramebuffers(Context *context, GLint n, GLuint *) +{ + return ValidateGenOrDelete(context, n); +} + +bool ValidateDeleteFramebuffers(Context *context, GLint n, const GLuint *) +{ + return ValidateGenOrDelete(context, n); +} + +bool ValidateGenRenderbuffers(Context *context, GLint n, GLuint *) +{ + return ValidateGenOrDelete(context, n); +} + +bool ValidateDeleteRenderbuffers(Context *context, GLint n, const GLuint *) +{ + return ValidateGenOrDelete(context, n); +} + +bool ValidateGenTextures(Context *context, GLint n, GLuint *) +{ + return ValidateGenOrDelete(context, n); +} + +bool ValidateDeleteTextures(Context *context, GLint n, const GLuint *) +{ + return ValidateGenOrDelete(context, n); +} + +bool ValidateGenOrDelete(Context *context, GLint n) +{ + if (n < 0) + { + context->recordError(Error(GL_INVALID_VALUE, "n < 0")); + return false; + } + return true; +} + +} // namespace gl diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/validationES.h b/Source/ThirdParty/ANGLE/src/libANGLE/validationES.h index b0ccd8eecce3..c36b1eeba5da 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/validationES.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/validationES.h @@ -14,22 +14,51 @@ #include #include -namespace gl +namespace egl { +class Display; +class Image; +} +namespace gl +{ class Context; +class Program; +class Shader; +class ValidationContext; bool ValidCap(const Context *context, GLenum cap); -bool ValidTextureTarget(const Context *context, GLenum target); -bool ValidTexture2DDestinationTarget(const Context *context, GLenum target); +bool ValidTextureTarget(const ValidationContext *context, GLenum target); +bool ValidTexture2DTarget(const ValidationContext *context, GLenum target); +bool ValidTexture3DTarget(const ValidationContext *context, GLenum target); +bool ValidTexture2DDestinationTarget(const ValidationContext *context, GLenum target); +bool ValidTexture3DDestinationTarget(const ValidationContext *context, GLenum target); bool ValidFramebufferTarget(GLenum target); bool ValidBufferTarget(const Context *context, GLenum target); bool ValidBufferParameter(const Context *context, GLenum pname); -bool ValidMipLevel(const Context *context, GLenum target, GLint level); -bool ValidImageSize(const Context *context, GLenum target, GLint level, GLsizei width, GLsizei height, GLsizei depth); -bool ValidCompressedImageSize(const Context *context, GLenum internalFormat, GLsizei width, GLsizei height); +bool ValidMipLevel(const ValidationContext *context, GLenum target, GLint level); +bool ValidImageSizeParameters(const Context *context, + GLenum target, + GLint level, + GLsizei width, + GLsizei height, + GLsizei depth, + bool isSubImage); +bool ValidCompressedImageSize(const ValidationContext *context, + GLenum internalFormat, + GLsizei width, + GLsizei height); bool ValidQueryType(const Context *context, GLenum queryType); -bool ValidProgram(Context *context, GLuint id); + +// 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(Context *context, GLuint 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(Context *context, GLuint id); bool ValidateAttachmentTarget(Context *context, GLenum attachment); bool ValidateRenderbufferStorageParametersBase(Context *context, GLenum target, GLsizei samples, @@ -40,9 +69,17 @@ bool ValidateRenderbufferStorageParametersANGLE(Context *context, GLenum target, bool ValidateFramebufferRenderbufferParameters(Context *context, GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); -bool ValidateBlitFramebufferParameters(Context *context, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, - GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, - GLenum filter, bool fromAngleExtension); +bool ValidateBlitFramebufferParameters(Context *context, + GLint srcX0, + GLint srcY0, + GLint srcX1, + GLint srcY1, + GLint dstX0, + GLint dstY0, + GLint dstX1, + GLint dstY1, + GLbitfield mask, + GLenum filter); bool ValidateGetVertexAttribParameters(Context *context, GLenum pname); @@ -50,11 +87,38 @@ bool ValidateTexParamParameters(Context *context, GLenum pname, GLint param); bool ValidateSamplerObjectParameter(Context *context, GLenum pname); -bool ValidateReadPixelsParameters(Context *context, GLint x, GLint y, GLsizei width, GLsizei height, - GLenum format, GLenum type, GLsizei *bufSize, GLvoid *pixels); +bool ValidateReadPixels(Context *context, + GLint x, + GLint y, + GLsizei width, + GLsizei height, + GLenum format, + GLenum type, + GLvoid *pixels); +bool ValidateReadnPixelsEXT(Context *context, + GLint x, + GLint y, + GLsizei width, + GLsizei height, + GLenum format, + GLenum type, + GLsizei bufSize, + GLvoid *pixels); -bool ValidateBeginQuery(Context *context, GLenum target, GLuint id); -bool ValidateEndQuery(Context *context, GLenum target); +bool ValidateGenQueriesEXT(gl::Context *context, GLsizei n); +bool ValidateDeleteQueriesEXT(gl::Context *context, GLsizei n); +bool ValidateBeginQueryBase(Context *context, GLenum target, GLuint id); +bool ValidateBeginQueryEXT(Context *context, GLenum target, GLuint id); +bool ValidateEndQueryBase(Context *context, GLenum target); +bool ValidateEndQueryEXT(Context *context, GLenum target); +bool ValidateQueryCounterEXT(Context *context, GLuint id, GLenum target); +bool ValidateGetQueryivBase(Context *context, GLenum target, GLenum pname); +bool ValidateGetQueryivEXT(Context *context, GLenum target, GLenum pname, GLint *params); +bool ValidateGetQueryObjectValueBase(Context *context, GLenum target, GLenum pname); +bool ValidateGetQueryObjectivEXT(Context *context, GLuint id, GLenum pname, GLint *params); +bool ValidateGetQueryObjectuivEXT(Context *context, GLuint id, GLenum pname, GLuint *params); +bool ValidateGetQueryObjecti64vEXT(Context *context, GLuint id, GLenum pname, GLint64 *params); +bool ValidateGetQueryObjectui64vEXT(Context *context, GLuint id, GLenum pname, GLuint64 *params); bool ValidateUniform(Context *context, GLenum uniformType, GLint location, GLsizei count); bool ValidateUniformMatrix(Context *context, GLenum matrixType, GLint location, GLsizei count, @@ -62,26 +126,57 @@ bool ValidateUniformMatrix(Context *context, GLenum matrixType, GLint location, bool ValidateStateQuery(Context *context, GLenum pname, GLenum *nativeType, unsigned int *numParams); -bool ValidateCopyTexImageParametersBase(Context* context, GLenum target, GLint level, GLenum internalformat, bool isSubImage, - GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, - GLint border, GLenum *textureInternalFormatOut); +bool ValidateCopyTexImageParametersBase(ValidationContext *context, + GLenum target, + GLint level, + GLenum internalformat, + bool isSubImage, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLint x, + GLint y, + GLsizei width, + GLsizei height, + GLint border, + GLenum *textureInternalFormatOut); bool ValidateDrawArrays(Context *context, GLenum mode, GLint first, GLsizei count, GLsizei primcount); bool ValidateDrawArraysInstanced(Context *context, GLenum mode, GLint first, GLsizei count, GLsizei primcount); bool ValidateDrawArraysInstancedANGLE(Context *context, GLenum mode, GLint first, GLsizei count, GLsizei primcount); -bool ValidateDrawElements(Context *context, GLenum mode, GLsizei count, GLenum type, - const GLvoid* indices, GLsizei primcount, rx::RangeUI *indexRangeOut); +bool ValidateDrawElements(ValidationContext *context, + GLenum mode, + GLsizei count, + GLenum type, + const GLvoid *indices, + GLsizei primcount, + IndexRange *indexRangeOut); -bool ValidateDrawElementsInstanced(Context *context, GLenum mode, GLsizei count, GLenum type, - const GLvoid *indices, GLsizei primcount, rx::RangeUI *indexRangeOut); -bool ValidateDrawElementsInstancedANGLE(Context *context, GLenum mode, GLsizei count, GLenum type, - const GLvoid *indices, GLsizei primcount, rx::RangeUI *indexRangeOut); +bool ValidateDrawElementsInstanced(Context *context, + GLenum mode, + GLsizei count, + GLenum type, + const GLvoid *indices, + GLsizei primcount, + IndexRange *indexRangeOut); +bool ValidateDrawElementsInstancedANGLE(Context *context, + GLenum mode, + GLsizei count, + GLenum type, + const GLvoid *indices, + GLsizei primcount, + IndexRange *indexRangeOut); bool ValidateFramebufferTextureBase(Context *context, GLenum target, GLenum attachment, GLuint texture, GLint level); bool ValidateFramebufferTexture2D(Context *context, GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +bool ValidateFramebufferRenderbuffer(Context *context, + GLenum target, + GLenum attachment, + GLenum renderbuffertarget, + GLuint renderbuffer); bool ValidateGetUniformBase(Context *context, GLuint program, GLint location); bool ValidateGetUniformfv(Context *context, GLuint program, GLint location, GLfloat* params); @@ -89,6 +184,82 @@ bool ValidateGetUniformiv(Context *context, GLuint program, GLint location, GLin bool ValidateGetnUniformfvEXT(Context *context, GLuint program, GLint location, GLsizei bufSize, GLfloat* params); bool ValidateGetnUniformivEXT(Context *context, GLuint program, GLint location, GLsizei bufSize, GLint* params); -} +bool ValidateDiscardFramebufferBase(Context *context, GLenum target, GLsizei numAttachments, + const GLenum *attachments, bool defaultFramebuffer); + +bool ValidateInsertEventMarkerEXT(Context *context, GLsizei length, const char *marker); +bool ValidatePushGroupMarkerEXT(Context *context, GLsizei length, const char *marker); + +bool ValidateEGLImageTargetTexture2DOES(Context *context, + egl::Display *display, + GLenum target, + egl::Image *image); +bool ValidateEGLImageTargetRenderbufferStorageOES(Context *context, + egl::Display *display, + GLenum target, + egl::Image *image); + +bool ValidateBindVertexArrayBase(Context *context, GLuint array); + +bool ValidateLinkProgram(Context *context, GLuint program); +bool ValidateProgramBinaryBase(Context *context, + GLuint program, + GLenum binaryFormat, + const void *binary, + GLint length); +bool ValidateGetProgramBinaryBase(Context *context, + GLuint program, + GLsizei bufSize, + GLsizei *length, + GLenum *binaryFormat, + void *binary); +bool ValidateUseProgram(Context *context, GLuint program); + +bool ValidateCopyTexImage2D(ValidationContext *context, + GLenum target, + GLint level, + GLenum internalformat, + GLint x, + GLint y, + GLsizei width, + GLsizei height, + GLint border); +bool ValidateDrawBuffersBase(ValidationContext *context, GLsizei n, const GLenum *bufs); +bool ValidateCopyTexSubImage2D(Context *context, + GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLint x, + GLint y, + GLsizei width, + GLsizei height); + +bool ValidateGetBufferPointervBase(Context *context, GLenum target, GLenum pname, void **params); +bool ValidateUnmapBufferBase(Context *context, GLenum target); +bool ValidateMapBufferRangeBase(Context *context, + GLenum target, + GLintptr offset, + GLsizeiptr length, + GLbitfield access); +bool ValidateFlushMappedBufferRangeBase(Context *context, + GLenum target, + GLintptr offset, + GLsizeiptr length); + +bool ValidateGenBuffers(Context *context, GLint n, GLuint *buffers); +bool ValidateDeleteBuffers(Context *context, GLint n, const GLuint *buffers); +bool ValidateGenFramebuffers(Context *context, GLint n, GLuint *framebuffers); +bool ValidateDeleteFramebuffers(Context *context, GLint n, const GLuint *framebuffers); +bool ValidateGenRenderbuffers(Context *context, GLint n, GLuint *renderbuffers); +bool ValidateDeleteRenderbuffers(Context *context, GLint n, const GLuint *renderbuffers); +bool ValidateGenTextures(Context *context, GLint n, GLuint *textures); +bool ValidateDeleteTextures(Context *context, GLint n, const GLuint *textures); + +bool ValidateGenOrDelete(Context *context, GLint n); + +// Error messages shared here for use in testing. +extern const char *g_ExceedsMaxElementErrorMessage; +} // namespace gl #endif // LIBANGLE_VALIDATION_ES_H_ diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/validationES2.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/validationES2.cpp index 9eece1b54aca..a8266b963936 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/validationES2.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/validationES2.cpp @@ -8,6 +8,7 @@ #include "libANGLE/validationES2.h" #include "libANGLE/validationES.h" +#include "libANGLE/validationES3.h" #include "libANGLE/Context.h" #include "libANGLE/Texture.h" #include "libANGLE/Framebuffer.h" @@ -21,6 +22,42 @@ namespace gl { +namespace +{ + +bool IsPartialBlit(gl::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; +} + +} // anonymous namespace + bool ValidateES2TexImageParameters(Context *context, GLenum target, GLint level, GLenum internalformat, bool isCompressed, bool isSubImage, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels) @@ -31,7 +68,7 @@ bool ValidateES2TexImageParameters(Context *context, GLenum target, GLint level, return false; } - if (!ValidImageSize(context, target, level, width, height, 1)) + if (!ValidImageSizeParameters(context, target, level, width, height, 1, isSubImage)) { context->recordError(Error(GL_INVALID_VALUE)); return false; @@ -110,7 +147,7 @@ bool ValidateES2TexImageParameters(Context *context, GLenum target, GLint level, } else { - if (texture->isImmutable()) + if (texture->getImmutableFormat()) { context->recordError(Error(GL_INVALID_OPERATION)); return false; @@ -124,23 +161,10 @@ bool ValidateES2TexImageParameters(Context *context, GLenum target, GLint level, return false; } - GLenum actualInternalFormat = isSubImage ? texture->getInternalFormat(target, level) : internalformat; - const InternalFormat &actualFormatInfo = GetInternalFormatInfo(actualInternalFormat); - - if (isCompressed != actualFormatInfo.compressed) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return false; - } - if (isCompressed) { - if (!ValidCompressedImageSize(context, actualInternalFormat, width, height)) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return false; - } - + GLenum actualInternalFormat = + isSubImage ? texture->getInternalFormat(target, level) : internalformat; switch (actualInternalFormat) { case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: @@ -165,8 +189,29 @@ bool ValidateES2TexImageParameters(Context *context, GLenum target, GLint level, return false; } break; + case GL_ETC1_RGB8_OES: + if (!context->getExtensions().compressedETC1RGB8Texture) + { + context->recordError(Error(GL_INVALID_ENUM)); + return false; + } + break; + case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE: + if (!context->getExtensions().lossyETCDecode) + { + context->recordError( + Error(GL_INVALID_ENUM, "ANGLE_lossy_etc_decode extension is not supported")); + return false; + } + break; default: - context->recordError(Error(GL_INVALID_ENUM)); + context->recordError(Error( + GL_INVALID_ENUM, "internalformat is not a supported compressed internal format")); + return false; + } + if (!ValidCompressedImageSize(context, actualInternalFormat, width, height)) + { + context->recordError(Error(GL_INVALID_OPERATION)); return false; } } @@ -350,6 +395,33 @@ bool ValidateES2TexImageParameters(Context *context, GLenum target, GLint level, return false; } break; + case GL_ETC1_RGB8_OES: + if (context->getExtensions().compressedETC1RGB8Texture) + { + context->recordError(Error(GL_INVALID_OPERATION)); + return false; + } + else + { + context->recordError(Error(GL_INVALID_ENUM)); + return false; + } + break; + case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE: + if (context->getExtensions().lossyETCDecode) + { + context->recordError( + Error(GL_INVALID_OPERATION, + "ETC1_RGB8_LOSSY_DECODE_ANGLE can't work with this type.")); + return false; + } + else + { + context->recordError( + Error(GL_INVALID_ENUM, "ANGLE_lossy_etc_decode extension is not supported.")); + return false; + } + break; case GL_DEPTH_COMPONENT: case GL_DEPTH_STENCIL_OES: if (!context->getExtensions().depthTextures) @@ -395,21 +467,34 @@ bool ValidateES2TexImageParameters(Context *context, GLenum target, GLint level, return true; } - - -bool ValidateES2CopyTexImageParameters(Context* context, GLenum target, GLint level, GLenum internalformat, bool isSubImage, - GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, +bool ValidateES2CopyTexImageParameters(ValidationContext *context, + GLenum target, + GLint level, + GLenum internalformat, + bool isSubImage, + GLint xoffset, + GLint yoffset, + GLint x, + GLint y, + GLsizei width, + GLsizei height, GLint border) { GLenum textureInternalFormat = GL_NONE; + if (!ValidTexture2DDestinationTarget(context, target)) + { + context->recordError(Error(GL_INVALID_ENUM, "Invalid texture target")); + return false; + } + if (!ValidateCopyTexImageParametersBase(context, target, level, internalformat, isSubImage, xoffset, yoffset, 0, x, y, width, height, border, &textureInternalFormat)) { return false; } - gl::Framebuffer *framebuffer = context->getState().getReadFramebuffer(); + const gl::Framebuffer *framebuffer = context->getState().getReadFramebuffer(); GLenum colorbufferFormat = framebuffer->getReadColorbuffer()->getInternalFormat(); const auto &internalFormatInfo = gl::GetInternalFormatInfo(textureInternalFormat); GLenum textureFormat = internalFormatInfo.format; @@ -502,6 +587,8 @@ bool ValidateES2CopyTexImageParameters(Context* context, GLenum target, GLint le case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE: case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE: + case GL_ETC1_RGB8_OES: + case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE: context->recordError(Error(GL_INVALID_OPERATION)); return false; case GL_DEPTH_COMPONENT: @@ -642,6 +729,32 @@ bool ValidateES2CopyTexImageParameters(Context* context, GLenum target, GLint le return false; } break; + case GL_ETC1_RGB8_OES: + if (context->getExtensions().compressedETC1RGB8Texture) + { + context->recordError(Error(GL_INVALID_OPERATION)); + return false; + } + else + { + context->recordError(Error(GL_INVALID_ENUM)); + return false; + } + break; + case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE: + if (context->getExtensions().lossyETCDecode) + { + context->recordError(Error(GL_INVALID_OPERATION, + "ETC1_RGB8_LOSSY_DECODE_ANGLE can't be copied to.")); + return false; + } + else + { + context->recordError( + Error(GL_INVALID_ENUM, "ANGLE_lossy_etc_decode extension is not supported.")); + return false; + } + break; case GL_DEPTH_COMPONENT: case GL_DEPTH_COMPONENT16: case GL_DEPTH_COMPONENT32_OES: @@ -759,6 +872,21 @@ bool ValidateES2TexStorageParameters(Context *context, GLenum target, GLsizei le return false; } break; + case GL_ETC1_RGB8_OES: + if (!context->getExtensions().compressedETC1RGB8Texture) + { + context->recordError(Error(GL_INVALID_ENUM)); + return false; + } + break; + case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE: + if (!context->getExtensions().lossyETCDecode) + { + context->recordError( + Error(GL_INVALID_ENUM, "ANGLE_lossy_etc_decode extension is not supported.")); + return false; + } + break; case GL_RGBA32F_EXT: case GL_RGB32F_EXT: case GL_ALPHA32F_EXT: @@ -824,7 +952,7 @@ bool ValidateES2TexStorageParameters(Context *context, GLenum target, GLsizei le return false; } - if (texture->isImmutable()) + if (texture->getImmutableFormat()) { context->recordError(Error(GL_INVALID_OPERATION)); return false; @@ -879,4 +1007,1008 @@ bool ValidES2ReadFormatType(Context *context, GLenum format, GLenum type) return true; } +bool ValidateDiscardFramebufferEXT(Context *context, GLenum target, GLsizei numAttachments, + const GLenum *attachments) +{ + if (!context->getExtensions().discardFramebuffer) + { + context->recordError(Error(GL_INVALID_OPERATION, "Extension not enabled")); + return false; + } + + bool defaultFramebuffer = false; + + switch (target) + { + case GL_FRAMEBUFFER: + defaultFramebuffer = (context->getState().getTargetFramebuffer(GL_FRAMEBUFFER)->id() == 0); + break; + default: + context->recordError(Error(GL_INVALID_ENUM, "Invalid framebuffer target")); + return false; + } + + return ValidateDiscardFramebufferBase(context, target, numAttachments, attachments, defaultFramebuffer); +} + +bool ValidateBindVertexArrayOES(Context *context, GLuint array) +{ + if (!context->getExtensions().vertexArrayObject) + { + context->recordError(Error(GL_INVALID_OPERATION, "Extension not enabled")); + return false; + } + + return ValidateBindVertexArrayBase(context, array); +} + +bool ValidateDeleteVertexArraysOES(Context *context, GLsizei n) +{ + if (!context->getExtensions().vertexArrayObject) + { + context->recordError(Error(GL_INVALID_OPERATION, "Extension not enabled")); + return false; + } + + return ValidateGenOrDelete(context, n); +} + +bool ValidateGenVertexArraysOES(Context *context, GLsizei n) +{ + if (!context->getExtensions().vertexArrayObject) + { + context->recordError(Error(GL_INVALID_OPERATION, "Extension not enabled")); + return false; + } + + return ValidateGenOrDelete(context, n); +} + +bool ValidateIsVertexArrayOES(Context *context) +{ + if (!context->getExtensions().vertexArrayObject) + { + context->recordError(Error(GL_INVALID_OPERATION, "Extension not enabled")); + return false; + } + + return true; +} + +bool ValidateProgramBinaryOES(Context *context, + GLuint program, + GLenum binaryFormat, + const void *binary, + GLint length) +{ + if (!context->getExtensions().getProgramBinary) + { + context->recordError(Error(GL_INVALID_OPERATION, "Extension not enabled")); + return false; + } + + return ValidateProgramBinaryBase(context, program, binaryFormat, binary, length); +} + +bool ValidateGetProgramBinaryOES(Context *context, + GLuint program, + GLsizei bufSize, + GLsizei *length, + GLenum *binaryFormat, + void *binary) +{ + if (!context->getExtensions().getProgramBinary) + { + context->recordError(Error(GL_INVALID_OPERATION, "Extension not enabled")); + return false; + } + + return ValidateGetProgramBinaryBase(context, 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(Context *context, + GLenum source, + GLenum type, + GLenum severity, + GLsizei count, + const GLuint *ids, + GLboolean enabled) +{ + if (!context->getExtensions().debug) + { + context->recordError(Error(GL_INVALID_OPERATION, "Extension not enabled")); + return false; + } + + if (!ValidDebugSource(source, false) && source != GL_DONT_CARE) + { + context->recordError(Error(GL_INVALID_ENUM, "Invalid debug source.")); + return false; + } + + if (!ValidDebugType(type) && type != GL_DONT_CARE) + { + context->recordError(Error(GL_INVALID_ENUM, "Invalid debug type.")); + return false; + } + + if (!ValidDebugSeverity(severity) && severity != GL_DONT_CARE) + { + context->recordError(Error(GL_INVALID_ENUM, "Invalid debug severity.")); + return false; + } + + if (count > 0) + { + if (source == GL_DONT_CARE || type == GL_DONT_CARE) + { + context->recordError(Error( + GL_INVALID_OPERATION, + "If count is greater than zero, source and severity cannot be GL_DONT_CARE.")); + return false; + } + + if (severity != GL_DONT_CARE) + { + context->recordError( + Error(GL_INVALID_OPERATION, + "If count is greater than zero, severity must be GL_DONT_CARE.")); + return false; + } + } + + return true; +} + +bool ValidateDebugMessageInsertKHR(Context *context, + GLenum source, + GLenum type, + GLuint id, + GLenum severity, + GLsizei length, + const GLchar *buf) +{ + if (!context->getExtensions().debug) + { + context->recordError(Error(GL_INVALID_OPERATION, "Extension not enabled")); + 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->recordError(Error(GL_INVALID_ENUM, "Invalid debug severity.")); + return false; + } + + if (!ValidDebugType(type)) + { + context->recordError(Error(GL_INVALID_ENUM, "Invalid debug type.")); + return false; + } + + if (!ValidDebugSource(source, true)) + { + context->recordError(Error(GL_INVALID_ENUM, "Invalid debug source.")); + return false; + } + + size_t messageLength = (length < 0) ? strlen(buf) : length; + if (messageLength > context->getExtensions().maxDebugMessageLength) + { + context->recordError( + Error(GL_INVALID_VALUE, "Message length is larger than GL_MAX_DEBUG_MESSAGE_LENGTH.")); + return false; + } + + return true; +} + +bool ValidateDebugMessageCallbackKHR(Context *context, + GLDEBUGPROCKHR callback, + const void *userParam) +{ + if (!context->getExtensions().debug) + { + context->recordError(Error(GL_INVALID_OPERATION, "Extension not enabled")); + return false; + } + + return true; +} + +bool ValidateGetDebugMessageLogKHR(Context *context, + GLuint count, + GLsizei bufSize, + GLenum *sources, + GLenum *types, + GLuint *ids, + GLenum *severities, + GLsizei *lengths, + GLchar *messageLog) +{ + if (!context->getExtensions().debug) + { + context->recordError(Error(GL_INVALID_OPERATION, "Extension not enabled")); + return false; + } + + if (bufSize < 0 && messageLog != nullptr) + { + context->recordError( + Error(GL_INVALID_VALUE, "bufSize must be positive if messageLog is not null.")); + return false; + } + + return true; } + +bool ValidatePushDebugGroupKHR(Context *context, + GLenum source, + GLuint id, + GLsizei length, + const GLchar *message) +{ + if (!context->getExtensions().debug) + { + context->recordError(Error(GL_INVALID_OPERATION, "Extension not enabled")); + return false; + } + + if (!ValidDebugSource(source, true)) + { + context->recordError(Error(GL_INVALID_ENUM, "Invalid debug source.")); + return false; + } + + size_t messageLength = (length < 0) ? strlen(message) : length; + if (messageLength > context->getExtensions().maxDebugMessageLength) + { + context->recordError( + Error(GL_INVALID_VALUE, "Message length is larger than GL_MAX_DEBUG_MESSAGE_LENGTH.")); + return false; + } + + size_t currentStackSize = context->getState().getDebug().getGroupStackDepth(); + if (currentStackSize >= context->getExtensions().maxDebugGroupStackDepth) + { + context->recordError( + Error(GL_STACK_OVERFLOW, + "Cannot push more than GL_MAX_DEBUG_GROUP_STACK_DEPTH debug groups.")); + return false; + } + + return true; +} + +bool ValidatePopDebugGroupKHR(Context *context) +{ + if (!context->getExtensions().debug) + { + context->recordError(Error(GL_INVALID_OPERATION, "Extension not enabled")); + return false; + } + + size_t currentStackSize = context->getState().getDebug().getGroupStackDepth(); + if (currentStackSize <= 1) + { + context->recordError(Error(GL_STACK_UNDERFLOW, "Cannot pop the default debug group.")); + return false; + } + + return true; +} + +static bool ValidateObjectIdentifierAndName(Context *context, GLenum identifier, GLuint name) +{ + switch (identifier) + { + case GL_BUFFER: + if (context->getBuffer(name) == nullptr) + { + context->recordError(Error(GL_INVALID_VALUE, "name is not a valid buffer.")); + return false; + } + return true; + + case GL_SHADER: + if (context->getShader(name) == nullptr) + { + context->recordError(Error(GL_INVALID_VALUE, "name is not a valid shader.")); + return false; + } + return true; + + case GL_PROGRAM: + if (context->getProgram(name) == nullptr) + { + context->recordError(Error(GL_INVALID_VALUE, "name is not a valid program.")); + return false; + } + return true; + + case GL_VERTEX_ARRAY: + if (context->getVertexArray(name) == nullptr) + { + context->recordError(Error(GL_INVALID_VALUE, "name is not a valid vertex array.")); + return false; + } + return true; + + case GL_QUERY: + if (context->getQuery(name) == nullptr) + { + context->recordError(Error(GL_INVALID_VALUE, "name is not a valid query.")); + return false; + } + return true; + + case GL_TRANSFORM_FEEDBACK: + if (context->getTransformFeedback(name) == nullptr) + { + context->recordError( + Error(GL_INVALID_VALUE, "name is not a valid transform feedback.")); + return false; + } + return true; + + case GL_SAMPLER: + if (context->getSampler(name) == nullptr) + { + context->recordError(Error(GL_INVALID_VALUE, "name is not a valid sampler.")); + return false; + } + return true; + + case GL_TEXTURE: + if (context->getTexture(name) == nullptr) + { + context->recordError(Error(GL_INVALID_VALUE, "name is not a valid texture.")); + return false; + } + return true; + + case GL_RENDERBUFFER: + if (context->getRenderbuffer(name) == nullptr) + { + context->recordError(Error(GL_INVALID_VALUE, "name is not a valid renderbuffer.")); + return false; + } + return true; + + case GL_FRAMEBUFFER: + if (context->getFramebuffer(name) == nullptr) + { + context->recordError(Error(GL_INVALID_VALUE, "name is not a valid framebuffer.")); + return false; + } + return true; + + default: + context->recordError(Error(GL_INVALID_ENUM, "Invalid identifier.")); + return false; + } + + return true; +} + +bool ValidateObjectLabelKHR(Context *context, + GLenum identifier, + GLuint name, + GLsizei length, + const GLchar *label) +{ + if (!context->getExtensions().debug) + { + context->recordError(Error(GL_INVALID_OPERATION, "Extension not enabled")); + return false; + } + + if (!ValidateObjectIdentifierAndName(context, identifier, name)) + { + return false; + } + + size_t labelLength = (length < 0) ? strlen(label) : length; + if (labelLength > context->getExtensions().maxLabelLength) + { + context->recordError( + Error(GL_INVALID_VALUE, "Label length is larger than GL_MAX_LABEL_LENGTH.")); + return false; + } + + return true; +} + +bool ValidateGetObjectLabelKHR(Context *context, + GLenum identifier, + GLuint name, + GLsizei bufSize, + GLsizei *length, + GLchar *label) +{ + if (!context->getExtensions().debug) + { + context->recordError(Error(GL_INVALID_OPERATION, "Extension not enabled")); + return false; + } + + if (bufSize < 0) + { + context->recordError(Error(GL_INVALID_VALUE, "bufSize cannot be negative.")); + return false; + } + + if (!ValidateObjectIdentifierAndName(context, identifier, name)) + { + return false; + } + + // Can no-op if bufSize is zero. + return bufSize > 0; +} + +static bool ValidateObjectPtrName(Context *context, const void *ptr) +{ + if (context->getFenceSync(reinterpret_cast(const_cast(ptr))) == nullptr) + { + context->recordError(Error(GL_INVALID_VALUE, "name is not a valid sync.")); + return false; + } + + return true; +} + +bool ValidateObjectPtrLabelKHR(Context *context, + const void *ptr, + GLsizei length, + const GLchar *label) +{ + if (!context->getExtensions().debug) + { + context->recordError(Error(GL_INVALID_OPERATION, "Extension not enabled")); + return false; + } + + if (!ValidateObjectPtrName(context, ptr)) + { + return false; + } + + size_t labelLength = (length < 0) ? strlen(label) : length; + if (labelLength > context->getExtensions().maxLabelLength) + { + context->recordError( + Error(GL_INVALID_VALUE, "Label length is larger than GL_MAX_LABEL_LENGTH.")); + return false; + } + + return true; +} + +bool ValidateGetObjectPtrLabelKHR(Context *context, + const void *ptr, + GLsizei bufSize, + GLsizei *length, + GLchar *label) +{ + if (!context->getExtensions().debug) + { + context->recordError(Error(GL_INVALID_OPERATION, "Extension not enabled")); + return false; + } + + if (bufSize < 0) + { + context->recordError(Error(GL_INVALID_VALUE, "bufSize cannot be negative.")); + return false; + } + + if (!ValidateObjectPtrName(context, ptr)) + { + return false; + } + + // Can no-op if bufSize is zero. + return bufSize > 0; +} + +bool ValidateGetPointervKHR(Context *context, GLenum pname, void **params) +{ + if (!context->getExtensions().debug) + { + context->recordError(Error(GL_INVALID_OPERATION, "Extension not enabled")); + return false; + } + + // TODO: represent this in Context::getQueryParameterInfo. + switch (pname) + { + case GL_DEBUG_CALLBACK_FUNCTION: + case GL_DEBUG_CALLBACK_USER_PARAM: + break; + + default: + context->recordError(Error(GL_INVALID_ENUM, "Invalid pname.")); + return false; + } + + return true; +} + +bool ValidateBlitFramebufferANGLE(Context *context, + GLint srcX0, + GLint srcY0, + GLint srcX1, + GLint srcY1, + GLint dstX0, + GLint dstY0, + GLint dstX1, + GLint dstY1, + GLbitfield mask, + GLenum filter) +{ + if (!context->getExtensions().framebufferBlit) + { + context->recordError(Error(GL_INVALID_OPERATION, "Blit extension not available.")); + return false; + } + + if (srcX1 - srcX0 != dstX1 - dstX0 || srcY1 - srcY0 != dstY1 - dstY0) + { + // TODO(jmadill): Determine if this should be available on other implementations. + context->recordError(Error( + GL_INVALID_OPERATION, + "Scaling and flipping in BlitFramebufferANGLE not supported by this implementation.")); + return false; + } + + if (filter == GL_LINEAR) + { + context->recordError(Error(GL_INVALID_ENUM, "Linear blit not supported in this extension")); + return false; + } + + const Framebuffer *readFramebuffer = context->getState().getReadFramebuffer(); + const Framebuffer *drawFramebuffer = context->getState().getDrawFramebuffer(); + + if (mask & GL_COLOR_BUFFER_BIT) + { + const FramebufferAttachment *readColorAttachment = readFramebuffer->getReadColorbuffer(); + const FramebufferAttachment *drawColorAttachment = drawFramebuffer->getFirstColorbuffer(); + + if (readColorAttachment && drawColorAttachment) + { + if (!(readColorAttachment->type() == GL_TEXTURE && + readColorAttachment->getTextureImageIndex().type == GL_TEXTURE_2D) && + readColorAttachment->type() != GL_RENDERBUFFER && + readColorAttachment->type() != GL_FRAMEBUFFER_DEFAULT) + { + context->recordError(Error(GL_INVALID_OPERATION)); + 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().type == GL_TEXTURE_2D) && + attachment->type() != GL_RENDERBUFFER && + attachment->type() != GL_FRAMEBUFFER_DEFAULT) + { + context->recordError(Error(GL_INVALID_OPERATION)); + return false; + } + + // Return an error if the destination formats do not match + if (attachment->getInternalFormat() != readColorAttachment->getInternalFormat()) + { + context->recordError(Error(GL_INVALID_OPERATION)); + return false; + } + } + } + + int readSamples = readFramebuffer->getSamples(context->getData()); + + if (readSamples != 0 && + IsPartialBlit(context, readColorAttachment, drawColorAttachment, srcX0, srcY0, + srcX1, srcY1, dstX0, dstY0, dstX1, dstY1)) + { + context->recordError(Error(GL_INVALID_OPERATION)); + 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(attachments[i]); + const FramebufferAttachment *drawBuffer = + drawFramebuffer->getAttachment(attachments[i]); + + if (readBuffer && drawBuffer) + { + if (IsPartialBlit(context, readBuffer, drawBuffer, srcX0, srcY0, srcX1, srcY1, + dstX0, dstY0, dstX1, dstY1)) + { + // only whole-buffer copies are permitted + ERR( + "Only whole-buffer depth and stencil blits are supported by this " + "implementation."); + context->recordError(Error(GL_INVALID_OPERATION)); + return false; + } + + if (readBuffer->getSamples() != 0 || drawBuffer->getSamples() != 0) + { + context->recordError(Error(GL_INVALID_OPERATION)); + return false; + } + } + } + } + + return ValidateBlitFramebufferParameters(context, srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, + dstX1, dstY1, mask, filter); +} + +bool ValidateClear(ValidationContext *context, GLbitfield mask) +{ + const Framebuffer *framebufferObject = context->getState().getDrawFramebuffer(); + ASSERT(framebufferObject); + + if (framebufferObject->checkStatus(context->getData()) != GL_FRAMEBUFFER_COMPLETE) + { + context->recordError(Error(GL_INVALID_FRAMEBUFFER_OPERATION)); + return false; + } + + if ((mask & ~(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) != 0) + { + context->recordError(Error(GL_INVALID_VALUE)); + return false; + } + + return true; +} + +bool ValidateDrawBuffersEXT(ValidationContext *context, GLsizei n, const GLenum *bufs) +{ + if (!context->getExtensions().drawBuffers) + { + context->recordError(Error(GL_INVALID_OPERATION, "Extension not supported.")); + return false; + } + + return ValidateDrawBuffersBase(context, n, bufs); +} + +bool ValidateTexImage2D(Context *context, + GLenum target, + GLint level, + GLint internalformat, + GLsizei width, + GLsizei height, + GLint border, + GLenum format, + GLenum type, + const GLvoid *pixels) +{ + if (context->getClientVersion() < 3) + { + return ValidateES2TexImageParameters(context, target, level, internalformat, false, false, + 0, 0, width, height, border, format, type, pixels); + } + + ASSERT(context->getClientVersion() >= 3); + return ValidateES3TexImage2DParameters(context, target, level, internalformat, false, false, 0, + 0, 0, width, height, 1, border, format, type, pixels); +} + +bool ValidateTexSubImage2D(Context *context, + GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLsizei width, + GLsizei height, + GLenum format, + GLenum type, + const GLvoid *pixels) +{ + + if (context->getClientVersion() < 3) + { + return ValidateES2TexImageParameters(context, target, level, GL_NONE, false, true, xoffset, + yoffset, width, height, 0, format, type, pixels); + } + + ASSERT(context->getClientVersion() >= 3); + return ValidateES3TexImage2DParameters(context, target, level, GL_NONE, false, true, xoffset, + yoffset, 0, width, height, 1, 0, format, type, pixels); +} + +bool ValidateCompressedTexImage2D(Context *context, + GLenum target, + GLint level, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLint border, + GLsizei imageSize, + const GLvoid *data) +{ + if (context->getClientVersion() < 3) + { + if (!ValidateES2TexImageParameters(context, target, level, internalformat, true, false, 0, + 0, width, height, border, GL_NONE, GL_NONE, data)) + { + return false; + } + } + else + { + ASSERT(context->getClientVersion() >= 3); + if (!ValidateES3TexImage2DParameters(context, target, level, internalformat, true, false, 0, + 0, 0, width, height, 1, border, GL_NONE, GL_NONE, + data)) + { + return false; + } + } + + const InternalFormat &formatInfo = GetInternalFormatInfo(internalformat); + if (imageSize < 0 || + static_cast(imageSize) != + formatInfo.computeBlockSize(GL_UNSIGNED_BYTE, width, height)) + { + context->recordError(Error(GL_INVALID_VALUE)); + return false; + } + + return true; +} + +bool ValidateCompressedTexSubImage2D(Context *context, + GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLsizei width, + GLsizei height, + GLenum format, + GLsizei imageSize, + const GLvoid *data) +{ + if (context->getClientVersion() < 3) + { + if (!ValidateES2TexImageParameters(context, target, level, GL_NONE, true, true, xoffset, + yoffset, width, height, 0, GL_NONE, GL_NONE, data)) + { + return false; + } + } + else + { + ASSERT(context->getClientVersion() >= 3); + if (!ValidateES3TexImage2DParameters(context, target, level, GL_NONE, true, true, xoffset, + yoffset, 0, width, height, 1, 0, GL_NONE, GL_NONE, + data)) + { + return false; + } + } + + const InternalFormat &formatInfo = GetInternalFormatInfo(format); + if (imageSize < 0 || + static_cast(imageSize) != + formatInfo.computeBlockSize(GL_UNSIGNED_BYTE, width, height)) + { + context->recordError(Error(GL_INVALID_VALUE)); + return false; + } + + return true; +} + +bool ValidateGetBufferPointervOES(Context *context, GLenum target, GLenum pname, void **params) +{ + if (!context->getExtensions().mapBuffer) + { + context->recordError(Error(GL_INVALID_OPERATION, "Map buffer extension not available.")); + return false; + } + + return ValidateGetBufferPointervBase(context, target, pname, params); +} + +bool ValidateMapBufferOES(Context *context, GLenum target, GLenum access) +{ + if (!context->getExtensions().mapBuffer) + { + context->recordError(Error(GL_INVALID_OPERATION, "Map buffer extension not available.")); + return false; + } + + if (!ValidBufferTarget(context, target)) + { + context->recordError(Error(GL_INVALID_ENUM, "Invalid buffer target.")); + return false; + } + + Buffer *buffer = context->getState().getTargetBuffer(target); + + if (buffer == nullptr) + { + context->recordError(Error(GL_INVALID_OPERATION, "Attempted to map buffer object zero.")); + return false; + } + + if (access != GL_WRITE_ONLY_OES) + { + context->recordError(Error(GL_INVALID_ENUM, "Non-write buffer mapping not supported.")); + return false; + } + + if (buffer->isMapped()) + { + context->recordError(Error(GL_INVALID_OPERATION, "Buffer is already mapped.")); + return false; + } + + return true; +} + +bool ValidateUnmapBufferOES(Context *context, GLenum target) +{ + if (!context->getExtensions().mapBuffer) + { + context->recordError(Error(GL_INVALID_OPERATION, "Map buffer extension not available.")); + return false; + } + + return ValidateUnmapBufferBase(context, target); +} + +bool ValidateMapBufferRangeEXT(Context *context, + GLenum target, + GLintptr offset, + GLsizeiptr length, + GLbitfield access) +{ + if (!context->getExtensions().mapBufferRange) + { + context->recordError( + Error(GL_INVALID_OPERATION, "Map buffer range extension not available.")); + return false; + } + + return ValidateMapBufferRangeBase(context, target, offset, length, access); +} + +bool ValidateFlushMappedBufferRangeEXT(Context *context, + GLenum target, + GLintptr offset, + GLsizeiptr length) +{ + if (!context->getExtensions().mapBufferRange) + { + context->recordError( + Error(GL_INVALID_OPERATION, "Map buffer range extension not available.")); + return false; + } + + return ValidateFlushMappedBufferRangeBase(context, target, offset, length); +} + +bool ValidateBindTexture(Context *context, GLenum target, GLuint texture) +{ + Texture *textureObject = context->getTexture(texture); + if (textureObject && textureObject->getTarget() != target && texture != 0) + { + context->recordError(Error(GL_INVALID_OPERATION, "Invalid texture")); + return false; + } + + switch (target) + { + case GL_TEXTURE_2D: + case GL_TEXTURE_CUBE_MAP: + break; + + case GL_TEXTURE_3D: + case GL_TEXTURE_2D_ARRAY: + if (context->getClientVersion() < 3) + { + context->recordError(Error(GL_INVALID_ENUM, "GLES 3.0 disabled")); + return false; + } + break; + case GL_TEXTURE_EXTERNAL_OES: + if (!context->getExtensions().eglStreamConsumerExternal) + { + context->recordError( + Error(GL_INVALID_ENUM, "External texture extension not enabled")); + return false; + } + break; + default: + context->recordError(Error(GL_INVALID_ENUM, "Invalid target")); + return false; + } + + return true; +} + +} // namespace gl diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/validationES2.h b/Source/ThirdParty/ANGLE/src/libANGLE/validationES2.h index b9c1fd3bc40d..9acfec1828f7 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/validationES2.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/validationES2.h @@ -10,18 +10,29 @@ #define LIBANGLE_VALIDATION_ES2_H_ #include +#include namespace gl { - class Context; +class ValidationContext; +class Texture; bool ValidateES2TexImageParameters(Context *context, GLenum target, GLint level, GLenum internalformat, bool isCompressed, bool isSubImage, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels); -bool ValidateES2CopyTexImageParameters(Context* context, GLenum target, GLint level, GLenum internalformat, bool isSubImage, - GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, +bool ValidateES2CopyTexImageParameters(ValidationContext *context, + GLenum target, + GLint level, + GLenum internalformat, + bool isSubImage, + GLint xoffset, + GLint yoffset, + GLint x, + GLint y, + GLsizei width, + GLsizei height, GLint border); bool ValidateES2TexStorageParameters(Context *context, GLenum target, GLsizei levels, GLenum internalformat, @@ -29,6 +40,149 @@ bool ValidateES2TexStorageParameters(Context *context, GLenum target, GLsizei le bool ValidES2ReadFormatType(Context *context, GLenum format, GLenum type); -} +bool ValidateDiscardFramebufferEXT(Context *context, GLenum target, GLsizei numAttachments, + const GLenum *attachments); + +bool ValidateDrawBuffersEXT(ValidationContext *context, GLsizei n, const GLenum *bufs); + +bool ValidateBindVertexArrayOES(Context *context, GLuint array); +bool ValidateDeleteVertexArraysOES(Context *context, GLsizei n); +bool ValidateGenVertexArraysOES(Context *context, GLsizei n); +bool ValidateIsVertexArrayOES(Context *context); + +bool ValidateProgramBinaryOES(Context *context, + GLuint program, + GLenum binaryFormat, + const void *binary, + GLint length); +bool ValidateGetProgramBinaryOES(Context *context, + GLuint program, + GLsizei bufSize, + GLsizei *length, + GLenum *binaryFormat, + void *binary); + +// GL_KHR_debug +bool ValidateDebugMessageControlKHR(Context *context, + GLenum source, + GLenum type, + GLenum severity, + GLsizei count, + const GLuint *ids, + GLboolean enabled); +bool ValidateDebugMessageInsertKHR(Context *context, + GLenum source, + GLenum type, + GLuint id, + GLenum severity, + GLsizei length, + const GLchar *buf); +bool ValidateDebugMessageCallbackKHR(Context *context, + GLDEBUGPROCKHR callback, + const void *userParam); +bool ValidateGetDebugMessageLogKHR(Context *context, + GLuint count, + GLsizei bufSize, + GLenum *sources, + GLenum *types, + GLuint *ids, + GLenum *severities, + GLsizei *lengths, + GLchar *messageLog); +bool ValidatePushDebugGroupKHR(Context *context, + GLenum source, + GLuint id, + GLsizei length, + const GLchar *message); +bool ValidatePopDebugGroupKHR(Context *context); +bool ValidateObjectLabelKHR(Context *context, + GLenum identifier, + GLuint name, + GLsizei length, + const GLchar *label); +bool ValidateGetObjectLabelKHR(Context *context, + GLenum identifier, + GLuint name, + GLsizei bufSize, + GLsizei *length, + GLchar *label); +bool ValidateObjectPtrLabelKHR(Context *context, + const void *ptr, + GLsizei length, + const GLchar *label); +bool ValidateGetObjectPtrLabelKHR(Context *context, + const void *ptr, + GLsizei bufSize, + GLsizei *length, + GLchar *label); +bool ValidateGetPointervKHR(Context *context, GLenum pname, void **params); +bool ValidateBlitFramebufferANGLE(Context *context, + GLint srcX0, + GLint srcY0, + GLint srcX1, + GLint srcY1, + GLint dstX0, + GLint dstY0, + GLint dstX1, + GLint dstY1, + GLbitfield mask, + GLenum filter); + +bool ValidateClear(ValidationContext *context, GLbitfield mask); +bool ValidateTexImage2D(Context *context, + GLenum target, + GLint level, + GLint internalformat, + GLsizei width, + GLsizei height, + GLint border, + GLenum format, + GLenum type, + const GLvoid *pixels); +bool ValidateTexSubImage2D(Context *context, + GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLsizei width, + GLsizei height, + GLenum format, + GLenum type, + const GLvoid *pixels); +bool ValidateCompressedTexImage2D(Context *context, + GLenum target, + GLint level, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLint border, + GLsizei imageSize, + const GLvoid *data); +bool ValidateCompressedTexSubImage2D(Context *context, + GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLsizei width, + GLsizei height, + GLenum format, + GLsizei imageSize, + const GLvoid *data); +bool ValidateBindTexture(Context *context, GLenum target, GLuint texture); + +bool ValidateGetBufferPointervOES(Context *context, GLenum target, GLenum pname, void **params); +bool ValidateMapBufferOES(Context *context, GLenum target, GLenum access); +bool ValidateUnmapBufferOES(Context *context, GLenum target); +bool ValidateMapBufferRangeEXT(Context *context, + GLenum target, + GLintptr offset, + GLsizeiptr length, + GLbitfield access); +bool ValidateFlushMappedBufferRangeEXT(Context *context, + GLenum target, + GLintptr offset, + GLsizeiptr length); + +} // namespace gl #endif // LIBANGLE_VALIDATION_ES2_H_ diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/validationES3.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/validationES3.cpp index 9d07af31f6e5..c879ea5b797d 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/validationES3.cpp +++ b/Source/ThirdParty/ANGLE/src/libANGLE/validationES3.cpp @@ -131,6 +131,15 @@ ES3FormatCombinationSet BuildES3FormatSet() InsertES3FormatCombo(&set, GL_ALPHA, GL_ALPHA, GL_UNSIGNED_BYTE ); InsertES3FormatCombo(&set, GL_SRGB_ALPHA_EXT, GL_SRGB_ALPHA_EXT, GL_UNSIGNED_BYTE ); InsertES3FormatCombo(&set, GL_SRGB_EXT, GL_SRGB_EXT, GL_UNSIGNED_BYTE ); + InsertES3FormatCombo(&set, GL_RG, GL_RG, GL_UNSIGNED_BYTE ); + InsertES3FormatCombo(&set, GL_RG, GL_RG, GL_FLOAT ); + InsertES3FormatCombo(&set, GL_RG, GL_RG, GL_HALF_FLOAT ); + InsertES3FormatCombo(&set, GL_RG, GL_RG, GL_HALF_FLOAT_OES ); + InsertES3FormatCombo(&set, GL_RED, GL_RED, GL_UNSIGNED_BYTE ); + InsertES3FormatCombo(&set, GL_RED, GL_RED, GL_FLOAT ); + InsertES3FormatCombo(&set, GL_RED, GL_RED, GL_HALF_FLOAT ); + InsertES3FormatCombo(&set, GL_RED, GL_RED, GL_HALF_FLOAT_OES ); + InsertES3FormatCombo(&set, GL_DEPTH_STENCIL, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8 ); // Depth stencil formats InsertES3FormatCombo(&set, GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT ); @@ -145,6 +154,8 @@ ES3FormatCombinationSet BuildES3FormatSet() InsertES3FormatCombo(&set, GL_SRGB8, GL_SRGB_EXT, GL_UNSIGNED_BYTE ); // From GL_OES_texture_float + InsertES3FormatCombo(&set, GL_RGBA, GL_RGBA, GL_FLOAT ); + InsertES3FormatCombo(&set, GL_RGB, GL_RGB, GL_FLOAT ); InsertES3FormatCombo(&set, GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_FLOAT ); InsertES3FormatCombo(&set, GL_LUMINANCE, GL_LUMINANCE, GL_FLOAT ); InsertES3FormatCombo(&set, GL_ALPHA, GL_ALPHA, GL_FLOAT ); @@ -186,44 +197,19 @@ ES3FormatCombinationSet BuildES3FormatSet() // From GL_ANGLE_depth_texture InsertES3FormatCombo(&set, GL_DEPTH_COMPONENT32_OES, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT_24_8_OES ); - // Compressed formats - // From ES 3.0.1 spec, table 3.16 - // | Internal format | Format | Type | - // | | | | - InsertES3FormatCombo(&set, GL_COMPRESSED_R11_EAC, GL_COMPRESSED_R11_EAC, GL_UNSIGNED_BYTE); - InsertES3FormatCombo(&set, GL_COMPRESSED_R11_EAC, GL_COMPRESSED_R11_EAC, GL_UNSIGNED_BYTE); - InsertES3FormatCombo(&set, GL_COMPRESSED_SIGNED_R11_EAC, GL_COMPRESSED_SIGNED_R11_EAC, GL_UNSIGNED_BYTE); - InsertES3FormatCombo(&set, GL_COMPRESSED_RG11_EAC, GL_COMPRESSED_RG11_EAC, GL_UNSIGNED_BYTE); - InsertES3FormatCombo(&set, GL_COMPRESSED_SIGNED_RG11_EAC, GL_COMPRESSED_SIGNED_RG11_EAC, GL_UNSIGNED_BYTE); - InsertES3FormatCombo(&set, GL_COMPRESSED_RGB8_ETC2, GL_COMPRESSED_RGB8_ETC2, GL_UNSIGNED_BYTE); - InsertES3FormatCombo(&set, GL_COMPRESSED_SRGB8_ETC2, GL_COMPRESSED_SRGB8_ETC2, GL_UNSIGNED_BYTE); - InsertES3FormatCombo(&set, GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2, GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2, GL_UNSIGNED_BYTE); - InsertES3FormatCombo(&set, GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, GL_UNSIGNED_BYTE); - InsertES3FormatCombo(&set, GL_COMPRESSED_RGBA8_ETC2_EAC, GL_COMPRESSED_RGBA8_ETC2_EAC, GL_UNSIGNED_BYTE); - InsertES3FormatCombo(&set, GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC, GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC, GL_UNSIGNED_BYTE); - - - // From GL_EXT_texture_compression_dxt1 - InsertES3FormatCombo(&set, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, GL_UNSIGNED_BYTE); - InsertES3FormatCombo(&set, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_UNSIGNED_BYTE); - - // From GL_ANGLE_texture_compression_dxt3 - InsertES3FormatCombo(&set, GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, GL_UNSIGNED_BYTE); - - // From GL_ANGLE_texture_compression_dxt5 - InsertES3FormatCombo(&set, GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, GL_UNSIGNED_BYTE); - return set; } static bool ValidateTexImageFormatCombination(gl::Context *context, GLenum internalFormat, GLenum format, GLenum type) { - // Note: dEQP 2013.4 expects an INVALID_VALUE error for TexImage3D with an invalid - // internal format. (dEQP-GLES3.functional.negative_api.texture.teximage3d) + // 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. const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalFormat); if (!formatInfo.textureSupport(context->getClientVersion(), context->getExtensions())) { - context->recordError(Error(GL_INVALID_ENUM)); + context->recordError(Error(GL_INVALID_VALUE)); return false; } @@ -276,18 +262,25 @@ static bool ValidateTexImageFormatCombination(gl::Context *context, GLenum inter return true; } -bool ValidateES3TexImageParameters(Context *context, GLenum 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, const GLvoid *pixels) +bool ValidateES3TexImageParametersBase(Context *context, + GLenum 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, + const GLvoid *pixels) { - if (!ValidTexture2DDestinationTarget(context, target)) - { - context->recordError(Error(GL_INVALID_ENUM)); - return false; - } - // Validate image size - if (!ValidImageSize(context, target, level, width, height, depth)) + if (!ValidImageSizeParameters(context, target, level, width, height, depth, isSubImage)) { context->recordError(Error(GL_INVALID_VALUE)); return false; @@ -354,7 +347,7 @@ bool ValidateES3TexImageParameters(Context *context, GLenum target, GLint level, case GL_TEXTURE_2D_ARRAY: if (static_cast(width) > (caps.max2DTextureSize >> level) || static_cast(height) > (caps.max2DTextureSize >> level) || - static_cast(depth) > (caps.maxArrayTextureLayers >> level)) + static_cast(depth) > caps.maxArrayTextureLayers) { context->recordError(Error(GL_INVALID_VALUE)); return false; @@ -373,7 +366,7 @@ bool ValidateES3TexImageParameters(Context *context, GLenum target, GLint level, return false; } - if (texture->isImmutable() && !isSubImage) + if (texture->getImmutableFormat() && !isSubImage) { context->recordError(Error(GL_INVALID_OPERATION)); return false; @@ -384,13 +377,20 @@ bool ValidateES3TexImageParameters(Context *context, GLenum target, GLint level, const gl::InternalFormat &actualFormatInfo = gl::GetInternalFormatInfo(actualInternalFormat); if (isCompressed) { + if (!actualFormatInfo.compressed) + { + context->recordError(Error( + GL_INVALID_ENUM, "internalformat is not a supported compressed internal format.")); + return false; + } + if (!ValidCompressedImageSize(context, actualInternalFormat, width, height)) { context->recordError(Error(GL_INVALID_OPERATION)); return false; } - if (!actualFormatInfo.compressed) + if (!actualFormatInfo.textureSupport(context->getClientVersion(), context->getExtensions())) { context->recordError(Error(GL_INVALID_ENUM)); return false; @@ -511,6 +511,62 @@ bool ValidateES3TexImageParameters(Context *context, GLenum target, GLint level, return true; } +bool ValidateES3TexImage2DParameters(Context *context, + GLenum 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, + const GLvoid *pixels) +{ + if (!ValidTexture2DDestinationTarget(context, target)) + { + context->recordError(Error(GL_INVALID_ENUM)); + return false; + } + + return ValidateES3TexImageParametersBase(context, target, level, internalformat, isCompressed, + isSubImage, xoffset, yoffset, zoffset, width, height, + depth, border, format, type, pixels); +} + +bool ValidateES3TexImage3DParameters(Context *context, + GLenum 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, + const GLvoid *pixels) +{ + if (!ValidTexture3DDestinationTarget(context, target)) + { + context->recordError(Error(GL_INVALID_ENUM)); + return false; + } + + return ValidateES3TexImageParametersBase(context, target, level, internalformat, isCompressed, + isSubImage, xoffset, yoffset, zoffset, width, height, + depth, border, format, type, pixels); +} + struct EffectiveInternalFormatInfo { GLenum mEffectiveFormat; @@ -795,9 +851,19 @@ static bool IsValidES3CopyTexImageCombination(GLenum textureInternalFormat, GLen return false; } -bool ValidateES3CopyTexImageParameters(Context *context, GLenum target, GLint level, GLenum internalformat, - bool isSubImage, GLint xoffset, GLint yoffset, GLint zoffset, - GLint x, GLint y, GLsizei width, GLsizei height, GLint border) +bool ValidateES3CopyTexImageParametersBase(ValidationContext *context, + GLenum target, + GLint level, + GLenum internalformat, + bool isSubImage, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLint x, + GLint y, + GLsizei width, + GLsizei height, + GLint border) { GLenum textureInternalFormat; if (!ValidateCopyTexImageParametersBase(context, target, level, internalformat, isSubImage, @@ -807,7 +873,9 @@ bool ValidateES3CopyTexImageParameters(Context *context, GLenum target, GLint le return false; } - gl::Framebuffer *framebuffer = context->getState().getReadFramebuffer(); + const auto &state = context->getState(); + const gl::Framebuffer *framebuffer = state.getReadFramebuffer(); + GLuint readFramebufferID = framebuffer->id(); if (framebuffer->checkStatus(context->getData()) != GL_FRAMEBUFFER_COMPLETE) { @@ -815,8 +883,7 @@ bool ValidateES3CopyTexImageParameters(Context *context, GLenum target, GLint le return false; } - if (context->getState().getReadFramebuffer()->id() != 0 && - framebuffer->getSamples(context->getData()) != 0) + if (readFramebufferID != 0 && framebuffer->getSamples(context->getData()) != 0) { context->recordError(Error(GL_INVALID_OPERATION)); return false; @@ -828,7 +895,7 @@ bool ValidateES3CopyTexImageParameters(Context *context, GLenum target, GLint le if (isSubImage) { if (!IsValidES3CopyTexImageCombination(textureInternalFormat, colorbufferInternalFormat, - context->getState().getReadFramebuffer()->id())) + readFramebufferID)) { context->recordError(Error(GL_INVALID_OPERATION)); return false; @@ -837,7 +904,7 @@ bool ValidateES3CopyTexImageParameters(Context *context, GLenum target, GLint le else { if (!gl::IsValidES3CopyTexImageCombination(internalformat, colorbufferInternalFormat, - context->getState().getReadFramebuffer()->id())) + readFramebufferID)) { context->recordError(Error(GL_INVALID_OPERATION)); return false; @@ -848,8 +915,63 @@ bool ValidateES3CopyTexImageParameters(Context *context, GLenum target, GLint le return (width > 0 && height > 0); } -bool ValidateES3TexStorageParameters(Context *context, GLenum target, GLsizei levels, GLenum internalformat, - GLsizei width, GLsizei height, GLsizei depth) +bool ValidateES3CopyTexImage2DParameters(ValidationContext *context, + GLenum 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->recordError(Error(GL_INVALID_ENUM)); + return false; + } + + return ValidateES3CopyTexImageParametersBase(context, target, level, internalformat, isSubImage, + xoffset, yoffset, zoffset, x, y, width, height, + border); +} + +bool ValidateES3CopyTexImage3DParameters(ValidationContext *context, + GLenum 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->recordError(Error(GL_INVALID_ENUM)); + return false; + } + + return ValidateES3CopyTexImageParametersBase(context, target, level, internalformat, isSubImage, + xoffset, yoffset, zoffset, x, y, width, height, + border); +} + +bool ValidateES3TexStorageParametersBase(Context *context, + GLenum target, + GLsizei levels, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLsizei depth) { if (width < 1 || height < 1 || depth < 1 || levels < 1) { @@ -857,7 +979,13 @@ bool ValidateES3TexStorageParameters(Context *context, GLenum target, GLsizei le return false; } - if (levels > gl::log2(std::max(std::max(width, height), depth)) + 1) + GLsizei maxDim = std::max(width, height); + if (target != GL_TEXTURE_2D_ARRAY) + { + maxDim = std::max(maxDim, depth); + } + + if (levels > gl::log2(maxDim) + 1) { context->recordError(Error(GL_INVALID_OPERATION)); return false; @@ -919,7 +1047,7 @@ bool ValidateES3TexStorageParameters(Context *context, GLenum target, GLsizei le break; default: - context->recordError(Error(GL_INVALID_ENUM)); + UNREACHABLE(); return false; } @@ -930,7 +1058,7 @@ bool ValidateES3TexStorageParameters(Context *context, GLenum target, GLsizei le return false; } - if (texture->isImmutable()) + if (texture->getImmutableFormat()) { context->recordError(Error(GL_INVALID_OPERATION)); return false; @@ -952,6 +1080,86 @@ bool ValidateES3TexStorageParameters(Context *context, GLenum target, GLsizei le return true; } +bool ValidateES3TexStorage2DParameters(Context *context, + GLenum target, + GLsizei levels, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLsizei depth) +{ + if (!ValidTexture2DTarget(context, target)) + { + context->recordError(Error(GL_INVALID_ENUM)); + return false; + } + + return ValidateES3TexStorageParametersBase(context, target, levels, internalformat, width, + height, depth); +} + +bool ValidateES3TexStorage3DParameters(Context *context, + GLenum target, + GLsizei levels, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLsizei depth) +{ + if (!ValidTexture3DTarget(context, target)) + { + context->recordError(Error(GL_INVALID_ENUM)); + return false; + } + + return ValidateES3TexStorageParametersBase(context, target, levels, internalformat, width, + height, depth); +} + +bool ValidateBeginQuery(gl::Context *context, GLenum target, GLuint id) +{ + if (context->getClientVersion() < 3) + { + context->recordError(Error(GL_INVALID_OPERATION, "GLES version < 3.0")); + return false; + } + + return ValidateBeginQueryBase(context, target, id); +} + +bool ValidateEndQuery(gl::Context *context, GLenum target) +{ + if (context->getClientVersion() < 3) + { + context->recordError(Error(GL_INVALID_OPERATION, "GLES version < 3.0")); + return false; + } + + return ValidateEndQueryBase(context, target); +} + +bool ValidateGetQueryiv(Context *context, GLenum target, GLenum pname, GLint *params) +{ + if (context->getClientVersion() < 3) + { + context->recordError(Error(GL_INVALID_OPERATION, "GLES version < 3.0")); + return false; + } + + return ValidateGetQueryivBase(context, target, pname); +} + +bool ValidateGetQueryObjectuiv(Context *context, GLuint id, GLenum pname, GLuint *params) +{ + if (context->getClientVersion() < 3) + { + context->recordError(Error(GL_INVALID_OPERATION, "GLES version < 3.0")); + return false; + } + + return ValidateGetQueryObjectValueBase(context, id, pname); +} + bool ValidateFramebufferTextureLayer(Context *context, GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer) { @@ -1125,16 +1333,24 @@ bool ValidateES3RenderbufferStorageParameters(gl::Context *context, GLenum targe const TextureCaps &formatCaps = context->getTextureCaps().get(internalformat); if (static_cast(samples) > formatCaps.getMaxSamples()) { - context->recordError(Error(GL_INVALID_VALUE)); + context->recordError( + Error(GL_INVALID_OPERATION, + "Samples must not be greater than maximum supported value for the format.")); return false; } return true; } -bool ValidateInvalidateFramebufferParameters(Context *context, GLenum target, GLsizei numAttachments, - const GLenum* attachments) +bool ValidateInvalidateFramebuffer(Context *context, GLenum target, GLsizei numAttachments, + const GLenum *attachments) { + if (context->getClientVersion() < 3) + { + context->recordError(Error(GL_INVALID_OPERATION, "Operation only supported on ES 3.0 and above")); + return false; + } + bool defaultFramebuffer = false; switch (target) @@ -1147,73 +1363,64 @@ bool ValidateInvalidateFramebufferParameters(Context *context, GLenum target, GL defaultFramebuffer = context->getState().getReadFramebuffer()->id() == 0; break; default: - context->recordError(Error(GL_INVALID_ENUM)); - return false; + context->recordError(Error(GL_INVALID_ENUM, "Invalid framebuffer target")); + return false; } - for (int i = 0; i < numAttachments; ++i) + return ValidateDiscardFramebufferBase(context, target, numAttachments, attachments, defaultFramebuffer); +} + +bool ValidateClearBuffer(ValidationContext *context) +{ + if (context->getClientVersion() < 3) { - if (attachments[i] >= GL_COLOR_ATTACHMENT0 && attachments[i] <= GL_COLOR_ATTACHMENT15) - { - if (defaultFramebuffer) - { - context->recordError(Error(GL_INVALID_ENUM)); - return false; - } + context->recordError(Error(GL_INVALID_OPERATION)); + return false; + } - if (attachments[i] >= GL_COLOR_ATTACHMENT0 + context->getCaps().maxColorAttachments) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return false; - } - } - else - { - switch (attachments[i]) - { - case GL_DEPTH_ATTACHMENT: - case GL_STENCIL_ATTACHMENT: - case GL_DEPTH_STENCIL_ATTACHMENT: - if (defaultFramebuffer) - { - context->recordError(Error(GL_INVALID_ENUM)); - return false; - } - break; - case GL_COLOR: - case GL_DEPTH: - case GL_STENCIL: - if (!defaultFramebuffer) - { - context->recordError(Error(GL_INVALID_ENUM)); - return false; - } - break; - default: - context->recordError(Error(GL_INVALID_ENUM)); - return false; - } - } + const gl::Framebuffer *fbo = context->getState().getDrawFramebuffer(); + if (!fbo || fbo->checkStatus(context->getData()) != GL_FRAMEBUFFER_COMPLETE) + { + context->recordError(Error(GL_INVALID_FRAMEBUFFER_OPERATION)); + return false; } return true; } -bool ValidateClearBuffer(Context *context) +bool ValidateDrawRangeElements(Context *context, + GLenum mode, + GLuint start, + GLuint end, + GLsizei count, + GLenum type, + const GLvoid *indices, + IndexRange *indexRange) { if (context->getClientVersion() < 3) { - context->recordError(Error(GL_INVALID_OPERATION)); + context->recordError(Error(GL_INVALID_OPERATION, "Context does not support GLES3.")); return false; } - const gl::Framebuffer *fbo = context->getState().getDrawFramebuffer(); - if (!fbo || fbo->checkStatus(context->getData()) != GL_FRAMEBUFFER_COMPLETE) + if (end < start) { - context->recordError(Error(GL_INVALID_FRAMEBUFFER_OPERATION)); + context->recordError(Error(GL_INVALID_VALUE, "end < start")); return false; } + if (!ValidateDrawElements(context, mode, count, type, indices, 0, indexRange)) + { + return false; + } + + if (indexRange->end > end || indexRange->start < start) + { + // GL spec says that behavior in this case is undefined - generating an error is fine. + context->recordError( + Error(GL_INVALID_OPERATION, "Indices are out of the start, end range.")); + return false; + } return true; } @@ -1249,7 +1456,7 @@ bool ValidateReadBuffer(Context *context, GLenum src) return true; } - if (src != GL_BACK && (src < GL_COLOR_ATTACHMENT0 || src > GL_COLOR_ATTACHMENT15)) + if (src != GL_BACK && (src < GL_COLOR_ATTACHMENT0 || src > GL_COLOR_ATTACHMENT31)) { context->recordError(gl::Error(GL_INVALID_ENUM, "Unknown enum for 'src' in ReadBuffer")); return false; @@ -1279,4 +1486,578 @@ bool ValidateReadBuffer(Context *context, GLenum src) return true; } +bool ValidateCompressedTexImage3D(Context *context, + GLenum target, + GLint level, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLsizei depth, + GLint border, + GLsizei imageSize, + const GLvoid *data) +{ + if (context->getClientVersion() < 3) + { + context->recordError(Error(GL_INVALID_OPERATION)); + return false; + } + + const InternalFormat &formatInfo = GetInternalFormatInfo(internalformat); + if (imageSize < 0 || + static_cast(imageSize) != + formatInfo.computeBlockSize(GL_UNSIGNED_BYTE, width, height)) + { + context->recordError(Error(GL_INVALID_VALUE)); + return false; + } + + // 3D texture target validation + if (target != GL_TEXTURE_3D && target != GL_TEXTURE_2D_ARRAY) + { + context->recordError( + Error(GL_INVALID_ENUM, "Must specify a valid 3D texture destination target")); + return false; + } + + // validateES3TexImageFormat sets the error code if there is an error + if (!ValidateES3TexImage3DParameters(context, target, level, internalformat, true, false, 0, 0, + 0, width, height, depth, border, GL_NONE, GL_NONE, data)) + { + return false; + } + + return true; +} + +bool ValidateBindVertexArray(Context *context, GLuint array) +{ + if (context->getClientVersion() < 3) + { + context->recordError(Error(GL_INVALID_OPERATION)); + return false; + } + + return ValidateBindVertexArrayBase(context, array); +} + +bool ValidateIsVertexArray(Context *context) +{ + if (context->getClientVersion() < 3) + { + context->recordError(Error(GL_INVALID_OPERATION)); + return false; + } + + return true; +} + +bool ValidateProgramBinary(Context *context, + GLuint program, + GLenum binaryFormat, + const void *binary, + GLint length) +{ + if (context->getClientVersion() < 3) + { + context->recordError(Error(GL_INVALID_OPERATION)); + return false; + } + + return ValidateProgramBinaryBase(context, program, binaryFormat, binary, length); +} + +bool ValidateGetProgramBinary(Context *context, + GLuint program, + GLsizei bufSize, + GLsizei *length, + GLenum *binaryFormat, + void *binary) +{ + if (context->getClientVersion() < 3) + { + context->recordError(Error(GL_INVALID_OPERATION)); + return false; + } + + return ValidateGetProgramBinaryBase(context, program, bufSize, length, binaryFormat, binary); +} + +bool ValidateProgramParameteri(Context *context, GLuint program, GLenum pname, GLint value) +{ + if (context->getClientVersion() < 3) + { + context->recordError(Error(GL_INVALID_OPERATION, "Context does not support GLES3.")); + return false; + } + + if (GetValidProgram(context, program) == nullptr) + { + return false; + } + + switch (pname) + { + case GL_PROGRAM_BINARY_RETRIEVABLE_HINT: + if (value != GL_FALSE && value != GL_TRUE) + { + context->recordError(Error( + GL_INVALID_VALUE, "Invalid value, expected GL_FALSE or GL_TRUE: %i", value)); + return false; + } + break; + + default: + context->recordError(Error(GL_INVALID_ENUM, "Invalid pname: 0x%X", pname)); + return false; + } + + return true; +} + +bool ValidateBlitFramebuffer(Context *context, + GLint srcX0, + GLint srcY0, + GLint srcX1, + GLint srcY1, + GLint dstX0, + GLint dstY0, + GLint dstX1, + GLint dstY1, + GLbitfield mask, + GLenum filter) +{ + if (context->getClientVersion() < 3) + { + context->recordError(Error(GL_INVALID_OPERATION)); + return false; + } + + return ValidateBlitFramebufferParameters(context, srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, + dstX1, dstY1, mask, filter); +} + +bool ValidateClearBufferiv(ValidationContext *context, + GLenum buffer, + GLint drawbuffer, + const GLint *value) +{ + switch (buffer) + { + case GL_COLOR: + if (drawbuffer < 0 || + static_cast(drawbuffer) >= context->getCaps().maxDrawBuffers) + { + context->recordError(Error(GL_INVALID_VALUE)); + return false; + } + break; + + case GL_STENCIL: + if (drawbuffer != 0) + { + context->recordError(Error(GL_INVALID_VALUE)); + return false; + } + break; + + default: + context->recordError(Error(GL_INVALID_ENUM)); + return false; + } + + return ValidateClearBuffer(context); +} + +bool ValidateClearBufferuiv(ValidationContext *context, + GLenum buffer, + GLint drawbuffer, + const GLuint *value) +{ + switch (buffer) + { + case GL_COLOR: + if (drawbuffer < 0 || + static_cast(drawbuffer) >= context->getCaps().maxDrawBuffers) + { + context->recordError(Error(GL_INVALID_VALUE)); + return false; + } + break; + + default: + context->recordError(Error(GL_INVALID_ENUM)); + return false; + } + + return ValidateClearBuffer(context); +} + +bool ValidateClearBufferfv(ValidationContext *context, + GLenum buffer, + GLint drawbuffer, + const GLfloat *value) +{ + switch (buffer) + { + case GL_COLOR: + if (drawbuffer < 0 || + static_cast(drawbuffer) >= context->getCaps().maxDrawBuffers) + { + context->recordError(Error(GL_INVALID_VALUE)); + return false; + } + break; + + case GL_DEPTH: + if (drawbuffer != 0) + { + context->recordError(Error(GL_INVALID_VALUE)); + return false; + } + break; + + default: + context->recordError(Error(GL_INVALID_ENUM)); + return false; + } + + return ValidateClearBuffer(context); +} + +bool ValidateClearBufferfi(ValidationContext *context, + GLenum buffer, + GLint drawbuffer, + GLfloat depth, + GLint stencil) +{ + switch (buffer) + { + case GL_DEPTH_STENCIL: + if (drawbuffer != 0) + { + context->recordError(Error(GL_INVALID_VALUE)); + return false; + } + break; + + default: + context->recordError(Error(GL_INVALID_ENUM)); + return false; + } + + return ValidateClearBuffer(context); +} + +bool ValidateDrawBuffers(ValidationContext *context, GLsizei n, const GLenum *bufs) +{ + if (context->getClientVersion() < 3) + { + context->recordError(Error(GL_INVALID_OPERATION, "Context does not support GLES3.")); + return false; + } + + return ValidateDrawBuffersBase(context, n, bufs); +} + +bool ValidateCopyTexSubImage3D(Context *context, + GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLint x, + GLint y, + GLsizei width, + GLsizei height) +{ + if (context->getClientVersion() < 3) + { + context->recordError(Error(GL_INVALID_OPERATION)); + return false; + } + + return ValidateES3CopyTexImage3DParameters(context, target, level, GL_NONE, true, xoffset, + yoffset, zoffset, x, y, width, height, 0); +} + +bool ValidateTexImage3D(Context *context, + GLenum target, + GLint level, + GLint internalformat, + GLsizei width, + GLsizei height, + GLsizei depth, + GLint border, + GLenum format, + GLenum type, + const GLvoid *pixels) +{ + if (context->getClientVersion() < 3) + { + context->recordError(Error(GL_INVALID_OPERATION)); + return false; + } + + return ValidateES3TexImage3DParameters(context, target, level, internalformat, false, false, 0, + 0, 0, width, height, depth, border, format, type, + pixels); +} + +bool ValidateTexSubImage3D(Context *context, + GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLsizei width, + GLsizei height, + GLsizei depth, + GLenum format, + GLenum type, + const GLvoid *pixels) +{ + if (context->getClientVersion() < 3) + { + context->recordError(Error(GL_INVALID_OPERATION)); + return false; + } + + return ValidateES3TexImage3DParameters(context, target, level, GL_NONE, false, true, xoffset, + yoffset, zoffset, width, height, depth, 0, format, type, + pixels); +} + +bool ValidateCompressedTexSubImage3D(Context *context, + GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLsizei width, + GLsizei height, + GLsizei depth, + GLenum format, + GLsizei imageSize, + const GLvoid *data) +{ + if (context->getClientVersion() < 3) + { + context->recordError(Error(GL_INVALID_OPERATION)); + return false; + } + + const InternalFormat &formatInfo = GetInternalFormatInfo(format); + if (imageSize < 0 || + static_cast(imageSize) != + formatInfo.computeBlockSize(GL_UNSIGNED_BYTE, width, height)) + { + context->recordError(Error(GL_INVALID_VALUE)); + return false; + } + + if (!data) + { + context->recordError(Error(GL_INVALID_VALUE)); + return false; + } + + return ValidateES3TexImage3DParameters(context, target, level, GL_NONE, true, true, 0, 0, 0, + width, height, depth, 0, GL_NONE, GL_NONE, data); +} + +bool ValidateGenQueries(Context *context, GLint n, GLuint *) +{ + return ValidateGenOrDeleteES3(context, n); +} + +bool ValidateDeleteQueries(Context *context, GLint n, const GLuint *) +{ + return ValidateGenOrDeleteES3(context, n); +} + +bool ValidateGenSamplers(Context *context, GLint count, GLuint *) +{ + return ValidateGenOrDeleteCountES3(context, count); +} + +bool ValidateDeleteSamplers(Context *context, GLint count, const GLuint *) +{ + return ValidateGenOrDeleteCountES3(context, count); +} + +bool ValidateGenTransformFeedbacks(Context *context, GLint n, GLuint *) +{ + return ValidateGenOrDeleteES3(context, n); +} + +bool ValidateDeleteTransformFeedbacks(Context *context, GLint n, const GLuint *ids) +{ + if (!ValidateGenOrDeleteES3(context, 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->recordError( + Error(GL_INVALID_OPERATION, "Attempt to delete active transform feedback.")); + return false; + } + } + return true; +} + +bool ValidateGenVertexArrays(Context *context, GLint n, GLuint *) +{ + return ValidateGenOrDeleteES3(context, n); +} + +bool ValidateDeleteVertexArrays(Context *context, GLint n, const GLuint *) +{ + return ValidateGenOrDeleteES3(context, n); +} + +bool ValidateGenOrDeleteES3(Context *context, GLint n) +{ + if (context->getClientVersion() < 3) + { + context->recordError(Error(GL_INVALID_OPERATION, "Context does not support GLES3.")); + return false; + } + return ValidateGenOrDelete(context, n); +} + +bool ValidateGenOrDeleteCountES3(Context *context, GLint count) +{ + if (context->getClientVersion() < 3) + { + context->recordError(Error(GL_INVALID_OPERATION, "Context does not support GLES3.")); + return false; + } + if (count < 0) + { + context->recordError(Error(GL_INVALID_VALUE, "count < 0")); + return false; + } + return true; +} + +bool ValidateBeginTransformFeedback(Context *context, GLenum primitiveMode) +{ + if (context->getClientVersion() < 3) + { + context->recordError(Error(GL_INVALID_OPERATION, "Context does not support GLES3.")); + return false; + } + switch (primitiveMode) + { + case GL_TRIANGLES: + case GL_LINES: + case GL_POINTS: + break; + + default: + context->recordError(Error(GL_INVALID_ENUM, "Invalid primitive mode.")); + return false; + } + + TransformFeedback *transformFeedback = context->getState().getCurrentTransformFeedback(); + ASSERT(transformFeedback != nullptr); + + if (transformFeedback->isActive()) + { + context->recordError(Error(GL_INVALID_OPERATION, "Transform feedback is already active.")); + return false; + } + return true; +} + +bool ValidateSamplerParameteri(Context *context, GLuint sampler, GLenum pname, GLint param) +{ + if (context->getClientVersion() < 3) + { + context->recordError(Error(GL_INVALID_OPERATION, "Context does not support GLES3.")); + return false; + } + + if (!context->isSampler(sampler)) + { + context->recordError(Error(GL_INVALID_OPERATION)); + return false; + } + + if (!ValidateSamplerObjectParameter(context, pname)) + { + return false; + } + + if (!ValidateTexParamParameters(context, pname, param)) + { + return false; + } + return true; +} + +bool ValidateSamplerParameterf(Context *context, GLuint sampler, GLenum pname, GLfloat param) +{ + // The only float parameters are MIN_LOD and MAX_LOD. For these any value is permissible, so + // ValidateSamplerParameteri can be used for validation here. + return ValidateSamplerParameteri(context, sampler, pname, static_cast(param)); +} + +bool ValidateGetBufferPointerv(Context *context, GLenum target, GLenum pname, GLvoid **params) +{ + if (context->getClientVersion() < 3) + { + context->recordError(Error(GL_INVALID_OPERATION, "Context does not support GLES3.")); + return false; + } + + return ValidateGetBufferPointervBase(context, target, pname, params); +} + +bool ValidateUnmapBuffer(Context *context, GLenum target) +{ + if (context->getClientVersion() < 3) + { + context->recordError(Error(GL_INVALID_OPERATION)); + return false; + } + + return ValidateUnmapBufferBase(context, target); } + +bool ValidateMapBufferRange(Context *context, + GLenum target, + GLintptr offset, + GLsizeiptr length, + GLbitfield access) +{ + if (context->getClientVersion() < 3) + { + context->recordError(Error(GL_INVALID_OPERATION, "Context does not support GLES3.")); + return false; + } + + return ValidateMapBufferRangeBase(context, target, offset, length, access); +} + +bool ValidateFlushMappedBufferRange(Context *context, + GLenum target, + GLintptr offset, + GLsizeiptr length) +{ + if (context->getClientVersion() < 3) + { + context->recordError(Error(GL_INVALID_OPERATION, "Context does not support GLES3.")); + return false; + } + + return ValidateFlushMappedBufferRangeBase(context, target, offset, length); +} + +} // namespace gl diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/validationES3.h b/Source/ThirdParty/ANGLE/src/libANGLE/validationES3.h index 517cb5d27fbc..61303795d636 100644 --- a/Source/ThirdParty/ANGLE/src/libANGLE/validationES3.h +++ b/Source/ThirdParty/ANGLE/src/libANGLE/validationES3.h @@ -13,19 +13,142 @@ namespace gl { - class Context; +struct IndexRange; +class ValidationContext; + +bool ValidateES3TexImageParametersBase(ValidationContext *context, + GLenum 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, + const GLvoid *pixels); + +bool ValidateES3TexStorageParameters(Context *context, + GLenum target, + GLsizei levels, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLsizei depth); + +bool ValidateES3TexImage2DParameters(Context *context, + GLenum 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, + const GLvoid *pixels); + +bool ValidateES3TexImage3DParameters(Context *context, + GLenum 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, + const GLvoid *pixels); + +bool ValidateES3CopyTexImageParametersBase(ValidationContext *context, + GLenum target, + GLint level, + GLenum internalformat, + bool isSubImage, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLint x, + GLint y, + GLsizei width, + GLsizei height, + GLint border); + +bool ValidateES3CopyTexImage2DParameters(ValidationContext *context, + GLenum target, + GLint level, + GLenum internalformat, + bool isSubImage, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLint x, + GLint y, + GLsizei width, + GLsizei height, + GLint border); + +bool ValidateES3CopyTexImage3DParameters(ValidationContext *context, + GLenum 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(Context *context, + GLenum target, + GLsizei levels, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLsizei depth); + +bool ValidateES3TexStorage2DParameters(Context *context, + GLenum target, + GLsizei levels, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLsizei depth); + +bool ValidateES3TexStorage3DParameters(Context *context, + GLenum target, + GLsizei levels, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLsizei depth); -bool ValidateES3TexImageParameters(Context *context, GLenum 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, const GLvoid *pixels); +bool ValidateBeginQuery(Context *context, GLenum target, GLuint id); -bool ValidateES3CopyTexImageParameters(Context *context, GLenum target, GLint level, GLenum internalformat, - bool isSubImage, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, - GLsizei width, GLsizei height, GLint border); +bool ValidateEndQuery(Context *context, GLenum target); -bool ValidateES3TexStorageParameters(Context *context, GLenum target, GLsizei levels, GLenum internalformat, - GLsizei width, GLsizei height, GLsizei depth); +bool ValidateGetQueryiv(Context *context, GLenum target, GLenum pname, GLint *params); + +bool ValidateGetQueryObjectuiv(Context *context, GLuint id, GLenum pname, GLuint *params); bool ValidateFramebufferTextureLayer(Context *context, GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); @@ -35,15 +158,154 @@ bool ValidES3ReadFormatType(Context *context, GLenum internalFormat, GLenum form bool ValidateES3RenderbufferStorageParameters(Context *context, GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); -bool ValidateInvalidateFramebufferParameters(Context *context, GLenum target, GLsizei numAttachments, - const GLenum* attachments); +bool ValidateInvalidateFramebuffer(Context *context, GLenum target, GLsizei numAttachments, + const GLenum *attachments); + +bool ValidateClearBuffer(ValidationContext *context); -bool ValidateClearBuffer(Context *context); +bool ValidateDrawRangeElements(Context *context, + GLenum mode, + GLuint start, + GLuint end, + GLsizei count, + GLenum type, + const GLvoid *indices, + IndexRange *indexRange); bool ValidateGetUniformuiv(Context *context, GLuint program, GLint location, GLuint* params); bool ValidateReadBuffer(Context *context, GLenum mode); -} +bool ValidateCompressedTexImage3D(Context *context, + GLenum target, + GLint level, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLsizei depth, + GLint border, + GLsizei imageSize, + const GLvoid *data); + +bool ValidateBindVertexArray(Context *context, GLuint array); +bool ValidateIsVertexArray(Context *context); + +bool ValidateProgramBinary(Context *context, + GLuint program, + GLenum binaryFormat, + const void *binary, + GLint length); +bool ValidateGetProgramBinary(Context *context, + GLuint program, + GLsizei bufSize, + GLsizei *length, + GLenum *binaryFormat, + void *binary); +bool ValidateProgramParameteri(Context *context, GLuint program, GLenum pname, GLint value); +bool ValidateBlitFramebuffer(Context *context, + GLint srcX0, + GLint srcY0, + GLint srcX1, + GLint srcY1, + GLint dstX0, + GLint dstY0, + GLint dstX1, + GLint dstY1, + GLbitfield mask, + GLenum filter); +bool ValidateClearBufferiv(ValidationContext *context, + GLenum buffer, + GLint drawbuffer, + const GLint *value); +bool ValidateClearBufferuiv(ValidationContext *context, + GLenum buffer, + GLint drawbuffer, + const GLuint *value); +bool ValidateClearBufferfv(ValidationContext *context, + GLenum buffer, + GLint drawbuffer, + const GLfloat *value); +bool ValidateClearBufferfi(ValidationContext *context, + GLenum buffer, + GLint drawbuffer, + GLfloat depth, + GLint stencil); +bool ValidateDrawBuffers(ValidationContext *context, GLsizei n, const GLenum *bufs); +bool ValidateCopyTexSubImage3D(Context *context, + GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLint x, + GLint y, + GLsizei width, + GLsizei height); +bool ValidateTexImage3D(Context *context, + GLenum target, + GLint level, + GLint internalformat, + GLsizei width, + GLsizei height, + GLsizei depth, + GLint border, + GLenum format, + GLenum type, + const GLvoid *pixels); +bool ValidateTexSubImage3D(Context *context, + GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLsizei width, + GLsizei height, + GLsizei depth, + GLenum format, + GLenum type, + const GLvoid *pixels); +bool ValidateCompressedTexSubImage3D(Context *context, + GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLsizei width, + GLsizei height, + GLsizei depth, + GLenum format, + GLsizei imageSize, + const GLvoid *data); + +bool ValidateGenQueries(Context *context, GLint n, GLuint *ids); +bool ValidateDeleteQueries(Context *context, GLint n, const GLuint *ids); +bool ValidateGenSamplers(Context *context, GLint count, GLuint *samplers); +bool ValidateDeleteSamplers(Context *context, GLint count, const GLuint *samplers); +bool ValidateGenTransformFeedbacks(Context *context, GLint n, GLuint *ids); +bool ValidateDeleteTransformFeedbacks(Context *context, GLint n, const GLuint *ids); +bool ValidateGenVertexArrays(Context *context, GLint n, GLuint *arrays); +bool ValidateDeleteVertexArrays(Context *context, GLint n, const GLuint *arrays); + +bool ValidateGenOrDeleteES3(Context *context, GLint n); +bool ValidateGenOrDeleteCountES3(Context *context, GLint count); + +bool ValidateBeginTransformFeedback(Context *context, GLenum primitiveMode); + +bool ValidateSamplerParameteri(Context *context, GLuint sampler, GLenum pname, GLint param); +bool ValidateSamplerParameterf(Context *context, GLuint sampler, GLenum pname, GLfloat param); + +bool ValidateGetBufferPointerv(Context *context, GLenum target, GLenum pname, GLvoid **params); +bool ValidateUnmapBuffer(Context *context, GLenum target); +bool ValidateMapBufferRange(Context *context, + GLenum target, + GLintptr offset, + GLsizeiptr length, + GLbitfield access); +bool ValidateFlushMappedBufferRange(Context *context, + GLenum target, + GLintptr offset, + GLsizeiptr length); + +} // namespace gl #endif // LIBANGLE_VALIDATION_ES3_H_ diff --git a/Source/ThirdParty/ANGLE/src/libANGLE/validationES_unittest.cpp b/Source/ThirdParty/ANGLE/src/libANGLE/validationES_unittest.cpp new file mode 100644 index 000000000000..ef049f99c263 --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/libANGLE/validationES_unittest.cpp @@ -0,0 +1,142 @@ +// +// 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. +// +// validationES unit tests: +// Unit tests for general ES validation functions. +// + +#include +#include + +#include "libANGLE/Data.h" +#include "libANGLE/renderer/FramebufferImpl_mock.h" +#include "libANGLE/renderer/ProgramImpl_mock.h" +#include "libANGLE/renderer/TextureImpl_mock.h" +#include "libANGLE/validationES.h" +#include "tests/angle_unittests_utils.h" + +using namespace gl; +using namespace rx; +using testing::_; +using testing::NiceMock; +using testing::Return; + +namespace +{ + +class MockFactory : public NullFactory +{ + public: + MOCK_METHOD1(createFramebuffer, FramebufferImpl *(const gl::Framebuffer::Data &)); + MOCK_METHOD1(createProgram, ProgramImpl *(const gl::Program::Data &)); + MOCK_METHOD1(createVertexArray, VertexArrayImpl *(const gl::VertexArray::Data &)); +}; + +class MockValidationContext : public ValidationContext +{ + public: + MockValidationContext(GLint clientVersion, + const State &state, + const Caps &caps, + const TextureCapsMap &textureCaps, + const Extensions &extensions, + const ResourceManager *resourceManager, + const Limitations &limitations, + bool skipValidation); + + MOCK_METHOD1(recordError, void(const Error &)); +}; + +MockValidationContext::MockValidationContext(GLint clientVersion, + const State &state, + const Caps &caps, + const TextureCapsMap &textureCaps, + const Extensions &extensions, + const ResourceManager *resourceManager, + const Limitations &limitations, + bool skipValidation) + : ValidationContext(clientVersion, + state, + caps, + textureCaps, + extensions, + resourceManager, + limitations, + skipValidation) +{ +} + +// Test that ANGLE generates an INVALID_OPERATION when validating index data that uses a value +// larger than MAX_ELEMENT_INDEX. Not specified in the GLES 3 spec, it's undefined behaviour, +// but we want a test to ensure we maintain this behaviour. +TEST(ValidationESTest, DrawElementsWithMaxIndexGivesError) +{ + auto framebufferImpl = MakeFramebufferMock(); + auto programImpl = MakeProgramMock(); + + // TODO(jmadill): Generalize some of this code so we can re-use it for other tests. + NiceMock mockFactory; + EXPECT_CALL(mockFactory, createFramebuffer(_)).WillOnce(Return(framebufferImpl)); + EXPECT_CALL(mockFactory, createProgram(_)).WillOnce(Return(programImpl)); + EXPECT_CALL(mockFactory, createVertexArray(_)).WillOnce(Return(nullptr)); + + State state; + Caps caps; + TextureCapsMap textureCaps; + Extensions extensions; + Limitations limitations; + + // Set some basic caps. + caps.maxElementIndex = 100; + caps.maxDrawBuffers = 1; + caps.maxColorAttachments = 1; + state.initialize(caps, extensions, 3, false); + + NiceMock *textureImpl = new NiceMock(); + EXPECT_CALL(*textureImpl, setStorage(_, _, _, _)).WillOnce(Return(Error(GL_NO_ERROR))); + EXPECT_CALL(*textureImpl, destructor()).Times(1).RetiresOnSaturation(); + + Texture *texture = new Texture(textureImpl, 0, GL_TEXTURE_2D); + texture->addRef(); + texture->setStorage(GL_TEXTURE_2D, 1, GL_RGBA8, Extents(1, 1, 0)); + + VertexArray *vertexArray = new VertexArray(&mockFactory, 0, 1); + Framebuffer *framebuffer = new Framebuffer(caps, &mockFactory, 1); + framebuffer->setAttachment(GL_FRAMEBUFFER_DEFAULT, GL_BACK, ImageIndex::Make2D(0), texture); + + Program *program = new Program(&mockFactory, nullptr, 1); + + state.setVertexArrayBinding(vertexArray); + state.setDrawFramebufferBinding(framebuffer); + state.setProgram(program); + + NiceMock testContext(3, state, caps, textureCaps, extensions, nullptr, + limitations, false); + + // Set the expectation for the validation error here. + Error expectedError(GL_INVALID_OPERATION, g_ExceedsMaxElementErrorMessage); + EXPECT_CALL(testContext, recordError(expectedError)).Times(1); + + // Call once with maximum index, and once with an excessive index. + GLuint indexData[] = {0, 1, static_cast(caps.maxElementIndex - 1), + 3, 4, static_cast(caps.maxElementIndex)}; + IndexRange indexRange; + EXPECT_TRUE(ValidateDrawElements(&testContext, GL_TRIANGLES, 3, GL_UNSIGNED_INT, indexData, 1, + &indexRange)); + EXPECT_FALSE(ValidateDrawElements(&testContext, GL_TRIANGLES, 6, GL_UNSIGNED_INT, indexData, 2, + &indexRange)); + + texture->release(); + + state.setVertexArrayBinding(nullptr); + state.setDrawFramebufferBinding(nullptr); + state.setProgram(nullptr); + + SafeDelete(vertexArray); + SafeDelete(framebuffer); + SafeDelete(program); +} + +} // anonymous namespace diff --git a/Source/ThirdParty/ANGLE/src/libEGL.gypi b/Source/ThirdParty/ANGLE/src/libEGL.gypi index 1190596205eb..1d8870452a82 100644 --- a/Source/ThirdParty/ANGLE/src/libEGL.gypi +++ b/Source/ThirdParty/ANGLE/src/libEGL.gypi @@ -5,13 +5,24 @@ { # Everything below this is duplicated in the GN build. If you change # anything also change angle/BUILD.gn + 'variables': + { + 'angle_standalone%': 0, + }, 'targets': [ { 'target_name': 'libEGL', - 'type': 'shared_library', - 'dependencies': [ 'libGLESv2', ], - 'includes': [ '../build/common_defines.gypi', ], + 'type': '<(angle_gl_library_type)', + 'dependencies': + [ + 'libANGLE', + 'libGLESv2', + ], + 'includes': + [ + '../build/common_defines.gypi', + ], 'include_dirs': [ '.', @@ -21,31 +32,11 @@ [ '<@(libegl_sources)', ], - 'defines': - [ - 'GL_APICALL=', - 'GL_GLEXT_PROTOTYPES=', - 'EGLAPI=', - 'LIBEGL_IMPLEMENTATION', - ], 'conditions': [ ['angle_build_winrt==1', { - 'msvs_enable_winrt' : '1', 'msvs_requires_importlibrary' : 'true', - 'msvs_settings': - { - 'VCLinkerTool': - { - 'EnableCOMDATFolding': '1', - 'OptimizeReferences': '1', - } - }, - }], - ['angle_build_winphone==1', - { - 'msvs_enable_winphone' : '1', }], ], }, diff --git a/Source/ThirdParty/ANGLE/src/libEGL/libEGL.cpp b/Source/ThirdParty/ANGLE/src/libEGL/libEGL.cpp index 1f9e257becfa..511565379ec1 100644 --- a/Source/ThirdParty/ANGLE/src/libEGL/libEGL.cpp +++ b/Source/ThirdParty/ANGLE/src/libEGL/libEGL.cpp @@ -257,9 +257,105 @@ const char * EGLAPIENTRY eglQueryDeviceStringEXT(EGLDeviceEXT device, EGLint nam return egl::QueryDeviceStringEXT(device, name); } +EGLImageKHR EGLAPIENTRY eglCreateImageKHR(EGLDisplay dpy, + EGLContext ctx, + EGLenum target, + EGLClientBuffer buffer, + const EGLint *attrib_list) +{ + return egl::CreateImageKHR(dpy, ctx, target, buffer, attrib_list); +} + +EGLBoolean EGLAPIENTRY eglDestroyImageKHR(EGLDisplay dpy, EGLImageKHR image) +{ + return egl::DestroyImageKHR(dpy, image); +} + +EGLDeviceEXT EGLAPIENTRY eglCreateDeviceANGLE(EGLint device_type, + void *native_device, + const EGLAttrib *attrib_list) +{ + return egl::CreateDeviceANGLE(device_type, native_device, attrib_list); +} + +EGLBoolean EGLAPIENTRY eglReleaseDeviceANGLE(EGLDeviceEXT device) +{ + return egl::ReleaseDeviceANGLE(device); +} + __eglMustCastToProperFunctionPointerType EGLAPIENTRY eglGetProcAddress(const char *procname) { return egl::GetProcAddress(procname); } +EGLStreamKHR EGLAPIENTRY eglCreateStreamKHR(EGLDisplay dpy, const EGLint *attrib_list) +{ + return egl::CreateStreamKHR(dpy, attrib_list); +} + +EGLBoolean EGLAPIENTRY eglDestroyStreamKHR(EGLDisplay dpy, EGLStreamKHR stream) +{ + return egl::DestroyStreamKHR(dpy, stream); +} + +EGLBoolean EGLAPIENTRY eglStreamAttribKHR(EGLDisplay dpy, + EGLStreamKHR stream, + EGLenum attribute, + EGLint value) +{ + return egl::StreamAttribKHR(dpy, stream, attribute, value); +} + +EGLBoolean EGLAPIENTRY eglQueryStreamKHR(EGLDisplay dpy, + EGLStreamKHR stream, + EGLenum attribute, + EGLint *value) +{ + return egl::QueryStreamKHR(dpy, stream, attribute, value); +} + +EGLBoolean EGLAPIENTRY eglQueryStreamu64KHR(EGLDisplay dpy, + EGLStreamKHR stream, + EGLenum attribute, + EGLuint64KHR *value) +{ + return egl::QueryStreamu64KHR(dpy, stream, attribute, value); +} + +EGLBoolean EGLAPIENTRY eglStreamConsumerGLTextureExternalKHR(EGLDisplay dpy, EGLStreamKHR stream) +{ + return egl::StreamConsumerGLTextureExternalKHR(dpy, stream); +} + +EGLBoolean EGLAPIENTRY eglStreamConsumerAcquireKHR(EGLDisplay dpy, EGLStreamKHR stream) +{ + return egl::StreamConsumerAcquireKHR(dpy, stream); +} + +EGLBoolean EGLAPIENTRY eglStreamConsumerReleaseKHR(EGLDisplay dpy, EGLStreamKHR stream) +{ + return egl::StreamConsumerReleaseKHR(dpy, stream); +} + +EGLBoolean EGLAPIENTRY eglStreamConsumerGLTextureExternalAttribsNV(EGLDisplay dpy, + EGLStreamKHR stream, + EGLAttrib *attrib_list) +{ + return egl::StreamConsumerGLTextureExternalAttribsNV(dpy, stream, attrib_list); +} + +EGLBoolean EGLAPIENTRY eglCreateStreamProducerD3DTextureNV12ANGLE(EGLDisplay dpy, + EGLStreamKHR stream, + const EGLAttrib *attrib_list) +{ + return egl::CreateStreamProducerD3DTextureNV12ANGLE(dpy, stream, attrib_list); +} + +EGLBoolean EGLAPIENTRY eglStreamPostD3DTextureNV12ANGLE(EGLDisplay dpy, + EGLStreamKHR stream, + void *texture, + const EGLAttrib *attrib_list) +{ + return egl::StreamPostD3DTextureNV12ANGLE(dpy, stream, texture, attrib_list); +} } diff --git a/Source/ThirdParty/ANGLE/src/libEGL/libEGL.def b/Source/ThirdParty/ANGLE/src/libEGL/libEGL.def index 48f6b58d630e..d4596c23d067 100644 --- a/Source/ThirdParty/ANGLE/src/libEGL/libEGL.def +++ b/Source/ThirdParty/ANGLE/src/libEGL/libEGL.def @@ -1,56 +1,71 @@ LIBRARY libEGL EXPORTS - eglBindAPI @14 - eglBindTexImage @20 - eglChooseConfig @7 - eglCopyBuffers @33 - eglCreateContext @23 - eglCreatePbufferFromClientBuffer @18 - eglCreatePbufferSurface @10 - eglCreatePixmapSurface @11 - eglCreateWindowSurface @9 - eglDestroyContext @24 - eglDestroySurface @12 - eglGetConfigAttrib @8 - eglGetConfigs @6 - eglGetCurrentContext @26 - eglGetCurrentDisplay @28 - eglGetCurrentSurface @27 - eglGetDisplay @2 - eglGetError @1 - eglGetProcAddress @34 - eglInitialize @3 - eglMakeCurrent @25 - eglQueryAPI @15 - eglQueryContext @29 - eglQueryString @5 - eglQuerySurface @13 - eglReleaseTexImage @21 - eglReleaseThread @17 - eglSurfaceAttrib @19 - eglSwapBuffers @32 - eglSwapInterval @22 - eglTerminate @4 - eglWaitClient @16 - eglWaitGL @30 - eglWaitNative @31 + eglBindAPI @14 + eglBindTexImage @20 + eglChooseConfig @7 + eglCopyBuffers @33 + eglCreateContext @23 + eglCreatePbufferFromClientBuffer @18 + eglCreatePbufferSurface @10 + eglCreatePixmapSurface @11 + eglCreateWindowSurface @9 + eglDestroyContext @24 + eglDestroySurface @12 + eglGetConfigAttrib @8 + eglGetConfigs @6 + eglGetCurrentContext @26 + eglGetCurrentDisplay @28 + eglGetCurrentSurface @27 + eglGetDisplay @2 + eglGetError @1 + eglGetProcAddress @34 + eglInitialize @3 + eglMakeCurrent @25 + eglQueryAPI @15 + eglQueryContext @29 + eglQueryString @5 + eglQuerySurface @13 + eglReleaseTexImage @21 + eglReleaseThread @17 + eglSurfaceAttrib @19 + eglSwapBuffers @32 + eglSwapInterval @22 + eglTerminate @4 + eglWaitClient @16 + eglWaitGL @30 + eglWaitNative @31 ; Extensions - eglGetPlatformDisplayEXT @35 - eglQuerySurfacePointerANGLE @36 - eglPostSubBufferNV @37 - eglQueryDisplayAttribEXT @48 - eglQueryDeviceAttribEXT @49 - eglQueryDeviceStringEXT @50 + eglGetPlatformDisplayEXT @35 + eglQuerySurfacePointerANGLE @36 + eglPostSubBufferNV @37 + eglQueryDisplayAttribEXT @48 + eglQueryDeviceAttribEXT @49 + eglQueryDeviceStringEXT @50 + eglCreateImageKHR @51 + eglDestroyImageKHR @52 + eglCreateDeviceANGLE @53 + eglReleaseDeviceANGLE @54 + eglCreateStreamKHR @55 + eglDestroyStreamKHR @56 + eglStreamAttribKHR @57 + eglQueryStreamKHR @58 + eglQueryStreamu64KHR @59 + eglStreamConsumerGLTextureExternalKHR @60 + eglStreamConsumerAcquireKHR @61 + eglStreamConsumerReleaseKHR @62 + eglStreamConsumerGLTextureExternalAttribsNV @63 + eglCreateStreamProducerD3DTextureNV12ANGLE @64 + eglStreamPostD3DTextureNV12ANGLE @65 ; 1.5 entry points - eglCreateSync @38 - eglDestroySync @39 - eglClientWaitSync @40 - eglGetSyncAttrib @41 - eglCreateImage @42 - eglDestroyImage @43 - eglGetPlatformDisplay @44 - eglCreatePlatformWindowSurface @45 - eglCreatePlatformPixmapSurface @46 - eglWaitSync @47 + eglCreateSync @38 + eglDestroySync @39 + eglClientWaitSync @40 + eglGetSyncAttrib @41 + eglCreateImage @42 + eglDestroyImage @43 + eglGetPlatformDisplay @44 + eglCreatePlatformWindowSurface @45 + eglCreatePlatformPixmapSurface @46 + eglWaitSync @47 diff --git a/Source/ThirdParty/ANGLE/src/libEGL/libEGL.rc b/Source/ThirdParty/ANGLE/src/libEGL/libEGL.rc index bbb0d00ce2eb..acffcef61288 100644 --- a/Source/ThirdParty/ANGLE/src/libEGL/libEGL.rc +++ b/Source/ThirdParty/ANGLE/src/libEGL/libEGL.rc @@ -54,8 +54,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION ANGLE_MAJOR_VERSION,ANGLE_MINOR_VERSION,0,0 - PRODUCTVERSION ANGLE_MAJOR_VERSION,ANGLE_MINOR_VERSION,0,0 + FILEVERSION ANGLE_MAJOR_VERSION,ANGLE_MINOR_VERSION,ANGLE_REVISION,0 + PRODUCTVERSION ANGLE_MAJOR_VERSION,ANGLE_MINOR_VERSION,ANGLE_REVISION,0 FILEFLAGSMASK 0x17L #ifdef _DEBUG FILEFLAGS 0x1L diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2.gypi b/Source/ThirdParty/ANGLE/src/libGLESv2.gypi index 6d54f669c5af..591fa9a43498 100644 --- a/Source/ThirdParty/ANGLE/src/libGLESv2.gypi +++ b/Source/ThirdParty/ANGLE/src/libGLESv2.gypi @@ -5,9 +5,13 @@ { 'variables': { + 'angle_standalone%': 0, + # These file lists are shared with the GN build. 'libangle_common_sources': [ + 'common/BitSetIterator.h', + 'common/Float16ToFloat32.cpp', 'common/MemoryBuffer.cpp', 'common/MemoryBuffer.h', 'common/Optional.h', @@ -17,7 +21,10 @@ 'common/debug.h', 'common/mathutil.cpp', 'common/mathutil.h', + 'common/matrix_utils.h', 'common/platform.h', + 'common/string_utils.cpp', + 'common/string_utils.h', 'common/tls.cpp', 'common/tls.h', 'common/utilities.cpp', @@ -35,8 +42,9 @@ '../include/GLES2/gl2ext.h', '../include/GLES2/gl2platform.h', '../include/GLES3/gl3.h', - '../include/GLES3/gl3ext.h', '../include/GLES3/gl3platform.h', + '../include/GLES3/gl31.h', + '../include/GLES3/gl32.h', '../include/GLSLANG/ShaderLang.h', '../include/GLSLANG/ShaderVars.h', '../include/KHR/khrplatform.h', @@ -62,6 +70,8 @@ 'libANGLE/Context.h', 'libANGLE/Data.cpp', 'libANGLE/Data.h', + 'libANGLE/Debug.cpp', + 'libANGLE/Debug.h', 'libANGLE/Device.cpp', 'libANGLE/Device.h', 'libANGLE/Display.cpp', @@ -71,21 +81,23 @@ 'libANGLE/Error.inl', 'libANGLE/Fence.cpp', 'libANGLE/Fence.h', - 'libANGLE/Float16ToFloat32.cpp', 'libANGLE/Framebuffer.cpp', 'libANGLE/Framebuffer.h', 'libANGLE/FramebufferAttachment.cpp', 'libANGLE/FramebufferAttachment.h', 'libANGLE/HandleAllocator.cpp', 'libANGLE/HandleAllocator.h', + 'libANGLE/Image.h', + 'libANGLE/Image.cpp', 'libANGLE/ImageIndex.h', 'libANGLE/ImageIndex.cpp', + 'libANGLE/IndexRangeCache.cpp', + 'libANGLE/IndexRangeCache.h', 'libANGLE/Platform.cpp', 'libANGLE/Program.cpp', 'libANGLE/Program.h', 'libANGLE/Query.cpp', 'libANGLE/Query.h', - 'libANGLE/RefCountObject.cpp', 'libANGLE/RefCountObject.h', 'libANGLE/Renderbuffer.cpp', 'libANGLE/Renderbuffer.h', @@ -97,6 +109,8 @@ 'libANGLE/Shader.h', 'libANGLE/State.cpp', 'libANGLE/State.h', + 'libANGLE/Stream.cpp', + 'libANGLE/Stream.h', 'libANGLE/Surface.cpp', 'libANGLE/Surface.h', 'libANGLE/Texture.cpp', @@ -105,12 +119,16 @@ 'libANGLE/TransformFeedback.h', 'libANGLE/Uniform.cpp', 'libANGLE/Uniform.h', + 'libANGLE/Version.h', + 'libANGLE/Version.inl', 'libANGLE/VertexArray.cpp', 'libANGLE/VertexArray.h', 'libANGLE/VertexAttribute.cpp', 'libANGLE/VertexAttribute.h', + 'libANGLE/VertexAttribute.inl', 'libANGLE/angletypes.cpp', 'libANGLE/angletypes.h', + 'libANGLE/angletypes.inl', 'libANGLE/features.h', 'libANGLE/formatutils.cpp', 'libANGLE/formatutils.h', @@ -126,23 +144,21 @@ 'libANGLE/renderer/FenceNVImpl.h', 'libANGLE/renderer/FenceSyncImpl.h', 'libANGLE/renderer/FramebufferImpl.h', + 'libANGLE/renderer/ImageImpl.h', 'libANGLE/renderer/ImplFactory.h', - 'libANGLE/renderer/IndexRangeCache.cpp', - 'libANGLE/renderer/IndexRangeCache.h', - 'libANGLE/renderer/ProgramImpl.cpp', 'libANGLE/renderer/ProgramImpl.h', 'libANGLE/renderer/QueryImpl.h', 'libANGLE/renderer/RenderbufferImpl.h', - 'libANGLE/renderer/RenderbufferImpl.cpp', 'libANGLE/renderer/Renderer.cpp', 'libANGLE/renderer/Renderer.h', + 'libANGLE/renderer/SamplerImpl.h', 'libANGLE/renderer/ShaderImpl.h', + 'libANGLE/renderer/StreamImpl.h', 'libANGLE/renderer/SurfaceImpl.cpp', 'libANGLE/renderer/SurfaceImpl.h', 'libANGLE/renderer/TextureImpl.h', 'libANGLE/renderer/TransformFeedbackImpl.h', 'libANGLE/renderer/VertexArrayImpl.h', - 'libANGLE/renderer/Workarounds.h', 'libANGLE/validationEGL.cpp', 'libANGLE/validationEGL.h', 'libANGLE/validationES.cpp', @@ -169,6 +185,8 @@ 'libANGLE/renderer/d3d/DisplayD3D.h', 'libANGLE/renderer/d3d/DynamicHLSL.cpp', 'libANGLE/renderer/d3d/DynamicHLSL.h', + 'libANGLE/renderer/d3d/EGLImageD3D.cpp', + 'libANGLE/renderer/d3d/EGLImageD3D.h', 'libANGLE/renderer/d3d/formatutilsD3D.cpp', 'libANGLE/renderer/d3d/formatutilsD3D.h', 'libANGLE/renderer/d3d/FramebufferD3D.cpp', @@ -188,6 +206,8 @@ 'libANGLE/renderer/d3d/loadimage.h', 'libANGLE/renderer/d3d/loadimage.inl', 'libANGLE/renderer/d3d/loadimageSSE2.cpp', + 'libANGLE/renderer/d3d/loadimage_etc.cpp', + 'libANGLE/renderer/d3d/loadimage_etc.h', 'libANGLE/renderer/d3d/ProgramD3D.cpp', 'libANGLE/renderer/d3d/ProgramD3D.h', 'libANGLE/renderer/d3d/RenderbufferD3D.cpp', @@ -196,6 +216,7 @@ 'libANGLE/renderer/d3d/RendererD3D.h', 'libANGLE/renderer/d3d/RenderTargetD3D.h', 'libANGLE/renderer/d3d/RenderTargetD3D.cpp', + 'libANGLE/renderer/d3d/SamplerD3D.h', 'libANGLE/renderer/d3d/ShaderD3D.cpp', 'libANGLE/renderer/d3d/ShaderD3D.h', 'libANGLE/renderer/d3d/ShaderExecutableD3D.cpp', @@ -205,14 +226,16 @@ 'libANGLE/renderer/d3d/SwapChainD3D.h', 'libANGLE/renderer/d3d/TextureD3D.cpp', 'libANGLE/renderer/d3d/TextureD3D.h', - 'libANGLE/renderer/d3d/TextureStorage.cpp', 'libANGLE/renderer/d3d/TextureStorage.h', 'libANGLE/renderer/d3d/TransformFeedbackD3D.cpp', 'libANGLE/renderer/d3d/TransformFeedbackD3D.h', + 'libANGLE/renderer/d3d/VaryingPacking.cpp', + 'libANGLE/renderer/d3d/VaryingPacking.h', 'libANGLE/renderer/d3d/VertexBuffer.cpp', 'libANGLE/renderer/d3d/VertexBuffer.h', 'libANGLE/renderer/d3d/VertexDataManager.cpp', 'libANGLE/renderer/d3d/VertexDataManager.h', + 'libANGLE/renderer/d3d/WorkaroundsD3D.h', ], 'libangle_d3d9_sources': [ @@ -248,6 +271,8 @@ 'libANGLE/renderer/d3d/d3d9/shaders/compiled/luminanceps.h', 'libANGLE/renderer/d3d/d3d9/shaders/compiled/passthroughps.h', 'libANGLE/renderer/d3d/d3d9/shaders/compiled/standardvs.h', + 'libANGLE/renderer/d3d/d3d9/StateManager9.cpp', + 'libANGLE/renderer/d3d/d3d9/StateManager9.h', 'libANGLE/renderer/d3d/d3d9/SwapChain9.cpp', 'libANGLE/renderer/d3d/d3d9/SwapChain9.h', 'libANGLE/renderer/d3d/d3d9/TextureStorage9.cpp', @@ -271,6 +296,8 @@ 'libANGLE/renderer/d3d/d3d11/copyvertex.inl', 'libANGLE/renderer/d3d/d3d11/DebugAnnotator11.cpp', 'libANGLE/renderer/d3d/d3d11/DebugAnnotator11.h', + 'libANGLE/renderer/d3d/d3d11/dxgi_support_table.cpp', + 'libANGLE/renderer/d3d/d3d11/dxgi_support_table.h', 'libANGLE/renderer/d3d/d3d11/Fence11.cpp', 'libANGLE/renderer/d3d/d3d11/Fence11.h', 'libANGLE/renderer/d3d/d3d11/formatutils11.cpp', @@ -283,6 +310,8 @@ 'libANGLE/renderer/d3d/d3d11/IndexBuffer11.h', 'libANGLE/renderer/d3d/d3d11/InputLayoutCache.cpp', 'libANGLE/renderer/d3d/d3d11/InputLayoutCache.h', + 'libANGLE/renderer/d3d/d3d11/load_functions_table.h', + 'libANGLE/renderer/d3d/d3d11/load_functions_table_autogen.cpp', 'libANGLE/renderer/d3d/d3d11/NativeWindow.h', 'libANGLE/renderer/d3d/d3d11/PixelTransfer11.cpp', 'libANGLE/renderer/d3d/d3d11/PixelTransfer11.h', @@ -350,12 +379,20 @@ 'libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzleui2darrayps.h', 'libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzleui2dps.h', 'libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzleui3dps.h', + 'libANGLE/renderer/d3d/d3d11/StateManager11.cpp', + 'libANGLE/renderer/d3d/d3d11/StateManager11.h', + 'libANGLE/renderer/d3d/d3d11/Stream11.cpp', + 'libANGLE/renderer/d3d/d3d11/Stream11.h', 'libANGLE/renderer/d3d/d3d11/SwapChain11.cpp', 'libANGLE/renderer/d3d/d3d11/SwapChain11.h', 'libANGLE/renderer/d3d/d3d11/TextureStorage11.cpp', 'libANGLE/renderer/d3d/d3d11/TextureStorage11.h', 'libANGLE/renderer/d3d/d3d11/Trim11.cpp', 'libANGLE/renderer/d3d/d3d11/Trim11.h', + 'libANGLE/renderer/d3d/d3d11/texture_format_table_autogen.cpp', + 'libANGLE/renderer/d3d/d3d11/texture_format_table_autogen.h', + 'libANGLE/renderer/d3d/d3d11/texture_format_table.h', + 'libANGLE/renderer/d3d/d3d11/VertexArray11.cpp', 'libANGLE/renderer/d3d/d3d11/VertexArray11.h', 'libANGLE/renderer/d3d/d3d11/VertexBuffer11.cpp', 'libANGLE/renderer/d3d/d3d11/VertexBuffer11.h', @@ -377,6 +414,8 @@ ], 'libangle_gl_sources': [ + 'libANGLE/renderer/gl/BlitGL.cpp', + 'libANGLE/renderer/gl/BlitGL.h', 'libANGLE/renderer/gl/BufferGL.cpp', 'libANGLE/renderer/gl/BufferGL.h', 'libANGLE/renderer/gl/CompilerGL.cpp', @@ -399,6 +438,8 @@ 'libANGLE/renderer/gl/RenderbufferGL.h', 'libANGLE/renderer/gl/RendererGL.cpp', 'libANGLE/renderer/gl/RendererGL.h', + 'libANGLE/renderer/gl/SamplerGL.cpp', + 'libANGLE/renderer/gl/SamplerGL.h', 'libANGLE/renderer/gl/ShaderGL.cpp', 'libANGLE/renderer/gl/ShaderGL.h', 'libANGLE/renderer/gl/StateManagerGL.cpp', @@ -411,6 +452,7 @@ 'libANGLE/renderer/gl/TransformFeedbackGL.h', 'libANGLE/renderer/gl/VertexArrayGL.cpp', 'libANGLE/renderer/gl/VertexArrayGL.h', + 'libANGLE/renderer/gl/WorkaroundsGL.h', 'libANGLE/renderer/gl/formatutilsgl.cpp', 'libANGLE/renderer/gl/formatutilsgl.h', 'libANGLE/renderer/gl/functionsgl_enums.h', @@ -422,6 +464,8 @@ [ 'libANGLE/renderer/gl/wgl/DisplayWGL.cpp', 'libANGLE/renderer/gl/wgl/DisplayWGL.h', + 'libANGLE/renderer/gl/wgl/DXGISwapChainWindowSurfaceWGL.cpp', + 'libANGLE/renderer/gl/wgl/DXGISwapChainWindowSurfaceWGL.h', 'libANGLE/renderer/gl/wgl/FunctionsWGL.cpp', 'libANGLE/renderer/gl/wgl/FunctionsWGL.h', 'libANGLE/renderer/gl/wgl/PbufferSurfaceWGL.cpp', @@ -433,6 +477,29 @@ 'libANGLE/renderer/gl/wgl/wgl_utils.h', 'third_party/khronos/GL/wglext.h', ], + 'libangle_gl_glx_sources': + [ + 'libANGLE/renderer/gl/glx/DisplayGLX.cpp', + 'libANGLE/renderer/gl/glx/DisplayGLX.h', + 'libANGLE/renderer/gl/glx/FunctionsGLX.cpp', + 'libANGLE/renderer/gl/glx/FunctionsGLX.h', + 'libANGLE/renderer/gl/glx/PbufferSurfaceGLX.cpp', + 'libANGLE/renderer/gl/glx/PbufferSurfaceGLX.h', + 'libANGLE/renderer/gl/glx/SurfaceGLX.h', + 'libANGLE/renderer/gl/glx/WindowSurfaceGLX.cpp', + 'libANGLE/renderer/gl/glx/WindowSurfaceGLX.h', + 'libANGLE/renderer/gl/glx/functionsglx_typedefs.h', + 'libANGLE/renderer/gl/glx/platform_glx.h', + ], + 'libangle_gl_cgl_sources': + [ + 'libANGLE/renderer/gl/cgl/DisplayCGL.mm', + 'libANGLE/renderer/gl/cgl/DisplayCGL.h', + 'libANGLE/renderer/gl/cgl/PbufferSurfaceCGL.mm', + 'libANGLE/renderer/gl/cgl/PbufferSurfaceCGL.h', + 'libANGLE/renderer/gl/cgl/WindowSurfaceCGL.mm', + 'libANGLE/renderer/gl/cgl/WindowSurfaceCGL.h', + ], 'libglesv2_sources': [ 'common/angleutils.h', @@ -447,8 +514,6 @@ 'libGLESv2/entry_points_gles_2_0_ext.h', 'libGLESv2/entry_points_gles_3_0.cpp', 'libGLESv2/entry_points_gles_3_0.h', - 'libGLESv2/entry_points_gles_3_0_ext.cpp', - 'libGLESv2/entry_points_gles_3_0_ext.h', 'libGLESv2/global_state.cpp', 'libGLESv2/global_state.h', 'libGLESv2/libGLESv2.cpp', @@ -491,10 +556,6 @@ ], 'defines': [ - 'GL_APICALL=', - 'GL_GLEXT_PROTOTYPES=', - 'EGLAPI=', - 'ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ "d3dcompiler_47.dll", "d3dcompiler_46.dll", "d3dcompiler_43.dll" }', 'LIBANGLE_IMPLEMENTATION', ], 'direct_dependent_settings': @@ -506,13 +567,31 @@ ], 'defines': [ - 'GL_APICALL=', - 'GL_GLEXT_PROTOTYPES=', - 'EGLAPI=', + 'GL_GLEXT_PROTOTYPES', 'ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ "d3dcompiler_47.dll", "d3dcompiler_46.dll", "d3dcompiler_43.dll" }', ], 'conditions': [ + ['OS=="win"', { + 'defines': + [ + 'GL_APICALL=', + 'EGLAPI=', + ], + }, { + 'defines': + [ + 'GL_APICALL=__attribute__((visibility("default")))', + 'EGLAPI=__attribute__((visibility("default")))', + ], + }], + ['OS == "mac"', + { + 'xcode_settings': + { + 'DYLIB_INSTALL_NAME_BASE': '@rpath', + }, + }], ['angle_enable_d3d9==1', { 'defines': @@ -533,6 +612,16 @@ [ 'ANGLE_ENABLE_OPENGL', ], + 'conditions': + [ + ['angle_use_glx==1', + { + 'defines': + [ + 'ANGLE_USE_X11', + ], + }], + ], }], ], }, @@ -643,6 +732,66 @@ '<@(libangle_gl_wgl_sources)', ], }], + ['angle_use_glx==1', + { + 'defines': + [ + 'ANGLE_USE_X11', + ], + 'dependencies': + [ + '<(angle_path)/src/third_party/libXNVCtrl/libXNVCtrl.gyp:libXNVCtrl', + ], + 'sources': + [ + '<@(libangle_gl_glx_sources)', + ], + 'link_settings': { + 'ldflags': [ + '(display_id), AttributeMap()); } EGLBoolean EGLAPIENTRY Initialize(EGLDisplay dpy, EGLint *major, EGLint *minor) @@ -48,14 +49,13 @@ EGLBoolean EGLAPIENTRY Initialize(EGLDisplay dpy, EGLint *major, EGLint *minor) EVENT("(EGLDisplay dpy = 0x%0.8p, EGLint *major = 0x%0.8p, EGLint *minor = 0x%0.8p)", dpy, major, minor); - if (dpy == EGL_NO_DISPLAY) + Display *display = static_cast(dpy); + if (dpy == EGL_NO_DISPLAY || !Display::isValidDisplay(display)) { SetGlobalError(Error(EGL_BAD_DISPLAY)); return EGL_FALSE; } - Display *display = static_cast(dpy); - Error error = display->initialize(); if (error.isError()) { @@ -74,13 +74,13 @@ EGLBoolean EGLAPIENTRY Terminate(EGLDisplay dpy) { EVENT("(EGLDisplay dpy = 0x%0.8p)", dpy); - if (dpy == EGL_NO_DISPLAY) + Display *display = static_cast(dpy); + if (dpy == EGL_NO_DISPLAY || !Display::isValidDisplay(display)) { SetGlobalError(Error(EGL_BAD_DISPLAY)); return EGL_FALSE; } - Display *display = static_cast(dpy); gl::Context *context = GetGlobalContext(); if (display->isValidContext(context)) @@ -171,7 +171,7 @@ EGLBoolean EGLAPIENTRY GetConfigs(EGLDisplay dpy, EGLConfig *configs, EGLint con configs[i] = const_cast(filteredConfigs[i]); } } - *num_config = filteredConfigs.size(); + *num_config = static_cast(filteredConfigs.size()); SetGlobalError(Error(EGL_SUCCESS)); return EGL_TRUE; @@ -198,7 +198,8 @@ EGLBoolean EGLAPIENTRY ChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, E return EGL_FALSE; } - std::vector filteredConfigs = display->getConfigs(AttributeMap(attrib_list)); + std::vector filteredConfigs = + display->getConfigs(AttributeMap::CreateFromIntArray(attrib_list)); if (configs) { filteredConfigs.resize(std::min(filteredConfigs.size(), config_size)); @@ -207,7 +208,7 @@ EGLBoolean EGLAPIENTRY ChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, E configs[i] = const_cast(filteredConfigs[i]); } } - *num_config = filteredConfigs.size(); + *num_config = static_cast(filteredConfigs.size()); SetGlobalError(Error(EGL_SUCCESS)); return EGL_TRUE; @@ -245,7 +246,7 @@ EGLSurface EGLAPIENTRY CreateWindowSurface(EGLDisplay dpy, EGLConfig config, EGL Display *display = static_cast(dpy); Config *configuration = static_cast(config); - AttributeMap attributes(attrib_list); + AttributeMap attributes = AttributeMap::CreateFromIntArray(attrib_list); Error error = ValidateCreateWindowSurface(display, configuration, win, attributes); if (error.isError()) @@ -272,7 +273,7 @@ EGLSurface EGLAPIENTRY CreatePbufferSurface(EGLDisplay dpy, EGLConfig config, co Display *display = static_cast(dpy); Config *configuration = static_cast(config); - AttributeMap attributes(attrib_list); + AttributeMap attributes = AttributeMap::CreateFromIntArray(attrib_list); Error error = ValidateCreatePbufferSurface(display, configuration, attributes); if (error.isError()) @@ -426,6 +427,37 @@ EGLBoolean EGLAPIENTRY QuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint a } *value = eglSurface->isFixedSize(); break; + case EGL_FLEXIBLE_SURFACE_COMPATIBILITY_SUPPORTED_ANGLE: + if (!display->getExtensions().flexibleSurfaceCompatibility) + { + SetGlobalError( + Error(EGL_BAD_ATTRIBUTE, + "EGL_FLEXIBLE_SURFACE_COMPATIBILITY_SUPPORTED_ANGLE cannot be used without " + "EGL_ANGLE_flexible_surface_compatibility support.")); + return EGL_FALSE; + } + *value = eglSurface->flexibleSurfaceCompatibilityRequested(); + break; + case EGL_SURFACE_ORIENTATION_ANGLE: + if (!display->getExtensions().surfaceOrientation) + { + SetGlobalError(Error(EGL_BAD_ATTRIBUTE, + "EGL_SURFACE_ORIENTATION_ANGLE cannot be queried without " + "EGL_ANGLE_surface_orientation support.")); + return EGL_FALSE; + } + *value = eglSurface->getOrientation(); + break; + case EGL_DIRECT_COMPOSITION_ANGLE: + if (!display->getExtensions().directComposition) + { + SetGlobalError(Error(EGL_BAD_ATTRIBUTE, + "EGL_DIRECT_COMPOSITION_ANGLE cannot be used without " + "EGL_ANGLE_direct_composition support.")); + return EGL_FALSE; + } + *value = eglSurface->directComposition(); + break; default: SetGlobalError(Error(EGL_BAD_ATTRIBUTE)); return EGL_FALSE; @@ -443,7 +475,7 @@ EGLContext EGLAPIENTRY CreateContext(EGLDisplay dpy, EGLConfig config, EGLContex Display *display = static_cast(dpy); Config *configuration = static_cast(config); gl::Context* sharedGLContext = static_cast(share_context); - AttributeMap attributes(attrib_list); + AttributeMap attributes = AttributeMap::CreateFromIntArray(attrib_list); Error error = ValidateCreateContext(display, configuration, sharedGLContext, attributes); if (error.isError()) @@ -504,23 +536,37 @@ EGLBoolean EGLAPIENTRY MakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface r Display *display = static_cast(dpy); gl::Context *context = static_cast(ctx); - bool noContext = (ctx == EGL_NO_CONTEXT); - bool noSurface = (draw == EGL_NO_SURFACE || read == EGL_NO_SURFACE); - if (noContext != noSurface) + // If ctx is EGL_NO_CONTEXT and either draw or read are not EGL_NO_SURFACE, an EGL_BAD_MATCH + // error is generated. + if (ctx == EGL_NO_CONTEXT && (draw != EGL_NO_SURFACE || read != EGL_NO_SURFACE)) { SetGlobalError(Error(EGL_BAD_MATCH)); return EGL_FALSE; } - if (dpy == EGL_NO_DISPLAY) + if (ctx != EGL_NO_CONTEXT && draw == EGL_NO_SURFACE && read == EGL_NO_SURFACE) + { + SetGlobalError(Error(EGL_BAD_MATCH)); + return EGL_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)) + { + SetGlobalError(Error( + EGL_BAD_MATCH, "read and draw must both be valid surfaces, or both be EGL_NO_SURFACE")); + return EGL_FALSE; + } + + if (dpy == EGL_NO_DISPLAY || !Display::isValidDisplay(display)) { SetGlobalError(Error(EGL_BAD_DISPLAY, "'dpy' not a valid EGLDisplay handle")); return EGL_FALSE; } // EGL 1.5 spec: dpy can be uninitialized if all other parameters are null - if (dpy != EGL_NO_DISPLAY && !display->isInitialized() && - (ctx != EGL_NO_CONTEXT || draw != EGL_NO_SURFACE || read != EGL_NO_SURFACE)) + if (!display->isInitialized() && (ctx != EGL_NO_CONTEXT || draw != EGL_NO_SURFACE || read != EGL_NO_SURFACE)) { SetGlobalError(Error(EGL_NOT_INITIALIZED, "'dpy' not initialized")); return EGL_FALSE; @@ -536,7 +582,7 @@ EGLBoolean EGLAPIENTRY MakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface r } } - if (dpy != EGL_NO_DISPLAY && display->isInitialized()) + if (display->isInitialized()) { if (display->testDeviceLost()) { @@ -573,9 +619,40 @@ EGLBoolean EGLAPIENTRY MakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface r } } + if (readSurface) + { + Error readCompatError = + ValidateCompatibleConfigs(display, readSurface->getConfig(), readSurface, + context->getConfig(), readSurface->getType()); + if (readCompatError.isError()) + { + SetGlobalError(readCompatError); + return EGL_FALSE; + } + } + if (draw != read) { UNIMPLEMENTED(); // FIXME + + if (drawSurface) + { + Error drawCompatError = + ValidateCompatibleConfigs(display, drawSurface->getConfig(), drawSurface, + context->getConfig(), drawSurface->getType()); + if (drawCompatError.isError()) + { + SetGlobalError(drawCompatError); + return EGL_FALSE; + } + } + } + + Error makeCurrentError = display->makeCurrent(drawSurface, readSurface, context); + if (makeCurrentError.isError()) + { + SetGlobalError(makeCurrentError); + return EGL_FALSE; } gl::Context *previousContext = GetGlobalContext(); @@ -585,8 +662,6 @@ EGLBoolean EGLAPIENTRY MakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface r SetGlobalReadSurface(readSurface); SetGlobalContext(context); - display->makeCurrent(drawSurface, readSurface, context); - // Release the surface from the previously-current context, to allow // destroyed surfaces to delete themselves. if (previousContext != nullptr && context != previousContext) @@ -647,7 +722,7 @@ EGLBoolean EGLAPIENTRY QueryContext(EGLDisplay dpy, EGLContext ctx, EGLint attri switch (attribute) { case EGL_CONFIG_ID: - *value = context->getConfigID(); + *value = context->getConfig()->configID; break; case EGL_CONTEXT_CLIENT_TYPE: *value = context->getClientType(); @@ -671,20 +746,56 @@ EGLBoolean EGLAPIENTRY WaitGL(void) { EVENT("()"); - UNIMPLEMENTED(); // FIXME + Display *display = GetGlobalDisplay(); + + Error error = ValidateDisplay(display); + if (error.isError()) + { + SetGlobalError(error); + return EGL_FALSE; + } + + // eglWaitGL like calling eglWaitClient with the OpenGL ES API bound. Since we only implement + // OpenGL ES we can do the call directly. + error = display->waitClient(); + if (error.isError()) + { + SetGlobalError(error); + return EGL_FALSE; + } SetGlobalError(Error(EGL_SUCCESS)); - return 0; + return EGL_TRUE; } EGLBoolean EGLAPIENTRY WaitNative(EGLint engine) { EVENT("(EGLint engine = %d)", engine); - UNIMPLEMENTED(); // FIXME + Display *display = GetGlobalDisplay(); + + Error error = ValidateDisplay(display); + if (error.isError()) + { + SetGlobalError(error); + return EGL_FALSE; + } + + if (engine != EGL_CORE_NATIVE_ENGINE) + { + SetGlobalError( + Error(EGL_BAD_PARAMETER, "the 'engine' parameter has an unrecognized value")); + } + + error = display->waitNative(engine, GetGlobalDrawSurface(), GetGlobalReadSurface()); + if (error.isError()) + { + SetGlobalError(error); + return EGL_FALSE; + } SetGlobalError(Error(EGL_SUCCESS)); - return 0; + return EGL_TRUE; } EGLBoolean EGLAPIENTRY SwapBuffers(EGLDisplay dpy, EGLSurface surface) @@ -795,13 +906,13 @@ EGLBoolean EGLAPIENTRY BindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint b gl::Texture *textureObject = context->getTargetTexture(GL_TEXTURE_2D); ASSERT(textureObject != NULL); - if (textureObject->isImmutable()) + if (textureObject->getImmutableFormat()) { SetGlobalError(Error(EGL_BAD_MATCH)); return EGL_FALSE; } - egl::Error error = eglSurface->bindTexImage(textureObject, buffer); + error = eglSurface->bindTexImage(textureObject, buffer); if (error.isError()) { SetGlobalError(error); @@ -870,7 +981,7 @@ EGLBoolean EGLAPIENTRY ReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLin if (texture) { - egl::Error error = eglSurface->releaseTexImage(buffer); + error = eglSurface->releaseTexImage(buffer); if (error.isError()) { SetGlobalError(error); @@ -955,7 +1066,7 @@ EGLSurface EGLAPIENTRY CreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buf Display *display = static_cast(dpy); Config *configuration = static_cast(config); - AttributeMap attributes(attrib_list); + AttributeMap attributes = AttributeMap::CreateFromIntArray(attrib_list); Error error = ValidateCreatePbufferFromClientBuffer(display, buftype, buffer, configuration, attributes); if (error.isError()) @@ -989,10 +1100,24 @@ EGLBoolean EGLAPIENTRY WaitClient(void) { EVENT("()"); - UNIMPLEMENTED(); // FIXME + Display *display = GetGlobalDisplay(); + + Error error = ValidateDisplay(display); + if (error.isError()) + { + SetGlobalError(error); + return EGL_FALSE; + } + + error = display->waitClient(); + if (error.isError()) + { + SetGlobalError(error); + return EGL_FALSE; + } SetGlobalError(Error(EGL_SUCCESS)); - return 0; + return EGL_TRUE; } // EGL 1.4 @@ -1096,65 +1221,458 @@ __eglMustCastToProperFunctionPointerType EGLAPIENTRY GetProcAddress(const char * { EVENT("(const char *procname = \"%s\")", procname); - struct Extension - { - const char *name; - __eglMustCastToProperFunctionPointerType address; + typedef std::map ProcAddressMap; + auto generateProcAddressMap = []() + { + ProcAddressMap map; +#define INSERT_PROC_ADDRESS(ns, proc) \ + map[#ns #proc] = reinterpret_cast<__eglMustCastToProperFunctionPointerType>(ns::proc) + + // GLES2 core + INSERT_PROC_ADDRESS(gl, ActiveTexture); + INSERT_PROC_ADDRESS(gl, AttachShader); + INSERT_PROC_ADDRESS(gl, BindAttribLocation); + INSERT_PROC_ADDRESS(gl, BindBuffer); + INSERT_PROC_ADDRESS(gl, BindFramebuffer); + INSERT_PROC_ADDRESS(gl, BindRenderbuffer); + INSERT_PROC_ADDRESS(gl, BindTexture); + INSERT_PROC_ADDRESS(gl, BlendColor); + INSERT_PROC_ADDRESS(gl, BlendEquation); + INSERT_PROC_ADDRESS(gl, BlendEquationSeparate); + INSERT_PROC_ADDRESS(gl, BlendFunc); + INSERT_PROC_ADDRESS(gl, BlendFuncSeparate); + INSERT_PROC_ADDRESS(gl, BufferData); + INSERT_PROC_ADDRESS(gl, BufferSubData); + INSERT_PROC_ADDRESS(gl, CheckFramebufferStatus); + INSERT_PROC_ADDRESS(gl, Clear); + INSERT_PROC_ADDRESS(gl, ClearColor); + INSERT_PROC_ADDRESS(gl, ClearDepthf); + INSERT_PROC_ADDRESS(gl, ClearStencil); + INSERT_PROC_ADDRESS(gl, ColorMask); + INSERT_PROC_ADDRESS(gl, CompileShader); + INSERT_PROC_ADDRESS(gl, CompressedTexImage2D); + INSERT_PROC_ADDRESS(gl, CompressedTexSubImage2D); + INSERT_PROC_ADDRESS(gl, CopyTexImage2D); + INSERT_PROC_ADDRESS(gl, CopyTexSubImage2D); + INSERT_PROC_ADDRESS(gl, CreateProgram); + INSERT_PROC_ADDRESS(gl, CreateShader); + INSERT_PROC_ADDRESS(gl, CullFace); + INSERT_PROC_ADDRESS(gl, DeleteBuffers); + INSERT_PROC_ADDRESS(gl, DeleteFramebuffers); + INSERT_PROC_ADDRESS(gl, DeleteProgram); + INSERT_PROC_ADDRESS(gl, DeleteRenderbuffers); + INSERT_PROC_ADDRESS(gl, DeleteShader); + INSERT_PROC_ADDRESS(gl, DeleteTextures); + INSERT_PROC_ADDRESS(gl, DepthFunc); + INSERT_PROC_ADDRESS(gl, DepthMask); + INSERT_PROC_ADDRESS(gl, DepthRangef); + INSERT_PROC_ADDRESS(gl, DetachShader); + INSERT_PROC_ADDRESS(gl, Disable); + INSERT_PROC_ADDRESS(gl, DisableVertexAttribArray); + INSERT_PROC_ADDRESS(gl, DrawArrays); + INSERT_PROC_ADDRESS(gl, DrawElements); + INSERT_PROC_ADDRESS(gl, Enable); + INSERT_PROC_ADDRESS(gl, EnableVertexAttribArray); + INSERT_PROC_ADDRESS(gl, Finish); + INSERT_PROC_ADDRESS(gl, Flush); + INSERT_PROC_ADDRESS(gl, FramebufferRenderbuffer); + INSERT_PROC_ADDRESS(gl, FramebufferTexture2D); + INSERT_PROC_ADDRESS(gl, FrontFace); + INSERT_PROC_ADDRESS(gl, GenBuffers); + INSERT_PROC_ADDRESS(gl, GenerateMipmap); + INSERT_PROC_ADDRESS(gl, GenFramebuffers); + INSERT_PROC_ADDRESS(gl, GenRenderbuffers); + INSERT_PROC_ADDRESS(gl, GenTextures); + INSERT_PROC_ADDRESS(gl, GetActiveAttrib); + INSERT_PROC_ADDRESS(gl, GetActiveUniform); + INSERT_PROC_ADDRESS(gl, GetAttachedShaders); + INSERT_PROC_ADDRESS(gl, GetAttribLocation); + INSERT_PROC_ADDRESS(gl, GetBooleanv); + INSERT_PROC_ADDRESS(gl, GetBufferParameteriv); + INSERT_PROC_ADDRESS(gl, GetError); + INSERT_PROC_ADDRESS(gl, GetFloatv); + INSERT_PROC_ADDRESS(gl, GetFramebufferAttachmentParameteriv); + INSERT_PROC_ADDRESS(gl, GetIntegerv); + INSERT_PROC_ADDRESS(gl, GetProgramiv); + INSERT_PROC_ADDRESS(gl, GetProgramInfoLog); + INSERT_PROC_ADDRESS(gl, GetRenderbufferParameteriv); + INSERT_PROC_ADDRESS(gl, GetShaderiv); + INSERT_PROC_ADDRESS(gl, GetShaderInfoLog); + INSERT_PROC_ADDRESS(gl, GetShaderPrecisionFormat); + INSERT_PROC_ADDRESS(gl, GetShaderSource); + INSERT_PROC_ADDRESS(gl, GetString); + INSERT_PROC_ADDRESS(gl, GetTexParameterfv); + INSERT_PROC_ADDRESS(gl, GetTexParameteriv); + INSERT_PROC_ADDRESS(gl, GetUniformfv); + INSERT_PROC_ADDRESS(gl, GetUniformiv); + INSERT_PROC_ADDRESS(gl, GetUniformLocation); + INSERT_PROC_ADDRESS(gl, GetVertexAttribfv); + INSERT_PROC_ADDRESS(gl, GetVertexAttribiv); + INSERT_PROC_ADDRESS(gl, GetVertexAttribPointerv); + INSERT_PROC_ADDRESS(gl, Hint); + INSERT_PROC_ADDRESS(gl, IsBuffer); + INSERT_PROC_ADDRESS(gl, IsEnabled); + INSERT_PROC_ADDRESS(gl, IsFramebuffer); + INSERT_PROC_ADDRESS(gl, IsProgram); + INSERT_PROC_ADDRESS(gl, IsRenderbuffer); + INSERT_PROC_ADDRESS(gl, IsShader); + INSERT_PROC_ADDRESS(gl, IsTexture); + INSERT_PROC_ADDRESS(gl, LineWidth); + INSERT_PROC_ADDRESS(gl, LinkProgram); + INSERT_PROC_ADDRESS(gl, PixelStorei); + INSERT_PROC_ADDRESS(gl, PolygonOffset); + INSERT_PROC_ADDRESS(gl, ReadPixels); + INSERT_PROC_ADDRESS(gl, ReleaseShaderCompiler); + INSERT_PROC_ADDRESS(gl, RenderbufferStorage); + INSERT_PROC_ADDRESS(gl, SampleCoverage); + INSERT_PROC_ADDRESS(gl, Scissor); + INSERT_PROC_ADDRESS(gl, ShaderBinary); + INSERT_PROC_ADDRESS(gl, ShaderSource); + INSERT_PROC_ADDRESS(gl, StencilFunc); + INSERT_PROC_ADDRESS(gl, StencilFuncSeparate); + INSERT_PROC_ADDRESS(gl, StencilMask); + INSERT_PROC_ADDRESS(gl, StencilMaskSeparate); + INSERT_PROC_ADDRESS(gl, StencilOp); + INSERT_PROC_ADDRESS(gl, StencilOpSeparate); + INSERT_PROC_ADDRESS(gl, TexImage2D); + INSERT_PROC_ADDRESS(gl, TexParameterf); + INSERT_PROC_ADDRESS(gl, TexParameterfv); + INSERT_PROC_ADDRESS(gl, TexParameteri); + INSERT_PROC_ADDRESS(gl, TexParameteriv); + INSERT_PROC_ADDRESS(gl, TexSubImage2D); + INSERT_PROC_ADDRESS(gl, Uniform1f); + INSERT_PROC_ADDRESS(gl, Uniform1fv); + INSERT_PROC_ADDRESS(gl, Uniform1i); + INSERT_PROC_ADDRESS(gl, Uniform1iv); + INSERT_PROC_ADDRESS(gl, Uniform2f); + INSERT_PROC_ADDRESS(gl, Uniform2fv); + INSERT_PROC_ADDRESS(gl, Uniform2i); + INSERT_PROC_ADDRESS(gl, Uniform2iv); + INSERT_PROC_ADDRESS(gl, Uniform3f); + INSERT_PROC_ADDRESS(gl, Uniform3fv); + INSERT_PROC_ADDRESS(gl, Uniform3i); + INSERT_PROC_ADDRESS(gl, Uniform3iv); + INSERT_PROC_ADDRESS(gl, Uniform4f); + INSERT_PROC_ADDRESS(gl, Uniform4fv); + INSERT_PROC_ADDRESS(gl, Uniform4i); + INSERT_PROC_ADDRESS(gl, Uniform4iv); + INSERT_PROC_ADDRESS(gl, UniformMatrix2fv); + INSERT_PROC_ADDRESS(gl, UniformMatrix3fv); + INSERT_PROC_ADDRESS(gl, UniformMatrix4fv); + INSERT_PROC_ADDRESS(gl, UseProgram); + INSERT_PROC_ADDRESS(gl, ValidateProgram); + INSERT_PROC_ADDRESS(gl, VertexAttrib1f); + INSERT_PROC_ADDRESS(gl, VertexAttrib1fv); + INSERT_PROC_ADDRESS(gl, VertexAttrib2f); + INSERT_PROC_ADDRESS(gl, VertexAttrib2fv); + INSERT_PROC_ADDRESS(gl, VertexAttrib3f); + INSERT_PROC_ADDRESS(gl, VertexAttrib3fv); + INSERT_PROC_ADDRESS(gl, VertexAttrib4f); + INSERT_PROC_ADDRESS(gl, VertexAttrib4fv); + INSERT_PROC_ADDRESS(gl, VertexAttribPointer); + INSERT_PROC_ADDRESS(gl, Viewport); + + // GL_ANGLE_framebuffer_blit + INSERT_PROC_ADDRESS(gl, BlitFramebufferANGLE); + + // GL_ANGLE_framebuffer_multisample + INSERT_PROC_ADDRESS(gl, RenderbufferStorageMultisampleANGLE); + + // GL_EXT_discard_framebuffer + INSERT_PROC_ADDRESS(gl, DiscardFramebufferEXT); + + // GL_NV_fence + INSERT_PROC_ADDRESS(gl, DeleteFencesNV); + INSERT_PROC_ADDRESS(gl, GenFencesNV); + INSERT_PROC_ADDRESS(gl, IsFenceNV); + INSERT_PROC_ADDRESS(gl, TestFenceNV); + INSERT_PROC_ADDRESS(gl, GetFenceivNV); + INSERT_PROC_ADDRESS(gl, FinishFenceNV); + INSERT_PROC_ADDRESS(gl, SetFenceNV); + + // GL_ANGLE_translated_shader_source + INSERT_PROC_ADDRESS(gl, GetTranslatedShaderSourceANGLE); + + // GL_EXT_texture_storage + INSERT_PROC_ADDRESS(gl, TexStorage2DEXT); + + // GL_EXT_robustness + INSERT_PROC_ADDRESS(gl, GetGraphicsResetStatusEXT); + INSERT_PROC_ADDRESS(gl, ReadnPixelsEXT); + INSERT_PROC_ADDRESS(gl, GetnUniformfvEXT); + INSERT_PROC_ADDRESS(gl, GetnUniformivEXT); + + // GL_EXT_occlusion_query_boolean + INSERT_PROC_ADDRESS(gl, GenQueriesEXT); + INSERT_PROC_ADDRESS(gl, DeleteQueriesEXT); + INSERT_PROC_ADDRESS(gl, IsQueryEXT); + INSERT_PROC_ADDRESS(gl, BeginQueryEXT); + INSERT_PROC_ADDRESS(gl, EndQueryEXT); + INSERT_PROC_ADDRESS(gl, GetQueryivEXT); + INSERT_PROC_ADDRESS(gl, GetQueryObjectuivEXT); + + // GL_EXT_draw_buffers + INSERT_PROC_ADDRESS(gl, DrawBuffersEXT); + + // GL_ANGLE_instanced_arrays + INSERT_PROC_ADDRESS(gl, DrawArraysInstancedANGLE); + INSERT_PROC_ADDRESS(gl, DrawElementsInstancedANGLE); + INSERT_PROC_ADDRESS(gl, VertexAttribDivisorANGLE); + + // GL_OES_get_program_binary + INSERT_PROC_ADDRESS(gl, GetProgramBinaryOES); + INSERT_PROC_ADDRESS(gl, ProgramBinaryOES); + + // GL_OES_mapbuffer + INSERT_PROC_ADDRESS(gl, MapBufferOES); + INSERT_PROC_ADDRESS(gl, UnmapBufferOES); + INSERT_PROC_ADDRESS(gl, GetBufferPointervOES); + + // GL_EXT_map_buffer_range + INSERT_PROC_ADDRESS(gl, MapBufferRangeEXT); + INSERT_PROC_ADDRESS(gl, FlushMappedBufferRangeEXT); + + // GL_EXT_debug_marker + INSERT_PROC_ADDRESS(gl, InsertEventMarkerEXT); + INSERT_PROC_ADDRESS(gl, PushGroupMarkerEXT); + INSERT_PROC_ADDRESS(gl, PopGroupMarkerEXT); + + // GL_OES_EGL_image + INSERT_PROC_ADDRESS(gl, EGLImageTargetTexture2DOES); + INSERT_PROC_ADDRESS(gl, EGLImageTargetRenderbufferStorageOES); + + // GL_OES_vertex_array_object + INSERT_PROC_ADDRESS(gl, BindVertexArrayOES); + INSERT_PROC_ADDRESS(gl, DeleteVertexArraysOES); + INSERT_PROC_ADDRESS(gl, GenVertexArraysOES); + INSERT_PROC_ADDRESS(gl, IsVertexArrayOES); + + // GL_KHR_debug + INSERT_PROC_ADDRESS(gl, DebugMessageControlKHR); + INSERT_PROC_ADDRESS(gl, DebugMessageInsertKHR); + INSERT_PROC_ADDRESS(gl, DebugMessageCallbackKHR); + INSERT_PROC_ADDRESS(gl, GetDebugMessageLogKHR); + INSERT_PROC_ADDRESS(gl, PushDebugGroupKHR); + INSERT_PROC_ADDRESS(gl, PopDebugGroupKHR); + INSERT_PROC_ADDRESS(gl, ObjectLabelKHR); + INSERT_PROC_ADDRESS(gl, GetObjectLabelKHR); + INSERT_PROC_ADDRESS(gl, ObjectPtrLabelKHR); + INSERT_PROC_ADDRESS(gl, GetObjectPtrLabelKHR); + INSERT_PROC_ADDRESS(gl, GetPointervKHR); + + // GLES3 core + INSERT_PROC_ADDRESS(gl, ReadBuffer); + INSERT_PROC_ADDRESS(gl, DrawRangeElements); + INSERT_PROC_ADDRESS(gl, TexImage3D); + INSERT_PROC_ADDRESS(gl, TexSubImage3D); + INSERT_PROC_ADDRESS(gl, CopyTexSubImage3D); + INSERT_PROC_ADDRESS(gl, CompressedTexImage3D); + INSERT_PROC_ADDRESS(gl, CompressedTexSubImage3D); + INSERT_PROC_ADDRESS(gl, GenQueries); + INSERT_PROC_ADDRESS(gl, DeleteQueries); + INSERT_PROC_ADDRESS(gl, IsQuery); + INSERT_PROC_ADDRESS(gl, BeginQuery); + INSERT_PROC_ADDRESS(gl, EndQuery); + INSERT_PROC_ADDRESS(gl, GetQueryiv); + INSERT_PROC_ADDRESS(gl, GetQueryObjectuiv); + INSERT_PROC_ADDRESS(gl, UnmapBuffer); + INSERT_PROC_ADDRESS(gl, GetBufferPointerv); + INSERT_PROC_ADDRESS(gl, DrawBuffers); + INSERT_PROC_ADDRESS(gl, UniformMatrix2x3fv); + INSERT_PROC_ADDRESS(gl, UniformMatrix3x2fv); + INSERT_PROC_ADDRESS(gl, UniformMatrix2x4fv); + INSERT_PROC_ADDRESS(gl, UniformMatrix4x2fv); + INSERT_PROC_ADDRESS(gl, UniformMatrix3x4fv); + INSERT_PROC_ADDRESS(gl, UniformMatrix4x3fv); + INSERT_PROC_ADDRESS(gl, BlitFramebuffer); + INSERT_PROC_ADDRESS(gl, RenderbufferStorageMultisample); + INSERT_PROC_ADDRESS(gl, FramebufferTextureLayer); + INSERT_PROC_ADDRESS(gl, MapBufferRange); + INSERT_PROC_ADDRESS(gl, FlushMappedBufferRange); + INSERT_PROC_ADDRESS(gl, BindVertexArray); + INSERT_PROC_ADDRESS(gl, DeleteVertexArrays); + INSERT_PROC_ADDRESS(gl, GenVertexArrays); + INSERT_PROC_ADDRESS(gl, IsVertexArray); + INSERT_PROC_ADDRESS(gl, GetIntegeri_v); + INSERT_PROC_ADDRESS(gl, BeginTransformFeedback); + INSERT_PROC_ADDRESS(gl, EndTransformFeedback); + INSERT_PROC_ADDRESS(gl, BindBufferRange); + INSERT_PROC_ADDRESS(gl, BindBufferBase); + INSERT_PROC_ADDRESS(gl, TransformFeedbackVaryings); + INSERT_PROC_ADDRESS(gl, GetTransformFeedbackVarying); + INSERT_PROC_ADDRESS(gl, VertexAttribIPointer); + INSERT_PROC_ADDRESS(gl, GetVertexAttribIiv); + INSERT_PROC_ADDRESS(gl, GetVertexAttribIuiv); + INSERT_PROC_ADDRESS(gl, VertexAttribI4i); + INSERT_PROC_ADDRESS(gl, VertexAttribI4ui); + INSERT_PROC_ADDRESS(gl, VertexAttribI4iv); + INSERT_PROC_ADDRESS(gl, VertexAttribI4uiv); + INSERT_PROC_ADDRESS(gl, GetUniformuiv); + INSERT_PROC_ADDRESS(gl, GetFragDataLocation); + INSERT_PROC_ADDRESS(gl, Uniform1ui); + INSERT_PROC_ADDRESS(gl, Uniform2ui); + INSERT_PROC_ADDRESS(gl, Uniform3ui); + INSERT_PROC_ADDRESS(gl, Uniform4ui); + INSERT_PROC_ADDRESS(gl, Uniform1uiv); + INSERT_PROC_ADDRESS(gl, Uniform2uiv); + INSERT_PROC_ADDRESS(gl, Uniform3uiv); + INSERT_PROC_ADDRESS(gl, Uniform4uiv); + INSERT_PROC_ADDRESS(gl, ClearBufferiv); + INSERT_PROC_ADDRESS(gl, ClearBufferuiv); + INSERT_PROC_ADDRESS(gl, ClearBufferfv); + INSERT_PROC_ADDRESS(gl, ClearBufferfi); + INSERT_PROC_ADDRESS(gl, GetStringi); + INSERT_PROC_ADDRESS(gl, CopyBufferSubData); + INSERT_PROC_ADDRESS(gl, GetUniformIndices); + INSERT_PROC_ADDRESS(gl, GetActiveUniformsiv); + INSERT_PROC_ADDRESS(gl, GetUniformBlockIndex); + INSERT_PROC_ADDRESS(gl, GetActiveUniformBlockiv); + INSERT_PROC_ADDRESS(gl, GetActiveUniformBlockName); + INSERT_PROC_ADDRESS(gl, UniformBlockBinding); + INSERT_PROC_ADDRESS(gl, DrawArraysInstanced); + INSERT_PROC_ADDRESS(gl, DrawElementsInstanced); + map["glFenceSync"] = + reinterpret_cast<__eglMustCastToProperFunctionPointerType>(gl::FenceSync_); + INSERT_PROC_ADDRESS(gl, IsSync); + INSERT_PROC_ADDRESS(gl, DeleteSync); + INSERT_PROC_ADDRESS(gl, ClientWaitSync); + INSERT_PROC_ADDRESS(gl, WaitSync); + INSERT_PROC_ADDRESS(gl, GetInteger64v); + INSERT_PROC_ADDRESS(gl, GetSynciv); + INSERT_PROC_ADDRESS(gl, GetInteger64i_v); + INSERT_PROC_ADDRESS(gl, GetBufferParameteri64v); + INSERT_PROC_ADDRESS(gl, GenSamplers); + INSERT_PROC_ADDRESS(gl, DeleteSamplers); + INSERT_PROC_ADDRESS(gl, IsSampler); + INSERT_PROC_ADDRESS(gl, BindSampler); + INSERT_PROC_ADDRESS(gl, SamplerParameteri); + INSERT_PROC_ADDRESS(gl, SamplerParameteriv); + INSERT_PROC_ADDRESS(gl, SamplerParameterf); + INSERT_PROC_ADDRESS(gl, SamplerParameterfv); + INSERT_PROC_ADDRESS(gl, GetSamplerParameteriv); + INSERT_PROC_ADDRESS(gl, GetSamplerParameterfv); + INSERT_PROC_ADDRESS(gl, VertexAttribDivisor); + INSERT_PROC_ADDRESS(gl, BindTransformFeedback); + INSERT_PROC_ADDRESS(gl, DeleteTransformFeedbacks); + INSERT_PROC_ADDRESS(gl, GenTransformFeedbacks); + INSERT_PROC_ADDRESS(gl, IsTransformFeedback); + INSERT_PROC_ADDRESS(gl, PauseTransformFeedback); + INSERT_PROC_ADDRESS(gl, ResumeTransformFeedback); + INSERT_PROC_ADDRESS(gl, GetProgramBinary); + INSERT_PROC_ADDRESS(gl, ProgramBinary); + INSERT_PROC_ADDRESS(gl, ProgramParameteri); + INSERT_PROC_ADDRESS(gl, InvalidateFramebuffer); + INSERT_PROC_ADDRESS(gl, InvalidateSubFramebuffer); + INSERT_PROC_ADDRESS(gl, TexStorage2D); + INSERT_PROC_ADDRESS(gl, TexStorage3D); + INSERT_PROC_ADDRESS(gl, GetInternalformativ); + + // EGL 1.0 + INSERT_PROC_ADDRESS(egl, ChooseConfig); + INSERT_PROC_ADDRESS(egl, CopyBuffers); + INSERT_PROC_ADDRESS(egl, CreateContext); + INSERT_PROC_ADDRESS(egl, CreatePbufferSurface); + INSERT_PROC_ADDRESS(egl, CreatePixmapSurface); + INSERT_PROC_ADDRESS(egl, CreateWindowSurface); + INSERT_PROC_ADDRESS(egl, DestroyContext); + INSERT_PROC_ADDRESS(egl, DestroySurface); + INSERT_PROC_ADDRESS(egl, GetConfigAttrib); + INSERT_PROC_ADDRESS(egl, GetConfigs); + INSERT_PROC_ADDRESS(egl, GetCurrentDisplay); + INSERT_PROC_ADDRESS(egl, GetCurrentSurface); + INSERT_PROC_ADDRESS(egl, GetDisplay); + INSERT_PROC_ADDRESS(egl, GetError); + INSERT_PROC_ADDRESS(egl, GetProcAddress); + INSERT_PROC_ADDRESS(egl, Initialize); + INSERT_PROC_ADDRESS(egl, MakeCurrent); + INSERT_PROC_ADDRESS(egl, QueryContext); + INSERT_PROC_ADDRESS(egl, QueryString); + INSERT_PROC_ADDRESS(egl, QuerySurface); + INSERT_PROC_ADDRESS(egl, SwapBuffers); + INSERT_PROC_ADDRESS(egl, Terminate); + INSERT_PROC_ADDRESS(egl, WaitGL); + INSERT_PROC_ADDRESS(egl, WaitNative); + + // EGL 1.1 + INSERT_PROC_ADDRESS(egl, BindTexImage); + INSERT_PROC_ADDRESS(egl, ReleaseTexImage); + INSERT_PROC_ADDRESS(egl, SurfaceAttrib); + INSERT_PROC_ADDRESS(egl, SwapInterval); + + // EGL 1.2 + INSERT_PROC_ADDRESS(egl, BindAPI); + INSERT_PROC_ADDRESS(egl, QueryAPI); + INSERT_PROC_ADDRESS(egl, CreatePbufferFromClientBuffer); + INSERT_PROC_ADDRESS(egl, ReleaseThread); + INSERT_PROC_ADDRESS(egl, WaitClient); + + // EGL 1.4 + INSERT_PROC_ADDRESS(egl, GetCurrentContext); + + // EGL 1.5 + INSERT_PROC_ADDRESS(egl, CreateSync); + INSERT_PROC_ADDRESS(egl, DestroySync); + INSERT_PROC_ADDRESS(egl, ClientWaitSync); + INSERT_PROC_ADDRESS(egl, GetSyncAttrib); + INSERT_PROC_ADDRESS(egl, CreateImage); + INSERT_PROC_ADDRESS(egl, DestroyImage); + INSERT_PROC_ADDRESS(egl, GetPlatformDisplay); + INSERT_PROC_ADDRESS(egl, CreatePlatformWindowSurface); + INSERT_PROC_ADDRESS(egl, CreatePlatformPixmapSurface); + INSERT_PROC_ADDRESS(egl, WaitSync); + + // EGL_ANGLE_query_surface_pointer + INSERT_PROC_ADDRESS(egl, QuerySurfacePointerANGLE); + + // EGL_NV_post_sub_buffer + INSERT_PROC_ADDRESS(egl, PostSubBufferNV); + + // EGL_EXT_platform_base + INSERT_PROC_ADDRESS(egl, GetPlatformDisplayEXT); + + // EGL_EXT_device_query + INSERT_PROC_ADDRESS(egl, QueryDisplayAttribEXT); + INSERT_PROC_ADDRESS(egl, QueryDeviceAttribEXT); + INSERT_PROC_ADDRESS(egl, QueryDeviceStringEXT); + + // EGL_KHR_image_base/EGL_KHR_image + INSERT_PROC_ADDRESS(egl, CreateImageKHR); + INSERT_PROC_ADDRESS(egl, DestroyImageKHR); + + // EGL_EXT_device_creation + INSERT_PROC_ADDRESS(egl, CreateDeviceANGLE); + INSERT_PROC_ADDRESS(egl, ReleaseDeviceANGLE); + + // EGL_KHR_stream + INSERT_PROC_ADDRESS(egl, CreateStreamKHR); + INSERT_PROC_ADDRESS(egl, DestroyStreamKHR); + INSERT_PROC_ADDRESS(egl, StreamAttribKHR); + INSERT_PROC_ADDRESS(egl, QueryStreamKHR); + INSERT_PROC_ADDRESS(egl, QueryStreamu64KHR); + + // EGL_KHR_stream_consumer_gltexture + INSERT_PROC_ADDRESS(egl, StreamConsumerGLTextureExternalKHR); + INSERT_PROC_ADDRESS(egl, StreamConsumerAcquireKHR); + INSERT_PROC_ADDRESS(egl, StreamConsumerReleaseKHR); + + // EGL_NV_stream_consumer_gltexture_yuv + INSERT_PROC_ADDRESS(egl, StreamConsumerGLTextureExternalAttribsNV); + +#undef INSERT_PROC_ADDRESS + return map; }; - static const Extension extensions[] = - { - { "eglQueryDeviceAttribEXT", (__eglMustCastToProperFunctionPointerType)QueryDeviceAttribEXT }, - { "eglQueryDeviceStringEXT", (__eglMustCastToProperFunctionPointerType)QueryDeviceStringEXT }, - { "eglQueryDisplayAttribEXT", (__eglMustCastToProperFunctionPointerType)QueryDisplayAttribEXT }, - { "eglQuerySurfacePointerANGLE", (__eglMustCastToProperFunctionPointerType)QuerySurfacePointerANGLE }, - { "eglPostSubBufferNV", (__eglMustCastToProperFunctionPointerType)PostSubBufferNV }, - { "eglGetPlatformDisplayEXT", (__eglMustCastToProperFunctionPointerType)GetPlatformDisplayEXT }, - { "glBlitFramebufferANGLE", (__eglMustCastToProperFunctionPointerType)gl::BlitFramebufferANGLE }, - { "glRenderbufferStorageMultisampleANGLE", (__eglMustCastToProperFunctionPointerType)gl::RenderbufferStorageMultisampleANGLE }, - { "glDeleteFencesNV", (__eglMustCastToProperFunctionPointerType)gl::DeleteFencesNV }, - { "glGenFencesNV", (__eglMustCastToProperFunctionPointerType)gl::GenFencesNV }, - { "glIsFenceNV", (__eglMustCastToProperFunctionPointerType)gl::IsFenceNV }, - { "glTestFenceNV", (__eglMustCastToProperFunctionPointerType)gl::TestFenceNV }, - { "glGetFenceivNV", (__eglMustCastToProperFunctionPointerType)gl::GetFenceivNV }, - { "glFinishFenceNV", (__eglMustCastToProperFunctionPointerType)gl::FinishFenceNV }, - { "glSetFenceNV", (__eglMustCastToProperFunctionPointerType)gl::SetFenceNV }, - { "glGetTranslatedShaderSourceANGLE", (__eglMustCastToProperFunctionPointerType)gl::GetTranslatedShaderSourceANGLE }, - { "glTexStorage2DEXT", (__eglMustCastToProperFunctionPointerType)gl::TexStorage2DEXT }, - { "glGetGraphicsResetStatusEXT", (__eglMustCastToProperFunctionPointerType)gl::GetGraphicsResetStatusEXT }, - { "glReadnPixelsEXT", (__eglMustCastToProperFunctionPointerType)gl::ReadnPixelsEXT }, - { "glGetnUniformfvEXT", (__eglMustCastToProperFunctionPointerType)gl::GetnUniformfvEXT }, - { "glGetnUniformivEXT", (__eglMustCastToProperFunctionPointerType)gl::GetnUniformivEXT }, - { "glGenQueriesEXT", (__eglMustCastToProperFunctionPointerType)gl::GenQueriesEXT }, - { "glDeleteQueriesEXT", (__eglMustCastToProperFunctionPointerType)gl::DeleteQueriesEXT }, - { "glIsQueryEXT", (__eglMustCastToProperFunctionPointerType)gl::IsQueryEXT }, - { "glBeginQueryEXT", (__eglMustCastToProperFunctionPointerType)gl::BeginQueryEXT }, - { "glEndQueryEXT", (__eglMustCastToProperFunctionPointerType)gl::EndQueryEXT }, - { "glGetQueryivEXT", (__eglMustCastToProperFunctionPointerType)gl::GetQueryivEXT }, - { "glGetQueryObjectuivEXT", (__eglMustCastToProperFunctionPointerType)gl::GetQueryObjectuivEXT }, - { "glDrawBuffersEXT", (__eglMustCastToProperFunctionPointerType)gl::DrawBuffersEXT }, - { "glVertexAttribDivisorANGLE", (__eglMustCastToProperFunctionPointerType)gl::VertexAttribDivisorANGLE }, - { "glDrawArraysInstancedANGLE", (__eglMustCastToProperFunctionPointerType)gl::DrawArraysInstancedANGLE }, - { "glDrawElementsInstancedANGLE", (__eglMustCastToProperFunctionPointerType)gl::DrawElementsInstancedANGLE }, - { "glGetProgramBinaryOES", (__eglMustCastToProperFunctionPointerType)gl::GetProgramBinaryOES }, - { "glProgramBinaryOES", (__eglMustCastToProperFunctionPointerType)gl::ProgramBinaryOES }, - { "glGetBufferPointervOES", (__eglMustCastToProperFunctionPointerType)gl::GetBufferPointervOES }, - { "glMapBufferOES", (__eglMustCastToProperFunctionPointerType)gl::MapBufferOES }, - { "glUnmapBufferOES", (__eglMustCastToProperFunctionPointerType)gl::UnmapBufferOES }, - { "glMapBufferRangeEXT", (__eglMustCastToProperFunctionPointerType)gl::MapBufferRangeEXT }, - { "glFlushMappedBufferRangeEXT", (__eglMustCastToProperFunctionPointerType)gl::FlushMappedBufferRangeEXT }, - { "", NULL }, - }; + static const ProcAddressMap procAddressMap = generateProcAddressMap(); - for (const Extension *extension = &extensions[0]; extension->address != nullptr; extension++) + auto iter = procAddressMap.find(procname); + if (iter != procAddressMap.end()) { - if (strcmp(procname, extension->name) == 0) - { - return reinterpret_cast<__eglMustCastToProperFunctionPointerType>(extension->address); - } + return iter->second; + } + else + { + return nullptr; } - - return NULL; } } diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/entry_points_egl_ext.cpp b/Source/ThirdParty/ANGLE/src/libGLESv2/entry_points_egl_ext.cpp index 7de510411185..ddaea1e2a1a5 100644 --- a/Source/ThirdParty/ANGLE/src/libGLESv2/entry_points_egl_ext.cpp +++ b/Source/ThirdParty/ANGLE/src/libGLESv2/entry_points_egl_ext.cpp @@ -9,9 +9,11 @@ #include "libGLESv2/entry_points_egl_ext.h" #include "libGLESv2/global_state.h" +#include "libANGLE/Context.h" #include "libANGLE/Display.h" #include "libANGLE/Device.h" #include "libANGLE/Surface.h" +#include "libANGLE/Stream.h" #include "libANGLE/validationEGL.h" #include "common/debug.h" @@ -57,7 +59,13 @@ EGLBoolean EGLAPIENTRY QuerySurfacePointerANGLE(EGLDisplay dpy, EGLSurface surfa return EGL_FALSE; } break; - + case EGL_DXGI_KEYED_MUTEX_ANGLE: + if (!display->getExtensions().keyedMutex) + { + SetGlobalError(Error(EGL_BAD_ATTRIBUTE)); + return EGL_FALSE; + } + break; default: SetGlobalError(Error(EGL_BAD_ATTRIBUTE)); return EGL_FALSE; @@ -137,136 +145,210 @@ EGLDisplay EGLAPIENTRY GetPlatformDisplayEXT(EGLenum platform, void *native_disp return EGL_NO_DISPLAY; } break; - + case EGL_PLATFORM_DEVICE_EXT: + if (!clientExtensions.platformDevice) + { + SetGlobalError(Error(EGL_BAD_PARAMETER, "Platform Device extension is not active")); + return EGL_NO_DISPLAY; + } + break; default: SetGlobalError(Error(EGL_BAD_CONFIG)); return EGL_NO_DISPLAY; } - EGLint platformType = EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE; - EGLint deviceType = EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE; - bool majorVersionSpecified = false; - bool minorVersionSpecified = false; - bool enableAutoTrimSpecified = false; - - if (attrib_list) + if (platform == EGL_PLATFORM_ANGLE_ANGLE) { - for (const EGLint *curAttrib = attrib_list; curAttrib[0] != EGL_NONE; curAttrib += 2) + EGLint platformType = EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE; + EGLint deviceType = EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE; + bool majorVersionSpecified = false; + bool minorVersionSpecified = false; + bool enableAutoTrimSpecified = false; + bool deviceTypeSpecified = false; + bool presentPathSpecified = false; + + if (attrib_list) { - switch (curAttrib[0]) + for (const EGLint *curAttrib = attrib_list; curAttrib[0] != EGL_NONE; curAttrib += 2) { - case EGL_PLATFORM_ANGLE_TYPE_ANGLE: - switch (curAttrib[1]) + switch (curAttrib[0]) { - 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) + case EGL_PLATFORM_ANGLE_TYPE_ANGLE: + switch (curAttrib[1]) { + 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) + { + SetGlobalError(Error(EGL_BAD_ATTRIBUTE)); + return EGL_NO_DISPLAY; + } + break; + + case EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE: + case EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE: + if (!clientExtensions.platformANGLEOpenGL) + { + SetGlobalError(Error(EGL_BAD_ATTRIBUTE)); + return EGL_NO_DISPLAY; + } + break; + + default: SetGlobalError(Error(EGL_BAD_ATTRIBUTE)); return EGL_NO_DISPLAY; } + platformType = curAttrib[1]; break; - case EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE: - case EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE: - if (!clientExtensions.platformANGLEOpenGL) + case EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE: + if (curAttrib[1] != EGL_DONT_CARE) + { + majorVersionSpecified = true; + } + break; + + case EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE: + if (curAttrib[1] != EGL_DONT_CARE) + { + minorVersionSpecified = true; + } + break; + + case EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE: + switch (curAttrib[1]) { + case EGL_TRUE: + case EGL_FALSE: + break; + default: SetGlobalError(Error(EGL_BAD_ATTRIBUTE)); return EGL_NO_DISPLAY; } + enableAutoTrimSpecified = true; break; - default: - SetGlobalError(Error(EGL_BAD_ATTRIBUTE)); - return EGL_NO_DISPLAY; - } - platformType = curAttrib[1]; - break; - - case EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE: - if (curAttrib[1] != EGL_DONT_CARE) - { - majorVersionSpecified = true; - } - break; + case EGL_EXPERIMENTAL_PRESENT_PATH_ANGLE: + if (!clientExtensions.experimentalPresentPath) + { + SetGlobalError( + Error(EGL_BAD_ATTRIBUTE, + "EGL_ANGLE_experimental_present_path extension not active")); + return EGL_NO_DISPLAY; + } + + switch (curAttrib[1]) + { + case EGL_EXPERIMENTAL_PRESENT_PATH_FAST_ANGLE: + case EGL_EXPERIMENTAL_PRESENT_PATH_COPY_ANGLE: + break; + default: + SetGlobalError( + Error(EGL_BAD_ATTRIBUTE, + "Invalid value for EGL_EXPERIMENTAL_PRESENT_PATH_ANGLE")); + return EGL_NO_DISPLAY; + } + presentPathSpecified = true; + break; + + case EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE: + switch (curAttrib[1]) + { + case EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE: + case EGL_PLATFORM_ANGLE_DEVICE_TYPE_WARP_ANGLE: + case EGL_PLATFORM_ANGLE_DEVICE_TYPE_REFERENCE_ANGLE: + deviceTypeSpecified = true; + break; + + case EGL_PLATFORM_ANGLE_DEVICE_TYPE_NULL_ANGLE: + // This is a hidden option, accepted by the OpenGL back-end. + break; + + default: + SetGlobalError(Error(EGL_BAD_ATTRIBUTE, + "Invalid value for " + "EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE " + "attrib")); + return EGL_NO_DISPLAY; + } + deviceType = curAttrib[1]; + break; - case EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE: - if (curAttrib[1] != EGL_DONT_CARE) - { - minorVersionSpecified = true; + default: + break; } - break; + } + } - case EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE: - switch (curAttrib[1]) - { - case EGL_TRUE: - case EGL_FALSE: - break; - default: - SetGlobalError(Error(EGL_BAD_ATTRIBUTE)); - return EGL_NO_DISPLAY; - } - enableAutoTrimSpecified = true; - break; + if (!majorVersionSpecified && minorVersionSpecified) + { + SetGlobalError(Error(EGL_BAD_ATTRIBUTE)); + return EGL_NO_DISPLAY; + } - case EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE: - if (!clientExtensions.platformANGLED3D) - { - SetGlobalError(Error(EGL_BAD_ATTRIBUTE)); - return EGL_NO_DISPLAY; - } + if (deviceType == EGL_PLATFORM_ANGLE_DEVICE_TYPE_WARP_ANGLE && + platformType != EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE) + { + SetGlobalError( + Error(EGL_BAD_ATTRIBUTE, + "EGL_PLATFORM_ANGLE_DEVICE_TYPE_WARP_ANGLE requires a device type of " + "EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE.")); + return EGL_NO_DISPLAY; + } - switch (curAttrib[1]) - { - case EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE: - case EGL_PLATFORM_ANGLE_DEVICE_TYPE_WARP_ANGLE: - case EGL_PLATFORM_ANGLE_DEVICE_TYPE_REFERENCE_ANGLE: - case EGL_PLATFORM_ANGLE_DEVICE_TYPE_NULL_ANGLE: - break; + if (enableAutoTrimSpecified && platformType != EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE) + { + SetGlobalError( + Error(EGL_BAD_ATTRIBUTE, + "EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE requires a device type of " + "EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE.")); + return EGL_NO_DISPLAY; + } - default: - SetGlobalError(Error(EGL_BAD_ATTRIBUTE)); - return EGL_NO_DISPLAY; - } - deviceType = curAttrib[1]; - break; + if (presentPathSpecified && platformType != EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE) + { + SetGlobalError(Error(EGL_BAD_ATTRIBUTE, + "EGL_EXPERIMENTAL_PRESENT_PATH_ANGLE requires a device type of " + "EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE.")); + return EGL_NO_DISPLAY; + } - default: - break; - } + if (deviceTypeSpecified && platformType != EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE && + platformType != EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE) + { + SetGlobalError( + Error(EGL_BAD_ATTRIBUTE, + "EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE requires a device type of " + "EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE or EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE.")); + return EGL_NO_DISPLAY; } - } - if (!majorVersionSpecified && minorVersionSpecified) - { - SetGlobalError(Error(EGL_BAD_ATTRIBUTE)); - return EGL_NO_DISPLAY; + SetGlobalError(Error(EGL_SUCCESS)); + return Display::GetDisplayFromAttribs(native_display, + AttributeMap::CreateFromIntArray(attrib_list)); } - - if (deviceType == EGL_PLATFORM_ANGLE_DEVICE_TYPE_WARP_ANGLE && - platformType != EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE) + else if (platform == EGL_PLATFORM_DEVICE_EXT) { - SetGlobalError(Error(EGL_BAD_ATTRIBUTE, "EGL_PLATFORM_ANGLE_DEVICE_TYPE_WARP_ANGLE requires a device type of " - "EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE.")); - return EGL_NO_DISPLAY; - } + Device *eglDevice = reinterpret_cast(native_display); + if (eglDevice == nullptr || !Device::IsValidDevice(eglDevice)) + { + SetGlobalError(Error(EGL_BAD_ATTRIBUTE, + "native_display should be a valid EGL device if platform equals " + "EGL_PLATFORM_DEVICE_EXT")); + return EGL_NO_DISPLAY; + } - if (enableAutoTrimSpecified && - platformType != EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE) + SetGlobalError(Error(EGL_SUCCESS)); + return Display::GetDisplayFromDevice(native_display); + } + else { - SetGlobalError(Error(EGL_BAD_ATTRIBUTE, "EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE requires a device type of " - "EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE.")); + UNREACHABLE(); return EGL_NO_DISPLAY; } - - SetGlobalError(Error(EGL_SUCCESS)); - - EGLNativeDisplayType displayId = static_cast(native_display); - return Display::getDisplay(displayId, AttributeMap(attrib_list)); } // EGL_EXT_device_query @@ -276,34 +358,31 @@ EGLBoolean EGLAPIENTRY QueryDeviceAttribEXT(EGLDeviceEXT device, EGLint attribut device, attribute, value); Device *dev = static_cast(device); - if (dev == EGL_NO_DEVICE_EXT) + if (dev == EGL_NO_DEVICE_EXT || !Device::IsValidDevice(dev)) { SetGlobalError(Error(EGL_BAD_ACCESS)); return EGL_FALSE; } - Display *display = dev->getDisplay(); - Error error(EGL_SUCCESS); - - if (!display->getExtensions().deviceQuery) + // If the device was created by (and is owned by) a display, and that display doesn't support + // device querying, then this call should fail + Display *owningDisplay = dev->getOwningDisplay(); + if (owningDisplay != nullptr && !owningDisplay->getExtensions().deviceQuery) { - SetGlobalError(Error(EGL_BAD_ACCESS)); + SetGlobalError(Error(EGL_BAD_ACCESS, + "Device wasn't created using eglCreateDeviceANGLE, and the Display " + "that created it doesn't support device querying")); return EGL_FALSE; } + Error error(EGL_SUCCESS); + // validate the attribute parameter switch (attribute) { case EGL_D3D11_DEVICE_ANGLE: - if (!dev->getExtensions().deviceD3D || dev->getType() != EGL_D3D11_DEVICE_ANGLE) - { - SetGlobalError(Error(EGL_BAD_ATTRIBUTE)); - return EGL_FALSE; - } - error = dev->getDevice(value); - break; case EGL_D3D9_DEVICE_ANGLE: - if (!dev->getExtensions().deviceD3D || dev->getType() != EGL_D3D9_DEVICE_ANGLE) + if (!dev->getExtensions().deviceD3D || dev->getType() != attribute) { SetGlobalError(Error(EGL_BAD_ATTRIBUTE)); return EGL_FALSE; @@ -326,7 +405,7 @@ const char * EGLAPIENTRY QueryDeviceStringEXT(EGLDeviceEXT device, EGLint name) device, name); Device *dev = static_cast(device); - if (dev == EGL_NO_DEVICE_EXT) + if (dev == EGL_NO_DEVICE_EXT || !Device::IsValidDevice(dev)) { SetGlobalError(Error(EGL_BAD_DEVICE_EXT)); return nullptr; @@ -378,4 +457,379 @@ EGLBoolean EGLAPIENTRY QueryDisplayAttribEXT(EGLDisplay dpy, EGLint attribute, E return (error.isError() ? EGL_FALSE : EGL_TRUE); } +ANGLE_EXPORT EGLImageKHR EGLAPIENTRY CreateImageKHR(EGLDisplay dpy, + EGLContext ctx, + EGLenum target, + EGLClientBuffer buffer, + const EGLint *attrib_list) +{ + EVENT( + "(EGLDisplay dpy = 0x%0.8p, EGLContext ctx = 0x%0.8p, EGLenum target = 0x%X, " + "EGLClientBuffer buffer = 0x%0.8p, const EGLAttrib *attrib_list = 0x%0.8p)", + dpy, ctx, target, buffer, attrib_list); + + Display *display = static_cast(dpy); + gl::Context *context = static_cast(ctx); + AttributeMap attributes = AttributeMap::CreateFromIntArray(attrib_list); + + Error error = ValidateCreateImageKHR(display, context, target, buffer, attributes); + if (error.isError()) + { + SetGlobalError(error); + return EGL_NO_IMAGE; + } + + Image *image = nullptr; + error = display->createImage(context, target, buffer, attributes, &image); + if (error.isError()) + { + SetGlobalError(error); + return EGL_NO_IMAGE; + } + + return static_cast(image); +} + +ANGLE_EXPORT EGLBoolean EGLAPIENTRY DestroyImageKHR(EGLDisplay dpy, EGLImageKHR image) +{ + EVENT("(EGLDisplay dpy = 0x%0.8p, EGLImage image = 0x%0.8p)", dpy, image); + + Display *display = static_cast(dpy); + Image *img = static_cast(image); + + Error error = ValidateDestroyImageKHR(display, img); + if (error.isError()) + { + SetGlobalError(error); + return EGL_FALSE; + } + + display->destroyImage(img); + + return EGL_TRUE; +} + +ANGLE_EXPORT EGLDeviceEXT EGLAPIENTRY CreateDeviceANGLE(EGLint device_type, + void *native_device, + const EGLAttrib *attrib_list) +{ + EVENT( + "(EGLint device_type = %d, void* native_device = 0x%0.8p, const EGLAttrib* attrib_list = " + "0x%0.8p)", + device_type, native_device, attrib_list); + + Error error = ValidateCreateDeviceANGLE(device_type, native_device, attrib_list); + if (error.isError()) + { + SetGlobalError(error); + return EGL_NO_DEVICE_EXT; + } + + Device *device = nullptr; + error = Device::CreateDevice(native_device, device_type, &device); + if (error.isError()) + { + ASSERT(device == nullptr); + SetGlobalError(error); + return EGL_NO_DEVICE_EXT; + } + + return device; +} + +ANGLE_EXPORT EGLBoolean EGLAPIENTRY ReleaseDeviceANGLE(EGLDeviceEXT device) +{ + EVENT("(EGLDeviceEXT device = 0x%0.8p)", device); + + Device *dev = static_cast(device); + + Error error = ValidateReleaseDeviceANGLE(dev); + if (error.isError()) + { + SetGlobalError(error); + return EGL_FALSE; + } + + SafeDelete(dev); + + return EGL_TRUE; +} + +// EGL_KHR_stream +EGLStreamKHR EGLAPIENTRY CreateStreamKHR(EGLDisplay dpy, const EGLint *attrib_list) +{ + EVENT("(EGLDisplay dpy = 0x%0.8p, const EGLAttrib* attrib_list = 0x%0.8p)", dpy, attrib_list); + + Display *display = static_cast(dpy); + AttributeMap attributes = AttributeMap::CreateFromIntArray(attrib_list); + + Error error = ValidateCreateStreamKHR(display, attributes); + if (error.isError()) + { + SetGlobalError(error); + return EGL_NO_STREAM_KHR; + } + + Stream *stream; + error = display->createStream(attributes, &stream); + if (error.isError()) + { + SetGlobalError(error); + return EGL_NO_STREAM_KHR; + } + + SetGlobalError(error); + return static_cast(stream); +} + +EGLBoolean EGLAPIENTRY DestroyStreamKHR(EGLDisplay dpy, EGLStreamKHR stream) +{ + EVENT("(EGLDisplay dpy = 0x%0.8p, EGLStreamKHR = 0x%0.8p)", dpy, stream); + + Display *display = static_cast(dpy); + Stream *streamObject = static_cast(stream); + + Error error = ValidateDestroyStreamKHR(display, streamObject); + if (error.isError()) + { + SetGlobalError(error); + return EGL_FALSE; + } + + display->destroyStream(streamObject); + SetGlobalError(error); + return EGL_TRUE; +} + +EGLBoolean EGLAPIENTRY StreamAttribKHR(EGLDisplay dpy, + EGLStreamKHR stream, + EGLenum attribute, + EGLint value) +{ + EVENT( + "(EGLDisplay dpy = 0x%0.8p, EGLStreamKHR stream = 0x%0.8p, EGLenum attribute = 0x%X, " + "EGLint value = 0x%X)", + dpy, stream, attribute, value); + + Display *display = static_cast(dpy); + Stream *streamObject = static_cast(stream); + + Error error = ValidateStreamAttribKHR(display, streamObject, attribute, value); + if (error.isError()) + { + SetGlobalError(error); + return EGL_FALSE; + } + + switch (attribute) + { + case EGL_CONSUMER_LATENCY_USEC_KHR: + streamObject->setConsumerLatency(value); + break; + case EGL_CONSUMER_ACQUIRE_TIMEOUT_USEC_KHR: + streamObject->setConsumerAcquireTimeout(value); + break; + default: + UNREACHABLE(); + } + + SetGlobalError(error); + return EGL_TRUE; +} + +EGLBoolean EGLAPIENTRY QueryStreamKHR(EGLDisplay dpy, + EGLStreamKHR stream, + EGLenum attribute, + EGLint *value) +{ + EVENT( + "(EGLDisplay dpy = 0x%0.8p, EGLStreamKHR stream = 0x%0.8p, EGLenum attribute = 0x%X, " + "EGLint value = 0x%0.8p)", + dpy, stream, attribute, value); + + Display *display = static_cast(dpy); + Stream *streamObject = static_cast(stream); + + Error error = ValidateQueryStreamKHR(display, streamObject, attribute, value); + if (error.isError()) + { + SetGlobalError(error); + return EGL_FALSE; + } + + switch (attribute) + { + case EGL_STREAM_STATE_KHR: + *value = streamObject->getState(); + break; + case EGL_CONSUMER_LATENCY_USEC_KHR: + *value = streamObject->getConsumerLatency(); + break; + case EGL_CONSUMER_ACQUIRE_TIMEOUT_USEC_KHR: + *value = streamObject->getConsumerAcquireTimeout(); + break; + default: + UNREACHABLE(); + } + + SetGlobalError(error); + return EGL_TRUE; +} + +EGLBoolean EGLAPIENTRY QueryStreamu64KHR(EGLDisplay dpy, + EGLStreamKHR stream, + EGLenum attribute, + EGLuint64KHR *value) +{ + EVENT( + "(EGLDisplay dpy = 0x%0.8p, EGLStreamKHR stream = 0x%0.8p, EGLenum attribute = 0x%X, " + "EGLuint64KHR value = 0x%0.8p)", + dpy, stream, attribute, value); + + Display *display = static_cast(dpy); + Stream *streamObject = static_cast(stream); + + Error error = ValidateQueryStreamu64KHR(display, streamObject, attribute, value); + if (error.isError()) + { + SetGlobalError(error); + return EGL_FALSE; + } + + switch (attribute) + { + case EGL_PRODUCER_FRAME_KHR: + *value = streamObject->getProducerFrame(); + break; + case EGL_CONSUMER_FRAME_KHR: + *value = streamObject->getConsumerFrame(); + break; + default: + UNREACHABLE(); + } + + SetGlobalError(error); + return EGL_TRUE; +} + +EGLBoolean EGLAPIENTRY StreamConsumerGLTextureExternalKHR(EGLDisplay dpy, EGLStreamKHR stream) +{ + EVENT("(EGLDisplay dpy = 0x%0.8p, EGLStreamKHR = 0x%0.8p)", dpy, stream); + Display *display = static_cast(dpy); + Stream *streamObject = static_cast(stream); + gl::Context *context = gl::GetValidGlobalContext(); + + Error error = ValidateStreamConsumerGLTextureExternalKHR(display, context, streamObject); + if (error.isError()) + { + SetGlobalError(error); + return EGL_FALSE; + } + SetGlobalError(error); + return EGL_FALSE; +} + +EGLBoolean EGLAPIENTRY StreamConsumerAcquireKHR(EGLDisplay dpy, EGLStreamKHR stream) +{ + EVENT("(EGLDisplay dpy = 0x%0.8p, EGLStreamKHR = 0x%0.8p)", dpy, stream); + Display *display = static_cast(dpy); + Stream *streamObject = static_cast(stream); + gl::Context *context = gl::GetValidGlobalContext(); + + Error error = ValidateStreamConsumerAcquireKHR(display, context, streamObject); + if (error.isError()) + { + SetGlobalError(error); + return EGL_FALSE; + } + SetGlobalError(error); + return EGL_FALSE; +} + +EGLBoolean EGLAPIENTRY StreamConsumerReleaseKHR(EGLDisplay dpy, EGLStreamKHR stream) +{ + EVENT("(EGLDisplay dpy = 0x%0.8p, EGLStreamKHR = 0x%0.8p)", dpy, stream); + Display *display = static_cast(dpy); + Stream *streamObject = static_cast(stream); + gl::Context *context = gl::GetValidGlobalContext(); + + Error error = ValidateStreamConsumerReleaseKHR(display, context, streamObject); + if (error.isError()) + { + SetGlobalError(error); + return EGL_FALSE; + } + SetGlobalError(error); + return EGL_FALSE; +} + +EGLBoolean EGLAPIENTRY StreamConsumerGLTextureExternalAttribsNV(EGLDisplay dpy, + EGLStreamKHR stream, + const EGLAttrib *attrib_list) +{ + EVENT( + "(EGLDisplay dpy = 0x%0.8p, EGLStreamKHR stream = 0x%0.8p, EGLAttrib attrib_list = 0x%0.8p", + dpy, stream, attrib_list); + Display *display = static_cast(dpy); + Stream *streamObject = static_cast(stream); + gl::Context *context = gl::GetValidGlobalContext(); + AttributeMap attributes = AttributeMap::CreateFromAttribArray(attrib_list); + + Error error = ValidateStreamConsumerGLTextureExternalAttribsNV(display, context, streamObject, + attributes); + if (error.isError()) + { + SetGlobalError(error); + return EGL_FALSE; + } + SetGlobalError(error); + return EGL_FALSE; +} + +EGLBoolean EGLAPIENTRY CreateStreamProducerD3DTextureNV12ANGLE(EGLDisplay dpy, + EGLStreamKHR stream, + const EGLAttrib *attrib_list) +{ + EVENT( + "(EGLDisplay dpy = 0x%0.8p, EGLStreamKHR stream = 0x%0.8p, EGLAttrib attrib_list = 0x%0.8p", + dpy, stream, attrib_list); + Display *display = static_cast(dpy); + Stream *streamObject = static_cast(stream); + AttributeMap attributes = AttributeMap::CreateFromAttribArray(attrib_list); + + Error error = + ValidateCreateStreamProducerD3DTextureNV12ANGLE(display, streamObject, attributes); + if (error.isError()) + { + SetGlobalError(error); + return EGL_FALSE; + } + + SetGlobalError(error); + return EGL_FALSE; +} + +EGLBoolean EGLAPIENTRY StreamPostD3DTextureNV12ANGLE(EGLDisplay dpy, + EGLStreamKHR stream, + void *texture, + const EGLAttrib *attrib_list) +{ + EVENT( + "(EGLDisplay dpy = 0x%0.8p, EGLStreamKHR stream = 0x%0.8p, void* texture = 0x%0.8p, " + "EGLAttrib attrib_list = 0x%0.8p", + dpy, stream, texture, attrib_list); + Display *display = static_cast(dpy); + Stream *streamObject = static_cast(stream); + AttributeMap attributes = AttributeMap::CreateFromAttribArray(attrib_list); + + Error error = ValidateStreamPostD3DTextureNV12ANGLE(display, streamObject, texture, attributes); + if (error.isError()) + { + SetGlobalError(error); + return EGL_FALSE; + } + + SetGlobalError(error); + return EGL_FALSE; +} } diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/entry_points_egl_ext.h b/Source/ThirdParty/ANGLE/src/libGLESv2/entry_points_egl_ext.h index 557470dd4311..4ec0450bfcb9 100644 --- a/Source/ThirdParty/ANGLE/src/libGLESv2/entry_points_egl_ext.h +++ b/Source/ThirdParty/ANGLE/src/libGLESv2/entry_points_egl_ext.h @@ -30,6 +30,55 @@ ANGLE_EXPORT EGLBoolean EGLAPIENTRY QueryDisplayAttribEXT(EGLDisplay dpy, EGLint ANGLE_EXPORT EGLBoolean EGLAPIENTRY QueryDeviceAttribEXT(EGLDeviceEXT device, EGLint attribute, EGLAttrib *value); ANGLE_EXPORT const char * EGLAPIENTRY QueryDeviceStringEXT(EGLDeviceEXT device, EGLint name); -} +// EGL_KHR_image_base/EGL_KHR_image +ANGLE_EXPORT EGLImageKHR EGLAPIENTRY CreateImageKHR(EGLDisplay dpy, + EGLContext ctx, + EGLenum target, + EGLClientBuffer buffer, + const EGLint *attrib_list); +ANGLE_EXPORT EGLBoolean EGLAPIENTRY DestroyImageKHR(EGLDisplay dpy, EGLImageKHR image); + +// EGL_EXT_device_creation +ANGLE_EXPORT EGLDeviceEXT EGLAPIENTRY CreateDeviceANGLE(EGLint device_type, + void *native_device, + const EGLAttrib *attrib_list); +ANGLE_EXPORT EGLBoolean EGLAPIENTRY ReleaseDeviceANGLE(EGLDeviceEXT device); + +// EGL_KHR_stream +ANGLE_EXPORT EGLStreamKHR EGLAPIENTRY CreateStreamKHR(EGLDisplay dpy, const EGLint *attrib_list); +ANGLE_EXPORT EGLBoolean EGLAPIENTRY DestroyStreamKHR(EGLDisplay dpy, EGLStreamKHR stream); +ANGLE_EXPORT EGLBoolean EGLAPIENTRY StreamAttribKHR(EGLDisplay dpy, + EGLStreamKHR stream, + EGLenum attribute, + EGLint value); +ANGLE_EXPORT EGLBoolean EGLAPIENTRY QueryStreamKHR(EGLDisplay dpy, + EGLStreamKHR stream, + EGLenum attribute, + EGLint *value); +ANGLE_EXPORT EGLBoolean EGLAPIENTRY QueryStreamu64KHR(EGLDisplay dpy, + EGLStreamKHR stream, + EGLenum attribute, + EGLuint64KHR *value); + +// EGL_KHR_stream_consumer_gltexture +ANGLE_EXPORT EGLBoolean EGLAPIENTRY StreamConsumerGLTextureExternalKHR(EGLDisplay dpy, + EGLStreamKHR stream); +ANGLE_EXPORT EGLBoolean EGLAPIENTRY StreamConsumerAcquireKHR(EGLDisplay dpy, EGLStreamKHR stream); +ANGLE_EXPORT EGLBoolean EGLAPIENTRY StreamConsumerReleaseKHR(EGLDisplay dpy, EGLStreamKHR stream); +ANGLE_EXPORT EGLBoolean EGLAPIENTRY +StreamConsumerGLTextureExternalAttribsNV(EGLDisplay dpy, + EGLStreamKHR stream, + const EGLAttrib *attrib_list); + +// EGL_ANGLE_stream_producer_d3d_texture_nv12 +ANGLE_EXPORT EGLBoolean EGLAPIENTRY +CreateStreamProducerD3DTextureNV12ANGLE(EGLDisplay dpy, + EGLStreamKHR stream, + const EGLAttrib *attrib_list); +ANGLE_EXPORT EGLBoolean EGLAPIENTRY StreamPostD3DTextureNV12ANGLE(EGLDisplay dpy, + EGLStreamKHR stream, + void *texture, + const EGLAttrib *attrib_list); +} // namespace egl #endif // LIBGLESV2_ENTRYPOINTSEGLEXT_H_ diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/entry_points_gles_2_0.cpp b/Source/ThirdParty/ANGLE/src/libGLESv2/entry_points_gles_2_0.cpp index 08c7b5b83698..b48bf46deb3f 100644 --- a/Source/ThirdParty/ANGLE/src/libGLESv2/entry_points_gles_2_0.cpp +++ b/Source/ThirdParty/ANGLE/src/libGLESv2/entry_points_gles_2_0.cpp @@ -59,35 +59,16 @@ void GL_APIENTRY AttachShader(GLuint program, GLuint shader) Context *context = GetValidGlobalContext(); if (context) { - Program *programObject = context->getProgram(program); - Shader *shaderObject = context->getShader(shader); - + Program *programObject = GetValidProgram(context, program); if (!programObject) { - if (context->getShader(program)) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - else - { - context->recordError(Error(GL_INVALID_VALUE)); - return; - } + return; } + Shader *shaderObject = GetValidShader(context, shader); if (!shaderObject) { - if (context->getProgram(shader)) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - else - { - context->recordError(Error(GL_INVALID_VALUE)); - return; - } + return; } if (!programObject->attachShader(shaderObject)) @@ -111,20 +92,11 @@ void GL_APIENTRY BindAttribLocation(GLuint program, GLuint index, const GLchar* return; } - Program *programObject = context->getProgram(program); + Program *programObject = GetValidProgram(context, program); if (!programObject) { - if (context->getShader(program)) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - else - { - context->recordError(Error(GL_INVALID_VALUE)); - return; - } + return; } if (strncmp(name, "gl_", 3) == 0) @@ -233,31 +205,8 @@ void GL_APIENTRY BindTexture(GLenum target, GLuint texture) Context *context = GetValidGlobalContext(); if (context) { - Texture *textureObject = context->getTexture(texture); - - if (textureObject && textureObject->getTarget() != target && texture != 0) + if (!ValidateBindTexture(context, target, texture)) { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - - switch (target) - { - case GL_TEXTURE_2D: - case GL_TEXTURE_CUBE_MAP: - break; - - case GL_TEXTURE_3D: - case GL_TEXTURE_2D_ARRAY: - if (context->getClientVersion() < 3) - { - context->recordError(Error(GL_INVALID_ENUM)); - return; - } - break; - - default: - context->recordError(Error(GL_INVALID_ENUM)); return; } @@ -444,17 +393,25 @@ void GL_APIENTRY BlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha return; } - bool constantColorUsed = (srcRGB == GL_CONSTANT_COLOR || srcRGB == GL_ONE_MINUS_CONSTANT_COLOR || - dstRGB == GL_CONSTANT_COLOR || dstRGB == GL_ONE_MINUS_CONSTANT_COLOR); + if (context->getLimitations().noSimultaneousConstantColorAndAlphaBlendFunc) + { + 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); + 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) - { - ERR("Simultaneous use of GL_CONSTANT_ALPHA/GL_ONE_MINUS_CONSTANT_ALPHA and GL_CONSTANT_COLOR/GL_ONE_MINUS_CONSTANT_COLOR invalid under WebGL"); - context->recordError(Error(GL_INVALID_OPERATION)); - return; + if (constantColorUsed && constantAlphaUsed) + { + ERR( + "Simultaneous use of GL_CONSTANT_ALPHA/GL_ONE_MINUS_CONSTANT_ALPHA and " + "GL_CONSTANT_COLOR/GL_ONE_MINUS_CONSTANT_COLOR not supported by this " + "implementation."); + context->recordError(Error(GL_INVALID_OPERATION)); + return; + } } context->getState().setBlendFactors(srcRGB, dstRGB, srcAlpha, dstAlpha); @@ -613,27 +570,12 @@ void GL_APIENTRY Clear(GLbitfield mask) Context *context = GetValidGlobalContext(); if (context) { - Framebuffer *framebufferObject = context->getState().getDrawFramebuffer(); - ASSERT(framebufferObject); - - if (framebufferObject->checkStatus(context->getData()) != GL_FRAMEBUFFER_COMPLETE) - { - context->recordError(Error(GL_INVALID_FRAMEBUFFER_OPERATION)); - return; - } - - if ((mask & ~(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) != 0) + if (!context->skipValidation() && !ValidateClear(context, mask)) { - context->recordError(Error(GL_INVALID_VALUE)); return; } - Error error = framebufferObject->clear(context->getData(), mask); - if (error.isError()) - { - context->recordError(error); - return; - } + context->clear(mask); } } @@ -690,22 +632,11 @@ void GL_APIENTRY CompileShader(GLuint shader) Context *context = GetValidGlobalContext(); if (context) { - Shader *shaderObject = context->getShader(shader); - + Shader *shaderObject = GetValidShader(context, shader); if (!shaderObject) { - if (context->getProgram(shader)) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - else - { - context->recordError(Error(GL_INVALID_VALUE)); - return; - } + return; } - shaderObject->compile(context->getCompiler()); } } @@ -720,36 +651,15 @@ void GL_APIENTRY CompressedTexImage2D(GLenum target, GLint level, GLenum interna Context *context = GetValidGlobalContext(); if (context) { - if (context->getClientVersion() < 3 && - !ValidateES2TexImageParameters(context, target, level, internalformat, true, false, - 0, 0, width, height, border, GL_NONE, GL_NONE, data)) + if (!context->skipValidation() && + !ValidateCompressedTexImage2D(context, target, level, internalformat, width, height, + border, imageSize, data)) { return; } - if (context->getClientVersion() >= 3 && - !ValidateES3TexImageParameters(context, target, level, internalformat, true, false, - 0, 0, 0, width, height, 1, border, GL_NONE, GL_NONE, data)) - { - return; - } - - const InternalFormat &formatInfo = GetInternalFormatInfo(internalformat); - if (imageSize < 0 || static_cast(imageSize) != formatInfo.computeBlockSize(GL_UNSIGNED_BYTE, width, height)) - { - context->recordError(Error(GL_INVALID_VALUE)); - return; - } - - Extents size(width, height, 1); - Texture *texture = context->getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target); - Error error = texture->setCompressedImage(target, level, internalformat, size, context->getState().getUnpackState(), - reinterpret_cast(data)); - if (error.isError()) - { - context->recordError(error); - return; - } + context->compressedTexImage2D(target, level, internalformat, width, height, border, + imageSize, data); } } @@ -764,37 +674,15 @@ void GL_APIENTRY CompressedTexSubImage2D(GLenum target, GLint level, GLint xoffs Context *context = GetValidGlobalContext(); if (context) { - if (context->getClientVersion() < 3 && - !ValidateES2TexImageParameters(context, target, level, GL_NONE, true, true, - xoffset, yoffset, width, height, 0, GL_NONE, GL_NONE, data)) - { - return; - } - - if (context->getClientVersion() >= 3 && - !ValidateES3TexImageParameters(context, target, level, GL_NONE, true, true, - xoffset, yoffset, 0, width, height, 1, 0, GL_NONE, GL_NONE, data)) + if (!context->skipValidation() && + !ValidateCompressedTexSubImage2D(context, target, level, xoffset, yoffset, width, + height, format, imageSize, data)) { return; } - const InternalFormat &formatInfo = GetInternalFormatInfo(format); - if (imageSize < 0 || static_cast(imageSize) != formatInfo.computeBlockSize(GL_UNSIGNED_BYTE, width, height)) - { - context->recordError(Error(GL_INVALID_VALUE)); - return; - } - - - Box area(xoffset, yoffset, 0, width, height, 1); - Texture *texture = context->getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target); - Error error = texture->setCompressedSubImage(target, level, area, format, context->getState().getUnpackState(), - reinterpret_cast(data)); - if (error.isError()) - { - context->recordError(error); - return; - } + context->compressedTexSubImage2D(target, level, xoffset, yoffset, width, height, format, + imageSize, data); } } @@ -807,30 +695,13 @@ void GL_APIENTRY CopyTexImage2D(GLenum target, GLint level, GLenum internalforma Context *context = GetValidGlobalContext(); if (context) { - if (context->getClientVersion() < 3 && - !ValidateES2CopyTexImageParameters(context, target, level, internalformat, false, - 0, 0, x, y, width, height, border)) - { - return; - } - - if (context->getClientVersion() >= 3 && - !ValidateES3CopyTexImageParameters(context, target, level, internalformat, false, - 0, 0, 0, x, y, width, height, border)) + if (!context->skipValidation() && + !ValidateCopyTexImage2D(context, target, level, internalformat, x, y, width, height, + border)) { return; } - - Rectangle sourceArea(x, y, width, height); - - const Framebuffer *framebuffer = context->getState().getReadFramebuffer(); - Texture *texture = context->getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target); - Error error = texture->copyImage(target, level, sourceArea, internalformat, framebuffer); - if (error.isError()) - { - context->recordError(error); - return; - } + context->copyTexImage2D(target, level, internalformat, x, y, width, height, border); } } @@ -843,31 +714,14 @@ void GL_APIENTRY CopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GL Context *context = GetValidGlobalContext(); if (context) { - if (context->getClientVersion() < 3 && - !ValidateES2CopyTexImageParameters(context, target, level, GL_NONE, true, - xoffset, yoffset, x, y, width, height, 0)) - { - return; - } - - if (context->getClientVersion() >= 3 && - !ValidateES3CopyTexImageParameters(context, target, level, GL_NONE, true, - xoffset, yoffset, 0, x, y, width, height, 0)) + if (!context->skipValidation() && + !ValidateCopyTexSubImage2D(context, target, level, xoffset, yoffset, x, y, width, + height)) { return; } - Offset destOffset(xoffset, yoffset, 0); - Rectangle sourceArea(x, y, width, height); - - const Framebuffer *framebuffer = context->getState().getReadFramebuffer(); - Texture *texture = context->getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target); - Error error = texture->copySubImage(target, level, destOffset, sourceArea, framebuffer); - if (error.isError()) - { - context->recordError(error); - return; - } + context->copyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height); } } @@ -936,9 +790,8 @@ void GL_APIENTRY DeleteBuffers(GLsizei n, const GLuint* buffers) Context *context = GetValidGlobalContext(); if (context) { - if (n < 0) + if (!context->skipValidation() && !ValidateDeleteBuffers(context, n, buffers)) { - context->recordError(Error(GL_INVALID_VALUE)); return; } @@ -956,9 +809,8 @@ void GL_APIENTRY DeleteFramebuffers(GLsizei n, const GLuint* framebuffers) Context *context = GetValidGlobalContext(); if (context) { - if (n < 0) + if (!context->skipValidation() && !ValidateDeleteFramebuffers(context, n, framebuffers)) { - context->recordError(Error(GL_INVALID_VALUE)); return; } @@ -1009,9 +861,8 @@ void GL_APIENTRY DeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers) Context *context = GetValidGlobalContext(); if (context) { - if (n < 0) + if (!context->skipValidation() && !ValidateDeleteRenderbuffers(context, n, renderbuffers)) { - context->recordError(Error(GL_INVALID_VALUE)); return; } @@ -1059,9 +910,8 @@ void GL_APIENTRY DeleteTextures(GLsizei n, const GLuint* textures) Context *context = GetValidGlobalContext(); if (context) { - if (n < 0) + if (!context->skipValidation() && !ValidateDeleteTextures(context, n, textures)) { - context->recordError(Error(GL_INVALID_VALUE)); return; } @@ -1131,38 +981,16 @@ void GL_APIENTRY DetachShader(GLuint program, GLuint shader) Context *context = GetValidGlobalContext(); if (context) { - Program *programObject = context->getProgram(program); - Shader *shaderObject = context->getShader(shader); - + Program *programObject = GetValidProgram(context, program); if (!programObject) { - Shader *shaderByProgramHandle; - shaderByProgramHandle = context->getShader(program); - if (!shaderByProgramHandle) - { - context->recordError(Error(GL_INVALID_VALUE)); - return; - } - else - { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } + return; } + Shader *shaderObject = GetValidShader(context, shader); if (!shaderObject) { - Program *programByShaderHandle = context->getProgram(shader); - if (!programByShaderHandle) - { - context->recordError(Error(GL_INVALID_VALUE)); - return; - } - else - { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } + return; } if (!programObject->detachShader(shaderObject)) @@ -1219,7 +1047,7 @@ void GL_APIENTRY DrawArrays(GLenum mode, GLint first, GLsizei count) return; } - Error error = context->drawArrays(mode, first, count, 0); + Error error = context->drawArrays(mode, first, count); if (error.isError()) { context->recordError(error); @@ -1236,13 +1064,13 @@ void GL_APIENTRY DrawElements(GLenum mode, GLsizei count, GLenum type, const GLv Context *context = GetValidGlobalContext(); if (context) { - rx::RangeUI indexRange; + IndexRange indexRange; if (!ValidateDrawElements(context, mode, count, type, indices, 0, &indexRange)) { return; } - Error error = context->drawElements(mode, count, type, indices, 0, indexRange); + Error error = context->drawElements(mode, count, type, indices, indexRange); if (error.isError()) { context->recordError(error); @@ -1264,6 +1092,20 @@ void GL_APIENTRY Enable(GLenum cap) return; } + if (context->getLimitations().noSampleAlphaToCoverageSupport) + { + if (cap == GL_SAMPLE_ALPHA_TO_COVERAGE) + { + const char *errorMessage = "Current renderer doesn't support alpha-to-coverage"; + context->recordError(Error(GL_INVALID_OPERATION, errorMessage)); + + // We also output an error message to the debugger window if tracing is active, so that developers can see the error message. + ERR("%s", errorMessage); + + return; + } + } + context->getState().setEnableFeature(cap, true); } } @@ -1325,29 +1167,14 @@ void GL_APIENTRY FramebufferRenderbuffer(GLenum target, GLenum attachment, GLenu Context *context = GetValidGlobalContext(); if (context) { - if (!ValidFramebufferTarget(target) || (renderbuffertarget != GL_RENDERBUFFER && renderbuffer != 0)) - { - context->recordError(Error(GL_INVALID_ENUM)); - return; - } - - if (!ValidateFramebufferRenderbufferParameters(context, target, attachment, renderbuffertarget, renderbuffer)) + if (!context->skipValidation() && + !ValidateFramebufferRenderbuffer(context, target, attachment, renderbuffertarget, + renderbuffer)) { return; } - Framebuffer *framebuffer = context->getState().getTargetFramebuffer(target); - ASSERT(framebuffer); - - if (renderbuffer != 0) - { - Renderbuffer *renderbufferObject = context->getRenderbuffer(renderbuffer); - framebuffer->setAttachment(GL_RENDERBUFFER, attachment, gl::ImageIndex::MakeInvalid(), renderbufferObject); - } - else - { - framebuffer->resetAttachment(attachment); - } + context->framebufferRenderbuffer(target, attachment, renderbuffertarget, renderbuffer); } } @@ -1359,36 +1186,13 @@ void GL_APIENTRY FramebufferTexture2D(GLenum target, GLenum attachment, GLenum t Context *context = GetValidGlobalContext(); if (context) { - if (!ValidateFramebufferTexture2D(context, target, attachment, textarget, texture, level)) + if (!context->skipValidation() && + !ValidateFramebufferTexture2D(context, target, attachment, textarget, texture, level)) { return; } - Framebuffer *framebuffer = context->getState().getTargetFramebuffer(target); - ASSERT(framebuffer); - - if (texture != 0) - { - Texture *textureObj = context->getTexture(texture); - - ImageIndex index = ImageIndex::MakeInvalid(); - - if (textarget == GL_TEXTURE_2D) - { - index = ImageIndex::Make2D(level); - } - else - { - ASSERT(IsCubeMapTextureTarget(textarget)); - index = ImageIndex::MakeCube(textarget, level); - } - - framebuffer->setAttachment(GL_TEXTURE, attachment, index, textureObj); - } - else - { - framebuffer->resetAttachment(attachment); - } + context->framebufferTexture2D(target, attachment, textarget, texture, level); } } @@ -1419,9 +1223,8 @@ void GL_APIENTRY GenBuffers(GLsizei n, GLuint* buffers) Context *context = GetValidGlobalContext(); if (context) { - if (n < 0) + if (!context->skipValidation() && !ValidateGenBuffers(context, n, buffers)) { - context->recordError(Error(GL_INVALID_VALUE)); return; } @@ -1485,7 +1288,9 @@ void GL_APIENTRY GenerateMipmap(GLenum target) } // Non-power of 2 ES2 check - if (!context->getExtensions().textureNPOT && (!isPow2(texture->getWidth(baseTarget, 0)) || !isPow2(texture->getHeight(baseTarget, 0)))) + if (!context->getExtensions().textureNPOT && + (!isPow2(static_cast(texture->getWidth(baseTarget, 0))) || + !isPow2(static_cast(texture->getHeight(baseTarget, 0))))) { ASSERT(context->getClientVersion() <= 2 && (target == GL_TEXTURE_2D || target == GL_TEXTURE_CUBE_MAP)); context->recordError(Error(GL_INVALID_OPERATION)); @@ -1515,9 +1320,8 @@ void GL_APIENTRY GenFramebuffers(GLsizei n, GLuint* framebuffers) Context *context = GetValidGlobalContext(); if (context) { - if (n < 0) + if (!context->skipValidation() && !ValidateGenFramebuffers(context, n, framebuffers)) { - context->recordError(Error(GL_INVALID_VALUE)); return; } @@ -1535,9 +1339,8 @@ void GL_APIENTRY GenRenderbuffers(GLsizei n, GLuint* renderbuffers) Context *context = GetValidGlobalContext(); if (context) { - if (n < 0) + if (!context->skipValidation() && !ValidateGenRenderbuffers(context, n, renderbuffers)) { - context->recordError(Error(GL_INVALID_VALUE)); return; } @@ -1555,9 +1358,8 @@ void GL_APIENTRY GenTextures(GLsizei n, GLuint* textures) Context *context = GetValidGlobalContext(); if (context) { - if (n < 0) + if (!context->skipValidation() && !ValidateGenTextures(context, n, textures)) { - context->recordError(Error(GL_INVALID_VALUE)); return; } @@ -1583,20 +1385,11 @@ void GL_APIENTRY GetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, return; } - Program *programObject = context->getProgram(program); + Program *programObject = GetValidProgram(context, program); if (!programObject) { - if (context->getShader(program)) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - else - { - context->recordError(Error(GL_INVALID_VALUE)); - return; - } + return; } if (index >= (GLuint)programObject->getActiveAttributeCount()) @@ -1625,20 +1418,11 @@ void GL_APIENTRY GetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, return; } - Program *programObject = context->getProgram(program); + Program *programObject = GetValidProgram(context, program); if (!programObject) { - if (context->getShader(program)) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - else - { - context->recordError(Error(GL_INVALID_VALUE)); - return; - } + return; } if (index >= (GLuint)programObject->getActiveUniformCount()) @@ -1665,20 +1449,11 @@ void GL_APIENTRY GetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* c return; } - Program *programObject = context->getProgram(program); + Program *programObject = GetValidProgram(context, program); if (!programObject) { - if (context->getShader(program)) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - else - { - context->recordError(Error(GL_INVALID_VALUE)); - return; - } + return; } return programObject->getAttachedShaders(maxcount, count, shaders); @@ -1692,20 +1467,11 @@ GLint GL_APIENTRY GetAttribLocation(GLuint program, const GLchar* name) Context *context = GetValidGlobalContext(); if (context) { - Program *programObject = context->getProgram(program); + Program *programObject = GetValidProgram(context, program); if (!programObject) { - if (context->getShader(program)) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return -1; - } - else - { - context->recordError(Error(GL_INVALID_VALUE)); - return -1; - } + return -1; } if (!programObject->isLinked()) @@ -1960,7 +1726,7 @@ void GL_APIENTRY GetFramebufferAttachmentParameteriv(GLenum target, GLenum attac break; case GL_DEPTH_STENCIL_ATTACHMENT: - if (framebuffer->hasValidDepthStencil()) + if (!framebuffer->hasValidDepthStencil()) { context->recordError(Error(GL_INVALID_OPERATION)); return; @@ -2138,11 +1904,10 @@ void GL_APIENTRY GetProgramiv(GLuint program, GLenum pname, GLint* params) Context *context = GetValidGlobalContext(); if (context) { - Program *programObject = context->getProgram(program); + Program *programObject = GetValidProgram(context, program); if (!programObject) { - context->recordError(Error(GL_INVALID_VALUE)); return; } @@ -2155,6 +1920,7 @@ void GL_APIENTRY GetProgramiv(GLuint program, GLenum pname, GLint* params) case GL_TRANSFORM_FEEDBACK_BUFFER_MODE: case GL_TRANSFORM_FEEDBACK_VARYINGS: case GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH: + case GL_PROGRAM_BINARY_RETRIEVABLE_HINT: context->recordError(Error(GL_INVALID_ENUM)); return; } @@ -2207,6 +1973,9 @@ void GL_APIENTRY GetProgramiv(GLuint program, GLenum pname, GLint* params) case GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH: *params = programObject->getTransformFeedbackVaryingMaxLength(); break; + case GL_PROGRAM_BINARY_RETRIEVABLE_HINT: + *params = programObject->getBinaryRetrievableHint(); + break; default: context->recordError(Error(GL_INVALID_ENUM)); @@ -2229,11 +1998,9 @@ void GL_APIENTRY GetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* len return; } - Program *programObject = context->getProgram(program); - + Program *programObject = GetValidProgram(context, program); if (!programObject) { - context->recordError(Error(GL_INVALID_VALUE)); return; } @@ -2297,11 +2064,9 @@ void GL_APIENTRY GetShaderiv(GLuint shader, GLenum pname, GLint* params) Context *context = GetValidGlobalContext(); if (context) { - Shader *shaderObject = context->getShader(shader); - + Shader *shaderObject = GetValidShader(context, shader); if (!shaderObject) { - context->recordError(Error(GL_INVALID_VALUE)); return; } @@ -2323,7 +2088,7 @@ void GL_APIENTRY GetShaderiv(GLuint shader, GLenum pname, GLint* params) *params = shaderObject->getSourceLength(); return; case GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE: - *params = shaderObject->getTranslatedSourceLength(); + *params = shaderObject->getTranslatedSourceWithDebugInfoLength(); return; default: @@ -2347,11 +2112,9 @@ void GL_APIENTRY GetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* lengt return; } - Shader *shaderObject = context->getShader(shader); - + Shader *shaderObject = GetValidShader(context, shader); if (!shaderObject) { - context->recordError(Error(GL_INVALID_VALUE)); return; } @@ -2447,11 +2210,9 @@ void GL_APIENTRY GetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length return; } - Shader *shaderObject = context->getShader(shader); - + Shader *shaderObject = GetValidShader(context, shader); if (!shaderObject) { - context->recordError(Error(GL_INVALID_OPERATION)); return; } @@ -2465,44 +2226,50 @@ const GLubyte *GL_APIENTRY GetString(GLenum name) Context *context = GetValidGlobalContext(); - switch (name) + if (context) { - case GL_VENDOR: - return (GLubyte*)"Google Inc."; + switch (name) + { + case GL_VENDOR: + return reinterpret_cast("Google Inc."); - case GL_RENDERER: - return (GLubyte*)((context != NULL) ? context->getRendererString().c_str() : "ANGLE"); + case GL_RENDERER: + return reinterpret_cast(context->getRendererString().c_str()); - case GL_VERSION: - if (context->getClientVersion() == 2) - { - return (GLubyte*)"OpenGL ES 2.0 (ANGLE " ANGLE_VERSION_STRING ")"; - } - else - { - return (GLubyte*)"OpenGL ES 3.0 (ANGLE " ANGLE_VERSION_STRING ")"; - } + case GL_VERSION: + if (context->getClientVersion() == 2) + { + return reinterpret_cast( + "OpenGL ES 2.0 (ANGLE " ANGLE_VERSION_STRING ")"); + } + else + { + return reinterpret_cast( + "OpenGL ES 3.0 (ANGLE " ANGLE_VERSION_STRING ")"); + } - case GL_SHADING_LANGUAGE_VERSION: - if (context->getClientVersion() == 2) - { - return (GLubyte*)"OpenGL ES GLSL ES 1.00 (ANGLE " ANGLE_VERSION_STRING ")"; - } - else - { - return (GLubyte*)"OpenGL ES GLSL ES 3.00 (ANGLE " ANGLE_VERSION_STRING ")"; - } + case GL_SHADING_LANGUAGE_VERSION: + if (context->getClientVersion() == 2) + { + return reinterpret_cast( + "OpenGL ES GLSL ES 1.00 (ANGLE " ANGLE_VERSION_STRING ")"); + } + else + { + return reinterpret_cast( + "OpenGL ES GLSL ES 3.00 (ANGLE " ANGLE_VERSION_STRING ")"); + } - case GL_EXTENSIONS: - return (GLubyte*)((context != NULL) ? context->getExtensionString().c_str() : ""); + case GL_EXTENSIONS: + return reinterpret_cast(context->getExtensionString().c_str()); - default: - if (context) - { + default: context->recordError(Error(GL_INVALID_ENUM)); + return nullptr; } - return NULL; } + + return nullptr; } void GL_APIENTRY GetTexParameterfv(GLenum target, GLenum pname, GLfloat* params) @@ -2529,16 +2296,16 @@ void GL_APIENTRY GetTexParameterfv(GLenum target, GLenum pname, GLfloat* params) switch (pname) { case GL_TEXTURE_MAG_FILTER: - *params = (GLfloat)texture->getSamplerState().magFilter; + *params = (GLfloat)texture->getMagFilter(); break; case GL_TEXTURE_MIN_FILTER: - *params = (GLfloat)texture->getSamplerState().minFilter; + *params = (GLfloat)texture->getMinFilter(); break; case GL_TEXTURE_WRAP_S: - *params = (GLfloat)texture->getSamplerState().wrapS; + *params = (GLfloat)texture->getWrapS(); break; case GL_TEXTURE_WRAP_T: - *params = (GLfloat)texture->getSamplerState().wrapT; + *params = (GLfloat)texture->getWrapT(); break; case GL_TEXTURE_WRAP_R: if (context->getClientVersion() < 3) @@ -2546,11 +2313,11 @@ void GL_APIENTRY GetTexParameterfv(GLenum target, GLenum pname, GLfloat* params) context->recordError(Error(GL_INVALID_ENUM)); return; } - *params = (GLfloat)texture->getSamplerState().wrapR; + *params = (GLfloat)texture->getWrapR(); break; case GL_TEXTURE_IMMUTABLE_FORMAT: // Exposed to ES2.0 through EXT_texture_storage, no client version validation. - *params = (GLfloat)(texture->isImmutable() ? GL_TRUE : GL_FALSE); + *params = (GLfloat)(texture->getImmutableFormat() ? GL_TRUE : GL_FALSE); break; case GL_TEXTURE_IMMUTABLE_LEVELS: if (context->getClientVersion() < 3) @@ -2558,7 +2325,7 @@ void GL_APIENTRY GetTexParameterfv(GLenum target, GLenum pname, GLfloat* params) context->recordError(Error(GL_INVALID_ENUM)); return; } - *params = (GLfloat)texture->immutableLevelCount(); + *params = (GLfloat)texture->getImmutableLevels(); break; case GL_TEXTURE_USAGE_ANGLE: *params = (GLfloat)texture->getUsage(); @@ -2569,7 +2336,7 @@ void GL_APIENTRY GetTexParameterfv(GLenum target, GLenum pname, GLfloat* params) context->recordError(Error(GL_INVALID_ENUM)); return; } - *params = (GLfloat)texture->getSamplerState().maxAnisotropy; + *params = (GLfloat)texture->getMaxAnisotropy(); break; case GL_TEXTURE_SWIZZLE_R: if (context->getClientVersion() < 3) @@ -2577,7 +2344,7 @@ void GL_APIENTRY GetTexParameterfv(GLenum target, GLenum pname, GLfloat* params) context->recordError(Error(GL_INVALID_ENUM)); return; } - *params = (GLfloat)texture->getSamplerState().swizzleRed; + *params = (GLfloat)texture->getSwizzleRed(); break; case GL_TEXTURE_SWIZZLE_G: if (context->getClientVersion() < 3) @@ -2585,7 +2352,7 @@ void GL_APIENTRY GetTexParameterfv(GLenum target, GLenum pname, GLfloat* params) context->recordError(Error(GL_INVALID_ENUM)); return; } - *params = (GLfloat)texture->getSamplerState().swizzleGreen; + *params = (GLfloat)texture->getSwizzleGreen(); break; case GL_TEXTURE_SWIZZLE_B: if (context->getClientVersion() < 3) @@ -2593,7 +2360,7 @@ void GL_APIENTRY GetTexParameterfv(GLenum target, GLenum pname, GLfloat* params) context->recordError(Error(GL_INVALID_ENUM)); return; } - *params = (GLfloat)texture->getSamplerState().swizzleBlue; + *params = (GLfloat)texture->getSwizzleBlue(); break; case GL_TEXTURE_SWIZZLE_A: if (context->getClientVersion() < 3) @@ -2601,7 +2368,7 @@ void GL_APIENTRY GetTexParameterfv(GLenum target, GLenum pname, GLfloat* params) context->recordError(Error(GL_INVALID_ENUM)); return; } - *params = (GLfloat)texture->getSamplerState().swizzleAlpha; + *params = (GLfloat)texture->getSwizzleAlpha(); break; case GL_TEXTURE_BASE_LEVEL: if (context->getClientVersion() < 3) @@ -2609,7 +2376,7 @@ void GL_APIENTRY GetTexParameterfv(GLenum target, GLenum pname, GLfloat* params) context->recordError(Error(GL_INVALID_ENUM)); return; } - *params = (GLfloat)texture->getSamplerState().baseLevel; + *params = (GLfloat)texture->getBaseLevel(); break; case GL_TEXTURE_MAX_LEVEL: if (context->getClientVersion() < 3) @@ -2617,7 +2384,7 @@ void GL_APIENTRY GetTexParameterfv(GLenum target, GLenum pname, GLfloat* params) context->recordError(Error(GL_INVALID_ENUM)); return; } - *params = (GLfloat)texture->getSamplerState().maxLevel; + *params = (GLfloat)texture->getMaxLevel(); break; case GL_TEXTURE_MIN_LOD: if (context->getClientVersion() < 3) @@ -2635,7 +2402,26 @@ void GL_APIENTRY GetTexParameterfv(GLenum target, GLenum pname, GLfloat* params) } *params = texture->getSamplerState().maxLod; break; - + case GL_TEXTURE_COMPARE_MODE: + if (context->getClientVersion() < 3) + { + context->recordError( + Error(GL_INVALID_ENUM, + "GL_TEXTURE_COMPARE_MODE not available in ES versions < 3.0")); + return; + } + *params = static_cast(texture->getCompareMode()); + break; + case GL_TEXTURE_COMPARE_FUNC: + if (context->getClientVersion() < 3) + { + context->recordError( + Error(GL_INVALID_ENUM, + "GL_TEXTURE_COMPARE_FUNC not available in ES versions < 3.0")); + return; + } + *params = static_cast(texture->getCompareFunc()); + break; default: context->recordError(Error(GL_INVALID_ENUM)); return; @@ -2688,7 +2474,7 @@ void GL_APIENTRY GetTexParameteriv(GLenum target, GLenum pname, GLint* params) break; case GL_TEXTURE_IMMUTABLE_FORMAT: // Exposed to ES2.0 through EXT_texture_storage, no client version validation. - *params = texture->isImmutable() ? GL_TRUE : GL_FALSE; + *params = texture->getImmutableFormat() ? GL_TRUE : GL_FALSE; break; case GL_TEXTURE_IMMUTABLE_LEVELS: if (context->getClientVersion() < 3) @@ -2696,7 +2482,7 @@ void GL_APIENTRY GetTexParameteriv(GLenum target, GLenum pname, GLint* params) context->recordError(Error(GL_INVALID_ENUM)); return; } - *params = static_cast(texture->immutableLevelCount()); + *params = static_cast(texture->getImmutableLevels()); break; case GL_TEXTURE_USAGE_ANGLE: *params = texture->getUsage(); @@ -2707,7 +2493,7 @@ void GL_APIENTRY GetTexParameteriv(GLenum target, GLenum pname, GLint* params) context->recordError(Error(GL_INVALID_ENUM)); return; } - *params = (GLint)texture->getSamplerState().maxAnisotropy; + *params = (GLint)texture->getMaxAnisotropy(); break; case GL_TEXTURE_SWIZZLE_R: if (context->getClientVersion() < 3) @@ -2715,7 +2501,7 @@ void GL_APIENTRY GetTexParameteriv(GLenum target, GLenum pname, GLint* params) context->recordError(Error(GL_INVALID_ENUM)); return; } - *params = texture->getSamplerState().swizzleRed; + *params = texture->getSwizzleRed(); break; case GL_TEXTURE_SWIZZLE_G: if (context->getClientVersion() < 3) @@ -2723,7 +2509,7 @@ void GL_APIENTRY GetTexParameteriv(GLenum target, GLenum pname, GLint* params) context->recordError(Error(GL_INVALID_ENUM)); return; } - *params = texture->getSamplerState().swizzleGreen; + *params = texture->getSwizzleGreen(); break; case GL_TEXTURE_SWIZZLE_B: if (context->getClientVersion() < 3) @@ -2731,7 +2517,7 @@ void GL_APIENTRY GetTexParameteriv(GLenum target, GLenum pname, GLint* params) context->recordError(Error(GL_INVALID_ENUM)); return; } - *params = texture->getSamplerState().swizzleBlue; + *params = texture->getSwizzleBlue(); break; case GL_TEXTURE_SWIZZLE_A: if (context->getClientVersion() < 3) @@ -2739,7 +2525,7 @@ void GL_APIENTRY GetTexParameteriv(GLenum target, GLenum pname, GLint* params) context->recordError(Error(GL_INVALID_ENUM)); return; } - *params = texture->getSamplerState().swizzleAlpha; + *params = texture->getSwizzleAlpha(); break; case GL_TEXTURE_BASE_LEVEL: if (context->getClientVersion() < 3) @@ -2747,7 +2533,7 @@ void GL_APIENTRY GetTexParameteriv(GLenum target, GLenum pname, GLint* params) context->recordError(Error(GL_INVALID_ENUM)); return; } - *params = texture->getSamplerState().baseLevel; + *params = texture->getBaseLevel(); break; case GL_TEXTURE_MAX_LEVEL: if (context->getClientVersion() < 3) @@ -2755,7 +2541,7 @@ void GL_APIENTRY GetTexParameteriv(GLenum target, GLenum pname, GLint* params) context->recordError(Error(GL_INVALID_ENUM)); return; } - *params = texture->getSamplerState().maxLevel; + *params = texture->getMaxLevel(); break; case GL_TEXTURE_MIN_LOD: if (context->getClientVersion() < 3) @@ -2763,7 +2549,7 @@ void GL_APIENTRY GetTexParameteriv(GLenum target, GLenum pname, GLint* params) context->recordError(Error(GL_INVALID_ENUM)); return; } - *params = (GLint)texture->getSamplerState().minLod; + *params = iround(texture->getMinLod()); break; case GL_TEXTURE_MAX_LOD: if (context->getClientVersion() < 3) @@ -2771,9 +2557,28 @@ void GL_APIENTRY GetTexParameteriv(GLenum target, GLenum pname, GLint* params) context->recordError(Error(GL_INVALID_ENUM)); return; } - *params = (GLint)texture->getSamplerState().maxLod; + *params = iround(texture->getMaxLod()); + break; + case GL_TEXTURE_COMPARE_MODE: + if (context->getClientVersion() < 3) + { + context->recordError( + Error(GL_INVALID_ENUM, + "GL_TEXTURE_COMPARE_MODE not available in ES versions < 3.0")); + return; + } + *params = texture->getCompareMode(); + break; + case GL_TEXTURE_COMPARE_FUNC: + if (context->getClientVersion() < 3) + { + context->recordError( + Error(GL_INVALID_ENUM, + "GL_TEXTURE_COMPARE_FUNC not available in ES versions < 3.0")); + return; + } + *params = texture->getCompareFunc(); break; - default: context->recordError(Error(GL_INVALID_ENUM)); return; @@ -2831,20 +2636,11 @@ GLint GL_APIENTRY GetUniformLocation(GLuint program, const GLchar* name) return -1; } - Program *programObject = context->getProgram(program); + Program *programObject = GetValidProgram(context, program); if (!programObject) { - if (context->getShader(program)) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return -1; - } - else - { - context->recordError(Error(GL_INVALID_VALUE)); - return -1; - } + return -1; } if (!programObject->isLinked()) @@ -3138,20 +2934,15 @@ void GL_APIENTRY LinkProgram(GLuint program) Context *context = GetValidGlobalContext(); if (context) { - Program *programObject = context->getProgram(program); + if (!context->skipValidation() && !ValidateLinkProgram(context, program)) + { + return; + } + Program *programObject = GetValidProgram(context, program); if (!programObject) { - if (context->getShader(program)) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - else - { - context->recordError(Error(GL_INVALID_VALUE)); - return; - } + return; } Error error = programObject->link(context->getData()); @@ -3176,14 +2967,28 @@ void GL_APIENTRY PixelStorei(GLenum pname, GLint param) { case GL_UNPACK_IMAGE_HEIGHT: case GL_UNPACK_SKIP_IMAGES: + context->recordError(Error(GL_INVALID_ENUM)); + return; + case GL_UNPACK_ROW_LENGTH: case GL_UNPACK_SKIP_ROWS: case GL_UNPACK_SKIP_PIXELS: + if (!context->getExtensions().unpackSubimage) + { + context->recordError(Error(GL_INVALID_ENUM)); + return; + } + break; + case GL_PACK_ROW_LENGTH: case GL_PACK_SKIP_ROWS: case GL_PACK_SKIP_PIXELS: - context->recordError(Error(GL_INVALID_ENUM)); - return; + if (!context->getExtensions().packSubimage) + { + context->recordError(Error(GL_INVALID_ENUM)); + return; + } + break; } } @@ -3222,43 +3027,43 @@ void GL_APIENTRY PixelStorei(GLenum pname, GLint param) break; case GL_UNPACK_ROW_LENGTH: - ASSERT(context->getClientVersion() >= 3); + ASSERT((context->getClientVersion() >= 3) || context->getExtensions().unpackSubimage); state.setUnpackRowLength(param); break; case GL_UNPACK_IMAGE_HEIGHT: ASSERT(context->getClientVersion() >= 3); - state.getUnpackState().imageHeight = param; + state.setUnpackImageHeight(param); break; case GL_UNPACK_SKIP_IMAGES: - ASSERT(context->getClientVersion() >= 3); - state.getUnpackState().skipImages = param; + ASSERT(context->getClientVersion() >= 3); + state.setUnpackSkipImages(param); break; case GL_UNPACK_SKIP_ROWS: - ASSERT(context->getClientVersion() >= 3); - state.getUnpackState().skipRows = param; + ASSERT((context->getClientVersion() >= 3) || context->getExtensions().unpackSubimage); + state.setUnpackSkipRows(param); break; case GL_UNPACK_SKIP_PIXELS: - ASSERT(context->getClientVersion() >= 3); - state.getUnpackState().skipPixels = param; + ASSERT((context->getClientVersion() >= 3) || context->getExtensions().unpackSubimage); + state.setUnpackSkipPixels(param); break; case GL_PACK_ROW_LENGTH: - ASSERT(context->getClientVersion() >= 3); - state.getPackState().rowLength = param; + ASSERT((context->getClientVersion() >= 3) || context->getExtensions().packSubimage); + state.setPackRowLength(param); break; case GL_PACK_SKIP_ROWS: - ASSERT(context->getClientVersion() >= 3); - state.getPackState().skipRows = param; + ASSERT((context->getClientVersion() >= 3) || context->getExtensions().packSubimage); + state.setPackSkipRows(param); break; case GL_PACK_SKIP_PIXELS: - ASSERT(context->getClientVersion() >= 3); - state.getPackState().skipPixels = param; + ASSERT((context->getClientVersion() >= 3) || context->getExtensions().packSubimage); + state.setPackSkipPixels(param); break; default: @@ -3289,28 +3094,13 @@ void GL_APIENTRY ReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, Context *context = GetValidGlobalContext(); if (context) { - if (width < 0 || height < 0) + if (!context->skipValidation() && + !ValidateReadPixels(context, x, y, width, height, format, type, pixels)) { - context->recordError(Error(GL_INVALID_VALUE)); return; } - if (!ValidateReadPixelsParameters(context, x, y, width, height, - format, type, NULL, pixels)) - { - return; - } - - Framebuffer *framebufferObject = context->getState().getReadFramebuffer(); - ASSERT(framebufferObject); - - Rectangle area(x, y, width, height); - Error error = framebufferObject->readPixels(context->getState(), area, format, type, pixels); - if (error.isError()) - { - context->recordError(error); - return; - } + context->readPixels(x, y, width, height, format, type, pixels); } } @@ -3420,22 +3210,11 @@ void GL_APIENTRY ShaderSource(GLuint shader, GLsizei count, const GLchar* const* return; } - Shader *shaderObject = context->getShader(shader); - + Shader *shaderObject = GetValidShader(context, shader); if (!shaderObject) { - if (context->getProgram(shader)) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - else - { - context->recordError(Error(GL_INVALID_VALUE)); - return; - } + return; } - shaderObject->setSource(count, string, length); } } @@ -3627,29 +3406,15 @@ void GL_APIENTRY TexImage2D(GLenum target, GLint level, GLint internalformat, GL Context *context = GetValidGlobalContext(); if (context) { - if (context->getClientVersion() < 3 && - !ValidateES2TexImageParameters(context, target, level, internalformat, false, false, - 0, 0, width, height, border, format, type, pixels)) - { - return; - } - - if (context->getClientVersion() >= 3 && - !ValidateES3TexImageParameters(context, target, level, internalformat, false, false, - 0, 0, 0, width, height, 1, border, format, type, pixels)) + if (!context->skipValidation() && + !ValidateTexImage2D(context, target, level, internalformat, width, height, border, + format, type, pixels)) { return; } - Extents size(width, height, 1); - Texture *texture = context->getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target); - Error error = texture->setImage(target, level, internalformat, size, format, type, context->getState().getUnpackState(), - reinterpret_cast(pixels)); - if (error.isError()) - { - context->recordError(error); - return; - } + context->texImage2D(target, level, internalformat, width, height, border, format, type, + pixels); } } @@ -3679,27 +3444,29 @@ void GL_APIENTRY TexParameterf(GLenum target, GLenum pname, GLfloat param) return; } + // clang-format off switch (pname) { - case GL_TEXTURE_WRAP_S: texture->getSamplerState().wrapS = uiround(param); break; - case GL_TEXTURE_WRAP_T: texture->getSamplerState().wrapT = uiround(param); break; - case GL_TEXTURE_WRAP_R: texture->getSamplerState().wrapR = uiround(param); break; - case GL_TEXTURE_MIN_FILTER: texture->getSamplerState().minFilter = uiround(param); break; - case GL_TEXTURE_MAG_FILTER: texture->getSamplerState().magFilter = uiround(param); break; - case GL_TEXTURE_USAGE_ANGLE: texture->setUsage(uiround(param)); break; - case GL_TEXTURE_MAX_ANISOTROPY_EXT: texture->getSamplerState().maxAnisotropy = std::min(param, context->getExtensions().maxTextureAnisotropy); break; - case GL_TEXTURE_COMPARE_MODE: texture->getSamplerState().compareMode = uiround(param); break; - case GL_TEXTURE_COMPARE_FUNC: texture->getSamplerState().compareFunc = uiround(param); break; - case GL_TEXTURE_SWIZZLE_R: texture->getSamplerState().swizzleRed = uiround(param); break; - case GL_TEXTURE_SWIZZLE_G: texture->getSamplerState().swizzleGreen = uiround(param); break; - case GL_TEXTURE_SWIZZLE_B: texture->getSamplerState().swizzleBlue = uiround(param); break; - case GL_TEXTURE_SWIZZLE_A: texture->getSamplerState().swizzleAlpha = uiround(param); break; - case GL_TEXTURE_BASE_LEVEL: texture->getSamplerState().baseLevel = iround(param); break; - case GL_TEXTURE_MAX_LEVEL: texture->getSamplerState().maxLevel = iround(param); break; - case GL_TEXTURE_MIN_LOD: texture->getSamplerState().minLod = param; break; - case GL_TEXTURE_MAX_LOD: texture->getSamplerState().maxLod = param; break; + case GL_TEXTURE_WRAP_S: texture->setWrapS(uiround(param)); break; + case GL_TEXTURE_WRAP_T: texture->setWrapT(uiround(param)); break; + case GL_TEXTURE_WRAP_R: texture->setWrapR(uiround(param)); break; + case GL_TEXTURE_MIN_FILTER: texture->setMinFilter(uiround(param)); break; + case GL_TEXTURE_MAG_FILTER: texture->setMagFilter(uiround(param)); break; + case GL_TEXTURE_USAGE_ANGLE: texture->setUsage(uiround(param)); break; + case GL_TEXTURE_MAX_ANISOTROPY_EXT: texture->setMaxAnisotropy(std::min(param, context->getExtensions().maxTextureAnisotropy)); break; + case GL_TEXTURE_COMPARE_MODE: texture->setCompareMode(uiround(param)); break; + case GL_TEXTURE_COMPARE_FUNC: texture->setCompareFunc(uiround(param)); break; + case GL_TEXTURE_SWIZZLE_R: texture->setSwizzleRed(uiround(param)); break; + case GL_TEXTURE_SWIZZLE_G: texture->setSwizzleGreen(uiround(param)); break; + case GL_TEXTURE_SWIZZLE_B: texture->setSwizzleBlue(uiround(param)); break; + case GL_TEXTURE_SWIZZLE_A: texture->setSwizzleAlpha(uiround(param)); break; + case GL_TEXTURE_BASE_LEVEL: texture->setBaseLevel(uiround(param)); break; + case GL_TEXTURE_MAX_LEVEL: texture->setMaxLevel(uiround(param)); break; + case GL_TEXTURE_MIN_LOD: texture->setMinLod(param); break; + case GL_TEXTURE_MAX_LOD: texture->setMaxLod(param); break; default: UNREACHABLE(); break; } + // clang-format on } } @@ -3734,27 +3501,29 @@ void GL_APIENTRY TexParameteri(GLenum target, GLenum pname, GLint param) return; } + // clang-format off switch (pname) { - case GL_TEXTURE_WRAP_S: texture->getSamplerState().wrapS = (GLenum)param; break; - case GL_TEXTURE_WRAP_T: texture->getSamplerState().wrapT = (GLenum)param; break; - case GL_TEXTURE_WRAP_R: texture->getSamplerState().wrapR = (GLenum)param; break; - case GL_TEXTURE_MIN_FILTER: texture->getSamplerState().minFilter = (GLenum)param; break; - case GL_TEXTURE_MAG_FILTER: texture->getSamplerState().magFilter = (GLenum)param; break; - case GL_TEXTURE_USAGE_ANGLE: texture->setUsage((GLenum)param); break; - case GL_TEXTURE_MAX_ANISOTROPY_EXT: texture->getSamplerState().maxAnisotropy = std::min((float)param, context->getExtensions().maxTextureAnisotropy); break; - case GL_TEXTURE_COMPARE_MODE: texture->getSamplerState().compareMode = (GLenum)param; break; - case GL_TEXTURE_COMPARE_FUNC: texture->getSamplerState().compareFunc = (GLenum)param; break; - case GL_TEXTURE_SWIZZLE_R: texture->getSamplerState().swizzleRed = (GLenum)param; break; - case GL_TEXTURE_SWIZZLE_G: texture->getSamplerState().swizzleGreen = (GLenum)param; break; - case GL_TEXTURE_SWIZZLE_B: texture->getSamplerState().swizzleBlue = (GLenum)param; break; - case GL_TEXTURE_SWIZZLE_A: texture->getSamplerState().swizzleAlpha = (GLenum)param; break; - case GL_TEXTURE_BASE_LEVEL: texture->getSamplerState().baseLevel = param; break; - case GL_TEXTURE_MAX_LEVEL: texture->getSamplerState().maxLevel = param; break; - case GL_TEXTURE_MIN_LOD: texture->getSamplerState().minLod = (GLfloat)param; break; - case GL_TEXTURE_MAX_LOD: texture->getSamplerState().maxLod = (GLfloat)param; break; + case GL_TEXTURE_WRAP_S: texture->setWrapS(static_cast(param)); break; + case GL_TEXTURE_WRAP_T: texture->setWrapT(static_cast(param)); break; + case GL_TEXTURE_WRAP_R: texture->setWrapR(static_cast(param)); break; + case GL_TEXTURE_MIN_FILTER: texture->setMinFilter(static_cast(param)); break; + case GL_TEXTURE_MAG_FILTER: texture->setMagFilter(static_cast(param)); break; + case GL_TEXTURE_USAGE_ANGLE: texture->setUsage(static_cast(param)); break; + case GL_TEXTURE_MAX_ANISOTROPY_EXT: texture->setMaxAnisotropy(std::min(static_cast(param), context->getExtensions().maxTextureAnisotropy)); break; + case GL_TEXTURE_COMPARE_MODE: texture->setCompareMode(static_cast(param)); break; + case GL_TEXTURE_COMPARE_FUNC: texture->setCompareFunc(static_cast(param)); break; + case GL_TEXTURE_SWIZZLE_R: texture->setSwizzleRed(static_cast(param)); break; + case GL_TEXTURE_SWIZZLE_G: texture->setSwizzleGreen(static_cast(param)); break; + case GL_TEXTURE_SWIZZLE_B: texture->setSwizzleBlue(static_cast(param)); break; + case GL_TEXTURE_SWIZZLE_A: texture->setSwizzleAlpha(static_cast(param)); break; + case GL_TEXTURE_BASE_LEVEL: texture->setBaseLevel(static_cast(param)); break; + case GL_TEXTURE_MAX_LEVEL: texture->setMaxLevel(static_cast(param)); break; + case GL_TEXTURE_MIN_LOD: texture->setMinLod(static_cast(param)); break; + case GL_TEXTURE_MAX_LOD: texture->setMaxLod(static_cast(param)); break; default: UNREACHABLE(); break; } + // clang-format on } } @@ -3774,35 +3543,15 @@ void GL_APIENTRY TexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint Context *context = GetValidGlobalContext(); if (context) { - if (context->getClientVersion() < 3 && - !ValidateES2TexImageParameters(context, target, level, GL_NONE, false, true, - xoffset, yoffset, width, height, 0, format, type, pixels)) - { - return; - } - - if (context->getClientVersion() >= 3 && - !ValidateES3TexImageParameters(context, target, level, GL_NONE, false, true, - xoffset, yoffset, 0, width, height, 1, 0, format, type, pixels)) - { - return; - } - - // Zero sized uploads are valid but no-ops - if (width == 0 || height == 0) + if (!context->skipValidation() && + !ValidateTexSubImage2D(context, target, level, xoffset, yoffset, width, height, format, + type, pixels)) { return; } - Box area(xoffset, yoffset, 0, width, height, 1); - Texture *texture = context->getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target); - Error error = texture->setSubImage(target, level, area, format, type, context->getState().getUnpackState(), - reinterpret_cast(pixels)); - if (error.isError()) - { - context->recordError(error); - return; - } + context->texSubImage2D(target, level, xoffset, yoffset, width, height, format, type, + pixels); } } @@ -4055,25 +3804,8 @@ void GL_APIENTRY UseProgram(GLuint program) Context *context = GetValidGlobalContext(); if (context) { - Program *programObject = context->getProgram(program); - - if (!programObject && program != 0) - { - if (context->getShader(program)) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - else - { - context->recordError(Error(GL_INVALID_VALUE)); - return; - } - } - - if (program != 0 && !programObject->isLinked()) + if (!context->skipValidation() && !ValidateUseProgram(context, program)) { - context->recordError(Error(GL_INVALID_OPERATION)); return; } @@ -4088,20 +3820,11 @@ void GL_APIENTRY ValidateProgram(GLuint program) Context *context = GetValidGlobalContext(); if (context) { - Program *programObject = context->getProgram(program); + Program *programObject = GetValidProgram(context, program); if (!programObject) { - if (context->getShader(program)) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - else - { - context->recordError(Error(GL_INVALID_VALUE)); - return; - } + return; } programObject->validate(context->getCaps()); diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/entry_points_gles_2_0_ext.cpp b/Source/ThirdParty/ANGLE/src/libGLESv2/entry_points_gles_2_0_ext.cpp index 1756618ab334..f31663b33f40 100644 --- a/Source/ThirdParty/ANGLE/src/libGLESv2/entry_points_gles_2_0_ext.cpp +++ b/Source/ThirdParty/ANGLE/src/libGLESv2/entry_points_gles_2_0_ext.cpp @@ -27,6 +27,57 @@ namespace gl { +void GL_APIENTRY GenQueriesEXT(GLsizei n, GLuint *ids) +{ + EVENT("(GLsizei n = %d, GLuint* ids = 0x%0.8p)", n, ids); + + Context *context = GetValidGlobalContext(); + if (context) + { + if (!context->skipValidation() && !ValidateGenQueriesEXT(context, n)) + { + return; + } + + for (GLsizei i = 0; i < n; i++) + { + ids[i] = context->createQuery(); + } + } +} + +void GL_APIENTRY DeleteQueriesEXT(GLsizei n, const GLuint *ids) +{ + EVENT("(GLsizei n = %d, const GLuint *ids = 0x%0.8p)", n, ids); + + Context *context = GetValidGlobalContext(); + if (context) + { + if (!context->skipValidation() && !ValidateDeleteQueriesEXT(context, n)) + { + return; + } + + for (int i = 0; i < n; i++) + { + context->deleteQuery(ids[i]); + } + } +} + +GLboolean GL_APIENTRY IsQueryEXT(GLuint id) +{ + EVENT("(GLuint id = %d)", id); + + Context *context = GetValidGlobalContext(); + if (context) + { + return (context->getQuery(id, false, GL_NONE) != NULL) ? GL_TRUE : GL_FALSE; + } + + return GL_FALSE; +} + void GL_APIENTRY BeginQueryEXT(GLenum target, GLuint id) { EVENT("(GLenum target = 0x%X, GLuint %d)", target, id); @@ -34,7 +85,7 @@ void GL_APIENTRY BeginQueryEXT(GLenum target, GLuint id) Context *context = GetValidGlobalContext(); if (context) { - if (!ValidateBeginQuery(context, target, id)) + if (!ValidateBeginQueryEXT(context, target, id)) { return; } @@ -48,59 +99,78 @@ void GL_APIENTRY BeginQueryEXT(GLenum target, GLuint id) } } -void GL_APIENTRY DeleteFencesNV(GLsizei n, const GLuint* fences) +void GL_APIENTRY EndQueryEXT(GLenum target) { - EVENT("(GLsizei n = %d, const GLuint* fences = 0x%0.8p)", n, fences); + EVENT("GLenum target = 0x%X)", target); Context *context = GetValidGlobalContext(); if (context) { - if (n < 0) + if (!ValidateEndQueryEXT(context, target)) { - context->recordError(Error(GL_INVALID_VALUE)); return; } - for (int i = 0; i < n; i++) + Error error = context->endQuery(target); + if (error.isError()) { - context->deleteFenceNV(fences[i]); + context->recordError(error); + return; } } } -void GL_APIENTRY DeleteQueriesEXT(GLsizei n, const GLuint *ids) +void GL_APIENTRY QueryCounterEXT(GLuint id, GLenum target) { - EVENT("(GLsizei n = %d, const GLuint *ids = 0x%0.8p)", n, ids); + EVENT("GLuint id = %d, GLenum target = 0x%X)", id, target); Context *context = GetValidGlobalContext(); if (context) { - if (n < 0) + if (!ValidateQueryCounterEXT(context, id, target)) { - context->recordError(Error(GL_INVALID_VALUE)); return; } - for (int i = 0; i < n; i++) + Error error = context->queryCounter(id, target); + if (error.isError()) { - context->deleteQuery(ids[i]); + context->recordError(error); + return; } } } -void GL_APIENTRY DrawArraysInstancedANGLE(GLenum mode, GLint first, GLsizei count, GLsizei primcount) +void GL_APIENTRY GetQueryivEXT(GLenum target, GLenum pname, GLint *params) { - EVENT("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d, GLsizei primcount = %d)", mode, first, count, primcount); + EVENT("GLenum target = 0x%X, GLenum pname = 0x%X, GLint *params = 0x%0.8p)", target, pname, + params); Context *context = GetValidGlobalContext(); if (context) { - if (!ValidateDrawArraysInstancedANGLE(context, mode, first, count, primcount)) + if (!ValidateGetQueryivEXT(context, target, pname, params)) + { + return; + } + + context->getQueryiv(target, pname, params); + } +} + +void GL_APIENTRY GetQueryObjectivEXT(GLuint id, GLenum pname, GLint *params) +{ + EVENT("(GLuint id = %d, GLenum pname = 0x%X, GLuint *params = 0x%0.8p)", id, pname, params); + + Context *context = GetValidGlobalContext(); + if (context) + { + if (!ValidateGetQueryObjectivEXT(context, id, pname, params)) { return; } - Error error = context->drawArrays(mode, first, count, primcount); + Error error = context->getQueryObjectiv(id, pname, params); if (error.isError()) { context->recordError(error); @@ -109,21 +179,19 @@ void GL_APIENTRY DrawArraysInstancedANGLE(GLenum mode, GLint first, GLsizei coun } } -void GL_APIENTRY DrawElementsInstancedANGLE(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei primcount) +void GL_APIENTRY GetQueryObjectuivEXT(GLuint id, GLenum pname, GLuint *params) { - EVENT("(GLenum mode = 0x%X, GLsizei count = %d, GLenum type = 0x%X, const GLvoid* indices = 0x%0.8p, GLsizei primcount = %d)", - mode, count, type, indices, primcount); + EVENT("(GLuint id = %d, GLenum pname = 0x%X, GLuint *params = 0x%0.8p)", id, pname, params); Context *context = GetValidGlobalContext(); if (context) { - rx::RangeUI indexRange; - if (!ValidateDrawElementsInstancedANGLE(context, mode, count, type, indices, primcount, &indexRange)) + if (!ValidateGetQueryObjectuivEXT(context, id, pname, params)) { return; } - Error error = context->drawElements(mode, count, type, indices, primcount, indexRange); + Error error = context->getQueryObjectuiv(id, pname, params); if (error.isError()) { context->recordError(error); @@ -132,19 +200,19 @@ void GL_APIENTRY DrawElementsInstancedANGLE(GLenum mode, GLsizei count, GLenum t } } -void GL_APIENTRY EndQueryEXT(GLenum target) +void GL_APIENTRY GetQueryObjecti64vEXT(GLuint id, GLenum pname, GLint64 *params) { - EVENT("GLenum target = 0x%X)", target); + EVENT("(GLuint id = %d, GLenum pname = 0x%X, GLuint *params = 0x%0.16p)", id, pname, params); Context *context = GetValidGlobalContext(); if (context) { - if (!ValidateEndQuery(context, target)) + if (!ValidateGetQueryObjecti64vEXT(context, id, pname, params)) { return; } - Error error = context->endQuery(target); + Error error = context->getQueryObjecti64v(id, pname, params); if (error.isError()) { context->recordError(error); @@ -153,34 +221,30 @@ void GL_APIENTRY EndQueryEXT(GLenum target) } } -void GL_APIENTRY FinishFenceNV(GLuint fence) +void GL_APIENTRY GetQueryObjectui64vEXT(GLuint id, GLenum pname, GLuint64 *params) { - EVENT("(GLuint fence = %d)", fence); + EVENT("(GLuint id = %d, GLenum pname = 0x%X, GLuint *params = 0x%0.16p)", id, pname, params); Context *context = GetValidGlobalContext(); if (context) { - FenceNV *fenceObject = context->getFenceNV(fence); - - if (fenceObject == NULL) + if (!ValidateGetQueryObjectui64vEXT(context, id, pname, params)) { - context->recordError(Error(GL_INVALID_OPERATION)); return; } - if (fenceObject->isSet() != GL_TRUE) + Error error = context->getQueryObjectui64v(id, pname, params); + if (error.isError()) { - context->recordError(Error(GL_INVALID_OPERATION)); + context->recordError(error); return; } - - fenceObject->finish(); } } -void GL_APIENTRY GenFencesNV(GLsizei n, GLuint* fences) +void GL_APIENTRY DeleteFencesNV(GLsizei n, const GLuint *fences) { - EVENT("(GLsizei n = %d, GLuint* fences = 0x%0.8p)", n, fences); + EVENT("(GLsizei n = %d, const GLuint* fences = 0x%0.8p)", n, fences); Context *context = GetValidGlobalContext(); if (context) @@ -193,14 +257,95 @@ void GL_APIENTRY GenFencesNV(GLsizei n, GLuint* fences) for (int i = 0; i < n; i++) { - fences[i] = context->createFenceNV(); + context->deleteFenceNV(fences[i]); } } } -void GL_APIENTRY GenQueriesEXT(GLsizei n, GLuint* ids) +void GL_APIENTRY DrawArraysInstancedANGLE(GLenum mode, + GLint first, + GLsizei count, + GLsizei primcount) { - EVENT("(GLsizei n = %d, GLuint* ids = 0x%0.8p)", n, ids); + EVENT("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d, GLsizei primcount = %d)", + mode, first, count, primcount); + + Context *context = GetValidGlobalContext(); + if (context) + { + if (!ValidateDrawArraysInstancedANGLE(context, mode, first, count, primcount)) + { + return; + } + + Error error = context->drawArraysInstanced(mode, first, count, primcount); + if (error.isError()) + { + context->recordError(error); + return; + } + } +} + +void GL_APIENTRY DrawElementsInstancedANGLE(GLenum mode, + GLsizei count, + GLenum type, + const GLvoid *indices, + GLsizei primcount) +{ + EVENT( + "(GLenum mode = 0x%X, GLsizei count = %d, GLenum type = 0x%X, const GLvoid* indices = " + "0x%0.8p, GLsizei primcount = %d)", + mode, count, type, indices, primcount); + + Context *context = GetValidGlobalContext(); + if (context) + { + IndexRange indexRange; + if (!ValidateDrawElementsInstancedANGLE(context, mode, count, type, indices, primcount, + &indexRange)) + { + return; + } + + Error error = + context->drawElementsInstanced(mode, count, type, indices, primcount, indexRange); + if (error.isError()) + { + context->recordError(error); + return; + } + } +} + +void GL_APIENTRY FinishFenceNV(GLuint fence) +{ + EVENT("(GLuint fence = %d)", fence); + + Context *context = GetValidGlobalContext(); + if (context) + { + FenceNV *fenceObject = context->getFenceNV(fence); + + if (fenceObject == NULL) + { + context->recordError(Error(GL_INVALID_OPERATION)); + return; + } + + if (fenceObject->isSet() != GL_TRUE) + { + context->recordError(Error(GL_INVALID_OPERATION)); + return; + } + + fenceObject->finish(); + } +} + +void GL_APIENTRY GenFencesNV(GLsizei n, GLuint *fences) +{ + EVENT("(GLsizei n = %d, GLuint* fences = 0x%0.8p)", n, fences); Context *context = GetValidGlobalContext(); if (context) @@ -211,9 +356,9 @@ void GL_APIENTRY GenQueriesEXT(GLsizei n, GLuint* ids) return; } - for (GLsizei i = 0; i < n; i++) + for (int i = 0; i < n; i++) { - ids[i] = context->createQuery(); + fences[i] = context->createFenceNV(); } } } @@ -289,84 +434,6 @@ GLenum GL_APIENTRY GetGraphicsResetStatusEXT(void) return GL_NO_ERROR; } -void GL_APIENTRY GetQueryivEXT(GLenum target, GLenum pname, GLint *params) -{ - EVENT("GLenum target = 0x%X, GLenum pname = 0x%X, GLint *params = 0x%0.8p)", target, pname, params); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (!ValidQueryType(context, target)) - { - context->recordError(Error(GL_INVALID_ENUM)); - return; - } - - switch (pname) - { - case GL_CURRENT_QUERY_EXT: - params[0] = context->getState().getActiveQueryId(target); - break; - - default: - context->recordError(Error(GL_INVALID_ENUM)); - return; - } - } -} - -void GL_APIENTRY GetQueryObjectuivEXT(GLuint id, GLenum pname, GLuint *params) -{ - EVENT("(GLuint id = %d, GLenum pname = 0x%X, GLuint *params = 0x%0.8p)", id, pname, params); - - Context *context = GetValidGlobalContext(); - if (context) - { - Query *queryObject = context->getQuery(id, false, GL_NONE); - - if (!queryObject) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - - if (context->getState().getActiveQueryId(queryObject->getType()) == id) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - - switch(pname) - { - case GL_QUERY_RESULT_EXT: - { - Error error = queryObject->getResult(params); - if (error.isError()) - { - context->recordError(error); - return; - } - } - break; - - case GL_QUERY_RESULT_AVAILABLE_EXT: - { - Error error = queryObject->isResultAvailable(params); - if (error.isError()) - { - context->recordError(error); - return; - } - } - break; - - default: - context->recordError(Error(GL_INVALID_ENUM)); - return; - } - } -} - void GL_APIENTRY GetTranslatedShaderSourceANGLE(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source) { EVENT("(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLchar* source = 0x%0.8p)", @@ -389,7 +456,6 @@ void GL_APIENTRY GetTranslatedShaderSourceANGLE(GLuint shader, GLsizei bufsize, return; } - // Only returns extra info if ANGLE_GENERATE_SHADER_DEBUG_INFO is defined shaderObject->getTranslatedSourceWithDebugInfo(bufsize, length, source); } } @@ -456,19 +522,6 @@ GLboolean GL_APIENTRY IsFenceNV(GLuint fence) return GL_FALSE; } -GLboolean GL_APIENTRY IsQueryEXT(GLuint id) -{ - EVENT("(GLuint id = %d)", id); - - Context *context = GetValidGlobalContext(); - if (context) - { - return (context->getQuery(id, false, GL_NONE) != NULL) ? GL_TRUE : GL_FALSE; - } - - return GL_FALSE; -} - void GL_APIENTRY ReadnPixelsEXT(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, GLvoid *data) @@ -480,28 +533,13 @@ void GL_APIENTRY ReadnPixelsEXT(GLint x, GLint y, GLsizei width, GLsizei height, Context *context = GetValidGlobalContext(); if (context) { - if (width < 0 || height < 0 || bufSize < 0) - { - context->recordError(Error(GL_INVALID_VALUE)); - return; - } - - if (!ValidateReadPixelsParameters(context, x, y, width, height, - format, type, &bufSize, data)) + if (!context->skipValidation() && + !ValidateReadnPixelsEXT(context, x, y, width, height, format, type, bufSize, data)) { return; } - Framebuffer *framebufferObject = context->getState().getReadFramebuffer(); - ASSERT(framebufferObject); - - Rectangle area(x, y, width, height); - Error error = framebufferObject->readPixels(context->getState(), area, format, type, data); - if (error.isError()) - { - context->recordError(error); - return; - } + context->readPixels(x, y, width, height, format, type, data); } } @@ -615,7 +653,8 @@ void GL_APIENTRY TexStorage2DEXT(GLenum target, GLsizei levels, GLenum internalf } if (context->getClientVersion() >= 3 && - !ValidateES3TexStorageParameters(context, target, levels, internalformat, width, height, 1)) + !ValidateES3TexStorage2DParameters(context, target, levels, internalformat, width, + height, 1)) { return; } @@ -644,9 +683,24 @@ void GL_APIENTRY VertexAttribDivisorANGLE(GLuint index, GLuint divisor) return; } - context->setVertexAttribDivisor(index, divisor); - } -} + if (context->getLimitations().attributeZeroRequiresZeroDivisorInEXT) + { + if (index == 0 && divisor != 0) + { + const char *errorMessage = "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."; + context->recordError(Error(GL_INVALID_OPERATION, errorMessage)); + + // We also output an error message to the debugger window if tracing is active, so that developers can see the error message. + ERR("%s", errorMessage); + + return; + } + } + + context->setVertexAttribDivisor(index, divisor); + } +} void GL_APIENTRY BlitFramebufferANGLE(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) @@ -659,28 +713,32 @@ void GL_APIENTRY BlitFramebufferANGLE(GLint srcX0, GLint srcY0, GLint srcX1, GLi Context *context = GetValidGlobalContext(); if (context) { - if (!ValidateBlitFramebufferParameters(context, srcX0, srcY0, srcX1, srcY1, - dstX0, dstY0, dstX1, dstY1, mask, filter, - true)) + if (!context->skipValidation() && + !ValidateBlitFramebufferANGLE(context, srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, + dstY1, mask, filter)) { return; } - Framebuffer *readFramebuffer = context->getState().getReadFramebuffer(); - ASSERT(readFramebuffer); - - Framebuffer *drawFramebuffer = context->getState().getDrawFramebuffer(); - ASSERT(drawFramebuffer); + context->blitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, + filter); + } +} - Rectangle srcArea(srcX0, srcY0, srcX1 - srcX0, srcY1 - srcY0); - Rectangle dstArea(dstX0, dstY0, dstX1 - dstX0, dstY1 - dstY0); +void GL_APIENTRY DiscardFramebufferEXT(GLenum target, GLsizei numAttachments, const GLenum *attachments) +{ + EVENT("(GLenum target = 0x%X, GLsizei numAttachments = %d, attachments = 0x%0.8p)", target, numAttachments, attachments); - Error error = drawFramebuffer->blit(context->getState(), srcArea, dstArea, mask, filter, readFramebuffer); - if (error.isError()) + Context *context = GetValidGlobalContext(); + if (context) + { + if (!context->skipValidation() && + !ValidateDiscardFramebufferEXT(context, target, numAttachments, attachments)) { - context->recordError(error); return; } + + context->discardFramebuffer(target, numAttachments, attachments); } } @@ -703,14 +761,14 @@ void GL_APIENTRY GetProgramBinaryOES(GLuint program, GLsizei bufSize, GLsizei *l Context *context = GetValidGlobalContext(); if (context) { - Program *programObject = context->getProgram(program); - - if (!programObject || !programObject->isLinked()) + if (!ValidateGetProgramBinaryOES(context, program, bufSize, length, binaryFormat, binary)) { - context->recordError(Error(GL_INVALID_OPERATION)); return; } + Program *programObject = context->getProgram(program); + ASSERT(programObject != nullptr); + Error error = programObject->saveBinary(binaryFormat, binary, bufSize, length); if (error.isError()) { @@ -728,19 +786,13 @@ void GL_APIENTRY ProgramBinaryOES(GLuint program, GLenum binaryFormat, const voi Context *context = GetValidGlobalContext(); if (context) { - const std::vector &programBinaryFormats = context->getCaps().programBinaryFormats; - if (std::find(programBinaryFormats.begin(), programBinaryFormats.end(), binaryFormat) == programBinaryFormats.end()) + if (!ValidateProgramBinaryOES(context, program, binaryFormat, binary, length)) { - context->recordError(Error(GL_INVALID_ENUM)); return; } Program *programObject = context->getProgram(program); - if (!programObject) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } + ASSERT(programObject != nullptr); Error error = programObject->loadBinary(binaryFormat, binary, length); if (error.isError()) @@ -758,302 +810,563 @@ void GL_APIENTRY DrawBuffersEXT(GLsizei n, const GLenum *bufs) Context *context = GetValidGlobalContext(); if (context) { - if (n < 0 || static_cast(n) > context->getCaps().maxDrawBuffers) + if (!context->skipValidation() && !ValidateDrawBuffersEXT(context, n, bufs)) { - context->recordError(Error(GL_INVALID_VALUE)); return; } - ASSERT(context->getState().getDrawFramebuffer()); + context->drawBuffers(n, bufs); + } +} - if (context->getState().getDrawFramebuffer()->id() == 0) +void GL_APIENTRY GetBufferPointervOES(GLenum target, GLenum pname, void** params) +{ + EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLvoid** params = 0x%0.8p)", target, pname, params); + + Context *context = GetValidGlobalContext(); + if (context) + { + if (!context->skipValidation() && + !ValidateGetBufferPointervOES(context, target, pname, params)) { - if (n != 1) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } + return; + } - if (bufs[0] != GL_NONE && bufs[0] != GL_BACK) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } + context->getBufferPointerv(target, pname, params); + } +} + +void *GL_APIENTRY MapBufferOES(GLenum target, GLenum access) +{ + EVENT("(GLenum target = 0x%X, GLbitfield access = 0x%X)", target, access); + + Context *context = GetValidGlobalContext(); + if (context) + { + if (!context->skipValidation() && !ValidateMapBufferOES(context, target, access)) + { + return nullptr; } - else + + return context->mapBuffer(target, access); + } + + return nullptr; +} + +GLboolean GL_APIENTRY UnmapBufferOES(GLenum target) +{ + EVENT("(GLenum target = 0x%X)", target); + + Context *context = GetValidGlobalContext(); + if (context) + { + if (!context->skipValidation() && !ValidateUnmapBufferOES(context, target)) { - for (int colorAttachment = 0; colorAttachment < n; colorAttachment++) - { - const GLenum attachment = GL_COLOR_ATTACHMENT0_EXT + colorAttachment; - if (bufs[colorAttachment] != GL_NONE && bufs[colorAttachment] != attachment) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - } + return GL_FALSE; } - Framebuffer *framebuffer = context->getState().getDrawFramebuffer(); - ASSERT(framebuffer); + return context->unmapBuffer(target); + } + + return GL_FALSE; +} + +void *GL_APIENTRY MapBufferRangeEXT(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access) +{ + EVENT("(GLenum target = 0x%X, GLintptr offset = %d, GLsizeiptr length = %d, GLbitfield access = 0x%X)", + target, offset, length, access); - framebuffer->setDrawBuffers(n, bufs); + Context *context = GetValidGlobalContext(); + if (context) + { + if (!context->skipValidation() && + !ValidateMapBufferRangeEXT(context, target, offset, length, access)) + { + return nullptr; + } + + return context->mapBufferRange(target, offset, length, access); } + + return nullptr; } -void GL_APIENTRY GetBufferPointervOES(GLenum target, GLenum pname, void** params) +void GL_APIENTRY FlushMappedBufferRangeEXT(GLenum target, GLintptr offset, GLsizeiptr length) { - EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLvoid** params = 0x%0.8p)", target, pname, params); + EVENT("(GLenum target = 0x%X, GLintptr offset = %d, GLsizeiptr length = %d)", target, offset, length); Context *context = GetValidGlobalContext(); if (context) { - if (!ValidBufferTarget(context, target)) + if (!context->skipValidation() && + !ValidateFlushMappedBufferRangeEXT(context, target, offset, length)) { - context->recordError(Error(GL_INVALID_ENUM)); return; } - if (pname != GL_BUFFER_MAP_POINTER) + context->flushMappedBufferRange(target, offset, length); + } +} + +void GL_APIENTRY InsertEventMarkerEXT(GLsizei length, const char *marker) +{ + // Don't run an EVENT() macro on the EXT_debug_marker entry points. + // It can interfere with the debug events being set by the caller. + + Context *context = GetValidGlobalContext(); + if (context) + { + if (!context->getExtensions().debugMarker) { - context->recordError(Error(GL_INVALID_ENUM)); + // 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->recordError(Error(GL_INVALID_OPERATION, "Extension not enabled")); + return; + } + + if (!ValidateInsertEventMarkerEXT(context, length, marker)) + { + return; + } + + context->insertEventMarker(length, marker); + } +} + +void GL_APIENTRY PushGroupMarkerEXT(GLsizei length, const char *marker) +{ + // Don't run an EVENT() macro on the EXT_debug_marker entry points. + // It can interfere with the debug events being set by the caller. + + Context *context = GetValidGlobalContext(); + if (context) + { + if (!context->getExtensions().debugMarker) + { + // 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->recordError(Error(GL_INVALID_OPERATION, "Extension not enabled")); return; } - Buffer *buffer = context->getState().getTargetBuffer(target); + if (!ValidatePushGroupMarkerEXT(context, length, marker)) + { + return; + } - if (!buffer || !buffer->isMapped()) + if (marker == nullptr) { - *params = NULL; + // From the EXT_debug_marker spec, + // "If is null then an empty string is pushed on the stack." + context->pushGroupMarker(length, ""); } else { - *params = buffer->getMapPointer(); + context->pushGroupMarker(length, marker); } } } -void *GL_APIENTRY MapBufferOES(GLenum target, GLenum access) +void GL_APIENTRY PopGroupMarkerEXT() { - EVENT("(GLenum target = 0x%X, GLbitfield access = 0x%X)", target, access); + // Don't run an EVENT() macro on the EXT_debug_marker entry points. + // It can interfere with the debug events being set by the caller. Context *context = GetValidGlobalContext(); if (context) { - if (!ValidBufferTarget(context, target)) + if (!context->getExtensions().debugMarker) { - context->recordError(Error(GL_INVALID_ENUM)); - return NULL; + // 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->recordError(Error(GL_INVALID_OPERATION, "Extension not enabled")); + return; } - Buffer *buffer = context->getState().getTargetBuffer(target); + context->popGroupMarker(); + } +} + +ANGLE_EXPORT void GL_APIENTRY EGLImageTargetTexture2DOES(GLenum target, GLeglImageOES image) +{ + EVENT("(GLenum target = 0x%X, GLeglImageOES image = 0x%0.8p)", target, image); - if (buffer == NULL) + Context *context = GetValidGlobalContext(); + if (context) + { + egl::Display *display = egl::GetGlobalDisplay(); + egl::Image *imageObject = reinterpret_cast(image); + if (!ValidateEGLImageTargetTexture2DOES(context, display, target, imageObject)) { - context->recordError(Error(GL_INVALID_OPERATION)); - return NULL; + return; } - if (access != GL_WRITE_ONLY_OES) + Texture *texture = context->getTargetTexture(target); + Error error = texture->setEGLImageTarget(target, imageObject); + if (error.isError()) { - context->recordError(Error(GL_INVALID_ENUM)); - return NULL; + context->recordError(error); + return; } + } +} - if (buffer->isMapped()) +ANGLE_EXPORT void GL_APIENTRY EGLImageTargetRenderbufferStorageOES(GLenum target, + GLeglImageOES image) +{ + EVENT("(GLenum target = 0x%X, GLeglImageOES image = 0x%0.8p)", target, image); + + Context *context = GetValidGlobalContext(); + if (context) + { + egl::Display *display = egl::GetGlobalDisplay(); + egl::Image *imageObject = reinterpret_cast(image); + if (!ValidateEGLImageTargetRenderbufferStorageOES(context, display, target, imageObject)) { - context->recordError(Error(GL_INVALID_OPERATION)); - return NULL; + return; } - Error error = buffer->map(access); + Renderbuffer *renderbuffer = context->getState().getCurrentRenderbuffer(); + Error error = renderbuffer->setStorageEGLImageTarget(imageObject); if (error.isError()) { context->recordError(error); - return NULL; + return; } - - return buffer->getMapPointer(); } - - return NULL; } -GLboolean GL_APIENTRY UnmapBufferOES(GLenum target) +void GL_APIENTRY BindVertexArrayOES(GLuint array) { - EVENT("(GLenum target = 0x%X)", target); + EVENT("(GLuint array = %u)", array); Context *context = GetValidGlobalContext(); if (context) { - if (!ValidBufferTarget(context, target)) + if (!ValidateBindVertexArrayOES(context, array)) { - context->recordError(Error(GL_INVALID_ENUM)); - return GL_FALSE; + return; } - Buffer *buffer = context->getState().getTargetBuffer(target); + context->bindVertexArray(array); + } +} + +void GL_APIENTRY DeleteVertexArraysOES(GLsizei n, const GLuint *arrays) +{ + EVENT("(GLsizei n = %d, const GLuint* arrays = 0x%0.8p)", n, arrays); - if (buffer == NULL || !buffer->isMapped()) + Context *context = GetValidGlobalContext(); + if (context) + { + if (!ValidateDeleteVertexArraysOES(context, n)) { - context->recordError(Error(GL_INVALID_OPERATION)); - return GL_FALSE; + return; } - GLboolean result; - Error error = buffer->unmap(&result); - if (error.isError()) + for (int arrayIndex = 0; arrayIndex < n; arrayIndex++) { - context->recordError(error); - return GL_FALSE; + if (arrays[arrayIndex] != 0) + { + context->deleteVertexArray(arrays[arrayIndex]); + } } - - return result; } - - return GL_FALSE; } -void *GL_APIENTRY MapBufferRangeEXT(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access) +void GL_APIENTRY GenVertexArraysOES(GLsizei n, GLuint *arrays) { - EVENT("(GLenum target = 0x%X, GLintptr offset = %d, GLsizeiptr length = %d, GLbitfield access = 0x%X)", - target, offset, length, access); + EVENT("(GLsizei n = %d, GLuint* arrays = 0x%0.8p)", n, arrays); Context *context = GetValidGlobalContext(); if (context) { - if (!ValidBufferTarget(context, target)) + if (!ValidateGenVertexArraysOES(context, n)) { - context->recordError(Error(GL_INVALID_ENUM)); - return NULL; + return; } - if (offset < 0 || length < 0) + for (int arrayIndex = 0; arrayIndex < n; arrayIndex++) { - context->recordError(Error(GL_INVALID_VALUE)); - return NULL; + arrays[arrayIndex] = context->createVertexArray(); } + } +} - Buffer *buffer = context->getState().getTargetBuffer(target); +GLboolean GL_APIENTRY IsVertexArrayOES(GLuint array) +{ + EVENT("(GLuint array = %u)", array); - if (buffer == NULL) + Context *context = GetValidGlobalContext(); + if (context) + { + if (!ValidateIsVertexArrayOES(context)) { - context->recordError(Error(GL_INVALID_OPERATION)); - return NULL; + return GL_FALSE; } - // Check for buffer overflow - size_t offsetSize = static_cast(offset); - size_t lengthSize = static_cast(length); - - if (!rx::IsUnsignedAdditionSafe(offsetSize, lengthSize) || - offsetSize + lengthSize > static_cast(buffer->getSize())) + if (array == 0) { - context->recordError(Error(GL_INVALID_VALUE)); - return NULL; + return GL_FALSE; } - // Check for invalid bits in the mask - GLbitfield allAccessBits = 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; + VertexArray *vao = context->getVertexArray(array); + + return (vao != nullptr ? GL_TRUE : GL_FALSE); + } - if (access & ~(allAccessBits)) + return GL_FALSE; +} + +void GL_APIENTRY DebugMessageControlKHR(GLenum source, + GLenum type, + GLenum severity, + GLsizei count, + const GLuint *ids, + GLboolean enabled) +{ + EVENT( + "(GLenum source = 0x%X, GLenum type = 0x%X, GLenum severity = 0x%X, GLsizei count = %d, " + "GLint *ids = 0x%0.8p, GLboolean enabled = %d)", + source, type, severity, count, ids, enabled); + + Context *context = GetValidGlobalContext(); + if (context) + { + if (!ValidateDebugMessageControlKHR(context, source, type, severity, count, ids, enabled)) { - context->recordError(Error(GL_INVALID_VALUE)); - return NULL; + return; } - if (length == 0 || buffer->isMapped()) + std::vector idVector(ids, ids + count); + context->getState().getDebug().setMessageControl( + source, type, severity, std::move(idVector), (enabled != GL_FALSE)); + } +} + +void GL_APIENTRY DebugMessageInsertKHR(GLenum source, + GLenum type, + GLuint id, + GLenum severity, + GLsizei length, + const GLchar *buf) +{ + EVENT( + "(GLenum source = 0x%X, GLenum type = 0x%X, GLint id = %d, GLenum severity = 0x%X, GLsizei " + "length = %d, const GLchar *buf = 0x%0.8p)", + source, type, id, severity, length, buf); + + Context *context = GetValidGlobalContext(); + if (context) + { + if (!ValidateDebugMessageInsertKHR(context, source, type, id, severity, length, buf)) { - context->recordError(Error(GL_INVALID_OPERATION)); - return NULL; + return; } - // Check for invalid bit combinations - if ((access & (GL_MAP_READ_BIT | GL_MAP_WRITE_BIT)) == 0) + std::string msg(buf, (length > 0) ? static_cast(length) : strlen(buf)); + context->getState().getDebug().insertMessage(source, type, id, severity, std::move(msg)); + } +} + +void GL_APIENTRY DebugMessageCallbackKHR(GLDEBUGPROCKHR callback, const void *userParam) +{ + EVENT("(GLDEBUGPROCKHR callback = 0x%0.8p, const void *userParam = 0x%0.8p)", callback, + userParam); + + Context *context = GetValidGlobalContext(); + if (context) + { + if (!ValidateDebugMessageCallbackKHR(context, callback, userParam)) { - context->recordError(Error(GL_INVALID_OPERATION)); - return NULL; + return; } - GLbitfield writeOnlyBits = GL_MAP_INVALIDATE_RANGE_BIT | - GL_MAP_INVALIDATE_BUFFER_BIT | - GL_MAP_UNSYNCHRONIZED_BIT; + context->getState().getDebug().setCallback(callback, userParam); + } +} + +GLuint GL_APIENTRY GetDebugMessageLogKHR(GLuint count, + GLsizei bufSize, + GLenum *sources, + GLenum *types, + GLuint *ids, + GLenum *severities, + GLsizei *lengths, + GLchar *messageLog) +{ + EVENT( + "(GLsizei count = %d, GLsizei bufSize = %d, GLenum *sources, GLenum *types = 0x%0.8p, " + "GLuint *ids = 0x%0.8p, GLenum *severities = 0x%0.8p, GLsizei *lengths = 0x%0.8p, GLchar " + "*messageLog = 0x%0.8p)", + count, bufSize, sources, types, ids, severities, lengths, messageLog); - if ((access & GL_MAP_READ_BIT) != 0 && (access & writeOnlyBits) != 0) + Context *context = GetValidGlobalContext(); + if (context) + { + if (!ValidateGetDebugMessageLogKHR(context, count, bufSize, sources, types, ids, severities, + lengths, messageLog)) { - context->recordError(Error(GL_INVALID_OPERATION)); - return NULL; + return 0; } - if ((access & GL_MAP_WRITE_BIT) == 0 && (access & GL_MAP_FLUSH_EXPLICIT_BIT) != 0) + return static_cast(context->getState().getDebug().getMessages( + count, bufSize, sources, types, ids, severities, lengths, messageLog)); + } + + return 0; +} + +void GL_APIENTRY PushDebugGroupKHR(GLenum source, GLuint id, GLsizei length, const GLchar *message) +{ + EVENT( + "(GLenum source = 0x%X, GLuint id = 0x%X, GLsizei length = %d, const GLchar *message = " + "0x%0.8p)", + source, id, length, message); + + Context *context = GetValidGlobalContext(); + if (context) + { + if (!ValidatePushDebugGroupKHR(context, source, id, length, message)) { - context->recordError(Error(GL_INVALID_OPERATION)); - return NULL; + return; } - Error error = buffer->mapRange(offset, length, access); - if (error.isError()) + std::string msg(message, (length > 0) ? static_cast(length) : strlen(message)); + context->getState().getDebug().pushGroup(source, id, std::move(msg)); + } +} + +void GL_APIENTRY PopDebugGroupKHR(void) +{ + EVENT("()"); + + Context *context = GetValidGlobalContext(); + if (context) + { + if (!ValidatePopDebugGroupKHR(context)) { - context->recordError(error); - return NULL; + return; } - return buffer->getMapPointer(); + context->getState().getDebug().popGroup(); } - - return NULL; } -void GL_APIENTRY FlushMappedBufferRangeEXT(GLenum target, GLintptr offset, GLsizeiptr length) +void GL_APIENTRY ObjectLabelKHR(GLenum identifier, GLuint name, GLsizei length, const GLchar *label) { - EVENT("(GLenum target = 0x%X, GLintptr offset = %d, GLsizeiptr length = %d)", target, offset, length); + EVENT( + "(GLenum identifier = 0x%X, GLuint name = %u, GLsizei length = %d, const GLchar *label = " + "0x%0.8p)", + identifier, name, length, label); Context *context = GetValidGlobalContext(); if (context) { - if (offset < 0 || length < 0) + if (!ValidateObjectLabelKHR(context, identifier, name, length, label)) { - context->recordError(Error(GL_INVALID_VALUE)); return; } - if (!ValidBufferTarget(context, target)) + LabeledObject *object = context->getLabeledObject(identifier, name); + ASSERT(object != nullptr); + + std::string lbl(label, (length > 0) ? static_cast(length) : strlen(label)); + object->setLabel(lbl); + } +} + +void GL_APIENTRY +GetObjectLabelKHR(GLenum identifier, GLuint name, GLsizei bufSize, GLsizei *length, GLchar *label) +{ + EVENT( + "(GLenum identifier = 0x%X, GLuint name = %u, GLsizei bufSize = %d, GLsizei *length = " + "0x%0.8p, GLchar *label = 0x%0.8p)", + identifier, name, bufSize, length, label); + + Context *context = GetValidGlobalContext(); + if (context) + { + if (!ValidateGetObjectLabelKHR(context, identifier, name, bufSize, length, label)) { - context->recordError(Error(GL_INVALID_ENUM)); return; } - Buffer *buffer = context->getState().getTargetBuffer(target); + LabeledObject *object = context->getLabeledObject(identifier, name); + ASSERT(object != nullptr); - if (buffer == NULL) + const std::string &objectLabel = object->getLabel(); + size_t writeLength = std::min(static_cast(bufSize) - 1, objectLabel.length()); + std::copy(objectLabel.begin(), objectLabel.begin() + writeLength, label); + label[writeLength] = '\0'; + *length = static_cast(writeLength); + } +} + +void GL_APIENTRY ObjectPtrLabelKHR(const void *ptr, GLsizei length, const GLchar *label) +{ + EVENT("(const void *ptr = 0x%0.8p, GLsizei length = %d, const GLchar *label = 0x%0.8p)", ptr, + length, label); + + Context *context = GetValidGlobalContext(); + if (context) + { + if (!ValidateObjectPtrLabelKHR(context, ptr, length, label)) { - context->recordError(Error(GL_INVALID_OPERATION)); return; } - if (!buffer->isMapped() || (buffer->getAccessFlags() & GL_MAP_FLUSH_EXPLICIT_BIT) == 0) + LabeledObject *object = context->getLabeledObjectFromPtr(ptr); + ASSERT(object != nullptr); + + std::string lbl(label, (length > 0) ? static_cast(length) : strlen(label)); + object->setLabel(lbl); + } +} + +void GL_APIENTRY GetObjectPtrLabelKHR(const void *ptr, + GLsizei bufSize, + GLsizei *length, + GLchar *label) +{ + EVENT( + "(const void *ptr = 0x%0.8p, GLsizei bufSize = %d, GLsizei *length = 0x%0.8p, GLchar " + "*label = 0x%0.8p)", + ptr, bufSize, length, label); + + Context *context = GetValidGlobalContext(); + if (context) + { + if (!ValidateGetObjectPtrLabelKHR(context, ptr, bufSize, length, label)) { - context->recordError(Error(GL_INVALID_OPERATION)); return; } - // Check for buffer overflow - size_t offsetSize = static_cast(offset); - size_t lengthSize = static_cast(length); + LabeledObject *object = context->getLabeledObjectFromPtr(ptr); + ASSERT(object != nullptr); - if (!rx::IsUnsignedAdditionSafe(offsetSize, lengthSize) || - offsetSize + lengthSize > static_cast(buffer->getMapLength())) + const std::string &objectLabel = object->getLabel(); + size_t writeLength = std::min(static_cast(bufSize) - 1, objectLabel.length()); + std::copy(objectLabel.begin(), objectLabel.begin() + writeLength, label); + label[writeLength] = '\0'; + *length = static_cast(writeLength); + } +} + +void GL_APIENTRY GetPointervKHR(GLenum pname, void **params) +{ + EVENT("(GLenum pname = 0x%X, void **params = 0x%0.8p)", pname, params); + + Context *context = GetValidGlobalContext(); + if (context) + { + if (!ValidateGetPointervKHR(context, pname, params)) { - context->recordError(Error(GL_INVALID_VALUE)); return; } - // We do not currently support a non-trivial implementation of FlushMappedBufferRange + context->getPointerv(pname, params); } } - } diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/entry_points_gles_2_0_ext.h b/Source/ThirdParty/ANGLE/src/libGLESv2/entry_points_gles_2_0_ext.h index 816519fe1f5f..a2fb9c5e80f6 100644 --- a/Source/ThirdParty/ANGLE/src/libGLESv2/entry_points_gles_2_0_ext.h +++ b/Source/ThirdParty/ANGLE/src/libGLESv2/entry_points_gles_2_0_ext.h @@ -22,6 +22,9 @@ ANGLE_EXPORT void GL_APIENTRY BlitFramebufferANGLE(GLint srcX0, GLint srcY0, GLi // GL_ANGLE_framebuffer_multisample ANGLE_EXPORT void GL_APIENTRY RenderbufferStorageMultisampleANGLE(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +// GL_EXT_discard_framebuffer +ANGLE_EXPORT void GL_APIENTRY DiscardFramebufferEXT(GLenum target, GLsizei numAttachments, const GLenum *attachments); + // GL_NV_fence ANGLE_EXPORT void GL_APIENTRY DeleteFencesNV(GLsizei n, const GLuint* fences); ANGLE_EXPORT void GL_APIENTRY GenFencesNV(GLsizei n, GLuint* fences); @@ -52,6 +55,12 @@ ANGLE_EXPORT void GL_APIENTRY EndQueryEXT(GLenum target); ANGLE_EXPORT void GL_APIENTRY GetQueryivEXT(GLenum target, GLenum pname, GLint *params); ANGLE_EXPORT void GL_APIENTRY GetQueryObjectuivEXT(GLuint id, GLenum pname, GLuint *params); +// GL_EXT_disjoint_timer_query +ANGLE_EXPORT void GL_APIENTRY QueryCounterEXT(GLuint id, GLenum target); +ANGLE_EXPORT void GL_APIENTRY GetQueryObjectivEXT(GLuint id, GLenum pname, GLint *params); +ANGLE_EXPORT void GL_APIENTRY GetQueryObjecti64vEXT(GLuint id, GLenum pname, GLint64 *params); +ANGLE_EXPORT void GL_APIENTRY GetQueryObjectui64vEXT(GLuint id, GLenum pname, GLuint64 *params); + // GL_EXT_draw_buffers ANGLE_EXPORT void GL_APIENTRY DrawBuffersEXT(GLsizei n, const GLenum *bufs); @@ -73,6 +82,64 @@ ANGLE_EXPORT void GL_APIENTRY GetBufferPointervOES(GLenum target, GLenum pname, ANGLE_EXPORT void *GL_APIENTRY MapBufferRangeEXT(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access); ANGLE_EXPORT void GL_APIENTRY FlushMappedBufferRangeEXT(GLenum target, GLintptr offset, GLsizeiptr length); +// GL_EXT_debug_marker +ANGLE_EXPORT void GL_APIENTRY InsertEventMarkerEXT(GLsizei length, const char *marker); +ANGLE_EXPORT void GL_APIENTRY PushGroupMarkerEXT(GLsizei length, const char *marker); +ANGLE_EXPORT void GL_APIENTRY PopGroupMarkerEXT(); + +// GL_OES_EGL_image +ANGLE_EXPORT void GL_APIENTRY EGLImageTargetTexture2DOES(GLenum target, GLeglImageOES image); +ANGLE_EXPORT void GL_APIENTRY EGLImageTargetRenderbufferStorageOES(GLenum target, + GLeglImageOES image); + +// GL_OES_vertex_array_object +ANGLE_EXPORT void GL_APIENTRY BindVertexArrayOES(GLuint array); +ANGLE_EXPORT void GL_APIENTRY DeleteVertexArraysOES(GLsizei n, const GLuint *arrays); +ANGLE_EXPORT void GL_APIENTRY GenVertexArraysOES(GLsizei n, GLuint *arrays); +ANGLE_EXPORT GLboolean GL_APIENTRY IsVertexArrayOES(GLuint array); + +// GL_KHR_debug +ANGLE_EXPORT void GL_APIENTRY DebugMessageControlKHR(GLenum source, + GLenum type, + GLenum severity, + GLsizei count, + const GLuint *ids, + GLboolean enabled); +ANGLE_EXPORT void GL_APIENTRY DebugMessageInsertKHR(GLenum source, + GLenum type, + GLuint id, + GLenum severity, + GLsizei length, + const GLchar *buf); +ANGLE_EXPORT void GL_APIENTRY DebugMessageCallbackKHR(GLDEBUGPROCKHR callback, + const void *userParam); +ANGLE_EXPORT GLuint GL_APIENTRY GetDebugMessageLogKHR(GLuint count, + GLsizei bufSize, + GLenum *sources, + GLenum *types, + GLuint *ids, + GLenum *severities, + GLsizei *lengths, + GLchar *messageLog); +ANGLE_EXPORT void GL_APIENTRY PushDebugGroupKHR(GLenum source, + GLuint id, + GLsizei length, + const GLchar *message); +ANGLE_EXPORT void GL_APIENTRY PopDebugGroupKHR(void); +ANGLE_EXPORT void GL_APIENTRY ObjectLabelKHR(GLenum identifier, + GLuint name, + GLsizei length, + const GLchar *label); +ANGLE_EXPORT void GL_APIENTRY +GetObjectLabelKHR(GLenum identifier, GLuint name, GLsizei bufSize, GLsizei *length, GLchar *label); +ANGLE_EXPORT void GL_APIENTRY ObjectPtrLabelKHR(const void *ptr, + GLsizei length, + const GLchar *label); +ANGLE_EXPORT void GL_APIENTRY GetObjectPtrLabelKHR(const void *ptr, + GLsizei bufSize, + GLsizei *length, + GLchar *label); +ANGLE_EXPORT void GL_APIENTRY GetPointervKHR(GLenum pname, void **params); } #endif // LIBGLESV2_ENTRYPOINTGLES20EXT_H_ diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/entry_points_gles_3_0.cpp b/Source/ThirdParty/ANGLE/src/libGLESv2/entry_points_gles_3_0.cpp index 0ab42ead00ab..00c1f511c2ed 100644 --- a/Source/ThirdParty/ANGLE/src/libGLESv2/entry_points_gles_3_0.cpp +++ b/Source/ThirdParty/ANGLE/src/libGLESv2/entry_points_gles_3_0.cpp @@ -35,13 +35,12 @@ void GL_APIENTRY ReadBuffer(GLenum mode) Context *context = GetValidGlobalContext(); if (context) { - if (!ValidateReadBuffer(context, mode)) + if (!context->skipValidation() && !ValidateReadBuffer(context, mode)) { return; } - Framebuffer *readFBO = context->getState().getReadFramebuffer(); - readFBO->setReadBuffer(mode); + context->readBuffer(mode); } } @@ -53,21 +52,11 @@ void GL_APIENTRY DrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsize Context *context = GetValidGlobalContext(); if (context) { - if (context->getClientVersion() < 3) + IndexRange indexRange; + if (!context->skipValidation() && + !ValidateDrawRangeElements(context, mode, start, end, count, type, indices, + &indexRange)) { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - - rx::RangeUI indexRange; - if (!ValidateDrawElements(context, mode, count, type, indices, 0, &indexRange)) - { - return; - } - if (indexRange.end > end || indexRange.start < start) - { - // GL spec says that behavior in this case is undefined - generating an error is fine. - context->recordError(Error(GL_INVALID_OPERATION)); return; } @@ -75,7 +64,8 @@ void GL_APIENTRY DrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsize // a drawRangeElements call - the GL back-end is free to choose to call drawRangeElements based on the // validated index range. If index validation is removed, adding drawRangeElements to the context interface // should be reconsidered. - Error error = context->drawElements(mode, count, type, indices, 0, indexRange); + Error error = + context->drawRangeElements(mode, start, end, count, type, indices, indexRange); if (error.isError()) { context->recordError(error); @@ -94,28 +84,15 @@ void GL_APIENTRY TexImage3D(GLenum target, GLint level, GLint internalformat, GL Context *context = GetValidGlobalContext(); if (context) { - if (context->getClientVersion() < 3) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - - // validateES3TexImageFormat sets the error code if there is an error - if (!ValidateES3TexImageParameters(context, target, level, internalformat, false, false, - 0, 0, 0, width, height, depth, border, format, type, pixels)) + if (!context->skipValidation() && + !ValidateTexImage3D(context, target, level, internalformat, width, height, depth, + border, format, type, pixels)) { return; } - Extents size(width, height, depth); - Texture *texture = context->getTargetTexture(target); - Error error = texture->setImage(target, level, internalformat, size, format, type, context->getState().getUnpackState(), - reinterpret_cast(pixels)); - if (error.isError()) - { - context->recordError(error); - return; - } + context->texImage3D(target, level, internalformat, width, height, depth, border, format, + type, pixels); } } @@ -129,35 +106,15 @@ void GL_APIENTRY TexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint Context *context = GetValidGlobalContext(); if (context) { - if (context->getClientVersion() < 3) + if (!context->skipValidation() && + !ValidateTexSubImage3D(context, target, level, xoffset, yoffset, zoffset, width, height, + depth, format, type, pixels)) { - context->recordError(Error(GL_INVALID_OPERATION)); return; } - // validateES3TexImageFormat sets the error code if there is an error - if (!ValidateES3TexImageParameters(context, target, level, GL_NONE, false, true, - xoffset, yoffset, zoffset, width, height, depth, 0, - format, type, pixels)) - { - return; - } - - // Zero sized uploads are valid but no-ops - if (width == 0 || height == 0 || depth == 0) - { - return; - } - - Box area(xoffset, yoffset, zoffset, width, height, depth); - Texture *texture = context->getTargetTexture(target); - Error error = texture->setSubImage(target, level, area, format, type, context->getState().getUnpackState(), - reinterpret_cast(pixels)); - if (error.isError()) - { - context->recordError(error); - return; - } + context->texSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, + format, type, pixels); } } @@ -170,29 +127,14 @@ void GL_APIENTRY CopyTexSubImage3D(GLenum target, GLint level, GLint xoffset, GL Context *context = GetValidGlobalContext(); if (context) { - if (context->getClientVersion() < 3) + if (!context->skipValidation() && + !ValidateCopyTexSubImage3D(context, target, level, xoffset, yoffset, zoffset, x, y, + width, height)) { - context->recordError(Error(GL_INVALID_OPERATION)); return; } - if (!ValidateES3CopyTexImageParameters(context, target, level, GL_NONE, true, xoffset, yoffset, zoffset, - x, y, width, height, 0)) - { - return; - } - - Offset destOffset(xoffset, yoffset, zoffset); - Rectangle sourceArea(x, y, width, height); - - const Framebuffer *framebuffer = context->getState().getReadFramebuffer(); - Texture *texture = context->getTargetTexture(target); - Error error = texture->copySubImage(target, level, destOffset, sourceArea, framebuffer); - if (error.isError()) - { - context->recordError(error); - return; - } + context->copyTexSubImage3D(target, level, xoffset, yoffset, zoffset, x, y, width, height); } } @@ -206,35 +148,15 @@ void GL_APIENTRY CompressedTexImage3D(GLenum target, GLint level, GLenum interna Context *context = GetValidGlobalContext(); if (context) { - if (context->getClientVersion() < 3) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - - const InternalFormat &formatInfo = GetInternalFormatInfo(internalformat); - if (imageSize < 0 || static_cast(imageSize) != formatInfo.computeBlockSize(GL_UNSIGNED_BYTE, width, height)) - { - context->recordError(Error(GL_INVALID_VALUE)); - return; - } - - // validateES3TexImageFormat sets the error code if there is an error - if (!ValidateES3TexImageParameters(context, target, level, internalformat, true, false, - 0, 0, 0, width, height, depth, border, GL_NONE, GL_NONE, data)) + if (!context->skipValidation() && + !ValidateCompressedTexImage3D(context, target, level, internalformat, width, height, + depth, border, imageSize, data)) { return; } - Extents size(width, height, depth); - Texture *texture = context->getTargetTexture(target); - Error error = texture->setCompressedImage(target, level, internalformat, size, context->getState().getUnpackState(), - reinterpret_cast(data)); - if (error.isError()) - { - context->recordError(error); - return; - } + context->compressedTexImage3D(target, level, internalformat, width, height, depth, border, + imageSize, data); } } @@ -248,47 +170,15 @@ void GL_APIENTRY CompressedTexSubImage3D(GLenum target, GLint level, GLint xoffs Context *context = GetValidGlobalContext(); if (context) { - if (context->getClientVersion() < 3) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - - const InternalFormat &formatInfo = GetInternalFormatInfo(format); - if (imageSize < 0 || static_cast(imageSize) != formatInfo.computeBlockSize(GL_UNSIGNED_BYTE, width, height)) - { - context->recordError(Error(GL_INVALID_VALUE)); - return; - } - - if (!data) - { - context->recordError(Error(GL_INVALID_VALUE)); - return; - } - - // validateES3TexImageFormat sets the error code if there is an error - if (!ValidateES3TexImageParameters(context, target, level, GL_NONE, true, true, - 0, 0, 0, width, height, depth, 0, GL_NONE, GL_NONE, data)) + if (!context->skipValidation() && + !ValidateCompressedTexSubImage3D(context, target, level, xoffset, yoffset, zoffset, + width, height, depth, format, imageSize, data)) { return; } - // Zero sized uploads are valid but no-ops - if (width == 0 || height == 0) - { - return; - } - - Box area(xoffset, yoffset, zoffset, width, height, depth); - Texture *texture = context->getTargetTexture(target); - Error error = texture->setCompressedSubImage(target, level, area, format, context->getState().getUnpackState(), - reinterpret_cast(data)); - if (error.isError()) - { - context->recordError(error); - return; - } + context->compressedTexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, + depth, format, imageSize, data); } } @@ -299,15 +189,8 @@ void GL_APIENTRY GenQueries(GLsizei n, GLuint* ids) Context *context = GetValidGlobalContext(); if (context) { - if (context->getClientVersion() < 3) + if (!context->skipValidation() && !ValidateGenQueries(context, n, ids)) { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - - if (n < 0) - { - context->recordError(Error(GL_INVALID_VALUE)); return; } @@ -325,19 +208,12 @@ void GL_APIENTRY DeleteQueries(GLsizei n, const GLuint* ids) Context *context = GetValidGlobalContext(); if (context) { - if (context->getClientVersion() < 3) + if (!context->skipValidation() && !ValidateDeleteQueries(context, n, ids)) { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - - if (n < 0) - { - context->recordError(Error(GL_INVALID_VALUE)); return; } - for (GLsizei i = 0; i < n; i++) + for (int i = 0; i < n; i++) { context->deleteQuery(ids[i]); } @@ -370,12 +246,6 @@ void GL_APIENTRY BeginQuery(GLenum target, GLuint id) Context *context = GetValidGlobalContext(); if (context) { - if (context->getClientVersion() < 3) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - if (!ValidateBeginQuery(context, target, id)) { return; @@ -397,12 +267,6 @@ void GL_APIENTRY EndQuery(GLenum target) Context *context = GetValidGlobalContext(); if (context) { - if (context->getClientVersion() < 3) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - if (!ValidateEndQuery(context, target)) { return; @@ -424,28 +288,12 @@ void GL_APIENTRY GetQueryiv(GLenum target, GLenum pname, GLint* params) Context *context = GetValidGlobalContext(); if (context) { - if (context->getClientVersion() < 3) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - - if (!ValidQueryType(context, target)) + if (!ValidateGetQueryiv(context, target, pname, params)) { - context->recordError(Error(GL_INVALID_ENUM)); return; } - switch (pname) - { - case GL_CURRENT_QUERY: - params[0] = static_cast(context->getState().getActiveQueryId(target)); - break; - - default: - context->recordError(Error(GL_INVALID_ENUM)); - return; - } + context->getQueryiv(target, pname, params); } } @@ -456,52 +304,15 @@ void GL_APIENTRY GetQueryObjectuiv(GLuint id, GLenum pname, GLuint* params) Context *context = GetValidGlobalContext(); if (context) { - if (context->getClientVersion() < 3) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - - Query *queryObject = context->getQuery(id, false, GL_NONE); - - if (!queryObject) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - - if (context->getState().getActiveQueryId(queryObject->getType()) == id) + if (!ValidateGetQueryObjectuiv(context, id, pname, params)) { - context->recordError(Error(GL_INVALID_OPERATION)); return; } - switch(pname) + Error error = context->getQueryObjectuiv(id, pname, params); + if (error.isError()) { - case GL_QUERY_RESULT_EXT: - { - Error error = queryObject->getResult(params); - if (error.isError()) - { - context->recordError(error); - return; - } - } - break; - - case GL_QUERY_RESULT_AVAILABLE_EXT: - { - Error error = queryObject->isResultAvailable(params); - if (error.isError()) - { - context->recordError(error); - return; - } - } - break; - - default: - context->recordError(Error(GL_INVALID_ENUM)); + context->recordError(error); return; } } @@ -514,13 +325,12 @@ GLboolean GL_APIENTRY UnmapBuffer(GLenum target) Context *context = GetValidGlobalContext(); if (context) { - if (context->getClientVersion() < 3) + if (!context->skipValidation() && !ValidateUnmapBuffer(context, target)) { - context->recordError(Error(GL_INVALID_OPERATION)); return GL_FALSE; } - return UnmapBufferOES(target); + return context->unmapBuffer(target); } return GL_FALSE; @@ -533,13 +343,13 @@ void GL_APIENTRY GetBufferPointerv(GLenum target, GLenum pname, GLvoid** params) Context *context = GetValidGlobalContext(); if (context) { - if (context->getClientVersion() < 3) + if (!context->skipValidation() && + !ValidateGetBufferPointerv(context, target, pname, params)) { - context->recordError(Error(GL_INVALID_OPERATION)); return; } - GetBufferPointervOES(target, pname, params); + context->getBufferPointerv(target, pname, params); } } @@ -548,13 +358,12 @@ void GL_APIENTRY DrawBuffers(GLsizei n, const GLenum* bufs) Context *context = GetValidGlobalContext(); if (context) { - if (context->getClientVersion() < 3) + if (!context->skipValidation() && !ValidateDrawBuffers(context, n, bufs)) { - context->recordError(Error(GL_INVALID_OPERATION)); return; } - DrawBuffersEXT(n, bufs); + context->drawBuffers(n, bufs); } } @@ -675,34 +484,15 @@ void GL_APIENTRY BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint sr Context *context = GetValidGlobalContext(); if (context) { - if (context->getClientVersion() < 3) + if (!context->skipValidation() && + !ValidateBlitFramebuffer(context, srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, + dstY1, mask, filter)) { - context->recordError(Error(GL_INVALID_OPERATION)); return; } - if (!ValidateBlitFramebufferParameters(context, srcX0, srcY0, srcX1, srcY1, - dstX0, dstY0, dstX1, dstY1, mask, filter, - false)) - { - return; - } - - Framebuffer *readFramebuffer = context->getState().getReadFramebuffer(); - ASSERT(readFramebuffer); - - Framebuffer *drawFramebuffer = context->getState().getDrawFramebuffer(); - ASSERT(drawFramebuffer); - - Rectangle srcArea(srcX0, srcY0, srcX1 - srcX0, srcY1 - srcY0); - Rectangle dstArea(dstX0, dstY0, dstX1 - dstX0, dstY1 - dstY0); - - Error error = drawFramebuffer->blit(context->getState(), srcArea, dstArea, mask, filter, readFramebuffer); - if (error.isError()) - { - context->recordError(error); - return; - } + context->blitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, + filter); } } @@ -738,37 +528,13 @@ void GL_APIENTRY FramebufferTextureLayer(GLenum target, GLenum attachment, GLuin Context *context = GetValidGlobalContext(); if (context) { - if (!ValidateFramebufferTextureLayer(context, target, attachment, texture, - level, layer)) + if (!context->skipValidation() && + !ValidateFramebufferTextureLayer(context, target, attachment, texture, level, layer)) { return; } - Framebuffer *framebuffer = context->getState().getTargetFramebuffer(target); - ASSERT(framebuffer); - - if (texture != 0) - { - Texture *textureObject = context->getTexture(texture); - - ImageIndex index = ImageIndex::MakeInvalid(); - - if (textureObject->getTarget() == GL_TEXTURE_3D) - { - index = ImageIndex::Make3D(level, layer); - } - else - { - ASSERT(textureObject->getTarget() == GL_TEXTURE_2D_ARRAY); - index = ImageIndex::Make2DArray(level, layer); - } - - framebuffer->setAttachment(GL_TEXTURE, attachment, index, textureObject); - } - else - { - framebuffer->resetAttachment(attachment); - } + context->framebufferTextureLayer(target, attachment, texture, level, layer); } } @@ -780,16 +546,16 @@ GLvoid *GL_APIENTRY MapBufferRange(GLenum target, GLintptr offset, GLsizeiptr le Context *context = GetValidGlobalContext(); if (context) { - if (context->getClientVersion() < 3) + if (!context->skipValidation() && + !ValidateMapBufferRange(context, target, offset, length, access)) { - context->recordError(Error(GL_INVALID_OPERATION)); - return NULL; + return nullptr; } - return MapBufferRangeEXT(target, offset, length, access); + return context->mapBufferRange(target, offset, length, access); } - return NULL; + return nullptr; } void GL_APIENTRY FlushMappedBufferRange(GLenum target, GLintptr offset, GLsizeiptr length) @@ -799,13 +565,13 @@ void GL_APIENTRY FlushMappedBufferRange(GLenum target, GLintptr offset, GLsizeip Context *context = GetValidGlobalContext(); if (context) { - if (context->getClientVersion() < 3) + if (!context->skipValidation() && + !ValidateFlushMappedBufferRange(context, target, offset, length)) { - context->recordError(Error(GL_INVALID_OPERATION)); return; } - FlushMappedBufferRangeEXT(target, offset, length); + context->flushMappedBufferRange(target, offset, length); } } @@ -816,19 +582,8 @@ void GL_APIENTRY BindVertexArray(GLuint array) Context *context = GetValidGlobalContext(); if (context) { - if (context->getClientVersion() < 3) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - - VertexArray *vao = context->getVertexArray(array); - - if (!vao) + if (!ValidateBindVertexArray(context, array)) { - // The default VAO should always exist - ASSERT(array != 0); - context->recordError(Error(GL_INVALID_OPERATION)); return; } @@ -843,15 +598,8 @@ void GL_APIENTRY DeleteVertexArrays(GLsizei n, const GLuint* arrays) Context *context = GetValidGlobalContext(); if (context) { - if (context->getClientVersion() < 3) + if (!context->skipValidation() && !ValidateDeleteVertexArrays(context, n, arrays)) { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - - if (n < 0) - { - context->recordError(Error(GL_INVALID_VALUE)); return; } @@ -872,15 +620,8 @@ void GL_APIENTRY GenVertexArrays(GLsizei n, GLuint* arrays) Context *context = GetValidGlobalContext(); if (context) { - if (context->getClientVersion() < 3) + if (!context->skipValidation() && !ValidateGenVertexArrays(context, n, arrays)) { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - - if (n < 0) - { - context->recordError(Error(GL_INVALID_VALUE)); return; } @@ -898,9 +639,8 @@ GLboolean GL_APIENTRY IsVertexArray(GLuint array) Context *context = GetValidGlobalContext(); if (context) { - if (context->getClientVersion() < 3) + if (!ValidateIsVertexArray(context)) { - context->recordError(Error(GL_INVALID_OPERATION)); return GL_FALSE; } @@ -1005,41 +745,12 @@ void GL_APIENTRY BeginTransformFeedback(GLenum primitiveMode) Context *context = GetValidGlobalContext(); if (context) { - if (context->getClientVersion() < 3) + if (!context->skipValidation() && !ValidateBeginTransformFeedback(context, primitiveMode)) { - context->recordError(Error(GL_INVALID_OPERATION)); return; } - switch (primitiveMode) - { - case GL_TRIANGLES: - case GL_LINES: - case GL_POINTS: - break; - - default: - context->recordError(Error(GL_INVALID_ENUM)); - return; - } - - TransformFeedback *transformFeedback = context->getState().getCurrentTransformFeedback(); - ASSERT(transformFeedback != NULL); - - if (transformFeedback->isActive()) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - - if (transformFeedback->isPaused()) - { - transformFeedback->resume(); - } - else - { - transformFeedback->begin(primitiveMode); - } + context->beginTransformFeedback(primitiveMode); } } @@ -1258,13 +969,11 @@ void GL_APIENTRY TransformFeedbackVaryings(GLuint program, GLsizei count, const return; } - if (!ValidProgram(context, program)) + Program *programObject = GetValidProgram(context, program); + if (!programObject) { - return; - } - - Program *programObject = context->getProgram(program); - ASSERT(programObject); + return; + } programObject->setTransformFeedbackVaryings(count, varyings, bufferMode); } @@ -1291,14 +1000,12 @@ void GL_APIENTRY GetTransformFeedbackVarying(GLuint program, GLuint index, GLsiz return; } - if (!ValidProgram(context, program)) + Program *programObject = GetValidProgram(context, program); + if (!programObject) { return; } - Program *programObject = context->getProgram(program); - ASSERT(programObject); - if (index >= static_cast(programObject->getTransformFeedbackVaryingCount())) { context->recordError(Error(GL_INVALID_VALUE)); @@ -1714,43 +1421,13 @@ void GL_APIENTRY ClearBufferiv(GLenum buffer, GLint drawbuffer, const GLint* val Context *context = GetValidGlobalContext(); if (context) { - if (!ValidateClearBuffer(context)) - { - return; - } - - switch (buffer) + if (!context->skipValidation() && + !ValidateClearBufferiv(context, buffer, drawbuffer, value)) { - case GL_COLOR: - if (drawbuffer < 0 || static_cast(drawbuffer) >= context->getCaps().maxDrawBuffers) - { - context->recordError(Error(GL_INVALID_VALUE)); - return; - } - break; - - case GL_STENCIL: - if (drawbuffer != 0) - { - context->recordError(Error(GL_INVALID_VALUE)); - return; - } - break; - - default: - context->recordError(Error(GL_INVALID_ENUM)); return; } - Framebuffer *framebufferObject = context->getState().getDrawFramebuffer(); - ASSERT(framebufferObject); - - Error error = framebufferObject->clearBufferiv(context->getState(), buffer, drawbuffer, value); - if (error.isError()) - { - context->recordError(error); - return; - } + context->clearBufferiv(buffer, drawbuffer, value); } } @@ -1762,35 +1439,13 @@ void GL_APIENTRY ClearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint* v Context *context = GetValidGlobalContext(); if (context) { - if (!ValidateClearBuffer(context)) - { - return; - } - - switch (buffer) + if (!context->skipValidation() && + !ValidateClearBufferuiv(context, buffer, drawbuffer, value)) { - case GL_COLOR: - if (drawbuffer < 0 || static_cast(drawbuffer) >= context->getCaps().maxDrawBuffers) - { - context->recordError(Error(GL_INVALID_VALUE)); - return; - } - break; - - default: - context->recordError(Error(GL_INVALID_ENUM)); return; } - Framebuffer *framebufferObject = context->getState().getDrawFramebuffer(); - ASSERT(framebufferObject); - - Error error = framebufferObject->clearBufferuiv(context->getState(), buffer, drawbuffer, value); - if (error.isError()) - { - context->recordError(error); - return; - } + context->clearBufferuiv(buffer, drawbuffer, value); } } @@ -1802,43 +1457,13 @@ void GL_APIENTRY ClearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat* v Context *context = GetValidGlobalContext(); if (context) { - if (!ValidateClearBuffer(context)) + if (!context->skipValidation() && + !ValidateClearBufferfv(context, buffer, drawbuffer, value)) { return; } - switch (buffer) - { - case GL_COLOR: - if (drawbuffer < 0 || static_cast(drawbuffer) >= context->getCaps().maxDrawBuffers) - { - context->recordError(Error(GL_INVALID_VALUE)); - return; - } - break; - - case GL_DEPTH: - if (drawbuffer != 0) - { - context->recordError(Error(GL_INVALID_VALUE)); - return; - } - break; - - default: - context->recordError(Error(GL_INVALID_ENUM)); - return; - } - - Framebuffer *framebufferObject = context->getState().getDrawFramebuffer(); - ASSERT(framebufferObject); - - Error error = framebufferObject->clearBufferfv(context->getState(), buffer, drawbuffer, value); - if (error.isError()) - { - context->recordError(error); - return; - } + context->clearBufferfv(buffer, drawbuffer, value); } } @@ -1850,35 +1475,13 @@ void GL_APIENTRY ClearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, G Context *context = GetValidGlobalContext(); if (context) { - if (!ValidateClearBuffer(context)) + if (!context->skipValidation() && + !ValidateClearBufferfi(context, buffer, drawbuffer, depth, stencil)) { return; } - switch (buffer) - { - case GL_DEPTH_STENCIL: - if (drawbuffer != 0) - { - context->recordError(Error(GL_INVALID_VALUE)); - return; - } - break; - - default: - context->recordError(Error(GL_INVALID_ENUM)); - return; - } - - Framebuffer *framebufferObject = context->getState().getDrawFramebuffer(); - ASSERT(framebufferObject); - - Error error = framebufferObject->clearBufferfi(context->getState(), buffer, drawbuffer, depth, stencil); - if (error.isError()) - { - context->recordError(error); - return; - } + context->clearBufferfi(buffer, drawbuffer, depth, stencil); } } @@ -1996,20 +1599,11 @@ void GL_APIENTRY GetUniformIndices(GLuint program, GLsizei uniformCount, const G return; } - Program *programObject = context->getProgram(program); + Program *programObject = GetValidProgram(context, program); if (!programObject) { - if (context->getShader(program)) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - else - { - context->recordError(Error(GL_INVALID_VALUE)); - return; - } + return; } if (!programObject->isLinked()) @@ -2049,20 +1643,11 @@ void GL_APIENTRY GetActiveUniformsiv(GLuint program, GLsizei uniformCount, const return; } - Program *programObject = context->getProgram(program); + Program *programObject = GetValidProgram(context, program); if (!programObject) { - if (context->getShader(program)) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - else - { - context->recordError(Error(GL_INVALID_VALUE)); - return; - } + return; } switch (pname) @@ -2120,20 +1705,10 @@ GLuint GL_APIENTRY GetUniformBlockIndex(GLuint program, const GLchar* uniformBlo return GL_INVALID_INDEX; } - Program *programObject = context->getProgram(program); - + Program *programObject = GetValidProgram(context, program); if (!programObject) { - if (context->getShader(program)) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return GL_INVALID_INDEX; - } - else - { - context->recordError(Error(GL_INVALID_VALUE)); - return GL_INVALID_INDEX; - } + return GL_INVALID_INDEX; } return programObject->getUniformBlockIndex(uniformBlockName); @@ -2155,20 +1730,11 @@ void GL_APIENTRY GetActiveUniformBlockiv(GLuint program, GLuint uniformBlockInde context->recordError(Error(GL_INVALID_OPERATION)); return; } - Program *programObject = context->getProgram(program); + Program *programObject = GetValidProgram(context, program); if (!programObject) { - if (context->getShader(program)) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - else - { - context->recordError(Error(GL_INVALID_VALUE)); - return; - } + return; } if (uniformBlockIndex >= programObject->getActiveUniformBlockCount()) @@ -2213,20 +1779,11 @@ void GL_APIENTRY GetActiveUniformBlockName(GLuint program, GLuint uniformBlockIn return; } - Program *programObject = context->getProgram(program); + Program *programObject = GetValidProgram(context, program); if (!programObject) { - if (context->getShader(program)) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - else - { - context->recordError(Error(GL_INVALID_VALUE)); - return; - } + return; } if (uniformBlockIndex >= programObject->getActiveUniformBlockCount()) @@ -2259,20 +1816,11 @@ void GL_APIENTRY UniformBlockBinding(GLuint program, GLuint uniformBlockIndex, G return; } - Program *programObject = context->getProgram(program); + Program *programObject = GetValidProgram(context, program); if (!programObject) { - if (context->getShader(program)) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - else - { - context->recordError(Error(GL_INVALID_VALUE)); - return; - } + return; } // if never linked, there won't be any uniform blocks @@ -2305,7 +1853,7 @@ void GL_APIENTRY DrawArraysInstanced(GLenum mode, GLint first, GLsizei count, GL return; } - Error error = context->drawArrays(mode, first, count, instanceCount); + Error error = context->drawArraysInstanced(mode, first, count, instanceCount); if (error.isError()) { context->recordError(error); @@ -2328,13 +1876,14 @@ void GL_APIENTRY DrawElementsInstanced(GLenum mode, GLsizei count, GLenum type, return; } - rx::RangeUI indexRange; + IndexRange indexRange; if (!ValidateDrawElementsInstanced(context, mode, count, type, indices, instanceCount, &indexRange)) { return; } - Error error = context->drawElements(mode, count, type, indices, instanceCount, indexRange); + Error error = + context->drawElementsInstanced(mode, count, type, indices, instanceCount, indexRange); if (error.isError()) { context->recordError(error); @@ -2738,15 +2287,8 @@ void GL_APIENTRY GenSamplers(GLsizei count, GLuint* samplers) Context *context = GetValidGlobalContext(); if (context) { - if (context->getClientVersion() < 3) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - - if (count < 0) + if (!context->skipValidation() && !ValidateGenSamplers(context, count, samplers)) { - context->recordError(Error(GL_INVALID_VALUE)); return; } @@ -2764,15 +2306,8 @@ void GL_APIENTRY DeleteSamplers(GLsizei count, const GLuint* samplers) Context *context = GetValidGlobalContext(); if (context) { - if (context->getClientVersion() < 3) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - - if (count < 0) + if (!context->skipValidation() && !ValidateDeleteSamplers(context, count, samplers)) { - context->recordError(Error(GL_INVALID_VALUE)); return; } @@ -2838,28 +2373,12 @@ void GL_APIENTRY SamplerParameteri(GLuint sampler, GLenum pname, GLint param) Context *context = GetValidGlobalContext(); if (context) { - if (context->getClientVersion() < 3) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - - if (!ValidateSamplerObjectParameter(context, pname)) - { - return; - } - - if (!ValidateTexParamParameters(context, pname, param)) + if (!context->skipValidation() && + !ValidateSamplerParameteri(context, sampler, pname, param)) { return; } - if (!context->isSampler(sampler)) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - context->samplerParameteri(sampler, pname, param); } } @@ -2876,25 +2395,9 @@ void GL_APIENTRY SamplerParameterf(GLuint sampler, GLenum pname, GLfloat param) Context *context = GetValidGlobalContext(); if (context) { - if (context->getClientVersion() < 3) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - - if (!ValidateSamplerObjectParameter(context, pname)) - { - return; - } - - if (!ValidateTexParamParameters(context, pname, static_cast(param))) - { - return; - } - - if (!context->isSampler(sampler)) + if (!context->skipValidation() && + !ValidateSamplerParameterf(context, sampler, pname, param)) { - context->recordError(Error(GL_INVALID_OPERATION)); return; } @@ -3012,9 +2515,11 @@ void GL_APIENTRY BindTransformFeedback(GLenum target, GLuint id) } // Cannot bind a transform feedback object that does not exist (3.0.2 pg 85 section 2.14.1) - if (context->getTransformFeedback(id) == NULL) + if (!context->isTransformFeedbackGenerated(id)) { - context->recordError(Error(GL_INVALID_OPERATION)); + context->recordError( + Error(GL_INVALID_OPERATION, + "Cannot bind a transform feedback object that does not exist.")); return; } @@ -3036,9 +2541,8 @@ void GL_APIENTRY DeleteTransformFeedbacks(GLsizei n, const GLuint* ids) Context *context = GetValidGlobalContext(); if (context) { - if (context->getClientVersion() < 3) + if (!context->skipValidation() && !ValidateDeleteTransformFeedbacks(context, n, ids)) { - context->recordError(Error(GL_INVALID_OPERATION)); return; } @@ -3056,9 +2560,8 @@ void GL_APIENTRY GenTransformFeedbacks(GLsizei n, GLuint* ids) Context *context = GetValidGlobalContext(); if (context) { - if (context->getClientVersion() < 3) + if (!context->skipValidation() && !ValidateGenTransformFeedbacks(context, n, ids)) { - context->recordError(Error(GL_INVALID_OPERATION)); return; } @@ -3082,7 +2585,15 @@ GLboolean GL_APIENTRY IsTransformFeedback(GLuint id) return GL_FALSE; } - return ((context->getTransformFeedback(id) != NULL) ? GL_TRUE : GL_FALSE); + if (id == 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 = context->getTransformFeedback(id); + return ((transformFeedback != nullptr) ? GL_TRUE : GL_FALSE); } return GL_FALSE; @@ -3150,14 +2661,20 @@ void GL_APIENTRY GetProgramBinary(GLuint program, GLsizei bufSize, GLsizei* leng Context *context = GetValidGlobalContext(); if (context) { - if (context->getClientVersion() < 3) + if (!ValidateGetProgramBinary(context, program, bufSize, length, binaryFormat, binary)) { - context->recordError(Error(GL_INVALID_OPERATION)); return; } - // TODO: Pipe through to the OES extension for now, needs proper validation - return GetProgramBinaryOES(program, bufSize, length, binaryFormat, binary); + Program *programObject = context->getProgram(program); + ASSERT(programObject != nullptr); + + Error error = programObject->saveBinary(binaryFormat, binary, bufSize, length); + if (error.isError()) + { + context->recordError(error); + return; + } } } @@ -3169,14 +2686,20 @@ void GL_APIENTRY ProgramBinary(GLuint program, GLenum binaryFormat, const GLvoid Context *context = GetValidGlobalContext(); if (context) { - if (context->getClientVersion() < 3) + if (!ValidateProgramBinary(context, program, binaryFormat, binary, length)) { - context->recordError(Error(GL_INVALID_OPERATION)); return; } - // TODO: Pipe through to the OES extension for now, needs proper validation - return ProgramBinaryOES(program, binaryFormat, binary, length); + Program *programObject = context->getProgram(program); + ASSERT(programObject != nullptr); + + Error error = programObject->loadBinary(binaryFormat, binary, length); + if (error.isError()) + { + context->recordError(error); + return; + } } } @@ -3188,14 +2711,13 @@ void GL_APIENTRY ProgramParameteri(GLuint program, GLenum pname, GLint value) Context *context = GetValidGlobalContext(); if (context) { - if (context->getClientVersion() < 3) + if (!context->skipValidation() && + !ValidateProgramParameteri(context, program, pname, value)) { - context->recordError(Error(GL_INVALID_OPERATION)); return; } - // glProgramParameteri - UNIMPLEMENTED(); + context->programParameteri(program, pname, value); } } @@ -3207,29 +2729,13 @@ void GL_APIENTRY InvalidateFramebuffer(GLenum target, GLsizei numAttachments, co Context *context = GetValidGlobalContext(); if (context) { - if (context->getClientVersion() < 3) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - - if (!ValidateInvalidateFramebufferParameters(context, target, numAttachments, attachments)) + if (!context->skipValidation() && + !ValidateInvalidateFramebuffer(context, target, numAttachments, attachments)) { return; } - Framebuffer *framebuffer = context->getState().getTargetFramebuffer(target); - ASSERT(framebuffer); - - if (framebuffer->checkStatus(context->getData()) == GL_FRAMEBUFFER_COMPLETE) - { - Error error = framebuffer->invalidate(numAttachments, attachments); - if (error.isError()) - { - context->recordError(error); - return; - } - } + context->invalidateFramebuffer(target, numAttachments, attachments); } } @@ -3242,30 +2748,13 @@ void GL_APIENTRY InvalidateSubFramebuffer(GLenum target, GLsizei numAttachments, Context *context = GetValidGlobalContext(); if (context) { - if (context->getClientVersion() < 3) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - - if (!ValidateInvalidateFramebufferParameters(context, target, numAttachments, attachments)) + if (!context->skipValidation() && + !ValidateInvalidateFramebuffer(context, target, numAttachments, attachments)) { return; } - Framebuffer *framebuffer = context->getState().getTargetFramebuffer(target); - ASSERT(framebuffer); - - if (framebuffer->checkStatus(context->getData()) == GL_FRAMEBUFFER_COMPLETE) - { - Rectangle area(x, y, width, height); - Error error = framebuffer->invalidateSub(numAttachments, attachments, area); - if (error.isError()) - { - context->recordError(error); - return; - } - } + context->invalidateSubFramebuffer(target, numAttachments, attachments, x, y, width, height); } } @@ -3283,7 +2772,8 @@ void GL_APIENTRY TexStorage2D(GLenum target, GLsizei levels, GLenum internalform return; } - if (!ValidateES3TexStorageParameters(context, target, levels, internalformat, width, height, 1)) + if (!ValidateES3TexStorage2DParameters(context, target, levels, internalformat, width, + height, 1)) { return; } @@ -3314,7 +2804,8 @@ void GL_APIENTRY TexStorage3D(GLenum target, GLsizei levels, GLenum internalform return; } - if (!ValidateES3TexStorageParameters(context, target, levels, internalformat, width, height, depth)) + if (!ValidateES3TexStorage3DParameters(context, target, levels, internalformat, width, + height, depth)) { return; } @@ -3369,7 +2860,7 @@ void GL_APIENTRY GetInternalformativ(GLenum target, GLenum internalformat, GLenu case GL_NUM_SAMPLE_COUNTS: if (bufSize != 0) { - *params = formatCaps.sampleCounts.size(); + *params = static_cast(formatCaps.sampleCounts.size()); } break; diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/global_state.cpp b/Source/ThirdParty/ANGLE/src/libGLESv2/global_state.cpp index 686f0bf49bc0..b99c3e1ca9ba 100644 --- a/Source/ThirdParty/ANGLE/src/libGLESv2/global_state.cpp +++ b/Source/ThirdParty/ANGLE/src/libGLESv2/global_state.cpp @@ -55,13 +55,6 @@ Current *AllocateCurrent() return current; } -void DeallocateCurrent() -{ - Current *current = reinterpret_cast(GetTLSValue(currentTLS)); - SafeDelete(current); - SetTLSValue(currentTLS, NULL); -} - Current *GetCurrentData() { // Create a TLS index if one has not been created for this DLL @@ -78,6 +71,14 @@ Current *GetCurrentData() } #ifdef ANGLE_PLATFORM_WINDOWS + +void DeallocateCurrent() +{ + Current *current = reinterpret_cast(GetTLSValue(currentTLS)); + SafeDelete(current); + SetTLSValue(currentTLS, NULL); +} + extern "C" BOOL WINAPI DllMain(HINSTANCE, DWORD reason, LPVOID) { switch (reason) diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/libGLESv2.cpp b/Source/ThirdParty/ANGLE/src/libGLESv2/libGLESv2.cpp index 038f0b4e98cf..42b749f3739c 100644 --- a/Source/ThirdParty/ANGLE/src/libGLESv2/libGLESv2.cpp +++ b/Source/ThirdParty/ANGLE/src/libGLESv2/libGLESv2.cpp @@ -9,7 +9,6 @@ #include "libGLESv2/entry_points_gles_2_0.h" #include "libGLESv2/entry_points_gles_2_0_ext.h" #include "libGLESv2/entry_points_gles_3_0.h" -#include "libGLESv2/entry_points_gles_3_0_ext.h" #include "common/event_tracer.h" @@ -1256,6 +1255,11 @@ void GL_APIENTRY glRenderbufferStorageMultisampleANGLE(GLenum target, GLsizei sa return gl::RenderbufferStorageMultisampleANGLE(target, samples, internalformat, width, height); } +void GL_APIENTRY glDiscardFramebufferEXT(GLenum target, GLsizei numAttachments, const GLenum *attachments) +{ + return gl::DiscardFramebufferEXT(target, numAttachments, attachments); +} + void GL_APIENTRY glDeleteFencesNV(GLsizei n, const GLuint* fences) { return gl::DeleteFencesNV(n, fences); @@ -1346,16 +1350,36 @@ void GL_APIENTRY glEndQueryEXT(GLenum target) return gl::EndQueryEXT(target); } +void GL_APIENTRY glQueryCounterEXT(GLuint id, GLenum target) +{ + return gl::QueryCounterEXT(id, target); +} + void GL_APIENTRY glGetQueryivEXT(GLenum target, GLenum pname, GLint *params) { return gl::GetQueryivEXT(target, pname, params); } +void GL_APIENTRY glGetQueryObjectivEXT(GLuint id, GLenum pname, GLint *params) +{ + return gl::GetQueryObjectivEXT(id, pname, params); +} + void GL_APIENTRY glGetQueryObjectuivEXT(GLuint id, GLenum pname, GLuint *params) { return gl::GetQueryObjectuivEXT(id, pname, params); } +void GL_APIENTRY glGetQueryObjecti64vEXT(GLuint id, GLenum pname, GLint64 *params) +{ + return gl::GetQueryObjecti64vEXT(id, pname, params); +} + +void GL_APIENTRY glGetQueryObjectui64vEXT(GLuint id, GLenum pname, GLuint64 *params) +{ + return gl::GetQueryObjectui64vEXT(id, pname, params); +} + void GL_APIENTRY glDrawBuffersEXT(GLsizei n, const GLenum *bufs) { return gl::DrawBuffersEXT(n, bufs); @@ -1411,4 +1435,131 @@ void GL_APIENTRY glFlushMappedBufferRangeEXT(GLenum target, GLintptr offset, GLs return gl::FlushMappedBufferRangeEXT(target, offset, length); } +void GL_APIENTRY glInsertEventMarkerEXT(GLsizei length, const char *marker) +{ + return gl::InsertEventMarkerEXT(length, marker); +} + +void GL_APIENTRY glPushGroupMarkerEXT(GLsizei length, const char *marker) +{ + return gl::PushGroupMarkerEXT(length, marker); +} + +void GL_APIENTRY glPopGroupMarkerEXT() +{ + return gl::PopGroupMarkerEXT(); +} + +void GL_APIENTRY glEGLImageTargetTexture2DOES(GLenum target, GLeglImageOES image) +{ + return gl::EGLImageTargetTexture2DOES(target, image); +} + +void GL_APIENTRY glEGLImageTargetRenderbufferStorageOES(GLenum target, GLeglImageOES image) +{ + return gl::EGLImageTargetRenderbufferStorageOES(target, image); +} + +void GL_APIENTRY glBindVertexArrayOES(GLuint array) +{ + return gl::BindVertexArrayOES(array); +} + +void GL_APIENTRY glDeleteVertexArraysOES(GLsizei n, const GLuint *arrays) +{ + return gl::DeleteVertexArraysOES(n, arrays); +} + +void GL_APIENTRY glGenVertexArraysOES(GLsizei n, GLuint *arrays) +{ + return gl::GenVertexArraysOES(n, arrays); +} + +GLboolean GL_APIENTRY glIsVertexArrayOES(GLuint array) +{ + return gl::IsVertexArrayOES(array); +} + +void GL_APIENTRY glDebugMessageControlKHR(GLenum source, + GLenum type, + GLenum severity, + GLsizei count, + const GLuint *ids, + GLboolean enabled) +{ + return gl::DebugMessageControlKHR(source, type, severity, count, ids, enabled); +} + +void GL_APIENTRY glDebugMessageInsertKHR(GLenum source, + GLenum type, + GLuint id, + GLenum severity, + GLsizei length, + const GLchar *buf) +{ + return gl::DebugMessageInsertKHR(source, type, id, severity, length, buf); +} + +void GL_APIENTRY glDebugMessageCallbackKHR(GLDEBUGPROCKHR callback, const void *userParam) +{ + return gl::DebugMessageCallbackKHR(callback, userParam); +} + +GLuint GL_APIENTRY glGetDebugMessageLogKHR(GLuint count, + GLsizei bufSize, + GLenum *sources, + GLenum *types, + GLuint *ids, + GLenum *severities, + GLsizei *lengths, + GLchar *messageLog) +{ + return gl::GetDebugMessageLogKHR(count, bufSize, sources, types, ids, severities, lengths, + messageLog); +} + +void GL_APIENTRY glPushDebugGroupKHR(GLenum source, + GLuint id, + GLsizei length, + const GLchar *message) +{ + return gl::PushDebugGroupKHR(source, id, length, message); +} + +void GL_APIENTRY glPopDebugGroupKHR(void) +{ + return gl::PopDebugGroupKHR(); +} + +void GL_APIENTRY glObjectLabelKHR(GLenum identifier, + GLuint name, + GLsizei length, + const GLchar *label) +{ + return gl::ObjectLabelKHR(identifier, name, length, label); +} + +void GL_APIENTRY +glGetObjectLabelKHR(GLenum identifier, GLuint name, GLsizei bufSize, GLsizei *length, GLchar *label) +{ + return gl::GetObjectLabelKHR(identifier, name, bufSize, length, label); +} + +void GL_APIENTRY glObjectPtrLabelKHR(const void *ptr, GLsizei length, const GLchar *label) +{ + return gl::ObjectPtrLabelKHR(ptr, length, label); +} + +void GL_APIENTRY glGetObjectPtrLabelKHR(const void *ptr, + GLsizei bufSize, + GLsizei *length, + GLchar *label) +{ + return gl::GetObjectPtrLabelKHR(ptr, bufSize, length, label); +} + +void GL_APIENTRY glGetPointervKHR(GLenum pname, void **params) +{ + return gl::GetPointervKHR(pname, params); +} } diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/libGLESv2.def b/Source/ThirdParty/ANGLE/src/libGLESv2/libGLESv2.def index 3ff32fe60d24..0aebb6c86404 100644 --- a/Source/ThirdParty/ANGLE/src/libGLESv2/libGLESv2.def +++ b/Source/ThirdParty/ANGLE/src/libGLESv2/libGLESv2.def @@ -177,6 +177,31 @@ EXPORTS glGetBufferPointervOES @287 glMapBufferRangeEXT @288 glFlushMappedBufferRangeEXT @289 + glDiscardFramebufferEXT @293 + glInsertEventMarkerEXT @294 + glPushGroupMarkerEXT @295 + glPopGroupMarkerEXT @296 + glEGLImageTargetTexture2DOES @297 + glEGLImageTargetRenderbufferStorageOES @298 + glBindVertexArrayOES @299 + glDeleteVertexArraysOES @300 + glGenVertexArraysOES @301 + glIsVertexArrayOES @302 + glDebugMessageControlKHR @303 + glDebugMessageInsertKHR @304 + glDebugMessageCallbackKHR @305 + glGetDebugMessageLogKHR @306 + glPushDebugGroupKHR @307 + glPopDebugGroupKHR @308 + glObjectLabelKHR @309 + glGetObjectLabelKHR @310 + glObjectPtrLabelKHR @311 + glGetObjectPtrLabelKHR @312 + glGetPointervKHR @313 + glQueryCounterEXT @314 + glGetQueryObjectivEXT @315 + glGetQueryObjecti64vEXT @316 + glGetQueryObjectui64vEXT @317 ; GLES 3.0 Functions glReadBuffer @180 diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/libGLESv2.rc b/Source/ThirdParty/ANGLE/src/libGLESv2/libGLESv2.rc index 909c3080affd..dfae63eaa094 100644 --- a/Source/ThirdParty/ANGLE/src/libGLESv2/libGLESv2.rc +++ b/Source/ThirdParty/ANGLE/src/libGLESv2/libGLESv2.rc @@ -54,8 +54,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION ANGLE_MAJOR_VERSION,ANGLE_MINOR_VERSION,0,0 - PRODUCTVERSION ANGLE_MAJOR_VERSION,ANGLE_MINOR_VERSION,0,0 + FILEVERSION ANGLE_MAJOR_VERSION,ANGLE_MINOR_VERSION,ANGLE_REVISION,0 + PRODUCTVERSION ANGLE_MAJOR_VERSION,ANGLE_MINOR_VERSION,ANGLE_REVISION,0 FILEFLAGSMASK 0x17L #ifdef _DEBUG FILEFLAGS 0x1L diff --git a/Source/ThirdParty/ANGLE/src/third_party/compiler/ArrayBoundsClamper.cpp b/Source/ThirdParty/ANGLE/src/third_party/compiler/ArrayBoundsClamper.cpp index 288f5529adef..fa6c8b8d79ba 100644 --- a/Source/ThirdParty/ANGLE/src/third_party/compiler/ArrayBoundsClamper.cpp +++ b/Source/ThirdParty/ANGLE/src/third_party/compiler/ArrayBoundsClamper.cpp @@ -43,11 +43,12 @@ namespace { class ArrayBoundsClamperMarker : public TIntermTraverser { public: ArrayBoundsClamperMarker() - : mNeedsClamp(false) + : TIntermTraverser(true, false, false), + mNeedsClamp(false) { } - virtual bool visitBinary(Visit visit, TIntermBinary* node) + bool visitBinary(Visit visit, TIntermBinary *node) override { if (node->getOp() == EOpIndexIndirect) { diff --git a/Source/ThirdParty/ANGLE/src/third_party/murmurhash/MurmurHash3.cpp b/Source/ThirdParty/ANGLE/src/third_party/murmurhash/MurmurHash3.cpp index a599c26502ee..4aaa321e1c50 100644 --- a/Source/ThirdParty/ANGLE/src/third_party/murmurhash/MurmurHash3.cpp +++ b/Source/ThirdParty/ANGLE/src/third_party/murmurhash/MurmurHash3.cpp @@ -16,22 +16,20 @@ #if defined(_MSC_VER) -#define FORCE_INLINE __forceinline +#define FORCE_INLINE __forceinline #include -#define ROTL32(x,y) _rotl(x,y) -#define ROTL64(x,y) _rotl64(x,y) +#define ROTL32(x,y) _rotl(x,y) +#define ROTL64(x,y) _rotl64(x,y) #define BIG_CONSTANT(x) (x) // Other compilers -#else // defined(_MSC_VER) +#else // defined(_MSC_VER) -// Ignore GCC force inline warnings -#pragma GCC diagnostic ignored "-Wattributes" -#define FORCE_INLINE __attribute__((always_inline)) +#define FORCE_INLINE inline __attribute__((always_inline)) inline uint32_t rotl32 ( uint32_t x, int8_t r ) { @@ -43,8 +41,8 @@ inline uint64_t rotl64 ( uint64_t x, int8_t r ) return (x << r) | (x >> (64 - r)); } -#define ROTL32(x,y) rotl32(x,y) -#define ROTL64(x,y) rotl64(x,y) +#define ROTL32(x,y) rotl32(x,y) +#define ROTL64(x,y) rotl64(x,y) #define BIG_CONSTANT(x) (x##LLU) @@ -54,12 +52,12 @@ inline uint64_t rotl64 ( uint64_t x, int8_t r ) // Block read - if your platform needs to do endian-swapping or can only // handle aligned reads, do the conversion here -FORCE_INLINE uint32_t getblock ( const uint32_t * p, int i ) +FORCE_INLINE uint32_t getblock32 ( const uint32_t * p, int i ) { return p[i]; } -FORCE_INLINE uint64_t getblock ( const uint64_t * p, int i ) +FORCE_INLINE uint64_t getblock64 ( const uint64_t * p, int i ) { return p[i]; } @@ -67,7 +65,7 @@ FORCE_INLINE uint64_t getblock ( const uint64_t * p, int i ) //----------------------------------------------------------------------------- // Finalization mix - force all bits of a hash block to avalanche -FORCE_INLINE uint32_t fmix ( uint32_t h ) +FORCE_INLINE uint32_t fmix32 ( uint32_t h ) { h ^= h >> 16; h *= 0x85ebca6b; @@ -80,7 +78,7 @@ FORCE_INLINE uint32_t fmix ( uint32_t h ) //---------- -FORCE_INLINE uint64_t fmix ( uint64_t k ) +FORCE_INLINE uint64_t fmix64 ( uint64_t k ) { k ^= k >> 33; k *= BIG_CONSTANT(0xff51afd7ed558ccd); @@ -111,7 +109,7 @@ void MurmurHash3_x86_32 ( const void * key, int len, for(int i = -nblocks; i; i++) { - uint32_t k1 = getblock(blocks,i); + uint32_t k1 = getblock32(blocks,i); k1 *= c1; k1 = ROTL32(k1,15); @@ -142,7 +140,7 @@ void MurmurHash3_x86_32 ( const void * key, int len, h1 ^= len; - h1 = fmix(h1); + h1 = fmix32(h1); *(uint32_t*)out = h1; } @@ -172,10 +170,10 @@ void MurmurHash3_x86_128 ( const void * key, const int len, for(int i = -nblocks; i; i++) { - uint32_t k1 = getblock(blocks,i*4+0); - uint32_t k2 = getblock(blocks,i*4+1); - uint32_t k3 = getblock(blocks,i*4+2); - uint32_t k4 = getblock(blocks,i*4+3); + uint32_t k1 = getblock32(blocks,i*4+0); + uint32_t k2 = getblock32(blocks,i*4+1); + uint32_t k3 = getblock32(blocks,i*4+2); + uint32_t k4 = getblock32(blocks,i*4+3); k1 *= c1; k1 = ROTL32(k1,15); k1 *= c2; h1 ^= k1; @@ -238,10 +236,10 @@ void MurmurHash3_x86_128 ( const void * key, const int len, h1 += h2; h1 += h3; h1 += h4; h2 += h1; h3 += h1; h4 += h1; - h1 = fmix(h1); - h2 = fmix(h2); - h3 = fmix(h3); - h4 = fmix(h4); + h1 = fmix32(h1); + h2 = fmix32(h2); + h3 = fmix32(h3); + h4 = fmix32(h4); h1 += h2; h1 += h3; h1 += h4; h2 += h1; h3 += h1; h4 += h1; @@ -273,8 +271,8 @@ void MurmurHash3_x64_128 ( const void * key, const int len, for(int i = 0; i < nblocks; i++) { - uint64_t k1 = getblock(blocks,i*2+0); - uint64_t k2 = getblock(blocks,i*2+1); + uint64_t k1 = getblock64(blocks,i*2+0); + uint64_t k2 = getblock64(blocks,i*2+1); k1 *= c1; k1 = ROTL64(k1,31); k1 *= c2; h1 ^= k1; @@ -295,23 +293,23 @@ void MurmurHash3_x64_128 ( const void * key, const int len, switch(len & 15) { - case 15: k2 ^= uint64_t(tail[14]) << 48; - case 14: k2 ^= uint64_t(tail[13]) << 40; - case 13: k2 ^= uint64_t(tail[12]) << 32; - case 12: k2 ^= uint64_t(tail[11]) << 24; - case 11: k2 ^= uint64_t(tail[10]) << 16; - case 10: k2 ^= uint64_t(tail[ 9]) << 8; - case 9: k2 ^= uint64_t(tail[ 8]) << 0; + case 15: k2 ^= ((uint64_t)tail[14]) << 48; + case 14: k2 ^= ((uint64_t)tail[13]) << 40; + case 13: k2 ^= ((uint64_t)tail[12]) << 32; + case 12: k2 ^= ((uint64_t)tail[11]) << 24; + case 11: k2 ^= ((uint64_t)tail[10]) << 16; + case 10: k2 ^= ((uint64_t)tail[ 9]) << 8; + case 9: k2 ^= ((uint64_t)tail[ 8]) << 0; k2 *= c2; k2 = ROTL64(k2,33); k2 *= c1; h2 ^= k2; - case 8: k1 ^= uint64_t(tail[ 7]) << 56; - case 7: k1 ^= uint64_t(tail[ 6]) << 48; - case 6: k1 ^= uint64_t(tail[ 5]) << 40; - case 5: k1 ^= uint64_t(tail[ 4]) << 32; - case 4: k1 ^= uint64_t(tail[ 3]) << 24; - case 3: k1 ^= uint64_t(tail[ 2]) << 16; - case 2: k1 ^= uint64_t(tail[ 1]) << 8; - case 1: k1 ^= uint64_t(tail[ 0]) << 0; + case 8: k1 ^= ((uint64_t)tail[ 7]) << 56; + case 7: k1 ^= ((uint64_t)tail[ 6]) << 48; + case 6: k1 ^= ((uint64_t)tail[ 5]) << 40; + case 5: k1 ^= ((uint64_t)tail[ 4]) << 32; + case 4: k1 ^= ((uint64_t)tail[ 3]) << 24; + case 3: k1 ^= ((uint64_t)tail[ 2]) << 16; + case 2: k1 ^= ((uint64_t)tail[ 1]) << 8; + case 1: k1 ^= ((uint64_t)tail[ 0]) << 0; k1 *= c1; k1 = ROTL64(k1,31); k1 *= c2; h1 ^= k1; }; @@ -323,8 +321,8 @@ void MurmurHash3_x64_128 ( const void * key, const int len, h1 += h2; h2 += h1; - h1 = fmix(h1); - h2 = fmix(h2); + h1 = fmix64(h1); + h2 = fmix64(h2); h1 += h2; h2 += h1; @@ -334,3 +332,4 @@ void MurmurHash3_x64_128 ( const void * key, const int len, } //----------------------------------------------------------------------------- + diff --git a/Source/ThirdParty/ANGLE/src/third_party/murmurhash/MurmurHash3.h b/Source/ThirdParty/ANGLE/src/third_party/murmurhash/MurmurHash3.h index bb02cd508f26..ed4ee0e84c61 100644 --- a/Source/ThirdParty/ANGLE/src/third_party/murmurhash/MurmurHash3.h +++ b/Source/ThirdParty/ANGLE/src/third_party/murmurhash/MurmurHash3.h @@ -8,8 +8,22 @@ //----------------------------------------------------------------------------- // Platform-specific functions and macros +// Microsoft Visual Studio + +#if defined(_MSC_VER) && (_MSC_VER < 1600) + +typedef unsigned char uint8_t; +typedef unsigned int uint32_t; +typedef unsigned __int64 uint64_t; + +// Other compilers + +#else // defined(_MSC_VER) + #include +#endif // !defined(_MSC_VER) + //----------------------------------------------------------------------------- void MurmurHash3_x86_32 ( const void * key, int len, uint32_t seed, void * out ); diff --git a/Source/ThirdParty/ANGLE/util/EGLWindow.cpp b/Source/ThirdParty/ANGLE/util/EGLWindow.cpp index 78228bea4339..2f436d97da59 100644 --- a/Source/ThirdParty/ANGLE/util/EGLWindow.cpp +++ b/Source/ThirdParty/ANGLE/util/EGLWindow.cpp @@ -10,19 +10,14 @@ #include "EGLWindow.h" #include "OSWindow.h" - -#ifdef _WIN32 -#include "win32/Win32Timer.h" -#include "win32/Win32Window.h" -#else -#error unsupported OS. -#endif +#include "common/debug.h" EGLPlatformParameters::EGLPlatformParameters() : renderer(EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE), majorVersion(EGL_DONT_CARE), minorVersion(EGL_DONT_CARE), - deviceType(EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE) + deviceType(EGL_DONT_CARE), + presentPath(EGL_DONT_CARE) { } @@ -30,27 +25,82 @@ EGLPlatformParameters::EGLPlatformParameters(EGLint renderer) : renderer(renderer), majorVersion(EGL_DONT_CARE), minorVersion(EGL_DONT_CARE), - deviceType(EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE) + deviceType(EGL_DONT_CARE), + presentPath(EGL_DONT_CARE) +{ + if (renderer == EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE || + renderer == EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE) + { + deviceType = EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE; + } +} + +EGLPlatformParameters::EGLPlatformParameters(EGLint renderer, + EGLint majorVersion, + EGLint minorVersion, + EGLint useWarp) + : renderer(renderer), + majorVersion(majorVersion), + minorVersion(minorVersion), + deviceType(useWarp), + presentPath(EGL_DONT_CARE) { } -EGLPlatformParameters::EGLPlatformParameters(EGLint renderer, EGLint majorVersion, EGLint minorVersion, EGLint useWarp) +EGLPlatformParameters::EGLPlatformParameters(EGLint renderer, + EGLint majorVersion, + EGLint minorVersion, + EGLint useWarp, + EGLint presentPath) : renderer(renderer), majorVersion(majorVersion), minorVersion(minorVersion), - deviceType(useWarp) + deviceType(useWarp), + presentPath(presentPath) { } +bool operator<(const EGLPlatformParameters &a, const EGLPlatformParameters &b) +{ + if (a.renderer != b.renderer) + { + return a.renderer < b.renderer; + } + + if (a.majorVersion != b.majorVersion) + { + return a.majorVersion < b.majorVersion; + } + + if (a.minorVersion != b.minorVersion) + { + return a.minorVersion < b.minorVersion; + } + + if (a.deviceType != b.deviceType) + { + return a.deviceType < b.deviceType; + } + + return a.presentPath < b.presentPath; +} + +bool operator==(const EGLPlatformParameters &a, const EGLPlatformParameters &b) +{ + return (a.renderer == b.renderer) && (a.majorVersion == b.majorVersion) && + (a.minorVersion == b.minorVersion) && (a.deviceType == b.deviceType) && + (a.presentPath == b.presentPath); +} -EGLWindow::EGLWindow(size_t width, size_t height, EGLint glesMajorVersion, const EGLPlatformParameters &platform) - : mSurface(EGL_NO_SURFACE), +EGLWindow::EGLWindow(EGLint glesMajorVersion, + EGLint glesMinorVersion, + const EGLPlatformParameters &platform) + : mDisplay(EGL_NO_DISPLAY), + mSurface(EGL_NO_SURFACE), mContext(EGL_NO_CONTEXT), - mDisplay(EGL_NO_DISPLAY), - mClientVersion(glesMajorVersion), + mClientMajorVersion(glesMajorVersion), + mClientMinorVersion(glesMinorVersion), mPlatform(platform), - mWidth(width), - mHeight(height), mRedBits(-1), mGreenBits(-1), mBlueBits(-1), @@ -58,6 +108,8 @@ EGLWindow::EGLWindow(size_t width, size_t height, EGLint glesMajorVersion, const mDepthBits(-1), mStencilBits(-1), mMultisample(false), + mDebug(false), + mNoError(false), mSwapInterval(-1) { } @@ -100,16 +152,38 @@ bool EGLWindow::initializeGL(OSWindow *osWindow) return false; } - const EGLint displayAttributes[] = + std::vector displayAttributes; + displayAttributes.push_back(EGL_PLATFORM_ANGLE_TYPE_ANGLE); + displayAttributes.push_back(mPlatform.renderer); + displayAttributes.push_back(EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE); + displayAttributes.push_back(mPlatform.majorVersion); + displayAttributes.push_back(EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE); + displayAttributes.push_back(mPlatform.minorVersion); + + if (mPlatform.deviceType != EGL_DONT_CARE) { - EGL_PLATFORM_ANGLE_TYPE_ANGLE, mPlatform.renderer, - EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE, mPlatform.majorVersion, - EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE, mPlatform.minorVersion, - EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE, mPlatform.deviceType, - EGL_NONE, - }; + displayAttributes.push_back(EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE); + displayAttributes.push_back(mPlatform.deviceType); + } + + if (mPlatform.presentPath != EGL_DONT_CARE) + { + const char *extensionString = + static_cast(eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS)); + if (strstr(extensionString, "EGL_ANGLE_experimental_present_path") == nullptr) + { + destroyGL(); + return false; + } + + displayAttributes.push_back(EGL_EXPERIMENTAL_PRESENT_PATH_ANGLE); + displayAttributes.push_back(mPlatform.presentPath); + } + displayAttributes.push_back(EGL_NONE); - mDisplay = eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, osWindow->getNativeDisplay(), displayAttributes); + mDisplay = eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, + reinterpret_cast(osWindow->getNativeDisplay()), + &displayAttributes[0]); if (mDisplay == EGL_NO_DISPLAY) { destroyGL(); @@ -117,7 +191,17 @@ bool EGLWindow::initializeGL(OSWindow *osWindow) } EGLint majorVersion, minorVersion; - if (!eglInitialize(mDisplay, &majorVersion, &minorVersion)) + if (eglInitialize(mDisplay, &majorVersion, &minorVersion) == EGL_FALSE) + { + destroyGL(); + return false; + } + + const char *displayExtensions = eglQueryString(mDisplay, EGL_EXTENSIONS); + + // EGL_KHR_create_context is required to request a non-ES2 context. + bool hasKHRCreateContext = strstr(displayExtensions, "EGL_KHR_create_context") != nullptr; + if (majorVersion != 2 && minorVersion != 0 && !hasKHRCreateContext) { destroyGL(); return false; @@ -152,40 +236,49 @@ bool EGLWindow::initializeGL(OSWindow *osWindow) eglGetConfigAttrib(mDisplay, mConfig, EGL_RED_SIZE, &mRedBits); eglGetConfigAttrib(mDisplay, mConfig, EGL_GREEN_SIZE, &mGreenBits); eglGetConfigAttrib(mDisplay, mConfig, EGL_BLUE_SIZE, &mBlueBits); - eglGetConfigAttrib(mDisplay, mConfig, EGL_ALPHA_SIZE, &mBlueBits); + eglGetConfigAttrib(mDisplay, mConfig, EGL_ALPHA_SIZE, &mAlphaBits); eglGetConfigAttrib(mDisplay, mConfig, EGL_DEPTH_SIZE, &mDepthBits); eglGetConfigAttrib(mDisplay, mConfig, EGL_STENCIL_SIZE, &mStencilBits); std::vector surfaceAttributes; - if (strstr(eglQueryString(mDisplay, EGL_EXTENSIONS), "EGL_NV_post_sub_buffer") != nullptr) + if (strstr(displayExtensions, "EGL_NV_post_sub_buffer") != nullptr) { surfaceAttributes.push_back(EGL_POST_SUB_BUFFER_SUPPORTED_NV); surfaceAttributes.push_back(EGL_TRUE); } - surfaceAttributes.push_back(EGL_NONE); surfaceAttributes.push_back(EGL_NONE); mSurface = eglCreateWindowSurface(mDisplay, mConfig, osWindow->getNativeWindow(), &surfaceAttributes[0]); - if (mSurface == EGL_NO_SURFACE) - { - eglGetError(); // Clear error and try again - mSurface = eglCreateWindowSurface(mDisplay, mConfig, NULL, NULL); - } - if (eglGetError() != EGL_SUCCESS) { destroyGL(); return false; } + ASSERT(mSurface != EGL_NO_SURFACE); - EGLint contextAttibutes[] = + std::vector contextAttributes; + if (hasKHRCreateContext) { - EGL_CONTEXT_CLIENT_VERSION, mClientVersion, - EGL_NONE - }; + contextAttributes.push_back(EGL_CONTEXT_MAJOR_VERSION_KHR); + contextAttributes.push_back(mClientMajorVersion); + + contextAttributes.push_back(EGL_CONTEXT_MINOR_VERSION_KHR); + contextAttributes.push_back(mClientMinorVersion); + + contextAttributes.push_back(EGL_CONTEXT_OPENGL_DEBUG); + contextAttributes.push_back(mDebug ? EGL_TRUE : EGL_FALSE); + + // TODO(jmadill): Check for the extension string. + // bool hasKHRCreateContextNoError = strstr(displayExtensions, + // "EGL_KHR_create_context_no_error") != nullptr; + + contextAttributes.push_back(EGL_CONTEXT_OPENGL_NO_ERROR_KHR); + contextAttributes.push_back(mNoError ? EGL_TRUE : EGL_FALSE); + } + contextAttributes.push_back(EGL_NONE); - mContext = eglCreateContext(mDisplay, mConfig, NULL, contextAttibutes); + mContext = eglCreateContext(mDisplay, mConfig, nullptr, &contextAttributes[0]); if (eglGetError() != EGL_SUCCESS) { destroyGL(); @@ -237,3 +330,36 @@ bool EGLWindow::isGLInitialized() const mContext != EGL_NO_CONTEXT && mDisplay != EGL_NO_DISPLAY; } + +// Find an EGLConfig that is an exact match for the specified attributes. EGL_FALSE is returned if +// the EGLConfig is found. This indicates that the EGLConfig is not supported. +EGLBoolean EGLWindow::FindEGLConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *config) +{ + EGLint numConfigs = 0; + eglGetConfigs(dpy, nullptr, 0, &numConfigs); + std::vector allConfigs(numConfigs); + eglGetConfigs(dpy, allConfigs.data(), static_cast(allConfigs.size()), &numConfigs); + + for (size_t i = 0; i < allConfigs.size(); i++) + { + bool matchFound = true; + for (const EGLint *curAttrib = attrib_list; curAttrib[0] != EGL_NONE; curAttrib += 2) + { + EGLint actualValue = EGL_DONT_CARE; + eglGetConfigAttrib(dpy, allConfigs[i], curAttrib[0], &actualValue); + if (curAttrib[1] != actualValue) + { + matchFound = false; + break; + } + } + + if (matchFound) + { + *config = allConfigs[i]; + return EGL_TRUE; + } + } + + return EGL_FALSE; +} diff --git a/Source/ThirdParty/ANGLE/util/EGLWindow.h b/Source/ThirdParty/ANGLE/util/EGLWindow.h index 8ee7acb4d062..9651c3c89f2a 100644 --- a/Source/ThirdParty/ANGLE/util/EGLWindow.h +++ b/Source/ThirdParty/ANGLE/util/EGLWindow.h @@ -7,20 +7,17 @@ #ifndef UTIL_EGLWINDOW_H_ #define UTIL_EGLWINDOW_H_ -#define GL_GLEXT_PROTOTYPES +#include +#include +#include +#include -#include -#include #include #include +#include #include #include -#include -#include -#include -#include - #include "common/angleutils.h" class OSWindow; @@ -37,22 +34,30 @@ struct EGLPlatformParameters EGLint majorVersion; EGLint minorVersion; EGLint deviceType; + EGLint presentPath; EGLPlatformParameters(); explicit EGLPlatformParameters(EGLint renderer); EGLPlatformParameters(EGLint renderer, EGLint majorVersion, EGLint minorVersion, EGLint deviceType); + EGLPlatformParameters(EGLint renderer, + EGLint majorVersion, + EGLint minorVersion, + EGLint deviceType, + EGLint presentPath); }; +bool operator<(const EGLPlatformParameters &a, const EGLPlatformParameters &b); +bool operator==(const EGLPlatformParameters &a, const EGLPlatformParameters &b); + class EGLWindow : angle::NonCopyable { public: - EGLWindow(size_t width, size_t height, EGLint glesMajorVersion, const EGLPlatformParameters &platform); + EGLWindow(EGLint glesMajorVersion, + EGLint glesMinorVersion, + const EGLPlatformParameters &platform); ~EGLWindow(); - void setClientVersion(EGLint glesMajorVersion) { mClientVersion = glesMajorVersion; } - void setWidth(size_t width) { mWidth = width; } - void setHeight(size_t height) { mHeight = height; } void setConfigRedBits(int bits) { mRedBits = bits; } void setConfigGreenBits(int bits) { mGreenBits = bits; } void setConfigBlueBits(int bits) { mBlueBits = bits; } @@ -60,18 +65,21 @@ class EGLWindow : angle::NonCopyable void setConfigDepthBits(int bits) { mDepthBits = bits; } void setConfigStencilBits(int bits) { mStencilBits = bits; } void setMultisample(bool multisample) { mMultisample = multisample; } + void setDebugEnabled(bool debug) { mDebug = debug; } + void setNoErrorEnabled(bool noError) { mNoError = noError; } void setSwapInterval(EGLint swapInterval) { mSwapInterval = swapInterval; } + static EGLBoolean FindEGLConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *config); + void swap(); - EGLint getClientVersion() const { return mClientVersion; } + EGLint getClientMajorVersion() const { return mClientMajorVersion; } + EGLint getClientMinorVersion() const { return mClientMinorVersion; } const EGLPlatformParameters &getPlatform() const { return mPlatform; } EGLConfig getConfig() const; EGLDisplay getDisplay() const; EGLSurface getSurface() const; EGLContext getContext() const; - size_t getWidth() const { return mWidth; } - size_t getHeight() const { return mHeight; } int getConfigRedBits() const { return mRedBits; } int getConfigGreenBits() const { return mGreenBits; } int getConfigBlueBits() const { return mBlueBits; } @@ -79,6 +87,7 @@ class EGLWindow : angle::NonCopyable int getConfigDepthBits() const { return mDepthBits; } int getConfigStencilBits() const { return mStencilBits; } bool isMultisample() const { return mMultisample; } + bool isDebugEnabled() const { return mDebug; } EGLint getSwapInterval() const { return mSwapInterval; } bool initializeGL(OSWindow *osWindow); @@ -91,10 +100,9 @@ class EGLWindow : angle::NonCopyable EGLSurface mSurface; EGLContext mContext; - EGLint mClientVersion; + EGLint mClientMajorVersion; + EGLint mClientMinorVersion; EGLPlatformParameters mPlatform; - size_t mWidth; - size_t mHeight; int mRedBits; int mGreenBits; int mBlueBits; @@ -102,6 +110,8 @@ class EGLWindow : angle::NonCopyable int mDepthBits; int mStencilBits; bool mMultisample; + bool mDebug; + bool mNoError; EGLint mSwapInterval; }; diff --git a/Source/ThirdParty/ANGLE/util/Matrix.cpp b/Source/ThirdParty/ANGLE/util/Matrix.cpp new file mode 100644 index 000000000000..52c3d3867a79 --- /dev/null +++ b/Source/ThirdParty/ANGLE/util/Matrix.cpp @@ -0,0 +1,302 @@ +// +// Copyright (c) 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. +// +// Matrix: +// Helper class for doing matrix math. +// + +#include "Matrix.h" + +#define _USE_MATH_DEFINES +#include +#include + +Matrix4::Matrix4() +{ + data[0] = 1.0f; + data[4] = 0.0f; + data[8] = 0.0f; + data[12] = 0.0f; + data[1] = 0.0f; + data[5] = 1.0f; + data[9] = 0.0f; + data[13] = 0.0f; + data[2] = 0.0f; + data[6] = 0.0f; + data[10] = 1.0f; + data[14] = 0.0f; + data[3] = 0.0f; + data[7] = 0.0f; + data[11] = 0.0f; + data[15] = 1.0f; +} + +Matrix4::Matrix4(float m00, + float m01, + float m02, + float m03, + float m10, + float m11, + float m12, + float m13, + float m20, + float m21, + float m22, + float m23, + float m30, + float m31, + float m32, + float m33) +{ + data[0] = m00; + data[4] = m01; + data[8] = m02; + data[12] = m03; + data[1] = m10; + data[5] = m11; + data[9] = m12; + data[13] = m13; + data[2] = m20; + data[6] = m21; + data[10] = m22; + data[14] = m23; + data[3] = m30; + data[7] = m31; + data[11] = m32; + data[15] = m33; +} + +Matrix4 Matrix4::identity() +{ + return Matrix4(1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 1.0f); +} + +Matrix4 Matrix4::rotate(float angle, const Vector3 &p) +{ + Vector3 u = Vector3::normalize(p); + float theta = static_cast(angle * (M_PI / 180.0f)); + float cos_t = cosf(theta); + float sin_t = sinf(theta); + + return Matrix4( + cos_t + (u.x * u.x * (1.0f - cos_t)), (u.x * u.y * (1.0f - cos_t)) - (u.z * sin_t), + (u.x * u.z * (1.0f - cos_t)) + (u.y * sin_t), 0.0f, + (u.y * u.x * (1.0f - cos_t)) + (u.z * sin_t), cos_t + (u.y * u.y * (1.0f - cos_t)), + (u.y * u.z * (1.0f - cos_t)) - (u.x * sin_t), 0.0f, + (u.z * u.x * (1.0f - cos_t)) - (u.y * sin_t), (u.z * u.y * (1.0f - cos_t)) + (u.x * sin_t), + cos_t + (u.z * u.z * (1.0f - cos_t)), 0.0f, 0.0f, 0.0f, 0.0f, 1.0f); +} + +Matrix4 Matrix4::translate(const Vector3 &t) +{ + return Matrix4(1.0f, 0.0f, 0.0f, t.x, 0.0f, 1.0f, 0.0f, t.y, 0.0f, 0.0f, 1.0f, t.z, 0.0f, 0.0f, + 0.0f, 1.0f); +} + +Matrix4 Matrix4::scale(const Vector3 &s) +{ + return Matrix4(s.x, 0.0f, 0.0f, 0.0f, 0.0f, s.y, 0.0f, 0.0f, 0.0f, 0.0f, s.z, 0.0f, 0.0f, 0.0f, + 0.0f, 1.0f); +} + +Matrix4 Matrix4::frustum(float l, float r, float b, float t, float n, float f) +{ + return Matrix4((2.0f * n) / (r - l), 0.0f, (r + l) / (r - l), 0.0f, 0.0f, (2.0f * n) / (t - b), + (t + b) / (t - b), 0.0f, 0.0f, 0.0f, -(f + n) / (f - n), + -(2.0f * f * n) / (f - n), 0.0f, 0.0f, -1.0f, 0.0f); +} + +Matrix4 Matrix4::perspective(float fovY, float aspectRatio, float nearZ, float farZ) +{ + const float frustumHeight = tanf(static_cast(fovY / 360.0f * M_PI)) * nearZ; + const float frustumWidth = frustumHeight * aspectRatio; + return frustum(-frustumWidth, frustumWidth, -frustumHeight, frustumHeight, nearZ, farZ); +} + +Matrix4 Matrix4::ortho(float l, float r, float b, float t, float n, float f) +{ + return Matrix4(2.0f / (r - l), 0.0f, 0.0f, -(r + l) / (r - l), 0.0f, 2.0f / (t - b), 0.0f, + -(t + b) / (t - b), 0.0f, 0.0f, -2.0f / (f - n), -(f + n) / (f - n), 0.0f, 0.0f, + 0.0f, 1.0f); +} + +Matrix4 Matrix4::rollPitchYaw(float roll, float pitch, float yaw) +{ + return rotate(yaw, Vector3(0, 0, 1)) * rotate(pitch, Vector3(0, 1, 0)) * + rotate(roll, Vector3(1, 0, 0)); +} + +Matrix4 Matrix4::invert(const Matrix4 &mat) +{ + Matrix4 inverted( + mat.data[5] * mat.data[10] * mat.data[15] - mat.data[5] * mat.data[11] * mat.data[14] - + mat.data[9] * mat.data[6] * mat.data[15] + mat.data[9] * mat.data[7] * mat.data[14] + + mat.data[13] * mat.data[6] * mat.data[11] - mat.data[13] * mat.data[7] * mat.data[10], + -mat.data[4] * mat.data[10] * mat.data[15] + mat.data[4] * mat.data[11] * mat.data[14] + + mat.data[8] * mat.data[6] * mat.data[15] - mat.data[8] * mat.data[7] * mat.data[14] - + mat.data[12] * mat.data[6] * mat.data[11] + mat.data[12] * mat.data[7] * mat.data[10], + mat.data[4] * mat.data[9] * mat.data[15] - mat.data[4] * mat.data[11] * mat.data[13] - + mat.data[8] * mat.data[5] * mat.data[15] + mat.data[8] * mat.data[7] * mat.data[13] + + mat.data[12] * mat.data[5] * mat.data[11] - mat.data[12] * mat.data[7] * mat.data[9], + -mat.data[4] * mat.data[9] * mat.data[14] + mat.data[4] * mat.data[10] * mat.data[13] + + mat.data[8] * mat.data[5] * mat.data[14] - mat.data[8] * mat.data[6] * mat.data[13] - + mat.data[12] * mat.data[5] * mat.data[10] + mat.data[12] * mat.data[6] * mat.data[9], + -mat.data[1] * mat.data[10] * mat.data[15] + mat.data[1] * mat.data[11] * mat.data[14] + + mat.data[9] * mat.data[2] * mat.data[15] - mat.data[9] * mat.data[3] * mat.data[14] - + mat.data[13] * mat.data[2] * mat.data[11] + mat.data[13] * mat.data[3] * mat.data[10], + mat.data[0] * mat.data[10] * mat.data[15] - mat.data[0] * mat.data[11] * mat.data[14] - + mat.data[8] * mat.data[2] * mat.data[15] + mat.data[8] * mat.data[3] * mat.data[14] + + mat.data[12] * mat.data[2] * mat.data[11] - mat.data[12] * mat.data[3] * mat.data[10], + -mat.data[0] * mat.data[9] * mat.data[15] + mat.data[0] * mat.data[11] * mat.data[13] + + mat.data[8] * mat.data[1] * mat.data[15] - mat.data[8] * mat.data[3] * mat.data[13] - + mat.data[12] * mat.data[1] * mat.data[11] + mat.data[12] * mat.data[3] * mat.data[9], + mat.data[0] * mat.data[9] * mat.data[14] - mat.data[0] * mat.data[10] * mat.data[13] - + mat.data[8] * mat.data[1] * mat.data[14] + mat.data[8] * mat.data[2] * mat.data[13] + + mat.data[12] * mat.data[1] * mat.data[10] - mat.data[12] * mat.data[2] * mat.data[9], + mat.data[1] * mat.data[6] * mat.data[15] - mat.data[1] * mat.data[7] * mat.data[14] - + mat.data[5] * mat.data[2] * mat.data[15] + mat.data[5] * mat.data[3] * mat.data[14] + + mat.data[13] * mat.data[2] * mat.data[7] - mat.data[13] * mat.data[3] * mat.data[6], + -mat.data[0] * mat.data[6] * mat.data[15] + mat.data[0] * mat.data[7] * mat.data[14] + + mat.data[4] * mat.data[2] * mat.data[15] - mat.data[4] * mat.data[3] * mat.data[14] - + mat.data[12] * mat.data[2] * mat.data[7] + mat.data[12] * mat.data[3] * mat.data[6], + mat.data[0] * mat.data[5] * mat.data[15] - mat.data[0] * mat.data[7] * mat.data[13] - + mat.data[4] * mat.data[1] * mat.data[15] + mat.data[4] * mat.data[3] * mat.data[13] + + mat.data[12] * mat.data[1] * mat.data[7] - mat.data[12] * mat.data[3] * mat.data[5], + -mat.data[0] * mat.data[5] * mat.data[14] + mat.data[0] * mat.data[6] * mat.data[13] + + mat.data[4] * mat.data[1] * mat.data[14] - mat.data[4] * mat.data[2] * mat.data[13] - + mat.data[12] * mat.data[1] * mat.data[6] + mat.data[12] * mat.data[2] * mat.data[5], + -mat.data[1] * mat.data[6] * mat.data[11] + mat.data[1] * mat.data[7] * mat.data[10] + + mat.data[5] * mat.data[2] * mat.data[11] - mat.data[5] * mat.data[3] * mat.data[10] - + mat.data[9] * mat.data[2] * mat.data[7] + mat.data[9] * mat.data[3] * mat.data[6], + mat.data[0] * mat.data[6] * mat.data[11] - mat.data[0] * mat.data[7] * mat.data[10] - + mat.data[4] * mat.data[2] * mat.data[11] + mat.data[4] * mat.data[3] * mat.data[10] + + mat.data[8] * mat.data[2] * mat.data[7] - mat.data[8] * mat.data[3] * mat.data[6], + -mat.data[0] * mat.data[5] * mat.data[11] + mat.data[0] * mat.data[7] * mat.data[9] + + mat.data[4] * mat.data[1] * mat.data[11] - mat.data[4] * mat.data[3] * mat.data[9] - + mat.data[8] * mat.data[1] * mat.data[7] + mat.data[8] * mat.data[3] * mat.data[5], + mat.data[0] * mat.data[5] * mat.data[10] - mat.data[0] * mat.data[6] * mat.data[9] - + mat.data[4] * mat.data[1] * mat.data[10] + mat.data[4] * mat.data[2] * mat.data[9] + + mat.data[8] * mat.data[1] * mat.data[6] - mat.data[8] * mat.data[2] * mat.data[5]); + + float determinant = mat.data[0] * inverted.data[0] + mat.data[1] * inverted.data[4] + + mat.data[2] * inverted.data[8] + mat.data[3] * inverted.data[12]; + + if (determinant != 0.0f) + { + inverted *= 1.0f / determinant; + } + else + { + inverted = identity(); + } + + return inverted; +} + +Matrix4 Matrix4::transpose(const Matrix4 &mat) +{ + return Matrix4(mat.data[0], mat.data[1], mat.data[2], mat.data[3], mat.data[4], mat.data[5], + mat.data[6], mat.data[7], mat.data[8], mat.data[9], mat.data[10], mat.data[11], + mat.data[12], mat.data[13], mat.data[14], mat.data[15]); +} + +Vector3 Matrix4::transform(const Matrix4 &mat, const Vector3 &pt) +{ + Vector4 transformed = Vector4::normalize(mat * Vector4(pt.x, pt.y, pt.z, 1.0f)); + return Vector3(transformed.x, transformed.y, transformed.z); +} + +Vector3 Matrix4::transform(const Matrix4 &mat, const Vector4 &pt) +{ + Vector4 transformed = Vector4::normalize(mat * pt); + return Vector3(transformed.x, transformed.y, transformed.z); +} + +Matrix4 operator*(const Matrix4 &a, const Matrix4 &b) +{ + return Matrix4(a.data[0] * b.data[0] + a.data[4] * b.data[1] + a.data[8] * b.data[2] + + a.data[12] * b.data[3], + a.data[0] * b.data[4] + a.data[4] * b.data[5] + a.data[8] * b.data[6] + + a.data[12] * b.data[7], + a.data[0] * b.data[8] + a.data[4] * b.data[9] + a.data[8] * b.data[10] + + a.data[12] * b.data[11], + a.data[0] * b.data[12] + a.data[4] * b.data[13] + a.data[8] * b.data[14] + + a.data[12] * b.data[15], + a.data[1] * b.data[0] + a.data[5] * b.data[1] + a.data[9] * b.data[2] + + a.data[13] * b.data[3], + a.data[1] * b.data[4] + a.data[5] * b.data[5] + a.data[9] * b.data[6] + + a.data[13] * b.data[7], + a.data[1] * b.data[8] + a.data[5] * b.data[9] + a.data[9] * b.data[10] + + a.data[13] * b.data[11], + a.data[1] * b.data[12] + a.data[5] * b.data[13] + a.data[9] * b.data[14] + + a.data[13] * b.data[15], + a.data[2] * b.data[0] + a.data[6] * b.data[1] + a.data[10] * b.data[2] + + a.data[14] * b.data[3], + a.data[2] * b.data[4] + a.data[6] * b.data[5] + a.data[10] * b.data[6] + + a.data[14] * b.data[7], + a.data[2] * b.data[8] + a.data[6] * b.data[9] + a.data[10] * b.data[10] + + a.data[14] * b.data[11], + a.data[2] * b.data[12] + a.data[6] * b.data[13] + a.data[10] * b.data[14] + + a.data[14] * b.data[15], + a.data[3] * b.data[0] + a.data[7] * b.data[1] + a.data[11] * b.data[2] + + a.data[15] * b.data[3], + a.data[3] * b.data[4] + a.data[7] * b.data[5] + a.data[11] * b.data[6] + + a.data[15] * b.data[7], + a.data[3] * b.data[8] + a.data[7] * b.data[9] + a.data[11] * b.data[10] + + a.data[15] * b.data[11], + a.data[3] * b.data[12] + a.data[7] * b.data[13] + a.data[11] * b.data[14] + + a.data[15] * b.data[15]); +} + +Matrix4 &operator*=(Matrix4 &a, const Matrix4 &b) +{ + a = a * b; + return a; +} + +Matrix4 operator*(const Matrix4 &a, float b) +{ + Matrix4 ret(a); + for (size_t i = 0; i < 16; i++) + { + ret.data[i] *= b; + } + return ret; +} + +Matrix4 &operator*=(Matrix4 &a, float b) +{ + for (size_t i = 0; i < 16; i++) + { + a.data[i] *= b; + } + return a; +} + +Vector4 operator*(const Matrix4 &a, const Vector4 &b) +{ + return Vector4(a.data[0] * b.x + a.data[4] * b.y + a.data[8] * b.z + a.data[12] * b.w, + a.data[1] * b.x + a.data[5] * b.y + a.data[9] * b.z + a.data[13] * b.w, + a.data[2] * b.x + a.data[6] * b.y + a.data[10] * b.z + a.data[14] * b.w, + a.data[3] * b.x + a.data[7] * b.y + a.data[11] * b.z + a.data[15] * b.w); +} + +bool operator==(const Matrix4 &a, const Matrix4 &b) +{ + for (size_t i = 0; i < 16; i++) + { + if (a.data[i] != b.data[i]) + { + return false; + } + } + return true; +} + +bool operator!=(const Matrix4 &a, const Matrix4 &b) +{ + return !(a == b); +} diff --git a/Source/ThirdParty/ANGLE/util/Matrix.h b/Source/ThirdParty/ANGLE/util/Matrix.h new file mode 100644 index 000000000000..abcfe43de18c --- /dev/null +++ b/Source/ThirdParty/ANGLE/util/Matrix.h @@ -0,0 +1,61 @@ +// +// Copyright (c) 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. +// +// Matrix: +// Helper class for doing matrix math. +// + +#ifndef UTIL_MATRIX_H +#define UTIL_MATRIX_H + +#include "Vector.h" + +struct Matrix4 +{ + float data[16]; + + Matrix4(); + Matrix4(float m00, + float m01, + float m02, + float m03, + float m10, + float m11, + float m12, + float m13, + float m20, + float m21, + float m22, + float m23, + float m30, + float m31, + float m32, + float m33); + + static Matrix4 identity(); + static Matrix4 rotate(float angle, const Vector3 &p); + static Matrix4 translate(const Vector3 &t); + static Matrix4 scale(const Vector3 &s); + static Matrix4 frustum(float l, float r, float b, float t, float n, float f); + static Matrix4 perspective(float fov, float aspectRatio, float n, float f); + static Matrix4 ortho(float l, float r, float b, float t, float n, float f); + static Matrix4 rollPitchYaw(float roll, float pitch, float yaw); + + static Matrix4 invert(const Matrix4 &mat); + static Matrix4 transpose(const Matrix4 &mat); + static Vector3 transform(const Matrix4 &mat, const Vector3 &pt); + static Vector3 transform(const Matrix4 &mat, const Vector4 &pt); +}; + +Matrix4 operator*(const Matrix4 &a, const Matrix4 &b); +Matrix4 &operator*=(Matrix4 &a, const Matrix4 &b); +Matrix4 operator*(const Matrix4 &a, float b); +Matrix4 &operator*=(Matrix4 &a, float b); +Vector4 operator*(const Matrix4 &a, const Vector4 &b); + +bool operator==(const Matrix4 &a, const Matrix4 &b); +bool operator!=(const Matrix4 &a, const Matrix4 &b); + +#endif // UTIL_MATRIX_H diff --git a/Source/ThirdParty/ANGLE/util/OSPixmap.h b/Source/ThirdParty/ANGLE/util/OSPixmap.h new file mode 100644 index 000000000000..47cd53175fd4 --- /dev/null +++ b/Source/ThirdParty/ANGLE/util/OSPixmap.h @@ -0,0 +1,32 @@ +// +// Copyright (c) 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. +// + +// OSPixmap.h: Definition of an abstract pixmap class + +#ifndef SAMPLE_UTIL_PIXMAP_H_ +#define SAMPLE_UTIL_PIXMAP_H_ + +#include + +#include +#include + +#include "Event.h" + +class OSPixmap +{ + public: + OSPixmap() {} + virtual ~OSPixmap() {} + + virtual bool initialize(EGLNativeDisplayType display, size_t width, size_t height, int depth) = 0; + + virtual EGLNativePixmapType getNativePixmap() const = 0; +}; + +OSPixmap *CreateOSPixmap(); + +#endif // SAMPLE_UTIL_PIXMAP_H_ diff --git a/Source/ThirdParty/ANGLE/util/OSWindow.cpp b/Source/ThirdParty/ANGLE/util/OSWindow.cpp index 2dc842da7304..abe8607af9ab 100644 --- a/Source/ThirdParty/ANGLE/util/OSWindow.cpp +++ b/Source/ThirdParty/ANGLE/util/OSWindow.cpp @@ -6,6 +6,240 @@ #include "OSWindow.h" +#include +#include + +#include "common/debug.h" + +#ifndef DEBUG_EVENTS +#define DEBUG_EVENTS 0 +#endif + +#if DEBUG_EVENTS +static const char *MouseButtonName(MouseButton button) +{ + switch (button) + { + case MOUSEBUTTON_UNKNOWN: + return "Unknown"; + case MOUSEBUTTON_LEFT: + return "Left"; + case MOUSEBUTTON_RIGHT: + return "Right"; + case MOUSEBUTTON_MIDDLE: + return "Middle"; + case MOUSEBUTTON_BUTTON4: + return "Button4"; + case MOUSEBUTTON_BUTTON5: + return "Button5"; + default: + UNREACHABLE(); + return nullptr; + } +} + +static const char *KeyName(Key key) +{ + switch (key) + { + case KEY_UNKNOWN: return "Unknown"; + case KEY_A: return "A"; + case KEY_B: return "B"; + case KEY_C: return "C"; + case KEY_D: return "D"; + case KEY_E: return "E"; + case KEY_F: return "F"; + case KEY_G: return "G"; + case KEY_H: return "H"; + case KEY_I: return "I"; + case KEY_J: return "J"; + case KEY_K: return "K"; + case KEY_L: return "L"; + case KEY_M: return "M"; + case KEY_N: return "N"; + case KEY_O: return "O"; + case KEY_P: return "P"; + case KEY_Q: return "Q"; + case KEY_R: return "R"; + case KEY_S: return "S"; + case KEY_T: return "T"; + case KEY_U: return "U"; + case KEY_V: return "V"; + case KEY_W: return "W"; + case KEY_X: return "X"; + case KEY_Y: return "Y"; + case KEY_Z: return "Z"; + case KEY_NUM0: return "Num0"; + case KEY_NUM1: return "Num1"; + case KEY_NUM2: return "Num2"; + case KEY_NUM3: return "Num3"; + case KEY_NUM4: return "Num4"; + case KEY_NUM5: return "Num5"; + case KEY_NUM6: return "Num6"; + case KEY_NUM7: return "Num7"; + case KEY_NUM8: return "Num8"; + case KEY_NUM9: return "Num9"; + case KEY_ESCAPE: return "Escape"; + case KEY_LCONTROL: return "Left Control"; + case KEY_LSHIFT: return "Left Shift"; + case KEY_LALT: return "Left Alt"; + case KEY_LSYSTEM: return "Left System"; + case KEY_RCONTROL: return "Right Control"; + case KEY_RSHIFT: return "Right Shift"; + case KEY_RALT: return "Right Alt"; + case KEY_RSYSTEM: return "Right System"; + case KEY_MENU: return "Menu"; + case KEY_LBRACKET: return "Left Bracket"; + case KEY_RBRACKET: return "Right Bracket"; + case KEY_SEMICOLON: return "Semicolon"; + case KEY_COMMA: return "Comma"; + case KEY_PERIOD: return "Period"; + case KEY_QUOTE: return "Quote"; + case KEY_SLASH: return "Slash"; + case KEY_BACKSLASH: return "Backslash"; + case KEY_TILDE: return "Tilde"; + case KEY_EQUAL: return "Equal"; + case KEY_DASH: return "Dash"; + case KEY_SPACE: return "Space"; + case KEY_RETURN: return "Return"; + case KEY_BACK: return "Back"; + case KEY_TAB: return "Tab"; + case KEY_PAGEUP: return "Page Up"; + case KEY_PAGEDOWN: return "Page Down"; + case KEY_END: return "End"; + case KEY_HOME: return "Home"; + case KEY_INSERT: return "Insert"; + case KEY_DELETE: return "Delete"; + case KEY_ADD: return "Add"; + case KEY_SUBTRACT: return "Substract"; + case KEY_MULTIPLY: return "Multiply"; + case KEY_DIVIDE: return "Divide"; + case KEY_LEFT: return "Left"; + case KEY_RIGHT: return "Right"; + case KEY_UP: return "Up"; + case KEY_DOWN: return "Down"; + case KEY_NUMPAD0: return "Numpad 0"; + case KEY_NUMPAD1: return "Numpad 1"; + case KEY_NUMPAD2: return "Numpad 2"; + case KEY_NUMPAD3: return "Numpad 3"; + case KEY_NUMPAD4: return "Numpad 4"; + case KEY_NUMPAD5: return "Numpad 5"; + case KEY_NUMPAD6: return "Numpad 6"; + case KEY_NUMPAD7: return "Numpad 7"; + case KEY_NUMPAD8: return "Numpad 8"; + case KEY_NUMPAD9: return "Numpad 9"; + case KEY_F1: return "F1"; + case KEY_F2: return "F2"; + case KEY_F3: return "F3"; + case KEY_F4: return "F4"; + case KEY_F5: return "F5"; + case KEY_F6: return "F6"; + case KEY_F7: return "F7"; + case KEY_F8: return "F8"; + case KEY_F9: return "F9"; + case KEY_F10: return "F10"; + case KEY_F11: return "F11"; + case KEY_F12: return "F12"; + case KEY_F13: return "F13"; + case KEY_F14: return "F14"; + case KEY_F15: return "F15"; + case KEY_PAUSE: return "Pause"; + default: return "Unknown Key"; + } +} + +static std::string KeyState(const Event::KeyEvent &event) +{ + if (event.Shift || event.Control || event.Alt || event.System) + { + std::ostringstream buffer; + buffer << " ["; + + if (event.Shift) + { + buffer << "Shift"; + } + if (event.Control) + { + buffer << "Control"; + } + if (event.Alt) + { + buffer << "Alt"; + } + if (event.System) + { + buffer << "System"; + } + + buffer << "]"; + return buffer.str(); + } + return ""; +} + +static void PrintEvent(const Event& event) +{ + switch (event.Type) + { + case Event::EVENT_CLOSED: + std::cout << "Event: Window Closed" << std::endl; + break; + case Event::EVENT_MOVED: + std::cout << "Event: Window Moved (" << event.Move.X + << ", " << event.Move.Y << ")" << std::endl; + break; + case Event::EVENT_RESIZED: + std::cout << "Event: Window Resized (" << event.Size.Width + << ", " << event.Size.Height << ")" << std::endl; + break; + case Event::EVENT_LOST_FOCUS: + std::cout << "Event: Window Lost Focus" << std::endl; + break; + case Event::EVENT_GAINED_FOCUS: + std::cout << "Event: Window Gained Focus" << std::endl; + break; + case Event::EVENT_TEXT_ENTERED: + // TODO(cwallez) show the character + std::cout << "Event: Text Entered" << std::endl; + break; + case Event::EVENT_KEY_PRESSED: + std::cout << "Event: Key Pressed (" << KeyName(event.Key.Code) << KeyState(event.Key) << ")" << std::endl; + break; + case Event::EVENT_KEY_RELEASED: + std::cout << "Event: Key Released (" << KeyName(event.Key.Code) << KeyState(event.Key) << ")" << std::endl; + break; + case Event::EVENT_MOUSE_WHEEL_MOVED: + std::cout << "Event: Mouse Wheel (" << event.MouseWheel.Delta << ")" << std::endl; + break; + case Event::EVENT_MOUSE_BUTTON_PRESSED: + std::cout << "Event: Mouse Button Pressed " << MouseButtonName(event.MouseButton.Button) << + " at (" << event.MouseButton.X << ", " << event.MouseButton.Y << ")" << std::endl; + break; + case Event::EVENT_MOUSE_BUTTON_RELEASED: + std::cout << "Event: Mouse Button Released " << MouseButtonName(event.MouseButton.Button) << + " at (" << event.MouseButton.X << ", " << event.MouseButton.Y << ")" << std::endl; + break; + case Event::EVENT_MOUSE_MOVED: + std::cout << "Event: Mouse Moved (" << event.MouseMove.X + << ", " << event.MouseMove.Y << ")" << std::endl; + break; + case Event::EVENT_MOUSE_ENTERED: + std::cout << "Event: Mouse Entered Window" << std::endl; + break; + case Event::EVENT_MOUSE_LEFT: + std::cout << "Event: Mouse Left Window" << std::endl; + break; + case Event::EVENT_TEST: + std::cout << "Event: Test" << std::endl; + break; + default: + UNREACHABLE(); + break; + } +} +#endif + OSWindow::OSWindow() : mX(0), mY(0), @@ -68,6 +302,10 @@ void OSWindow::pushEvent(Event event) } mEvents.push_back(event); + +#if DEBUG_EVENTS + PrintEvent(event); +#endif } bool OSWindow::didTestEventFire() diff --git a/Source/ThirdParty/ANGLE/util/OSWindow.h b/Source/ThirdParty/ANGLE/util/OSWindow.h index aed8e269c566..6aa9e0e9910a 100644 --- a/Source/ThirdParty/ANGLE/util/OSWindow.h +++ b/Source/ThirdParty/ANGLE/util/OSWindow.h @@ -7,12 +7,14 @@ #ifndef SAMPLE_UTIL_WINDOW_H #define SAMPLE_UTIL_WINDOW_H -#include "Event.h" +#include +#include +#include #include #include -#include -#include + +#include "Event.h" class OSWindow { @@ -28,6 +30,12 @@ class OSWindow int getWidth() const; int getHeight() const; + // Takes a screenshot of the window, returning the result as a mWidth * mHeight * 4 + // normalized unsigned byte BGRA array. Note that it will be used to test the window + // manager's behavior so it needs to take an actual screenshot of the screen and not + // just grab the pixels of the window. Returns if it was successful. + virtual bool takeScreenshot(uint8_t *pixelData) { return false; } + virtual EGLNativeWindowType getNativeWindow() const = 0; virtual EGLNativeDisplayType getNativeDisplay() const = 0; diff --git a/Source/ThirdParty/ANGLE/util/Vector.cpp b/Source/ThirdParty/ANGLE/util/Vector.cpp new file mode 100644 index 000000000000..1d84f1845707 --- /dev/null +++ b/Source/ThirdParty/ANGLE/util/Vector.cpp @@ -0,0 +1,170 @@ +// +// Copyright (c) 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. +// +// Vector: +// Vector class for linear math. +// + +#include "Vector.h" + +#include + +Vector2::Vector2() : x(0.0), y(0.0) +{ +} + +Vector2::Vector2(float x, float y) : x(x), y(y) +{ +} + +bool Vector2::operator==(const Vector2 &vec) const +{ + return x == vec.x && y == vec.y; +} + +bool Vector2::operator!=(const Vector2 &vec) const +{ + return !(*this == vec); +} + +std::ostream &operator<<(std::ostream &stream, const Vector2 &vec) +{ + stream << "(" << vec.x << "," << vec.y << ")"; + return stream; +} + +float Vector2::length(const Vector2 &vec) +{ + float lenSquared = lengthSquared(vec); + return (lenSquared != 0.0f) ? sqrtf(lenSquared) : 0.0f; +} + +float Vector2::lengthSquared(const Vector2 &vec) +{ + return vec.x * vec.x + vec.y * vec.y; +} + +Vector2 Vector2::normalize(const Vector2 &vec) +{ + Vector2 ret(0.0f, 0.0f); + float len = length(vec); + if (len != 0.0f) + { + float invLen = 1.0f / len; + ret.x = vec.x * invLen; + ret.y = vec.y * invLen; + } + return ret; +} + +Vector3::Vector3() : x(0.0), y(0.0), z(0.0) +{ +} + +Vector3::Vector3(float x, float y, float z) : x(x), y(y), z(z) +{ +} + +float Vector3::length(const Vector3 &vec) +{ + float lenSquared = lengthSquared(vec); + return (lenSquared != 0.0f) ? sqrtf(lenSquared) : 0.0f; +} + +float Vector3::lengthSquared(const Vector3 &vec) +{ + return vec.x * vec.x + vec.y * vec.y + vec.z * vec.z; +} + +Vector3 Vector3::normalize(const Vector3 &vec) +{ + Vector3 ret(0.0f, 0.0f, 0.0f); + float len = length(vec); + if (len != 0.0f) + { + float invLen = 1.0f / len; + ret.x = vec.x * invLen; + ret.y = vec.y * invLen; + ret.z = vec.z * invLen; + } + return ret; +} + +float Vector3::dot(const Vector3 &a, const Vector3 &b) +{ + return a.x * b.x + a.y * b.y + a.z * b.z; +} + +Vector3 Vector3::cross(const Vector3 &a, const Vector3 &b) +{ + return Vector3(a.y * b.z - a.z * b.y, a.z * b.x - a.x * b.z, a.x * b.y - a.y * b.x); +} + +Vector3 operator*(const Vector3 &a, const Vector3 &b) +{ + return Vector3(a.x * b.x, a.y * b.y, a.z * b.z); +} + +Vector3 operator*(const Vector3 &a, const float &b) +{ + return Vector3(a.x * b, a.y * b, a.z * b); +} + +Vector3 operator/(const Vector3 &a, const Vector3 &b) +{ + return Vector3(a.x / b.x, a.y / b.y, a.z / b.z); +} + +Vector3 operator/(const Vector3 &a, const float &b) +{ + return Vector3(a.x / b, a.y / b, a.z / b); +} + +Vector3 operator+(const Vector3 &a, const Vector3 &b) +{ + return Vector3(a.x + b.x, a.y + b.y, a.z + b.z); +} + +Vector3 operator-(const Vector3 &a, const Vector3 &b) +{ + return Vector3(a.x - b.x, a.y - b.y, a.z - b.z); +} + +Vector4::Vector4() : x(0.0f), y(0.0f), z(0.0f), w(0.0f) +{ +} + +Vector4::Vector4(float x, float y, float z, float w) : x(x), y(y), z(z), w(w) +{ +} + +float Vector4::length(const Vector4 &vec) +{ + float lenSquared = lengthSquared(vec); + return (lenSquared != 0.0f) ? sqrtf(lenSquared) : 0.0f; +} + +float Vector4::lengthSquared(const Vector4 &vec) +{ + return vec.x * vec.x + vec.y * vec.y + vec.z * vec.z + vec.w * vec.w; +} + +Vector4 Vector4::normalize(const Vector4 &vec) +{ + Vector4 ret(0.0f, 0.0f, 0.0f, 1.0f); + if (vec.w != 0.0f) + { + float invLen = 1.0f / vec.w; + ret.x = vec.x * invLen; + ret.y = vec.y * invLen; + ret.z = vec.z * invLen; + } + return ret; +} + +float Vector4::dot(const Vector4 &a, const Vector4 &b) +{ + return a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w; +} diff --git a/Source/ThirdParty/ANGLE/util/Vector.h b/Source/ThirdParty/ANGLE/util/Vector.h new file mode 100644 index 000000000000..2a1f52672b35 --- /dev/null +++ b/Source/ThirdParty/ANGLE/util/Vector.h @@ -0,0 +1,80 @@ +// +// Copyright (c) 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. +// +// Vector: +// Vector class for linear math. +// + +#ifndef UTIL_VECTOR_H +#define UTIL_VECTOR_H + +#include + +struct Vector2 +{ + Vector2(); + Vector2(float x, float y); + + bool operator==(const Vector2 &vec) const; + bool operator!=(const Vector2 &vec) const; + + static float length(const Vector2 &vec); + static float lengthSquared(const Vector2 &vec); + + static Vector2 normalize(const Vector2 &vec); + + float *data() { return &x; } + const float *data() const { return &x; } + + float x, y; +}; + +std::ostream &operator<<(std::ostream &stream, const Vector2 &vec); + +struct Vector3 +{ + Vector3(); + Vector3(float x, float y, float z); + + static float length(const Vector3 &vec); + static float lengthSquared(const Vector3 &vec); + + static Vector3 normalize(const Vector3 &vec); + + static float dot(const Vector3 &a, const Vector3 &b); + static Vector3 cross(const Vector3 &a, const Vector3 &b); + + float *data() { return &x; } + const float *data() const { return &x; } + + float x, y, z; +}; + +Vector3 operator*(const Vector3 &a, const Vector3 &b); +Vector3 operator*(const Vector3 &a, const float &b); +Vector3 operator/(const Vector3 &a, const Vector3 &b); +Vector3 operator/(const Vector3 &a, const float &b); +Vector3 operator+(const Vector3 &a, const Vector3 &b); +Vector3 operator-(const Vector3 &a, const Vector3 &b); + +struct Vector4 +{ + Vector4(); + Vector4(float x, float y, float z, float w); + + static float length(const Vector4 &vec); + static float lengthSquared(const Vector4 &vec); + + static Vector4 normalize(const Vector4 &vec); + + static float dot(const Vector4 &a, const Vector4 &b); + + float *data() { return &x; } + const float *data() const { return &x; } + + float x, y, z, w; +}; + +#endif // UTIL_VECTOR_H diff --git a/Source/ThirdParty/ANGLE/util/geometry_utils.cpp b/Source/ThirdParty/ANGLE/util/geometry_utils.cpp new file mode 100644 index 000000000000..e62c0fbdb844 --- /dev/null +++ b/Source/ThirdParty/ANGLE/util/geometry_utils.cpp @@ -0,0 +1,173 @@ +// +// Copyright (c) 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. +// +// geometry_utils: +// Helper library for generating certain sets of geometry. +// + +#include "geometry_utils.h" + +#define _USE_MATH_DEFINES +#include + +void CreateSphereGeometry(size_t sliceCount, float radius, SphereGeometry *result) +{ + size_t parellelCount = sliceCount / 2; + size_t vertexCount = (parellelCount + 1) * (sliceCount + 1); + size_t indexCount = parellelCount * sliceCount * 6; + float angleStep = static_cast(2.0f * M_PI) / sliceCount; + + result->positions.resize(vertexCount); + result->normals.resize(vertexCount); + for (size_t i = 0; i < parellelCount + 1; i++) + { + for (size_t j = 0; j < sliceCount + 1; j++) + { + Vector3 direction(sinf(angleStep * i) * sinf(angleStep * j), cosf(angleStep * i), + sinf(angleStep * i) * cosf(angleStep * j)); + + size_t vertexIdx = i * (sliceCount + 1) + j; + result->positions[vertexIdx] = direction * radius; + result->normals[vertexIdx] = direction; + } + } + + result->indices.clear(); + result->indices.reserve(indexCount); + for (size_t i = 0; i < parellelCount; i++) + { + for (size_t j = 0; j < sliceCount; j++) + { + result->indices.push_back(static_cast(i * (sliceCount + 1) + j)); + result->indices.push_back(static_cast((i + 1) * (sliceCount + 1) + j)); + result->indices.push_back( + static_cast((i + 1) * (sliceCount + 1) + (j + 1))); + + result->indices.push_back(static_cast(i * (sliceCount + 1) + j)); + result->indices.push_back( + static_cast((i + 1) * (sliceCount + 1) + (j + 1))); + result->indices.push_back(static_cast(i * (sliceCount + 1) + (j + 1))); + } + } +} + +void GenerateCubeGeometry(float radius, CubeGeometry *result) +{ + result->positions.resize(24); + result->positions[0] = Vector3(-radius, -radius, -radius); + result->positions[1] = Vector3(-radius, -radius, radius); + result->positions[2] = Vector3(radius, -radius, radius); + result->positions[3] = Vector3(radius, -radius, -radius); + result->positions[4] = Vector3(-radius, radius, -radius); + result->positions[5] = Vector3(-radius, radius, radius); + result->positions[6] = Vector3(radius, radius, radius); + result->positions[7] = Vector3(radius, radius, -radius); + result->positions[8] = Vector3(-radius, -radius, -radius); + result->positions[9] = Vector3(-radius, radius, -radius); + result->positions[10] = Vector3(radius, radius, -radius); + result->positions[11] = Vector3(radius, -radius, -radius); + result->positions[12] = Vector3(-radius, -radius, radius); + result->positions[13] = Vector3(-radius, radius, radius); + result->positions[14] = Vector3(radius, radius, radius); + result->positions[15] = Vector3(radius, -radius, radius); + result->positions[16] = Vector3(-radius, -radius, -radius); + result->positions[17] = Vector3(-radius, -radius, radius); + result->positions[18] = Vector3(-radius, radius, radius); + result->positions[19] = Vector3(-radius, radius, -radius); + result->positions[20] = Vector3(radius, -radius, -radius); + result->positions[21] = Vector3(radius, -radius, radius); + result->positions[22] = Vector3(radius, radius, radius); + result->positions[23] = Vector3(radius, radius, -radius); + + result->normals.resize(24); + result->normals[0] = Vector3(0.0f, -1.0f, 0.0f); + result->normals[1] = Vector3(0.0f, -1.0f, 0.0f); + result->normals[2] = Vector3(0.0f, -1.0f, 0.0f); + result->normals[3] = Vector3(0.0f, -1.0f, 0.0f); + result->normals[4] = Vector3(0.0f, 1.0f, 0.0f); + result->normals[5] = Vector3(0.0f, 1.0f, 0.0f); + result->normals[6] = Vector3(0.0f, 1.0f, 0.0f); + result->normals[7] = Vector3(0.0f, 1.0f, 0.0f); + result->normals[8] = Vector3(0.0f, 0.0f, -1.0f); + result->normals[9] = Vector3(0.0f, 0.0f, -1.0f); + result->normals[10] = Vector3(0.0f, 0.0f, -1.0f); + result->normals[11] = Vector3(0.0f, 0.0f, -1.0f); + result->normals[12] = Vector3(0.0f, 0.0f, 1.0f); + result->normals[13] = Vector3(0.0f, 0.0f, 1.0f); + result->normals[14] = Vector3(0.0f, 0.0f, 1.0f); + result->normals[15] = Vector3(0.0f, 0.0f, 1.0f); + result->normals[16] = Vector3(-1.0f, 0.0f, 0.0f); + result->normals[17] = Vector3(-1.0f, 0.0f, 0.0f); + result->normals[18] = Vector3(-1.0f, 0.0f, 0.0f); + result->normals[19] = Vector3(-1.0f, 0.0f, 0.0f); + result->normals[20] = Vector3(1.0f, 0.0f, 0.0f); + result->normals[21] = Vector3(1.0f, 0.0f, 0.0f); + result->normals[22] = Vector3(1.0f, 0.0f, 0.0f); + result->normals[23] = Vector3(1.0f, 0.0f, 0.0f); + + result->texcoords.resize(24); + result->texcoords[0] = Vector2(0.0f, 0.0f); + result->texcoords[1] = Vector2(0.0f, 1.0f); + result->texcoords[2] = Vector2(1.0f, 1.0f); + result->texcoords[3] = Vector2(1.0f, 0.0f); + result->texcoords[4] = Vector2(1.0f, 0.0f); + result->texcoords[5] = Vector2(1.0f, 1.0f); + result->texcoords[6] = Vector2(0.0f, 1.0f); + result->texcoords[7] = Vector2(0.0f, 0.0f); + result->texcoords[8] = Vector2(0.0f, 0.0f); + result->texcoords[9] = Vector2(0.0f, 1.0f); + result->texcoords[10] = Vector2(1.0f, 1.0f); + result->texcoords[11] = Vector2(1.0f, 0.0f); + result->texcoords[12] = Vector2(0.0f, 0.0f); + result->texcoords[13] = Vector2(0.0f, 1.0f); + result->texcoords[14] = Vector2(1.0f, 1.0f); + result->texcoords[15] = Vector2(1.0f, 0.0f); + result->texcoords[16] = Vector2(0.0f, 0.0f); + result->texcoords[17] = Vector2(0.0f, 1.0f); + result->texcoords[18] = Vector2(1.0f, 1.0f); + result->texcoords[19] = Vector2(1.0f, 0.0f); + result->texcoords[20] = Vector2(0.0f, 0.0f); + result->texcoords[21] = Vector2(0.0f, 1.0f); + result->texcoords[22] = Vector2(1.0f, 1.0f); + result->texcoords[23] = Vector2(1.0f, 0.0f); + + result->indices.resize(36); + result->indices[0] = 0; + result->indices[1] = 2; + result->indices[2] = 1; + result->indices[3] = 0; + result->indices[4] = 3; + result->indices[5] = 2; + result->indices[6] = 4; + result->indices[7] = 5; + result->indices[8] = 6; + result->indices[9] = 4; + result->indices[10] = 6; + result->indices[11] = 7; + result->indices[12] = 8; + result->indices[13] = 9; + result->indices[14] = 10; + result->indices[15] = 8; + result->indices[16] = 10; + result->indices[17] = 11; + result->indices[18] = 12; + result->indices[19] = 15; + result->indices[20] = 14; + result->indices[21] = 12; + result->indices[22] = 14; + result->indices[23] = 13; + result->indices[24] = 16; + result->indices[25] = 17; + result->indices[26] = 18; + result->indices[27] = 16; + result->indices[28] = 18; + result->indices[29] = 19; + result->indices[30] = 20; + result->indices[31] = 23; + result->indices[32] = 22; + result->indices[33] = 20; + result->indices[34] = 22; + result->indices[35] = 21; +} diff --git a/Source/ThirdParty/ANGLE/util/geometry_utils.h b/Source/ThirdParty/ANGLE/util/geometry_utils.h new file mode 100644 index 000000000000..7bca056063e0 --- /dev/null +++ b/Source/ThirdParty/ANGLE/util/geometry_utils.h @@ -0,0 +1,38 @@ +// +// Copyright (c) 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. +// +// geometry_utils: +// Helper library for generating certain sets of geometry. +// + +#ifndef UTIL_GEOMETRY_UTILS_H +#define UTIL_GEOMETRY_UTILS_H + +#include +#include +#include + +#include "Vector.h" + +struct SphereGeometry +{ + std::vector positions; + std::vector normals; + std::vector indices; +}; + +void CreateSphereGeometry(size_t sliceCount, float radius, SphereGeometry *result); + +struct CubeGeometry +{ + std::vector positions; + std::vector normals; + std::vector texcoords; + std::vector indices; +}; + +void GenerateCubeGeometry(float radius, CubeGeometry *result); + +#endif // UTIL_GEOMETRY_UTILS_H diff --git a/Source/ThirdParty/ANGLE/util/random_utils.cpp b/Source/ThirdParty/ANGLE/util/random_utils.cpp index e95ae274c0b6..2968a3f91131 100644 --- a/Source/ThirdParty/ANGLE/util/random_utils.cpp +++ b/Source/ThirdParty/ANGLE/util/random_utils.cpp @@ -3,20 +3,73 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // +// random_utils: +// Helper functions for random number generation. +// #include "random_utils.h" -#include + +#include + #include -float RandomBetween(float min, float max) +namespace angle +{ + +// Seed from clock +RNG::RNG() +{ + long long timeSeed = std::chrono::system_clock::now().time_since_epoch().count(); + mGenerator.seed(static_cast(timeSeed)); +} + +// Seed from fixed number. +RNG::RNG(unsigned int seed) : mGenerator(seed) +{ +} + +RNG::~RNG() +{ +} + +void RNG::reseed(unsigned int newSeed) +{ + mGenerator.seed(newSeed); +} + +int RNG::randomInt() +{ + std::uniform_int_distribution intDistribution; + return intDistribution(mGenerator); +} + +int RNG::randomIntBetween(int min, int max) +{ + std::uniform_int_distribution intDistribution(min, max); + return intDistribution(mGenerator); +} + +unsigned int RNG::randomUInt() +{ + std::uniform_int_distribution uintDistribution; + return uintDistribution(mGenerator); +} + +float RNG::randomFloat() +{ + std::uniform_real_distribution floatDistribution; + return floatDistribution(mGenerator); +} + +float RNG::randomFloatBetween(float min, float max) { - static bool randInitialized = false; - if (!randInitialized) - { - srand(static_cast(time(NULL))); - randInitialized = true; - } + std::uniform_real_distribution floatDistribution(min, max); + return floatDistribution(mGenerator); +} - const size_t divisor = 10000; - return min + ((rand() % divisor) / static_cast(divisor)) * (max - min); +float RNG::randomNegativeOneToOne() +{ + return randomFloatBetween(-1.0f, 1.0f); } + +} // namespace angle diff --git a/Source/ThirdParty/ANGLE/util/random_utils.h b/Source/ThirdParty/ANGLE/util/random_utils.h index ea0c8537eaa2..2d4aa9998933 100644 --- a/Source/ThirdParty/ANGLE/util/random_utils.h +++ b/Source/ThirdParty/ANGLE/util/random_utils.h @@ -3,10 +3,41 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // +// random_utils: +// Helper functions for random number generation. +// #ifndef UTIL_RANDOM_UTILS_H #define UTIL_RANDOM_UTILS_H -float RandomBetween(float min, float max); +// TODO(jmadill): Rework this if Chromium decides to ban +#include + +namespace angle +{ + +class RNG +{ + public: + // Seed from clock + RNG(); + // Seed from fixed number. + RNG(unsigned int seed); + ~RNG(); + + void reseed(unsigned int newSeed); + + int randomInt(); + int randomIntBetween(int min, int max); + unsigned int randomUInt(); + float randomFloat(); + float randomFloatBetween(float min, float max); + float randomNegativeOneToOne(); + + private: + std::default_random_engine mGenerator; +}; + +} // namespace angle #endif // UTIL_RANDOM_UTILS_H diff --git a/Source/ThirdParty/ANGLE/util/shader_utils.cpp b/Source/ThirdParty/ANGLE/util/shader_utils.cpp index 4a710175fcb5..62223b524f10 100644 --- a/Source/ThirdParty/ANGLE/util/shader_utils.cpp +++ b/Source/ThirdParty/ANGLE/util/shader_utils.cpp @@ -12,7 +12,7 @@ static std::string ReadFileToString(const std::string &source) { - std::ifstream stream(source); + std::ifstream stream(source.c_str()); if (!stream) { std::cerr << "Failed to load shader file: " << source; @@ -46,10 +46,18 @@ GLuint CompileShader(GLenum type, const std::string &source) GLint infoLogLength; glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLogLength); - std::vector infoLog(infoLogLength); - glGetShaderInfoLog(shader, infoLog.size(), NULL, &infoLog[0]); - - std::cerr << "shader compilation failed: " << &infoLog[0]; + // Info log length includes the null terminator, so 1 means that the info log is an empty + // string. + if (infoLogLength > 1) + { + std::vector infoLog(infoLogLength); + glGetShaderInfoLog(shader, static_cast(infoLog.size()), NULL, &infoLog[0]); + std::cerr << "shader compilation failed: " << &infoLog[0]; + } + else + { + std::cerr << "shader compilation failed. "; + } glDeleteShader(shader); shader = 0; @@ -69,7 +77,11 @@ GLuint CompileShaderFromFile(GLenum type, const std::string &sourcePath) return CompileShader(type, source); } -GLuint CompileProgram(const std::string &vsSource, const std::string &fsSource) +GLuint CompileProgramWithTransformFeedback( + const std::string &vsSource, + const std::string &fsSource, + const std::vector &transformFeedbackVaryings, + GLenum bufferMode) { GLuint program = glCreateProgram(); @@ -90,6 +102,19 @@ GLuint CompileProgram(const std::string &vsSource, const std::string &fsSource) glAttachShader(program, fs); glDeleteShader(fs); + if (transformFeedbackVaryings.size() > 0) + { + std::vector constCharTFVaryings; + + for (const std::string &transformFeedbackVarying : transformFeedbackVaryings) + { + constCharTFVaryings.push_back(transformFeedbackVarying.c_str()); + } + + glTransformFeedbackVaryings(program, static_cast(transformFeedbackVaryings.size()), + &constCharTFVaryings[0], bufferMode); + } + glLinkProgram(program); GLint linkStatus; @@ -100,10 +125,19 @@ GLuint CompileProgram(const std::string &vsSource, const std::string &fsSource) GLint infoLogLength; glGetProgramiv(program, GL_INFO_LOG_LENGTH, &infoLogLength); - std::vector infoLog(infoLogLength); - glGetProgramInfoLog(program, infoLog.size(), NULL, &infoLog[0]); + // Info log length includes the null terminator, so 1 means that the info log is an empty + // string. + if (infoLogLength > 1) + { + std::vector infoLog(infoLogLength); + glGetProgramInfoLog(program, static_cast(infoLog.size()), nullptr, &infoLog[0]); - std::cerr << "program link failed: " << &infoLog[0]; + std::cerr << "program link failed: " << &infoLog[0]; + } + else + { + std::cerr << "program link failed. "; + } glDeleteProgram(program); return 0; @@ -112,6 +146,12 @@ GLuint CompileProgram(const std::string &vsSource, const std::string &fsSource) return program; } +GLuint CompileProgram(const std::string &vsSource, const std::string &fsSource) +{ + std::vector emptyVector; + return CompileProgramWithTransformFeedback(vsSource, fsSource, emptyVector, GL_NONE); +} + GLuint CompileProgramFromFiles(const std::string &vsPath, const std::string &fsPath) { std::string vsSource = ReadFileToString(vsPath); diff --git a/Source/ThirdParty/ANGLE/util/shader_utils.h b/Source/ThirdParty/ANGLE/util/shader_utils.h index 6ac7eb2876fe..abf32fee6745 100644 --- a/Source/ThirdParty/ANGLE/util/shader_utils.h +++ b/Source/ThirdParty/ANGLE/util/shader_utils.h @@ -7,22 +7,25 @@ #ifndef SAMPLE_UTIL_SHADER_UTILS_H #define SAMPLE_UTIL_SHADER_UTILS_H -#define GL_GLEXT_PROTOTYPES - #include -#include #include #include #include #include #include +#include #define SHADER_SOURCE(...) #__VA_ARGS__ GLuint CompileShader(GLenum type, const std::string &source); GLuint CompileShaderFromFile(GLenum type, const std::string &sourcePath); +GLuint CompileProgramWithTransformFeedback( + const std::string &vsSource, + const std::string &fsSource, + const std::vector &transformFeedbackVaryings, + GLenum bufferMode); GLuint CompileProgram(const std::string &vsSource, const std::string &fsSource); GLuint CompileProgramFromFiles(const std::string &vsPath, const std::string &fsPath); diff --git a/Source/ThirdParty/ANGLE/util/system_utils.h b/Source/ThirdParty/ANGLE/util/system_utils.h new file mode 100644 index 000000000000..9767b0e4072f --- /dev/null +++ b/Source/ThirdParty/ANGLE/util/system_utils.h @@ -0,0 +1,30 @@ +// +// Copyright (c) 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. +// + +// system_utils.h: declaration of OS-specific utility functions + +#ifndef SAMPLE_UTIL_PATH_UTILS_H +#define SAMPLE_UTIL_PATH_UTILS_H + +#include + +namespace angle +{ + +std::string GetExecutablePath(); +std::string GetExecutableDirectory(); + +// Cross platform equivalent of the Windows Sleep function +void Sleep(unsigned int milliseconds); + +void SetLowPriorityProcess(); + +// Write a debug message, either to a standard output or Debug window. +void WriteDebugMessage(const char *format, ...); + +} // namespace angle + +#endif // SAMPLE_UTIL_PATH_UTILS_H diff --git a/Source/ThirdParty/ANGLE/util/util.gyp b/Source/ThirdParty/ANGLE/util/util.gyp index 8f7422e34fd0..c29fffca2868 100644 --- a/Source/ThirdParty/ANGLE/util/util.gyp +++ b/Source/ThirdParty/ANGLE/util/util.gyp @@ -3,65 +3,181 @@ # found in the LICENSE file. { - 'conditions': + # Everything below this is duplicated in the GN build, except Mac support. + # If you change anything also change angle/BUILD.gn + 'variables': + { + 'util_sources': + [ + 'com_utils.h', + 'keyboard.h', + 'geometry_utils.cpp', + 'geometry_utils.h', + 'mouse.h', + 'random_utils.cpp', + 'random_utils.h', + 'shader_utils.cpp', + 'shader_utils.h', + 'system_utils.h', + 'Event.h', + 'EGLWindow.cpp', + 'EGLWindow.h', + 'Matrix.cpp', + 'Matrix.h', + 'OSPixmap.h', + 'OSWindow.cpp', + 'OSWindow.h', + 'Timer.h', + 'Vector.cpp', + 'Vector.h', + ], + 'util_win32_sources': + [ + 'windows/win32/Win32_system_utils.cpp', + 'windows/win32/Win32Pixmap.cpp', + 'windows/win32/Win32Pixmap.h', + 'windows/win32/Win32Window.cpp', + 'windows/win32/Win32Window.h', + 'windows/Windows_system_utils.cpp', + 'windows/WindowsTimer.cpp', + 'windows/WindowsTimer.h', + ], + 'util_winrt_sources': + [ + 'windows/winrt/WinRT_system_utils.cpp', + 'windows/winrt/WinRTPixmap.cpp', + 'windows/winrt/WinRTWindow.cpp', + 'windows/winrt/WinRTWindow.h', + 'windows/Windows_system_utils.cpp', + 'windows/WindowsTimer.cpp', + 'windows/WindowsTimer.h', + ], + 'util_linux_sources': + [ + 'linux/Linux_system_utils.cpp', + 'linux/LinuxTimer.cpp', + 'linux/LinuxTimer.h', + 'posix/Posix_system_utils.cpp', + ], + 'util_x11_sources': + [ + 'x11/X11Pixmap.cpp', + 'x11/X11Pixmap.h', + 'x11/X11Window.cpp', + 'x11/X11Window.h', + ], + 'util_osx_sources': + [ + 'osx/OSX_system_utils.cpp', + 'osx/OSXTimer.cpp', + 'osx/OSXTimer.h', + 'osx/OSXPixmap.mm', + 'osx/OSXPixmap.h', + 'osx/OSXWindow.mm', + 'osx/OSXWindow.h', + 'posix/Posix_system_utils.cpp', + ], + }, + 'targets': [ - ['OS=="win"', { - 'targets': + 'target_name': 'angle_util', + 'type': 'static_library', + 'includes': [ '../build/common_defines.gypi', ], + 'dependencies': [ + '<(angle_path)/src/angle.gyp:angle_common', + '<(angle_path)/src/angle.gyp:libEGL', + '<(angle_path)/src/angle.gyp:libGLESv2', + ], + 'export_dependent_settings': + [ + '<(angle_path)/src/angle.gyp:angle_common', + ], + 'include_dirs': + [ + '<(angle_path)/include', + '<(angle_path)/util', + ], + 'sources': + [ + '<@(util_sources)', + ], + 'defines': + [ + 'GL_GLEXT_PROTOTYPES', + 'EGL_EGLEXT_PROTOTYPES', + ], + 'direct_dependent_settings': + { + 'include_dirs': + [ + '<(angle_path)/include', + '<(angle_path)/util', + ], + 'defines': + [ + 'GL_GLEXT_PROTOTYPES', + 'EGL_EGLEXT_PROTOTYPES', + ], + }, + 'conditions': + [ + ['OS=="win" and angle_build_winrt==0', + { + 'sources': + [ + '<@(util_win32_sources)', + ], + }], + ['OS=="win" and angle_build_winrt==1', { - 'target_name': 'angle_util', - 'type': 'static_library', - 'includes': [ '../build/common_defines.gypi', ], - 'dependencies': + 'sources': [ - '<(angle_path)/src/angle.gyp:angle_common', - '<(angle_path)/src/angle.gyp:libEGL', - '<(angle_path)/src/angle.gyp:libGLESv2', + '<@(util_winrt_sources)', ], - 'export_dependent_settings': + }], + ['OS=="linux"', + { + 'sources': [ - '<(angle_path)/src/angle.gyp:angle_common', + '<@(util_linux_sources)', ], - 'include_dirs': + }], + ['use_x11==1', + { + 'sources': [ - '<(angle_path)/include', - '<(angle_path)/util', + '<@(util_x11_sources)', ], + 'link_settings': + { + 'ldflags': + [ + ' + + Update ANGLE + https://bugs.webkit.org/show_bug.cgi?id=156755 + + Reviewed by Dean Jackson. + + * CMakeLists.txt: + * platform/graphics/ANGLEWebKitBridge.h: + (WebCore::ANGLEWebKitBridge::getResources): + * platform/graphics/cairo/GraphicsContext3DCairo.cpp: + (WebCore::GraphicsContext3D::GraphicsContext3D): + Continue to compile successfully with new ANGLE. + 2016-04-19 Chris Dumez Mark more classes as WTF_MAKE_FAST_ALLOCATED diff --git a/Source/WebCore/platform/graphics/ANGLEWebKitBridge.h b/Source/WebCore/platform/graphics/ANGLEWebKitBridge.h index 6f00b4dae467..9716c9893a4f 100644 --- a/Source/WebCore/platform/graphics/ANGLEWebKitBridge.h +++ b/Source/WebCore/platform/graphics/ANGLEWebKitBridge.h @@ -81,7 +81,7 @@ struct ANGLEShaderSymbol { class ANGLEWebKitBridge { public: - ANGLEWebKitBridge(ShShaderOutput = SH_GLSL_OUTPUT, ShShaderSpec = SH_WEBGL_SPEC); + ANGLEWebKitBridge(ShShaderOutput = SH_GLSL_COMPATIBILITY_OUTPUT, ShShaderSpec = SH_WEBGL_SPEC); ~ANGLEWebKitBridge(); ShBuiltInResources getResources() { return m_resources; } diff --git a/Source/WebCore/platform/graphics/cairo/GraphicsContext3DCairo.cpp b/Source/WebCore/platform/graphics/cairo/GraphicsContext3DCairo.cpp index 8c4186d71e53..58281d34fa54 100644 --- a/Source/WebCore/platform/graphics/cairo/GraphicsContext3DCairo.cpp +++ b/Source/WebCore/platform/graphics/cairo/GraphicsContext3DCairo.cpp @@ -80,7 +80,7 @@ PassRefPtr GraphicsContext3D::create(GraphicsContext3D::Attri GraphicsContext3D::GraphicsContext3D(GraphicsContext3D::Attributes attributes, HostWindow*, GraphicsContext3D::RenderStyle renderStyle) : m_currentWidth(0) , m_currentHeight(0) - , m_compiler(isGLES2Compliant() ? SH_ESSL_OUTPUT : SH_GLSL_OUTPUT) + , m_compiler(isGLES2Compliant() ? SH_ESSL_OUTPUT : SH_GLSL_COMPATIBILITY_OUTPUT) , m_attrs(attributes) , m_texture(0) , m_compositorTexture(0)