Restructured some Shader code. Added runtime temporary caching and sharing of shader stages. Resolves issue #1235.

--HG--
branch : minor
This commit is contained in:
Alex Szpakowski
2017-10-21 03:08:18 -03:00
parent f4e515edac
commit e5b0d96b27
16 changed files with 683 additions and 371 deletions
+4
View File
@@ -529,6 +529,8 @@ set(LOVE_SRC_MODULE_GRAPHICS_ROOT
src/modules/graphics/Quad.h
src/modules/graphics/Shader.cpp
src/modules/graphics/Shader.h
src/modules/graphics/ShaderStage.cpp
src/modules/graphics/ShaderStage.h
src/modules/graphics/SpriteBatch.cpp
src/modules/graphics/SpriteBatch.h
src/modules/graphics/StreamBuffer.cpp
@@ -588,6 +590,8 @@ set(LOVE_SRC_MODULE_GRAPHICS_OPENGL
src/modules/graphics/opengl/ParticleSystem.h
src/modules/graphics/opengl/Shader.cpp
src/modules/graphics/opengl/Shader.h
src/modules/graphics/opengl/ShaderStage.cpp
src/modules/graphics/opengl/ShaderStage.h
src/modules/graphics/opengl/SpriteBatch.cpp
src/modules/graphics/opengl/SpriteBatch.h
src/modules/graphics/opengl/StreamBuffer.cpp
@@ -821,9 +821,6 @@
FA27B39D1B498151008A9DCE /* Video.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA27B38A1B498151008A9DCE /* Video.cpp */; };
FA27B39E1B498151008A9DCE /* Video.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA27B38A1B498151008A9DCE /* Video.cpp */; };
FA27B39F1B498151008A9DCE /* Video.h in Headers */ = {isa = PBXBuildFile; fileRef = FA27B38B1B498151008A9DCE /* Video.h */; };
FA27B3A01B498151008A9DCE /* VideoStream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA27B38C1B498151008A9DCE /* VideoStream.cpp */; };
FA27B3A11B498151008A9DCE /* VideoStream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA27B38C1B498151008A9DCE /* VideoStream.cpp */; };
FA27B3A21B498151008A9DCE /* VideoStream.h in Headers */ = {isa = PBXBuildFile; fileRef = FA27B38D1B498151008A9DCE /* VideoStream.h */; };
FA27B3A91B498151008A9DCE /* Video.h in Headers */ = {isa = PBXBuildFile; fileRef = FA27B3931B498151008A9DCE /* Video.h */; };
FA27B3AA1B498151008A9DCE /* VideoStream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA27B3941B498151008A9DCE /* VideoStream.cpp */; };
FA27B3AB1B498151008A9DCE /* VideoStream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA27B3941B498151008A9DCE /* VideoStream.cpp */; };
@@ -843,6 +840,12 @@
FA2AF6741DAD64970032B62C /* vertex.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA2AF6731DAD64970032B62C /* vertex.cpp */; };
FA2AF6751DAD64970032B62C /* vertex.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA2AF6731DAD64970032B62C /* vertex.cpp */; };
FA317EBA18F28B6D00B0BCD7 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = FA317EB918F28B6D00B0BCD7 /* libz.dylib */; };
FA3C5E421F8C368C0003C579 /* ShaderStage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA3C5E401F8C368C0003C579 /* ShaderStage.cpp */; };
FA3C5E431F8C368C0003C579 /* ShaderStage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA3C5E401F8C368C0003C579 /* ShaderStage.cpp */; };
FA3C5E441F8C368C0003C579 /* ShaderStage.h in Headers */ = {isa = PBXBuildFile; fileRef = FA3C5E411F8C368C0003C579 /* ShaderStage.h */; };
FA3C5E471F8D80CA0003C579 /* ShaderStage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA3C5E451F8D80CA0003C579 /* ShaderStage.cpp */; };
FA3C5E481F8D80CA0003C579 /* ShaderStage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA3C5E451F8D80CA0003C579 /* ShaderStage.cpp */; };
FA3C5E491F8D80CA0003C579 /* ShaderStage.h in Headers */ = {isa = PBXBuildFile; fileRef = FA3C5E461F8D80CA0003C579 /* ShaderStage.h */; };
FA41A3C81C0A1F950084430C /* ASTCHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA41A3C61C0A1F950084430C /* ASTCHandler.cpp */; };
FA41A3C91C0A1F950084430C /* ASTCHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA41A3C61C0A1F950084430C /* ASTCHandler.cpp */; };
FA41A3CA1C0A1F950084430C /* ASTCHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = FA41A3C71C0A1F950084430C /* ASTCHandler.h */; };
@@ -963,6 +966,10 @@
FAA3A9AE1B7D465A00CED060 /* android.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAA3A9AC1B7D465A00CED060 /* android.cpp */; };
FAA3A9AF1B7D465A00CED060 /* android.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAA3A9AC1B7D465A00CED060 /* android.cpp */; };
FAA3A9B01B7D465A00CED060 /* android.h in Headers */ = {isa = PBXBuildFile; fileRef = FAA3A9AD1B7D465A00CED060 /* android.h */; };
FAA54ACA1F91660400A8FA7B /* OggDemuxer.h in Headers */ = {isa = PBXBuildFile; fileRef = FAA54AC61F91660400A8FA7B /* OggDemuxer.h */; };
FAA54ACB1F91660400A8FA7B /* TheoraVideoStream.h in Headers */ = {isa = PBXBuildFile; fileRef = FAA54AC71F91660400A8FA7B /* TheoraVideoStream.h */; };
FAA54ACC1F91660400A8FA7B /* TheoraVideoStream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAA54AC81F91660400A8FA7B /* TheoraVideoStream.cpp */; };
FAA54ACD1F91660400A8FA7B /* OggDemuxer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAA54AC91F91660400A8FA7B /* OggDemuxer.cpp */; };
FAA627CE18E7E1560080752D /* CoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FAA627CD18E7E1560080752D /* CoreServices.framework */; };
FAAA3FD81F64B3AD00F89E99 /* lprefix.h in Headers */ = {isa = PBXBuildFile; fileRef = FAAA3FD31F64B3AD00F89E99 /* lprefix.h */; };
FAAA3FD91F64B3AD00F89E99 /* lstrlib.c in Sources */ = {isa = PBXBuildFile; fileRef = FAAA3FD41F64B3AD00F89E99 /* lstrlib.c */; };
@@ -1737,8 +1744,6 @@
FA1E88821DF363DB00E808AA /* Filter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Filter.h; sourceTree = "<group>"; };
FA27B38A1B498151008A9DCE /* Video.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Video.cpp; sourceTree = "<group>"; };
FA27B38B1B498151008A9DCE /* Video.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Video.h; sourceTree = "<group>"; };
FA27B38C1B498151008A9DCE /* VideoStream.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = VideoStream.cpp; sourceTree = "<group>"; };
FA27B38D1B498151008A9DCE /* VideoStream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VideoStream.h; sourceTree = "<group>"; };
FA27B3931B498151008A9DCE /* Video.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Video.h; sourceTree = "<group>"; };
FA27B3941B498151008A9DCE /* VideoStream.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = VideoStream.cpp; sourceTree = "<group>"; };
FA27B3951B498151008A9DCE /* VideoStream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VideoStream.h; sourceTree = "<group>"; };
@@ -1757,6 +1762,10 @@
FA2AF6731DAD64970032B62C /* vertex.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = vertex.cpp; sourceTree = "<group>"; };
FA2E9BFE1C19E00C0004A1EE /* wrap_RandomGenerator.lua */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = wrap_RandomGenerator.lua; sourceTree = "<group>"; };
FA317EB918F28B6D00B0BCD7 /* libz.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.dylib; path = usr/lib/libz.dylib; sourceTree = SDKROOT; };
FA3C5E401F8C368C0003C579 /* ShaderStage.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = ShaderStage.cpp; sourceTree = "<group>"; };
FA3C5E411F8C368C0003C579 /* ShaderStage.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ShaderStage.h; sourceTree = "<group>"; };
FA3C5E451F8D80CA0003C579 /* ShaderStage.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = ShaderStage.cpp; sourceTree = "<group>"; };
FA3C5E461F8D80CA0003C579 /* ShaderStage.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ShaderStage.h; sourceTree = "<group>"; };
FA41A3C61C0A1F950084430C /* ASTCHandler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; path = ASTCHandler.cpp; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.cpp; };
FA41A3C71C0A1F950084430C /* ASTCHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = ASTCHandler.h; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
FA4B66C81ABBCF1900558F15 /* Timer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Timer.cpp; sourceTree = "<group>"; };
@@ -1835,6 +1844,10 @@
FA9D8DDF1DEF843D002CD881 /* Image.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Image.cpp; sourceTree = "<group>"; };
FAA3A9AC1B7D465A00CED060 /* android.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; path = android.cpp; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.cpp; };
FAA3A9AD1B7D465A00CED060 /* android.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = android.h; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
FAA54AC61F91660400A8FA7B /* OggDemuxer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OggDemuxer.h; sourceTree = "<group>"; };
FAA54AC71F91660400A8FA7B /* TheoraVideoStream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TheoraVideoStream.h; sourceTree = "<group>"; };
FAA54AC81F91660400A8FA7B /* TheoraVideoStream.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TheoraVideoStream.cpp; sourceTree = "<group>"; };
FAA54AC91F91660400A8FA7B /* OggDemuxer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OggDemuxer.cpp; sourceTree = "<group>"; };
FAA627CD18E7E1560080752D /* CoreServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreServices.framework; path = System/Library/Frameworks/CoreServices.framework; sourceTree = SDKROOT; };
FAAA3FD31F64B3AD00F89E99 /* lprefix.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = lprefix.h; sourceTree = "<group>"; };
FAAA3FD41F64B3AD00F89E99 /* lstrlib.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = lstrlib.c; sourceTree = "<group>"; };
@@ -2705,6 +2718,8 @@
FA0B7BBD1A95902C000E1D17 /* Quad.h */,
FA1BA0AF1E16FD0800AA2803 /* Shader.cpp */,
FA1BA0B01E16FD0800AA2803 /* Shader.h */,
FA3C5E401F8C368C0003C579 /* ShaderStage.cpp */,
FA3C5E411F8C368C0003C579 /* ShaderStage.h */,
FADF542D1E3DABF600012CC0 /* SpriteBatch.cpp */,
FADF542E1E3DABF600012CC0 /* SpriteBatch.h */,
FA29C0041E12355B00268CD8 /* StreamBuffer.cpp */,
@@ -2770,6 +2785,8 @@
FA0B7B9A1A95902C000E1D17 /* ParticleSystem.h */,
FA0B7B9D1A95902C000E1D17 /* Shader.cpp */,
FA0B7B9E1A95902C000E1D17 /* Shader.h */,
FA3C5E451F8D80CA0003C579 /* ShaderStage.cpp */,
FA3C5E461F8D80CA0003C579 /* ShaderStage.h */,
FA0B7B9F1A95902C000E1D17 /* SpriteBatch.cpp */,
FA0B7BA01A95902C000E1D17 /* SpriteBatch.h */,
FA7634481E28722A0066EF9E /* StreamBuffer.cpp */,
@@ -3244,10 +3261,12 @@
FA27B3891B498151008A9DCE /* theora */ = {
isa = PBXGroup;
children = (
FAA54AC91F91660400A8FA7B /* OggDemuxer.cpp */,
FAA54AC61F91660400A8FA7B /* OggDemuxer.h */,
FAA54AC81F91660400A8FA7B /* TheoraVideoStream.cpp */,
FAA54AC71F91660400A8FA7B /* TheoraVideoStream.h */,
FA27B38A1B498151008A9DCE /* Video.cpp */,
FA27B38B1B498151008A9DCE /* Video.h */,
FA27B38C1B498151008A9DCE /* VideoStream.cpp */,
FA27B38D1B498151008A9DCE /* VideoStream.h */,
);
path = theora;
sourceTree = "<group>";
@@ -3622,6 +3641,7 @@
FADF54361E3DAE6E00012CC0 /* wrap_SpriteBatch.h in Headers */,
FA0B7DB01A95902C000E1D17 /* wrap_CompressedImageData.h in Headers */,
FA0B7AC11A958EA3000E1D17 /* callbacks.h in Headers */,
FA3C5E491F8D80CA0003C579 /* ShaderStage.h in Headers */,
FA0B7D8F1A95902C000E1D17 /* ddsHandler.h in Headers */,
FAB2D5AC1AABDD8A008224A4 /* TrueTypeRasterizer.h in Headers */,
FAF140C41E20934C00F898D2 /* ShaderLang.h in Headers */,
@@ -3658,6 +3678,7 @@
FA0B7CE41A95902C000E1D17 /* wrap_Audio.h in Headers */,
FA0B7A7F1A958EA3000E1D17 /* b2ContactSolver.h in Headers */,
FADF540F1E3D7CDD00012CC0 /* wrap_Video.h in Headers */,
FAA54ACA1F91660400A8FA7B /* OggDemuxer.h in Headers */,
FA0B79491A958E3B000E1D17 /* version.h in Headers */,
FAF140581E20934C00F898D2 /* BaseTypes.h in Headers */,
FA0B7B2B1A958EA3000E1D17 /* stb_image.h in Headers */,
@@ -3783,9 +3804,9 @@
FA0B7E961A95902C000E1D17 /* Mpg123Decoder.h in Headers */,
FADF54091E3D78F700012CC0 /* Video.h in Headers */,
FA0B7D501A95902C000E1D17 /* SpriteBatch.h in Headers */,
FAA54ACB1F91660400A8FA7B /* TheoraVideoStream.h in Headers */,
FA0B7DD51A95902C000E1D17 /* BezierCurve.h in Headers */,
FA0B79271A958E3B000E1D17 /* int.h in Headers */,
FA27B3A21B498151008A9DCE /* VideoStream.h in Headers */,
FA0B7E531A95902C000E1D17 /* wrap_FrictionJoint.h in Headers */,
FA0B7EB71A95902C000E1D17 /* wrap_System.h in Headers */,
FA27B3A91B498151008A9DCE /* Video.h in Headers */,
@@ -3878,6 +3899,7 @@
217DFBF81D9F6D490055D849 /* pierror.h in Headers */,
217DFC021D9F6D490055D849 /* tcp.h in Headers */,
FA0B7A3D1A958EA3000E1D17 /* b2TimeOfImpact.h in Headers */,
FA3C5E441F8C368C0003C579 /* ShaderStage.h in Headers */,
FA0B79261A958E3B000E1D17 /* Exception.h in Headers */,
FA0B7D4D1A95902C000E1D17 /* Shader.h in Headers */,
FA0B793D1A958E3B000E1D17 /* runtime.h in Headers */,
@@ -4093,6 +4115,7 @@
FA4F2C031DE936C200CA37D7 /* auxiliar.c in Sources */,
FA0B7E731A95902C000E1D17 /* wrap_Shape.cpp in Sources */,
FA0B7CFE1A95902C000E1D17 /* File.cpp in Sources */,
FA3C5E481F8D80CA0003C579 /* ShaderStage.cpp in Sources */,
FA27B39E1B498151008A9DCE /* Video.cpp in Sources */,
FA0B7A751A958EA3000E1D17 /* b2ChainAndPolygonContact.cpp in Sources */,
FA0B7E6A1A95902C000E1D17 /* wrap_PulleyJoint.cpp in Sources */,
@@ -4128,6 +4151,7 @@
FAF140AA1E20934C00F898D2 /* SymbolTable.cpp in Sources */,
FA0B7A8D1A958EA3000E1D17 /* b2DistanceJoint.cpp in Sources */,
FA0B7A841A958EA3000E1D17 /* b2EdgeAndPolygonContact.cpp in Sources */,
FA3C5E431F8C368C0003C579 /* ShaderStage.cpp in Sources */,
FA0B7E191A95902C000E1D17 /* MotorJoint.cpp in Sources */,
FAF1406F1E20934C00F898D2 /* Initialize.cpp in Sources */,
FA0B7E4F1A95902C000E1D17 /* wrap_Fixture.cpp in Sources */,
@@ -4252,7 +4276,6 @@
FA0B791C1A958E3B000E1D17 /* b64.cpp in Sources */,
FA1E88851DF363E100E808AA /* Filter.cpp in Sources */,
FA0B7DA01A95902C000E1D17 /* KTXHandler.cpp in Sources */,
FA27B3A11B498151008A9DCE /* VideoStream.cpp in Sources */,
FA0B7A5C1A958EA3000E1D17 /* b2Timer.cpp in Sources */,
FA0B7CEC1A95902C000E1D17 /* Event.cpp in Sources */,
FA27B3AB1B498151008A9DCE /* VideoStream.cpp in Sources */,
@@ -4428,6 +4451,7 @@
FA0B7D2B1A95902C000E1D17 /* wrap_Rasterizer.cpp in Sources */,
FA0B7E8E1A95902C000E1D17 /* GmeDecoder.cpp in Sources */,
FA0B7CD61A95902C000E1D17 /* Audio.cpp in Sources */,
FA3C5E421F8C368C0003C579 /* ShaderStage.cpp in Sources */,
FA0B7A9E1A958EA3000E1D17 /* b2PrismaticJoint.cpp in Sources */,
FA0B7EAF1A95902C000E1D17 /* System.cpp in Sources */,
FA0B7EE21A95902D000E1D17 /* Window.cpp in Sources */,
@@ -4617,7 +4641,6 @@
FA0B7D9F1A95902C000E1D17 /* KTXHandler.cpp in Sources */,
FA1E88831DF363DB00E808AA /* Filter.cpp in Sources */,
FA0B7A2C1A958EA3000E1D17 /* b2CollideCircle.cpp in Sources */,
FA27B3A01B498151008A9DCE /* VideoStream.cpp in Sources */,
FA0B7CEB1A95902C000E1D17 /* Event.cpp in Sources */,
FA1557C31CE90BD200AFF582 /* EXRHandler.cpp in Sources */,
FA27B3AA1B498151008A9DCE /* VideoStream.cpp in Sources */,
@@ -4700,6 +4723,7 @@
FA0B7DCD1A95902C000E1D17 /* wrap_Keyboard.cpp in Sources */,
FA0B7EE51A95902D000E1D17 /* Window.cpp in Sources */,
FA6A2B6A1F5F7F560074C308 /* DataView.cpp in Sources */,
FA3C5E471F8D80CA0003C579 /* ShaderStage.cpp in Sources */,
FA0B7E391A95902C000E1D17 /* World.cpp in Sources */,
FA0B7ABD1A958EA3000E1D17 /* compress.c in Sources */,
FA0B7ACB1A958EA3000E1D17 /* list.c in Sources */,
@@ -4764,6 +4788,7 @@
FAF140881E20934C00F898D2 /* PoolAlloc.cpp in Sources */,
FA0B7AAD1A958EA3000E1D17 /* b2WheelJoint.cpp in Sources */,
FA0B7DEE1A95902C000E1D17 /* Mouse.cpp in Sources */,
FAA54ACC1F91660400A8FA7B /* TheoraVideoStream.cpp in Sources */,
FA1E887E1DF363CD00E808AA /* Filter.cpp in Sources */,
FA0B7D281A95902C000E1D17 /* wrap_GlyphData.cpp in Sources */,
FA0B7DE21A95902C000E1D17 /* wrap_RandomGenerator.cpp in Sources */,
@@ -4773,6 +4798,7 @@
FA0B7D0C1A95902C000E1D17 /* wrap_Filesystem.cpp in Sources */,
FA0B7AD91A958EA3000E1D17 /* glad.cpp in Sources */,
217DFBF61D9F6D490055D849 /* options.c in Sources */,
FAA54ACD1F91660400A8FA7B /* OggDemuxer.cpp in Sources */,
217DFBD91D9F6D490055D849 /* auxiliar.c in Sources */,
217DFBDB1D9F6D490055D849 /* buffer.c in Sources */,
FA0B7DB41A95902C000E1D17 /* wrap_ImageData.cpp in Sources */,
+81 -5
View File
@@ -22,6 +22,7 @@
#include "Graphics.h"
#include "Buffer.h"
#include "math/MathModule.h"
#include "data/DataModule.h"
#include "Polyline.h"
#include "font/Font.h"
#include "window/Window.h"
@@ -100,7 +101,7 @@ bool isDebugEnabled()
love::Type Graphics::type("graphics", &Module::type);
Shader::ShaderSource Graphics::defaultShaderCode[Shader::STANDARD_MAX_ENUM][Shader::LANGUAGE_MAX_ENUM][2];
Graphics::DefaultShaderCode Graphics::defaultShaderCode[Shader::STANDARD_MAX_ENUM][Shader::LANGUAGE_MAX_ENUM][2];
Graphics::Graphics()
: width(0)
@@ -115,6 +116,7 @@ Graphics::Graphics()
, canvasSwitchCount(0)
, drawCallsBatched(0)
, capabilities()
, cachedShaderStages()
{
transformStack.reserve(16);
transformStack.push_back(Matrix4());
@@ -149,6 +151,9 @@ Graphics::~Graphics()
delete streamBufferState.vb[1];
delete streamBufferState.indexBuffer;
for (int i = 0; i < (int) ShaderStage::STAGE_MAX_ENUM; i++)
cachedShaderStages[i].clear();
Shader::deinitialize();
}
@@ -177,9 +182,77 @@ Video *Graphics::newVideo(love::video::VideoStream *stream, float dpiscale)
return new Video(this, stream, dpiscale);
}
bool Graphics::validateShader(bool gles, const Shader::ShaderSource &source, std::string &err)
ShaderStage *Graphics::newShaderStage(ShaderStage::StageType stage, const std::string &optsource)
{
return Shader::validate(this, gles, source, true, err);
if (stage == ShaderStage::STAGE_MAX_ENUM)
throw love::Exception("Invalid shader stage.");
const std::string &source = optsource.empty() ? getCurrentDefaultShaderCode().source[stage] : optsource;
ShaderStage *s = nullptr;
std::string cachekey;
if (!source.empty())
{
data::HashFunction::Value hashvalue;
data::hash(data::HashFunction::FUNCTION_SHA1, source.c_str(), source.size(), hashvalue);
cachekey = std::string(hashvalue.data, hashvalue.size);
auto it = cachedShaderStages[stage].find(cachekey);
if (it != cachedShaderStages[stage].end())
{
s = it->second;
s->retain();
}
}
if (s == nullptr)
{
s = newShaderStageInternal(stage, cachekey, source, getRenderer() == RENDERER_OPENGLES);
if (!cachekey.empty())
cachedShaderStages[stage][cachekey] = s;
}
return s;
}
void Graphics::cleanupCachedShaderStage(ShaderStage::StageType type, const std::string &hashkey)
{
cachedShaderStages[type].erase(hashkey);
}
Shader *Graphics::newShader(const std::string &vertex, const std::string &pixel)
{
if (vertex.empty() && pixel.empty())
throw love::Exception("Error creating shader: no source code!");
StrongRef<ShaderStage> vertexstage(newShaderStage(ShaderStage::STAGE_VERTEX, vertex), Acquire::NORETAIN);
StrongRef<ShaderStage> pixelstage(newShaderStage(ShaderStage::STAGE_PIXEL, pixel), Acquire::NORETAIN);
return newShaderInternal(vertexstage.get(), pixelstage.get());
}
bool Graphics::validateShader(bool gles, const std::string &vertex, const std::string &pixel, std::string &err)
{
if (vertex.empty() && pixel.empty())
{
err = "Error validating shader: no source code!";
return false;
}
StrongRef<ShaderStage> vertexstage;
StrongRef<ShaderStage> pixelstage;
// Don't use cached shader stages, since the gles flag may not match the
// current renderer.
if (!vertex.empty())
vertexstage.set(new ShaderStageForValidation(this, ShaderStage::STAGE_VERTEX, vertex, gles), Acquire::NORETAIN);
if (!pixel.empty())
pixelstage.set(new ShaderStageForValidation(this, ShaderStage::STAGE_PIXEL, pixel, gles), Acquire::NORETAIN);
return Shader::validate(vertexstage.get(), pixelstage.get(), err);
}
int Graphics::getWidth() const
@@ -1425,9 +1498,12 @@ Vector2 Graphics::inverseTransformPoint(Vector2 point)
return p;
}
const Shader::ShaderSource &Graphics::getCurrentDefaultShaderCode() const
const Graphics::DefaultShaderCode &Graphics::getCurrentDefaultShaderCode() const
{
return defaultShaderCode[Shader::STANDARD_DEFAULT][getShaderLanguageTarget()][isGammaCorrect() ? 1 : 0];
int languageindex = (int) getShaderLanguageTarget();
int gammaindex = isGammaCorrect() ? 1 : 0;
return defaultShaderCode[Shader::STANDARD_DEFAULT][languageindex][gammaindex];
}
/**
+19 -4
View File
@@ -34,6 +34,7 @@
#include "Texture.h"
#include "Canvas.h"
#include "Font.h"
#include "ShaderStage.h"
#include "Shader.h"
#include "Quad.h"
#include "Mesh.h"
@@ -44,6 +45,7 @@
#include "font/Rasterizer.h"
#include "font/Font.h"
#include "video/VideoStream.h"
#include "data/HashFunction.h"
// C++
#include <string>
@@ -359,6 +361,11 @@ public:
{}
};
struct DefaultShaderCode
{
std::string source[ShaderStage::STAGE_MAX_ENUM];
};
Graphics();
virtual ~Graphics();
@@ -378,7 +385,9 @@ public:
virtual ParticleSystem *newParticleSystem(Texture *texture, int size) = 0;
virtual Canvas *newCanvas(const Canvas::Settings &settings) = 0;
virtual Shader *newShader(const Shader::ShaderSource &source) = 0;
ShaderStage *newShaderStage(ShaderStage::StageType stage, const std::string &source);
Shader *newShader(const std::string &vertex, const std::string &pixel);
virtual Buffer *newBuffer(size_t size, const void *data, BufferType type, vertex::Usage usage, uint32 mapflags) = 0;
@@ -390,7 +399,7 @@ public:
virtual Text *newText(Font *font, const std::vector<Font::ColoredString> &text = {}) = 0;
bool validateShader(bool gles, const Shader::ShaderSource &source, std::string &err);
bool validateShader(bool gles, const std::string &vertex, const std::string &pixel, std::string &err);
/**
* Resets the current color, background color, line style, and so forth.
@@ -758,7 +767,9 @@ public:
static void flushStreamDrawsGlobal();
virtual Shader::Language getShaderLanguageTarget() const = 0;
const Shader::ShaderSource &getCurrentDefaultShaderCode() const;
const DefaultShaderCode &getCurrentDefaultShaderCode() const;
void cleanupCachedShaderStage(ShaderStage::StageType type, const std::string &cachekey);
template <typename T>
T *getScratchBuffer(size_t count)
@@ -806,7 +817,7 @@ public:
static std::vector<std::string> getConstants(StackType);
// Default shader code (a shader is always required internally.)
static Shader::ShaderSource defaultShaderCode[Shader::STANDARD_MAX_ENUM][Shader::LANGUAGE_MAX_ENUM][2];
static DefaultShaderCode defaultShaderCode[Shader::STANDARD_MAX_ENUM][Shader::LANGUAGE_MAX_ENUM][2];
protected:
@@ -868,6 +879,8 @@ protected:
}
};
virtual ShaderStage *newShaderStageInternal(ShaderStage::StageType stage, const std::string &cachekey, const std::string &source, bool gles) = 0;
virtual Shader *newShaderInternal(ShaderStage *vertex, ShaderStage *pixel) = 0;
virtual StreamBuffer *newStreamBuffer(BufferType type, size_t size) = 0;
virtual void setCanvasInternal(const RenderTargets &rts, int w, int h, int pixelw, int pixelh, bool hasSRGBcanvas) = 0;
@@ -926,6 +939,8 @@ private:
std::vector<uint8> scratchBuffer;
std::unordered_map<std::string, ShaderStage *> cachedShaderStages[ShaderStage::STAGE_MAX_ENUM];
static StringMap<DrawMode, DRAW_MAX_ENUM>::Entry drawModeEntries[];
static StringMap<DrawMode, DRAW_MAX_ENUM> drawModes;
+11 -175
View File
@@ -29,103 +29,6 @@
// C++
#include <string>
// TODO: Use love.graphics to determine actual limits?
static const TBuiltInResource defaultTBuiltInResource = {
/* .MaxLights = */ 32,
/* .MaxClipPlanes = */ 6,
/* .MaxTextureUnits = */ 32,
/* .MaxTextureCoords = */ 32,
/* .MaxVertexAttribs = */ 64,
/* .MaxVertexUniformComponents = */ 16384,
/* .MaxVaryingFloats = */ 128,
/* .MaxVertexTextureImageUnits = */ 32,
/* .MaxCombinedTextureImageUnits = */ 80,
/* .MaxTextureImageUnits = */ 32,
/* .MaxFragmentUniformComponents = */ 16384,
/* .MaxDrawBuffers = */ 8,
/* .MaxVertexUniformVectors = */ 4096,
/* .MaxVaryingVectors = */ 32,
/* .MaxFragmentUniformVectors = */ 4096,
/* .MaxVertexOutputVectors = */ 32,
/* .MaxFragmentInputVectors = */ 31,
/* .MinProgramTexelOffset = */ -8,
/* .MaxProgramTexelOffset = */ 7,
/* .MaxClipDistances = */ 8,
/* .MaxComputeWorkGroupCountX = */ 65535,
/* .MaxComputeWorkGroupCountY = */ 65535,
/* .MaxComputeWorkGroupCountZ = */ 65535,
/* .MaxComputeWorkGroupSizeX = */ 1024,
/* .MaxComputeWorkGroupSizeY = */ 1024,
/* .MaxComputeWorkGroupSizeZ = */ 64,
/* .MaxComputeUniformComponents = */ 1024,
/* .MaxComputeTextureImageUnits = */ 32,
/* .MaxComputeImageUniforms = */ 16,
/* .MaxComputeAtomicCounters = */ 4096,
/* .MaxComputeAtomicCounterBuffers = */ 8,
/* .MaxVaryingComponents = */ 128,
/* .MaxVertexOutputComponents = */ 128,
/* .MaxGeometryInputComponents = */ 128,
/* .MaxGeometryOutputComponents = */ 128,
/* .MaxFragmentInputComponents = */ 128,
/* .MaxImageUnits = */ 192,
/* .MaxCombinedImageUnitsAndFragmentOutputs = */ 144,
/* .MaxCombinedShaderOutputResources = */ 144,
/* .MaxImageSamples = */ 32,
/* .MaxVertexImageUniforms = */ 16,
/* .MaxTessControlImageUniforms = */ 16,
/* .MaxTessEvaluationImageUniforms = */ 16,
/* .MaxGeometryImageUniforms = */ 16,
/* .MaxFragmentImageUniforms = */ 16,
/* .MaxCombinedImageUniforms = */ 80,
/* .MaxGeometryTextureImageUnits = */ 16,
/* .MaxGeometryOutputVertices = */ 256,
/* .MaxGeometryTotalOutputComponents = */ 1024,
/* .MaxGeometryUniformComponents = */ 1024,
/* .MaxGeometryVaryingComponents = */ 64,
/* .MaxTessControlInputComponents = */ 128,
/* .MaxTessControlOutputComponents = */ 128,
/* .MaxTessControlTextureImageUnits = */ 16,
/* .MaxTessControlUniformComponents = */ 1024,
/* .MaxTessControlTotalOutputComponents = */ 4096,
/* .MaxTessEvaluationInputComponents = */ 128,
/* .MaxTessEvaluationOutputComponents = */ 128,
/* .MaxTessEvaluationTextureImageUnits = */ 16,
/* .MaxTessEvaluationUniformComponents = */ 1024,
/* .MaxTessPatchComponents = */ 120,
/* .MaxPatchVertices = */ 32,
/* .MaxTessGenLevel = */ 64,
/* .MaxViewports = */ 16,
/* .MaxVertexAtomicCounters = */ 4096,
/* .MaxTessControlAtomicCounters = */ 4096,
/* .MaxTessEvaluationAtomicCounters = */ 4096,
/* .MaxGeometryAtomicCounters = */ 4096,
/* .MaxFragmentAtomicCounters = */ 4096,
/* .MaxCombinedAtomicCounters = */ 4096,
/* .MaxAtomicCounterBindings = */ 8,
/* .MaxVertexAtomicCounterBuffers = */ 8,
/* .MaxTessControlAtomicCounterBuffers = */ 8,
/* .MaxTessEvaluationAtomicCounterBuffers = */ 8,
/* .MaxGeometryAtomicCounterBuffers = */ 8,
/* .MaxFragmentAtomicCounterBuffers = */ 8,
/* .MaxCombinedAtomicCounterBuffers = */ 8,
/* .MaxAtomicCounterBufferSize = */ 16384,
/* .MaxTransformFeedbackBuffers = */ 4,
/* .MaxTransformFeedbackInterleavedComponents = */ 64,
/* .MaxCullDistances = */ 8,
/* .MaxCombinedClipAndCullDistances = */ 8,
/* .MaxSamples = */ 32,
/* .limits = */ {
/* .nonInductiveForLoops = */ 1,
/* .whileLoops = */ 1,
/* .doWhileLoops = */ 1,
/* .generalUniformIndexing = */ 1,
/* .generalAttributeMatrixVectorIndexing = */ 1,
/* .generalVaryingIndexing = */ 1,
/* .generalSamplerIndexing = */ 1,
/* .generalVariableIndexing = */ 1,
/* .generalConstantMatrixVectorIndexing = */ 1,
}};
namespace love
{
namespace graphics
@@ -136,17 +39,15 @@ love::Type Shader::type("Shader", &Object::type);
Shader *Shader::current = nullptr;
Shader *Shader::standardShaders[Shader::STANDARD_MAX_ENUM] = {nullptr};
Shader::Shader(const ShaderSource &source)
: shaderSource(source)
Shader::Shader(ShaderStage *vertex, ShaderStage *pixel)
: stages()
{
auto gfx = Module::getInstance<Graphics>(Module::M_GRAPHICS);
if (gfx == nullptr)
throw love::Exception("love.graphics must be initialized to create a Shader.");
bool gles = gfx->getRenderer() == Graphics::RENDERER_OPENGLES;
std::string err;
if (!validate(gfx, gles, source, false, err))
if (!validate(vertex, pixel, err))
throw love::Exception("%s", err.c_str());
stages[ShaderStage::STAGE_VERTEX] = vertex;
stages[ShaderStage::STAGE_PIXEL] = pixel;
}
Shader::~Shader()
@@ -225,62 +126,15 @@ void Shader::checkMainTexture(Texture *tex) const
checkMainTextureType(tex->getTextureType(), tex->getDepthSampleMode().hasValue);
}
bool Shader::validate(Graphics *gfx, bool gles, const ShaderSource &source, bool checkWithDefaults, std::string &err)
bool Shader::validate(ShaderStage *vertex, ShaderStage *pixel, std::string &err)
{
if (source.vertex.empty() && source.pixel.empty())
{
err = "Error validating shader: no source code!";
return false;
}
bool supportsGLSL3 = gfx->getCapabilities().features[Graphics::FEATURE_GLSL3];
int defaultversion = gles ? 100 : 120;
EProfile defaultprofile = ENoProfile;
glslang::TShader vshader(EShLangVertex);
glslang::TShader pshader(EShLangFragment);
// TProgram must be destroyed before TShader.
glslang::TProgram program;
auto addshader = [&](glslang::TShader &s, const std::string &src, ShaderStage stage) -> bool
{
if (src.empty())
return true;
if (vertex != nullptr)
program.addShader(vertex->getGLSLangShader());
const char *csrc = src.c_str();
int srclen = (int) src.length();
s.setStringsWithLengths(&csrc, &srclen, 1);
bool forcedefault = false;
if (src.find("#define LOVE_GLSL1_ON_GLSL3") != std::string::npos)
forcedefault = true;
bool forwardcompat = supportsGLSL3 && !forcedefault;
if (!s.parse(&defaultTBuiltInResource, defaultversion, defaultprofile, forcedefault, forwardcompat, EShMsgSuppressWarnings))
{
const char *stagename = "unknown";
getConstant(stage, stagename);
err = "Error validating " + std::string(stagename) + " shader:\n\n"
+ std::string(s.getInfoLog()) + "\n" + std::string(s.getInfoDebugLog());
return false;
}
program.addShader(&s);
return true;
};
const ShaderSource &defaults = gfx->getCurrentDefaultShaderCode();
const std::string &vertcode = (checkWithDefaults && source.vertex.empty()) ? defaults.vertex : source.vertex;
const std::string &pixcode = (checkWithDefaults && source.pixel.empty()) ? defaults.pixel : source.pixel;
if (!addshader(vshader, vertcode, STAGE_VERTEX))
return false;
if (!addshader(pshader, pixcode, STAGE_PIXEL))
return false;
if (pixel != nullptr)
program.addShader(pixel->getGLSLangShader());
if (!program.link(EShMsgDefault))
{
@@ -311,16 +165,6 @@ bool Shader::getConstant(Language in, const char *&out)
return languages.find(in, out);
}
bool Shader::getConstant(const char *in, ShaderStage &out)
{
return stageNames.find(in, out);
}
bool Shader::getConstant(ShaderStage in, const char *&out)
{
return stageNames.find(in, out);
}
bool Shader::getConstant(const char *in, BuiltinUniform &out)
{
return builtinNames.find(in, out);
@@ -341,14 +185,6 @@ StringMap<Shader::Language, Shader::LANGUAGE_MAX_ENUM>::Entry Shader::languageEn
StringMap<Shader::Language, Shader::LANGUAGE_MAX_ENUM> Shader::languages(Shader::languageEntries, sizeof(Shader::languageEntries));
StringMap<Shader::ShaderStage, Shader::STAGE_MAX_ENUM>::Entry Shader::stageNameEntries[] =
{
{ "vertex", STAGE_VERTEX },
{ "pixel", STAGE_PIXEL },
};
StringMap<Shader::ShaderStage, Shader::STAGE_MAX_ENUM> Shader::stageNames(Shader::stageNameEntries, sizeof(Shader::stageNameEntries));
StringMap<Shader::BuiltinUniform, Shader::BUILTIN_MAX_ENUM>::Entry Shader::builtinNameEntries[] =
{
{ "MainTex", BUILTIN_TEXTURE_MAIN },
+4 -33
View File
@@ -24,6 +24,7 @@
#include "common/Object.h"
#include "common/StringMap.h"
#include "Texture.h"
#include "ShaderStage.h"
// STL
#include <string>
@@ -59,13 +60,6 @@ public:
LANGUAGE_MAX_ENUM
};
enum ShaderStage
{
STAGE_VERTEX,
STAGE_PIXEL,
STAGE_MAX_ENUM
};
// Built-in uniform variables.
enum BuiltinUniform
{
@@ -103,12 +97,6 @@ public:
STANDARD_MAX_ENUM
};
struct ShaderSource
{
std::string vertex;
std::string pixel;
};
struct MatrixSize
{
short columns;
@@ -150,7 +138,7 @@ public:
// Pointer to the default Shader.
static Shader *standardShaders[STANDARD_MAX_ENUM];
Shader(const ShaderSource &source);
Shader(ShaderStage *vertex, ShaderStage *pixel);
virtual ~Shader();
/**
@@ -197,7 +185,7 @@ public:
virtual ptrdiff_t getHandle() const = 0;
static bool validate(Graphics *gfx, bool gles, const ShaderSource &source, bool checkWithDefaults, std::string &err);
static bool validate(ShaderStage *vertex, ShaderStage *pixel, std::string &err);
static bool initialize();
static void deinitialize();
@@ -205,34 +193,17 @@ public:
static bool getConstant(const char *in, Language &out);
static bool getConstant(Language in, const char *&out);
static bool getConstant(const char *in, ShaderStage &out);
static bool getConstant(ShaderStage in, const char *&out);
static bool getConstant(const char *in, BuiltinUniform &out);
static bool getConstant(BuiltinUniform in, const char *&out);
protected:
struct CachedShaderStage
{
int referenceCount;
ShaderStage stage;
glslang::TShader *glslangShader;
ptrdiff_t handle;
};
// Source code used for this Shader.
ShaderSource shaderSource;
static std::map<std::string, CachedShaderStage> cachedShaders;
StrongRef<ShaderStage> stages[ShaderStage::STAGE_MAX_ENUM];
private:
static StringMap<Language, LANGUAGE_MAX_ENUM>::Entry languageEntries[];
static StringMap<Language, LANGUAGE_MAX_ENUM> languages;
static StringMap<ShaderStage, STAGE_MAX_ENUM>::Entry stageNameEntries[];
static StringMap<ShaderStage, STAGE_MAX_ENUM> stageNames;
// Names for the built-in uniform variables.
static StringMap<BuiltinUniform, BUILTIN_MAX_ENUM>::Entry builtinNameEntries[];
+205
View File
@@ -0,0 +1,205 @@
/**
* Copyright (c) 2006-2017 LOVE Development Team
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
**/
#include "ShaderStage.h"
#include "common/Exception.h"
#include "Graphics.h"
#include "libraries/glslang/glslang/Public/ShaderLang.h"
// TODO: Use love.graphics to determine actual limits?
static const TBuiltInResource defaultTBuiltInResource = {
/* .MaxLights = */ 32,
/* .MaxClipPlanes = */ 6,
/* .MaxTextureUnits = */ 32,
/* .MaxTextureCoords = */ 32,
/* .MaxVertexAttribs = */ 64,
/* .MaxVertexUniformComponents = */ 16384,
/* .MaxVaryingFloats = */ 128,
/* .MaxVertexTextureImageUnits = */ 32,
/* .MaxCombinedTextureImageUnits = */ 80,
/* .MaxTextureImageUnits = */ 32,
/* .MaxFragmentUniformComponents = */ 16384,
/* .MaxDrawBuffers = */ 8,
/* .MaxVertexUniformVectors = */ 4096,
/* .MaxVaryingVectors = */ 32,
/* .MaxFragmentUniformVectors = */ 4096,
/* .MaxVertexOutputVectors = */ 32,
/* .MaxFragmentInputVectors = */ 31,
/* .MinProgramTexelOffset = */ -8,
/* .MaxProgramTexelOffset = */ 7,
/* .MaxClipDistances = */ 8,
/* .MaxComputeWorkGroupCountX = */ 65535,
/* .MaxComputeWorkGroupCountY = */ 65535,
/* .MaxComputeWorkGroupCountZ = */ 65535,
/* .MaxComputeWorkGroupSizeX = */ 1024,
/* .MaxComputeWorkGroupSizeY = */ 1024,
/* .MaxComputeWorkGroupSizeZ = */ 64,
/* .MaxComputeUniformComponents = */ 1024,
/* .MaxComputeTextureImageUnits = */ 32,
/* .MaxComputeImageUniforms = */ 16,
/* .MaxComputeAtomicCounters = */ 4096,
/* .MaxComputeAtomicCounterBuffers = */ 8,
/* .MaxVaryingComponents = */ 128,
/* .MaxVertexOutputComponents = */ 128,
/* .MaxGeometryInputComponents = */ 128,
/* .MaxGeometryOutputComponents = */ 128,
/* .MaxFragmentInputComponents = */ 128,
/* .MaxImageUnits = */ 192,
/* .MaxCombinedImageUnitsAndFragmentOutputs = */ 144,
/* .MaxCombinedShaderOutputResources = */ 144,
/* .MaxImageSamples = */ 32,
/* .MaxVertexImageUniforms = */ 16,
/* .MaxTessControlImageUniforms = */ 16,
/* .MaxTessEvaluationImageUniforms = */ 16,
/* .MaxGeometryImageUniforms = */ 16,
/* .MaxFragmentImageUniforms = */ 16,
/* .MaxCombinedImageUniforms = */ 80,
/* .MaxGeometryTextureImageUnits = */ 16,
/* .MaxGeometryOutputVertices = */ 256,
/* .MaxGeometryTotalOutputComponents = */ 1024,
/* .MaxGeometryUniformComponents = */ 1024,
/* .MaxGeometryVaryingComponents = */ 64,
/* .MaxTessControlInputComponents = */ 128,
/* .MaxTessControlOutputComponents = */ 128,
/* .MaxTessControlTextureImageUnits = */ 16,
/* .MaxTessControlUniformComponents = */ 1024,
/* .MaxTessControlTotalOutputComponents = */ 4096,
/* .MaxTessEvaluationInputComponents = */ 128,
/* .MaxTessEvaluationOutputComponents = */ 128,
/* .MaxTessEvaluationTextureImageUnits = */ 16,
/* .MaxTessEvaluationUniformComponents = */ 1024,
/* .MaxTessPatchComponents = */ 120,
/* .MaxPatchVertices = */ 32,
/* .MaxTessGenLevel = */ 64,
/* .MaxViewports = */ 16,
/* .MaxVertexAtomicCounters = */ 4096,
/* .MaxTessControlAtomicCounters = */ 4096,
/* .MaxTessEvaluationAtomicCounters = */ 4096,
/* .MaxGeometryAtomicCounters = */ 4096,
/* .MaxFragmentAtomicCounters = */ 4096,
/* .MaxCombinedAtomicCounters = */ 4096,
/* .MaxAtomicCounterBindings = */ 8,
/* .MaxVertexAtomicCounterBuffers = */ 8,
/* .MaxTessControlAtomicCounterBuffers = */ 8,
/* .MaxTessEvaluationAtomicCounterBuffers = */ 8,
/* .MaxGeometryAtomicCounterBuffers = */ 8,
/* .MaxFragmentAtomicCounterBuffers = */ 8,
/* .MaxCombinedAtomicCounterBuffers = */ 8,
/* .MaxAtomicCounterBufferSize = */ 16384,
/* .MaxTransformFeedbackBuffers = */ 4,
/* .MaxTransformFeedbackInterleavedComponents = */ 64,
/* .MaxCullDistances = */ 8,
/* .MaxCombinedClipAndCullDistances = */ 8,
/* .MaxSamples = */ 32,
/* .limits = */ {
/* .nonInductiveForLoops = */ 1,
/* .whileLoops = */ 1,
/* .doWhileLoops = */ 1,
/* .generalUniformIndexing = */ 1,
/* .generalAttributeMatrixVectorIndexing = */ 1,
/* .generalVaryingIndexing = */ 1,
/* .generalSamplerIndexing = */ 1,
/* .generalVariableIndexing = */ 1,
/* .generalConstantMatrixVectorIndexing = */ 1,
}
};
namespace love
{
namespace graphics
{
ShaderStage::ShaderStage(Graphics *gfx, StageType stage, const std::string &glsl, bool gles, const std::string &cachekey)
: stageType(stage)
, source(glsl)
, cacheKey(cachekey)
, glslangShader(nullptr)
{
EShLanguage glslangStage = EShLangCount;
if (stage == STAGE_VERTEX)
glslangStage = EShLangVertex;
else if (stage == STAGE_PIXEL)
glslangStage = EShLangFragment;
else
throw love::Exception("Cannot compile shader stage: unknown stage type.");
glslangShader = new glslang::TShader(glslangStage);
bool supportsGLSL3 = gfx->getCapabilities().features[Graphics::FEATURE_GLSL3];
int defaultversion = gles ? 100 : 120;
EProfile defaultprofile = ENoProfile;
const char *csrc = glsl.c_str();
int srclen = (int) glsl.length();
glslangShader->setStringsWithLengths(&csrc, &srclen, 1);
bool forcedefault = false;
if (source.find("#define LOVE_GLSL1_ON_GLSL3") != std::string::npos)
forcedefault = true;
bool forwardcompat = supportsGLSL3 && !forcedefault;
if (!glslangShader->parse(&defaultTBuiltInResource, defaultversion, defaultprofile, forcedefault, forwardcompat, EShMsgSuppressWarnings))
{
const char *stagename = "unknown";
getConstant(stage, stagename);
std::string err = "Error validating " + std::string(stagename) + " shader:\n\n"
+ std::string(glslangShader->getInfoLog()) + "\n"
+ std::string(glslangShader->getInfoDebugLog());
delete glslangShader;
throw love::Exception("%s", err.c_str());
}
}
ShaderStage::~ShaderStage()
{
if (!cacheKey.empty())
{
auto gfx = Module::getInstance<Graphics>(Module::M_GRAPHICS);
if (gfx != nullptr)
gfx->cleanupCachedShaderStage(stageType, cacheKey);
}
delete glslangShader;
}
bool ShaderStage::getConstant(const char *in, StageType &out)
{
return stageNames.find(in, out);
}
bool ShaderStage::getConstant(StageType in, const char *&out)
{
return stageNames.find(in, out);
}
StringMap<ShaderStage::StageType, ShaderStage::STAGE_MAX_ENUM>::Entry ShaderStage::stageNameEntries[] =
{
{ "vertex", STAGE_VERTEX },
{ "pixel", STAGE_PIXEL },
};
StringMap<ShaderStage::StageType, ShaderStage::STAGE_MAX_ENUM> ShaderStage::stageNames(ShaderStage::stageNameEntries, sizeof(ShaderStage::stageNameEntries));
} // graphics
} // love
+99
View File
@@ -0,0 +1,99 @@
/**
* Copyright (c) 2006-2017 LOVE Development Team
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
**/
#pragma once
#include "common/Object.h"
#include "common/StringMap.h"
#include "Volatile.h"
#include <stddef.h>
#include <string>
namespace glslang
{
class TShader;
}
namespace love
{
namespace graphics
{
class Graphics;
class ShaderStage : public love::Object, public Volatile
{
public:
enum StageType
{
STAGE_VERTEX,
STAGE_PIXEL,
STAGE_MAX_ENUM
};
ShaderStage(Graphics *gfx, StageType stage, const std::string &glsl, bool gles, const std::string &cachekey);
virtual ~ShaderStage();
StageType getStageType() const { return stageType; }
const std::string &getSource() const { return source; }
const std::string &getWarnings() const { return warnings; }
glslang::TShader *getGLSLangShader() const { return glslangShader; }
virtual ptrdiff_t getHandle() const = 0;
static bool getConstant(const char *in, StageType &out);
static bool getConstant(StageType in, const char *&out);
protected:
std::string warnings;
private:
StageType stageType;
std::string source;
std::string cacheKey;
glslang::TShader *glslangShader;
static StringMap<StageType, STAGE_MAX_ENUM>::Entry stageNameEntries[];
static StringMap<StageType, STAGE_MAX_ENUM> stageNames;
}; // ShaderStage
class ShaderStageForValidation final : public ShaderStage
{
public:
ShaderStageForValidation(Graphics *gfx, StageType stage, const std::string &glsl, bool gles)
: ShaderStage(gfx, stage, glsl, gles, "")
{}
virtual ~ShaderStageForValidation() {}
ptrdiff_t getHandle() const override { return 0; }
bool loadVolatile() override { return true; }
void unloadVolatile() override { }
}; // ShaderStageForValidation
} // graphics
} // love
-8
View File
@@ -52,14 +52,6 @@ enum TextureType
TEXTURE_MAX_ENUM
};
class TextureTooLargeException : public love::Exception
{
public:
TextureTooLargeException(const char *dimname, int pix)
: Exception("Cannot create texture: %s of %d pixels is too large for this system.", dimname, pix)
{}
};
/**
* Base class for 2D textures. All textures can be drawn with Quads, have a
* width and height, and have filter and wrap modes.
+12 -3
View File
@@ -30,6 +30,7 @@
#include "window/Window.h"
#include "Buffer.h"
#include "Text.h"
#include "ShaderStage.h"
#include "libraries/xxHash/xxhash.h"
@@ -126,9 +127,14 @@ love::graphics::Canvas *Graphics::newCanvas(const Canvas::Settings &settings)
return new Canvas(settings);
}
love::graphics::Shader *Graphics::newShader(const Shader::ShaderSource &source)
love::graphics::ShaderStage *Graphics::newShaderStageInternal(ShaderStage::StageType stage, const std::string &cachekey, const std::string &source, bool gles)
{
return new Shader(source);
return new ShaderStage(this, stage, source, gles, cachekey);
}
love::graphics::Shader *Graphics::newShaderInternal(love::graphics::ShaderStage *vertex, love::graphics::ShaderStage *pixel)
{
return new Shader(vertex, pixel);
}
love::graphics::Buffer *Graphics::newBuffer(size_t size, const void *data, BufferType type, vertex::Usage usage, uint32 mapflags)
@@ -281,7 +287,10 @@ bool Graphics::setMode(int width, int height, int pixelwidth, int pixelheight, b
try
{
if (!Shader::standardShaders[i])
Shader::standardShaders[i] = newShader(defaultShaderCode[i][target][gammacorrect]);
{
const auto &code = defaultShaderCode[i][target][gammacorrect];
Shader::standardShaders[i] = love::graphics::Graphics::newShader(code.source[ShaderStage::STAGE_VERTEX], code.source[ShaderStage::STAGE_PIXEL]);
}
}
catch (love::Exception &)
{
+2 -1
View File
@@ -68,7 +68,6 @@ public:
love::graphics::ParticleSystem *newParticleSystem(Texture *texture, int size) override;
love::graphics::Canvas *newCanvas(const Canvas::Settings &settings) override;
love::graphics::Shader *newShader(const Shader::ShaderSource &source) override;
love::graphics::Buffer *newBuffer(size_t size, const void *data, BufferType type, vertex::Usage usage, uint32 mapflags) override;
@@ -126,6 +125,8 @@ public:
private:
love::graphics::ShaderStage *newShaderStageInternal(ShaderStage::StageType stage, const std::string &cachekey, const std::string &source, bool gles) override;
love::graphics::Shader *newShaderInternal(love::graphics::ShaderStage *vertex, love::graphics::ShaderStage *pixel) override;
love::graphics::StreamBuffer *newStreamBuffer(BufferType type, size_t size) override;
void setCanvasInternal(const RenderTargets &rts, int w, int h, int pixelw, int pixelh, bool hasSRGBcanvas) override;
void initCapabilities() override;
+18 -101
View File
@@ -36,8 +36,8 @@ namespace graphics
namespace opengl
{
Shader::Shader(const ShaderSource &source)
: love::graphics::Shader(source)
Shader::Shader(love::graphics::ShaderStage *vertex, love::graphics::ShaderStage *pixel)
: love::graphics::Shader(vertex, pixel)
, program(0)
, builtinUniforms()
, builtinUniformInfo()
@@ -73,71 +73,6 @@ Shader::~Shader()
}
}
GLuint Shader::compileCode(ShaderStage stage, const std::string &code)
{
GLenum glstage;
const char *typestr;
if (!getConstant(stage, typestr))
typestr = "";
switch (stage)
{
case STAGE_VERTEX:
glstage = GL_VERTEX_SHADER;
break;
case STAGE_PIXEL:
glstage = GL_FRAGMENT_SHADER;
break;
default:
throw love::Exception("Cannot create shader object: unknown shader type.");
break;
}
GLuint shaderid = glCreateShader(glstage);
if (shaderid == 0)
{
if (glGetError() == GL_INVALID_ENUM)
throw love::Exception("Cannot create %s shader object: %s shaders not supported.", typestr, typestr);
else
throw love::Exception("Cannot create %s shader object.", typestr);
}
const char *src = code.c_str();
GLint srclen = (GLint) code.length();
glShaderSource(shaderid, 1, (const GLchar **)&src, &srclen);
glCompileShader(shaderid);
GLint infologlen;
glGetShaderiv(shaderid, GL_INFO_LOG_LENGTH, &infologlen);
// Get any warnings the shader compiler may have produced.
if (infologlen > 0)
{
GLchar *infolog = new GLchar[infologlen];
glGetShaderInfoLog(shaderid, infologlen, nullptr, infolog);
// Save any warnings for later querying.
shaderWarnings[stage] = infolog;
delete[] infolog;
}
GLint status;
glGetShaderiv(shaderid, GL_COMPILE_STATUS, &status);
if (status == GL_FALSE)
{
glDeleteShader(shaderid);
throw love::Exception("Cannot compile %s shader code:\n%s",
typestr, shaderWarnings[stage].c_str());
}
return shaderid;
}
void Shader::mapActiveUniforms()
{
// Built-in uniform locations default to -1 (nonexistent.)
@@ -376,38 +311,22 @@ bool Shader::loadVolatile()
textureUnits.clear();
textureUnits.push_back(TextureUnit());
std::vector<GLuint> shaderids;
auto gfx = Module::getInstance<love::graphics::Graphics>(Module::M_GRAPHICS);
const ShaderSource &defaults = gfx->getCurrentDefaultShaderCode();
// The shader program must have both vertex and pixel shader stages.
const std::string &vertexcode = shaderSource.vertex.empty() ? defaults.vertex : shaderSource.vertex;
const std::string &pixelcode = shaderSource.pixel.empty() ? defaults.pixel : shaderSource.pixel;
try
for (const auto &stage : stages)
{
shaderids.push_back(compileCode(STAGE_VERTEX, vertexcode));
shaderids.push_back(compileCode(STAGE_PIXEL, pixelcode));
}
catch (love::Exception &)
{
for (GLuint id : shaderids)
glDeleteShader(id);
throw;
if (stage.get() != nullptr)
stage->loadVolatile();
}
program = glCreateProgram();
if (program == 0)
{
for (GLuint id : shaderids)
glDeleteShader(id);
throw love::Exception("Cannot create shader program object.");
}
for (GLuint id : shaderids)
glAttachShader(program, id);
for (const auto &stage : stages)
{
if (stage.get() != nullptr)
glAttachShader(program, (GLuint) stage->getHandle());
}
// Bind generic vertex attribute indices to names in the shader.
for (int i = 0; i < int(ATTRIB_MAX_ENUM); i++)
@@ -419,10 +338,6 @@ bool Shader::loadVolatile()
glLinkProgram(program);
// Flag shaders for auto-deletion when the program object is deleted.
for (GLuint id : shaderids)
glDeleteShader(id);
GLint status;
glGetProgramiv(program, GL_LINK_STATUS, &status);
@@ -477,8 +392,6 @@ void Shader::unloadVolatile()
// And the locations of any built-in uniform variables.
for (int i = 0; i < int(BUILTIN_MAX_ENUM); i++)
builtinUniforms[i] = -1;
shaderWarnings.clear();
}
std::string Shader::getProgramWarnings() const
@@ -506,11 +419,15 @@ std::string Shader::getWarnings() const
std::string warnings;
const char *stagestr;
// Get the individual shader stage warnings
for (const auto &warning : shaderWarnings)
for (const auto &stage : stages)
{
if (getConstant(warning.first, stagestr))
warnings += std::string(stagestr) + std::string(" shader:\n") + warning.second;
if (stage.get() == nullptr)
continue;
const std::string &stagewarnings = stage->getWarnings();
if (ShaderStage::getConstant(stage->getStageType(), stagestr))
warnings += std::string(stagestr) + std::string(" shader:\n") + stagewarnings;
}
warnings += getProgramWarnings();
+1 -7
View File
@@ -47,8 +47,7 @@ public:
* Creates a new Shader using a list of source codes.
* Source must contain either vertex or pixel shader code, or both.
**/
Shader(const ShaderSource &source);
Shader(love::graphics::ShaderStage *vertex, love::graphics::ShaderStage *pixel);
virtual ~Shader();
// Implements Volatile
@@ -96,16 +95,11 @@ private:
TextureType getUniformTextureType(GLenum type) const;
bool isDepthTextureType(GLenum type) const;
GLuint compileCode(ShaderStage stage, const std::string &code);
void flushStreamDraws() const;
// Get any warnings or errors generated only by the shader program object.
std::string getProgramWarnings() const;
// Shader compiler warning strings for individual shader stages.
std::map<ShaderStage, std::string> shaderWarnings;
// volatile
GLuint program;
+105
View File
@@ -0,0 +1,105 @@
/**
* Copyright (c) 2006-2017 LOVE Development Team
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
**/
#include "ShaderStage.h"
namespace love
{
namespace graphics
{
namespace opengl
{
ShaderStage::ShaderStage(love::graphics::Graphics *gfx, StageType stage, const std::string &source, bool gles, const std::string &cachekey)
: love::graphics::ShaderStage(gfx, stage, source, gles, cachekey)
, glShader(0)
{
loadVolatile();
}
ShaderStage::~ShaderStage()
{
unloadVolatile();
}
bool ShaderStage::loadVolatile()
{
if (glShader != 0)
return true;
StageType stage = getStageType();
const char *typestr = "unknown";
getConstant(stage, typestr);
GLenum glstage = 0;
if (stage == STAGE_VERTEX)
glstage = GL_VERTEX_SHADER;
else if (stage == STAGE_PIXEL)
glstage = GL_FRAGMENT_SHADER;
else
throw love::Exception("%s shader stage is not handled in OpenGL backend code.", typestr);
glShader = glCreateShader(glstage);
if (glShader == 0)
throw love::Exception("Cannot create OpenGL %s shader object.", typestr);
const std::string &sourcestring = getSource();
const char *src = sourcestring.c_str();
GLint srclen = (GLint) sourcestring.length();
glShaderSource(glShader, 1, (const GLchar **)&src, &srclen);
glCompileShader(glShader);
GLint infologlen;
glGetShaderiv(glShader, GL_INFO_LOG_LENGTH, &infologlen);
if (infologlen > 0)
{
GLchar *infolog = new GLchar[infologlen];
glGetShaderInfoLog(glShader, infologlen, nullptr, infolog);
warnings = infolog;
delete[] infolog;
}
GLint status = GL_FALSE;
glGetShaderiv(glShader, GL_COMPILE_STATUS, &status);
if (glShader == GL_FALSE)
{
glDeleteShader(glShader);
throw love::Exception("Cannot compile %s shader code:\n%s", typestr, warnings.c_str());
}
return true;
}
void ShaderStage::unloadVolatile()
{
if (glShader != 0)
glDeleteShader(glShader);
glShader = 0;
}
} // opengl
} // graphics
} // love
+55
View File
@@ -0,0 +1,55 @@
/**
* Copyright (c) 2006-2017 LOVE Development Team
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
**/
#pragma once
#include "graphics/ShaderStage.h"
#include "graphics/Volatile.h"
#include "OpenGL.h"
namespace love
{
namespace graphics
{
namespace opengl
{
class ShaderStage final : public love::graphics::ShaderStage
{
public:
ShaderStage(love::graphics::Graphics *gfx, StageType stage, const std::string &source, bool gles, const std::string &cachekey);
virtual ~ShaderStage();
ptrdiff_t getHandle() const override { return glShader; }
// Implements Volatile.
bool loadVolatile() override;
void unloadVolatile() override;
private:
GLuint glShader;
}; // ShaderStage
} // opengl
} // graphics
} // love
+31 -24
View File
@@ -1234,7 +1234,7 @@ int w_newCanvas(lua_State *L)
return 1;
}
static int w_getShaderSource(lua_State *L, int startidx, bool gles, Shader::ShaderSource &source)
static int w_getShaderSource(lua_State *L, int startidx, bool gles, std::string &vertexsource, std::string &pixelsource)
{
using namespace love::filesystem;
@@ -1315,17 +1315,17 @@ static int w_getShaderSource(lua_State *L, int startidx, bool gles, Shader::Shad
// vertex shader code
if (lua_isstring(L, -2))
source.vertex = luax_checkstring(L, -2);
vertexsource = luax_checkstring(L, -2);
else if (has_arg1 && has_arg2)
return luaL_error(L, "Could not parse vertex shader code (missing 'position' function?)");
// pixel shader code
if (lua_isstring(L, -1))
source.pixel = luax_checkstring(L, -1);
pixelsource = luax_checkstring(L, -1);
else if (has_arg1 && has_arg2)
return luaL_error(L, "Could not parse pixel shader code (missing 'effect' function?)");
if (source.vertex.empty() && source.pixel.empty())
if (vertexsource.empty() && pixelsource.empty())
{
// Original args had source code, but effectCodeToGLSL couldn't translate it
for (int i = startidx; i < startidx + 2; i++)
@@ -1342,13 +1342,13 @@ int w_newShader(lua_State *L)
{
bool gles = instance()->getRenderer() == Graphics::RENDERER_OPENGLES;
Shader::ShaderSource source;
w_getShaderSource(L, 1, gles, source);
std::string vertexsource, pixelsource;
w_getShaderSource(L, 1, gles, vertexsource, pixelsource);
bool should_error = false;
try
{
Shader *shader = instance()->newShader(source);
Shader *shader = instance()->newShader(vertexsource, pixelsource);
luax_pushtype(L, shader);
shader->release();
}
@@ -1372,11 +1372,20 @@ int w_validateShader(lua_State *L)
{
bool gles = luax_checkboolean(L, 1);
Shader::ShaderSource source;
w_getShaderSource(L, 2, gles, source);
std::string vertexsource, pixelsource;
w_getShaderSource(L, 2, gles, vertexsource, pixelsource);
bool success = true;
std::string err;
bool success = instance()->validateShader(gles, source, err);
try
{
success = instance()->validateShader(gles, vertexsource, pixelsource, err);
}
catch (love::Exception &e)
{
success = false;
err = e.what();
}
luax_pushboolean(L, success);
@@ -2007,23 +2016,21 @@ int w_setDefaultShaderCode(lua_State *L)
lua_getfield(L, -3, "videopixel");
lua_getfield(L, -4, "arraypixel");
Shader::ShaderSource code;
code.vertex = luax_checkstring(L, -4);
code.pixel = luax_checkstring(L, -3);
Shader::ShaderSource videocode;
videocode.vertex = luax_checkstring(L, -4);
videocode.pixel = luax_checkstring(L, -2);
Shader::ShaderSource arraycode;
arraycode.vertex = luax_checkstring(L, -4);
arraycode.pixel = luax_checkstring(L, -1);
std::string vertex = luax_checkstring(L, -4);
std::string pixel = luax_checkstring(L, -3);
std::string videopixel = luax_checkstring(L, -2);
std::string arraypixel = luax_checkstring(L, -1);
lua_pop(L, 5);
Graphics::defaultShaderCode[Shader::STANDARD_DEFAULT][lang][i] = code;
Graphics::defaultShaderCode[Shader::STANDARD_VIDEO][lang][i] = videocode;
Graphics::defaultShaderCode[Shader::STANDARD_ARRAY][lang][i] = arraycode;
Graphics::defaultShaderCode[Shader::STANDARD_DEFAULT][lang][i].source[ShaderStage::STAGE_VERTEX] = vertex;
Graphics::defaultShaderCode[Shader::STANDARD_DEFAULT][lang][i].source[ShaderStage::STAGE_PIXEL] = pixel;
Graphics::defaultShaderCode[Shader::STANDARD_VIDEO][lang][i].source[ShaderStage::STAGE_VERTEX] = vertex;
Graphics::defaultShaderCode[Shader::STANDARD_VIDEO][lang][i].source[ShaderStage::STAGE_PIXEL] = videopixel;
Graphics::defaultShaderCode[Shader::STANDARD_ARRAY][lang][i].source[ShaderStage::STAGE_VERTEX] = vertex;
Graphics::defaultShaderCode[Shader::STANDARD_ARRAY][lang][i].source[ShaderStage::STAGE_PIXEL] = arraypixel;
}
}