From d094d4163b71686e7d68a315a43112360a040806 Mon Sep 17 00:00:00 2001 From: coulsonwang Date: Thu, 3 Jan 2019 16:56:49 +0800 Subject: [PATCH 01/11] [Feature] update uniform location --- src/backend/Backend.h | 1 + src/backend/BindGroup.cpp | 10 ++++- src/backend/BindGroup.h | 9 ++-- src/backend/Device.h | 3 ++ src/backend/RenderPipelineDescriptor.h | 2 + src/backend/metal/CommandBufferMTL.h | 4 +- src/backend/metal/CommandBufferMTL.mm | 21 ++++------ src/backend/metal/DeviceMTL.h | 1 + src/backend/metal/DeviceMTL.mm | 6 +++ src/backend/metal/ProgramMTL.h | 21 ++++++++++ src/backend/metal/ProgramMTL.mm | 36 ++++++++++++++++ src/backend/metal/RenderPipelineMTL.h | 4 -- src/backend/metal/RenderPipelineMTL.mm | 7 ++-- src/backend/metal/ShaderModuleMTL.h | 5 ++- src/backend/metal/ShaderModuleMTL.mm | 2 +- src/backend/opengl/CommandBufferGL.cpp | 25 +++++++---- src/backend/opengl/CommandBufferGL.h | 6 +-- src/backend/opengl/DeviceGL.cpp | 6 +++ src/backend/opengl/DeviceGL.h | 1 + .../opengl/{Program.cpp => ProgramGL.cpp} | 35 ++++++++++++---- src/backend/opengl/{Program.h => ProgramGL.h} | 14 ++++--- src/backend/opengl/RenderPipelineGL.cpp | 8 ++-- src/backend/opengl/RenderPipelineGL.h | 6 +-- test/Test.xcodeproj/project.pbxproj | 28 ++++++++++--- test/tests/backend/BasicBackend.cpp | 7 ++-- test/tests/backend/BasicBackend.h | 1 + test/tests/backend/BlendingBackend.cpp | 41 +++++++++++-------- test/tests/backend/BunnyBackend.cpp | 17 +++++--- test/tests/backend/BunnyBackend.h | 4 ++ test/tests/backend/DepthTextureBackend.cpp | 41 +++++++++++++------ test/tests/backend/GuiProjectionBackend.cpp | 24 ++++++----- test/tests/backend/GuiProjectionBackend.h | 4 ++ test/tests/backend/MultiTexturesBackend.cpp | 9 ++-- test/tests/backend/MultiTexturesBackend.h | 3 ++ test/tests/backend/ParticleBackend.cpp | 12 +++--- test/tests/backend/ParticleBackend.h | 4 ++ test/tests/backend/PostProcessBackend.cpp | 40 ++++++++++++------ test/tests/backend/PostProcessBackend.h | 2 + test/tests/backend/StencilBackend.cpp | 27 +++++++----- test/tests/backend/StencilBackend.h | 3 ++ test/tests/backend/SubImageBackend.cpp | 10 +++-- test/tests/backend/SubImageBackend.h | 3 ++ test/tests/backend/Texture2DBackend.cpp | 15 ++++--- test/tests/backend/Texture2DBackend.h | 3 ++ 44 files changed, 376 insertions(+), 155 deletions(-) create mode 100644 src/backend/metal/ProgramMTL.h create mode 100644 src/backend/metal/ProgramMTL.mm rename src/backend/opengl/{Program.cpp => ProgramGL.cpp} (83%) rename src/backend/opengl/{Program.h => ProgramGL.h} (79%) diff --git a/src/backend/Backend.h b/src/backend/Backend.h index a8dbc4b..47458fd 100644 --- a/src/backend/Backend.h +++ b/src/backend/Backend.h @@ -13,3 +13,4 @@ #include "backend/Texture.h" #include "backend/DepthStencilState.h" #include "backend/BlendState.h" +#include "backend/Program.h" diff --git a/src/backend/BindGroup.cpp b/src/backend/BindGroup.cpp index 6857b7e..d17fd27 100644 --- a/src/backend/BindGroup.cpp +++ b/src/backend/BindGroup.cpp @@ -89,10 +89,16 @@ void BindGroup::setTextureArray(const std::string& name, const std::vector& indices, const std::vector textures); - void setUniform(const std::string& name, void* data, uint32_t size); + void setVertexUniform(int location, const std::string& name, void* data, uint32_t size); + void setFragmentUniform(int location, const std::string& name, void* data, uint32_t size); - inline const std::unordered_map& getUniformInfos() const { return _uniformInfos; } + inline const std::unordered_map& getVertexUniformInfos() const { return _vertexUniformInfos; } + inline const std::unordered_map& getFragUniformInfos() const { return _fragUniformInfos; } inline const std::unordered_map& getTextureInfos() const { return _textureInfos; } private: - std::unordered_map _uniformInfos; + std::unordered_map _vertexUniformInfos; + std::unordered_map _fragUniformInfos; std::unordered_map _textureInfos; }; diff --git a/src/backend/Device.h b/src/backend/Device.h index a223863..7789e91 100644 --- a/src/backend/Device.h +++ b/src/backend/Device.h @@ -19,6 +19,7 @@ class Buffer; class ShaderModule; class RenderPipeline; class RenderPass; +class Program; class Device : public cocos2d::Ref { @@ -41,6 +42,8 @@ class Device : public cocos2d::Ref virtual BlendState* createBlendState(const BlendDescriptor& descriptor) = 0; // Create a render pipeline, not auto released. virtual RenderPipeline* newRenderPipeline(const RenderPipelineDescriptor& descriptor) = 0; + virtual Program* createProgram(ShaderModule* vs, ShaderModule* fs) = 0; + private: static Device* _instance; diff --git a/src/backend/RenderPipelineDescriptor.h b/src/backend/RenderPipelineDescriptor.h index c5a60cd..15921e6 100644 --- a/src/backend/RenderPipelineDescriptor.h +++ b/src/backend/RenderPipelineDescriptor.h @@ -11,9 +11,11 @@ CC_BACKEND_BEGIN class ShaderModule; class DepthStencilState; class BlendState; +class Program; struct RenderPipelineDescriptor { + Program* program = nullptr; ShaderModule* vertexShaderModule = nullptr; ShaderModule* fragmentShaderModule = nullptr; DepthStencilState* depthStencilState = nullptr; diff --git a/src/backend/metal/CommandBufferMTL.h b/src/backend/metal/CommandBufferMTL.h index 309488c..58125f2 100644 --- a/src/backend/metal/CommandBufferMTL.h +++ b/src/backend/metal/CommandBufferMTL.h @@ -2,6 +2,8 @@ #include "../CommandBuffer.h" #include "DeviceMTL.h" +#include "../BindGroup.h" +#include CC_BACKEND_BEGIN @@ -31,7 +33,7 @@ class CommandBufferMTL : public CommandBuffer void setTextures() const; void doSetTextures(const std::vector& textures, bool isVertex) const; void setUniformBuffer() const; - uint32_t fillUniformBuffer(uint8_t* buffer, const std::vector& uniforms) const; + uint32_t fillUniformBuffer(uint8_t* buffer, const std::unordered_map& unifornInfo) const; void afterDraw(); id _mtlCommandBuffer = nil; diff --git a/src/backend/metal/CommandBufferMTL.mm b/src/backend/metal/CommandBufferMTL.mm index 385246a..070a2af 100644 --- a/src/backend/metal/CommandBufferMTL.mm +++ b/src/backend/metal/CommandBufferMTL.mm @@ -319,17 +319,19 @@ MTLCullMode toMTLCullMode(CullMode mode) { // Uniform buffer is bound to index 1. const auto& vertexUniformBuffer = _renderPipelineMTL->getVertexUniformBuffer(); + const auto& vertexUniformInfo = _bindGroup->getVertexUniformInfos(); if (vertexUniformBuffer) { - uint32_t size = fillUniformBuffer(vertexUniformBuffer.get(), _renderPipelineMTL->getVertexUniforms()); + uint32_t size = fillUniformBuffer(vertexUniformBuffer.get(), vertexUniformInfo); [_mtlRenderEncoder setVertexBytes:vertexUniformBuffer.get() length:size atIndex:1]; } const auto& fragUniformBuffer = _renderPipelineMTL->getFragmentUniformBuffer(); + const auto& fragUniformInfo = _bindGroup->getFragUniformInfos(); if (fragUniformBuffer) { - uint32_t size = fillUniformBuffer(fragUniformBuffer.get(), _renderPipelineMTL->getFragmentUniforms()); + uint32_t size = fillUniformBuffer(fragUniformBuffer.get(), fragUniformInfo); [_mtlRenderEncoder setFragmentBytes:fragUniformBuffer.get() length:size atIndex:1]; @@ -337,19 +339,14 @@ MTLCullMode toMTLCullMode(CullMode mode) } } -uint32_t CommandBufferMTL::fillUniformBuffer(uint8_t* buffer, const std::vector& uniforms) const +uint32_t CommandBufferMTL::fillUniformBuffer(uint8_t* buffer, const std::unordered_map& unifornInfo) const { - const auto& bindUniformInfos = _bindGroup->getUniformInfos(); uint32_t offset = 0; - for (const auto& uniform : uniforms) + for(const auto& iter : unifornInfo) { - auto iter = bindUniformInfos.find(uniform); - if (bindUniformInfos.end() != iter) - { - const auto& bindUniformInfo = iter->second; - memcpy(buffer + offset, bindUniformInfo.data, bindUniformInfo.size); - offset += bindUniformInfo.size; - } + const auto& bindUniformInfo = iter.second; + memcpy(buffer + iter.first, bindUniformInfo.data, bindUniformInfo.size); + offset += bindUniformInfo.size; } return offset; } diff --git a/src/backend/metal/DeviceMTL.h b/src/backend/metal/DeviceMTL.h index 0833a41..8d9ff05 100644 --- a/src/backend/metal/DeviceMTL.h +++ b/src/backend/metal/DeviceMTL.h @@ -26,6 +26,7 @@ class DeviceMTL : public Device virtual DepthStencilState* createDepthStencilState(const DepthStencilDescriptor& descriptor) override; virtual BlendState* createBlendState(const BlendDescriptor& descriptor) override; virtual RenderPipeline* newRenderPipeline(const RenderPipelineDescriptor& descriptor) override; + virtual Program* createProgram(ShaderModule* vs, ShaderModule* fs) override; inline id getMTLDevice() const { return _mtlDevice; } inline id getMTLCommandQueue() const { return _mtlCommandQueue; } diff --git a/src/backend/metal/DeviceMTL.mm b/src/backend/metal/DeviceMTL.mm index 7827c75..53519c5 100644 --- a/src/backend/metal/DeviceMTL.mm +++ b/src/backend/metal/DeviceMTL.mm @@ -7,6 +7,7 @@ #include "TextureMTL.h" #include "BlendStateMTL.h" #include "Utils.h" +#include "ProgramMTL.h" CC_BACKEND_BEGIN @@ -91,4 +92,9 @@ return new (std::nothrow) RenderPipelineMTL(_mtlDevice, descriptor); } +Program* DeviceMTL::createProgram(ShaderModule* vs, ShaderModule* fs) +{ + return new (std::nothrow) ProgramMTL(vs, fs); +} + CC_BACKEND_END diff --git a/src/backend/metal/ProgramMTL.h b/src/backend/metal/ProgramMTL.h new file mode 100644 index 0000000..4eda68f --- /dev/null +++ b/src/backend/metal/ProgramMTL.h @@ -0,0 +1,21 @@ +#pragma once + +#include "../Program.h" + +CC_BACKEND_BEGIN + +class ShaderModuleMTL; + +class ProgramMTL : public Program +{ +public: + ProgramMTL(ShaderModule* vs, ShaderModule* fs); + virtual ~ProgramMTL(); + virtual int getUniformLocation(const std::string& uniform) override; + +private: + ShaderModuleMTL* _vertexShader = nullptr; + ShaderModuleMTL* _fragmentShader = nullptr; +}; + +CC_BACKEND_END diff --git a/src/backend/metal/ProgramMTL.mm b/src/backend/metal/ProgramMTL.mm new file mode 100644 index 0000000..ed34434 --- /dev/null +++ b/src/backend/metal/ProgramMTL.mm @@ -0,0 +1,36 @@ +#include "ProgramMTL.h" +#include "ShaderModuleMTL.h" + +CC_BACKEND_BEGIN + +ProgramMTL::ProgramMTL(ShaderModule* vs, ShaderModule* fs) +: Program(vs, fs) +, _vertexShader(static_cast(vs)) +, _fragmentShader(static_cast(fs)) +{ + CC_SAFE_RETAIN(_vertexShader); + CC_SAFE_RETAIN(_fragmentShader); +} + +ProgramMTL::~ProgramMTL() +{ + CC_SAFE_RELEASE(_vertexShader); + CC_SAFE_RELEASE(_fragmentShader); +} + +int ProgramMTL::getUniformLocation(const std::string& uniform) +{ + const auto& vsUniforms = _vertexShader->getUniforms(); + const auto& fsUniforms = _fragmentShader->getUniforms(); + const auto& vsIter = vsUniforms.find(uniform); + if(vsIter != vsUniforms.end()) + return vsIter->second; + + const auto& fsIter = fsUniforms.find(uniform); + if(fsIter != fsUniforms.end()) + return fsIter->second; + + return -1; +} + +CC_BACKEND_END diff --git a/src/backend/metal/RenderPipelineMTL.h b/src/backend/metal/RenderPipelineMTL.h index ba97649..67939d3 100644 --- a/src/backend/metal/RenderPipelineMTL.h +++ b/src/backend/metal/RenderPipelineMTL.h @@ -21,8 +21,6 @@ class RenderPipelineMTL : public RenderPipeline inline const std::shared_ptr& getVertexUniformBuffer() const { return _vertexUniformBuffer; } inline const std::shared_ptr& getFragmentUniformBuffer() const { return _fragementUniformBuffer; } - inline const std::vector& getVertexUniforms() const { return _vertexUniforms; } - inline const std::vector& getFragmentUniforms() const { return _fragmentUniforms; } inline const std::vector& getVertexTextures() const { return _vertexTextures; } inline const std::vector& getFragmentTextures() const { return _fragmentTextures; } @@ -37,11 +35,9 @@ class RenderPipelineMTL : public RenderPipeline id _mtlDevice = nil; std::shared_ptr _vertexUniformBuffer = nullptr; - std::vector _vertexUniforms; std::vector _vertexTextures; std::shared_ptr _fragementUniformBuffer = nullptr; - std::vector _fragmentUniforms; std::vector _fragmentTextures; MTLRenderPipelineDescriptor* _mtlRenderPipelineDescriptor = nil; diff --git a/src/backend/metal/RenderPipelineMTL.mm b/src/backend/metal/RenderPipelineMTL.mm index 2508e60..e6240c2 100644 --- a/src/backend/metal/RenderPipelineMTL.mm +++ b/src/backend/metal/RenderPipelineMTL.mm @@ -3,6 +3,7 @@ #include "ShaderModuleMTL.h" #include "DepthStencilStateMTL.h" #include "Utils.h" +#include "../Program.h" CC_BACKEND_BEGIN @@ -134,15 +135,13 @@ MTLVertexFormat toMTLVertexFormat(VertexFormat vertexFormat) void RenderPipelineMTL::setShaderModules(const RenderPipelineDescriptor& descriptor) { - auto vertexShaderModule = static_cast(descriptor.vertexShaderModule); + auto vertexShaderModule = static_cast(descriptor.program->getVertexShader()); _mtlRenderPipelineDescriptor.vertexFunction = vertexShaderModule->getMTLFunction(); - _vertexUniforms = vertexShaderModule->getUniforms(); _vertexUniformBuffer = vertexShaderModule->getUniformBuffer(); _vertexTextures = vertexShaderModule->getTextures(); - auto fragShaderModule = static_cast(descriptor.fragmentShaderModule); + auto fragShaderModule = static_cast(descriptor.program->getFragmentShader()); _mtlRenderPipelineDescriptor.fragmentFunction = fragShaderModule->getMTLFunction(); - _fragmentUniforms = fragShaderModule->getUniforms(); _fragementUniformBuffer = fragShaderModule->getUniformBuffer(); _fragmentTextures = fragShaderModule->getTextures(); } diff --git a/src/backend/metal/ShaderModuleMTL.h b/src/backend/metal/ShaderModuleMTL.h index de123c8..97b4bd1 100644 --- a/src/backend/metal/ShaderModuleMTL.h +++ b/src/backend/metal/ShaderModuleMTL.h @@ -5,6 +5,7 @@ #include #include #import +#include struct glslopt_shader; @@ -18,7 +19,7 @@ class ShaderModuleMTL : public ShaderModule inline id getMTLFunction() const { return _mtlFunction; } inline const std::shared_ptr& getUniformBuffer() const { return _uniformBuffer; } - inline const std::vector& getUniforms() const { return _uniforms; } + inline const std::unordered_map& getUniforms() const { return _uniforms; } inline const std::vector& getTextures() const { return _textures; } private: @@ -28,7 +29,7 @@ class ShaderModuleMTL : public ShaderModule id _mtlFunction = nil; std::shared_ptr _uniformBuffer = nullptr; - std::vector _uniforms; + std::unordered_map _uniforms; // Texture index is the same as vector index. std::vector _textures; diff --git a/src/backend/metal/ShaderModuleMTL.mm b/src/backend/metal/ShaderModuleMTL.mm index 497b1bd..8a90637 100644 --- a/src/backend/metal/ShaderModuleMTL.mm +++ b/src/backend/metal/ShaderModuleMTL.mm @@ -84,7 +84,7 @@ glslopt_precision parPrec; int parVecSize, parMatSize, parArrSize, location; glslopt_shader_get_uniform_desc(shader, i, &parName, &parType, &parPrec, &parVecSize, &parMatSize, &parArrSize, &location); - _uniforms.push_back(parName); + _uniforms[parName] = location; } } diff --git a/src/backend/opengl/CommandBufferGL.cpp b/src/backend/opengl/CommandBufferGL.cpp index ee54543..a9a553c 100644 --- a/src/backend/opengl/CommandBufferGL.cpp +++ b/src/backend/opengl/CommandBufferGL.cpp @@ -4,7 +4,7 @@ #include "TextureGL.h" #include "DepthStencilStateGL.h" #include "../BindGroup.h" -#include "Program.h" +#include "ProgramGL.h" #include "BlendStateGL.h" #include "ccMacros.h" @@ -323,7 +323,7 @@ void CommandBufferGL::prepareDrawing() const } } -void CommandBufferGL::bindVertexBuffer(Program *program) const +void CommandBufferGL::bindVertexBuffer(ProgramGL *program) const { // Bind vertex buffers and set the attributes. int i = 0; @@ -351,24 +351,35 @@ void CommandBufferGL::bindVertexBuffer(Program *program) const } } -void CommandBufferGL::setUniforms(Program* program) const +void CommandBufferGL::setUniforms(ProgramGL* program) const { if (_bindGroup) { const auto& texutreInfos = _bindGroup->getTextureInfos(); - const auto& bindUniformInfos = _bindGroup->getUniformInfos(); + const auto& vsUniformInfos = _bindGroup->getVertexUniformInfos(); + const auto& fsUniformInfos = _bindGroup->getFragUniformInfos(); const auto& activeUniformInfos = program->getUniformInfos(); for (const auto& activeUinform : activeUniformInfos) { // Set normal uniforms. - const auto& bindUniformInfo = bindUniformInfos.find(activeUinform.name); - if (bindUniformInfos.end() != bindUniformInfo) + const auto& vsUniformInfo = vsUniformInfos.find(activeUinform.location); + if (vsUniformInfos.end() != vsUniformInfo) { setUniform(activeUinform.isArray, activeUinform.location, activeUinform.size, activeUinform.type, - (*bindUniformInfo).second.data); + (*vsUniformInfo).second.data); + } + + const auto& fsUniformInfo = fsUniformInfos.find(activeUinform.location); + if (fsUniformInfos.end() != fsUniformInfo) + { + setUniform(activeUinform.isArray, + activeUinform.location, + activeUinform.size, + activeUinform.type, + (*fsUniformInfo).second.data); } // Bind textures. diff --git a/src/backend/opengl/CommandBufferGL.h b/src/backend/opengl/CommandBufferGL.h index b855d0e..0071d61 100644 --- a/src/backend/opengl/CommandBufferGL.h +++ b/src/backend/opengl/CommandBufferGL.h @@ -11,7 +11,7 @@ CC_BACKEND_BEGIN class BufferGL; class RenderPipelineGL; -class Program; +class ProgramGL; class CommandBufferGL : public CommandBuffer { @@ -42,8 +42,8 @@ class CommandBufferGL : public CommandBuffer }; void prepareDrawing() const; - void bindVertexBuffer(Program* program) const; - void setUniforms(Program* program) const; + void bindVertexBuffer(ProgramGL* program) const; + void setUniforms(ProgramGL* program) const; void setUniform(bool isArray, GLuint location, uint32_t size, GLenum uniformType, void* data) const; void cleanResources(); void applyRenderPassDescriptor(const RenderPassDescriptor& descirptor); diff --git a/src/backend/opengl/DeviceGL.cpp b/src/backend/opengl/DeviceGL.cpp index 1b7848c..865c457 100644 --- a/src/backend/opengl/DeviceGL.cpp +++ b/src/backend/opengl/DeviceGL.cpp @@ -6,6 +6,7 @@ #include "TextureGL.h" #include "DepthStencilStateGL.h" #include "BlendStateGL.h" +#include "ProgramGL.h" CC_BACKEND_BEGIN @@ -64,4 +65,9 @@ RenderPipeline* DeviceGL::newRenderPipeline(const RenderPipelineDescriptor& desc return new (std::nothrow) RenderPipelineGL(descriptor); } +Program* DeviceGL::createProgram(ShaderModule* vs, ShaderModule* fs) +{ + return new (std::nothrow) ProgramGL(vs, fs); +} + CC_BACKEND_END diff --git a/src/backend/opengl/DeviceGL.h b/src/backend/opengl/DeviceGL.h index 1dcf45e..568332e 100644 --- a/src/backend/opengl/DeviceGL.h +++ b/src/backend/opengl/DeviceGL.h @@ -12,6 +12,7 @@ class DeviceGL : public Device virtual DepthStencilState* createDepthStencilState(const DepthStencilDescriptor& descriptor) override; virtual BlendState* createBlendState(const BlendDescriptor& descriptor) override; virtual RenderPipeline* newRenderPipeline(const RenderPipelineDescriptor& descriptor) override; + virtual Program* createProgram(ShaderModule* vs, ShaderModule* fs) override; }; CC_BACKEND_END diff --git a/src/backend/opengl/Program.cpp b/src/backend/opengl/ProgramGL.cpp similarity index 83% rename from src/backend/opengl/Program.cpp rename to src/backend/opengl/ProgramGL.cpp index 8eb8d4b..0f51e2d 100644 --- a/src/backend/opengl/Program.cpp +++ b/src/backend/opengl/ProgramGL.cpp @@ -1,5 +1,6 @@ -#include "Program.h" +#include "ProgramGL.h" #include "ShaderModuleGL.h" +#include "ccMacros.h" CC_BACKEND_BEGIN @@ -56,8 +57,21 @@ namespace } } -Program::Program(const RenderPipelineDescriptor& descriptor) -: _vertexShaderModule(static_cast(descriptor.vertexShaderModule)) +ProgramGL::ProgramGL(ShaderModule* vs, ShaderModule* fs) +:Program(vs, fs) +{ + _vertexShaderModule = (static_cast(vs)); + _fragmentShaderModule = (static_cast(fs)); + CC_SAFE_RETAIN(_vertexShaderModule); + CC_SAFE_RETAIN(_fragmentShaderModule); + + compileProgram(); + computeUniformInfos(); +} + +ProgramGL::ProgramGL(const RenderPipelineDescriptor& descriptor) +:Program(descriptor.vertexShaderModule, descriptor.fragmentShaderModule) +, _vertexShaderModule(static_cast(descriptor.vertexShaderModule)) , _fragmentShaderModule(static_cast(descriptor.fragmentShaderModule)) { assert(_vertexShaderModule != nullptr && _fragmentShaderModule != nullptr); @@ -70,7 +84,7 @@ Program::Program(const RenderPipelineDescriptor& descriptor) computeUniformInfos(); } -Program::~Program() +ProgramGL::~ProgramGL() { CC_SAFE_RELEASE(_vertexShaderModule); CC_SAFE_RELEASE(_fragmentShaderModule); @@ -78,7 +92,7 @@ Program::~Program() glDeleteProgram(_program); } -void Program::compileProgram() +void ProgramGL::compileProgram() { if (_vertexShaderModule == nullptr || _fragmentShaderModule == nullptr) return; @@ -108,7 +122,7 @@ void Program::compileProgram() } } -void Program::computeAttributeInfos(const RenderPipelineDescriptor& descriptor) +void ProgramGL::computeAttributeInfos(const RenderPipelineDescriptor& descriptor) { const auto& vertexLayouts = descriptor.vertexLayouts; for (const auto& vertexLayout : vertexLayouts) @@ -138,7 +152,7 @@ void Program::computeAttributeInfos(const RenderPipelineDescriptor& descriptor) } } -bool Program::getAttributeLocation(const std::string& attributeName, uint32_t& location) +bool ProgramGL::getAttributeLocation(const std::string& attributeName, uint32_t& location) { GLint loc = glGetAttribLocation(_program, attributeName.c_str()); if (-1 == loc) @@ -151,7 +165,7 @@ bool Program::getAttributeLocation(const std::string& attributeName, uint32_t& l return true; } -void Program::computeUniformInfos() +void ProgramGL::computeUniformInfos() { if (!_program) return; @@ -188,4 +202,9 @@ void Program::computeUniformInfos() free(uniformName); } +int ProgramGL::getUniformLocation(const std::string& uniform) +{ + return glGetUniformLocation(_program, uniform.c_str()); +} + CC_BACKEND_END diff --git a/src/backend/opengl/Program.h b/src/backend/opengl/ProgramGL.h similarity index 79% rename from src/backend/opengl/Program.h rename to src/backend/opengl/ProgramGL.h index e44a14c..1fb58a7 100644 --- a/src/backend/opengl/Program.h +++ b/src/backend/opengl/ProgramGL.h @@ -5,6 +5,7 @@ #include "../RenderPipelineDescriptor.h" #include "base/CCRef.h" #include "platform/CCGL.h" +#include "../Program.h" #include @@ -31,21 +32,24 @@ struct UniformInfo }; -class Program : public cocos2d::Ref +class ProgramGL : public Program { public: typedef std::vector VertexAttributeArray; - Program(const RenderPipelineDescriptor& descriptor); - ~Program(); + ProgramGL(ShaderModule* vs, ShaderModule* fs); + + ProgramGL(const RenderPipelineDescriptor& descriptor); + ~ProgramGL(); inline const std::vector& getAttributeInfos() const { return _attributeInfos; } inline const std::vector& getUniformInfos() const { return _uniformInfos; } inline GLuint getHandler() const { return _program; } - + void computeAttributeInfos(const RenderPipelineDescriptor& descriptor); + virtual int getUniformLocation(const std::string& uniform) override; private: void compileProgram(); - void computeAttributeInfos(const RenderPipelineDescriptor& descriptor); +// void computeAttributeInfos(const RenderPipelineDescriptor& descriptor); bool getAttributeLocation(const std::string& attributeName, uint32_t& location); void computeUniformInfos(); diff --git a/src/backend/opengl/RenderPipelineGL.cpp b/src/backend/opengl/RenderPipelineGL.cpp index 6155f8c..1804fbe 100644 --- a/src/backend/opengl/RenderPipelineGL.cpp +++ b/src/backend/opengl/RenderPipelineGL.cpp @@ -1,7 +1,7 @@ #include "RenderPipelineGL.h" #include "ShaderModuleGL.h" #include "DepthStencilStateGL.h" -#include "Program.h" +#include "ProgramGL.h" #include "BlendStateGL.h" #include @@ -10,7 +10,9 @@ CC_BACKEND_BEGIN RenderPipelineGL::RenderPipelineGL(const RenderPipelineDescriptor& descriptor) { - _program = new Program(descriptor); + _programGL = static_cast(descriptor.program); + _programGL->computeAttributeInfos(descriptor); + CC_SAFE_RETAIN(_programGL); const auto& depthStencilState = descriptor.depthStencilState; CC_SAFE_RETAIN(depthStencilState); @@ -23,7 +25,7 @@ RenderPipelineGL::RenderPipelineGL(const RenderPipelineDescriptor& descriptor) RenderPipelineGL::~RenderPipelineGL() { - CC_SAFE_RELEASE(_program); + CC_SAFE_RELEASE(_programGL); CC_SAFE_RELEASE(_depthStencilState); CC_SAFE_RELEASE(_blendState); } diff --git a/src/backend/opengl/RenderPipelineGL.h b/src/backend/opengl/RenderPipelineGL.h index cc94ef5..eff77e8 100644 --- a/src/backend/opengl/RenderPipelineGL.h +++ b/src/backend/opengl/RenderPipelineGL.h @@ -10,7 +10,7 @@ CC_BACKEND_BEGIN class DepthStencilStateGL; -class Program; +class ProgramGL; class BlendStateGL; class RenderPipelineGL : public RenderPipeline @@ -19,12 +19,12 @@ class RenderPipelineGL : public RenderPipeline RenderPipelineGL(const RenderPipelineDescriptor& descriptor); ~RenderPipelineGL(); - inline Program* getProgram() const { return _program; } + inline ProgramGL* getProgram() const { return _programGL; } inline DepthStencilStateGL* getDepthStencilState() const { return _depthStencilState; } inline BlendStateGL* getBlendState() const { return _blendState; } private: - Program* _program = nullptr; + ProgramGL* _programGL = nullptr; DepthStencilStateGL* _depthStencilState = nullptr; BlendStateGL* _blendState = nullptr; }; diff --git a/test/Test.xcodeproj/project.pbxproj b/test/Test.xcodeproj/project.pbxproj index 786481c..45921e6 100644 --- a/test/Test.xcodeproj/project.pbxproj +++ b/test/Test.xcodeproj/project.pbxproj @@ -133,7 +133,7 @@ 4603743F2147742800DC9ED4 /* DepthStencilState.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4603743C2147742800DC9ED4 /* DepthStencilState.cpp */; }; 4603744321479AFC00DC9ED4 /* DepthStencilStateGL.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4603744021479AFC00DC9ED4 /* DepthStencilStateGL.cpp */; }; 460374472147B88400DC9ED4 /* BunnyBackend.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 460374442147B88300DC9ED4 /* BunnyBackend.cpp */; }; - 4603744C2148BA9900DC9ED4 /* Program.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 460374492148BA9900DC9ED4 /* Program.cpp */; }; + 4603744C2148BA9900DC9ED4 /* ProgramGL.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 460374492148BA9900DC9ED4 /* ProgramGL.cpp */; }; 460374502148F6BE00DC9ED4 /* DepthTextureBackend.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4603744D2148F6BE00DC9ED4 /* DepthTextureBackend.cpp */; }; 46037576214F44CD00DC9ED4 /* BlendingBackend.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 46037573214F44CC00DC9ED4 /* BlendingBackend.cpp */; }; 4603757A214FA29500DC9ED4 /* BlendState.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 46037577214FA29500DC9ED4 /* BlendState.cpp */; }; @@ -192,6 +192,10 @@ 46F9B75321B67334009DF858 /* StencilBackend.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 46233BEB2176C978000F1F21 /* StencilBackend.cpp */; }; ED3B4C43217E15C000D982A0 /* GuiProjectionBackend.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED3B4C3E217E15BF00D982A0 /* GuiProjectionBackend.cpp */; }; ED3B4C45217E15C000D982A0 /* ParticleBackend.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED3B4C41217E15C000D982A0 /* ParticleBackend.cpp */; }; + EDC86F4C21DCBAE10086A0CA /* Program.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EDC86F4B21DCBAE10086A0CA /* Program.cpp */; }; + EDC86F4D21DCBAE10086A0CA /* Program.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EDC86F4B21DCBAE10086A0CA /* Program.cpp */; }; + EDC86F5321DDA3F00086A0CA /* ProgramMTL.mm in Sources */ = {isa = PBXBuildFile; fileRef = EDC86F5221DDA3F00086A0CA /* ProgramMTL.mm */; }; + EDC86F5421DDA3F00086A0CA /* ProgramMTL.mm in Sources */ = {isa = PBXBuildFile; fileRef = EDC86F5221DDA3F00086A0CA /* ProgramMTL.mm */; }; /* End PBXBuildFile section */ /* Begin PBXCopyFilesBuildPhase section */ @@ -390,8 +394,8 @@ 460374442147B88300DC9ED4 /* BunnyBackend.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = BunnyBackend.cpp; sourceTree = ""; }; 460374452147B88400DC9ED4 /* BunnyBackend.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BunnyBackend.h; sourceTree = ""; }; 460374482147BBFB00DC9ED4 /* BunnyData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BunnyData.h; sourceTree = ""; }; - 460374492148BA9900DC9ED4 /* Program.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Program.cpp; sourceTree = ""; }; - 4603744A2148BA9900DC9ED4 /* Program.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Program.h; sourceTree = ""; }; + 460374492148BA9900DC9ED4 /* ProgramGL.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = ProgramGL.cpp; sourceTree = ""; }; + 4603744A2148BA9900DC9ED4 /* ProgramGL.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ProgramGL.h; sourceTree = ""; }; 4603744D2148F6BE00DC9ED4 /* DepthTextureBackend.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DepthTextureBackend.cpp; sourceTree = ""; }; 4603744E2148F6BE00DC9ED4 /* DepthTextureBackend.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DepthTextureBackend.h; sourceTree = ""; }; 460374512148F78600DC9ED4 /* Backend.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Backend.h; sourceTree = ""; }; @@ -473,6 +477,10 @@ ED3B4C3F217E15BF00D982A0 /* ParticleBackend.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ParticleBackend.h; sourceTree = ""; }; ED3B4C40217E15C000D982A0 /* GuiProjectionBackend.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GuiProjectionBackend.h; sourceTree = ""; }; ED3B4C41217E15C000D982A0 /* ParticleBackend.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ParticleBackend.cpp; sourceTree = ""; }; + EDC86F4A21DCBAE10086A0CA /* Program.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Program.h; sourceTree = ""; }; + EDC86F4B21DCBAE10086A0CA /* Program.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Program.cpp; sourceTree = ""; }; + EDC86F5121DDA3CE0086A0CA /* ProgramMTL.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ProgramMTL.h; sourceTree = ""; }; + EDC86F5221DDA3F00086A0CA /* ProgramMTL.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = ProgramMTL.mm; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -828,6 +836,8 @@ 460373AF212FA9EB00DC9ED4 /* backend */ = { isa = PBXGroup; children = ( + EDC86F4B21DCBAE10086A0CA /* Program.cpp */, + EDC86F4A21DCBAE10086A0CA /* Program.h */, 460374512148F78600DC9ED4 /* Backend.h */, 460373F9213932AE00DC9ED4 /* BindGroup.cpp */, 460373FA213932AE00DC9ED4 /* BindGroup.h */, @@ -874,8 +884,8 @@ 46037406213FBEFE00DC9ED4 /* TextureGL.h */, 4603744021479AFC00DC9ED4 /* DepthStencilStateGL.cpp */, 4603744121479AFC00DC9ED4 /* DepthStencilStateGL.h */, - 460374492148BA9900DC9ED4 /* Program.cpp */, - 4603744A2148BA9900DC9ED4 /* Program.h */, + 460374492148BA9900DC9ED4 /* ProgramGL.cpp */, + 4603744A2148BA9900DC9ED4 /* ProgramGL.h */, 4603757B214FA82D00DC9ED4 /* BlendStateGL.cpp */, 4603757C214FA82D00DC9ED4 /* BlendStateGL.h */, ); @@ -975,6 +985,8 @@ 466BA3B5216C79C7006C15A5 /* DepthStencilStateMTL.h */, 46486F2F217077020078BE0E /* Utils.mm */, 46486F30217077020078BE0E /* Utils.h */, + EDC86F5121DDA3CE0086A0CA /* ProgramMTL.h */, + EDC86F5221DDA3F00086A0CA /* ProgramMTL.mm */, ); path = metal; sourceTree = ""; @@ -1233,7 +1245,7 @@ 461DD0E72153845000A8E43F /* Device.cpp in Sources */, 461F45AF217719F700D83671 /* PostProcessBackend.cpp in Sources */, 1A255E3820034B0D00069420 /* CCFileUtils.cpp in Sources */, - 4603744C2148BA9900DC9ED4 /* Program.cpp in Sources */, + 4603744C2148BA9900DC9ED4 /* ProgramGL.cpp in Sources */, 46037413214247A700DC9ED4 /* BindGroup.cpp in Sources */, 4603757E214FA82D00DC9ED4 /* BlendStateGL.cpp in Sources */, 461F45B32178570700D83671 /* SubImageBackend.cpp in Sources */, @@ -1253,7 +1265,9 @@ 46037422214247F000DC9ED4 /* BasicBackend.cpp in Sources */, 4603744321479AFC00DC9ED4 /* DepthStencilStateGL.cpp in Sources */, 1A255E5620034B0D00069420 /* Vec4.cpp in Sources */, + EDC86F5421DDA3F00086A0CA /* ProgramMTL.mm in Sources */, 1A255E6420034B0D00069420 /* ZipUtils.cpp in Sources */, + EDC86F4D21DCBAE10086A0CA /* Program.cpp in Sources */, 4603741C214247D500DC9ED4 /* RenderPipelineGL.cpp in Sources */, 46037576214F44CD00DC9ED4 /* BlendingBackend.cpp in Sources */, 1A255E7220034B0D00069420 /* CCConsole.cpp in Sources */, @@ -1314,6 +1328,7 @@ 1A255E6120034B0D00069420 /* ccRandom.cpp in Sources */, 1A255E5320034B0D00069420 /* CCVertex.cpp in Sources */, 1A255E2720034B0D00069420 /* CCSAXParser.cpp in Sources */, + EDC86F4C21DCBAE10086A0CA /* Program.cpp in Sources */, 461DD0D821536FC900A8E43F /* main.mm in Sources */, 46F9B74F21B65E70009DF858 /* DepthTextureBackend.cpp in Sources */, 1A255E2920034B0D00069420 /* CCImage.cpp in Sources */, @@ -1339,6 +1354,7 @@ 1A255E4720034B0D00069420 /* MathUtil.cpp in Sources */, 46E21B4021B8F8E400430A43 /* GuiProjectionBackend.cpp in Sources */, 1A255E4D20034B0D00069420 /* Mat4.cpp in Sources */, + EDC86F5321DDA3F00086A0CA /* ProgramMTL.mm in Sources */, 461DD0ED21538B0100A8E43F /* CommandBuffer.cpp in Sources */, 1A255E5D20034B0D00069420 /* CCAffineTransform.cpp in Sources */, 46E21B3D21B8F4BC00430A43 /* Texture2DBackend.cpp in Sources */, diff --git a/test/tests/backend/BasicBackend.cpp b/test/tests/backend/BasicBackend.cpp index db307d2..dc285ce 100644 --- a/test/tests/backend/BasicBackend.cpp +++ b/test/tests/backend/BasicBackend.cpp @@ -31,6 +31,7 @@ #include "backend/RenderPassDescriptor.h" #include "backend/ShaderModule.h" #include "backend/VertexLayout.h" +#include "backend/Program.h" std::string test_unrollLoops(const std::string& text); @@ -66,8 +67,8 @@ BasicBackend::BasicBackend() auto vs = device->createShaderModule(cocos2d::backend::ShaderStage::VERTEX, vert); auto fs = device->createShaderModule(cocos2d::backend::ShaderStage::FRAGMENT, frag); cocos2d::backend::RenderPipelineDescriptor renderPipelineDescriptor; - renderPipelineDescriptor.vertexShaderModule = vs; - renderPipelineDescriptor.fragmentShaderModule = fs; + renderPipelineDescriptor.program = device->createProgram(vs, fs); + _colorLocation = renderPipelineDescriptor.program->getUniformLocation("color"); backend::VertexLayout vertexLayout; vertexLayout.setAtrribute("a_position", 0, cocos2d::backend::VertexFormat::FLOAT_R32G32, 0); @@ -103,7 +104,7 @@ void BasicBackend::tick(float dt) _commandBuffer->setViewport(0, 0, utils::WINDOW_WIDTH, utils::WINDOW_HEIGHT); _commandBuffer->setRenderPipeline(_renderPipeline); _commandBuffer->setVertexBuffer(0, _vertexBuffer); - _bindGroup.setUniform("color", color, sizeof(color)); + _bindGroup.setFragmentUniform(_colorLocation, "color", color, sizeof(color)); _commandBuffer->setBindGroup(&_bindGroup); _commandBuffer->drawArrays(cocos2d::backend::PrimitiveType::TRIANGLE, 0, 3); _commandBuffer->endRenderPass(); diff --git a/test/tests/backend/BasicBackend.h b/test/tests/backend/BasicBackend.h index 4ca6532..54d2060 100644 --- a/test/tests/backend/BasicBackend.h +++ b/test/tests/backend/BasicBackend.h @@ -45,5 +45,6 @@ class BasicBackend : public TestBaseI cocos2d::backend::RenderPipeline* _renderPipeline = nullptr; cocos2d::backend::BindGroup _bindGroup; cocos2d::backend::RenderPassDescriptor _renderPassDescriptor; + int _colorLocation = -1; float _time; }; diff --git a/test/tests/backend/BlendingBackend.cpp b/test/tests/backend/BlendingBackend.cpp index c519360..a29dd99 100644 --- a/test/tests/backend/BlendingBackend.cpp +++ b/test/tests/backend/BlendingBackend.cpp @@ -68,8 +68,9 @@ namespace backend::RenderPipelineDescriptor renderPipelineDescriptor; auto vs = device->createShaderModule(cocos2d::backend::ShaderStage::VERTEX, vert); auto fs = device->createShaderModule(cocos2d::backend::ShaderStage::FRAGMENT, frag); - renderPipelineDescriptor.vertexShaderModule = vs; - renderPipelineDescriptor.fragmentShaderModule = fs; + renderPipelineDescriptor.program = device->createProgram(vs, fs); + _modelLocation = renderPipelineDescriptor.program->getUniformLocation("model"); + _projectionLocation = renderPipelineDescriptor.program->getUniformLocation("projection"); backend::VertexLayout vertexLayout; vertexLayout.setAtrribute("a_position", 0, cocos2d::backend::VertexFormat::FLOAT_R32G32, 0); @@ -166,6 +167,9 @@ namespace CC_SAFE_RELEASE(indexBuffer); } + inline int getModelLocation() const { return _modelLocation; } + inline int getProjectionLocation() const { return _projectionLocation; } + backend::RenderPipeline* renderPipelineNoBlending = nullptr; backend::RenderPipeline* renderPipelineNormal = nullptr; backend::RenderPipeline* renderPipelineAddtive = nullptr; @@ -173,6 +177,9 @@ namespace backend::RenderPipeline* renderPipelineMultiply = nullptr; backend::Buffer* vertexBuffer = nullptr; backend::Buffer* indexBuffer = nullptr; + + int _modelLocation = -1; + int _projectionLocation = -1; }; struct BigTriangle @@ -212,8 +219,8 @@ namespace backend::RenderPipelineDescriptor renderPipelineDescriptor; auto vs = device->createShaderModule(cocos2d::backend::ShaderStage::VERTEX, vert); auto fs = device->createShaderModule(cocos2d::backend::ShaderStage::FRAGMENT, frag); - renderPipelineDescriptor.vertexShaderModule = vs; - renderPipelineDescriptor.fragmentShaderModule = fs; + renderPipelineDescriptor.program = device->createProgram(vs, fs); + _timeLocation = renderPipelineDescriptor.program->getUniformLocation("time"); backend::VertexLayout vertexLayout; vertexLayout.setAtrribute("a_position", 0, cocos2d::backend::VertexFormat::FLOAT_R32G32, 0); @@ -239,8 +246,11 @@ namespace CC_SAFE_RELEASE(vertexBuffer); } + inline int getTimeLocation() const { return _timeLocation; } + backend::RenderPipeline* renderPipeline = nullptr; backend::Buffer* vertexBuffer = nullptr; + int _timeLocation = -1; }; // rotation is not used @@ -330,8 +340,7 @@ void BlendingBackend::tick(float dt) _commandBuffer->setViewport(0, 0, utils::WINDOW_WIDTH, utils::WINDOW_HEIGHT); _commandBuffer->setRenderPipeline(bigTriangle->renderPipeline); - _bindGroupBigTriangle.setUniform("time", &_dt, sizeof(_dt)); - _bindGroupBigTriangle.setUniform("projection", _projection.m, sizeof(_projection.m)); + _bindGroupBigTriangle.setFragmentUniform(bigTriangle->getTimeLocation(), "time", &_dt, sizeof(_dt)); _bindGroupBigTriangle.setTexture("texture", 0, _backgroud); _commandBuffer->setBindGroup(&_bindGroupBigTriangle); @@ -354,8 +363,8 @@ void BlendingBackend::tick(float dt) float offsetX = 5.f + hsize; float offsetY = 5.f + hsize; _model = std::move(createModel(cocos2d::Vec3(offsetX, offsetY, 0), cocos2d::Vec3(size, size, 0))); - _bindGroup.setUniform("model", _model.m, sizeof(_model.m)); - _bindGroup.setUniform("projection", _projection.m, sizeof(_projection.m)); + _bindGroup.setVertexUniform(quad->getModelLocation(), "model", _model.m, sizeof(_model.m)); + _bindGroup.setVertexUniform(quad->getProjectionLocation(), "projection", _projection.m, sizeof(_projection.m)); _bindGroup.setTexture("texture", 0, _sprite0); _commandBuffer->setBindGroup(&_bindGroup); @@ -373,8 +382,8 @@ void BlendingBackend::tick(float dt) offsetY = offsetY + 5.f + size; _model = std::move(createModel(cocos2d::Vec3(offsetX, offsetY, 0), cocos2d::Vec3(size, size, 0))); - _bindGroup.setUniform("model", _model.m, sizeof(_model.m)); - _bindGroup.setUniform("projection", _projection.m, sizeof(_projection.m)); + _bindGroup.setVertexUniform(quad->getModelLocation(), "model", _model.m, sizeof(_model.m)); + _bindGroup.setVertexUniform(quad->getProjectionLocation(), "projection", _projection.m, sizeof(_projection.m)); _bindGroup.setTexture("texture", 0, _sprite0); _commandBuffer->setBindGroup(&_bindGroup); @@ -392,8 +401,8 @@ void BlendingBackend::tick(float dt) offsetY = offsetY + 5.f + size; _model = std::move(createModel(cocos2d::Vec3(offsetX, offsetY, 0), cocos2d::Vec3(size, size, 0))); - _bindGroup.setUniform("model", _model.m, sizeof(_model.m)); - _bindGroup.setUniform("projection", _projection.m, sizeof(_projection.m)); + _bindGroup.setVertexUniform(quad->getModelLocation(), "model", _model.m, sizeof(_model.m)); + _bindGroup.setVertexUniform(quad->getProjectionLocation(), "projection", _projection.m, sizeof(_projection.m)); _bindGroup.setTexture("texture", 0, _sprite0); _commandBuffer->setBindGroup(&_bindGroup); @@ -411,8 +420,8 @@ void BlendingBackend::tick(float dt) offsetY = offsetY + 5.f + size; _model = std::move(createModel(cocos2d::Vec3(offsetX, offsetY, 0), cocos2d::Vec3(size, size, 0))); - _bindGroup.setUniform("model", _model.m, sizeof(_model.m)); - _bindGroup.setUniform("projection", _projection.m, sizeof(_projection.m)); + _bindGroup.setVertexUniform(quad->getModelLocation(), "model", _model.m, sizeof(_model.m)); + _bindGroup.setVertexUniform(quad->getProjectionLocation(), "projection", _projection.m, sizeof(_projection.m)); _bindGroup.setTexture("texture", 0, _sprite0); _commandBuffer->setBindGroup(&_bindGroup); @@ -430,8 +439,8 @@ void BlendingBackend::tick(float dt) offsetY = offsetY + 5.f + size; _model = std::move(createModel(cocos2d::Vec3(offsetX, offsetY, 0), cocos2d::Vec3(size, size, 0))); - _bindGroup.setUniform("model", _model.m, sizeof(_model.m)); - _bindGroup.setUniform("projection", _projection.m, sizeof(_projection.m)); + _bindGroup.setVertexUniform(quad->getModelLocation(), "model", _model.m, sizeof(_model.m)); + _bindGroup.setVertexUniform(quad->getProjectionLocation(), "projection", _projection.m, sizeof(_projection.m)); _bindGroup.setTexture("texture", 0, _sprite0); _commandBuffer->setBindGroup(&_bindGroup); diff --git a/test/tests/backend/BunnyBackend.cpp b/test/tests/backend/BunnyBackend.cpp index e719ffe..02bd66a 100644 --- a/test/tests/backend/BunnyBackend.cpp +++ b/test/tests/backend/BunnyBackend.cpp @@ -28,6 +28,7 @@ #include "../Utils.h" #include "backend/Device.h" #include "backend/VertexLayout.h" +#include "backend/Program.h" using namespace cocos2d; @@ -84,8 +85,11 @@ BunnyBackend::BunnyBackend() auto vs = device->createShaderModule(cocos2d::backend::ShaderStage::VERTEX, vert); auto fs = device->createShaderModule(cocos2d::backend::ShaderStage::FRAGMENT, frag); - renderPipelineDescriptor.vertexShaderModule = vs; - renderPipelineDescriptor.fragmentShaderModule = fs; + renderPipelineDescriptor.program = device->createProgram(vs, fs); + _modelLocation = renderPipelineDescriptor.program->getUniformLocation("model"); + _viewLocation = renderPipelineDescriptor.program->getUniformLocation("view"); + _projectionLocation = renderPipelineDescriptor.program->getUniformLocation("projection"); + _colorLocation = renderPipelineDescriptor.program->getUniformLocation("color"); _renderPipeline = device->newRenderPipeline(renderPipelineDescriptor); @@ -98,11 +102,11 @@ BunnyBackend::BunnyBackend() _renderPassDescriptor.needDepthAttachment = true; // bind group - _bindGroup.setUniform("model", _model.m, sizeof(_model.m)); + _bindGroup.setVertexUniform(_modelLocation, "model", _model.m, sizeof(_model.m)); Mat4::createPerspective(60.0f, 1.0f * utils::WINDOW_WIDTH / utils::WINDOW_HEIGHT, 0.01f, 1000.0f, &_projection); - _bindGroup.setUniform("projection", _projection.m, sizeof(_projection.m)); + _bindGroup.setVertexUniform(_projectionLocation, "projection", _projection.m, sizeof(_projection.m)); float color[4] = {0.5f, 0.5f, 0.5f, 1.0f}; - _bindGroup.setUniform("color", color, sizeof(color)); + _bindGroup.setFragmentUniform(_colorLocation, "color", color, sizeof(color)); // vertex buffer _vertexBuffer = device->newBuffer(sizeof(bunny_positions), @@ -131,7 +135,8 @@ void BunnyBackend::tick(float dt) { _time += dt; Mat4::createLookAt(Vec3(30.0f * std::cos(_time), 20.0f, 30.0f * std::sin(_time)), Vec3(0.0f, 2.5f, 0.0f), Vec3(0.0f, 1.0f, 0.f), &_view); - _bindGroup.setUniform("view", _view.m, sizeof(_view.m)); + + _bindGroup.setVertexUniform(_viewLocation, "view", _view.m, sizeof(_view.m)); _commandBuffer->beginFrame(); diff --git a/test/tests/backend/BunnyBackend.h b/test/tests/backend/BunnyBackend.h index f6a57ec..9fb27da 100644 --- a/test/tests/backend/BunnyBackend.h +++ b/test/tests/backend/BunnyBackend.h @@ -54,5 +54,9 @@ class BunnyBackend : public TestBaseI cocos2d::Mat4 _projection; float _time = 0.f; + int _modelLocation = -1; + int _viewLocation = -1; + int _projectionLocation = -1; + int _colorLocation = -1; }; diff --git a/test/tests/backend/DepthTextureBackend.cpp b/test/tests/backend/DepthTextureBackend.cpp index b3f0b97..672be80 100644 --- a/test/tests/backend/DepthTextureBackend.cpp +++ b/test/tests/backend/DepthTextureBackend.cpp @@ -77,8 +77,9 @@ namespace backend::RenderPipelineDescriptor renderPipelineDescriptor; auto vs = device->createShaderModule(cocos2d::backend::ShaderStage::VERTEX, vert); auto fs = device->createShaderModule(cocos2d::backend::ShaderStage::FRAGMENT, frag); - renderPipelineDescriptor.vertexShaderModule = vs; - renderPipelineDescriptor.fragmentShaderModule = fs; + renderPipelineDescriptor.program = device->createProgram(vs, fs); + _nearLocation = renderPipelineDescriptor.program->getUniformLocation("near"); + _farLocation = renderPipelineDescriptor.program->getUniformLocation("far"); backend::VertexLayout vertexLayout; vertexLayout.setAtrribute("a_position", 0, cocos2d::backend::VertexFormat::FLOAT_R32G32, 0); @@ -102,8 +103,14 @@ namespace CC_SAFE_RELEASE(vertexBuffer); } + inline int getNearLocation() const { return _nearLocation; } + inline int getFarLocaiton() const { return _farLocation; } + backend::RenderPipeline* renderPipeline = nullptr; backend::Buffer* vertexBuffer = nullptr; + + int _nearLocation = -1; + int _farLocation = -1; }; struct Bunny @@ -148,8 +155,10 @@ namespace renderPipelineDescriptor.colorAttachmentsFormat[0] = backend::TextureFormat::NONE; auto vs = device->createShaderModule(cocos2d::backend::ShaderStage::VERTEX, vert); auto fs = device->createShaderModule(cocos2d::backend::ShaderStage::FRAGMENT, frag); - renderPipelineDescriptor.vertexShaderModule = vs; - renderPipelineDescriptor.fragmentShaderModule =fs; + renderPipelineDescriptor.program = device->createProgram(vs, fs); + _modelLocation = renderPipelineDescriptor.program->getUniformLocation("model"); + _viewLocation = renderPipelineDescriptor.program->getUniformLocation("view"); + _projectionLocation = renderPipelineDescriptor.program->getUniformLocation("projection"); backend::VertexLayout vertexLayout; vertexLayout.setLayout(3 * sizeof(float), cocos2d::backend::VertexStepMode::VERTEX); @@ -186,9 +195,17 @@ namespace CC_SAFE_RELEASE(renderPipeline); } + inline int getModelLocation() const { return _modelLocation; } + inline int getViewLocation() const { return _viewLocation; } + inline int getProjectionLocation() const { return _projectionLocation; } + backend::Buffer* vertexBuffer = nullptr; backend::Buffer* indexBuffer = nullptr; backend::RenderPipeline* renderPipeline = nullptr; + + int _modelLocation = -1; + int _viewLocation = -1; + int _projectionLocation = -1; }; BigTriangle* bg; @@ -271,9 +288,9 @@ void DepthTextureBackend::tick(float dt) _model = Mat4::IDENTITY; _model.translate(5, 0, 0); - _bindGroupBunny.setUniform("model", _model.m, sizeof(_model.m)); - _bindGroupBunny.setUniform("view", _view.m, sizeof(_view.m)); - _bindGroupBunny.setUniform("projection", _projection.m, sizeof(_projection.m)); + _bindGroupBunny.setVertexUniform(bunny->getModelLocation(), "model", _model.m, sizeof(_model.m)); + _bindGroupBunny.setVertexUniform(bunny->getViewLocation(), "view", _view.m, sizeof(_view.m)); + _bindGroupBunny.setVertexUniform(bunny->getProjectionLocation(), "projection", _projection.m, sizeof(_projection.m)); _commandBuffer->setBindGroup(&_bindGroupBunny); _commandBuffer->drawElements(cocos2d::backend::PrimitiveType::TRIANGLE, @@ -288,9 +305,9 @@ void DepthTextureBackend::tick(float dt) _model = Mat4::IDENTITY; _model.translate(-5, 0, 0); - _bindGroupBunny.setUniform("model", _model.m, sizeof(_model.m)); - _bindGroupBunny.setUniform("view", _view.m, sizeof(_view.m)); - _bindGroupBunny.setUniform("projection", _projection.m, sizeof(_projection.m)); + _bindGroupBunny.setVertexUniform(bunny->getModelLocation(), "model", _model.m, sizeof(_model.m)); + _bindGroupBunny.setVertexUniform(bunny->getViewLocation(), "view", _view.m, sizeof(_view.m)); + _bindGroupBunny.setVertexUniform(bunny->getProjectionLocation(), "projection", _projection.m, sizeof(_projection.m)); _commandBuffer->setBindGroup(&_bindGroupBunny); _commandBuffer->drawElements(cocos2d::backend::PrimitiveType::TRIANGLE, @@ -307,8 +324,8 @@ void DepthTextureBackend::tick(float dt) _bindGroupBigTriangle.setTexture("texture", 0, _depthTexture); float near = 0.1f; float far = 100.f; - _bindGroupBigTriangle.setUniform("near", &near, sizeof(float)); - _bindGroupBigTriangle.setUniform("far", &far, sizeof(float)); + _bindGroupBigTriangle.setFragmentUniform(bg->getNearLocation(), "near", &near, sizeof(float)); + _bindGroupBigTriangle.setFragmentUniform(bg->getFarLocaiton(), "far", &far, sizeof(float)); _commandBuffer->setBindGroup(&_bindGroupBigTriangle); _commandBuffer->drawArrays(cocos2d::backend::PrimitiveType::TRIANGLE, 0, 6); diff --git a/test/tests/backend/GuiProjectionBackend.cpp b/test/tests/backend/GuiProjectionBackend.cpp index e7b7d02..84b5861 100644 --- a/test/tests/backend/GuiProjectionBackend.cpp +++ b/test/tests/backend/GuiProjectionBackend.cpp @@ -68,8 +68,10 @@ GuiProjectionBackend::GuiProjectionBackend() backend::RenderPipelineDescriptor renderPipelineDescriptor; auto vs = device->createShaderModule(backend::ShaderStage::VERTEX, vert); auto fs = device->createShaderModule(backend::ShaderStage::FRAGMENT, frag); - renderPipelineDescriptor.vertexShaderModule = vs; - renderPipelineDescriptor.fragmentShaderModule = fs; + renderPipelineDescriptor.program = device->createProgram(vs, fs); + _colorLocation = renderPipelineDescriptor.program->getUniformLocation("color"); + _projectionLocation = renderPipelineDescriptor.program->getUniformLocation("projection"); + _transformLocation = renderPipelineDescriptor.program->getUniformLocation("transform"); #define VERTEX_POSITION_SIZE 2 #define VERTEX_UV_SIZE 2 @@ -150,9 +152,9 @@ void GuiProjectionBackend::tick(float dt) _commandBuffer->setCullMode(backend::CullMode::NONE); _commandBuffer->setVertexBuffer(0, _vertexBuffer); float redColor[4] = {1, 0, 0, 1}; - _bindGroup.setUniform("color", redColor, sizeof(redColor)); - _bindGroup.setUniform("projection", _projection.m, sizeof(_projection.m)); - _bindGroup.setUniform("transform", _translantion.m, sizeof(_translantion.m)); + _bindGroup.setFragmentUniform(_colorLocation, "color", redColor, sizeof(redColor)); + _bindGroup.setVertexUniform(_projectionLocation, "projection", _projection.m, sizeof(_projection.m)); + _bindGroup.setVertexUniform(_transformLocation, "transform", _translantion.m, sizeof(_translantion.m)); _commandBuffer->setBindGroup(&_bindGroup); _commandBuffer->drawArrays(backend::PrimitiveType::TRIANGLE, 0, _vertexBufferElementCount); @@ -162,9 +164,9 @@ void GuiProjectionBackend::tick(float dt) _commandBuffer->setCullMode(backend::CullMode::NONE); _commandBuffer->setVertexBuffer(0, _vertexBuffer); float greenColor[4] = {0, 1, 0, 1}; - _bindGroup.setUniform("color", greenColor, sizeof(greenColor)); - _bindGroup.setUniform("projection", _projection.m, sizeof(_projection.m)); - _bindGroup.setUniform("transform", _rotation.m, sizeof(_rotation.m)); + _bindGroup.setFragmentUniform(_colorLocation, "color", greenColor, sizeof(greenColor)); + _bindGroup.setVertexUniform(_projectionLocation, "projection", _projection.m, sizeof(_projection.m)); + _bindGroup.setVertexUniform(_transformLocation, "transform", _rotation.m, sizeof(_rotation.m)); _commandBuffer->setBindGroup(&_bindGroup); _commandBuffer->drawArrays(backend::PrimitiveType::TRIANGLE, 0, _vertexBufferElementCount); @@ -175,9 +177,9 @@ void GuiProjectionBackend::tick(float dt) _commandBuffer->setCullMode(backend::CullMode::NONE); _commandBuffer->setVertexBuffer(0, _vertexBuffer); float blueColor[4] = {0, 0, 1, 1}; - _bindGroup.setUniform("color", blueColor, sizeof(blueColor)); - _bindGroup.setUniform("projection", _projection.m, sizeof(_projection.m)); - _bindGroup.setUniform("transform", _scale.m, sizeof(_scale.m)); + _bindGroup.setFragmentUniform(_colorLocation, "color", blueColor, sizeof(blueColor)); + _bindGroup.setVertexUniform(_projectionLocation, "projection", _projection.m, sizeof(_projection.m)); + _bindGroup.setVertexUniform(_transformLocation, "transform", _scale.m, sizeof(_scale.m)); _commandBuffer->setBindGroup(&_bindGroup); _commandBuffer->drawArrays(backend::PrimitiveType::TRIANGLE, 0, _vertexBufferElementCount); diff --git a/test/tests/backend/GuiProjectionBackend.h b/test/tests/backend/GuiProjectionBackend.h index 789586b..c404776 100644 --- a/test/tests/backend/GuiProjectionBackend.h +++ b/test/tests/backend/GuiProjectionBackend.h @@ -49,6 +49,10 @@ class GuiProjectionBackend : public TestBaseI cocos2d::Mat4 _translantion; cocos2d::Mat4 _rotation; cocos2d::Mat4 _scale; + + int _colorLocation = -1; + int _projectionLocation = -1; + int _transformLocation = -1; }; diff --git a/test/tests/backend/MultiTexturesBackend.cpp b/test/tests/backend/MultiTexturesBackend.cpp index f9adbe0..799fe6f 100644 --- a/test/tests/backend/MultiTexturesBackend.cpp +++ b/test/tests/backend/MultiTexturesBackend.cpp @@ -69,8 +69,9 @@ MultiTexturesBackend::MultiTexturesBackend() auto vs = device->createShaderModule(cocos2d::backend::ShaderStage::VERTEX, vert); auto fs = device->createShaderModule(cocos2d::backend::ShaderStage::FRAGMENT, frag); - renderPipelineDescriptor.vertexShaderModule = vs; - renderPipelineDescriptor.fragmentShaderModule = fs; + renderPipelineDescriptor.program = device->createProgram(vs, fs); + _transformLocation = renderPipelineDescriptor.program->getUniformLocation("transform"); + _colorLocation = renderPipelineDescriptor.program->getUniformLocation("color"); backend::VertexLayout vertexLayout; vertexLayout.setAtrribute("a_position", 0, cocos2d::backend::VertexFormat::FLOAT_R32G32, 0); @@ -142,8 +143,8 @@ void MultiTexturesBackend::tick(float dt) _commandBuffer->setVertexBuffer(0, _vertexBuffer); float color[4] = {1.f, 0, 0, 1.f}; - _bindGroup.setUniform("color", color, sizeof(color)); - _bindGroup.setUniform("transform", _transform.m, sizeof(_transform.m)); + _bindGroup.setFragmentUniform(_colorLocation, "color", color, sizeof(color)); + _bindGroup.setVertexUniform(_transformLocation, "transform", _transform.m, sizeof(_transform.m)); // _bindGroup.setTextureArray("texture", {6, 7}, {_background, _texture1}); _bindGroup.setTexture("texture1", 6, _background); _bindGroup.setTexture("texture2", 7, _texture1); diff --git a/test/tests/backend/MultiTexturesBackend.h b/test/tests/backend/MultiTexturesBackend.h index 07ca567..dca699c 100644 --- a/test/tests/backend/MultiTexturesBackend.h +++ b/test/tests/backend/MultiTexturesBackend.h @@ -46,4 +46,7 @@ class MultiTexturesBackend : public TestBaseI cocos2d::backend::BindGroup _bindGroup; cocos2d::Mat4 _transform; + + int _transformLocation = -1; + int _colorLocation = -1; }; diff --git a/test/tests/backend/ParticleBackend.cpp b/test/tests/backend/ParticleBackend.cpp index c55d1cf..4a17ee4 100644 --- a/test/tests/backend/ParticleBackend.cpp +++ b/test/tests/backend/ParticleBackend.cpp @@ -77,8 +77,10 @@ ParticleBackend::ParticleBackend() backend::RenderPipelineDescriptor renderPipelineDescriptor; auto vs = device->createShaderModule(backend::ShaderStage::VERTEX, vert); auto fs = device->createShaderModule(backend::ShaderStage::FRAGMENT, frag); - renderPipelineDescriptor.vertexShaderModule = vs; - renderPipelineDescriptor.fragmentShaderModule = fs; + renderPipelineDescriptor.program = device->createProgram(vs, fs); + _modelLocation = renderPipelineDescriptor.program->getUniformLocation("model"); + _viewLocation = renderPipelineDescriptor.program->getUniformLocation("view"); + _projectionLocation = renderPipelineDescriptor.program->getUniformLocation("projection"); #define VERTEX_QUAD_SIZE 2 #define VERTEX_POS_SIZE 3 @@ -226,9 +228,9 @@ void ParticleBackend::tick(float dt) } _vertexBuffer->updateData(_vbufferArray, sizeof(_vbufferArray)); - _bindGroup.setUniform("model", _model.m, sizeof(_model.m)); - _bindGroup.setUniform("view", _view.m, sizeof(_view.m)); - _bindGroup.setUniform("projection", _projection.m, sizeof(_projection.m)); + _bindGroup.setVertexUniform(_modelLocation, "model", _model.m, sizeof(_model.m)); + _bindGroup.setVertexUniform(_viewLocation, "view", _view.m, sizeof(_view.m)); + _bindGroup.setVertexUniform(_projectionLocation, "projection", _projection.m, sizeof(_projection.m)); _bindGroup.setTexture("u_texture", 0, _texture); _commandBuffer->setBindGroup(&_bindGroup); diff --git a/test/tests/backend/ParticleBackend.h b/test/tests/backend/ParticleBackend.h index 9ad4031..a08a4a8 100644 --- a/test/tests/backend/ParticleBackend.h +++ b/test/tests/backend/ParticleBackend.h @@ -66,5 +66,9 @@ class ParticleBackend : public TestBaseI #define particleCount 100 ParticleData _particles[particleCount]; + + int _modelLocation = -1; + int _viewLocation = -1; + int _projectionLocation = -1; }; diff --git a/test/tests/backend/PostProcessBackend.cpp b/test/tests/backend/PostProcessBackend.cpp index 6914085..c906af4 100644 --- a/test/tests/backend/PostProcessBackend.cpp +++ b/test/tests/backend/PostProcessBackend.cpp @@ -28,6 +28,7 @@ #include "PostProcessBackend.h" #include "BunnyData.h" #include "../Utils.h" +#include "backend/Program.h" using namespace cocos2d; @@ -93,9 +94,8 @@ namespace auto vs = device->createShaderModule(backend::ShaderStage::VERTEX, vert); auto fs = device->createShaderModule(backend::ShaderStage::FRAGMENT, frag); - renderPipelineDescriptor.vertexShaderModule = vs; - renderPipelineDescriptor.fragmentShaderModule = fs; - + renderPipelineDescriptor.program = device->createProgram(vs, fs); + backend::VertexLayout vertexLayout; vertexLayout.setAtrribute("a_position", 0, backend::VertexFormat::FLOAT_R32G32, 0); vertexLayout.setLayout(2 * sizeof(float), backend::VertexStepMode::VERTEX); @@ -163,8 +163,12 @@ namespace auto vs = device->createShaderModule(backend::ShaderStage::VERTEX, vert); auto fs = device->createShaderModule(backend::ShaderStage::FRAGMENT, frag); - renderPipelineDescriptor.vertexShaderModule = vs; - renderPipelineDescriptor.fragmentShaderModule = fs; + + renderPipelineDescriptor.program = device->createProgram(vs, fs); + _modelLocation = renderPipelineDescriptor.program->getUniformLocation("model"); + _viewLocation = renderPipelineDescriptor.program->getUniformLocation("view"); + _projectionLocation = renderPipelineDescriptor.program->getUniformLocation("projection"); + _colorLocation = renderPipelineDescriptor.program->getUniformLocation("color"); backend::VertexLayout vertexLayout; vertexLayout.setAtrribute("a_position", 0, backend::VertexFormat::FLOAT_R32G32B32, 0); @@ -197,9 +201,19 @@ namespace CC_SAFE_RELEASE(_renderPipeline); } + inline int getModelLocaiton() const { return _modelLocation; } + inline int getViewLocaiton() const { return _viewLocation; } + inline int getProjectionLocaiton() const { return _projectionLocation; } + inline int getColorLocaiton() const { return _colorLocation; } + backend::Buffer* _vertexBuffer = nullptr; backend::Buffer* _indexBuffer = nullptr; backend::RenderPipeline* _renderPipeline = nullptr; + + int _modelLocation = -1; + int _viewLocation = -1; + int _projectionLocation = -1; + int _colorLocation = -1; }; Bunny* bunny = nullptr; @@ -290,11 +304,11 @@ void PostProcessBackend::tick(float dt) _commandBuffer->setVertexBuffer(0, bunny->_vertexBuffer); _commandBuffer->setIndexBuffer(bunny->_indexBuffer); - _bindGroup.setUniform("model", _model.m, sizeof(_model.m)); - _bindGroup.setUniform("view", _view.m, sizeof(_view.m)); - _bindGroup.setUniform("projection", _projection.m, sizeof(_projection.m)); + _bindGroup.setVertexUniform(bunny->getModelLocaiton(), "model", _model.m, sizeof(_model.m)); + _bindGroup.setVertexUniform(bunny->getViewLocaiton(), "view", _view.m, sizeof(_view.m)); + _bindGroup.setVertexUniform(bunny->getProjectionLocaiton(), "projection", _projection.m, sizeof(_projection.m)); float color[4] = {0.1f, 0.1f, 0.1f, 1}; - _bindGroup.setUniform("color", color, sizeof(color)); + _bindGroup.setFragmentUniform(bunny->getColorLocaiton(), "color", color, sizeof(color)); _commandBuffer->setBindGroup(&_bindGroup); _commandBuffer->drawElements(backend::PrimitiveType::TRIANGLE, @@ -311,11 +325,11 @@ void PostProcessBackend::tick(float dt) _commandBuffer->setVertexBuffer(0, bunny->_vertexBuffer); _commandBuffer->setIndexBuffer(bunny->_indexBuffer); - _bindGroup.setUniform("model", _model.m, sizeof(_model.m)); - _bindGroup.setUniform("view", _view.m, sizeof(_view.m)); - _bindGroup.setUniform("projection", _projection.m, sizeof(_projection.m)); + _bindGroup.setVertexUniform(bunny->getModelLocaiton(), "model", _model.m, sizeof(_model.m)); + _bindGroup.setVertexUniform(bunny->getViewLocaiton(), "view", _view.m, sizeof(_view.m)); + _bindGroup.setVertexUniform(bunny->getProjectionLocaiton(), "projection", _projection.m, sizeof(_projection.m)); float color2[4] = {0.3f, 0.3f, 0.3f, 1}; - _bindGroup.setUniform("color", color2 , sizeof(color2)); + _bindGroup.setFragmentUniform(bunny->getColorLocaiton(), "color", color2 , sizeof(color2)); _commandBuffer->setBindGroup(&_bindGroup); _commandBuffer->drawElements(backend::PrimitiveType::TRIANGLE, diff --git a/test/tests/backend/PostProcessBackend.h b/test/tests/backend/PostProcessBackend.h index 87ed70e..c6fb92b 100644 --- a/test/tests/backend/PostProcessBackend.h +++ b/test/tests/backend/PostProcessBackend.h @@ -44,6 +44,8 @@ class PostProcessBackend : public TestBaseI cocos2d::backend::RenderPassDescriptor _renderPassDescriptorBg; cocos2d::backend::Texture* _colorTexture = nullptr; cocos2d::backend::Texture* _depthTexture = nullptr; + cocos2d::backend::Program* _programBigTriangle = nullptr; + float _t; diff --git a/test/tests/backend/StencilBackend.cpp b/test/tests/backend/StencilBackend.cpp index 0d62830..b217555 100644 --- a/test/tests/backend/StencilBackend.cpp +++ b/test/tests/backend/StencilBackend.cpp @@ -25,6 +25,7 @@ #include "StencilBackend.h" #include "cocos2d.h" #include "../Utils.h" +#include "backend/Program.h" #include @@ -93,8 +94,10 @@ StencilBackend::StencilBackend() renderPipelineDescriptor.colorAttachmentsFormat[0] = backend::TextureFormat::SYSTEM_DEFAULT; auto vs = device->createShaderModule(cocos2d::backend::ShaderStage::VERTEX, vert); auto fs = device->createShaderModule(cocos2d::backend::ShaderStage::FRAGMENT, frag); - renderPipelineDescriptor.vertexShaderModule = vs; - renderPipelineDescriptor.fragmentShaderModule = fs; + renderPipelineDescriptor.program = device->createProgram(vs, fs); + _transformLocation = renderPipelineDescriptor.program->getUniformLocation("transform"); + _colorLocation = renderPipelineDescriptor.program->getUniformLocation("color"); + backend::VertexLayout vertexLayout; vertexLayout.setAtrribute("a_position", 0, cocos2d::backend::VertexFormat::FLOAT_R32G32, 0); vertexLayout.setLayout(2 * sizeof(float), cocos2d::backend::VertexStepMode::VERTEX); @@ -185,8 +188,9 @@ void StencilBackend::tick(float dt) _commandBuffer->setCullMode(backend::CullMode::NONE); _commandBuffer->setRenderPipeline(_renderPipeline); - _bindGroup.setUniform("color", color, sizeof(color)); - _bindGroup.setUniform("transform", _transform0.m, sizeof(_transform0.m)); + + _bindGroup.setFragmentUniform(_colorLocation, "color", color, sizeof(color)); + _bindGroup.setVertexUniform(_transformLocation, "transform", _transform0.m, sizeof(_transform0.m)); _bindGroup.setTexture("texture", 0, _canvasTexture); _commandBuffer->setBindGroup(&_bindGroup); @@ -205,8 +209,9 @@ void StencilBackend::tick(float dt) _commandBuffer->setRenderPipeline(_renderPipeline); _commandBuffer->setVertexBuffer(0, _vertexBuffer); _commandBuffer->setCullMode(backend::CullMode::NONE); + _bindGroup.setTexture("texture", 0, _texture); - _bindGroup.setUniform("transform", _transform1.m, sizeof(_transform1.m)); + _bindGroup.setVertexUniform(_transformLocation, "transform", _transform1.m, sizeof(_transform1.m)); _commandBuffer->setBindGroup(&_bindGroup); _commandBuffer->drawArrays(cocos2d::backend::PrimitiveType::TRIANGLE, 0, 6); @@ -225,7 +230,7 @@ void StencilBackend::tick(float dt) _commandBuffer->setStencilReferenceValue(0x1); _commandBuffer->setRenderPipeline(_renderPipelineCavasTexture); - _bindGroup.setUniform("transform", _transform0.m, sizeof(_transform0.m)); + _bindGroup.setVertexUniform(_transformLocation, "transform", _transform0.m, sizeof(_transform0.m)); _bindGroup.setTexture("texture", 0, _canvasTexture); _commandBuffer->setBindGroup(&_bindGroup); _commandBuffer->drawArrays(cocos2d::backend::PrimitiveType::TRIANGLE, 0, 6); @@ -241,7 +246,7 @@ void StencilBackend::tick(float dt) _commandBuffer->setCullMode(backend::CullMode::NONE); _bindGroup.setTexture("texture", 0, _texture); - _bindGroup.setUniform("transform", _transform1.m, sizeof(_transform1.m)); + _bindGroup.setVertexUniform(_transformLocation, "transform", _transform1.m, sizeof(_transform1.m)); _commandBuffer->setBindGroup(&_bindGroup); _commandBuffer->drawArrays(cocos2d::backend::PrimitiveType::TRIANGLE, 0, 6); @@ -259,7 +264,7 @@ void StencilBackend::tick(float dt) _commandBuffer->setStencilReferenceValue(0x1); _commandBuffer->setRenderPipeline(_renderPipelineCavasTexture); - _bindGroup.setUniform("transform", _transform0.m, sizeof(_transform0.m)); + _bindGroup.setVertexUniform(_transformLocation, "transform", _transform0.m, sizeof(_transform0.m)); _bindGroup.setTexture("texture", 0, _canvasTexture); _commandBuffer->setBindGroup(&_bindGroup); _commandBuffer->drawArrays(cocos2d::backend::PrimitiveType::TRIANGLE, 0, 6); @@ -275,7 +280,7 @@ void StencilBackend::tick(float dt) _commandBuffer->setCullMode(backend::CullMode::NONE); _bindGroup.setTexture("texture", 0, _texture); - _bindGroup.setUniform("transform", _transform1.m, sizeof(_transform1.m)); + _bindGroup.setVertexUniform(_transformLocation, "transform", _transform1.m, sizeof(_transform1.m)); _commandBuffer->setBindGroup(&_bindGroup); _commandBuffer->drawArrays(cocos2d::backend::PrimitiveType::TRIANGLE, 0, 6); @@ -292,7 +297,7 @@ void StencilBackend::tick(float dt) _commandBuffer->setStencilReferenceValue(0x1); _commandBuffer->setRenderPipeline(_renderPipelineCavasTexture); - _bindGroup.setUniform("transform", _transform0.m, sizeof(_transform0.m)); + _bindGroup.setVertexUniform(_transformLocation, "transform", _transform0.m, sizeof(_transform0.m)); _bindGroup.setTexture("texture", 0, _canvasTexture); _commandBuffer->setBindGroup(&_bindGroup); _commandBuffer->drawArrays(cocos2d::backend::PrimitiveType::TRIANGLE, 0, 6); @@ -308,7 +313,7 @@ void StencilBackend::tick(float dt) _commandBuffer->setCullMode(backend::CullMode::NONE); _bindGroup.setTexture("texture", 0, _texture); - _bindGroup.setUniform("transform", _transform1.m, sizeof(_transform1.m)); + _bindGroup.setVertexUniform(_transformLocation, "transform", _transform1.m, sizeof(_transform1.m)); _commandBuffer->setBindGroup(&_bindGroup); _commandBuffer->drawArrays(cocos2d::backend::PrimitiveType::TRIANGLE, 0, 6); diff --git a/test/tests/backend/StencilBackend.h b/test/tests/backend/StencilBackend.h index 4d031f9..9bb33d1 100644 --- a/test/tests/backend/StencilBackend.h +++ b/test/tests/backend/StencilBackend.h @@ -52,6 +52,9 @@ class StencilBackend : public TestBaseI cocos2d::backend::RenderPipeline* _renderPipelineTextureBackAndFront = nullptr; cocos2d::backend::RenderPipeline* _renderPipelineTextureBack = nullptr; cocos2d::backend::RenderPipeline* _renderPipelineTextureFront = nullptr; + + int _transformLocation = -1; + int _colorLocation = -1; }; diff --git a/test/tests/backend/SubImageBackend.cpp b/test/tests/backend/SubImageBackend.cpp index 3e21e93..8dbad6c 100644 --- a/test/tests/backend/SubImageBackend.cpp +++ b/test/tests/backend/SubImageBackend.cpp @@ -25,6 +25,7 @@ #include "SubImageBackend.h" #include "cocos2d.h" #include "../Utils.h" +#include "backend/Program.h" #include @@ -62,8 +63,9 @@ SubImageBackend::SubImageBackend() backend::RenderPipelineDescriptor renderPipelineDescriptor; auto vs = device->createShaderModule(backend::ShaderStage::VERTEX, vert); auto fs = device->createShaderModule(backend::ShaderStage::FRAGMENT, frag); - renderPipelineDescriptor.vertexShaderModule = vs; - renderPipelineDescriptor.fragmentShaderModule = fs; + renderPipelineDescriptor.program = device->createProgram(vs, fs); + _transformLocation = renderPipelineDescriptor.program->getUniformLocation("transform"); + _colorLocation = renderPipelineDescriptor.program->getUniformLocation("color"); backend::VertexLayout vertexLayout; vertexLayout.setAtrribute("a_position", 0, backend::VertexFormat::FLOAT_R32G32, 0); @@ -135,8 +137,8 @@ void SubImageBackend::tick(float dt) _commandBuffer->setVertexBuffer(0, _vertexBuffer); float color[4] = {1, 0, 0, 1}; - _bindGroup.setUniform("color", color, sizeof(color)); - _bindGroup.setUniform("transform", _transform0.m, sizeof(_transform0.m)); + _bindGroup.setFragmentUniform(_colorLocation, "color", color, sizeof(color)); + _bindGroup.setVertexUniform(_transformLocation, "transform", _transform0.m, sizeof(_transform0.m)); _bindGroup.setTexture("texture", 0, _texture); _commandBuffer->setBindGroup(&_bindGroup); diff --git a/test/tests/backend/SubImageBackend.h b/test/tests/backend/SubImageBackend.h index 8a107d2..4143bc6 100644 --- a/test/tests/backend/SubImageBackend.h +++ b/test/tests/backend/SubImageBackend.h @@ -49,6 +49,9 @@ class SubImageBackend : public TestBaseI uint8_t* _data; size_t _dataSize; size_t _updatePixelIndex; + + int _transformLocation = -1; + int _colorLocation = -1; }; diff --git a/test/tests/backend/Texture2DBackend.cpp b/test/tests/backend/Texture2DBackend.cpp index 762a1d9..e174851 100644 --- a/test/tests/backend/Texture2DBackend.cpp +++ b/test/tests/backend/Texture2DBackend.cpp @@ -26,6 +26,7 @@ #include "cocos2d.h" #include "../Utils.h" #include "backend/Device.h" +#include "backend/Program.h" #include @@ -119,8 +120,9 @@ Texture2DBackendTest::Texture2DBackendTest() RenderPipelineDescriptor renderPipelineDescriptor; auto vs = device->createShaderModule(cocos2d::backend::ShaderStage::VERTEX, vert); auto fs = device->createShaderModule(cocos2d::backend::ShaderStage::FRAGMENT, frag); - renderPipelineDescriptor.vertexShaderModule = vs; - renderPipelineDescriptor.fragmentShaderModule = fs; + renderPipelineDescriptor.program = device->createProgram(vs, fs); + _transformLocation = renderPipelineDescriptor.program->getUniformLocation("transform"); + _colorLocation = renderPipelineDescriptor.program->getUniformLocation("color"); VertexLayout vertexLayout; vertexLayout.setAtrribute("a_position", 0, cocos2d::backend::VertexFormat::FLOAT_R32G32, 0); @@ -136,12 +138,13 @@ Texture2DBackendTest::Texture2DBackendTest() // set uniforms _bindGroupCanvas.setTexture("texture", 0, _canvasTexture); float color[4] = {1.f, 0.f, 0.f, 1.f}; - _bindGroupCanvas.setUniform("color", color, sizeof(color)); - _bindGroupCanvas.setUniform("transform", _transform0.m, sizeof(_transform0.m)); + + _bindGroupCanvas.setFragmentUniform(_colorLocation, "color", color, sizeof(color)); + _bindGroupCanvas.setVertexUniform(_transformLocation, "transform", _transform0.m, sizeof(_transform0.m)); _bindGroupdTexture.setTexture("texture", 0, _texture); - _bindGroupdTexture.setUniform("color", color, sizeof(color)); - _bindGroupdTexture.setUniform("transform", _transform1.m, sizeof(_transform1.m)); + _bindGroupdTexture.setFragmentUniform(_colorLocation, "color", color, sizeof(color)); + _bindGroupdTexture.setVertexUniform(_transformLocation, "transform", _transform1.m, sizeof(_transform1.m)); // render pass _renderPassDescriptor.clearColorValue = {0.1f, 0.1f, 0.1f, 0.1f}; diff --git a/test/tests/backend/Texture2DBackend.h b/test/tests/backend/Texture2DBackend.h index ddc2d8b..4f72c14 100644 --- a/test/tests/backend/Texture2DBackend.h +++ b/test/tests/backend/Texture2DBackend.h @@ -55,6 +55,9 @@ class Texture2DBackendTest : public TestBaseI cocos2d::backend::RenderPipeline* _renderPipeline = nullptr; cocos2d::backend::RenderPassDescriptor _renderPassDescriptor; cocos2d::backend::CommandBuffer* _commandBuffer = nullptr; + + int _transformLocation = -1; + int _colorLocation = -1; }; From 6b15161e7ef4f447da7854e296f8d17fadd17ee0 Mon Sep 17 00:00:00 2001 From: coulsonwang Date: Thu, 3 Jan 2019 17:05:13 +0800 Subject: [PATCH 02/11] [Feature] remove unneeded code --- src/backend/RenderPipelineDescriptor.h | 2 -- src/backend/opengl/ProgramGL.cpp | 15 --------------- src/backend/opengl/ProgramGL.h | 2 -- 3 files changed, 19 deletions(-) diff --git a/src/backend/RenderPipelineDescriptor.h b/src/backend/RenderPipelineDescriptor.h index 15921e6..fc823e7 100644 --- a/src/backend/RenderPipelineDescriptor.h +++ b/src/backend/RenderPipelineDescriptor.h @@ -16,8 +16,6 @@ class Program; struct RenderPipelineDescriptor { Program* program = nullptr; - ShaderModule* vertexShaderModule = nullptr; - ShaderModule* fragmentShaderModule = nullptr; DepthStencilState* depthStencilState = nullptr; BlendState* blendState = nullptr; std::vector vertexLayouts; diff --git a/src/backend/opengl/ProgramGL.cpp b/src/backend/opengl/ProgramGL.cpp index 0f51e2d..c6a9542 100644 --- a/src/backend/opengl/ProgramGL.cpp +++ b/src/backend/opengl/ProgramGL.cpp @@ -69,21 +69,6 @@ ProgramGL::ProgramGL(ShaderModule* vs, ShaderModule* fs) computeUniformInfos(); } -ProgramGL::ProgramGL(const RenderPipelineDescriptor& descriptor) -:Program(descriptor.vertexShaderModule, descriptor.fragmentShaderModule) -, _vertexShaderModule(static_cast(descriptor.vertexShaderModule)) -, _fragmentShaderModule(static_cast(descriptor.fragmentShaderModule)) -{ - assert(_vertexShaderModule != nullptr && _fragmentShaderModule != nullptr); - - CC_SAFE_RETAIN(_vertexShaderModule); - CC_SAFE_RETAIN(_fragmentShaderModule); - - compileProgram(); - computeAttributeInfos(descriptor); - computeUniformInfos(); -} - ProgramGL::~ProgramGL() { CC_SAFE_RELEASE(_vertexShaderModule); diff --git a/src/backend/opengl/ProgramGL.h b/src/backend/opengl/ProgramGL.h index 1fb58a7..5a3bcdf 100644 --- a/src/backend/opengl/ProgramGL.h +++ b/src/backend/opengl/ProgramGL.h @@ -38,8 +38,6 @@ class ProgramGL : public Program typedef std::vector VertexAttributeArray; ProgramGL(ShaderModule* vs, ShaderModule* fs); - - ProgramGL(const RenderPipelineDescriptor& descriptor); ~ProgramGL(); inline const std::vector& getAttributeInfos() const { return _attributeInfos; } From 01218b9416485cbe6cb63b15741f970dbbae48c6 Mon Sep 17 00:00:00 2001 From: coulsonwang Date: Thu, 3 Jan 2019 17:09:06 +0800 Subject: [PATCH 03/11] [Feature] add program files --- src/backend/Program.cpp | 20 ++++++++++++++++++++ src/backend/Program.h | 29 +++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+) create mode 100644 src/backend/Program.cpp create mode 100644 src/backend/Program.h diff --git a/src/backend/Program.cpp b/src/backend/Program.cpp new file mode 100644 index 0000000..e47d5d1 --- /dev/null +++ b/src/backend/Program.cpp @@ -0,0 +1,20 @@ +#include "Program.h" +#include "ShaderModule.h" + +CC_BACKEND_BEGIN + +Program::Program(ShaderModule* vs, ShaderModule* fs) +: _vertexShader(vs) +, _fragmentShader(fs) +{ + CC_SAFE_RETAIN(_vertexShader); + CC_SAFE_RETAIN(_fragmentShader); +} + +Program::~Program() +{ + CC_SAFE_RELEASE(_vertexShader); + CC_SAFE_RELEASE(_fragmentShader); +} + +CC_BACKEND_END diff --git a/src/backend/Program.h b/src/backend/Program.h new file mode 100644 index 0000000..5cec608 --- /dev/null +++ b/src/backend/Program.h @@ -0,0 +1,29 @@ +#pragma once + +#include "Macros.h" +#include "base/CCRef.h" +#include "platform/CCPlatformMacros.h" +#include + +CC_BACKEND_BEGIN + +class ShaderModule; + +class Program : public Ref +{ +public: + virtual int getUniformLocation(const std::string& uniform) = 0; + + inline ShaderModule* getVertexShader() const { return _vertexShader; } + inline ShaderModule* getFragmentShader() const { return _fragmentShader; } + +protected: + Program(ShaderModule* vs, ShaderModule* fs); + virtual ~Program(); + +private: + backend::ShaderModule* _vertexShader = nullptr; + backend::ShaderModule* _fragmentShader = nullptr; +}; + +CC_BACKEND_END From 17c23e41fd03b19a71281eccafdebc6fca608cde Mon Sep 17 00:00:00 2001 From: coulsonwang Date: Fri, 4 Jan 2019 16:07:06 +0800 Subject: [PATCH 04/11] [Feature] remove BindGroup --- src/backend/Backend.h | 1 - src/backend/BindGroup.cpp | 104 ----------- src/backend/BindGroup.h | 60 ------- src/backend/CommandBuffer.h | 2 - src/backend/Program.cpp | 59 ++++++ src/backend/Program.h | 24 +++ src/backend/RenderPipeline.cpp | 17 ++ src/backend/RenderPipeline.h | 10 +- src/backend/metal/CommandBufferMTL.h | 4 - src/backend/metal/CommandBufferMTL.mm | 34 +--- src/backend/metal/ProgramMTL.h | 6 +- src/backend/metal/ProgramMTL.mm | 22 +++ src/backend/metal/RenderPipelineMTL.h | 5 + src/backend/metal/RenderPipelineMTL.mm | 5 +- src/backend/metal/ShaderModuleMTL.h | 2 + src/backend/metal/ShaderModuleMTL.mm | 6 +- src/backend/opengl/CommandBufferGL.cpp | 143 ++------------- src/backend/opengl/CommandBufferGL.h | 3 - src/backend/opengl/ProgramGL.cpp | 190 +++++++++++++++++++- src/backend/opengl/ProgramGL.h | 11 +- src/backend/opengl/RenderPipelineGL.cpp | 1 + test/Test.xcodeproj/project.pbxproj | 14 +- test/tests/backend/BasicBackend.cpp | 3 +- test/tests/backend/BasicBackend.h | 2 - test/tests/backend/BlendingBackend.cpp | 39 ++-- test/tests/backend/BlendingBackend.h | 3 - test/tests/backend/BunnyBackend.cpp | 9 +- test/tests/backend/BunnyBackend.h | 2 - test/tests/backend/DepthTextureBackend.cpp | 29 ++- test/tests/backend/DepthTextureBackend.h | 2 - test/tests/backend/GuiProjectionBackend.cpp | 26 ++- test/tests/backend/GuiProjectionBackend.h | 1 - test/tests/backend/MultiTexturesBackend.cpp | 13 +- test/tests/backend/MultiTexturesBackend.h | 1 - test/tests/backend/ParticleBackend.cpp | 11 +- test/tests/backend/ParticleBackend.h | 1 - test/tests/backend/PostProcessBackend.cpp | 33 ++-- test/tests/backend/PostProcessBackend.h | 1 - test/tests/backend/StencilBackend.cpp | 48 +++-- test/tests/backend/StencilBackend.h | 1 - test/tests/backend/SubImageBackend.cpp | 13 +- test/tests/backend/SubImageBackend.h | 4 - test/tests/backend/Texture2DBackend.cpp | 22 +-- test/tests/backend/Texture2DBackend.h | 3 - 44 files changed, 476 insertions(+), 514 deletions(-) delete mode 100644 src/backend/BindGroup.cpp delete mode 100644 src/backend/BindGroup.h create mode 100644 src/backend/RenderPipeline.cpp diff --git a/src/backend/Backend.h b/src/backend/Backend.h index 47458fd..144f6e3 100644 --- a/src/backend/Backend.h +++ b/src/backend/Backend.h @@ -1,6 +1,5 @@ #pragma once -#include "backend/BindGroup.h" #include "backend/RenderPassDescriptor.h" #include "backend/RenderPipeline.h" #include "backend/RenderPipelineDescriptor.h" diff --git a/src/backend/BindGroup.cpp b/src/backend/BindGroup.cpp deleted file mode 100644 index d17fd27..0000000 --- a/src/backend/BindGroup.cpp +++ /dev/null @@ -1,104 +0,0 @@ -#include "BindGroup.h" -#include "Texture.h" - -CC_BACKEND_BEGIN - -BindGroup::UniformInfo::UniformInfo(const std::string& _name, void* _data, uint32_t _size) -: name(_name) -, size(_size) -{ - data = malloc(size); - if (data) - memcpy(data, _data, size); -} - -BindGroup::UniformInfo::~UniformInfo() -{ - if (data) - free(data); -} - -BindGroup::UniformInfo& BindGroup::UniformInfo::operator=(UniformInfo&& rhs) -{ - if (this != &rhs) - { - name = rhs.name; - size = rhs.size; - - data = rhs.data; - rhs.data = nullptr; - } - - return *this; -} - -BindGroup::TextureInfo::TextureInfo(const std::string& _name, const std::vector& _indices, const std::vector _textures) -: name(_name) -, indices(_indices) -, textures(_textures) -{ - retainTextures(); -} - -BindGroup::TextureInfo::~TextureInfo() -{ - releaseTextures(); -} - -BindGroup::TextureInfo& BindGroup::TextureInfo::operator=(TextureInfo&& rhs) -{ - if (this != &rhs) - { - name = rhs.name; - indices = rhs.indices; - - rhs.retainTextures(); - releaseTextures(); - textures = rhs.textures; - - //release the textures before cleaning the vertor - rhs.releaseTextures(); - rhs.textures.clear(); - } - return *this; -} - -void BindGroup::TextureInfo::retainTextures() -{ - for (auto& texture : textures) - CC_SAFE_RETAIN(texture); -} - -void BindGroup::TextureInfo::releaseTextures() -{ - for (auto& texture : textures) - CC_SAFE_RELEASE(texture); -} - -void BindGroup::setTexture(const std::string &name, uint32_t index, Texture *texture) -{ - TextureInfo textureInfo(name, {index}, {texture}); - _textureInfos[name] = std::move(textureInfo); -} - -void BindGroup::setTextureArray(const std::string& name, const std::vector& indices, const std::vector textures) -{ - assert(indices.size() == textures.size()); - - TextureInfo textureInfo(name, indices, textures); - _textureInfos[name] = std::move(textureInfo); -} - -void BindGroup::setVertexUniform(int location, const std::string& name, void* data, uint32_t size) -{ - UniformInfo uniform(name, data, size); - _vertexUniformInfos[location] = std::move(uniform); -} - -void BindGroup::setFragmentUniform(int location, const std::string& name, void* data, uint32_t size) -{ - UniformInfo uniform(name, data, size); - _fragUniformInfos[location] = std::move(uniform); -} - -CC_BACKEND_END diff --git a/src/backend/BindGroup.h b/src/backend/BindGroup.h deleted file mode 100644 index 4d81a49..0000000 --- a/src/backend/BindGroup.h +++ /dev/null @@ -1,60 +0,0 @@ -#pragma once - -#include "Macros.h" -#include "base/CCRef.h" - -#include -#include -#include - -CC_BACKEND_BEGIN - -class Texture; -class Sampler; - -class BindGroup : public cocos2d::Ref -{ -public: - struct UniformInfo - { - UniformInfo(const std::string& _name, void* _data, uint32_t _size); - UniformInfo() = default; - ~UniformInfo(); - UniformInfo& operator =(UniformInfo&& rhs); - - std::string name; - uint32_t size = 0; - void* data = nullptr; - }; - - struct TextureInfo - { - TextureInfo(const std::string& _name, const std::vector& _indices, const std::vector _textures); - TextureInfo() = default; - ~TextureInfo(); - TextureInfo& operator =(TextureInfo&& rhs); - - void retainTextures(); - void releaseTextures(); - - std::string name; - std::vector indices; - std::vector textures; - }; - - void setTexture(const std::string& name, uint32_t index, Texture* texture); - void setTextureArray(const std::string& name, const std::vector& indices, const std::vector textures); - void setVertexUniform(int location, const std::string& name, void* data, uint32_t size); - void setFragmentUniform(int location, const std::string& name, void* data, uint32_t size); - - inline const std::unordered_map& getVertexUniformInfos() const { return _vertexUniformInfos; } - inline const std::unordered_map& getFragUniformInfos() const { return _fragUniformInfos; } - inline const std::unordered_map& getTextureInfos() const { return _textureInfos; } - -private: - std::unordered_map _vertexUniformInfos; - std::unordered_map _fragUniformInfos; - std::unordered_map _textureInfos; -}; - -CC_BACKEND_END diff --git a/src/backend/CommandBuffer.h b/src/backend/CommandBuffer.h index 4997d1e..5df8160 100644 --- a/src/backend/CommandBuffer.h +++ b/src/backend/CommandBuffer.h @@ -13,7 +13,6 @@ CC_BACKEND_BEGIN class RenderPass; class RenderPipeline; class Buffer; -class BindGroup; class CommandBuffer : public cocos2d::Ref { @@ -24,7 +23,6 @@ class CommandBuffer : public cocos2d::Ref virtual void setViewport(uint32_t x, uint32_t y, uint32_t w, uint32_t h) = 0; virtual void setCullMode(CullMode mode) = 0; virtual void setVertexBuffer(uint32_t index, Buffer* buffer) = 0; - virtual void setBindGroup(BindGroup* bindGroup) = 0; virtual void setIndexBuffer(Buffer* buffer) = 0; virtual void drawArrays(PrimitiveType primitiveType, uint32_t start, uint32_t count) = 0; virtual void drawElements(PrimitiveType primitiveType, IndexFormat indexType, uint32_t count) = 0; diff --git a/src/backend/Program.cpp b/src/backend/Program.cpp index e47d5d1..956bbe2 100644 --- a/src/backend/Program.cpp +++ b/src/backend/Program.cpp @@ -1,5 +1,6 @@ #include "Program.h" #include "ShaderModule.h" +#include "Texture.h" CC_BACKEND_BEGIN @@ -15,6 +16,64 @@ Program::~Program() { CC_SAFE_RELEASE(_vertexShader); CC_SAFE_RELEASE(_fragmentShader); + _textureInfos.clear(); +} + +Program::TextureInfo::TextureInfo(const std::string& _name, const std::vector& _indices, const std::vector _textures) +: name(_name) +, indices(_indices) +, textures(_textures) +{ + retainTextures(); +} + +Program::TextureInfo::~TextureInfo() +{ + releaseTextures(); +} + +Program::TextureInfo& Program::TextureInfo::operator=(TextureInfo&& rhs) +{ + if (this != &rhs) + { + name = rhs.name; + indices = rhs.indices; + + rhs.retainTextures(); + releaseTextures(); + textures = rhs.textures; + + //release the textures before cleaning the vertor + rhs.releaseTextures(); + rhs.textures.clear(); + } + return *this; +} + +void Program::TextureInfo::retainTextures() +{ + for (auto& texture : textures) + CC_SAFE_RETAIN(texture); +} + +void Program::TextureInfo::releaseTextures() +{ + for (auto& texture : textures) + CC_SAFE_RELEASE(texture); +} + +void Program::setTexture(const std::string &name, uint32_t index, Texture *texture) +{ + TextureInfo textureInfo(name, {index}, {texture}); + _textureInfos[name] = std::move(textureInfo); +} + +void Program::setTextureArray(const std::string& name, const std::vector& indices, const std::vector textures) +{ + assert(indices.size() == textures.size()); + + TextureInfo textureInfo(name, indices, textures); + _textureInfos[name] = std::move(textureInfo); } CC_BACKEND_END diff --git a/src/backend/Program.h b/src/backend/Program.h index 5cec608..f851629 100644 --- a/src/backend/Program.h +++ b/src/backend/Program.h @@ -4,18 +4,41 @@ #include "base/CCRef.h" #include "platform/CCPlatformMacros.h" #include +#include +#include CC_BACKEND_BEGIN class ShaderModule; +class Texture; class Program : public Ref { public: + struct TextureInfo + { + TextureInfo(const std::string& _name, const std::vector& _indices, const std::vector _textures); + TextureInfo() = default; + ~TextureInfo(); + TextureInfo& operator =(TextureInfo&& rhs); + + void retainTextures(); + void releaseTextures(); + + std::string name; + std::vector indices; + std::vector textures; + }; + virtual int getUniformLocation(const std::string& uniform) = 0; + virtual void setVertexUniform(int location, void* data, uint32_t size) = 0; + virtual void setFragmentUniform(int location, void* data, uint32_t size) = 0; + virtual void setTexture(const std::string& name, uint32_t index, Texture* texture); + virtual void setTextureArray(const std::string& name, const std::vector& indices, const std::vector textures); inline ShaderModule* getVertexShader() const { return _vertexShader; } inline ShaderModule* getFragmentShader() const { return _fragmentShader; } + inline const std::unordered_map& getTextureInfos() const { return _textureInfos; } protected: Program(ShaderModule* vs, ShaderModule* fs); @@ -24,6 +47,7 @@ class Program : public Ref private: backend::ShaderModule* _vertexShader = nullptr; backend::ShaderModule* _fragmentShader = nullptr; + std::unordered_map _textureInfos; }; CC_BACKEND_END diff --git a/src/backend/RenderPipeline.cpp b/src/backend/RenderPipeline.cpp new file mode 100644 index 0000000..15a435f --- /dev/null +++ b/src/backend/RenderPipeline.cpp @@ -0,0 +1,17 @@ +#include "RenderPipeline.h" +#include "Program.h" + +CC_BACKEND_BEGIN + +RenderPipeline::RenderPipeline(Program* program) +:_program(program) +{ + CC_SAFE_RETAIN(_program); +} + +RenderPipeline::~RenderPipeline() +{ + CC_SAFE_RELEASE(_program); +} + +CC_BACKEND_END diff --git a/src/backend/RenderPipeline.h b/src/backend/RenderPipeline.h index 436e3f9..e0b5e05 100644 --- a/src/backend/RenderPipeline.h +++ b/src/backend/RenderPipeline.h @@ -6,11 +6,17 @@ #include "base/CCRef.h" CC_BACKEND_BEGIN - +class Program; class RenderPipeline : public cocos2d::Ref { +public: + RenderPipeline(Program* program); + virtual ~RenderPipeline(); + + virtual Program* getProgram() { return _program; } + protected: - virtual ~RenderPipeline() = default; + Program* _program = nullptr; }; CC_BACKEND_END diff --git a/src/backend/metal/CommandBufferMTL.h b/src/backend/metal/CommandBufferMTL.h index 58125f2..eaed0dd 100644 --- a/src/backend/metal/CommandBufferMTL.h +++ b/src/backend/metal/CommandBufferMTL.h @@ -2,7 +2,6 @@ #include "../CommandBuffer.h" #include "DeviceMTL.h" -#include "../BindGroup.h" #include CC_BACKEND_BEGIN @@ -21,7 +20,6 @@ class CommandBufferMTL : public CommandBuffer virtual void setViewport(uint32_t x, uint32_t y, uint32_t w, uint32_t h) override; virtual void setCullMode(CullMode mode) override; virtual void setVertexBuffer(uint32_t index, Buffer* buffer) override; - virtual void setBindGroup(BindGroup* bindGroup) override; virtual void setIndexBuffer(Buffer* buffer) override; virtual void drawArrays(PrimitiveType primitiveType, uint32_t start, uint32_t count) override; virtual void drawElements(PrimitiveType primitiveType, IndexFormat indexType, uint32_t count) override; @@ -33,7 +31,6 @@ class CommandBufferMTL : public CommandBuffer void setTextures() const; void doSetTextures(const std::vector& textures, bool isVertex) const; void setUniformBuffer() const; - uint32_t fillUniformBuffer(uint8_t* buffer, const std::unordered_map& unifornInfo) const; void afterDraw(); id _mtlCommandBuffer = nil; @@ -43,7 +40,6 @@ class CommandBufferMTL : public CommandBuffer DeviceMTL* _deviceMTL = nullptr; RenderPipelineMTL* _renderPipelineMTL = nullptr; - BindGroup* _bindGroup = nullptr; RenderPassDescriptor _renderPassDescriptor; }; diff --git a/src/backend/metal/CommandBufferMTL.mm b/src/backend/metal/CommandBufferMTL.mm index 070a2af..fea4e74 100644 --- a/src/backend/metal/CommandBufferMTL.mm +++ b/src/backend/metal/CommandBufferMTL.mm @@ -4,7 +4,7 @@ #include "RenderPipelineMTL.h" #include "TextureMTL.h" #include "Utils.h" -#include "../BindGroup.h" +#include "ProgramMTL.h" CC_BACKEND_BEGIN @@ -196,13 +196,6 @@ MTLCullMode toMTLCullMode(CullMode mode) atIndex:0]; } -void CommandBufferMTL::setBindGroup(BindGroup* bindGroup) -{ - CC_SAFE_RETAIN(bindGroup); - CC_SAFE_RELEASE(_bindGroup); - _bindGroup = bindGroup; -} - void CommandBufferMTL::setIndexBuffer(Buffer* buffer) { assert(buffer != nullptr); @@ -254,7 +247,6 @@ MTLCullMode toMTLCullMode(CullMode mode) _mtlIndexBuffer = nullptr; } - CC_SAFE_RELEASE_NULL(_bindGroup); } void CommandBufferMTL::prepareDrawing() const @@ -273,7 +265,7 @@ MTLCullMode toMTLCullMode(CullMode mode) void CommandBufferMTL::setTextures() const { - if (_bindGroup) + if (_renderPipelineMTL->getProgram()) { doSetTextures(_renderPipelineMTL->getVertexTextures(), true); doSetTextures(_renderPipelineMTL->getFragmentTextures(), false); @@ -282,7 +274,7 @@ MTLCullMode toMTLCullMode(CullMode mode) void CommandBufferMTL::doSetTextures(const std::vector& textures, bool isVertex) const { - const auto& bindTextureInfos = _bindGroup->getTextureInfos(); + const auto& bindTextureInfos = _renderPipelineMTL->getProgram()->getTextureInfos(); int i = 0; for (const auto& texture : textures) { @@ -315,23 +307,21 @@ MTLCullMode toMTLCullMode(CullMode mode) void CommandBufferMTL::setUniformBuffer() const { - if (_bindGroup) + if (_renderPipelineMTL->getProgram()) { // Uniform buffer is bound to index 1. const auto& vertexUniformBuffer = _renderPipelineMTL->getVertexUniformBuffer(); - const auto& vertexUniformInfo = _bindGroup->getVertexUniformInfos(); if (vertexUniformBuffer) { - uint32_t size = fillUniformBuffer(vertexUniformBuffer.get(), vertexUniformInfo); + auto size = _renderPipelineMTL->getVertexUniformBufferSize(); [_mtlRenderEncoder setVertexBytes:vertexUniformBuffer.get() length:size atIndex:1]; } const auto& fragUniformBuffer = _renderPipelineMTL->getFragmentUniformBuffer(); - const auto& fragUniformInfo = _bindGroup->getFragUniformInfos(); if (fragUniformBuffer) { - uint32_t size = fillUniformBuffer(fragUniformBuffer.get(), fragUniformInfo); + auto size = _renderPipelineMTL->getFragUniformBufferSize(); [_mtlRenderEncoder setFragmentBytes:fragUniformBuffer.get() length:size atIndex:1]; @@ -339,16 +329,4 @@ MTLCullMode toMTLCullMode(CullMode mode) } } -uint32_t CommandBufferMTL::fillUniformBuffer(uint8_t* buffer, const std::unordered_map& unifornInfo) const -{ - uint32_t offset = 0; - for(const auto& iter : unifornInfo) - { - const auto& bindUniformInfo = iter.second; - memcpy(buffer + iter.first, bindUniformInfo.data, bindUniformInfo.size); - offset += bindUniformInfo.size; - } - return offset; -} - CC_BACKEND_END diff --git a/src/backend/metal/ProgramMTL.h b/src/backend/metal/ProgramMTL.h index 4eda68f..2007393 100644 --- a/src/backend/metal/ProgramMTL.h +++ b/src/backend/metal/ProgramMTL.h @@ -12,7 +12,11 @@ class ProgramMTL : public Program ProgramMTL(ShaderModule* vs, ShaderModule* fs); virtual ~ProgramMTL(); virtual int getUniformLocation(const std::string& uniform) override; - + virtual void setVertexUniform(int location, void* data, uint32_t size) override; + virtual void setFragmentUniform(int location, void* data, uint32_t size) override; + + void fillUniformBuffer(uint8_t* buffer, uint32_t offset, void* uniformData, uint32_t uniformSize) const; + private: ShaderModuleMTL* _vertexShader = nullptr; ShaderModuleMTL* _fragmentShader = nullptr; diff --git a/src/backend/metal/ProgramMTL.mm b/src/backend/metal/ProgramMTL.mm index ed34434..69a73ce 100644 --- a/src/backend/metal/ProgramMTL.mm +++ b/src/backend/metal/ProgramMTL.mm @@ -33,4 +33,26 @@ return -1; } +void ProgramMTL::setVertexUniform(int location, void* data, uint32_t size) +{ + if(location < 0) + return; + + const auto& vertexUniformBuffer = _vertexShader->getUniformBuffer(); + fillUniformBuffer(vertexUniformBuffer.get(), location, data, size); +} + +void ProgramMTL::setFragmentUniform(int location, void* data, uint32_t size) +{ + if(location < 0) + return; + + const auto& fragUniformBuffer = _fragmentShader->getUniformBuffer(); + fillUniformBuffer(fragUniformBuffer.get(), location, data, size); +} + +void ProgramMTL::fillUniformBuffer(uint8_t* buffer, uint32_t offset, void* uniformData, uint32_t uniformSize) const +{ + memcpy(buffer + offset, uniformData, uniformSize); +} CC_BACKEND_END diff --git a/src/backend/metal/RenderPipelineMTL.h b/src/backend/metal/RenderPipelineMTL.h index 67939d3..fbd5a35 100644 --- a/src/backend/metal/RenderPipelineMTL.h +++ b/src/backend/metal/RenderPipelineMTL.h @@ -9,6 +9,7 @@ #import CC_BACKEND_BEGIN +class ProgramMTL; class RenderPipelineMTL : public RenderPipeline { @@ -23,6 +24,8 @@ class RenderPipelineMTL : public RenderPipeline inline const std::shared_ptr& getFragmentUniformBuffer() const { return _fragementUniformBuffer; } inline const std::vector& getVertexTextures() const { return _vertexTextures; } inline const std::vector& getFragmentTextures() const { return _fragmentTextures; } + inline uint32_t getVertexUniformBufferSize() const { return _vertexUniformBufferSize; } + inline uint32_t getFragUniformBufferSize() const { return _fragUniformBufferSize; } private: void setVertexLayout(MTLRenderPipelineDescriptor*, const RenderPipelineDescriptor&); @@ -34,6 +37,8 @@ class RenderPipelineMTL : public RenderPipeline id _mtlDepthStencilState = nil; id _mtlDevice = nil; + uint32_t _vertexUniformBufferSize = 0; + uint32_t _fragUniformBufferSize = 0; std::shared_ptr _vertexUniformBuffer = nullptr; std::vector _vertexTextures; diff --git a/src/backend/metal/RenderPipelineMTL.mm b/src/backend/metal/RenderPipelineMTL.mm index e6240c2..6fb891a 100644 --- a/src/backend/metal/RenderPipelineMTL.mm +++ b/src/backend/metal/RenderPipelineMTL.mm @@ -67,7 +67,8 @@ MTLVertexFormat toMTLVertexFormat(VertexFormat vertexFormat) } RenderPipelineMTL::RenderPipelineMTL(id mtlDevice, const RenderPipelineDescriptor& descriptor) -: _mtlDevice(mtlDevice) +: RenderPipeline(descriptor.program) +, _mtlDevice(mtlDevice) { _mtlRenderPipelineDescriptor = [[MTLRenderPipelineDescriptor alloc] init]; @@ -139,11 +140,13 @@ MTLVertexFormat toMTLVertexFormat(VertexFormat vertexFormat) _mtlRenderPipelineDescriptor.vertexFunction = vertexShaderModule->getMTLFunction(); _vertexUniformBuffer = vertexShaderModule->getUniformBuffer(); _vertexTextures = vertexShaderModule->getTextures(); + _vertexUniformBufferSize = vertexShaderModule->getUniformBufferSize(); auto fragShaderModule = static_cast(descriptor.program->getFragmentShader()); _mtlRenderPipelineDescriptor.fragmentFunction = fragShaderModule->getMTLFunction(); _fragementUniformBuffer = fragShaderModule->getUniformBuffer(); _fragmentTextures = fragShaderModule->getTextures(); + _fragUniformBufferSize = fragShaderModule->getUniformBufferSize(); } void RenderPipelineMTL::setBlendStateAndFormat(const RenderPipelineDescriptor& descriptor) diff --git a/src/backend/metal/ShaderModuleMTL.h b/src/backend/metal/ShaderModuleMTL.h index 97b4bd1..e8bc1a2 100644 --- a/src/backend/metal/ShaderModuleMTL.h +++ b/src/backend/metal/ShaderModuleMTL.h @@ -21,6 +21,7 @@ class ShaderModuleMTL : public ShaderModule inline const std::shared_ptr& getUniformBuffer() const { return _uniformBuffer; } inline const std::unordered_map& getUniforms() const { return _uniforms; } inline const std::vector& getTextures() const { return _textures; } + inline uint32_t getUniformBufferSize() const { return _uniformBufferSize; } private: void parseUniform(id mtlDevice, glslopt_shader* shader); @@ -30,6 +31,7 @@ class ShaderModuleMTL : public ShaderModule std::shared_ptr _uniformBuffer = nullptr; std::unordered_map _uniforms; + uint32_t _uniformBufferSize = 0; // Texture index is the same as vector index. std::vector _textures; diff --git a/src/backend/metal/ShaderModuleMTL.mm b/src/backend/metal/ShaderModuleMTL.mm index 8a90637..0f889c0 100644 --- a/src/backend/metal/ShaderModuleMTL.mm +++ b/src/backend/metal/ShaderModuleMTL.mm @@ -71,10 +71,10 @@ void ShaderModuleMTL::parseUniform(id mtlDevice, glslopt_shader* shader) { const int uniformCount = glslopt_shader_get_uniform_count(shader); - const int uniformSize = glslopt_shader_get_uniform_total_size(shader); - if (uniformSize > 0) + _uniformBufferSize = glslopt_shader_get_uniform_total_size(shader); + if (_uniformBufferSize > 0) { - std::shared_ptr sp(new uint8_t[uniformSize], [](uint8_t *p) { delete[] p; }); + std::shared_ptr sp(new uint8_t[_uniformBufferSize], [](uint8_t *p) { delete[] p; }); _uniformBuffer = sp; } for (int i = 0; i < uniformCount; ++i) diff --git a/src/backend/opengl/CommandBufferGL.cpp b/src/backend/opengl/CommandBufferGL.cpp index a9a553c..525ca07 100644 --- a/src/backend/opengl/CommandBufferGL.cpp +++ b/src/backend/opengl/CommandBufferGL.cpp @@ -3,7 +3,6 @@ #include "RenderPipelineGL.h" #include "TextureGL.h" #include "DepthStencilStateGL.h" -#include "../BindGroup.h" #include "ProgramGL.h" #include "BlendStateGL.h" #include "ccMacros.h" @@ -256,13 +255,6 @@ void CommandBufferGL::setVertexBuffer(uint32_t index, Buffer* buffer) _vertexBuffers[index] = static_cast(buffer); } -void CommandBufferGL::setBindGroup(BindGroup* bindGroup) -{ - CC_SAFE_RETAIN(bindGroup); - CC_SAFE_RELEASE(_bindGroup); - _bindGroup = bindGroup; -} - void CommandBufferGL::drawArrays(PrimitiveType primitiveType, uint32_t start, uint32_t count) { prepareDrawing(); @@ -353,35 +345,12 @@ void CommandBufferGL::bindVertexBuffer(ProgramGL *program) const void CommandBufferGL::setUniforms(ProgramGL* program) const { - if (_bindGroup) + if (program) { - const auto& texutreInfos = _bindGroup->getTextureInfos(); - const auto& vsUniformInfos = _bindGroup->getVertexUniformInfos(); - const auto& fsUniformInfos = _bindGroup->getFragUniformInfos(); + const auto& texutreInfos = program->getTextureInfos(); const auto& activeUniformInfos = program->getUniformInfos(); for (const auto& activeUinform : activeUniformInfos) { - // Set normal uniforms. - const auto& vsUniformInfo = vsUniformInfos.find(activeUinform.location); - if (vsUniformInfos.end() != vsUniformInfo) - { - setUniform(activeUinform.isArray, - activeUinform.location, - activeUinform.size, - activeUinform.type, - (*vsUniformInfo).second.data); - } - - const auto& fsUniformInfo = fsUniformInfos.find(activeUinform.location); - if (fsUniformInfos.end() != fsUniformInfo) - { - setUniform(activeUinform.isArray, - activeUinform.location, - activeUinform.size, - activeUinform.type, - (*fsUniformInfo).second.data); - } - // Bind textures. const auto& bindUniformTextureInfo = texutreInfos.find(activeUinform.name); if (texutreInfos.end() != bindUniformTextureInfo) @@ -396,112 +365,26 @@ void CommandBufferGL::setUniforms(ProgramGL* program) const ++i; } - setUniform(activeUinform.isArray, - activeUinform.location, - activeUinform.size, - activeUinform.type, - (void*)indices.data()); + switch (activeUinform.type) { + case GL_SAMPLER_2D: + case GL_SAMPLER_CUBE: + if (activeUinform.isArray) + glUniform1iv(activeUinform.location, activeUinform.size, (GLint*)indices.data()); + else + glUniform1i(activeUinform.location, *((GLint*)(indices.data()))); + break; + default: + break; + } } } } } -#define DEF_TO_INT(pointer, index) (*((GLint*)(pointer) + index)) -#define DEF_TO_FLOAT(pointer, index) (*((GLfloat*)(pointer) + index)) -void CommandBufferGL::setUniform(bool isArray, GLuint location, uint32_t size, GLenum uniformType, void* data) const -{ - GLsizei count = size; - switch (uniformType) - { - case GL_INT: - case GL_BOOL: - case GL_SAMPLER_2D: - case GL_SAMPLER_CUBE: - if (isArray) - glUniform1iv(location, count, (GLint*)data); - else - glUniform1i(location, DEF_TO_INT(data, 0)); - break; - case GL_INT_VEC2: - case GL_BOOL_VEC2: - if (isArray) - glUniform2iv(location, count, (GLint*)data); - else - glUniform2i(location, DEF_TO_INT(data, 0), DEF_TO_INT(data, 1)); - break; - case GL_INT_VEC3: - case GL_BOOL_VEC3: - if (isArray) - glUniform3iv(location, count, (GLint*)data); - else - glUniform3i(location, - DEF_TO_INT(data, 0), - DEF_TO_INT(data, 1), - DEF_TO_INT(data, 2)); - break; - case GL_INT_VEC4: - case GL_BOOL_VEC4: - if (isArray) - glUniform4iv(location, count, (GLint*)data); - else - glUniform4i(location, - DEF_TO_INT(data, 0), - DEF_TO_INT(data, 1), - DEF_TO_INT(data, 2), - DEF_TO_INT(data, 4)); - break; - case GL_FLOAT: - if (isArray) - glUniform1fv(location, count, (GLfloat*)data); - else - glUniform1f(location, DEF_TO_FLOAT(data, 0)); - break; - case GL_FLOAT_VEC2: - if (isArray) - glUniform2fv(location, count, (GLfloat*)data); - else - glUniform2f(location, DEF_TO_FLOAT(data, 0), DEF_TO_FLOAT(data, 1)); - break; - case GL_FLOAT_VEC3: - if (isArray) - glUniform3fv(location, count, (GLfloat*)data); - else - glUniform3f(location, - DEF_TO_FLOAT(data, 0), - DEF_TO_FLOAT(data, 1), - DEF_TO_FLOAT(data, 2)); - break; - case GL_FLOAT_VEC4: - if (isArray) - glUniform4fv(location, count, (GLfloat*)data); - else - glUniform4f(location, - DEF_TO_FLOAT(data, 0), - DEF_TO_FLOAT(data, 1), - DEF_TO_FLOAT(data, 2), - DEF_TO_FLOAT(data, 3)); - break; - case GL_FLOAT_MAT2: - glUniformMatrix2fv(location, count, GL_FALSE, (GLfloat*)data); - break; - case GL_FLOAT_MAT3: - glUniformMatrix3fv(location, count, GL_FALSE, (GLfloat*)data); - break; - case GL_FLOAT_MAT4: - glUniformMatrix4fv(location, count, GL_FALSE, (GLfloat*)data); - break; - break; - - default: - break; - } -} - void CommandBufferGL::cleanResources() { CC_SAFE_RELEASE_NULL(_indexBuffer); CC_SAFE_RELEASE_NULL(_renderPipeline); - CC_SAFE_RELEASE_NULL(_bindGroup); for (const auto& vertexBuffer : _vertexBuffers) CC_SAFE_RELEASE(vertexBuffer); diff --git a/src/backend/opengl/CommandBufferGL.h b/src/backend/opengl/CommandBufferGL.h index 0071d61..a6d7e5c 100644 --- a/src/backend/opengl/CommandBufferGL.h +++ b/src/backend/opengl/CommandBufferGL.h @@ -25,7 +25,6 @@ class CommandBufferGL : public CommandBuffer virtual void setViewport(uint32_t x, uint32_t y, uint32_t w, uint32_t h) override; virtual void setCullMode(CullMode mode) override; virtual void setVertexBuffer(uint32_t index, Buffer* buffer) override; - virtual void setBindGroup(BindGroup* bindGroup) override; virtual void setIndexBuffer(Buffer* buffer) override; virtual void drawArrays(PrimitiveType primitiveType, uint32_t start, uint32_t count) override; virtual void drawElements(PrimitiveType primitiveType, IndexFormat indexType, uint32_t count) override; @@ -44,7 +43,6 @@ class CommandBufferGL : public CommandBuffer void prepareDrawing() const; void bindVertexBuffer(ProgramGL* program) const; void setUniforms(ProgramGL* program) const; - void setUniform(bool isArray, GLuint location, uint32_t size, GLenum uniformType, void* data) const; void cleanResources(); void applyRenderPassDescriptor(const RenderPassDescriptor& descirptor); @@ -52,7 +50,6 @@ class CommandBufferGL : public CommandBuffer GLint _defaultFBO = 0; GLuint _currentFBO = 0; std::vector _vertexBuffers; - BindGroup* _bindGroup = nullptr; BufferGL* _indexBuffer = nullptr; RenderPipelineGL* _renderPipeline = nullptr; CullMode _cullMode = CullMode::NONE; diff --git a/src/backend/opengl/ProgramGL.cpp b/src/backend/opengl/ProgramGL.cpp index c6a9542..b0759ac 100644 --- a/src/backend/opengl/ProgramGL.cpp +++ b/src/backend/opengl/ProgramGL.cpp @@ -1,6 +1,10 @@ #include "ProgramGL.h" #include "ShaderModuleGL.h" #include "ccMacros.h" +#include "TextureGL.h" +#include +#include +#include CC_BACKEND_BEGIN @@ -55,17 +59,69 @@ namespace } return ret; } + + GLsizei getUniformSize(GLenum size) + { + GLsizei ret = 0; + switch (size) + { + case GL_BOOL: + case GL_BYTE: + case GL_UNSIGNED_BYTE: + ret = sizeof(GLbyte); + break; + case GL_BOOL_VEC2: + case GL_SHORT: + case GL_UNSIGNED_SHORT: + ret = sizeof(GLshort); + break; + case GL_BOOL_VEC3: + ret = sizeof(GLboolean); + break; + case GL_BOOL_VEC4: + case GL_INT: + case GL_UNSIGNED_INT: + case GL_FLOAT: + ret = sizeof(GLfloat); + break; + case GL_FLOAT_VEC2: + case GL_INT_VEC2: + ret = sizeof(GLfloat) * 2; + break; + case GL_FLOAT_VEC3: + case GL_INT_VEC3: + ret = sizeof(GLfloat) * 3; + break; + case GL_FLOAT_MAT2: + case GL_FLOAT_VEC4: + case GL_INT_VEC4: + ret = sizeof(GLfloat) * 4; + break; + case GL_FLOAT_MAT3: + ret = sizeof(GLfloat) * 9; + break; + case GL_FLOAT_MAT4: + ret = sizeof(GLfloat) * 16; + break; + default: + break; + } + return ret; + } } ProgramGL::ProgramGL(ShaderModule* vs, ShaderModule* fs) :Program(vs, fs) { + if(_vertexShaderModule == vs && _fragmentShaderModule == fs) + return; + _vertexShaderModule = (static_cast(vs)); _fragmentShaderModule = (static_cast(fs)); CC_SAFE_RETAIN(_vertexShaderModule); CC_SAFE_RETAIN(_fragmentShaderModule); - compileProgram(); + createProgram(); computeUniformInfos(); } @@ -77,7 +133,7 @@ ProgramGL::~ProgramGL() glDeleteProgram(_program); } -void ProgramGL::compileProgram() +void ProgramGL::createProgram() { if (_vertexShaderModule == nullptr || _fragmentShaderModule == nullptr) return; @@ -179,6 +235,13 @@ void ProgramGL::computeUniformInfos() } } + if (uniform.size > 0) + { + auto bufferSize = uniform.size * getUniformSize(uniform.type); + std::shared_ptr sp(new uint8_t[bufferSize], [](uint8_t *p) { delete[] p; }); + uniform.buffer = sp; + } + uniform.name = uniformName; uniform.location = glGetUniformLocation(_program, uniformName); @@ -192,4 +255,127 @@ int ProgramGL::getUniformLocation(const std::string& uniform) return glGetUniformLocation(_program, uniform.c_str()); } +void ProgramGL::setVertexUniform(int location, void* data, uint32_t size) +{ + setUniform(location, data, size); +} + +void ProgramGL::setFragmentUniform(int location, void* data, uint32_t size) +{ + setUniform(location, data, size); +} + +void ProgramGL::setUniform(int location, void* data, uint32_t size) +{ + if(location < 0) + return; + + glUseProgram(_program); + for(const auto& uniforn : _uniformInfos) + { + if(uniforn.location == location) + { + memcpy(uniforn.buffer.get(), data, size); + setUniform(uniforn.isArray, uniforn.location, uniforn.size, uniforn.type, uniforn.buffer.get()); + break; + } + } + glUseProgram(0); +} + +#define DEF_TO_INT(pointer, index) (*((GLint*)(pointer) + index)) +#define DEF_TO_FLOAT(pointer, index) (*((GLfloat*)(pointer) + index)) +void ProgramGL::setUniform(bool isArray, GLuint location, uint32_t size, GLenum uniformType, void* data) const +{ + GLsizei count = size; + switch (uniformType) + { + case GL_INT: + case GL_BOOL: + case GL_SAMPLER_2D: + case GL_SAMPLER_CUBE: + if (isArray) + glUniform1iv(location, count, (GLint*)data); + else + { + glUniform1i(location, DEF_TO_INT(data, 0)); + cocos2d::log("TextureID = %d\n", DEF_TO_INT(data, 0)); + } + break; + case GL_INT_VEC2: + case GL_BOOL_VEC2: + if (isArray) + glUniform2iv(location, count, (GLint*)data); + else + glUniform2i(location, DEF_TO_INT(data, 0), DEF_TO_INT(data, 1)); + break; + case GL_INT_VEC3: + case GL_BOOL_VEC3: + if (isArray) + glUniform3iv(location, count, (GLint*)data); + else + glUniform3i(location, + DEF_TO_INT(data, 0), + DEF_TO_INT(data, 1), + DEF_TO_INT(data, 2)); + break; + case GL_INT_VEC4: + case GL_BOOL_VEC4: + if (isArray) + glUniform4iv(location, count, (GLint*)data); + else + glUniform4i(location, + DEF_TO_INT(data, 0), + DEF_TO_INT(data, 1), + DEF_TO_INT(data, 2), + DEF_TO_INT(data, 4)); + break; + case GL_FLOAT: + if (isArray) + glUniform1fv(location, count, (GLfloat*)data); + else + glUniform1f(location, DEF_TO_FLOAT(data, 0)); + break; + case GL_FLOAT_VEC2: + if (isArray) + glUniform2fv(location, count, (GLfloat*)data); + else + glUniform2f(location, DEF_TO_FLOAT(data, 0), DEF_TO_FLOAT(data, 1)); + break; + case GL_FLOAT_VEC3: + if (isArray) + glUniform3fv(location, count, (GLfloat*)data); + else + glUniform3f(location, + DEF_TO_FLOAT(data, 0), + DEF_TO_FLOAT(data, 1), + DEF_TO_FLOAT(data, 2)); + break; + case GL_FLOAT_VEC4: + if (isArray) + glUniform4fv(location, count, (GLfloat*)data); + else + glUniform4f(location, + DEF_TO_FLOAT(data, 0), + DEF_TO_FLOAT(data, 1), + DEF_TO_FLOAT(data, 2), + DEF_TO_FLOAT(data, 3)); + break; + case GL_FLOAT_MAT2: + glUniformMatrix2fv(location, count, GL_FALSE, (GLfloat*)data); + break; + case GL_FLOAT_MAT3: + glUniformMatrix3fv(location, count, GL_FALSE, (GLfloat*)data); + break; + case GL_FLOAT_MAT4: + glUniformMatrix4fv(location, count, GL_FALSE, (GLfloat*)data); + break; + break; + + default: + break; + } +} + + CC_BACKEND_END diff --git a/src/backend/opengl/ProgramGL.h b/src/backend/opengl/ProgramGL.h index 5a3bcdf..8908387 100644 --- a/src/backend/opengl/ProgramGL.h +++ b/src/backend/opengl/ProgramGL.h @@ -29,6 +29,7 @@ struct UniformInfo GLuint location = 0; GLenum type = GL_FLOAT; bool isArray = false; + std::shared_ptr buffer = nullptr; }; @@ -40,13 +41,21 @@ class ProgramGL : public Program ProgramGL(ShaderModule* vs, ShaderModule* fs); ~ProgramGL(); + virtual void setVertexUniform(int location, void* data, uint32_t size) override; + virtual void setFragmentUniform(int location, void* data, uint32_t size) override; + inline const std::vector& getAttributeInfos() const { return _attributeInfos; } inline const std::vector& getUniformInfos() const { return _uniformInfos; } inline GLuint getHandler() const { return _program; } void computeAttributeInfos(const RenderPipelineDescriptor& descriptor); virtual int getUniformLocation(const std::string& uniform) override; + +protected: + void setUniform(int location, void* data, uint32_t size); + void setUniform(bool isArray, GLuint location, uint32_t size, GLenum uniformType, void* data) const; + private: - void compileProgram(); + void createProgram(); // void computeAttributeInfos(const RenderPipelineDescriptor& descriptor); bool getAttributeLocation(const std::string& attributeName, uint32_t& location); void computeUniformInfos(); diff --git a/src/backend/opengl/RenderPipelineGL.cpp b/src/backend/opengl/RenderPipelineGL.cpp index 1804fbe..8caf6bd 100644 --- a/src/backend/opengl/RenderPipelineGL.cpp +++ b/src/backend/opengl/RenderPipelineGL.cpp @@ -9,6 +9,7 @@ CC_BACKEND_BEGIN RenderPipelineGL::RenderPipelineGL(const RenderPipelineDescriptor& descriptor) +: RenderPipeline(descriptor.program) { _programGL = static_cast(descriptor.program); _programGL->computeAttributeInfos(descriptor); diff --git a/test/Test.xcodeproj/project.pbxproj b/test/Test.xcodeproj/project.pbxproj index 45921e6..0e96d71 100644 --- a/test/Test.xcodeproj/project.pbxproj +++ b/test/Test.xcodeproj/project.pbxproj @@ -118,7 +118,6 @@ 1ACB61B81FF6028F0007F081 /* tinyxml2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A69F0E31FF22B0200B224DF /* tinyxml2.cpp */; }; 1ACB61B91FF602A80007F081 /* assets in Resources */ = {isa = PBXBuildFile; fileRef = 1A69F1101FF36A4600B224DF /* assets */; }; 460373DB21363EDE00DC9ED4 /* BasicBackend.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 460373D921363EDD00DC9ED4 /* BasicBackend.cpp */; }; - 46037413214247A700DC9ED4 /* BindGroup.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 460373F9213932AE00DC9ED4 /* BindGroup.cpp */; }; 46037417214247C200DC9ED4 /* VertexLayout.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 460373B2212FA9EB00DC9ED4 /* VertexLayout.cpp */; }; 46037418214247C700DC9ED4 /* ShaderModule.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 460373C7212FEBC600DC9ED4 /* ShaderModule.cpp */; }; 46037419214247CB00DC9ED4 /* BufferGL.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 460373BA212FA9EB00DC9ED4 /* BufferGL.cpp */; }; @@ -169,7 +168,6 @@ 468BD2DB2154EB34007BCACF /* BufferMTL.mm in Sources */ = {isa = PBXBuildFile; fileRef = 468BD2D92154EB34007BCACF /* BufferMTL.mm */; }; 468BD2DF2154FCB0007BCACF /* BlendStateMTL.mm in Sources */ = {isa = PBXBuildFile; fileRef = 468BD2DD2154FCB0007BCACF /* BlendStateMTL.mm */; }; 468BD2E02154FE66007BCACF /* VertexLayout.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 460373B2212FA9EB00DC9ED4 /* VertexLayout.cpp */; }; - 468BD2E12154FE6D007BCACF /* BindGroup.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 460373F9213932AE00DC9ED4 /* BindGroup.cpp */; }; 468BD2E52154FE85007BCACF /* ShaderModule.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 460373C7212FEBC600DC9ED4 /* ShaderModule.cpp */; }; 468BD2E72154FE8D007BCACF /* Texture.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4603740A2141193F00DC9ED4 /* Texture.cpp */; }; 468BD2E82154FE92007BCACF /* DepthStencilState.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4603743C2147742800DC9ED4 /* DepthStencilState.cpp */; }; @@ -192,6 +190,8 @@ 46F9B75321B67334009DF858 /* StencilBackend.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 46233BEB2176C978000F1F21 /* StencilBackend.cpp */; }; ED3B4C43217E15C000D982A0 /* GuiProjectionBackend.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED3B4C3E217E15BF00D982A0 /* GuiProjectionBackend.cpp */; }; ED3B4C45217E15C000D982A0 /* ParticleBackend.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED3B4C41217E15C000D982A0 /* ParticleBackend.cpp */; }; + ED8D614121DE2BEC00EFB946 /* RenderPipeline.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED8D614021DE2BEC00EFB946 /* RenderPipeline.cpp */; }; + ED8D614221DE2BEC00EFB946 /* RenderPipeline.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED8D614021DE2BEC00EFB946 /* RenderPipeline.cpp */; }; EDC86F4C21DCBAE10086A0CA /* Program.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EDC86F4B21DCBAE10086A0CA /* Program.cpp */; }; EDC86F4D21DCBAE10086A0CA /* Program.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EDC86F4B21DCBAE10086A0CA /* Program.cpp */; }; EDC86F5321DDA3F00086A0CA /* ProgramMTL.mm in Sources */ = {isa = PBXBuildFile; fileRef = EDC86F5221DDA3F00086A0CA /* ProgramMTL.mm */; }; @@ -379,8 +379,6 @@ 460373D22133EA0E00DC9ED4 /* RenderPassDescriptor.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RenderPassDescriptor.h; sourceTree = ""; }; 460373D921363EDD00DC9ED4 /* BasicBackend.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = BasicBackend.cpp; sourceTree = ""; }; 460373DA21363EDD00DC9ED4 /* BasicBackend.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BasicBackend.h; sourceTree = ""; }; - 460373F9213932AE00DC9ED4 /* BindGroup.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = BindGroup.cpp; sourceTree = ""; }; - 460373FA213932AE00DC9ED4 /* BindGroup.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = BindGroup.h; sourceTree = ""; }; 46037404213FAEC600DC9ED4 /* Texture.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Texture.h; sourceTree = ""; }; 46037405213FBEFE00DC9ED4 /* TextureGL.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = TextureGL.cpp; sourceTree = ""; }; 46037406213FBEFE00DC9ED4 /* TextureGL.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TextureGL.h; sourceTree = ""; }; @@ -477,6 +475,7 @@ ED3B4C3F217E15BF00D982A0 /* ParticleBackend.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ParticleBackend.h; sourceTree = ""; }; ED3B4C40217E15C000D982A0 /* GuiProjectionBackend.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GuiProjectionBackend.h; sourceTree = ""; }; ED3B4C41217E15C000D982A0 /* ParticleBackend.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ParticleBackend.cpp; sourceTree = ""; }; + ED8D614021DE2BEC00EFB946 /* RenderPipeline.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = RenderPipeline.cpp; sourceTree = ""; }; EDC86F4A21DCBAE10086A0CA /* Program.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Program.h; sourceTree = ""; }; EDC86F4B21DCBAE10086A0CA /* Program.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Program.cpp; sourceTree = ""; }; EDC86F5121DDA3CE0086A0CA /* ProgramMTL.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ProgramMTL.h; sourceTree = ""; }; @@ -839,10 +838,9 @@ EDC86F4B21DCBAE10086A0CA /* Program.cpp */, EDC86F4A21DCBAE10086A0CA /* Program.h */, 460374512148F78600DC9ED4 /* Backend.h */, - 460373F9213932AE00DC9ED4 /* BindGroup.cpp */, - 460373FA213932AE00DC9ED4 /* BindGroup.h */, 460373D22133EA0E00DC9ED4 /* RenderPassDescriptor.h */, 460373B0212FA9EB00DC9ED4 /* RenderPipeline.h */, + ED8D614021DE2BEC00EFB946 /* RenderPipeline.cpp */, 460373C5212FE68300DC9ED4 /* RenderPipelineDescriptor.h */, 460373B1212FA9EB00DC9ED4 /* Device.h */, 461DD0E52153845000A8E43F /* Device.cpp */, @@ -1246,7 +1244,6 @@ 461F45AF217719F700D83671 /* PostProcessBackend.cpp in Sources */, 1A255E3820034B0D00069420 /* CCFileUtils.cpp in Sources */, 4603744C2148BA9900DC9ED4 /* ProgramGL.cpp in Sources */, - 46037413214247A700DC9ED4 /* BindGroup.cpp in Sources */, 4603757E214FA82D00DC9ED4 /* BlendStateGL.cpp in Sources */, 461F45B32178570700D83671 /* SubImageBackend.cpp in Sources */, 1A255E6220034B0D00069420 /* ccRandom.cpp in Sources */, @@ -1270,6 +1267,7 @@ EDC86F4D21DCBAE10086A0CA /* Program.cpp in Sources */, 4603741C214247D500DC9ED4 /* RenderPipelineGL.cpp in Sources */, 46037576214F44CD00DC9ED4 /* BlendingBackend.cpp in Sources */, + ED8D614221DE2BEC00EFB946 /* RenderPipeline.cpp in Sources */, 1A255E7220034B0D00069420 /* CCConsole.cpp in Sources */, 1A255E7020034B0D00069420 /* CCData.cpp in Sources */, 1ACB61B51FF6028B0007F081 /* ioapi_mem.cpp in Sources */, @@ -1335,6 +1333,7 @@ 466BA3B6216C79C7006C15A5 /* DepthStencilStateMTL.mm in Sources */, 1A255E6D20034B0D00069420 /* pvr.cpp in Sources */, 461DD0E62153845000A8E43F /* Device.cpp in Sources */, + ED8D614121DE2BEC00EFB946 /* RenderPipeline.cpp in Sources */, 468BD2DB2154EB34007BCACF /* BufferMTL.mm in Sources */, 1A255E6B20034B0D00069420 /* TGAlib.cpp in Sources */, 468BD2E92154FE95007BCACF /* BlendState.cpp in Sources */, @@ -1342,7 +1341,6 @@ 468BD2E02154FE66007BCACF /* VertexLayout.cpp in Sources */, 460373DB21363EDE00DC9ED4 /* BasicBackend.cpp in Sources */, 46F9B75321B67334009DF858 /* StencilBackend.cpp in Sources */, - 468BD2E12154FE6D007BCACF /* BindGroup.cpp in Sources */, 468BD2DF2154FCB0007BCACF /* BlendStateMTL.mm in Sources */, 46F9B75021B6645F009DF858 /* MultiTexturesBackend.cpp in Sources */, 1A255E5920034B0D00069420 /* Vec2.cpp in Sources */, diff --git a/test/tests/backend/BasicBackend.cpp b/test/tests/backend/BasicBackend.cpp index dc285ce..2c6ac24 100644 --- a/test/tests/backend/BasicBackend.cpp +++ b/test/tests/backend/BasicBackend.cpp @@ -104,8 +104,7 @@ void BasicBackend::tick(float dt) _commandBuffer->setViewport(0, 0, utils::WINDOW_WIDTH, utils::WINDOW_HEIGHT); _commandBuffer->setRenderPipeline(_renderPipeline); _commandBuffer->setVertexBuffer(0, _vertexBuffer); - _bindGroup.setFragmentUniform(_colorLocation, "color", color, sizeof(color)); - _commandBuffer->setBindGroup(&_bindGroup); + _renderPipeline->getProgram()->setFragmentUniform(_colorLocation, color, sizeof(color)); _commandBuffer->drawArrays(cocos2d::backend::PrimitiveType::TRIANGLE, 0, 3); _commandBuffer->endRenderPass(); _commandBuffer->endFrame(); diff --git a/test/tests/backend/BasicBackend.h b/test/tests/backend/BasicBackend.h index 54d2060..11182e2 100644 --- a/test/tests/backend/BasicBackend.h +++ b/test/tests/backend/BasicBackend.h @@ -29,7 +29,6 @@ #include "backend/Buffer.h" #include "backend/CommandBuffer.h" #include "backend/RenderPipeline.h" -#include "backend/BindGroup.h" class BasicBackend : public TestBaseI { @@ -43,7 +42,6 @@ class BasicBackend : public TestBaseI cocos2d::backend::CommandBuffer* _commandBuffer = nullptr; cocos2d::backend::Buffer* _vertexBuffer = nullptr; cocos2d::backend::RenderPipeline* _renderPipeline = nullptr; - cocos2d::backend::BindGroup _bindGroup; cocos2d::backend::RenderPassDescriptor _renderPassDescriptor; int _colorLocation = -1; float _time; diff --git a/test/tests/backend/BlendingBackend.cpp b/test/tests/backend/BlendingBackend.cpp index a29dd99..4aea658 100644 --- a/test/tests/backend/BlendingBackend.cpp +++ b/test/tests/backend/BlendingBackend.cpp @@ -169,6 +169,7 @@ namespace inline int getModelLocation() const { return _modelLocation; } inline int getProjectionLocation() const { return _projectionLocation; } + inline backend::Program* getProgram() { return renderPipelineNoBlending->getProgram(); } backend::RenderPipeline* renderPipelineNoBlending = nullptr; backend::RenderPipeline* renderPipelineNormal = nullptr; @@ -247,6 +248,7 @@ namespace } inline int getTimeLocation() const { return _timeLocation; } + inline backend::Program* getProgram() { return renderPipeline->getProgram(); } backend::RenderPipeline* renderPipeline = nullptr; backend::Buffer* vertexBuffer = nullptr; @@ -293,6 +295,7 @@ BlendingBackend::BlendingBackend() textureDescriptorBackgroud.textureFormat = backend::TextureFormat::R8G8B8A8; _backgroud = device->newTexture(textureDescriptorBackgroud); _backgroud->updateData(utils::loadData("assets/background.png").getBytes()); + bigTriangle->getProgram()->setTexture("texture", 0, _backgroud); backend::TextureDescriptor textureDescriptorSprite0; textureDescriptorSprite0.width = 128; @@ -300,6 +303,7 @@ BlendingBackend::BlendingBackend() textureDescriptorSprite0.textureFormat = backend::TextureFormat::R8G8B8A8; _sprite0 = device->newTexture(textureDescriptorSprite0); _sprite0->updateData(utils::loadData("assets/sprite0.png").getBytes()); + quad->getProgram()->setTexture("texture", 0, _sprite0); _commandBuffer = device->newCommandBuffer(); @@ -340,9 +344,7 @@ void BlendingBackend::tick(float dt) _commandBuffer->setViewport(0, 0, utils::WINDOW_WIDTH, utils::WINDOW_HEIGHT); _commandBuffer->setRenderPipeline(bigTriangle->renderPipeline); - _bindGroupBigTriangle.setFragmentUniform(bigTriangle->getTimeLocation(), "time", &_dt, sizeof(_dt)); - _bindGroupBigTriangle.setTexture("texture", 0, _backgroud); - _commandBuffer->setBindGroup(&_bindGroupBigTriangle); + bigTriangle->getProgram()->setFragmentUniform(bigTriangle->getTimeLocation(), &_dt, sizeof(_dt)); _commandBuffer->setVertexBuffer(0, bigTriangle->vertexBuffer); _commandBuffer->drawArrays(cocos2d::backend::PrimitiveType::TRIANGLE, 0, 3); @@ -363,10 +365,9 @@ void BlendingBackend::tick(float dt) float offsetX = 5.f + hsize; float offsetY = 5.f + hsize; _model = std::move(createModel(cocos2d::Vec3(offsetX, offsetY, 0), cocos2d::Vec3(size, size, 0))); - _bindGroup.setVertexUniform(quad->getModelLocation(), "model", _model.m, sizeof(_model.m)); - _bindGroup.setVertexUniform(quad->getProjectionLocation(), "projection", _projection.m, sizeof(_projection.m)); - _bindGroup.setTexture("texture", 0, _sprite0); - _commandBuffer->setBindGroup(&_bindGroup); + auto programQuad = quad->getProgram(); + programQuad->setVertexUniform(quad->getModelLocation(), _model.m, sizeof(_model.m)); + programQuad->setVertexUniform(quad->getProjectionLocation(), _projection.m, sizeof(_projection.m)); _commandBuffer->setVertexBuffer(0, quad->vertexBuffer); _commandBuffer->setIndexBuffer(quad->indexBuffer); @@ -382,10 +383,8 @@ void BlendingBackend::tick(float dt) offsetY = offsetY + 5.f + size; _model = std::move(createModel(cocos2d::Vec3(offsetX, offsetY, 0), cocos2d::Vec3(size, size, 0))); - _bindGroup.setVertexUniform(quad->getModelLocation(), "model", _model.m, sizeof(_model.m)); - _bindGroup.setVertexUniform(quad->getProjectionLocation(), "projection", _projection.m, sizeof(_projection.m)); - _bindGroup.setTexture("texture", 0, _sprite0); - _commandBuffer->setBindGroup(&_bindGroup); + programQuad->setVertexUniform(quad->getModelLocation(), _model.m, sizeof(_model.m)); + programQuad->setVertexUniform(quad->getProjectionLocation(), _projection.m, sizeof(_projection.m)); _commandBuffer->setVertexBuffer(0, quad->vertexBuffer); _commandBuffer->setIndexBuffer(quad->indexBuffer); @@ -401,10 +400,8 @@ void BlendingBackend::tick(float dt) offsetY = offsetY + 5.f + size; _model = std::move(createModel(cocos2d::Vec3(offsetX, offsetY, 0), cocos2d::Vec3(size, size, 0))); - _bindGroup.setVertexUniform(quad->getModelLocation(), "model", _model.m, sizeof(_model.m)); - _bindGroup.setVertexUniform(quad->getProjectionLocation(), "projection", _projection.m, sizeof(_projection.m)); - _bindGroup.setTexture("texture", 0, _sprite0); - _commandBuffer->setBindGroup(&_bindGroup); + programQuad->setVertexUniform(quad->getModelLocation(), _model.m, sizeof(_model.m)); + programQuad->setVertexUniform(quad->getProjectionLocation(), _projection.m, sizeof(_projection.m)); _commandBuffer->setVertexBuffer(0, quad->vertexBuffer); _commandBuffer->setIndexBuffer(quad->indexBuffer); @@ -420,10 +417,8 @@ void BlendingBackend::tick(float dt) offsetY = offsetY + 5.f + size; _model = std::move(createModel(cocos2d::Vec3(offsetX, offsetY, 0), cocos2d::Vec3(size, size, 0))); - _bindGroup.setVertexUniform(quad->getModelLocation(), "model", _model.m, sizeof(_model.m)); - _bindGroup.setVertexUniform(quad->getProjectionLocation(), "projection", _projection.m, sizeof(_projection.m)); - _bindGroup.setTexture("texture", 0, _sprite0); - _commandBuffer->setBindGroup(&_bindGroup); + programQuad->setVertexUniform(quad->getModelLocation(), _model.m, sizeof(_model.m)); + programQuad->setVertexUniform(quad->getProjectionLocation(), _projection.m, sizeof(_projection.m)); _commandBuffer->setVertexBuffer(0, quad->vertexBuffer); _commandBuffer->setIndexBuffer(quad->indexBuffer); @@ -439,10 +434,8 @@ void BlendingBackend::tick(float dt) offsetY = offsetY + 5.f + size; _model = std::move(createModel(cocos2d::Vec3(offsetX, offsetY, 0), cocos2d::Vec3(size, size, 0))); - _bindGroup.setVertexUniform(quad->getModelLocation(), "model", _model.m, sizeof(_model.m)); - _bindGroup.setVertexUniform(quad->getProjectionLocation(), "projection", _projection.m, sizeof(_projection.m)); - _bindGroup.setTexture("texture", 0, _sprite0); - _commandBuffer->setBindGroup(&_bindGroup); + programQuad->setVertexUniform(quad->getModelLocation(), _model.m, sizeof(_model.m)); + programQuad->setVertexUniform(quad->getProjectionLocation(), _projection.m, sizeof(_projection.m)); _commandBuffer->setVertexBuffer(0, quad->vertexBuffer); _commandBuffer->setIndexBuffer(quad->indexBuffer); diff --git a/test/tests/backend/BlendingBackend.h b/test/tests/backend/BlendingBackend.h index 32ac2ee..c3f63c1 100644 --- a/test/tests/backend/BlendingBackend.h +++ b/test/tests/backend/BlendingBackend.h @@ -43,9 +43,6 @@ class BlendingBackend : public TestBaseI cocos2d::backend::Texture* _sprite0 = nullptr; cocos2d::backend::CommandBuffer* _commandBuffer = nullptr; cocos2d::backend::RenderPassDescriptor _renderPassDescriptorBigTriangle; - cocos2d::backend::BindGroup _bindGroupBigTriangle; - - cocos2d::backend::BindGroup _bindGroup; cocos2d::Mat4 _projection; cocos2d::Mat4 _model; diff --git a/test/tests/backend/BunnyBackend.cpp b/test/tests/backend/BunnyBackend.cpp index 02bd66a..42f72c4 100644 --- a/test/tests/backend/BunnyBackend.cpp +++ b/test/tests/backend/BunnyBackend.cpp @@ -102,11 +102,11 @@ BunnyBackend::BunnyBackend() _renderPassDescriptor.needDepthAttachment = true; // bind group - _bindGroup.setVertexUniform(_modelLocation, "model", _model.m, sizeof(_model.m)); + _renderPipeline->getProgram()->setVertexUniform(_modelLocation, _model.m, sizeof(_model.m)); Mat4::createPerspective(60.0f, 1.0f * utils::WINDOW_WIDTH / utils::WINDOW_HEIGHT, 0.01f, 1000.0f, &_projection); - _bindGroup.setVertexUniform(_projectionLocation, "projection", _projection.m, sizeof(_projection.m)); + _renderPipeline->getProgram()->setVertexUniform(_projectionLocation, _projection.m, sizeof(_projection.m)); float color[4] = {0.5f, 0.5f, 0.5f, 1.0f}; - _bindGroup.setFragmentUniform(_colorLocation, "color", color, sizeof(color)); + _renderPipeline->getProgram()->setFragmentUniform(_colorLocation, color, sizeof(color)); // vertex buffer _vertexBuffer = device->newBuffer(sizeof(bunny_positions), @@ -136,7 +136,7 @@ void BunnyBackend::tick(float dt) _time += dt; Mat4::createLookAt(Vec3(30.0f * std::cos(_time), 20.0f, 30.0f * std::sin(_time)), Vec3(0.0f, 2.5f, 0.0f), Vec3(0.0f, 1.0f, 0.f), &_view); - _bindGroup.setVertexUniform(_viewLocation, "view", _view.m, sizeof(_view.m)); + _renderPipeline->getProgram()->setVertexUniform(_viewLocation, _view.m, sizeof(_view.m)); _commandBuffer->beginFrame(); @@ -145,7 +145,6 @@ void BunnyBackend::tick(float dt) _commandBuffer->setRenderPipeline(_renderPipeline); _commandBuffer->setVertexBuffer(0, _vertexBuffer); _commandBuffer->setIndexBuffer(_indexBuffer); - _commandBuffer->setBindGroup(&_bindGroup); _commandBuffer->drawElements(cocos2d::backend::PrimitiveType::TRIANGLE, cocos2d::backend::IndexFormat::U_SHORT, sizeof(bunny_cells) / sizeof(bunny_cells[0])); diff --git a/test/tests/backend/BunnyBackend.h b/test/tests/backend/BunnyBackend.h index 9fb27da..1561072 100644 --- a/test/tests/backend/BunnyBackend.h +++ b/test/tests/backend/BunnyBackend.h @@ -29,7 +29,6 @@ #include "backend/Buffer.h" #include "backend/CommandBuffer.h" #include "backend/DepthStencilState.h" -#include "backend/BindGroup.h" #include "math/Mat4.h" @@ -46,7 +45,6 @@ class BunnyBackend : public TestBaseI cocos2d::backend::Buffer* _indexBuffer = nullptr; cocos2d::backend::CommandBuffer* _commandBuffer = nullptr; cocos2d::backend::RenderPassDescriptor _renderPassDescriptor; - cocos2d::backend::BindGroup _bindGroup; cocos2d::backend::RenderPipeline* _renderPipeline = nullptr; cocos2d::Mat4 _model; diff --git a/test/tests/backend/DepthTextureBackend.cpp b/test/tests/backend/DepthTextureBackend.cpp index 672be80..3331224 100644 --- a/test/tests/backend/DepthTextureBackend.cpp +++ b/test/tests/backend/DepthTextureBackend.cpp @@ -105,6 +105,7 @@ namespace inline int getNearLocation() const { return _nearLocation; } inline int getFarLocaiton() const { return _farLocation; } + inline backend::Program* getProgram() { return renderPipeline->getProgram(); } backend::RenderPipeline* renderPipeline = nullptr; backend::Buffer* vertexBuffer = nullptr; @@ -198,6 +199,7 @@ namespace inline int getModelLocation() const { return _modelLocation; } inline int getViewLocation() const { return _viewLocation; } inline int getProjectionLocation() const { return _projectionLocation; } + inline backend::Program* getProgram() { return renderPipeline->getProgram(); } backend::Buffer* vertexBuffer = nullptr; backend::Buffer* indexBuffer = nullptr; @@ -215,6 +217,8 @@ namespace DepthTextureBackend::DepthTextureBackend() : _t(0.0f) { + bunny = new Bunny(); + bg = new BigTriangle(); auto device = backend::Device::getInstance(); // depth texture @@ -230,6 +234,7 @@ DepthTextureBackend::DepthTextureBackend() textureDescriptor.samplerDescriptor = samplerDescriptor; textureDescriptor.textureFormat = backend::TextureFormat::D24S8; _depthTexture = device->newTexture(textureDescriptor); + bg->getProgram()->setTexture("texture", 0, _depthTexture); // render pass Bunny 1 _renderPassBunny1.clearDepthValue = 1; @@ -252,9 +257,6 @@ DepthTextureBackend::DepthTextureBackend() _renderPassBigTriangle.needColorAttachment = true; _commandBuffer = device->newCommandBuffer(); - - bunny = new Bunny(); - bg = new BigTriangle(); } DepthTextureBackend::~DepthTextureBackend() @@ -288,10 +290,10 @@ void DepthTextureBackend::tick(float dt) _model = Mat4::IDENTITY; _model.translate(5, 0, 0); - _bindGroupBunny.setVertexUniform(bunny->getModelLocation(), "model", _model.m, sizeof(_model.m)); - _bindGroupBunny.setVertexUniform(bunny->getViewLocation(), "view", _view.m, sizeof(_view.m)); - _bindGroupBunny.setVertexUniform(bunny->getProjectionLocation(), "projection", _projection.m, sizeof(_projection.m)); - _commandBuffer->setBindGroup(&_bindGroupBunny); + + bunny->getProgram()->setVertexUniform(bunny->getModelLocation(), _model.m, sizeof(_model.m)); + bunny->getProgram()->setVertexUniform(bunny->getViewLocation(), _view.m, sizeof(_view.m)); + bunny->getProgram()->setVertexUniform(bunny->getProjectionLocation(), _projection.m, sizeof(_projection.m)); _commandBuffer->drawElements(cocos2d::backend::PrimitiveType::TRIANGLE, cocos2d::backend::IndexFormat::U_SHORT, @@ -305,10 +307,9 @@ void DepthTextureBackend::tick(float dt) _model = Mat4::IDENTITY; _model.translate(-5, 0, 0); - _bindGroupBunny.setVertexUniform(bunny->getModelLocation(), "model", _model.m, sizeof(_model.m)); - _bindGroupBunny.setVertexUniform(bunny->getViewLocation(), "view", _view.m, sizeof(_view.m)); - _bindGroupBunny.setVertexUniform(bunny->getProjectionLocation(), "projection", _projection.m, sizeof(_projection.m)); - _commandBuffer->setBindGroup(&_bindGroupBunny); + bunny->getProgram()->setVertexUniform(bunny->getModelLocation(), _model.m, sizeof(_model.m)); + bunny->getProgram()->setVertexUniform(bunny->getViewLocation(), _view.m, sizeof(_view.m)); + bunny->getProgram()->setVertexUniform(bunny->getProjectionLocation(), _projection.m, sizeof(_projection.m)); _commandBuffer->drawElements(cocos2d::backend::PrimitiveType::TRIANGLE, cocos2d::backend::IndexFormat::U_SHORT, @@ -321,12 +322,10 @@ void DepthTextureBackend::tick(float dt) _commandBuffer->setRenderPipeline(bg->renderPipeline); _commandBuffer->setVertexBuffer(0, bg->vertexBuffer); - _bindGroupBigTriangle.setTexture("texture", 0, _depthTexture); float near = 0.1f; float far = 100.f; - _bindGroupBigTriangle.setFragmentUniform(bg->getNearLocation(), "near", &near, sizeof(float)); - _bindGroupBigTriangle.setFragmentUniform(bg->getFarLocaiton(), "far", &far, sizeof(float)); - _commandBuffer->setBindGroup(&_bindGroupBigTriangle); + bg->getProgram()->setFragmentUniform(bg->getNearLocation(), &near, sizeof(float)); + bg->getProgram()->setFragmentUniform(bg->getFarLocaiton(), &far, sizeof(float)); _commandBuffer->drawArrays(cocos2d::backend::PrimitiveType::TRIANGLE, 0, 6); _commandBuffer->endRenderPass(); diff --git a/test/tests/backend/DepthTextureBackend.h b/test/tests/backend/DepthTextureBackend.h index 0511945..96a97e5 100644 --- a/test/tests/backend/DepthTextureBackend.h +++ b/test/tests/backend/DepthTextureBackend.h @@ -50,7 +50,5 @@ class DepthTextureBackend : public TestBaseI cocos2d::backend::RenderPassDescriptor _renderPassBunny1; cocos2d::backend::RenderPassDescriptor _renderPassBunny2; cocos2d::backend::RenderPassDescriptor _renderPassBigTriangle; - cocos2d::backend::BindGroup _bindGroupBunny; - cocos2d::backend::BindGroup _bindGroupBigTriangle; cocos2d::backend::CommandBuffer* _commandBuffer = nullptr; }; diff --git a/test/tests/backend/GuiProjectionBackend.cpp b/test/tests/backend/GuiProjectionBackend.cpp index 84b5861..e73441f 100644 --- a/test/tests/backend/GuiProjectionBackend.cpp +++ b/test/tests/backend/GuiProjectionBackend.cpp @@ -100,6 +100,7 @@ GuiProjectionBackend::GuiProjectionBackend() textureDescriptor.height = img->getHeight(); _texture = device->newTexture(textureDescriptor); _texture->updateData(data.getBytes()); + _renderPipeline->getProgram()->setTexture("texture", 0, _texture); img->release(); @@ -144,19 +145,16 @@ void GuiProjectionBackend::tick(float dt) _commandBuffer->beginRenderPass(_renderPassDescriptor); _commandBuffer->setRenderPipeline(_renderPipeline); _commandBuffer->setViewport(0, 0, utils::WINDOW_WIDTH, utils::WINDOW_HEIGHT); - + auto program = _renderPipeline->getProgram(); if (_texture) { - _bindGroup.setTexture("texture", 0, _texture); - // translation _commandBuffer->setCullMode(backend::CullMode::NONE); _commandBuffer->setVertexBuffer(0, _vertexBuffer); float redColor[4] = {1, 0, 0, 1}; - _bindGroup.setFragmentUniform(_colorLocation, "color", redColor, sizeof(redColor)); - _bindGroup.setVertexUniform(_projectionLocation, "projection", _projection.m, sizeof(_projection.m)); - _bindGroup.setVertexUniform(_transformLocation, "transform", _translantion.m, sizeof(_translantion.m)); + program->setFragmentUniform(_colorLocation, redColor, sizeof(redColor)); + program->setVertexUniform(_projectionLocation, _projection.m, sizeof(_projection.m)); + program->setVertexUniform(_transformLocation, _translantion.m, sizeof(_translantion.m)); - _commandBuffer->setBindGroup(&_bindGroup); _commandBuffer->drawArrays(backend::PrimitiveType::TRIANGLE, 0, _vertexBufferElementCount); // rotation @@ -164,11 +162,10 @@ void GuiProjectionBackend::tick(float dt) _commandBuffer->setCullMode(backend::CullMode::NONE); _commandBuffer->setVertexBuffer(0, _vertexBuffer); float greenColor[4] = {0, 1, 0, 1}; - _bindGroup.setFragmentUniform(_colorLocation, "color", greenColor, sizeof(greenColor)); - _bindGroup.setVertexUniform(_projectionLocation, "projection", _projection.m, sizeof(_projection.m)); - _bindGroup.setVertexUniform(_transformLocation, "transform", _rotation.m, sizeof(_rotation.m)); + program->setFragmentUniform(_colorLocation, greenColor, sizeof(greenColor)); + program->setVertexUniform(_projectionLocation, _projection.m, sizeof(_projection.m)); + program->setVertexUniform(_transformLocation, _rotation.m, sizeof(_rotation.m)); - _commandBuffer->setBindGroup(&_bindGroup); _commandBuffer->drawArrays(backend::PrimitiveType::TRIANGLE, 0, _vertexBufferElementCount); @@ -177,11 +174,10 @@ void GuiProjectionBackend::tick(float dt) _commandBuffer->setCullMode(backend::CullMode::NONE); _commandBuffer->setVertexBuffer(0, _vertexBuffer); float blueColor[4] = {0, 0, 1, 1}; - _bindGroup.setFragmentUniform(_colorLocation, "color", blueColor, sizeof(blueColor)); - _bindGroup.setVertexUniform(_projectionLocation, "projection", _projection.m, sizeof(_projection.m)); - _bindGroup.setVertexUniform(_transformLocation, "transform", _scale.m, sizeof(_scale.m)); + program->setFragmentUniform(_colorLocation, blueColor, sizeof(blueColor)); + program->setVertexUniform(_projectionLocation, _projection.m, sizeof(_projection.m)); + program->setVertexUniform(_transformLocation, _scale.m, sizeof(_scale.m)); - _commandBuffer->setBindGroup(&_bindGroup); _commandBuffer->drawArrays(backend::PrimitiveType::TRIANGLE, 0, _vertexBufferElementCount); } diff --git a/test/tests/backend/GuiProjectionBackend.h b/test/tests/backend/GuiProjectionBackend.h index c404776..794d32b 100644 --- a/test/tests/backend/GuiProjectionBackend.h +++ b/test/tests/backend/GuiProjectionBackend.h @@ -41,7 +41,6 @@ class GuiProjectionBackend : public TestBaseI cocos2d::backend::Texture *_texture = nullptr; cocos2d::backend::CommandBuffer* _commandBuffer = nullptr; cocos2d::backend::RenderPipeline* _renderPipeline = nullptr; - cocos2d::backend::BindGroup _bindGroup; cocos2d::backend::RenderPassDescriptor _renderPassDescriptor; uint32_t _vertexBufferElementCount = 0; diff --git a/test/tests/backend/MultiTexturesBackend.cpp b/test/tests/backend/MultiTexturesBackend.cpp index 799fe6f..f1c9161 100644 --- a/test/tests/backend/MultiTexturesBackend.cpp +++ b/test/tests/backend/MultiTexturesBackend.cpp @@ -94,6 +94,7 @@ MultiTexturesBackend::MultiTexturesBackend() textureDescriptor1.textureFormat = backend::TextureFormat::R8G8B8; _texture1 = device->newTexture(textureDescriptor1); _texture1->updateData(utils::loadData("assets/uv_checker_01.jpg").getBytes()); + _renderPipeline->getProgram()->setTexture("texture2", 7, _texture1); int dataSize = 512 * 512 * 3; uint8_t data[dataSize]; @@ -109,7 +110,8 @@ MultiTexturesBackend::MultiTexturesBackend() textureDescriptor2.textureFormat = backend::TextureFormat::R8G8B8; _background = device->newTexture(textureDescriptor2); _background->updateData(data); - + _renderPipeline->getProgram()->setTexture("texture1", 6, _background); + _transform = cocos2d::Mat4::IDENTITY; _transform.translate(0, 0, 0); _transform.scale(0.5, 0.5, 0.5); @@ -143,12 +145,9 @@ void MultiTexturesBackend::tick(float dt) _commandBuffer->setVertexBuffer(0, _vertexBuffer); float color[4] = {1.f, 0, 0, 1.f}; - _bindGroup.setFragmentUniform(_colorLocation, "color", color, sizeof(color)); - _bindGroup.setVertexUniform(_transformLocation, "transform", _transform.m, sizeof(_transform.m)); -// _bindGroup.setTextureArray("texture", {6, 7}, {_background, _texture1}); - _bindGroup.setTexture("texture1", 6, _background); - _bindGroup.setTexture("texture2", 7, _texture1); - _commandBuffer->setBindGroup(&_bindGroup); + auto program = _renderPipeline->getProgram(); + program->setFragmentUniform(_colorLocation, color, sizeof(color)); + program->setVertexUniform(_transformLocation, _transform.m, sizeof(_transform.m)); _commandBuffer->setVertexBuffer(0, _vertexBuffer); _commandBuffer->drawArrays(cocos2d::backend::PrimitiveType::TRIANGLE, 0, 6); diff --git a/test/tests/backend/MultiTexturesBackend.h b/test/tests/backend/MultiTexturesBackend.h index dca699c..f8967fa 100644 --- a/test/tests/backend/MultiTexturesBackend.h +++ b/test/tests/backend/MultiTexturesBackend.h @@ -43,7 +43,6 @@ class MultiTexturesBackend : public TestBaseI cocos2d::backend::RenderPipeline* _renderPipeline = nullptr; cocos2d::backend::CommandBuffer* _commandBuffer = nullptr; cocos2d::backend::RenderPassDescriptor _renderPassDescriptor; - cocos2d::backend::BindGroup _bindGroup; cocos2d::Mat4 _transform; diff --git a/test/tests/backend/ParticleBackend.cpp b/test/tests/backend/ParticleBackend.cpp index 4a17ee4..792c3aa 100644 --- a/test/tests/backend/ParticleBackend.cpp +++ b/test/tests/backend/ParticleBackend.cpp @@ -131,6 +131,7 @@ ParticleBackend::ParticleBackend() textureDescriptor.samplerDescriptor.mipmapEnabled = true; _texture = device->newTexture(textureDescriptor); _texture->updateData(imageData.getBytes()); + _renderPipelineWithBlend->getProgram()->setTexture("u_texture", 0, _texture); _commandBuffer = device->newCommandBuffer(); _vertexBuffer = device->newBuffer(sizeof(_vbufferArray), backend::BufferType::VERTEX, backend::BufferUsage::READ); @@ -227,12 +228,10 @@ void ParticleBackend::tick(float dt) } } _vertexBuffer->updateData(_vbufferArray, sizeof(_vbufferArray)); - - _bindGroup.setVertexUniform(_modelLocation, "model", _model.m, sizeof(_model.m)); - _bindGroup.setVertexUniform(_viewLocation, "view", _view.m, sizeof(_view.m)); - _bindGroup.setVertexUniform(_projectionLocation, "projection", _projection.m, sizeof(_projection.m)); - _bindGroup.setTexture("u_texture", 0, _texture); - _commandBuffer->setBindGroup(&_bindGroup); + auto program = _renderPipelineWithBlend->getProgram(); + program->setVertexUniform(_modelLocation, _model.m, sizeof(_model.m)); + program->setVertexUniform(_viewLocation, _view.m, sizeof(_view.m)); + program->setVertexUniform(_projectionLocation, _projection.m, sizeof(_projection.m)); _commandBuffer->setVertexBuffer(0, _vertexBuffer); _commandBuffer->setIndexBuffer(_indexBuffer); diff --git a/test/tests/backend/ParticleBackend.h b/test/tests/backend/ParticleBackend.h index a08a4a8..7189100 100644 --- a/test/tests/backend/ParticleBackend.h +++ b/test/tests/backend/ParticleBackend.h @@ -42,7 +42,6 @@ class ParticleBackend : public TestBaseI cocos2d::backend::RenderPipeline* _renderPipelineWithBlend = nullptr; cocos2d::backend::CommandBuffer* _commandBuffer = nullptr; cocos2d::backend::Texture* _texture = nullptr; - cocos2d::backend::BindGroup _bindGroup; cocos2d::backend::RenderPassDescriptor _renderPassDescriptor; cocos2d::Mat4 _model; diff --git a/test/tests/backend/PostProcessBackend.cpp b/test/tests/backend/PostProcessBackend.cpp index c906af4..bed2e81 100644 --- a/test/tests/backend/PostProcessBackend.cpp +++ b/test/tests/backend/PostProcessBackend.cpp @@ -115,6 +115,8 @@ namespace CC_SAFE_RELEASE(_renderPipeline); } + inline cocos2d::backend::Program* getProgram() { return _renderPipeline->getProgram(); } + backend::Buffer* _vertexBuffer = nullptr; backend::RenderPipeline* _renderPipeline = nullptr; }; @@ -205,6 +207,7 @@ namespace inline int getViewLocaiton() const { return _viewLocation; } inline int getProjectionLocaiton() const { return _projectionLocation; } inline int getColorLocaiton() const { return _colorLocation; } + inline backend::Program* getProgram() { return _renderPipeline->getProgram(); } backend::Buffer* _vertexBuffer = nullptr; backend::Buffer* _indexBuffer = nullptr; @@ -223,6 +226,9 @@ namespace PostProcessBackend::PostProcessBackend() : _t(0.0f) { + bunny = new Bunny(); + bg = new BigTriangle(); + auto device = backend::Device::getInstance(); backend::TextureDescriptor textureDescriptor; @@ -263,9 +269,6 @@ PostProcessBackend::PostProcessBackend() _renderPassDescriptorBg.needDepthAttachment = true; _commandBuffer = device->newCommandBuffer(); - - bunny = new Bunny(); - bg = new BigTriangle(); } PostProcessBackend::~PostProcessBackend() @@ -304,13 +307,11 @@ void PostProcessBackend::tick(float dt) _commandBuffer->setVertexBuffer(0, bunny->_vertexBuffer); _commandBuffer->setIndexBuffer(bunny->_indexBuffer); - _bindGroup.setVertexUniform(bunny->getModelLocaiton(), "model", _model.m, sizeof(_model.m)); - _bindGroup.setVertexUniform(bunny->getViewLocaiton(), "view", _view.m, sizeof(_view.m)); - _bindGroup.setVertexUniform(bunny->getProjectionLocaiton(), "projection", _projection.m, sizeof(_projection.m)); + bunny->getProgram()->setVertexUniform(bunny->getModelLocaiton(), _model.m, sizeof(_model.m)); + bunny->getProgram()->setVertexUniform(bunny->getViewLocaiton(), _view.m, sizeof(_view.m)); + bunny->getProgram()->setVertexUniform(bunny->getProjectionLocaiton(), _projection.m, sizeof(_projection.m)); float color[4] = {0.1f, 0.1f, 0.1f, 1}; - _bindGroup.setFragmentUniform(bunny->getColorLocaiton(), "color", color, sizeof(color)); - _commandBuffer->setBindGroup(&_bindGroup); - + bunny->getProgram()->setFragmentUniform(bunny->getColorLocaiton(), color, sizeof(color)); _commandBuffer->drawElements(backend::PrimitiveType::TRIANGLE, backend::IndexFormat::U_SHORT, sizeof(bunny_cells) / sizeof(bunny_cells[0])); @@ -325,12 +326,11 @@ void PostProcessBackend::tick(float dt) _commandBuffer->setVertexBuffer(0, bunny->_vertexBuffer); _commandBuffer->setIndexBuffer(bunny->_indexBuffer); - _bindGroup.setVertexUniform(bunny->getModelLocaiton(), "model", _model.m, sizeof(_model.m)); - _bindGroup.setVertexUniform(bunny->getViewLocaiton(), "view", _view.m, sizeof(_view.m)); - _bindGroup.setVertexUniform(bunny->getProjectionLocaiton(), "projection", _projection.m, sizeof(_projection.m)); + bunny->getProgram()->setVertexUniform(bunny->getModelLocaiton(), _model.m, sizeof(_model.m)); + bunny->getProgram()->setVertexUniform(bunny->getViewLocaiton(), _view.m, sizeof(_view.m)); + bunny->getProgram()->setVertexUniform(bunny->getProjectionLocaiton(), _projection.m, sizeof(_projection.m)); float color2[4] = {0.3f, 0.3f, 0.3f, 1}; - _bindGroup.setFragmentUniform(bunny->getColorLocaiton(), "color", color2 , sizeof(color2)); - _commandBuffer->setBindGroup(&_bindGroup); + bunny->getProgram()->setFragmentUniform(bunny->getColorLocaiton(), color2 , sizeof(color2)); _commandBuffer->drawElements(backend::PrimitiveType::TRIANGLE, backend::IndexFormat::U_SHORT, @@ -340,10 +340,7 @@ void PostProcessBackend::tick(float dt) // Draw bg. _commandBuffer->beginRenderPass(_renderPassDescriptorBg); - - _bindGroup.setTexture("texture", 0, _colorTexture); - _commandBuffer->setBindGroup(&_bindGroup); - + bg->getProgram()->setTexture("texture", 0, _colorTexture); _commandBuffer->setRenderPipeline(bg->_renderPipeline); _commandBuffer->setVertexBuffer(0, bg->_vertexBuffer); _commandBuffer->drawArrays(backend::PrimitiveType::TRIANGLE, 0, 3); diff --git a/test/tests/backend/PostProcessBackend.h b/test/tests/backend/PostProcessBackend.h index c6fb92b..8c5ed3c 100644 --- a/test/tests/backend/PostProcessBackend.h +++ b/test/tests/backend/PostProcessBackend.h @@ -38,7 +38,6 @@ class PostProcessBackend : public TestBaseI private: cocos2d::backend::CommandBuffer* _commandBuffer = nullptr; - cocos2d::backend::BindGroup _bindGroup; cocos2d::backend::RenderPassDescriptor _renderPassDescriptorBunny1; cocos2d::backend::RenderPassDescriptor _renderPassDescriptorBunny2; cocos2d::backend::RenderPassDescriptor _renderPassDescriptorBg; diff --git a/test/tests/backend/StencilBackend.cpp b/test/tests/backend/StencilBackend.cpp index b217555..f7f25a4 100644 --- a/test/tests/backend/StencilBackend.cpp +++ b/test/tests/backend/StencilBackend.cpp @@ -189,10 +189,9 @@ void StencilBackend::tick(float dt) _commandBuffer->setRenderPipeline(_renderPipeline); - _bindGroup.setFragmentUniform(_colorLocation, "color", color, sizeof(color)); - _bindGroup.setVertexUniform(_transformLocation, "transform", _transform0.m, sizeof(_transform0.m)); - _bindGroup.setTexture("texture", 0, _canvasTexture); - _commandBuffer->setBindGroup(&_bindGroup); + _renderPipeline->getProgram()->setFragmentUniform(_colorLocation, color, sizeof(color)); + _renderPipeline->getProgram()->setVertexUniform(_transformLocation, _transform0.m, sizeof(_transform0.m)); + _renderPipeline->getProgram()->setTexture("texture", 0, _canvasTexture); _commandBuffer->drawArrays(cocos2d::backend::PrimitiveType::TRIANGLE, 0, 6); @@ -210,10 +209,9 @@ void StencilBackend::tick(float dt) _commandBuffer->setVertexBuffer(0, _vertexBuffer); _commandBuffer->setCullMode(backend::CullMode::NONE); - _bindGroup.setTexture("texture", 0, _texture); - _bindGroup.setVertexUniform(_transformLocation, "transform", _transform1.m, sizeof(_transform1.m)); - _commandBuffer->setBindGroup(&_bindGroup); - + _renderPipeline->getProgram()->setTexture("texture", 0, _texture); + _renderPipeline->getProgram()->setVertexUniform(_transformLocation, _transform1.m, sizeof(_transform1.m)); + _commandBuffer->drawArrays(cocos2d::backend::PrimitiveType::TRIANGLE, 0, 6); _commandBuffer->endRenderPass(); } @@ -230,9 +228,8 @@ void StencilBackend::tick(float dt) _commandBuffer->setStencilReferenceValue(0x1); _commandBuffer->setRenderPipeline(_renderPipelineCavasTexture); - _bindGroup.setVertexUniform(_transformLocation, "transform", _transform0.m, sizeof(_transform0.m)); - _bindGroup.setTexture("texture", 0, _canvasTexture); - _commandBuffer->setBindGroup(&_bindGroup); + _renderPipeline->getProgram()->setVertexUniform(_transformLocation, _transform0.m, sizeof(_transform0.m)); + _renderPipeline->getProgram()->setTexture("texture", 0, _canvasTexture); _commandBuffer->drawArrays(cocos2d::backend::PrimitiveType::TRIANGLE, 0, 6); _commandBuffer->endRenderPass(); } @@ -245,10 +242,9 @@ void StencilBackend::tick(float dt) _commandBuffer->setVertexBuffer(0, _vertexBuffer); _commandBuffer->setCullMode(backend::CullMode::NONE); - _bindGroup.setTexture("texture", 0, _texture); - _bindGroup.setVertexUniform(_transformLocation, "transform", _transform1.m, sizeof(_transform1.m)); - _commandBuffer->setBindGroup(&_bindGroup); - + _renderPipeline->getProgram()->setTexture("texture", 0, _texture); + _renderPipeline->getProgram()->setVertexUniform(_transformLocation, _transform1.m, sizeof(_transform1.m)); + _commandBuffer->drawArrays(cocos2d::backend::PrimitiveType::TRIANGLE, 0, 6); _commandBuffer->endRenderPass(); } @@ -264,9 +260,8 @@ void StencilBackend::tick(float dt) _commandBuffer->setStencilReferenceValue(0x1); _commandBuffer->setRenderPipeline(_renderPipelineCavasTexture); - _bindGroup.setVertexUniform(_transformLocation, "transform", _transform0.m, sizeof(_transform0.m)); - _bindGroup.setTexture("texture", 0, _canvasTexture); - _commandBuffer->setBindGroup(&_bindGroup); + _renderPipeline->getProgram()->setVertexUniform(_transformLocation, _transform0.m, sizeof(_transform0.m)); + _renderPipeline->getProgram()->setTexture("texture", 0, _canvasTexture); _commandBuffer->drawArrays(cocos2d::backend::PrimitiveType::TRIANGLE, 0, 6); _commandBuffer->endRenderPass(); } @@ -279,10 +274,9 @@ void StencilBackend::tick(float dt) _commandBuffer->setVertexBuffer(0, _vertexBuffer); _commandBuffer->setCullMode(backend::CullMode::NONE); - _bindGroup.setTexture("texture", 0, _texture); - _bindGroup.setVertexUniform(_transformLocation, "transform", _transform1.m, sizeof(_transform1.m)); - _commandBuffer->setBindGroup(&_bindGroup); - + _renderPipeline->getProgram()->setTexture("texture", 0, _texture); + _renderPipeline->getProgram()->setVertexUniform(_transformLocation, _transform1.m, sizeof(_transform1.m)); + _commandBuffer->drawArrays(cocos2d::backend::PrimitiveType::TRIANGLE, 0, 6); _commandBuffer->endRenderPass(); } @@ -297,9 +291,8 @@ void StencilBackend::tick(float dt) _commandBuffer->setStencilReferenceValue(0x1); _commandBuffer->setRenderPipeline(_renderPipelineCavasTexture); - _bindGroup.setVertexUniform(_transformLocation, "transform", _transform0.m, sizeof(_transform0.m)); - _bindGroup.setTexture("texture", 0, _canvasTexture); - _commandBuffer->setBindGroup(&_bindGroup); + _renderPipeline->getProgram()->setVertexUniform(_transformLocation, _transform0.m, sizeof(_transform0.m)); + _renderPipeline->getProgram()->setTexture("texture", 0, _canvasTexture); _commandBuffer->drawArrays(cocos2d::backend::PrimitiveType::TRIANGLE, 0, 6); _commandBuffer->endRenderPass(); } @@ -312,9 +305,8 @@ void StencilBackend::tick(float dt) _commandBuffer->setStencilReferenceValue(0x1); _commandBuffer->setCullMode(backend::CullMode::NONE); - _bindGroup.setTexture("texture", 0, _texture); - _bindGroup.setVertexUniform(_transformLocation, "transform", _transform1.m, sizeof(_transform1.m)); - _commandBuffer->setBindGroup(&_bindGroup); + _renderPipeline->getProgram()->setTexture("texture", 0, _texture); + _renderPipeline->getProgram()->setVertexUniform(_transformLocation, _transform1.m, sizeof(_transform1.m)); _commandBuffer->drawArrays(cocos2d::backend::PrimitiveType::TRIANGLE, 0, 6); _commandBuffer->endRenderPass(); diff --git a/test/tests/backend/StencilBackend.h b/test/tests/backend/StencilBackend.h index 9bb33d1..0884cbc 100644 --- a/test/tests/backend/StencilBackend.h +++ b/test/tests/backend/StencilBackend.h @@ -45,7 +45,6 @@ class StencilBackend : public TestBaseI cocos2d::backend::Buffer* _vertexBuffer = nullptr; cocos2d::backend::CommandBuffer* _commandBuffer = nullptr; cocos2d::backend::RenderPassDescriptor _renderPassDescriptor; - cocos2d::backend::BindGroup _bindGroup; cocos2d::backend::RenderPipeline* _renderPipeline = nullptr; cocos2d::backend::RenderPipeline* _renderPipelineCavasTexture = nullptr; diff --git a/test/tests/backend/SubImageBackend.cpp b/test/tests/backend/SubImageBackend.cpp index 8dbad6c..e268dd4 100644 --- a/test/tests/backend/SubImageBackend.cpp +++ b/test/tests/backend/SubImageBackend.cpp @@ -37,11 +37,10 @@ SubImageBackend::SubImageBackend() #ifdef GL_ES precision highp float; #endif - uniform mat4 transform; attribute vec2 a_position; varying vec2 v_texcoord; void main () { - gl_Position = transform * vec4(a_position, 0, 1); + gl_Position = vec4(a_position, 0, 1); v_texcoord = a_position * 0.5 + 0.5; } )"; @@ -51,7 +50,6 @@ SubImageBackend::SubImageBackend() precision highp float; #endif uniform sampler2D texture; - uniform vec4 color; varying vec2 v_texcoord; void main () { gl_FragColor = texture2D(texture, v_texcoord); @@ -64,8 +62,6 @@ SubImageBackend::SubImageBackend() auto vs = device->createShaderModule(backend::ShaderStage::VERTEX, vert); auto fs = device->createShaderModule(backend::ShaderStage::FRAGMENT, frag); renderPipelineDescriptor.program = device->createProgram(vs, fs); - _transformLocation = renderPipelineDescriptor.program->getUniformLocation("transform"); - _colorLocation = renderPipelineDescriptor.program->getUniformLocation("color"); backend::VertexLayout vertexLayout; vertexLayout.setAtrribute("a_position", 0, backend::VertexFormat::FLOAT_R32G32, 0); @@ -135,12 +131,7 @@ void SubImageBackend::tick(float dt) _commandBuffer->setVertexBuffer(0, _vertexBuffer); - - float color[4] = {1, 0, 0, 1}; - _bindGroup.setFragmentUniform(_colorLocation, "color", color, sizeof(color)); - _bindGroup.setVertexUniform(_transformLocation, "transform", _transform0.m, sizeof(_transform0.m)); - _bindGroup.setTexture("texture", 0, _texture); - _commandBuffer->setBindGroup(&_bindGroup); + _renderPipeline->getProgram()->setTexture("texture", 0, _texture); _commandBuffer->drawArrays(backend::PrimitiveType::TRIANGLE, 0, 6); _commandBuffer->endRenderPass(); diff --git a/test/tests/backend/SubImageBackend.h b/test/tests/backend/SubImageBackend.h index 4143bc6..68d3274 100644 --- a/test/tests/backend/SubImageBackend.h +++ b/test/tests/backend/SubImageBackend.h @@ -41,7 +41,6 @@ class SubImageBackend : public TestBaseI cocos2d::backend::RenderPipeline* _renderPipeline = nullptr; cocos2d::backend::CommandBuffer* _commandBuffer = nullptr; cocos2d::backend::Texture* _texture = nullptr; - cocos2d::backend::BindGroup _bindGroup; cocos2d::backend::RenderPassDescriptor _renderPassDescriptor; cocos2d::Mat4 _transform0; @@ -49,9 +48,6 @@ class SubImageBackend : public TestBaseI uint8_t* _data; size_t _dataSize; size_t _updatePixelIndex; - - int _transformLocation = -1; - int _colorLocation = -1; }; diff --git a/test/tests/backend/Texture2DBackend.cpp b/test/tests/backend/Texture2DBackend.cpp index e174851..66ecc7a 100644 --- a/test/tests/backend/Texture2DBackend.cpp +++ b/test/tests/backend/Texture2DBackend.cpp @@ -135,17 +135,6 @@ Texture2DBackendTest::Texture2DBackendTest() _transform1.translate(0.5f, 0, 0); _transform1.scale(0.5f); - // set uniforms - _bindGroupCanvas.setTexture("texture", 0, _canvasTexture); - float color[4] = {1.f, 0.f, 0.f, 1.f}; - - _bindGroupCanvas.setFragmentUniform(_colorLocation, "color", color, sizeof(color)); - _bindGroupCanvas.setVertexUniform(_transformLocation, "transform", _transform0.m, sizeof(_transform0.m)); - - _bindGroupdTexture.setTexture("texture", 0, _texture); - _bindGroupdTexture.setFragmentUniform(_colorLocation, "color", color, sizeof(color)); - _bindGroupdTexture.setVertexUniform(_transformLocation, "transform", _transform1.m, sizeof(_transform1.m)); - // render pass _renderPassDescriptor.clearColorValue = {0.1f, 0.1f, 0.1f, 0.1f}; _renderPassDescriptor.needClearColor = true; @@ -166,6 +155,8 @@ Texture2DBackendTest::~Texture2DBackendTest() void Texture2DBackendTest::tick(float dt) { _commandBuffer->beginFrame(); + float color[4] = {1.f, 0.f, 0.f, 1.f}; + _renderPipeline->getProgram()->setFragmentUniform(_colorLocation, color, sizeof(color)); if (_canvasTexture) { _renderPassDescriptor.needClearColor = true; @@ -173,7 +164,9 @@ void Texture2DBackendTest::tick(float dt) _commandBuffer->setRenderPipeline(_renderPipeline); _commandBuffer->setViewport(0, 0, utils::WINDOW_WIDTH, utils::WINDOW_HEIGHT); _commandBuffer->setVertexBuffer(0, _vertexBuffer); - _commandBuffer->setBindGroup(&_bindGroupCanvas); + _renderPipeline->getProgram()->setVertexUniform(_transformLocation, _transform0.m, sizeof(_transform0.m)); + _renderPipeline->getProgram()->setTexture("texture", 0, _canvasTexture); + _commandBuffer->drawArrays(cocos2d::backend::PrimitiveType::TRIANGLE, 0, 6); _commandBuffer->endRenderPass(); } @@ -185,7 +178,10 @@ void Texture2DBackendTest::tick(float dt) _commandBuffer->setRenderPipeline(_renderPipeline); _commandBuffer->setViewport(0, 0, utils::WINDOW_WIDTH, utils::WINDOW_HEIGHT); _commandBuffer->setVertexBuffer(0, _vertexBuffer); - _commandBuffer->setBindGroup(&_bindGroupdTexture); + + _renderPipeline->getProgram()->setVertexUniform(_transformLocation, _transform1.m, sizeof(_transform1.m)); + _renderPipeline->getProgram()->setTexture("texture", 0, _texture); + _commandBuffer->drawArrays(cocos2d::backend::PrimitiveType::TRIANGLE, 0, 6); _commandBuffer->endRenderPass(); } diff --git a/test/tests/backend/Texture2DBackend.h b/test/tests/backend/Texture2DBackend.h index 4f72c14..88190d5 100644 --- a/test/tests/backend/Texture2DBackend.h +++ b/test/tests/backend/Texture2DBackend.h @@ -28,7 +28,6 @@ #include "backend/Buffer.h" #include "backend/Texture.h" #include "backend/RenderPipeline.h" -#include "backend/BindGroup.h" #include "backend/CommandBuffer.h" #include "math/Mat4.h" @@ -50,8 +49,6 @@ class Texture2DBackendTest : public TestBaseI cocos2d::backend::Texture* _canvasTexture = nullptr; cocos2d::backend::Texture* _texture = nullptr; - cocos2d::backend::BindGroup _bindGroupCanvas; - cocos2d::backend::BindGroup _bindGroupdTexture; cocos2d::backend::RenderPipeline* _renderPipeline = nullptr; cocos2d::backend::RenderPassDescriptor _renderPassDescriptor; cocos2d::backend::CommandBuffer* _commandBuffer = nullptr; From 9786a459c4f18461a84ce075294b934e3b303a15 Mon Sep 17 00:00:00 2001 From: coulsonwang Date: Fri, 4 Jan 2019 16:18:29 +0800 Subject: [PATCH 05/11] [BugFix] fix reference retain --- src/backend/opengl/ProgramGL.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/backend/opengl/ProgramGL.cpp b/src/backend/opengl/ProgramGL.cpp index b0759ac..b8bca1c 100644 --- a/src/backend/opengl/ProgramGL.cpp +++ b/src/backend/opengl/ProgramGL.cpp @@ -112,15 +112,15 @@ namespace ProgramGL::ProgramGL(ShaderModule* vs, ShaderModule* fs) :Program(vs, fs) +,_vertexShaderModule(static_cast(vs)) +,_fragmentShaderModule(static_cast(fs)) { - if(_vertexShaderModule == vs && _fragmentShaderModule == fs) - return; - - _vertexShaderModule = (static_cast(vs)); - _fragmentShaderModule = (static_cast(fs)); CC_SAFE_RETAIN(_vertexShaderModule); CC_SAFE_RETAIN(_fragmentShaderModule); + if(_vertexShaderModule == vs && _fragmentShaderModule == fs) + return; + createProgram(); computeUniformInfos(); } From 999198e2bbb5a8d8c13239cdbb038be88cee2bf0 Mon Sep 17 00:00:00 2001 From: coulsonwang Date: Sun, 6 Jan 2019 16:08:26 +0800 Subject: [PATCH 06/11] [Feature] update uniform location --- src/backend/Program.cpp | 85 ++++++++++----------- src/backend/Program.h | 39 +++++----- src/backend/metal/CommandBufferMTL.h | 2 +- src/backend/metal/CommandBufferMTL.mm | 52 ++++++------- src/backend/metal/DeviceMTL.mm | 6 +- src/backend/metal/ProgramMTL.h | 13 +++- src/backend/metal/ProgramMTL.mm | 37 +++++---- src/backend/metal/RenderPipelineMTL.h | 5 -- src/backend/metal/RenderPipelineMTL.mm | 8 +- src/backend/metal/ShaderModuleMTL.h | 4 +- src/backend/metal/ShaderModuleMTL.mm | 6 +- src/backend/opengl/CommandBufferGL.cpp | 12 +-- src/backend/opengl/DeviceGL.cpp | 6 +- src/backend/opengl/ProgramGL.cpp | 42 ++++++++-- src/backend/opengl/ProgramGL.h | 14 ++-- test/tests/backend/BasicBackend.cpp | 2 +- test/tests/backend/BlendingBackend.cpp | 14 ++-- test/tests/backend/BunnyBackend.cpp | 8 +- test/tests/backend/DepthTextureBackend.cpp | 14 ++-- test/tests/backend/GuiProjectionBackend.cpp | 9 ++- test/tests/backend/GuiProjectionBackend.h | 1 + test/tests/backend/MultiTexturesBackend.cpp | 12 +-- test/tests/backend/MultiTexturesBackend.h | 2 + test/tests/backend/ParticleBackend.cpp | 9 ++- test/tests/backend/ParticleBackend.h | 1 + test/tests/backend/PostProcessBackend.cpp | 12 +-- test/tests/backend/StencilBackend.cpp | 21 ++--- test/tests/backend/StencilBackend.h | 1 + test/tests/backend/SubImageBackend.cpp | 3 +- test/tests/backend/SubImageBackend.h | 2 + test/tests/backend/Texture2DBackend.cpp | 9 ++- test/tests/backend/Texture2DBackend.h | 1 + 32 files changed, 257 insertions(+), 195 deletions(-) diff --git a/src/backend/Program.cpp b/src/backend/Program.cpp index 956bbe2..7a4ac21 100644 --- a/src/backend/Program.cpp +++ b/src/backend/Program.cpp @@ -4,27 +4,10 @@ CC_BACKEND_BEGIN -Program::Program(ShaderModule* vs, ShaderModule* fs) -: _vertexShader(vs) -, _fragmentShader(fs) -{ - CC_SAFE_RETAIN(_vertexShader); - CC_SAFE_RETAIN(_fragmentShader); -} - Program::~Program() { - CC_SAFE_RELEASE(_vertexShader); - CC_SAFE_RELEASE(_fragmentShader); - _textureInfos.clear(); -} - -Program::TextureInfo::TextureInfo(const std::string& _name, const std::vector& _indices, const std::vector _textures) -: name(_name) -, indices(_indices) -, textures(_textures) -{ - retainTextures(); + _vertexTextureInfos.clear(); + _fragTextureInfos.clear(); } Program::TextureInfo::~TextureInfo() @@ -32,24 +15,6 @@ Program::TextureInfo::~TextureInfo() releaseTextures(); } -Program::TextureInfo& Program::TextureInfo::operator=(TextureInfo&& rhs) -{ - if (this != &rhs) - { - name = rhs.name; - indices = rhs.indices; - - rhs.retainTextures(); - releaseTextures(); - textures = rhs.textures; - - //release the textures before cleaning the vertor - rhs.releaseTextures(); - rhs.textures.clear(); - } - return *this; -} - void Program::TextureInfo::retainTextures() { for (auto& texture : textures) @@ -62,18 +27,48 @@ void Program::TextureInfo::releaseTextures() CC_SAFE_RELEASE(texture); } -void Program::setTexture(const std::string &name, uint32_t index, Texture *texture) +void Program::setVertexTexture(int location, uint32_t slot, Texture* texture) +{ + setTexture(location, slot, texture, _vertexTextureInfos); +} + +void Program::setFragmentTexture(int location, uint32_t slot, Texture* texture) +{ + setTexture(location, slot, texture, _fragTextureInfos); +} + +void Program::setVertexTextureArray(int location, const std::vector& slots, const std::vector textures) { - TextureInfo textureInfo(name, {index}, {texture}); - _textureInfos[name] = std::move(textureInfo); + setTextureArray(location, slots, textures, _vertexTextureInfos); +} + +void Program::setFragmentTextureArray(int location, const std::vector& slots, const std::vector textures) +{ + setTextureArray(location, slots, textures, _fragTextureInfos); +} + +void Program::setTexture(int location, uint32_t slot, Texture* texture, std::vector& textureInfo) +{ + if(location < 0) + return; + + TextureInfo info; + info.location = location; + info.slot = {slot}; + info.textures = {texture}; + info.retainTextures(); + textureInfo.at(location) = info; } -void Program::setTextureArray(const std::string& name, const std::vector& indices, const std::vector textures) +void Program::setTextureArray(int location, const std::vector& slots, const std::vector textures, std::vector& textureInfo) { - assert(indices.size() == textures.size()); - - TextureInfo textureInfo(name, indices, textures); - _textureInfos[name] = std::move(textureInfo); + assert(slots.size() == textures.size()); + TextureInfo info; + info.location = location; + info.slot = slots; + info.textures = textures; + info.retainTextures(); + textureInfo.at(location) = info; } CC_BACKEND_END diff --git a/src/backend/Program.h b/src/backend/Program.h index f851629..24a650f 100644 --- a/src/backend/Program.h +++ b/src/backend/Program.h @@ -5,7 +5,6 @@ #include "platform/CCPlatformMacros.h" #include #include -#include CC_BACKEND_BEGIN @@ -17,37 +16,39 @@ class Program : public Ref public: struct TextureInfo { - TextureInfo(const std::string& _name, const std::vector& _indices, const std::vector _textures); - TextureInfo() = default; ~TextureInfo(); - TextureInfo& operator =(TextureInfo&& rhs); - + void retainTextures(); void releaseTextures(); - - std::string name; - std::vector indices; + + int location = 0; + std::vector slot; std::vector textures; }; - virtual int getUniformLocation(const std::string& uniform) = 0; + virtual int getVertexUniformLocation(const std::string& uniform) const = 0; + virtual int getFragmentUniformLocation(const std::string& uniform) const = 0; virtual void setVertexUniform(int location, void* data, uint32_t size) = 0; virtual void setFragmentUniform(int location, void* data, uint32_t size) = 0; - virtual void setTexture(const std::string& name, uint32_t index, Texture* texture); - virtual void setTextureArray(const std::string& name, const std::vector& indices, const std::vector textures); + virtual void setVertexTexture(int location, uint32_t slot, Texture* texture); + virtual void setFragmentTexture(int location, uint32_t slot, Texture* texture); + virtual void setVertexTextureArray(int location, const std::vector& slots, const std::vector textures); + virtual void setFragmentTextureArray(int location, const std::vector& slots, const std::vector textures); - inline ShaderModule* getVertexShader() const { return _vertexShader; } - inline ShaderModule* getFragmentShader() const { return _fragmentShader; } - inline const std::unordered_map& getTextureInfos() const { return _textureInfos; } + inline const std::vector& getVertexTextureInfos() const { return _vertexTextureInfos; } + inline const std::vector& getFragmentTextureInfos() const { return _fragTextureInfos; } protected: - Program(ShaderModule* vs, ShaderModule* fs); + Program() = default; virtual ~Program(); -private: - backend::ShaderModule* _vertexShader = nullptr; - backend::ShaderModule* _fragmentShader = nullptr; - std::unordered_map _textureInfos; + void setTexture(int location, uint32_t slot, Texture* texture, std::vector& textureInfo); + void setTextureArray(int location, const std::vector& slots, const std::vector textures, std::vector& textureInfo); + + ShaderModule* _vertexShader = nullptr; + ShaderModule* _fragmentShader = nullptr; + std::vector _vertexTextureInfos; + std::vector _fragTextureInfos; }; CC_BACKEND_END diff --git a/src/backend/metal/CommandBufferMTL.h b/src/backend/metal/CommandBufferMTL.h index eaed0dd..ece1d9d 100644 --- a/src/backend/metal/CommandBufferMTL.h +++ b/src/backend/metal/CommandBufferMTL.h @@ -29,7 +29,7 @@ class CommandBufferMTL : public CommandBuffer private: void prepareDrawing() const; void setTextures() const; - void doSetTextures(const std::vector& textures, bool isVertex) const; + void doSetTextures(bool isVertex) const; void setUniformBuffer() const; void afterDraw(); diff --git a/src/backend/metal/CommandBufferMTL.mm b/src/backend/metal/CommandBufferMTL.mm index fea4e74..af11210 100644 --- a/src/backend/metal/CommandBufferMTL.mm +++ b/src/backend/metal/CommandBufferMTL.mm @@ -267,41 +267,37 @@ MTLCullMode toMTLCullMode(CullMode mode) { if (_renderPipelineMTL->getProgram()) { - doSetTextures(_renderPipelineMTL->getVertexTextures(), true); - doSetTextures(_renderPipelineMTL->getFragmentTextures(), false); + doSetTextures(true); + doSetTextures(false); } } -void CommandBufferMTL::doSetTextures(const std::vector& textures, bool isVertex) const +void CommandBufferMTL::doSetTextures(bool isVertex) const { - const auto& bindTextureInfos = _renderPipelineMTL->getProgram()->getTextureInfos(); - int i = 0; - for (const auto& texture : textures) + const auto& bindTextureInfos = (isVertex)?_renderPipelineMTL->getProgram()->getVertexTextureInfos():_renderPipelineMTL->getProgram()->getFragmentTextureInfos(); + for(const auto& textureInfo : bindTextureInfos) { - auto iter = bindTextureInfos.find(texture); - if (bindTextureInfos.end() != iter) + int i = 0; + //FIXME: should support texture array. + const auto& textures = textureInfo.textures; + const auto& mtlTexture = static_cast(textures[i]); + + if (isVertex) { - //FIXME: should support texture array. - const auto& textures = iter->second.textures; - const auto& mtlTexture = static_cast(textures[0]); - - if (isVertex) - { - [_mtlRenderEncoder setVertexTexture:mtlTexture->getMTLTexture() - atIndex:i]; - [_mtlRenderEncoder setVertexSamplerState:mtlTexture->getMTLSamplerState() - atIndex:i]; - } - else - { - [_mtlRenderEncoder setFragmentTexture:mtlTexture->getMTLTexture() - atIndex:i]; - [_mtlRenderEncoder setFragmentSamplerState:mtlTexture->getMTLSamplerState() - atIndex:i]; - } - - ++i; + [_mtlRenderEncoder setVertexTexture:mtlTexture->getMTLTexture() + atIndex:textureInfo.location]; + [_mtlRenderEncoder setVertexSamplerState:mtlTexture->getMTLSamplerState() + atIndex:textureInfo.location]; + } + else + { + [_mtlRenderEncoder setFragmentTexture:mtlTexture->getMTLTexture() + atIndex:textureInfo.location]; + [_mtlRenderEncoder setFragmentSamplerState:mtlTexture->getMTLSamplerState() + atIndex:textureInfo.location]; } + + ++i; } } diff --git a/src/backend/metal/DeviceMTL.mm b/src/backend/metal/DeviceMTL.mm index 53519c5..b7867fd 100644 --- a/src/backend/metal/DeviceMTL.mm +++ b/src/backend/metal/DeviceMTL.mm @@ -94,7 +94,11 @@ Program* DeviceMTL::createProgram(ShaderModule* vs, ShaderModule* fs) { - return new (std::nothrow) ProgramMTL(vs, fs); + auto ret = new (std::nothrow) ProgramMTL(vs, fs); + if (ret) + ret->autorelease(); + + return ret; } CC_BACKEND_END diff --git a/src/backend/metal/ProgramMTL.h b/src/backend/metal/ProgramMTL.h index 2007393..27903aa 100644 --- a/src/backend/metal/ProgramMTL.h +++ b/src/backend/metal/ProgramMTL.h @@ -1,6 +1,7 @@ #pragma once #include "../Program.h" +#include CC_BACKEND_BEGIN @@ -10,14 +11,20 @@ class ProgramMTL : public Program { public: ProgramMTL(ShaderModule* vs, ShaderModule* fs); - virtual ~ProgramMTL(); - virtual int getUniformLocation(const std::string& uniform) override; + ~ProgramMTL(); + + virtual int getVertexUniformLocation(const std::string& uniform) const override; + virtual int getFragmentUniformLocation(const std::string& uniform) const override; virtual void setVertexUniform(int location, void* data, uint32_t size) override; virtual void setFragmentUniform(int location, void* data, uint32_t size) override; - void fillUniformBuffer(uint8_t* buffer, uint32_t offset, void* uniformData, uint32_t uniformSize) const; + inline const ShaderModuleMTL* getVertexShaderModule() const { return _vertexShader; } + inline const ShaderModuleMTL* getFragmentShaderModule() const { return _fragmentShader; } private: + void fillUniformBuffer(uint8_t* buffer, uint32_t offset, void* uniformData, uint32_t uniformSize); + int getUniformLcation(const std::unordered_map& uniformsInfo, const std::string& uniform) const; + ShaderModuleMTL* _vertexShader = nullptr; ShaderModuleMTL* _fragmentShader = nullptr; }; diff --git a/src/backend/metal/ProgramMTL.mm b/src/backend/metal/ProgramMTL.mm index 69a73ce..b7bd2dd 100644 --- a/src/backend/metal/ProgramMTL.mm +++ b/src/backend/metal/ProgramMTL.mm @@ -4,12 +4,16 @@ CC_BACKEND_BEGIN ProgramMTL::ProgramMTL(ShaderModule* vs, ShaderModule* fs) -: Program(vs, fs) -, _vertexShader(static_cast(vs)) +: _vertexShader(static_cast(vs)) , _fragmentShader(static_cast(fs)) { CC_SAFE_RETAIN(_vertexShader); CC_SAFE_RETAIN(_fragmentShader); + + _vertexTextureInfos.reserve(_vertexShader->getUniformTextureCount()); + _vertexTextureInfos.resize(_vertexShader->getUniformTextureCount()); + _fragTextureInfos.reserve(_fragmentShader->getUniformTextureCount()); + _fragTextureInfos.resize(_fragmentShader->getUniformTextureCount()); } ProgramMTL::~ProgramMTL() @@ -18,17 +22,23 @@ CC_SAFE_RELEASE(_fragmentShader); } -int ProgramMTL::getUniformLocation(const std::string& uniform) +int ProgramMTL::getVertexUniformLocation(const std::string& uniform) const { - const auto& vsUniforms = _vertexShader->getUniforms(); - const auto& fsUniforms = _fragmentShader->getUniforms(); - const auto& vsIter = vsUniforms.find(uniform); - if(vsIter != vsUniforms.end()) - return vsIter->second; - - const auto& fsIter = fsUniforms.find(uniform); - if(fsIter != fsUniforms.end()) - return fsIter->second; + const auto& uniforms = _vertexShader->getUniforms(); + return getUniformLcation(uniforms, uniform); +} + +int ProgramMTL::getFragmentUniformLocation(const std::string& uniform) const +{ + const auto& uniforms = _fragmentShader->getUniforms(); + return getUniformLcation(uniforms, uniform); +} + +int ProgramMTL::getUniformLcation(const std::unordered_map& uniformsInfo, const std::string& uniform) const +{ + const auto& iter = uniformsInfo.find(uniform); + if(iter != uniformsInfo.end()) + return iter->second; return -1; } @@ -51,8 +61,9 @@ fillUniformBuffer(fragUniformBuffer.get(), location, data, size); } -void ProgramMTL::fillUniformBuffer(uint8_t* buffer, uint32_t offset, void* uniformData, uint32_t uniformSize) const +void ProgramMTL::fillUniformBuffer(uint8_t* buffer, uint32_t offset, void* uniformData, uint32_t uniformSize) { memcpy(buffer + offset, uniformData, uniformSize); } + CC_BACKEND_END diff --git a/src/backend/metal/RenderPipelineMTL.h b/src/backend/metal/RenderPipelineMTL.h index fbd5a35..e6e552c 100644 --- a/src/backend/metal/RenderPipelineMTL.h +++ b/src/backend/metal/RenderPipelineMTL.h @@ -22,8 +22,6 @@ class RenderPipelineMTL : public RenderPipeline inline const std::shared_ptr& getVertexUniformBuffer() const { return _vertexUniformBuffer; } inline const std::shared_ptr& getFragmentUniformBuffer() const { return _fragementUniformBuffer; } - inline const std::vector& getVertexTextures() const { return _vertexTextures; } - inline const std::vector& getFragmentTextures() const { return _fragmentTextures; } inline uint32_t getVertexUniformBufferSize() const { return _vertexUniformBufferSize; } inline uint32_t getFragUniformBufferSize() const { return _fragUniformBufferSize; } @@ -40,10 +38,7 @@ class RenderPipelineMTL : public RenderPipeline uint32_t _vertexUniformBufferSize = 0; uint32_t _fragUniformBufferSize = 0; std::shared_ptr _vertexUniformBuffer = nullptr; - std::vector _vertexTextures; - std::shared_ptr _fragementUniformBuffer = nullptr; - std::vector _fragmentTextures; MTLRenderPipelineDescriptor* _mtlRenderPipelineDescriptor = nil; BlendDescriptorMTL _blendDescriptorMTL; diff --git a/src/backend/metal/RenderPipelineMTL.mm b/src/backend/metal/RenderPipelineMTL.mm index 6fb891a..ffbc540 100644 --- a/src/backend/metal/RenderPipelineMTL.mm +++ b/src/backend/metal/RenderPipelineMTL.mm @@ -3,7 +3,7 @@ #include "ShaderModuleMTL.h" #include "DepthStencilStateMTL.h" #include "Utils.h" -#include "../Program.h" +#include "ProgramMTL.h" CC_BACKEND_BEGIN @@ -136,16 +136,14 @@ MTLVertexFormat toMTLVertexFormat(VertexFormat vertexFormat) void RenderPipelineMTL::setShaderModules(const RenderPipelineDescriptor& descriptor) { - auto vertexShaderModule = static_cast(descriptor.program->getVertexShader()); + auto vertexShaderModule = static_cast(descriptor.program)->getVertexShaderModule(); _mtlRenderPipelineDescriptor.vertexFunction = vertexShaderModule->getMTLFunction(); _vertexUniformBuffer = vertexShaderModule->getUniformBuffer(); - _vertexTextures = vertexShaderModule->getTextures(); _vertexUniformBufferSize = vertexShaderModule->getUniformBufferSize(); - auto fragShaderModule = static_cast(descriptor.program->getFragmentShader()); + auto fragShaderModule = static_cast(descriptor.program)->getFragmentShaderModule(); _mtlRenderPipelineDescriptor.fragmentFunction = fragShaderModule->getMTLFunction(); _fragementUniformBuffer = fragShaderModule->getUniformBuffer(); - _fragmentTextures = fragShaderModule->getTextures(); _fragUniformBufferSize = fragShaderModule->getUniformBufferSize(); } diff --git a/src/backend/metal/ShaderModuleMTL.h b/src/backend/metal/ShaderModuleMTL.h index e8bc1a2..6624fca 100644 --- a/src/backend/metal/ShaderModuleMTL.h +++ b/src/backend/metal/ShaderModuleMTL.h @@ -20,8 +20,8 @@ class ShaderModuleMTL : public ShaderModule inline id getMTLFunction() const { return _mtlFunction; } inline const std::shared_ptr& getUniformBuffer() const { return _uniformBuffer; } inline const std::unordered_map& getUniforms() const { return _uniforms; } - inline const std::vector& getTextures() const { return _textures; } inline uint32_t getUniformBufferSize() const { return _uniformBufferSize; } + inline uint32_t getUniformTextureCount() const { return _uniformTextureCount; } private: void parseUniform(id mtlDevice, glslopt_shader* shader); @@ -34,7 +34,7 @@ class ShaderModuleMTL : public ShaderModule uint32_t _uniformBufferSize = 0; // Texture index is the same as vector index. - std::vector _textures; + uint32_t _uniformTextureCount = 0; }; CC_BACKEND_END diff --git a/src/backend/metal/ShaderModuleMTL.mm b/src/backend/metal/ShaderModuleMTL.mm index 0f889c0..61de71f 100644 --- a/src/backend/metal/ShaderModuleMTL.mm +++ b/src/backend/metal/ShaderModuleMTL.mm @@ -90,15 +90,15 @@ void ShaderModuleMTL::parseTexture(id mtlDevice, glslopt_shader* shader) { - const int textureCount = glslopt_shader_get_texture_count(shader); - for (int i = 0; i < textureCount; ++i) + _uniformTextureCount = glslopt_shader_get_texture_count(shader); + for (int i = 0; i < _uniformTextureCount; ++i) { const char* parName; glslopt_basic_type parType; glslopt_precision parPrec; int parVecSize, parMatSize, parArrSize, location; glslopt_shader_get_texture_desc(shader, i, &parName, &parType, &parPrec, &parVecSize, &parMatSize, &parArrSize, &location); - _textures.push_back(parName); + _uniforms[parName] = location; } } diff --git a/src/backend/opengl/CommandBufferGL.cpp b/src/backend/opengl/CommandBufferGL.cpp index 525ca07..4563e35 100644 --- a/src/backend/opengl/CommandBufferGL.cpp +++ b/src/backend/opengl/CommandBufferGL.cpp @@ -347,16 +347,18 @@ void CommandBufferGL::setUniforms(ProgramGL* program) const { if (program) { - const auto& texutreInfos = program->getTextureInfos(); + const auto& texutreInfos = program->getFragmentTextureInfos(); const auto& activeUniformInfos = program->getUniformInfos(); for (const auto& activeUinform : activeUniformInfos) { // Bind textures. - const auto& bindUniformTextureInfo = texutreInfos.find(activeUinform.name); - if (texutreInfos.end() != bindUniformTextureInfo) + for(const auto& textureInfo : texutreInfos) { - const auto& textures = (*bindUniformTextureInfo).second.textures; - const auto& indices = (*bindUniformTextureInfo).second.indices; + if(activeUinform.location != textureInfo.location) + continue; + + const auto& textures = textureInfo.textures; + const auto& indices = textureInfo.slot; int i = 0; for (const auto& texture: textures) diff --git a/src/backend/opengl/DeviceGL.cpp b/src/backend/opengl/DeviceGL.cpp index 865c457..697afc2 100644 --- a/src/backend/opengl/DeviceGL.cpp +++ b/src/backend/opengl/DeviceGL.cpp @@ -67,7 +67,11 @@ RenderPipeline* DeviceGL::newRenderPipeline(const RenderPipelineDescriptor& desc Program* DeviceGL::createProgram(ShaderModule* vs, ShaderModule* fs) { - return new (std::nothrow) ProgramGL(vs, fs); + auto ret = new (std::nothrow) ProgramGL(vs, fs); + if (ret) + ret->autorelease(); + + return ret; } CC_BACKEND_END diff --git a/src/backend/opengl/ProgramGL.cpp b/src/backend/opengl/ProgramGL.cpp index b8bca1c..f5833fa 100644 --- a/src/backend/opengl/ProgramGL.cpp +++ b/src/backend/opengl/ProgramGL.cpp @@ -111,18 +111,26 @@ namespace } ProgramGL::ProgramGL(ShaderModule* vs, ShaderModule* fs) -:Program(vs, fs) -,_vertexShaderModule(static_cast(vs)) -,_fragmentShaderModule(static_cast(fs)) { - CC_SAFE_RETAIN(_vertexShaderModule); - CC_SAFE_RETAIN(_fragmentShaderModule); - if(_vertexShaderModule == vs && _fragmentShaderModule == fs) + { + CC_SAFE_RETAIN(_vertexShaderModule); + CC_SAFE_RETAIN(_fragmentShaderModule); return; + } + + _vertexShaderModule = (static_cast(vs)); + _fragmentShaderModule = (static_cast(fs)); + CC_SAFE_RETAIN(_vertexShaderModule); + CC_SAFE_RETAIN(_fragmentShaderModule); createProgram(); computeUniformInfos(); + + _vertexTextureInfos.reserve(_maxTextureLocation); + _vertexTextureInfos.resize(_maxTextureLocation); + _fragTextureInfos.reserve(_maxTextureLocation); + _fragTextureInfos.resize(_maxTextureLocation); } ProgramGL::~ProgramGL() @@ -206,6 +214,19 @@ bool ProgramGL::getAttributeLocation(const std::string& attributeName, uint32_t& return true; } +void ProgramGL::setMaxTextureLocation(GLenum type, int location) +{ + switch (type) { + case GL_SAMPLER_2D: + case GL_SAMPLER_CUBE: + _maxTextureLocation = location < _maxTextureLocation ? _maxTextureLocation : location + 1 ; + break; + + default: + break; + } +} + void ProgramGL::computeUniformInfos() { if (!_program) @@ -244,13 +265,18 @@ void ProgramGL::computeUniformInfos() uniform.name = uniformName; uniform.location = glGetUniformLocation(_program, uniformName); - + setMaxTextureLocation(uniform.type, uniform.location); _uniformInfos.push_back(uniform); } free(uniformName); } -int ProgramGL::getUniformLocation(const std::string& uniform) +int ProgramGL::getVertexUniformLocation(const std::string& uniform) const +{ + return glGetUniformLocation(_program, uniform.c_str()); +} + +int ProgramGL::getFragmentUniformLocation(const std::string& uniform) const { return glGetUniformLocation(_program, uniform.c_str()); } diff --git a/src/backend/opengl/ProgramGL.h b/src/backend/opengl/ProgramGL.h index 8908387..c73a3f1 100644 --- a/src/backend/opengl/ProgramGL.h +++ b/src/backend/opengl/ProgramGL.h @@ -43,22 +43,21 @@ class ProgramGL : public Program virtual void setVertexUniform(int location, void* data, uint32_t size) override; virtual void setFragmentUniform(int location, void* data, uint32_t size) override; - + virtual int getVertexUniformLocation(const std::string& uniform) const override; + virtual int getFragmentUniformLocation(const std::string& uniform) const override; + inline const std::vector& getAttributeInfos() const { return _attributeInfos; } inline const std::vector& getUniformInfos() const { return _uniformInfos; } inline GLuint getHandler() const { return _program; } void computeAttributeInfos(const RenderPipelineDescriptor& descriptor); - virtual int getUniformLocation(const std::string& uniform) override; - -protected: - void setUniform(int location, void* data, uint32_t size); - void setUniform(bool isArray, GLuint location, uint32_t size, GLenum uniformType, void* data) const; private: void createProgram(); -// void computeAttributeInfos(const RenderPipelineDescriptor& descriptor); bool getAttributeLocation(const std::string& attributeName, uint32_t& location); void computeUniformInfos(); + void setUniform(int location, void* data, uint32_t size); + void setUniform(bool isArray, GLuint location, uint32_t size, GLenum uniformType, void* data) const; + void setMaxTextureLocation(GLenum type, int location); GLuint _program = 0; ShaderModuleGL* _vertexShaderModule = nullptr; @@ -66,6 +65,7 @@ class ProgramGL : public Program std::vector _attributeInfos; std::vector _uniformInfos; + uint32_t _maxTextureLocation = 0; }; CC_BACKEND_END diff --git a/test/tests/backend/BasicBackend.cpp b/test/tests/backend/BasicBackend.cpp index 2c6ac24..4d864b4 100644 --- a/test/tests/backend/BasicBackend.cpp +++ b/test/tests/backend/BasicBackend.cpp @@ -68,7 +68,7 @@ BasicBackend::BasicBackend() auto fs = device->createShaderModule(cocos2d::backend::ShaderStage::FRAGMENT, frag); cocos2d::backend::RenderPipelineDescriptor renderPipelineDescriptor; renderPipelineDescriptor.program = device->createProgram(vs, fs); - _colorLocation = renderPipelineDescriptor.program->getUniformLocation("color"); + _colorLocation = renderPipelineDescriptor.program->getFragmentUniformLocation("color"); backend::VertexLayout vertexLayout; vertexLayout.setAtrribute("a_position", 0, cocos2d::backend::VertexFormat::FLOAT_R32G32, 0); diff --git a/test/tests/backend/BlendingBackend.cpp b/test/tests/backend/BlendingBackend.cpp index 4aea658..3354f22 100644 --- a/test/tests/backend/BlendingBackend.cpp +++ b/test/tests/backend/BlendingBackend.cpp @@ -69,8 +69,9 @@ namespace auto vs = device->createShaderModule(cocos2d::backend::ShaderStage::VERTEX, vert); auto fs = device->createShaderModule(cocos2d::backend::ShaderStage::FRAGMENT, frag); renderPipelineDescriptor.program = device->createProgram(vs, fs); - _modelLocation = renderPipelineDescriptor.program->getUniformLocation("model"); - _projectionLocation = renderPipelineDescriptor.program->getUniformLocation("projection"); + _modelLocation = renderPipelineDescriptor.program->getVertexUniformLocation("model"); + _projectionLocation = renderPipelineDescriptor.program->getVertexUniformLocation("projection"); + _textureLocation = renderPipelineDescriptor.program->getFragmentUniformLocation("texture"); backend::VertexLayout vertexLayout; vertexLayout.setAtrribute("a_position", 0, cocos2d::backend::VertexFormat::FLOAT_R32G32, 0); @@ -181,6 +182,7 @@ namespace int _modelLocation = -1; int _projectionLocation = -1; + int _textureLocation = -1; }; struct BigTriangle @@ -221,7 +223,8 @@ namespace auto vs = device->createShaderModule(cocos2d::backend::ShaderStage::VERTEX, vert); auto fs = device->createShaderModule(cocos2d::backend::ShaderStage::FRAGMENT, frag); renderPipelineDescriptor.program = device->createProgram(vs, fs); - _timeLocation = renderPipelineDescriptor.program->getUniformLocation("time"); + _timeLocation = renderPipelineDescriptor.program->getFragmentUniformLocation("time"); + _textureLocation = renderPipelineDescriptor.program->getFragmentUniformLocation("texture"); backend::VertexLayout vertexLayout; vertexLayout.setAtrribute("a_position", 0, cocos2d::backend::VertexFormat::FLOAT_R32G32, 0); @@ -253,6 +256,7 @@ namespace backend::RenderPipeline* renderPipeline = nullptr; backend::Buffer* vertexBuffer = nullptr; int _timeLocation = -1; + int _textureLocation = -1; }; // rotation is not used @@ -295,7 +299,7 @@ BlendingBackend::BlendingBackend() textureDescriptorBackgroud.textureFormat = backend::TextureFormat::R8G8B8A8; _backgroud = device->newTexture(textureDescriptorBackgroud); _backgroud->updateData(utils::loadData("assets/background.png").getBytes()); - bigTriangle->getProgram()->setTexture("texture", 0, _backgroud); + bigTriangle->getProgram()->setFragmentTexture(bigTriangle->_textureLocation, 0, _backgroud); backend::TextureDescriptor textureDescriptorSprite0; textureDescriptorSprite0.width = 128; @@ -303,7 +307,7 @@ BlendingBackend::BlendingBackend() textureDescriptorSprite0.textureFormat = backend::TextureFormat::R8G8B8A8; _sprite0 = device->newTexture(textureDescriptorSprite0); _sprite0->updateData(utils::loadData("assets/sprite0.png").getBytes()); - quad->getProgram()->setTexture("texture", 0, _sprite0); + quad->getProgram()->setFragmentTexture(quad->_textureLocation, 0, _sprite0); _commandBuffer = device->newCommandBuffer(); diff --git a/test/tests/backend/BunnyBackend.cpp b/test/tests/backend/BunnyBackend.cpp index 42f72c4..a67b3bc 100644 --- a/test/tests/backend/BunnyBackend.cpp +++ b/test/tests/backend/BunnyBackend.cpp @@ -86,10 +86,10 @@ BunnyBackend::BunnyBackend() auto fs = device->createShaderModule(cocos2d::backend::ShaderStage::FRAGMENT, frag); renderPipelineDescriptor.program = device->createProgram(vs, fs); - _modelLocation = renderPipelineDescriptor.program->getUniformLocation("model"); - _viewLocation = renderPipelineDescriptor.program->getUniformLocation("view"); - _projectionLocation = renderPipelineDescriptor.program->getUniformLocation("projection"); - _colorLocation = renderPipelineDescriptor.program->getUniformLocation("color"); + _modelLocation = renderPipelineDescriptor.program->getVertexUniformLocation("model"); + _viewLocation = renderPipelineDescriptor.program->getVertexUniformLocation("view"); + _projectionLocation = renderPipelineDescriptor.program->getVertexUniformLocation("projection"); + _colorLocation = renderPipelineDescriptor.program->getFragmentUniformLocation("color"); _renderPipeline = device->newRenderPipeline(renderPipelineDescriptor); diff --git a/test/tests/backend/DepthTextureBackend.cpp b/test/tests/backend/DepthTextureBackend.cpp index 3331224..59d0307 100644 --- a/test/tests/backend/DepthTextureBackend.cpp +++ b/test/tests/backend/DepthTextureBackend.cpp @@ -78,8 +78,9 @@ namespace auto vs = device->createShaderModule(cocos2d::backend::ShaderStage::VERTEX, vert); auto fs = device->createShaderModule(cocos2d::backend::ShaderStage::FRAGMENT, frag); renderPipelineDescriptor.program = device->createProgram(vs, fs); - _nearLocation = renderPipelineDescriptor.program->getUniformLocation("near"); - _farLocation = renderPipelineDescriptor.program->getUniformLocation("far"); + _nearLocation = renderPipelineDescriptor.program->getFragmentUniformLocation("near"); + _farLocation = renderPipelineDescriptor.program->getFragmentUniformLocation("far"); + _textureLocation = renderPipelineDescriptor.program->getFragmentUniformLocation("texture"); backend::VertexLayout vertexLayout; vertexLayout.setAtrribute("a_position", 0, cocos2d::backend::VertexFormat::FLOAT_R32G32, 0); @@ -112,6 +113,7 @@ namespace int _nearLocation = -1; int _farLocation = -1; + int _textureLocation = -1; }; struct Bunny @@ -157,9 +159,9 @@ namespace auto vs = device->createShaderModule(cocos2d::backend::ShaderStage::VERTEX, vert); auto fs = device->createShaderModule(cocos2d::backend::ShaderStage::FRAGMENT, frag); renderPipelineDescriptor.program = device->createProgram(vs, fs); - _modelLocation = renderPipelineDescriptor.program->getUniformLocation("model"); - _viewLocation = renderPipelineDescriptor.program->getUniformLocation("view"); - _projectionLocation = renderPipelineDescriptor.program->getUniformLocation("projection"); + _modelLocation = renderPipelineDescriptor.program->getVertexUniformLocation("model"); + _viewLocation = renderPipelineDescriptor.program->getVertexUniformLocation("view"); + _projectionLocation = renderPipelineDescriptor.program->getVertexUniformLocation("projection"); backend::VertexLayout vertexLayout; vertexLayout.setLayout(3 * sizeof(float), cocos2d::backend::VertexStepMode::VERTEX); @@ -234,7 +236,7 @@ DepthTextureBackend::DepthTextureBackend() textureDescriptor.samplerDescriptor = samplerDescriptor; textureDescriptor.textureFormat = backend::TextureFormat::D24S8; _depthTexture = device->newTexture(textureDescriptor); - bg->getProgram()->setTexture("texture", 0, _depthTexture); + bg->getProgram()->setFragmentTexture(bg->_textureLocation, 0, _depthTexture); // render pass Bunny 1 _renderPassBunny1.clearDepthValue = 1; diff --git a/test/tests/backend/GuiProjectionBackend.cpp b/test/tests/backend/GuiProjectionBackend.cpp index e73441f..c49010c 100644 --- a/test/tests/backend/GuiProjectionBackend.cpp +++ b/test/tests/backend/GuiProjectionBackend.cpp @@ -69,9 +69,10 @@ GuiProjectionBackend::GuiProjectionBackend() auto vs = device->createShaderModule(backend::ShaderStage::VERTEX, vert); auto fs = device->createShaderModule(backend::ShaderStage::FRAGMENT, frag); renderPipelineDescriptor.program = device->createProgram(vs, fs); - _colorLocation = renderPipelineDescriptor.program->getUniformLocation("color"); - _projectionLocation = renderPipelineDescriptor.program->getUniformLocation("projection"); - _transformLocation = renderPipelineDescriptor.program->getUniformLocation("transform"); + _colorLocation = renderPipelineDescriptor.program->getFragmentUniformLocation("color"); + _projectionLocation = renderPipelineDescriptor.program->getVertexUniformLocation("projection"); + _transformLocation = renderPipelineDescriptor.program->getVertexUniformLocation("transform"); + _textureLocation = renderPipelineDescriptor.program->getFragmentUniformLocation("texture"); #define VERTEX_POSITION_SIZE 2 #define VERTEX_UV_SIZE 2 @@ -100,7 +101,7 @@ GuiProjectionBackend::GuiProjectionBackend() textureDescriptor.height = img->getHeight(); _texture = device->newTexture(textureDescriptor); _texture->updateData(data.getBytes()); - _renderPipeline->getProgram()->setTexture("texture", 0, _texture); + _renderPipeline->getProgram()->setFragmentTexture(_textureLocation, 0, _texture); img->release(); diff --git a/test/tests/backend/GuiProjectionBackend.h b/test/tests/backend/GuiProjectionBackend.h index 794d32b..d701ec1 100644 --- a/test/tests/backend/GuiProjectionBackend.h +++ b/test/tests/backend/GuiProjectionBackend.h @@ -52,6 +52,7 @@ class GuiProjectionBackend : public TestBaseI int _colorLocation = -1; int _projectionLocation = -1; int _transformLocation = -1; + int _textureLocation = -1; }; diff --git a/test/tests/backend/MultiTexturesBackend.cpp b/test/tests/backend/MultiTexturesBackend.cpp index f1c9161..03f4558 100644 --- a/test/tests/backend/MultiTexturesBackend.cpp +++ b/test/tests/backend/MultiTexturesBackend.cpp @@ -70,8 +70,10 @@ MultiTexturesBackend::MultiTexturesBackend() auto vs = device->createShaderModule(cocos2d::backend::ShaderStage::VERTEX, vert); auto fs = device->createShaderModule(cocos2d::backend::ShaderStage::FRAGMENT, frag); renderPipelineDescriptor.program = device->createProgram(vs, fs); - _transformLocation = renderPipelineDescriptor.program->getUniformLocation("transform"); - _colorLocation = renderPipelineDescriptor.program->getUniformLocation("color"); + _transformLocation = renderPipelineDescriptor.program->getVertexUniformLocation("transform"); + _colorLocation = renderPipelineDescriptor.program->getFragmentUniformLocation("color"); + _texture1Location = renderPipelineDescriptor.program->getFragmentUniformLocation("texture1"); + _texture2Location = renderPipelineDescriptor.program->getFragmentUniformLocation("texture2"); backend::VertexLayout vertexLayout; vertexLayout.setAtrribute("a_position", 0, cocos2d::backend::VertexFormat::FLOAT_R32G32, 0); @@ -94,7 +96,7 @@ MultiTexturesBackend::MultiTexturesBackend() textureDescriptor1.textureFormat = backend::TextureFormat::R8G8B8; _texture1 = device->newTexture(textureDescriptor1); _texture1->updateData(utils::loadData("assets/uv_checker_01.jpg").getBytes()); - _renderPipeline->getProgram()->setTexture("texture2", 7, _texture1); + _renderPipeline->getProgram()->setFragmentTexture(_texture2Location, 7, _texture1); int dataSize = 512 * 512 * 3; uint8_t data[dataSize]; @@ -110,8 +112,8 @@ MultiTexturesBackend::MultiTexturesBackend() textureDescriptor2.textureFormat = backend::TextureFormat::R8G8B8; _background = device->newTexture(textureDescriptor2); _background->updateData(data); - _renderPipeline->getProgram()->setTexture("texture1", 6, _background); - + _renderPipeline->getProgram()->setFragmentTexture(_texture1Location, 6, _background); + _transform = cocos2d::Mat4::IDENTITY; _transform.translate(0, 0, 0); _transform.scale(0.5, 0.5, 0.5); diff --git a/test/tests/backend/MultiTexturesBackend.h b/test/tests/backend/MultiTexturesBackend.h index f8967fa..7743cbb 100644 --- a/test/tests/backend/MultiTexturesBackend.h +++ b/test/tests/backend/MultiTexturesBackend.h @@ -48,4 +48,6 @@ class MultiTexturesBackend : public TestBaseI int _transformLocation = -1; int _colorLocation = -1; + int _texture1Location = -1; + int _texture2Location = -1; }; diff --git a/test/tests/backend/ParticleBackend.cpp b/test/tests/backend/ParticleBackend.cpp index 792c3aa..4807f29 100644 --- a/test/tests/backend/ParticleBackend.cpp +++ b/test/tests/backend/ParticleBackend.cpp @@ -78,9 +78,10 @@ ParticleBackend::ParticleBackend() auto vs = device->createShaderModule(backend::ShaderStage::VERTEX, vert); auto fs = device->createShaderModule(backend::ShaderStage::FRAGMENT, frag); renderPipelineDescriptor.program = device->createProgram(vs, fs); - _modelLocation = renderPipelineDescriptor.program->getUniformLocation("model"); - _viewLocation = renderPipelineDescriptor.program->getUniformLocation("view"); - _projectionLocation = renderPipelineDescriptor.program->getUniformLocation("projection"); + _modelLocation = renderPipelineDescriptor.program->getVertexUniformLocation("model"); + _viewLocation = renderPipelineDescriptor.program->getVertexUniformLocation("view"); + _projectionLocation = renderPipelineDescriptor.program->getVertexUniformLocation("projection"); + _textureLocation = renderPipelineDescriptor.program->getFragmentUniformLocation("u_texture"); #define VERTEX_QUAD_SIZE 2 #define VERTEX_POS_SIZE 3 @@ -131,7 +132,7 @@ ParticleBackend::ParticleBackend() textureDescriptor.samplerDescriptor.mipmapEnabled = true; _texture = device->newTexture(textureDescriptor); _texture->updateData(imageData.getBytes()); - _renderPipelineWithBlend->getProgram()->setTexture("u_texture", 0, _texture); + _renderPipelineWithBlend->getProgram()->setFragmentTexture(_textureLocation, 0, _texture); _commandBuffer = device->newCommandBuffer(); _vertexBuffer = device->newBuffer(sizeof(_vbufferArray), backend::BufferType::VERTEX, backend::BufferUsage::READ); diff --git a/test/tests/backend/ParticleBackend.h b/test/tests/backend/ParticleBackend.h index 7189100..a5d7eb7 100644 --- a/test/tests/backend/ParticleBackend.h +++ b/test/tests/backend/ParticleBackend.h @@ -69,5 +69,6 @@ class ParticleBackend : public TestBaseI int _modelLocation = -1; int _viewLocation = -1; int _projectionLocation = -1; + int _textureLocation = -1; }; diff --git a/test/tests/backend/PostProcessBackend.cpp b/test/tests/backend/PostProcessBackend.cpp index bed2e81..d582dcb 100644 --- a/test/tests/backend/PostProcessBackend.cpp +++ b/test/tests/backend/PostProcessBackend.cpp @@ -95,6 +95,7 @@ namespace auto vs = device->createShaderModule(backend::ShaderStage::VERTEX, vert); auto fs = device->createShaderModule(backend::ShaderStage::FRAGMENT, frag); renderPipelineDescriptor.program = device->createProgram(vs, fs); + _textureLocation = renderPipelineDescriptor.program->getFragmentUniformLocation("texture"); backend::VertexLayout vertexLayout; vertexLayout.setAtrribute("a_position", 0, backend::VertexFormat::FLOAT_R32G32, 0); @@ -119,6 +120,7 @@ namespace backend::Buffer* _vertexBuffer = nullptr; backend::RenderPipeline* _renderPipeline = nullptr; + int _textureLocation = -1; }; struct Bunny @@ -167,10 +169,10 @@ namespace auto fs = device->createShaderModule(backend::ShaderStage::FRAGMENT, frag); renderPipelineDescriptor.program = device->createProgram(vs, fs); - _modelLocation = renderPipelineDescriptor.program->getUniformLocation("model"); - _viewLocation = renderPipelineDescriptor.program->getUniformLocation("view"); - _projectionLocation = renderPipelineDescriptor.program->getUniformLocation("projection"); - _colorLocation = renderPipelineDescriptor.program->getUniformLocation("color"); + _modelLocation = renderPipelineDescriptor.program->getVertexUniformLocation("model"); + _viewLocation = renderPipelineDescriptor.program->getVertexUniformLocation("view"); + _projectionLocation = renderPipelineDescriptor.program->getVertexUniformLocation("projection"); + _colorLocation = renderPipelineDescriptor.program->getFragmentUniformLocation("color"); backend::VertexLayout vertexLayout; vertexLayout.setAtrribute("a_position", 0, backend::VertexFormat::FLOAT_R32G32B32, 0); @@ -340,7 +342,7 @@ void PostProcessBackend::tick(float dt) // Draw bg. _commandBuffer->beginRenderPass(_renderPassDescriptorBg); - bg->getProgram()->setTexture("texture", 0, _colorTexture); + bg->getProgram()->setFragmentTexture(bg->_textureLocation, 0, _colorTexture); _commandBuffer->setRenderPipeline(bg->_renderPipeline); _commandBuffer->setVertexBuffer(0, bg->_vertexBuffer); _commandBuffer->drawArrays(backend::PrimitiveType::TRIANGLE, 0, 3); diff --git a/test/tests/backend/StencilBackend.cpp b/test/tests/backend/StencilBackend.cpp index f7f25a4..6d651fb 100644 --- a/test/tests/backend/StencilBackend.cpp +++ b/test/tests/backend/StencilBackend.cpp @@ -95,8 +95,9 @@ StencilBackend::StencilBackend() auto vs = device->createShaderModule(cocos2d::backend::ShaderStage::VERTEX, vert); auto fs = device->createShaderModule(cocos2d::backend::ShaderStage::FRAGMENT, frag); renderPipelineDescriptor.program = device->createProgram(vs, fs); - _transformLocation = renderPipelineDescriptor.program->getUniformLocation("transform"); - _colorLocation = renderPipelineDescriptor.program->getUniformLocation("color"); + _transformLocation = renderPipelineDescriptor.program->getVertexUniformLocation("transform"); + _colorLocation = renderPipelineDescriptor.program->getFragmentUniformLocation("color"); + _textureLocation = renderPipelineDescriptor.program->getFragmentUniformLocation("texture"); backend::VertexLayout vertexLayout; vertexLayout.setAtrribute("a_position", 0, cocos2d::backend::VertexFormat::FLOAT_R32G32, 0); @@ -191,7 +192,7 @@ void StencilBackend::tick(float dt) _renderPipeline->getProgram()->setFragmentUniform(_colorLocation, color, sizeof(color)); _renderPipeline->getProgram()->setVertexUniform(_transformLocation, _transform0.m, sizeof(_transform0.m)); - _renderPipeline->getProgram()->setTexture("texture", 0, _canvasTexture); + _renderPipeline->getProgram()->setFragmentTexture(_textureLocation, 0, _canvasTexture); _commandBuffer->drawArrays(cocos2d::backend::PrimitiveType::TRIANGLE, 0, 6); @@ -209,7 +210,7 @@ void StencilBackend::tick(float dt) _commandBuffer->setVertexBuffer(0, _vertexBuffer); _commandBuffer->setCullMode(backend::CullMode::NONE); - _renderPipeline->getProgram()->setTexture("texture", 0, _texture); + _renderPipeline->getProgram()->setFragmentTexture(_textureLocation, 0, _texture); _renderPipeline->getProgram()->setVertexUniform(_transformLocation, _transform1.m, sizeof(_transform1.m)); _commandBuffer->drawArrays(cocos2d::backend::PrimitiveType::TRIANGLE, 0, 6); @@ -229,7 +230,7 @@ void StencilBackend::tick(float dt) _commandBuffer->setRenderPipeline(_renderPipelineCavasTexture); _renderPipeline->getProgram()->setVertexUniform(_transformLocation, _transform0.m, sizeof(_transform0.m)); - _renderPipeline->getProgram()->setTexture("texture", 0, _canvasTexture); + _renderPipeline->getProgram()->setFragmentTexture(_textureLocation, 0, _canvasTexture); _commandBuffer->drawArrays(cocos2d::backend::PrimitiveType::TRIANGLE, 0, 6); _commandBuffer->endRenderPass(); } @@ -242,7 +243,7 @@ void StencilBackend::tick(float dt) _commandBuffer->setVertexBuffer(0, _vertexBuffer); _commandBuffer->setCullMode(backend::CullMode::NONE); - _renderPipeline->getProgram()->setTexture("texture", 0, _texture); + _renderPipeline->getProgram()->setFragmentTexture(_textureLocation, 0, _texture); _renderPipeline->getProgram()->setVertexUniform(_transformLocation, _transform1.m, sizeof(_transform1.m)); _commandBuffer->drawArrays(cocos2d::backend::PrimitiveType::TRIANGLE, 0, 6); @@ -261,7 +262,7 @@ void StencilBackend::tick(float dt) _commandBuffer->setRenderPipeline(_renderPipelineCavasTexture); _renderPipeline->getProgram()->setVertexUniform(_transformLocation, _transform0.m, sizeof(_transform0.m)); - _renderPipeline->getProgram()->setTexture("texture", 0, _canvasTexture); + _renderPipeline->getProgram()->setFragmentTexture(_textureLocation, 0, _canvasTexture); _commandBuffer->drawArrays(cocos2d::backend::PrimitiveType::TRIANGLE, 0, 6); _commandBuffer->endRenderPass(); } @@ -274,7 +275,7 @@ void StencilBackend::tick(float dt) _commandBuffer->setVertexBuffer(0, _vertexBuffer); _commandBuffer->setCullMode(backend::CullMode::NONE); - _renderPipeline->getProgram()->setTexture("texture", 0, _texture); + _renderPipeline->getProgram()->setFragmentTexture(_textureLocation, 0, _texture); _renderPipeline->getProgram()->setVertexUniform(_transformLocation, _transform1.m, sizeof(_transform1.m)); _commandBuffer->drawArrays(cocos2d::backend::PrimitiveType::TRIANGLE, 0, 6); @@ -292,7 +293,7 @@ void StencilBackend::tick(float dt) _commandBuffer->setRenderPipeline(_renderPipelineCavasTexture); _renderPipeline->getProgram()->setVertexUniform(_transformLocation, _transform0.m, sizeof(_transform0.m)); - _renderPipeline->getProgram()->setTexture("texture", 0, _canvasTexture); + _renderPipeline->getProgram()->setFragmentTexture(_textureLocation, 0, _canvasTexture); _commandBuffer->drawArrays(cocos2d::backend::PrimitiveType::TRIANGLE, 0, 6); _commandBuffer->endRenderPass(); } @@ -305,7 +306,7 @@ void StencilBackend::tick(float dt) _commandBuffer->setStencilReferenceValue(0x1); _commandBuffer->setCullMode(backend::CullMode::NONE); - _renderPipeline->getProgram()->setTexture("texture", 0, _texture); + _renderPipeline->getProgram()->setFragmentTexture(_textureLocation, 0, _texture); _renderPipeline->getProgram()->setVertexUniform(_transformLocation, _transform1.m, sizeof(_transform1.m)); _commandBuffer->drawArrays(cocos2d::backend::PrimitiveType::TRIANGLE, 0, 6); diff --git a/test/tests/backend/StencilBackend.h b/test/tests/backend/StencilBackend.h index 0884cbc..02dc5ed 100644 --- a/test/tests/backend/StencilBackend.h +++ b/test/tests/backend/StencilBackend.h @@ -54,6 +54,7 @@ class StencilBackend : public TestBaseI int _transformLocation = -1; int _colorLocation = -1; + int _textureLocation = -1; }; diff --git a/test/tests/backend/SubImageBackend.cpp b/test/tests/backend/SubImageBackend.cpp index e268dd4..41659c9 100644 --- a/test/tests/backend/SubImageBackend.cpp +++ b/test/tests/backend/SubImageBackend.cpp @@ -62,6 +62,7 @@ SubImageBackend::SubImageBackend() auto vs = device->createShaderModule(backend::ShaderStage::VERTEX, vert); auto fs = device->createShaderModule(backend::ShaderStage::FRAGMENT, frag); renderPipelineDescriptor.program = device->createProgram(vs, fs); + _textureLocation = renderPipelineDescriptor.program->getFragmentUniformLocation("texture"); backend::VertexLayout vertexLayout; vertexLayout.setAtrribute("a_position", 0, backend::VertexFormat::FLOAT_R32G32, 0); @@ -131,7 +132,7 @@ void SubImageBackend::tick(float dt) _commandBuffer->setVertexBuffer(0, _vertexBuffer); - _renderPipeline->getProgram()->setTexture("texture", 0, _texture); + _renderPipeline->getProgram()->setFragmentTexture(_textureLocation, 0, _texture); _commandBuffer->drawArrays(backend::PrimitiveType::TRIANGLE, 0, 6); _commandBuffer->endRenderPass(); diff --git a/test/tests/backend/SubImageBackend.h b/test/tests/backend/SubImageBackend.h index 68d3274..76c55a1 100644 --- a/test/tests/backend/SubImageBackend.h +++ b/test/tests/backend/SubImageBackend.h @@ -48,6 +48,8 @@ class SubImageBackend : public TestBaseI uint8_t* _data; size_t _dataSize; size_t _updatePixelIndex; + + int _textureLocation = 0; }; diff --git a/test/tests/backend/Texture2DBackend.cpp b/test/tests/backend/Texture2DBackend.cpp index 66ecc7a..53d693a 100644 --- a/test/tests/backend/Texture2DBackend.cpp +++ b/test/tests/backend/Texture2DBackend.cpp @@ -121,8 +121,9 @@ Texture2DBackendTest::Texture2DBackendTest() auto vs = device->createShaderModule(cocos2d::backend::ShaderStage::VERTEX, vert); auto fs = device->createShaderModule(cocos2d::backend::ShaderStage::FRAGMENT, frag); renderPipelineDescriptor.program = device->createProgram(vs, fs); - _transformLocation = renderPipelineDescriptor.program->getUniformLocation("transform"); - _colorLocation = renderPipelineDescriptor.program->getUniformLocation("color"); + _transformLocation = renderPipelineDescriptor.program->getVertexUniformLocation("transform"); + _colorLocation = renderPipelineDescriptor.program->getFragmentUniformLocation("color"); + _textureLocation = renderPipelineDescriptor.program->getFragmentUniformLocation("texture"); VertexLayout vertexLayout; vertexLayout.setAtrribute("a_position", 0, cocos2d::backend::VertexFormat::FLOAT_R32G32, 0); @@ -165,7 +166,7 @@ void Texture2DBackendTest::tick(float dt) _commandBuffer->setViewport(0, 0, utils::WINDOW_WIDTH, utils::WINDOW_HEIGHT); _commandBuffer->setVertexBuffer(0, _vertexBuffer); _renderPipeline->getProgram()->setVertexUniform(_transformLocation, _transform0.m, sizeof(_transform0.m)); - _renderPipeline->getProgram()->setTexture("texture", 0, _canvasTexture); + _renderPipeline->getProgram()->setFragmentTexture(_textureLocation, 0, _canvasTexture); _commandBuffer->drawArrays(cocos2d::backend::PrimitiveType::TRIANGLE, 0, 6); _commandBuffer->endRenderPass(); @@ -180,7 +181,7 @@ void Texture2DBackendTest::tick(float dt) _commandBuffer->setVertexBuffer(0, _vertexBuffer); _renderPipeline->getProgram()->setVertexUniform(_transformLocation, _transform1.m, sizeof(_transform1.m)); - _renderPipeline->getProgram()->setTexture("texture", 0, _texture); + _renderPipeline->getProgram()->setFragmentTexture(_textureLocation, 0, _texture); _commandBuffer->drawArrays(cocos2d::backend::PrimitiveType::TRIANGLE, 0, 6); _commandBuffer->endRenderPass(); diff --git a/test/tests/backend/Texture2DBackend.h b/test/tests/backend/Texture2DBackend.h index 88190d5..5b644fc 100644 --- a/test/tests/backend/Texture2DBackend.h +++ b/test/tests/backend/Texture2DBackend.h @@ -55,6 +55,7 @@ class Texture2DBackendTest : public TestBaseI int _transformLocation = -1; int _colorLocation = -1; + int _textureLocation = -1; }; From 2152f8e552ccad78fc5ed6625e3bacfc6de30f93 Mon Sep 17 00:00:00 2001 From: coulsonwang Date: Sun, 6 Jan 2019 16:17:43 +0800 Subject: [PATCH 07/11] [Feature] remove unneeded code --- src/backend/Program.h | 2 -- src/backend/metal/ShaderModuleMTL.h | 2 -- 2 files changed, 4 deletions(-) diff --git a/src/backend/Program.h b/src/backend/Program.h index 24a650f..9380b6d 100644 --- a/src/backend/Program.h +++ b/src/backend/Program.h @@ -45,8 +45,6 @@ class Program : public Ref void setTexture(int location, uint32_t slot, Texture* texture, std::vector& textureInfo); void setTextureArray(int location, const std::vector& slots, const std::vector textures, std::vector& textureInfo); - ShaderModule* _vertexShader = nullptr; - ShaderModule* _fragmentShader = nullptr; std::vector _vertexTextureInfos; std::vector _fragTextureInfos; }; diff --git a/src/backend/metal/ShaderModuleMTL.h b/src/backend/metal/ShaderModuleMTL.h index 6624fca..03c981a 100644 --- a/src/backend/metal/ShaderModuleMTL.h +++ b/src/backend/metal/ShaderModuleMTL.h @@ -32,8 +32,6 @@ class ShaderModuleMTL : public ShaderModule std::shared_ptr _uniformBuffer = nullptr; std::unordered_map _uniforms; uint32_t _uniformBufferSize = 0; - - // Texture index is the same as vector index. uint32_t _uniformTextureCount = 0; }; From c38092cf2c0170aec724c53633bff4d4790c2be5 Mon Sep 17 00:00:00 2001 From: coulsonwang Date: Mon, 7 Jan 2019 11:18:05 +0800 Subject: [PATCH 08/11] [Feature] use unordered_map to simply code --- src/backend/Program.cpp | 14 +++--- src/backend/Program.h | 13 +++--- src/backend/RenderPipeline.h | 5 ++- src/backend/metal/CommandBufferMTL.mm | 12 +++--- src/backend/metal/ProgramMTL.mm | 5 --- src/backend/opengl/CommandBufferGL.cpp | 59 +++++++++++++------------- src/backend/opengl/CommandBufferGL.h | 4 +- src/backend/opengl/ProgramGL.cpp | 45 +++----------------- src/backend/opengl/ProgramGL.h | 7 ++- src/backend/opengl/RenderPipelineGL.h | 2 +- 10 files changed, 65 insertions(+), 101 deletions(-) diff --git a/src/backend/Program.cpp b/src/backend/Program.cpp index 7a4ac21..36d9369 100644 --- a/src/backend/Program.cpp +++ b/src/backend/Program.cpp @@ -7,7 +7,7 @@ CC_BACKEND_BEGIN Program::~Program() { _vertexTextureInfos.clear(); - _fragTextureInfos.clear(); + _fragmentTextureInfos.clear(); } Program::TextureInfo::~TextureInfo() @@ -34,7 +34,7 @@ void Program::setVertexTexture(int location, uint32_t slot, Texture* texture) void Program::setFragmentTexture(int location, uint32_t slot, Texture* texture) { - setTexture(location, slot, texture, _fragTextureInfos); + setTexture(location, slot, texture, _fragmentTextureInfos); } void Program::setVertexTextureArray(int location, const std::vector& slots, const std::vector textures) @@ -44,10 +44,10 @@ void Program::setVertexTextureArray(int location, const std::vector& s void Program::setFragmentTextureArray(int location, const std::vector& slots, const std::vector textures) { - setTextureArray(location, slots, textures, _fragTextureInfos); + setTextureArray(location, slots, textures, _fragmentTextureInfos); } -void Program::setTexture(int location, uint32_t slot, Texture* texture, std::vector& textureInfo) +void Program::setTexture(int location, uint32_t slot, Texture* texture, std::unordered_map& textureInfo) { if(location < 0) return; @@ -57,10 +57,10 @@ void Program::setTexture(int location, uint32_t slot, Texture* texture, std::vec info.slot = {slot}; info.textures = {texture}; info.retainTextures(); - textureInfo.at(location) = info; + textureInfo[location] = info; } -void Program::setTextureArray(int location, const std::vector& slots, const std::vector textures, std::vector& textureInfo) +void Program::setTextureArray(int location, const std::vector& slots, const std::vector textures, std::unordered_map& textureInfo) { assert(slots.size() == textures.size()); TextureInfo info; @@ -68,7 +68,7 @@ void Program::setTextureArray(int location, const std::vector& slots, info.slot = slots; info.textures = textures; info.retainTextures(); - textureInfo.at(location) = info; + textureInfo[location] = info; } CC_BACKEND_END diff --git a/src/backend/Program.h b/src/backend/Program.h index 9380b6d..2378108 100644 --- a/src/backend/Program.h +++ b/src/backend/Program.h @@ -5,6 +5,7 @@ #include "platform/CCPlatformMacros.h" #include #include +#include CC_BACKEND_BEGIN @@ -35,18 +36,18 @@ class Program : public Ref virtual void setVertexTextureArray(int location, const std::vector& slots, const std::vector textures); virtual void setFragmentTextureArray(int location, const std::vector& slots, const std::vector textures); - inline const std::vector& getVertexTextureInfos() const { return _vertexTextureInfos; } - inline const std::vector& getFragmentTextureInfos() const { return _fragTextureInfos; } + inline const std::unordered_map& getVertexTextureInfos() const { return _vertexTextureInfos; } + inline const std::unordered_map& getFragmentTextureInfos() const { return _fragmentTextureInfos; } protected: Program() = default; virtual ~Program(); - void setTexture(int location, uint32_t slot, Texture* texture, std::vector& textureInfo); - void setTextureArray(int location, const std::vector& slots, const std::vector textures, std::vector& textureInfo); + void setTexture(int location, uint32_t slot, Texture* texture, std::unordered_map& textureInfo); + void setTextureArray(int location, const std::vector& slots, const std::vector textures, std::unordered_map& textureInfo); - std::vector _vertexTextureInfos; - std::vector _fragTextureInfos; + std::unordered_map _vertexTextureInfos; + std::unordered_map _fragmentTextureInfos; }; CC_BACKEND_END diff --git a/src/backend/RenderPipeline.h b/src/backend/RenderPipeline.h index e0b5e05..2f52316 100644 --- a/src/backend/RenderPipeline.h +++ b/src/backend/RenderPipeline.h @@ -10,12 +10,13 @@ class Program; class RenderPipeline : public cocos2d::Ref { public: - RenderPipeline(Program* program); virtual ~RenderPipeline(); - virtual Program* getProgram() { return _program; } + virtual Program* getProgram() const { return _program; } protected: + RenderPipeline(Program* program); + Program* _program = nullptr; }; diff --git a/src/backend/metal/CommandBufferMTL.mm b/src/backend/metal/CommandBufferMTL.mm index af11210..43940ae 100644 --- a/src/backend/metal/CommandBufferMTL.mm +++ b/src/backend/metal/CommandBufferMTL.mm @@ -278,23 +278,25 @@ MTLCullMode toMTLCullMode(CullMode mode) for(const auto& textureInfo : bindTextureInfos) { int i = 0; + int location = textureInfo.second.location; + //FIXME: should support texture array. - const auto& textures = textureInfo.textures; + const auto& textures = textureInfo.second.textures; const auto& mtlTexture = static_cast(textures[i]); if (isVertex) { [_mtlRenderEncoder setVertexTexture:mtlTexture->getMTLTexture() - atIndex:textureInfo.location]; + atIndex:location]; [_mtlRenderEncoder setVertexSamplerState:mtlTexture->getMTLSamplerState() - atIndex:textureInfo.location]; + atIndex:location]; } else { [_mtlRenderEncoder setFragmentTexture:mtlTexture->getMTLTexture() - atIndex:textureInfo.location]; + atIndex:location]; [_mtlRenderEncoder setFragmentSamplerState:mtlTexture->getMTLSamplerState() - atIndex:textureInfo.location]; + atIndex:location]; } ++i; diff --git a/src/backend/metal/ProgramMTL.mm b/src/backend/metal/ProgramMTL.mm index b7bd2dd..865335f 100644 --- a/src/backend/metal/ProgramMTL.mm +++ b/src/backend/metal/ProgramMTL.mm @@ -9,11 +9,6 @@ { CC_SAFE_RETAIN(_vertexShader); CC_SAFE_RETAIN(_fragmentShader); - - _vertexTextureInfos.reserve(_vertexShader->getUniformTextureCount()); - _vertexTextureInfos.resize(_vertexShader->getUniformTextureCount()); - _fragTextureInfos.reserve(_fragmentShader->getUniformTextureCount()); - _fragTextureInfos.resize(_fragmentShader->getUniformTextureCount()); } ProgramMTL::~ProgramMTL() diff --git a/src/backend/opengl/CommandBufferGL.cpp b/src/backend/opengl/CommandBufferGL.cpp index 4563e35..8b6baf7 100644 --- a/src/backend/opengl/CommandBufferGL.cpp +++ b/src/backend/opengl/CommandBufferGL.cpp @@ -284,7 +284,7 @@ void CommandBufferGL::prepareDrawing() const { glViewport(_viewport.x, _viewport.y, _viewport.w, _viewport.h); - const auto& program = _renderPipeline->getProgram(); + const auto& program = _renderPipeline->getGLProgram(); glUseProgram(program->getHandler()); bindVertexBuffer(program); @@ -315,7 +315,7 @@ void CommandBufferGL::prepareDrawing() const } } -void CommandBufferGL::bindVertexBuffer(ProgramGL *program) const +void CommandBufferGL::bindVertexBuffer(const ProgramGL *program) const { // Bind vertex buffers and set the attributes. int i = 0; @@ -343,41 +343,40 @@ void CommandBufferGL::bindVertexBuffer(ProgramGL *program) const } } -void CommandBufferGL::setUniforms(ProgramGL* program) const +void CommandBufferGL::setUniforms(const ProgramGL* program) const { if (program) { const auto& texutreInfos = program->getFragmentTextureInfos(); const auto& activeUniformInfos = program->getUniformInfos(); - for (const auto& activeUinform : activeUniformInfos) + + // Bind textures. + for(const auto& textureInfo : texutreInfos) { - // Bind textures. - for(const auto& textureInfo : texutreInfos) + int location = textureInfo.first; + const auto& activeUniform = activeUniformInfos.at(location); + assert(location == activeUniform.location); + + const auto& textures = textureInfo.second.textures; + const auto& indices = textureInfo.second.slot; + + int i = 0; + for (const auto& texture: textures) { - if(activeUinform.location != textureInfo.location) - continue; - - const auto& textures = textureInfo.textures; - const auto& indices = textureInfo.slot; - - int i = 0; - for (const auto& texture: textures) - { - static_cast(texture)->apply(indices[i]); - ++i; - } - - switch (activeUinform.type) { - case GL_SAMPLER_2D: - case GL_SAMPLER_CUBE: - if (activeUinform.isArray) - glUniform1iv(activeUinform.location, activeUinform.size, (GLint*)indices.data()); - else - glUniform1i(activeUinform.location, *((GLint*)(indices.data()))); - break; - default: - break; - } + static_cast(texture)->apply(indices[i]); + ++i; + } + + switch (activeUniform.type) { + case GL_SAMPLER_2D: + case GL_SAMPLER_CUBE: + if (activeUniform.isArray) + glUniform1iv(activeUniform.location, activeUniform.size, (GLint*)indices.data()); + else + glUniform1i(activeUniform.location, *((GLint*)(indices.data()))); + break; + default: + break; } } } diff --git a/src/backend/opengl/CommandBufferGL.h b/src/backend/opengl/CommandBufferGL.h index a6d7e5c..bb0516b 100644 --- a/src/backend/opengl/CommandBufferGL.h +++ b/src/backend/opengl/CommandBufferGL.h @@ -41,8 +41,8 @@ class CommandBufferGL : public CommandBuffer }; void prepareDrawing() const; - void bindVertexBuffer(ProgramGL* program) const; - void setUniforms(ProgramGL* program) const; + void bindVertexBuffer(const ProgramGL* program) const; + void setUniforms(const ProgramGL* program) const; void cleanResources(); void applyRenderPassDescriptor(const RenderPassDescriptor& descirptor); diff --git a/src/backend/opengl/ProgramGL.cpp b/src/backend/opengl/ProgramGL.cpp index f5833fa..2f44d1e 100644 --- a/src/backend/opengl/ProgramGL.cpp +++ b/src/backend/opengl/ProgramGL.cpp @@ -111,26 +111,14 @@ namespace } ProgramGL::ProgramGL(ShaderModule* vs, ShaderModule* fs) +: _vertexShaderModule(static_cast(vs)) +, _fragmentShaderModule(static_cast(fs)) { - if(_vertexShaderModule == vs && _fragmentShaderModule == fs) - { - CC_SAFE_RETAIN(_vertexShaderModule); - CC_SAFE_RETAIN(_fragmentShaderModule); - return; - } - - _vertexShaderModule = (static_cast(vs)); - _fragmentShaderModule = (static_cast(fs)); CC_SAFE_RETAIN(_vertexShaderModule); CC_SAFE_RETAIN(_fragmentShaderModule); createProgram(); computeUniformInfos(); - - _vertexTextureInfos.reserve(_maxTextureLocation); - _vertexTextureInfos.resize(_maxTextureLocation); - _fragTextureInfos.reserve(_maxTextureLocation); - _fragTextureInfos.resize(_maxTextureLocation); } ProgramGL::~ProgramGL() @@ -214,19 +202,6 @@ bool ProgramGL::getAttributeLocation(const std::string& attributeName, uint32_t& return true; } -void ProgramGL::setMaxTextureLocation(GLenum type, int location) -{ - switch (type) { - case GL_SAMPLER_2D: - case GL_SAMPLER_CUBE: - _maxTextureLocation = location < _maxTextureLocation ? _maxTextureLocation : location + 1 ; - break; - - default: - break; - } -} - void ProgramGL::computeUniformInfos() { if (!_program) @@ -265,8 +240,7 @@ void ProgramGL::computeUniformInfos() uniform.name = uniformName; uniform.location = glGetUniformLocation(_program, uniformName); - setMaxTextureLocation(uniform.type, uniform.location); - _uniformInfos.push_back(uniform); + _uniformInfos[uniform.location] = uniform; } free(uniformName); } @@ -297,16 +271,9 @@ void ProgramGL::setUniform(int location, void* data, uint32_t size) return; glUseProgram(_program); - for(const auto& uniforn : _uniformInfos) - { - if(uniforn.location == location) - { - memcpy(uniforn.buffer.get(), data, size); - setUniform(uniforn.isArray, uniforn.location, uniforn.size, uniforn.type, uniforn.buffer.get()); - break; - } - } - glUseProgram(0); + const auto& uniform = _uniformInfos[location]; + memcpy(uniform.buffer.get(), data, size); + setUniform(uniform.isArray, uniform.location, uniform.size, uniform.type, uniform.buffer.get()); } #define DEF_TO_INT(pointer, index) (*((GLint*)(pointer) + index)) diff --git a/src/backend/opengl/ProgramGL.h b/src/backend/opengl/ProgramGL.h index c73a3f1..b42a3a4 100644 --- a/src/backend/opengl/ProgramGL.h +++ b/src/backend/opengl/ProgramGL.h @@ -8,6 +8,7 @@ #include "../Program.h" #include +#include CC_BACKEND_BEGIN @@ -47,7 +48,7 @@ class ProgramGL : public Program virtual int getFragmentUniformLocation(const std::string& uniform) const override; inline const std::vector& getAttributeInfos() const { return _attributeInfos; } - inline const std::vector& getUniformInfos() const { return _uniformInfos; } + inline const std::unordered_map& getUniformInfos() const { return _uniformInfos; } inline GLuint getHandler() const { return _program; } void computeAttributeInfos(const RenderPipelineDescriptor& descriptor); @@ -57,15 +58,13 @@ class ProgramGL : public Program void computeUniformInfos(); void setUniform(int location, void* data, uint32_t size); void setUniform(bool isArray, GLuint location, uint32_t size, GLenum uniformType, void* data) const; - void setMaxTextureLocation(GLenum type, int location); GLuint _program = 0; ShaderModuleGL* _vertexShaderModule = nullptr; ShaderModuleGL* _fragmentShaderModule = nullptr; std::vector _attributeInfos; - std::vector _uniformInfos; - uint32_t _maxTextureLocation = 0; + std::unordered_map _uniformInfos; }; CC_BACKEND_END diff --git a/src/backend/opengl/RenderPipelineGL.h b/src/backend/opengl/RenderPipelineGL.h index eff77e8..d429a31 100644 --- a/src/backend/opengl/RenderPipelineGL.h +++ b/src/backend/opengl/RenderPipelineGL.h @@ -19,7 +19,7 @@ class RenderPipelineGL : public RenderPipeline RenderPipelineGL(const RenderPipelineDescriptor& descriptor); ~RenderPipelineGL(); - inline ProgramGL* getProgram() const { return _programGL; } + inline ProgramGL* getGLProgram() const { return _programGL; } inline DepthStencilStateGL* getDepthStencilState() const { return _depthStencilState; } inline BlendStateGL* getBlendState() const { return _blendState; } From 64706e1727fd90e80ed14e688dc8d565fc068c7a Mon Sep 17 00:00:00 2001 From: coulsonwang Date: Mon, 7 Jan 2019 15:29:41 +0800 Subject: [PATCH 09/11] [Feature] add ProgramCache --- src/backend/Backend.h | 3 +- src/backend/Program.cpp | 10 ++++ src/backend/Program.h | 8 ++- src/backend/ProgramCache.cpp | 58 +++++++++++++++++++++ src/backend/ProgramCache.h | 33 ++++++++++++ src/backend/metal/ProgramMTL.mm | 3 +- src/backend/opengl/ProgramGL.cpp | 3 +- test/Test-ios/RootViewController.mm | 2 +- test/Test.xcodeproj/project.pbxproj | 8 +++ test/macOS/main.mm | 4 +- test/tests/backend/BasicBackend.cpp | 8 +-- test/tests/backend/BlendingBackend.cpp | 8 +-- test/tests/backend/BunnyBackend.cpp | 7 +-- test/tests/backend/DepthTextureBackend.cpp | 8 +-- test/tests/backend/GuiProjectionBackend.cpp | 4 +- test/tests/backend/MultiTexturesBackend.cpp | 4 +- test/tests/backend/ParticleBackend.cpp | 4 +- test/tests/backend/PostProcessBackend.cpp | 12 ++--- test/tests/backend/PostProcessBackend.h | 2 +- test/tests/backend/StencilBackend.cpp | 5 +- test/tests/backend/SubImageBackend.cpp | 5 +- test/tests/backend/SubImageBackend.h | 4 +- test/tests/backend/Texture2DBackend.cpp | 6 +-- 23 files changed, 146 insertions(+), 63 deletions(-) create mode 100644 src/backend/ProgramCache.cpp create mode 100644 src/backend/ProgramCache.h diff --git a/src/backend/Backend.h b/src/backend/Backend.h index 144f6e3..c65d517 100644 --- a/src/backend/Backend.h +++ b/src/backend/Backend.h @@ -8,8 +8,7 @@ #include "backend/CommandBuffer.h" #include "backend/Buffer.h" #include "backend/VertexLayout.h" -#include "backend/ShaderModule.h" #include "backend/Texture.h" #include "backend/DepthStencilState.h" #include "backend/BlendState.h" -#include "backend/Program.h" +#include "backend/ProgramCache.h" diff --git a/src/backend/Program.cpp b/src/backend/Program.cpp index 36d9369..c1d08b2 100644 --- a/src/backend/Program.cpp +++ b/src/backend/Program.cpp @@ -4,8 +4,18 @@ CC_BACKEND_BEGIN +Program::Program(ShaderModule* vs, ShaderModule* fs) +: _vertexShader(vs) +, _fragmentShader(fs) +{ + CC_SAFE_RETAIN(_vertexShader); + CC_SAFE_RETAIN(_fragmentShader); +} + Program::~Program() { + CC_SAFE_RELEASE(_vertexShader); + CC_SAFE_RELEASE(_fragmentShader); _vertexTextureInfos.clear(); _fragmentTextureInfos.clear(); } diff --git a/src/backend/Program.h b/src/backend/Program.h index 2378108..f8dced7 100644 --- a/src/backend/Program.h +++ b/src/backend/Program.h @@ -39,8 +39,11 @@ class Program : public Ref inline const std::unordered_map& getVertexTextureInfos() const { return _vertexTextureInfos; } inline const std::unordered_map& getFragmentTextureInfos() const { return _fragmentTextureInfos; } + inline const ShaderModule* getVertexShaderModule() const { return _vertexShader; } + inline const ShaderModule* getFragmentShaderModule() const { return _fragmentShader; } + protected: - Program() = default; + Program(ShaderModule* vs, ShaderModule* fs); virtual ~Program(); void setTexture(int location, uint32_t slot, Texture* texture, std::unordered_map& textureInfo); @@ -48,6 +51,9 @@ class Program : public Ref std::unordered_map _vertexTextureInfos; std::unordered_map _fragmentTextureInfos; + + ShaderModule* _vertexShader = nullptr; + ShaderModule* _fragmentShader = nullptr; }; CC_BACKEND_END diff --git a/src/backend/ProgramCache.cpp b/src/backend/ProgramCache.cpp new file mode 100644 index 0000000..5bbba6f --- /dev/null +++ b/src/backend/ProgramCache.cpp @@ -0,0 +1,58 @@ +#include "ProgramCache.h" +#include "Program.h" +#include "Device.h" +#include "ShaderModule.h" + +CC_BACKEND_BEGIN + +std::unordered_map ProgramCache::_cachedPrograms; +static ProgramCache *_sharedProgramCache = nullptr; + +ProgramCache* ProgramCache::getInstance() +{ + if(!_sharedProgramCache) + { + _sharedProgramCache = new (std::nothrow) ProgramCache(); + if(!_sharedProgramCache) + { + CC_SAFE_RELEASE(_sharedProgramCache); + } + } + return _sharedProgramCache; +} + +void ProgramCache::destroyInstance() +{ + CC_SAFE_RELEASE_NULL(_sharedProgramCache); +} + +ProgramCache::~ProgramCache() +{ + for(auto& program : _cachedPrograms) + { + CC_SAFE_RELEASE(program.second); + } + CCLOGINFO("deallocing ProgramCache: %p", this); +} + +backend::Program* ProgramCache::newProgram(const std::string &vertexShader, const std::string &fragmentShader) +{ + std::string shaderSource = vertexShader + fragmentShader; + std::size_t key = std::hash{}(shaderSource); + const auto& iter = ProgramCache::_cachedPrograms.find(key); + if (ProgramCache::_cachedPrograms.end() != iter) + { + return iter->second; + } + + auto vertexShaderModule = backend::Device::getInstance()->createShaderModule(backend::ShaderStage::VERTEX, vertexShader); + auto fragmentShaderModule = backend::Device::getInstance()->createShaderModule(backend::ShaderStage::FRAGMENT, fragmentShader); + auto program = backend::Device::getInstance()->createProgram(vertexShaderModule, fragmentShaderModule); + CC_SAFE_RETAIN(program); + + ProgramCache::_cachedPrograms.emplace(key, program); + + return program; +} + +CC_BACKEND_END diff --git a/src/backend/ProgramCache.h b/src/backend/ProgramCache.h new file mode 100644 index 0000000..a96336a --- /dev/null +++ b/src/backend/ProgramCache.h @@ -0,0 +1,33 @@ +#pragma once + +#include "Macros.h" +#include "base/CCRef.h" +#include "platform/CCPlatformMacros.h" +#include "Program.h" + +#include +#include + +CC_BACKEND_BEGIN + +class ShaderModule; + +class ProgramCache : public Ref +{ +public: + /** returns the shared instance */ + static ProgramCache* getInstance(); + + /** purges the cache. It releases the retained instance. */ + static void destroyInstance(); + + backend::Program* newProgram(const std::string& vertexShader, const std::string& fragmentShader); + +protected: + ProgramCache() = default; + virtual ~ProgramCache(); + + static std::unordered_map _cachedPrograms; +}; + +CC_BACKEND_END diff --git a/src/backend/metal/ProgramMTL.mm b/src/backend/metal/ProgramMTL.mm index 865335f..b11ae76 100644 --- a/src/backend/metal/ProgramMTL.mm +++ b/src/backend/metal/ProgramMTL.mm @@ -4,7 +4,8 @@ CC_BACKEND_BEGIN ProgramMTL::ProgramMTL(ShaderModule* vs, ShaderModule* fs) -: _vertexShader(static_cast(vs)) +: Program(vs, fs) +, _vertexShader(static_cast(vs)) , _fragmentShader(static_cast(fs)) { CC_SAFE_RETAIN(_vertexShader); diff --git a/src/backend/opengl/ProgramGL.cpp b/src/backend/opengl/ProgramGL.cpp index 2f44d1e..5d6d941 100644 --- a/src/backend/opengl/ProgramGL.cpp +++ b/src/backend/opengl/ProgramGL.cpp @@ -111,7 +111,8 @@ namespace } ProgramGL::ProgramGL(ShaderModule* vs, ShaderModule* fs) -: _vertexShaderModule(static_cast(vs)) +: Program(vs, fs) +, _vertexShaderModule(static_cast(vs)) , _fragmentShaderModule(static_cast(fs)) { CC_SAFE_RETAIN(_vertexShaderModule); diff --git a/test/Test-ios/RootViewController.mm b/test/Test-ios/RootViewController.mm index 787ebe9..8ffd81f 100644 --- a/test/Test-ios/RootViewController.mm +++ b/test/Test-ios/RootViewController.mm @@ -18,7 +18,7 @@ #include "backend/ParticleBackend.h" #include "backend/GuiProjectionBackend.h" -#include "../Tests/Utils.h" +#include "../tests/Utils.h" namespace { diff --git a/test/Test.xcodeproj/project.pbxproj b/test/Test.xcodeproj/project.pbxproj index 0e96d71..f37d07e 100644 --- a/test/Test.xcodeproj/project.pbxproj +++ b/test/Test.xcodeproj/project.pbxproj @@ -188,6 +188,8 @@ 46F9B75121B66D7E009DF858 /* SubImageBackend.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 461F45B12178570700D83671 /* SubImageBackend.cpp */; }; 46F9B75221B66DA3009DF858 /* PostProcessBackend.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 461F45AC217719F700D83671 /* PostProcessBackend.cpp */; }; 46F9B75321B67334009DF858 /* StencilBackend.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 46233BEB2176C978000F1F21 /* StencilBackend.cpp */; }; + ED1B08F721E3011500E1191B /* ProgramCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED1B08F621E3011500E1191B /* ProgramCache.cpp */; }; + ED1B08F821E3011500E1191B /* ProgramCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED1B08F621E3011500E1191B /* ProgramCache.cpp */; }; ED3B4C43217E15C000D982A0 /* GuiProjectionBackend.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED3B4C3E217E15BF00D982A0 /* GuiProjectionBackend.cpp */; }; ED3B4C45217E15C000D982A0 /* ParticleBackend.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED3B4C41217E15C000D982A0 /* ParticleBackend.cpp */; }; ED8D614121DE2BEC00EFB946 /* RenderPipeline.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED8D614021DE2BEC00EFB946 /* RenderPipeline.cpp */; }; @@ -471,6 +473,8 @@ 4694927F1FE252E3008D19CC /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; }; 469492811FE252FB008D19CC /* IOKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOKit.framework; path = System/Library/Frameworks/IOKit.framework; sourceTree = SDKROOT; }; 469492831FE2530E008D19CC /* CoreVideo.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreVideo.framework; path = System/Library/Frameworks/CoreVideo.framework; sourceTree = SDKROOT; }; + ED1B08F521E2FDA000E1191B /* ProgramCache.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ProgramCache.h; sourceTree = ""; }; + ED1B08F621E3011500E1191B /* ProgramCache.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = ProgramCache.cpp; sourceTree = ""; }; ED3B4C3E217E15BF00D982A0 /* GuiProjectionBackend.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GuiProjectionBackend.cpp; sourceTree = ""; }; ED3B4C3F217E15BF00D982A0 /* ParticleBackend.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ParticleBackend.h; sourceTree = ""; }; ED3B4C40217E15C000D982A0 /* GuiProjectionBackend.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GuiProjectionBackend.h; sourceTree = ""; }; @@ -835,6 +839,8 @@ 460373AF212FA9EB00DC9ED4 /* backend */ = { isa = PBXGroup; children = ( + ED1B08F521E2FDA000E1191B /* ProgramCache.h */, + ED1B08F621E3011500E1191B /* ProgramCache.cpp */, EDC86F4B21DCBAE10086A0CA /* Program.cpp */, EDC86F4A21DCBAE10086A0CA /* Program.h */, 460374512148F78600DC9ED4 /* Backend.h */, @@ -1230,6 +1236,7 @@ 1A255E6C20034B0D00069420 /* TGAlib.cpp in Sources */, 1A255E5220034B0D00069420 /* Quaternion.cpp in Sources */, 460375822150C91D00DC9ED4 /* MultiTexturesBackend.cpp in Sources */, + ED1B08F821E3011500E1191B /* ProgramCache.cpp in Sources */, 1A255E3220034B0D00069420 /* CCDirectorCaller-ios.mm in Sources */, 1A255E6A20034B0D00069420 /* ccTypes.cpp in Sources */, 1A255E6820034B0D00069420 /* CCRef.cpp in Sources */, @@ -1353,6 +1360,7 @@ 46E21B4021B8F8E400430A43 /* GuiProjectionBackend.cpp in Sources */, 1A255E4D20034B0D00069420 /* Mat4.cpp in Sources */, EDC86F5321DDA3F00086A0CA /* ProgramMTL.mm in Sources */, + ED1B08F721E3011500E1191B /* ProgramCache.cpp in Sources */, 461DD0ED21538B0100A8E43F /* CommandBuffer.cpp in Sources */, 1A255E5D20034B0D00069420 /* CCAffineTransform.cpp in Sources */, 46E21B3D21B8F4BC00430A43 /* Texture2DBackend.cpp in Sources */, diff --git a/test/macOS/main.mm b/test/macOS/main.mm index 64be9c5..1c91558 100644 --- a/test/macOS/main.mm +++ b/test/macOS/main.mm @@ -22,6 +22,7 @@ #include "../tests/backend/SubImageBackend.h" #include "../tests/backend/ParticleBackend.h" #include "../tests/backend/GuiProjectionBackend.h" +#include "backend/ProgramCache.h" namespace { @@ -110,6 +111,7 @@ int main(int argc, char * argv[]) std::chrono::steady_clock::time_point prevTime; std::chrono::steady_clock::time_point now; float dt = 0.f; + cocos2d::backend::ProgramCache::getInstance(); while (!glfwWindowShouldClose(window)) { prevTime = std::chrono::steady_clock::now(); @@ -121,7 +123,7 @@ int main(int argc, char * argv[]) now = std::chrono::steady_clock::now(); dt = std::chrono::duration_cast(now - prevTime).count() / 1000000.f; } - + cocos2d::backend::ProgramCache::destroyInstance(); glfwDestroyWindow(window); glfwTerminate(); } diff --git a/test/tests/backend/BasicBackend.cpp b/test/tests/backend/BasicBackend.cpp index 4d864b4..db7f8cb 100644 --- a/test/tests/backend/BasicBackend.cpp +++ b/test/tests/backend/BasicBackend.cpp @@ -29,9 +29,8 @@ #include "backend/RenderPipelineDescriptor.h" #include "backend/RenderPassDescriptor.h" -#include "backend/ShaderModule.h" #include "backend/VertexLayout.h" -#include "backend/Program.h" +#include "backend/ProgramCache.h" std::string test_unrollLoops(const std::string& text); @@ -63,11 +62,8 @@ BasicBackend::BasicBackend() )"; auto device = cocos2d::backend::Device::getInstance(); - - auto vs = device->createShaderModule(cocos2d::backend::ShaderStage::VERTEX, vert); - auto fs = device->createShaderModule(cocos2d::backend::ShaderStage::FRAGMENT, frag); cocos2d::backend::RenderPipelineDescriptor renderPipelineDescriptor; - renderPipelineDescriptor.program = device->createProgram(vs, fs); + renderPipelineDescriptor.program = backend::ProgramCache::getInstance()->newProgram(vert, frag); _colorLocation = renderPipelineDescriptor.program->getFragmentUniformLocation("color"); backend::VertexLayout vertexLayout; diff --git a/test/tests/backend/BlendingBackend.cpp b/test/tests/backend/BlendingBackend.cpp index 3354f22..7a581c5 100644 --- a/test/tests/backend/BlendingBackend.cpp +++ b/test/tests/backend/BlendingBackend.cpp @@ -66,9 +66,7 @@ namespace auto device = backend::Device::getInstance(); backend::RenderPipelineDescriptor renderPipelineDescriptor; - auto vs = device->createShaderModule(cocos2d::backend::ShaderStage::VERTEX, vert); - auto fs = device->createShaderModule(cocos2d::backend::ShaderStage::FRAGMENT, frag); - renderPipelineDescriptor.program = device->createProgram(vs, fs); + renderPipelineDescriptor.program = backend::ProgramCache::getInstance()->newProgram(vert, frag); _modelLocation = renderPipelineDescriptor.program->getVertexUniformLocation("model"); _projectionLocation = renderPipelineDescriptor.program->getVertexUniformLocation("projection"); _textureLocation = renderPipelineDescriptor.program->getFragmentUniformLocation("texture"); @@ -220,9 +218,7 @@ namespace auto device = backend::Device::getInstance(); backend::RenderPipelineDescriptor renderPipelineDescriptor; - auto vs = device->createShaderModule(cocos2d::backend::ShaderStage::VERTEX, vert); - auto fs = device->createShaderModule(cocos2d::backend::ShaderStage::FRAGMENT, frag); - renderPipelineDescriptor.program = device->createProgram(vs, fs); + renderPipelineDescriptor.program = backend::ProgramCache::getInstance()->newProgram(vert, frag); _timeLocation = renderPipelineDescriptor.program->getFragmentUniformLocation("time"); _textureLocation = renderPipelineDescriptor.program->getFragmentUniformLocation("texture"); diff --git a/test/tests/backend/BunnyBackend.cpp b/test/tests/backend/BunnyBackend.cpp index a67b3bc..fe86bcb 100644 --- a/test/tests/backend/BunnyBackend.cpp +++ b/test/tests/backend/BunnyBackend.cpp @@ -28,7 +28,7 @@ #include "../Utils.h" #include "backend/Device.h" #include "backend/VertexLayout.h" -#include "backend/Program.h" +#include "backend/ProgramCache.h" using namespace cocos2d; @@ -82,10 +82,7 @@ BunnyBackend::BunnyBackend() auto depthStencilState = device->createDepthStencilState(depthStencilDescriptor); renderPipelineDescriptor.depthStencilState = depthStencilState; - auto vs = device->createShaderModule(cocos2d::backend::ShaderStage::VERTEX, vert); - auto fs = device->createShaderModule(cocos2d::backend::ShaderStage::FRAGMENT, frag); - - renderPipelineDescriptor.program = device->createProgram(vs, fs); + renderPipelineDescriptor.program = backend::ProgramCache::getInstance()->newProgram(vert, frag); _modelLocation = renderPipelineDescriptor.program->getVertexUniformLocation("model"); _viewLocation = renderPipelineDescriptor.program->getVertexUniformLocation("view"); _projectionLocation = renderPipelineDescriptor.program->getVertexUniformLocation("projection"); diff --git a/test/tests/backend/DepthTextureBackend.cpp b/test/tests/backend/DepthTextureBackend.cpp index 59d0307..4f1fef8 100644 --- a/test/tests/backend/DepthTextureBackend.cpp +++ b/test/tests/backend/DepthTextureBackend.cpp @@ -75,9 +75,7 @@ namespace // render pipeline backend::RenderPipelineDescriptor renderPipelineDescriptor; - auto vs = device->createShaderModule(cocos2d::backend::ShaderStage::VERTEX, vert); - auto fs = device->createShaderModule(cocos2d::backend::ShaderStage::FRAGMENT, frag); - renderPipelineDescriptor.program = device->createProgram(vs, fs); + renderPipelineDescriptor.program = backend::ProgramCache::getInstance()->newProgram(vert, frag); _nearLocation = renderPipelineDescriptor.program->getFragmentUniformLocation("near"); _farLocation = renderPipelineDescriptor.program->getFragmentUniformLocation("far"); _textureLocation = renderPipelineDescriptor.program->getFragmentUniformLocation("texture"); @@ -156,9 +154,7 @@ namespace backend::RenderPipelineDescriptor renderPipelineDescriptor; renderPipelineDescriptor.depthAttachmentFormat = backend::TextureFormat::D24S8; renderPipelineDescriptor.colorAttachmentsFormat[0] = backend::TextureFormat::NONE; - auto vs = device->createShaderModule(cocos2d::backend::ShaderStage::VERTEX, vert); - auto fs = device->createShaderModule(cocos2d::backend::ShaderStage::FRAGMENT, frag); - renderPipelineDescriptor.program = device->createProgram(vs, fs); + renderPipelineDescriptor.program = backend::ProgramCache::getInstance()->newProgram(vert, frag); _modelLocation = renderPipelineDescriptor.program->getVertexUniformLocation("model"); _viewLocation = renderPipelineDescriptor.program->getVertexUniformLocation("view"); _projectionLocation = renderPipelineDescriptor.program->getVertexUniformLocation("projection"); diff --git a/test/tests/backend/GuiProjectionBackend.cpp b/test/tests/backend/GuiProjectionBackend.cpp index c49010c..5d21a16 100644 --- a/test/tests/backend/GuiProjectionBackend.cpp +++ b/test/tests/backend/GuiProjectionBackend.cpp @@ -66,9 +66,7 @@ GuiProjectionBackend::GuiProjectionBackend() auto device = backend::Device::getInstance(); backend::RenderPipelineDescriptor renderPipelineDescriptor; - auto vs = device->createShaderModule(backend::ShaderStage::VERTEX, vert); - auto fs = device->createShaderModule(backend::ShaderStage::FRAGMENT, frag); - renderPipelineDescriptor.program = device->createProgram(vs, fs); + renderPipelineDescriptor.program = backend::ProgramCache::getInstance()->newProgram(vert, frag); _colorLocation = renderPipelineDescriptor.program->getFragmentUniformLocation("color"); _projectionLocation = renderPipelineDescriptor.program->getVertexUniformLocation("projection"); _transformLocation = renderPipelineDescriptor.program->getVertexUniformLocation("transform"); diff --git a/test/tests/backend/MultiTexturesBackend.cpp b/test/tests/backend/MultiTexturesBackend.cpp index 03f4558..84e1552 100644 --- a/test/tests/backend/MultiTexturesBackend.cpp +++ b/test/tests/backend/MultiTexturesBackend.cpp @@ -67,9 +67,7 @@ MultiTexturesBackend::MultiTexturesBackend() renderPipelineDescriptor.colorAttachmentsFormat[0] = backend::TextureFormat::SYSTEM_DEFAULT; renderPipelineDescriptor.depthAttachmentFormat = backend::TextureFormat::D24S8; - auto vs = device->createShaderModule(cocos2d::backend::ShaderStage::VERTEX, vert); - auto fs = device->createShaderModule(cocos2d::backend::ShaderStage::FRAGMENT, frag); - renderPipelineDescriptor.program = device->createProgram(vs, fs); + renderPipelineDescriptor.program = backend::ProgramCache::getInstance()->newProgram(vert, frag); _transformLocation = renderPipelineDescriptor.program->getVertexUniformLocation("transform"); _colorLocation = renderPipelineDescriptor.program->getFragmentUniformLocation("color"); _texture1Location = renderPipelineDescriptor.program->getFragmentUniformLocation("texture1"); diff --git a/test/tests/backend/ParticleBackend.cpp b/test/tests/backend/ParticleBackend.cpp index 4807f29..ed3bbd2 100644 --- a/test/tests/backend/ParticleBackend.cpp +++ b/test/tests/backend/ParticleBackend.cpp @@ -75,9 +75,7 @@ ParticleBackend::ParticleBackend() auto device = backend::Device::getInstance(); backend::RenderPipelineDescriptor renderPipelineDescriptor; - auto vs = device->createShaderModule(backend::ShaderStage::VERTEX, vert); - auto fs = device->createShaderModule(backend::ShaderStage::FRAGMENT, frag); - renderPipelineDescriptor.program = device->createProgram(vs, fs); + renderPipelineDescriptor.program = backend::ProgramCache::getInstance()->newProgram(vert, frag); _modelLocation = renderPipelineDescriptor.program->getVertexUniformLocation("model"); _viewLocation = renderPipelineDescriptor.program->getVertexUniformLocation("view"); _projectionLocation = renderPipelineDescriptor.program->getVertexUniformLocation("projection"); diff --git a/test/tests/backend/PostProcessBackend.cpp b/test/tests/backend/PostProcessBackend.cpp index d582dcb..5f03dc6 100644 --- a/test/tests/backend/PostProcessBackend.cpp +++ b/test/tests/backend/PostProcessBackend.cpp @@ -28,7 +28,6 @@ #include "PostProcessBackend.h" #include "BunnyData.h" #include "../Utils.h" -#include "backend/Program.h" using namespace cocos2d; @@ -91,10 +90,8 @@ namespace backend::RenderPipelineDescriptor renderPipelineDescriptor; renderPipelineDescriptor.colorAttachmentsFormat[0] = backend::TextureFormat::SYSTEM_DEFAULT; renderPipelineDescriptor.depthAttachmentFormat = backend::TextureFormat::D24S8; - - auto vs = device->createShaderModule(backend::ShaderStage::VERTEX, vert); - auto fs = device->createShaderModule(backend::ShaderStage::FRAGMENT, frag); - renderPipelineDescriptor.program = device->createProgram(vs, fs); + + renderPipelineDescriptor.program = backend::ProgramCache::getInstance()->newProgram(vert, frag); _textureLocation = renderPipelineDescriptor.program->getFragmentUniformLocation("texture"); backend::VertexLayout vertexLayout; @@ -165,10 +162,7 @@ namespace renderPipelineDescriptor.colorAttachmentsFormat[0] = backend::TextureFormat::R8G8B8A8; renderPipelineDescriptor.depthAttachmentFormat = backend::TextureFormat::D24S8; - auto vs = device->createShaderModule(backend::ShaderStage::VERTEX, vert); - auto fs = device->createShaderModule(backend::ShaderStage::FRAGMENT, frag); - - renderPipelineDescriptor.program = device->createProgram(vs, fs); + renderPipelineDescriptor.program = backend::ProgramCache::getInstance()->newProgram(vert, frag); _modelLocation = renderPipelineDescriptor.program->getVertexUniformLocation("model"); _viewLocation = renderPipelineDescriptor.program->getVertexUniformLocation("view"); _projectionLocation = renderPipelineDescriptor.program->getVertexUniformLocation("projection"); diff --git a/test/tests/backend/PostProcessBackend.h b/test/tests/backend/PostProcessBackend.h index 8c5ed3c..28e5958 100644 --- a/test/tests/backend/PostProcessBackend.h +++ b/test/tests/backend/PostProcessBackend.h @@ -24,7 +24,7 @@ #pragma once -#include "backend/backend.h" +#include "backend/Backend.h" #include "math/Mat4.h" #include "../TestBase.h" diff --git a/test/tests/backend/StencilBackend.cpp b/test/tests/backend/StencilBackend.cpp index 6d651fb..72f0c7e 100644 --- a/test/tests/backend/StencilBackend.cpp +++ b/test/tests/backend/StencilBackend.cpp @@ -25,7 +25,6 @@ #include "StencilBackend.h" #include "cocos2d.h" #include "../Utils.h" -#include "backend/Program.h" #include @@ -92,9 +91,7 @@ StencilBackend::StencilBackend() backend::RenderPipelineDescriptor renderPipelineDescriptor; renderPipelineDescriptor.stencilAttachmentFormat = backend::TextureFormat::D24S8; renderPipelineDescriptor.colorAttachmentsFormat[0] = backend::TextureFormat::SYSTEM_DEFAULT; - auto vs = device->createShaderModule(cocos2d::backend::ShaderStage::VERTEX, vert); - auto fs = device->createShaderModule(cocos2d::backend::ShaderStage::FRAGMENT, frag); - renderPipelineDescriptor.program = device->createProgram(vs, fs); + renderPipelineDescriptor.program = backend::ProgramCache::getInstance()->newProgram(vert, frag); _transformLocation = renderPipelineDescriptor.program->getVertexUniformLocation("transform"); _colorLocation = renderPipelineDescriptor.program->getFragmentUniformLocation("color"); _textureLocation = renderPipelineDescriptor.program->getFragmentUniformLocation("texture"); diff --git a/test/tests/backend/SubImageBackend.cpp b/test/tests/backend/SubImageBackend.cpp index 41659c9..25af8b6 100644 --- a/test/tests/backend/SubImageBackend.cpp +++ b/test/tests/backend/SubImageBackend.cpp @@ -25,7 +25,6 @@ #include "SubImageBackend.h" #include "cocos2d.h" #include "../Utils.h" -#include "backend/Program.h" #include @@ -59,9 +58,7 @@ SubImageBackend::SubImageBackend() auto device = backend::Device::getInstance(); backend::RenderPipelineDescriptor renderPipelineDescriptor; - auto vs = device->createShaderModule(backend::ShaderStage::VERTEX, vert); - auto fs = device->createShaderModule(backend::ShaderStage::FRAGMENT, frag); - renderPipelineDescriptor.program = device->createProgram(vs, fs); + renderPipelineDescriptor.program = backend::ProgramCache::getInstance()->newProgram(vert, frag); _textureLocation = renderPipelineDescriptor.program->getFragmentUniformLocation("texture"); backend::VertexLayout vertexLayout; diff --git a/test/tests/backend/SubImageBackend.h b/test/tests/backend/SubImageBackend.h index 76c55a1..64aa4d2 100644 --- a/test/tests/backend/SubImageBackend.h +++ b/test/tests/backend/SubImageBackend.h @@ -24,9 +24,9 @@ #pragma once -#include "math/mat4.h" +#include "math/Mat4.h" #include "TestBase.h" -#include "backend/backend.h" +#include "backend/Backend.h" class SubImageBackend : public TestBaseI { diff --git a/test/tests/backend/Texture2DBackend.cpp b/test/tests/backend/Texture2DBackend.cpp index 53d693a..ba39b23 100644 --- a/test/tests/backend/Texture2DBackend.cpp +++ b/test/tests/backend/Texture2DBackend.cpp @@ -26,7 +26,7 @@ #include "cocos2d.h" #include "../Utils.h" #include "backend/Device.h" -#include "backend/Program.h" +#include "backend/ProgramCache.h" #include @@ -118,9 +118,7 @@ Texture2DBackendTest::Texture2DBackendTest() // create render pipeline RenderPipelineDescriptor renderPipelineDescriptor; - auto vs = device->createShaderModule(cocos2d::backend::ShaderStage::VERTEX, vert); - auto fs = device->createShaderModule(cocos2d::backend::ShaderStage::FRAGMENT, frag); - renderPipelineDescriptor.program = device->createProgram(vs, fs); + renderPipelineDescriptor.program = backend::ProgramCache::getInstance()->newProgram(vert, frag); _transformLocation = renderPipelineDescriptor.program->getVertexUniformLocation("transform"); _colorLocation = renderPipelineDescriptor.program->getFragmentUniformLocation("color"); _textureLocation = renderPipelineDescriptor.program->getFragmentUniformLocation("texture"); From 10c0698cde6706a164ef7090e0acd776385c74ba Mon Sep 17 00:00:00 2001 From: coulsonwang Date: Mon, 7 Jan 2019 15:38:43 +0800 Subject: [PATCH 10/11] [Feature] remove unneeded code --- src/backend/Program.cpp | 10 ---------- src/backend/Program.h | 8 +------- src/backend/metal/ProgramMTL.mm | 3 +-- src/backend/opengl/ProgramGL.cpp | 3 +-- 4 files changed, 3 insertions(+), 21 deletions(-) diff --git a/src/backend/Program.cpp b/src/backend/Program.cpp index c1d08b2..36d9369 100644 --- a/src/backend/Program.cpp +++ b/src/backend/Program.cpp @@ -4,18 +4,8 @@ CC_BACKEND_BEGIN -Program::Program(ShaderModule* vs, ShaderModule* fs) -: _vertexShader(vs) -, _fragmentShader(fs) -{ - CC_SAFE_RETAIN(_vertexShader); - CC_SAFE_RETAIN(_fragmentShader); -} - Program::~Program() { - CC_SAFE_RELEASE(_vertexShader); - CC_SAFE_RELEASE(_fragmentShader); _vertexTextureInfos.clear(); _fragmentTextureInfos.clear(); } diff --git a/src/backend/Program.h b/src/backend/Program.h index f8dced7..2378108 100644 --- a/src/backend/Program.h +++ b/src/backend/Program.h @@ -39,11 +39,8 @@ class Program : public Ref inline const std::unordered_map& getVertexTextureInfos() const { return _vertexTextureInfos; } inline const std::unordered_map& getFragmentTextureInfos() const { return _fragmentTextureInfos; } - inline const ShaderModule* getVertexShaderModule() const { return _vertexShader; } - inline const ShaderModule* getFragmentShaderModule() const { return _fragmentShader; } - protected: - Program(ShaderModule* vs, ShaderModule* fs); + Program() = default; virtual ~Program(); void setTexture(int location, uint32_t slot, Texture* texture, std::unordered_map& textureInfo); @@ -51,9 +48,6 @@ class Program : public Ref std::unordered_map _vertexTextureInfos; std::unordered_map _fragmentTextureInfos; - - ShaderModule* _vertexShader = nullptr; - ShaderModule* _fragmentShader = nullptr; }; CC_BACKEND_END diff --git a/src/backend/metal/ProgramMTL.mm b/src/backend/metal/ProgramMTL.mm index b11ae76..865335f 100644 --- a/src/backend/metal/ProgramMTL.mm +++ b/src/backend/metal/ProgramMTL.mm @@ -4,8 +4,7 @@ CC_BACKEND_BEGIN ProgramMTL::ProgramMTL(ShaderModule* vs, ShaderModule* fs) -: Program(vs, fs) -, _vertexShader(static_cast(vs)) +: _vertexShader(static_cast(vs)) , _fragmentShader(static_cast(fs)) { CC_SAFE_RETAIN(_vertexShader); diff --git a/src/backend/opengl/ProgramGL.cpp b/src/backend/opengl/ProgramGL.cpp index 5d6d941..2f44d1e 100644 --- a/src/backend/opengl/ProgramGL.cpp +++ b/src/backend/opengl/ProgramGL.cpp @@ -111,8 +111,7 @@ namespace } ProgramGL::ProgramGL(ShaderModule* vs, ShaderModule* fs) -: Program(vs, fs) -, _vertexShaderModule(static_cast(vs)) +: _vertexShaderModule(static_cast(vs)) , _fragmentShaderModule(static_cast(fs)) { CC_SAFE_RETAIN(_vertexShaderModule); From 2063ed71ba621179804feb5c1bea733c84ba0536 Mon Sep 17 00:00:00 2001 From: coulsonwang Date: Tue, 8 Jan 2019 10:19:25 +0800 Subject: [PATCH 11/11] [Feature] update ProgramCache --- src/backend/Device.h | 5 +-- src/backend/Program.cpp | 6 +++ src/backend/Program.h | 5 +++ src/backend/ProgramCache.cpp | 43 +++++++++++++++++---- src/backend/ProgramCache.h | 7 +++- src/backend/metal/DeviceMTL.h | 3 +- src/backend/metal/DeviceMTL.mm | 29 +++++++------- src/backend/metal/ProgramMTL.h | 3 +- src/backend/metal/ProgramMTL.mm | 9 ++--- src/backend/opengl/DeviceGL.cpp | 37 +++++++++++------- src/backend/opengl/DeviceGL.h | 5 ++- src/backend/opengl/ProgramGL.cpp | 9 ++--- src/backend/opengl/ProgramGL.h | 2 +- test/Test.xcodeproj/project.pbxproj | 6 +-- test/tests/backend/BasicBackend.cpp | 2 +- test/tests/backend/BlendingBackend.cpp | 4 +- test/tests/backend/BunnyBackend.cpp | 2 +- test/tests/backend/DepthTextureBackend.cpp | 4 +- test/tests/backend/GuiProjectionBackend.cpp | 2 +- test/tests/backend/MultiTexturesBackend.cpp | 2 +- test/tests/backend/ParticleBackend.cpp | 2 +- test/tests/backend/PostProcessBackend.cpp | 4 +- test/tests/backend/StencilBackend.cpp | 2 +- test/tests/backend/SubImageBackend.cpp | 2 +- test/tests/backend/Texture2DBackend.cpp | 2 +- 25 files changed, 120 insertions(+), 77 deletions(-) diff --git a/src/backend/Device.h b/src/backend/Device.h index 7789e91..334feae 100644 --- a/src/backend/Device.h +++ b/src/backend/Device.h @@ -7,6 +7,7 @@ #include "Texture.h" #include "DepthStencilState.h" #include "BlendState.h" +#include "ProgramCache.h" #include "base/CCRef.h" @@ -34,15 +35,13 @@ class Device : public cocos2d::Ref virtual Buffer* newBuffer(uint32_t size, BufferType type, BufferUsage usage) = 0; // Create a texture, not auto released. virtual Texture* newTexture(const TextureDescriptor& descriptor) = 0; - // Create a auto released shader module. - virtual ShaderModule* createShaderModule(ShaderStage stage, const std::string& source) = 0; // Create a auto released depth stencil state. virtual DepthStencilState* createDepthStencilState(const DepthStencilDescriptor& descriptor) = 0; // Create a auto released blend state. virtual BlendState* createBlendState(const BlendDescriptor& descriptor) = 0; // Create a render pipeline, not auto released. virtual RenderPipeline* newRenderPipeline(const RenderPipelineDescriptor& descriptor) = 0; - virtual Program* createProgram(ShaderModule* vs, ShaderModule* fs) = 0; + virtual Program* createProgram(const std::string& vertexShader, const std::string& fragmentShader) = 0; private: diff --git a/src/backend/Program.cpp b/src/backend/Program.cpp index 36d9369..8e54be7 100644 --- a/src/backend/Program.cpp +++ b/src/backend/Program.cpp @@ -4,6 +4,12 @@ CC_BACKEND_BEGIN +Program::Program(const std::string& vertexShader, const std::string& fragmentShader) +{ + std::string shaderSource = vertexShader + fragmentShader; + _key = std::hash{}(shaderSource); +} + Program::~Program() { _vertexTextureInfos.clear(); diff --git a/src/backend/Program.h b/src/backend/Program.h index 2378108..103a502 100644 --- a/src/backend/Program.h +++ b/src/backend/Program.h @@ -27,6 +27,8 @@ class Program : public Ref std::vector textures; }; + Program(const std::string& vertexShader, const std::string& fragmentShader); + virtual int getVertexUniformLocation(const std::string& uniform) const = 0; virtual int getFragmentUniformLocation(const std::string& uniform) const = 0; virtual void setVertexUniform(int location, void* data, uint32_t size) = 0; @@ -38,6 +40,7 @@ class Program : public Ref inline const std::unordered_map& getVertexTextureInfos() const { return _vertexTextureInfos; } inline const std::unordered_map& getFragmentTextureInfos() const { return _fragmentTextureInfos; } + inline std::size_t getKey() const { return _key; } protected: Program() = default; @@ -48,6 +51,8 @@ class Program : public Ref std::unordered_map _vertexTextureInfos; std::unordered_map _fragmentTextureInfos; + + std::size_t _key = 0; }; CC_BACKEND_END diff --git a/src/backend/ProgramCache.cpp b/src/backend/ProgramCache.cpp index 5bbba6f..e49a47e 100644 --- a/src/backend/ProgramCache.cpp +++ b/src/backend/ProgramCache.cpp @@ -35,24 +35,51 @@ ProgramCache::~ProgramCache() CCLOGINFO("deallocing ProgramCache: %p", this); } -backend::Program* ProgramCache::newProgram(const std::string &vertexShader, const std::string &fragmentShader) +backend::Program* ProgramCache::getProgram(const std::string& vertexShader, const std::string& fragmentShader) const { std::string shaderSource = vertexShader + fragmentShader; - std::size_t key = std::hash{}(shaderSource); + auto key = std::hash{}(shaderSource); const auto& iter = ProgramCache::_cachedPrograms.find(key); if (ProgramCache::_cachedPrograms.end() != iter) { return iter->second; } + + return nullptr; +} - auto vertexShaderModule = backend::Device::getInstance()->createShaderModule(backend::ShaderStage::VERTEX, vertexShader); - auto fragmentShaderModule = backend::Device::getInstance()->createShaderModule(backend::ShaderStage::FRAGMENT, fragmentShader); - auto program = backend::Device::getInstance()->createProgram(vertexShaderModule, fragmentShaderModule); +void ProgramCache::addProgram(backend::Program* program) +{ CC_SAFE_RETAIN(program); + ProgramCache::_cachedPrograms.emplace(program->getKey(), program); +} + +void ProgramCache::removeProgram(backend::Program* program) +{ + if (!program) + { + return; + } - ProgramCache::_cachedPrograms.emplace(key, program); - - return program; + for (auto it = _cachedPrograms.cbegin(); it != _cachedPrograms.cend();) + { + if (it->second == program) + { + it->second->release(); + it = _cachedPrograms.erase(it); + break; + } + else + ++it; + } +} + +void ProgramCache::removeAllProgram() +{ + for (auto& program : _cachedPrograms) { + program.second->release(); + } + _cachedPrograms.clear(); } CC_BACKEND_END diff --git a/src/backend/ProgramCache.h b/src/backend/ProgramCache.h index a96336a..d4a4dc4 100644 --- a/src/backend/ProgramCache.h +++ b/src/backend/ProgramCache.h @@ -20,8 +20,11 @@ class ProgramCache : public Ref /** purges the cache. It releases the retained instance. */ static void destroyInstance(); - - backend::Program* newProgram(const std::string& vertexShader, const std::string& fragmentShader); + + backend::Program* getProgram(const std::string& vertexShader, const std::string& fragmentShader) const; + void addProgram(backend::Program* program); + void removeProgram(backend::Program* program); + void removeAllProgram(); protected: ProgramCache() = default; diff --git a/src/backend/metal/DeviceMTL.h b/src/backend/metal/DeviceMTL.h index 8d9ff05..8ff9471 100644 --- a/src/backend/metal/DeviceMTL.h +++ b/src/backend/metal/DeviceMTL.h @@ -22,11 +22,10 @@ class DeviceMTL : public Device virtual CommandBuffer* newCommandBuffer() override; virtual Buffer* newBuffer(uint32_t size, BufferType type, BufferUsage usage) override; virtual Texture* newTexture(const TextureDescriptor& descriptor) override; - virtual ShaderModule* createShaderModule(ShaderStage stage, const std::string& source) override; virtual DepthStencilState* createDepthStencilState(const DepthStencilDescriptor& descriptor) override; virtual BlendState* createBlendState(const BlendDescriptor& descriptor) override; virtual RenderPipeline* newRenderPipeline(const RenderPipelineDescriptor& descriptor) override; - virtual Program* createProgram(ShaderModule* vs, ShaderModule* fs) override; + virtual Program* createProgram(const std::string& vertexShader, const std::string& fragmentShader) override; inline id getMTLDevice() const { return _mtlDevice; } inline id getMTLCommandQueue() const { return _mtlCommandQueue; } diff --git a/src/backend/metal/DeviceMTL.mm b/src/backend/metal/DeviceMTL.mm index b7867fd..809e5ac 100644 --- a/src/backend/metal/DeviceMTL.mm +++ b/src/backend/metal/DeviceMTL.mm @@ -39,10 +39,12 @@ { _mtlDevice = DeviceMTL::_metalLayer.device; _mtlCommandQueue = [_mtlDevice newCommandQueue]; + ProgramCache::getInstance(); } DeviceMTL::~DeviceMTL() { + ProgramCache::destroyInstance(); } CommandBuffer* DeviceMTL::newCommandBuffer() @@ -60,15 +62,6 @@ return new (std::nothrow) TextureMTL(_mtlDevice, descriptor); } -ShaderModule* DeviceMTL::createShaderModule(ShaderStage stage, const std::string& source) -{ - auto ret = new (std::nothrow) ShaderModuleMTL(_mtlDevice, stage, source); - if (ret) - ret->autorelease(); - - return ret; -} - DepthStencilState* DeviceMTL::createDepthStencilState(const DepthStencilDescriptor& descriptor) { auto ret = new (std::nothrow) DepthStencilStateMTL(_mtlDevice, descriptor); @@ -92,13 +85,19 @@ return new (std::nothrow) RenderPipelineMTL(_mtlDevice, descriptor); } -Program* DeviceMTL::createProgram(ShaderModule* vs, ShaderModule* fs) +Program* DeviceMTL::createProgram(const std::string& vertexShader, const std::string& fragmentShader) { - auto ret = new (std::nothrow) ProgramMTL(vs, fs); - if (ret) - ret->autorelease(); - - return ret; + auto program = ProgramCache::getInstance()->getProgram(vertexShader, fragmentShader); + if(!program) + { + program = new (std::nothrow) ProgramMTL(_mtlDevice, vertexShader, fragmentShader); + if (program) + { + program->autorelease(); + ProgramCache::getInstance()->addProgram(program); + } + } + return program; } CC_BACKEND_END diff --git a/src/backend/metal/ProgramMTL.h b/src/backend/metal/ProgramMTL.h index 27903aa..3c28028 100644 --- a/src/backend/metal/ProgramMTL.h +++ b/src/backend/metal/ProgramMTL.h @@ -2,6 +2,7 @@ #include "../Program.h" #include +#import CC_BACKEND_BEGIN @@ -10,7 +11,7 @@ class ShaderModuleMTL; class ProgramMTL : public Program { public: - ProgramMTL(ShaderModule* vs, ShaderModule* fs); + ProgramMTL(id mtlDevice, const std::string& vertexShader, const std::string& fragmentShader); ~ProgramMTL(); virtual int getVertexUniformLocation(const std::string& uniform) const override; diff --git a/src/backend/metal/ProgramMTL.mm b/src/backend/metal/ProgramMTL.mm index 865335f..0611725 100644 --- a/src/backend/metal/ProgramMTL.mm +++ b/src/backend/metal/ProgramMTL.mm @@ -3,12 +3,11 @@ CC_BACKEND_BEGIN -ProgramMTL::ProgramMTL(ShaderModule* vs, ShaderModule* fs) -: _vertexShader(static_cast(vs)) -, _fragmentShader(static_cast(fs)) +ProgramMTL::ProgramMTL(id mtlDevice, const std::string& vertexShader, const std::string& fragmentShader) +: Program(vertexShader, fragmentShader) { - CC_SAFE_RETAIN(_vertexShader); - CC_SAFE_RETAIN(_fragmentShader); + _vertexShader = new (std::nothrow) ShaderModuleMTL(mtlDevice, backend::ShaderStage::VERTEX, vertexShader); + _fragmentShader = new (std::nothrow) ShaderModuleMTL(mtlDevice, backend::ShaderStage::FRAGMENT, fragmentShader); } ProgramMTL::~ProgramMTL() diff --git a/src/backend/opengl/DeviceGL.cpp b/src/backend/opengl/DeviceGL.cpp index 697afc2..92e7526 100644 --- a/src/backend/opengl/DeviceGL.cpp +++ b/src/backend/opengl/DeviceGL.cpp @@ -15,9 +15,19 @@ Device* Device::getInstance() if (!_instance) _instance = new (std::nothrow) DeviceGL(); + if(_instance) + { + ProgramCache::getInstance(); + } + return _instance; } +DeviceGL::~DeviceGL() +{ + ProgramCache::destroyInstance(); +} + CommandBuffer* DeviceGL::newCommandBuffer() { return new (std::nothrow) CommandBufferGL(); @@ -33,15 +43,6 @@ Texture* DeviceGL::newTexture(const TextureDescriptor& descriptor) return new (std::nothrow) TextureGL(descriptor); } -ShaderModule* DeviceGL::createShaderModule(ShaderStage stage, const std::string& source) -{ - auto ret = new (std::nothrow) ShaderModuleGL(stage, source); - if (ret) - ret->autorelease(); - - return ret; -} - DepthStencilState* DeviceGL::createDepthStencilState(const DepthStencilDescriptor& descriptor) { auto ret = new (std::nothrow) DepthStencilStateGL(descriptor); @@ -65,13 +66,19 @@ RenderPipeline* DeviceGL::newRenderPipeline(const RenderPipelineDescriptor& desc return new (std::nothrow) RenderPipelineGL(descriptor); } -Program* DeviceGL::createProgram(ShaderModule* vs, ShaderModule* fs) +Program* DeviceGL::createProgram(const std::string& vertexShader, const std::string& fragmentShader) { - auto ret = new (std::nothrow) ProgramGL(vs, fs); - if (ret) - ret->autorelease(); - - return ret; + auto program = ProgramCache::getInstance()->getProgram(vertexShader, fragmentShader); + if(!program) + { + program = new (std::nothrow) ProgramGL(vertexShader, fragmentShader); + if (program) + { + program->autorelease(); + ProgramCache::getInstance()->addProgram(program); + } + } + return program; } CC_BACKEND_END diff --git a/src/backend/opengl/DeviceGL.h b/src/backend/opengl/DeviceGL.h index 568332e..2efd013 100644 --- a/src/backend/opengl/DeviceGL.h +++ b/src/backend/opengl/DeviceGL.h @@ -5,14 +5,15 @@ CC_BACKEND_BEGIN class DeviceGL : public Device { public: + ~DeviceGL(); + virtual CommandBuffer* newCommandBuffer() override; virtual Buffer* newBuffer(uint32_t size, BufferType type, BufferUsage usage) override; virtual Texture* newTexture(const TextureDescriptor& descriptor) override; - virtual ShaderModule* createShaderModule(ShaderStage stage, const std::string& source) override; virtual DepthStencilState* createDepthStencilState(const DepthStencilDescriptor& descriptor) override; virtual BlendState* createBlendState(const BlendDescriptor& descriptor) override; virtual RenderPipeline* newRenderPipeline(const RenderPipelineDescriptor& descriptor) override; - virtual Program* createProgram(ShaderModule* vs, ShaderModule* fs) override; + virtual Program* createProgram(const std::string& vertexShader, const std::string& fragmentShader) override; }; CC_BACKEND_END diff --git a/src/backend/opengl/ProgramGL.cpp b/src/backend/opengl/ProgramGL.cpp index 2f44d1e..69011e8 100644 --- a/src/backend/opengl/ProgramGL.cpp +++ b/src/backend/opengl/ProgramGL.cpp @@ -110,12 +110,11 @@ namespace } } -ProgramGL::ProgramGL(ShaderModule* vs, ShaderModule* fs) -: _vertexShaderModule(static_cast(vs)) -, _fragmentShaderModule(static_cast(fs)) +ProgramGL::ProgramGL(const std::string& vertexShader, const std::string& fragmentShader) +: Program(vertexShader, fragmentShader) { - CC_SAFE_RETAIN(_vertexShaderModule); - CC_SAFE_RETAIN(_fragmentShaderModule); + _vertexShaderModule = new (std::nothrow) ShaderModuleGL(backend::ShaderStage::VERTEX, vertexShader); + _fragmentShaderModule = new (std::nothrow) ShaderModuleGL(backend::ShaderStage::FRAGMENT, fragmentShader); createProgram(); computeUniformInfos(); diff --git a/src/backend/opengl/ProgramGL.h b/src/backend/opengl/ProgramGL.h index b42a3a4..96740ca 100644 --- a/src/backend/opengl/ProgramGL.h +++ b/src/backend/opengl/ProgramGL.h @@ -39,7 +39,7 @@ class ProgramGL : public Program public: typedef std::vector VertexAttributeArray; - ProgramGL(ShaderModule* vs, ShaderModule* fs); + ProgramGL(const std::string& vertexShader, const std::string& fragmentShader); ~ProgramGL(); virtual void setVertexUniform(int location, void* data, uint32_t size) override; diff --git a/test/Test.xcodeproj/project.pbxproj b/test/Test.xcodeproj/project.pbxproj index f37d07e..e5b86aa 100644 --- a/test/Test.xcodeproj/project.pbxproj +++ b/test/Test.xcodeproj/project.pbxproj @@ -197,7 +197,6 @@ EDC86F4C21DCBAE10086A0CA /* Program.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EDC86F4B21DCBAE10086A0CA /* Program.cpp */; }; EDC86F4D21DCBAE10086A0CA /* Program.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EDC86F4B21DCBAE10086A0CA /* Program.cpp */; }; EDC86F5321DDA3F00086A0CA /* ProgramMTL.mm in Sources */ = {isa = PBXBuildFile; fileRef = EDC86F5221DDA3F00086A0CA /* ProgramMTL.mm */; }; - EDC86F5421DDA3F00086A0CA /* ProgramMTL.mm in Sources */ = {isa = PBXBuildFile; fileRef = EDC86F5221DDA3F00086A0CA /* ProgramMTL.mm */; }; /* End PBXBuildFile section */ /* Begin PBXCopyFilesBuildPhase section */ @@ -1269,7 +1268,6 @@ 46037422214247F000DC9ED4 /* BasicBackend.cpp in Sources */, 4603744321479AFC00DC9ED4 /* DepthStencilStateGL.cpp in Sources */, 1A255E5620034B0D00069420 /* Vec4.cpp in Sources */, - EDC86F5421DDA3F00086A0CA /* ProgramMTL.mm in Sources */, 1A255E6420034B0D00069420 /* ZipUtils.cpp in Sources */, EDC86F4D21DCBAE10086A0CA /* Program.cpp in Sources */, 4603741C214247D500DC9ED4 /* RenderPipelineGL.cpp in Sources */, @@ -1403,7 +1401,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_IDENTITY = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; - DEVELOPMENT_TEAM = NQ596S94Q5; + DEVELOPMENT_TEAM = FJYDD5W27C; ENABLE_BITCODE = NO; GCC_PREPROCESSOR_DEFINITIONS = ( "$(inherited)", @@ -1436,7 +1434,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_IDENTITY = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; - DEVELOPMENT_TEAM = NQ596S94Q5; + DEVELOPMENT_TEAM = FJYDD5W27C; ENABLE_BITCODE = NO; HEADER_SEARCH_PATHS = "$(inherited)"; INFOPLIST_FILE = "Test-ios/Info.plist"; diff --git a/test/tests/backend/BasicBackend.cpp b/test/tests/backend/BasicBackend.cpp index db7f8cb..ffb6281 100644 --- a/test/tests/backend/BasicBackend.cpp +++ b/test/tests/backend/BasicBackend.cpp @@ -63,7 +63,7 @@ BasicBackend::BasicBackend() auto device = cocos2d::backend::Device::getInstance(); cocos2d::backend::RenderPipelineDescriptor renderPipelineDescriptor; - renderPipelineDescriptor.program = backend::ProgramCache::getInstance()->newProgram(vert, frag); + renderPipelineDescriptor.program = device->createProgram(vert, frag); _colorLocation = renderPipelineDescriptor.program->getFragmentUniformLocation("color"); backend::VertexLayout vertexLayout; diff --git a/test/tests/backend/BlendingBackend.cpp b/test/tests/backend/BlendingBackend.cpp index 7a581c5..0fd55f4 100644 --- a/test/tests/backend/BlendingBackend.cpp +++ b/test/tests/backend/BlendingBackend.cpp @@ -66,7 +66,7 @@ namespace auto device = backend::Device::getInstance(); backend::RenderPipelineDescriptor renderPipelineDescriptor; - renderPipelineDescriptor.program = backend::ProgramCache::getInstance()->newProgram(vert, frag); + renderPipelineDescriptor.program = device->createProgram(vert, frag); _modelLocation = renderPipelineDescriptor.program->getVertexUniformLocation("model"); _projectionLocation = renderPipelineDescriptor.program->getVertexUniformLocation("projection"); _textureLocation = renderPipelineDescriptor.program->getFragmentUniformLocation("texture"); @@ -218,7 +218,7 @@ namespace auto device = backend::Device::getInstance(); backend::RenderPipelineDescriptor renderPipelineDescriptor; - renderPipelineDescriptor.program = backend::ProgramCache::getInstance()->newProgram(vert, frag); + renderPipelineDescriptor.program = device->createProgram(vert, frag); _timeLocation = renderPipelineDescriptor.program->getFragmentUniformLocation("time"); _textureLocation = renderPipelineDescriptor.program->getFragmentUniformLocation("texture"); diff --git a/test/tests/backend/BunnyBackend.cpp b/test/tests/backend/BunnyBackend.cpp index fe86bcb..95599ef 100644 --- a/test/tests/backend/BunnyBackend.cpp +++ b/test/tests/backend/BunnyBackend.cpp @@ -82,7 +82,7 @@ BunnyBackend::BunnyBackend() auto depthStencilState = device->createDepthStencilState(depthStencilDescriptor); renderPipelineDescriptor.depthStencilState = depthStencilState; - renderPipelineDescriptor.program = backend::ProgramCache::getInstance()->newProgram(vert, frag); + renderPipelineDescriptor.program = device->createProgram(vert, frag); _modelLocation = renderPipelineDescriptor.program->getVertexUniformLocation("model"); _viewLocation = renderPipelineDescriptor.program->getVertexUniformLocation("view"); _projectionLocation = renderPipelineDescriptor.program->getVertexUniformLocation("projection"); diff --git a/test/tests/backend/DepthTextureBackend.cpp b/test/tests/backend/DepthTextureBackend.cpp index 4f1fef8..e5dc169 100644 --- a/test/tests/backend/DepthTextureBackend.cpp +++ b/test/tests/backend/DepthTextureBackend.cpp @@ -75,7 +75,7 @@ namespace // render pipeline backend::RenderPipelineDescriptor renderPipelineDescriptor; - renderPipelineDescriptor.program = backend::ProgramCache::getInstance()->newProgram(vert, frag); + renderPipelineDescriptor.program = device->createProgram(vert, frag); _nearLocation = renderPipelineDescriptor.program->getFragmentUniformLocation("near"); _farLocation = renderPipelineDescriptor.program->getFragmentUniformLocation("far"); _textureLocation = renderPipelineDescriptor.program->getFragmentUniformLocation("texture"); @@ -154,7 +154,7 @@ namespace backend::RenderPipelineDescriptor renderPipelineDescriptor; renderPipelineDescriptor.depthAttachmentFormat = backend::TextureFormat::D24S8; renderPipelineDescriptor.colorAttachmentsFormat[0] = backend::TextureFormat::NONE; - renderPipelineDescriptor.program = backend::ProgramCache::getInstance()->newProgram(vert, frag); + renderPipelineDescriptor.program = device->createProgram(vert, frag); _modelLocation = renderPipelineDescriptor.program->getVertexUniformLocation("model"); _viewLocation = renderPipelineDescriptor.program->getVertexUniformLocation("view"); _projectionLocation = renderPipelineDescriptor.program->getVertexUniformLocation("projection"); diff --git a/test/tests/backend/GuiProjectionBackend.cpp b/test/tests/backend/GuiProjectionBackend.cpp index 5d21a16..b09b1bb 100644 --- a/test/tests/backend/GuiProjectionBackend.cpp +++ b/test/tests/backend/GuiProjectionBackend.cpp @@ -66,7 +66,7 @@ GuiProjectionBackend::GuiProjectionBackend() auto device = backend::Device::getInstance(); backend::RenderPipelineDescriptor renderPipelineDescriptor; - renderPipelineDescriptor.program = backend::ProgramCache::getInstance()->newProgram(vert, frag); + renderPipelineDescriptor.program = device->createProgram(vert, frag); _colorLocation = renderPipelineDescriptor.program->getFragmentUniformLocation("color"); _projectionLocation = renderPipelineDescriptor.program->getVertexUniformLocation("projection"); _transformLocation = renderPipelineDescriptor.program->getVertexUniformLocation("transform"); diff --git a/test/tests/backend/MultiTexturesBackend.cpp b/test/tests/backend/MultiTexturesBackend.cpp index 84e1552..7e8f5d8 100644 --- a/test/tests/backend/MultiTexturesBackend.cpp +++ b/test/tests/backend/MultiTexturesBackend.cpp @@ -67,7 +67,7 @@ MultiTexturesBackend::MultiTexturesBackend() renderPipelineDescriptor.colorAttachmentsFormat[0] = backend::TextureFormat::SYSTEM_DEFAULT; renderPipelineDescriptor.depthAttachmentFormat = backend::TextureFormat::D24S8; - renderPipelineDescriptor.program = backend::ProgramCache::getInstance()->newProgram(vert, frag); + renderPipelineDescriptor.program = device->createProgram(vert, frag); _transformLocation = renderPipelineDescriptor.program->getVertexUniformLocation("transform"); _colorLocation = renderPipelineDescriptor.program->getFragmentUniformLocation("color"); _texture1Location = renderPipelineDescriptor.program->getFragmentUniformLocation("texture1"); diff --git a/test/tests/backend/ParticleBackend.cpp b/test/tests/backend/ParticleBackend.cpp index ed3bbd2..ce87562 100644 --- a/test/tests/backend/ParticleBackend.cpp +++ b/test/tests/backend/ParticleBackend.cpp @@ -75,7 +75,7 @@ ParticleBackend::ParticleBackend() auto device = backend::Device::getInstance(); backend::RenderPipelineDescriptor renderPipelineDescriptor; - renderPipelineDescriptor.program = backend::ProgramCache::getInstance()->newProgram(vert, frag); + renderPipelineDescriptor.program = device->createProgram(vert, frag); _modelLocation = renderPipelineDescriptor.program->getVertexUniformLocation("model"); _viewLocation = renderPipelineDescriptor.program->getVertexUniformLocation("view"); _projectionLocation = renderPipelineDescriptor.program->getVertexUniformLocation("projection"); diff --git a/test/tests/backend/PostProcessBackend.cpp b/test/tests/backend/PostProcessBackend.cpp index 5f03dc6..58dcd4f 100644 --- a/test/tests/backend/PostProcessBackend.cpp +++ b/test/tests/backend/PostProcessBackend.cpp @@ -91,7 +91,7 @@ namespace renderPipelineDescriptor.colorAttachmentsFormat[0] = backend::TextureFormat::SYSTEM_DEFAULT; renderPipelineDescriptor.depthAttachmentFormat = backend::TextureFormat::D24S8; - renderPipelineDescriptor.program = backend::ProgramCache::getInstance()->newProgram(vert, frag); + renderPipelineDescriptor.program = device->createProgram(vert, frag); _textureLocation = renderPipelineDescriptor.program->getFragmentUniformLocation("texture"); backend::VertexLayout vertexLayout; @@ -162,7 +162,7 @@ namespace renderPipelineDescriptor.colorAttachmentsFormat[0] = backend::TextureFormat::R8G8B8A8; renderPipelineDescriptor.depthAttachmentFormat = backend::TextureFormat::D24S8; - renderPipelineDescriptor.program = backend::ProgramCache::getInstance()->newProgram(vert, frag); + renderPipelineDescriptor.program = device->createProgram(vert, frag); _modelLocation = renderPipelineDescriptor.program->getVertexUniformLocation("model"); _viewLocation = renderPipelineDescriptor.program->getVertexUniformLocation("view"); _projectionLocation = renderPipelineDescriptor.program->getVertexUniformLocation("projection"); diff --git a/test/tests/backend/StencilBackend.cpp b/test/tests/backend/StencilBackend.cpp index 72f0c7e..bb4c90b 100644 --- a/test/tests/backend/StencilBackend.cpp +++ b/test/tests/backend/StencilBackend.cpp @@ -91,7 +91,7 @@ StencilBackend::StencilBackend() backend::RenderPipelineDescriptor renderPipelineDescriptor; renderPipelineDescriptor.stencilAttachmentFormat = backend::TextureFormat::D24S8; renderPipelineDescriptor.colorAttachmentsFormat[0] = backend::TextureFormat::SYSTEM_DEFAULT; - renderPipelineDescriptor.program = backend::ProgramCache::getInstance()->newProgram(vert, frag); + renderPipelineDescriptor.program = device->createProgram(vert, frag); _transformLocation = renderPipelineDescriptor.program->getVertexUniformLocation("transform"); _colorLocation = renderPipelineDescriptor.program->getFragmentUniformLocation("color"); _textureLocation = renderPipelineDescriptor.program->getFragmentUniformLocation("texture"); diff --git a/test/tests/backend/SubImageBackend.cpp b/test/tests/backend/SubImageBackend.cpp index 25af8b6..630d956 100644 --- a/test/tests/backend/SubImageBackend.cpp +++ b/test/tests/backend/SubImageBackend.cpp @@ -58,7 +58,7 @@ SubImageBackend::SubImageBackend() auto device = backend::Device::getInstance(); backend::RenderPipelineDescriptor renderPipelineDescriptor; - renderPipelineDescriptor.program = backend::ProgramCache::getInstance()->newProgram(vert, frag); + renderPipelineDescriptor.program = device->createProgram(vert, frag); _textureLocation = renderPipelineDescriptor.program->getFragmentUniformLocation("texture"); backend::VertexLayout vertexLayout; diff --git a/test/tests/backend/Texture2DBackend.cpp b/test/tests/backend/Texture2DBackend.cpp index ba39b23..68ae531 100644 --- a/test/tests/backend/Texture2DBackend.cpp +++ b/test/tests/backend/Texture2DBackend.cpp @@ -118,7 +118,7 @@ Texture2DBackendTest::Texture2DBackendTest() // create render pipeline RenderPipelineDescriptor renderPipelineDescriptor; - renderPipelineDescriptor.program = backend::ProgramCache::getInstance()->newProgram(vert, frag); + renderPipelineDescriptor.program = device->createProgram(vert, frag); _transformLocation = renderPipelineDescriptor.program->getVertexUniformLocation("transform"); _colorLocation = renderPipelineDescriptor.program->getFragmentUniformLocation("color"); _textureLocation = renderPipelineDescriptor.program->getFragmentUniformLocation("texture");