diff --git a/src/backend/Backend.h b/src/backend/Backend.h index a8dbc4b..c65d517 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" @@ -9,7 +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/ProgramCache.h" diff --git a/src/backend/BindGroup.cpp b/src/backend/BindGroup.cpp deleted file mode 100644 index 6857b7e..0000000 --- a/src/backend/BindGroup.cpp +++ /dev/null @@ -1,98 +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::setUniform(const std::string& name, void* data, uint32_t size) -{ - UniformInfo uniform(name, data, size); - _uniformInfos[name] = std::move(uniform); -} - -CC_BACKEND_END diff --git a/src/backend/BindGroup.h b/src/backend/BindGroup.h deleted file mode 100644 index 499059a..0000000 --- a/src/backend/BindGroup.h +++ /dev/null @@ -1,57 +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 setUniform(const std::string& name, void* data, uint32_t size); - - inline const std::unordered_map& getUniformInfos() const { return _uniformInfos; } - inline const std::unordered_map& getTextureInfos() const { return _textureInfos; } - -private: - std::unordered_map _uniformInfos; - 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/Device.h b/src/backend/Device.h index a223863..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" @@ -19,6 +20,7 @@ class Buffer; class ShaderModule; class RenderPipeline; class RenderPass; +class Program; class Device : public cocos2d::Ref { @@ -33,14 +35,14 @@ 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(const std::string& vertexShader, const std::string& fragmentShader) = 0; + private: static Device* _instance; diff --git a/src/backend/Program.cpp b/src/backend/Program.cpp new file mode 100644 index 0000000..8e54be7 --- /dev/null +++ b/src/backend/Program.cpp @@ -0,0 +1,80 @@ +#include "Program.h" +#include "ShaderModule.h" +#include "Texture.h" + +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(); + _fragmentTextureInfos.clear(); +} + +Program::TextureInfo::~TextureInfo() +{ + releaseTextures(); +} + +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::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, _fragmentTextureInfos); +} + +void Program::setVertexTextureArray(int location, const std::vector& slots, const std::vector textures) +{ + setTextureArray(location, slots, textures, _vertexTextureInfos); +} + +void Program::setFragmentTextureArray(int location, const std::vector& slots, const std::vector textures) +{ + setTextureArray(location, slots, textures, _fragmentTextureInfos); +} + +void Program::setTexture(int location, uint32_t slot, Texture* texture, std::unordered_map& textureInfo) +{ + if(location < 0) + return; + + TextureInfo info; + info.location = location; + info.slot = {slot}; + info.textures = {texture}; + info.retainTextures(); + textureInfo[location] = info; +} + +void Program::setTextureArray(int location, const std::vector& slots, const std::vector textures, std::unordered_map& textureInfo) +{ + assert(slots.size() == textures.size()); + TextureInfo info; + info.location = location; + info.slot = slots; + info.textures = textures; + info.retainTextures(); + textureInfo[location] = info; +} + +CC_BACKEND_END diff --git a/src/backend/Program.h b/src/backend/Program.h new file mode 100644 index 0000000..103a502 --- /dev/null +++ b/src/backend/Program.h @@ -0,0 +1,58 @@ +#pragma once + +#include "Macros.h" +#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(); + + void retainTextures(); + void releaseTextures(); + + int location = 0; + std::vector slot; + 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; + virtual void setFragmentUniform(int location, void* data, uint32_t size) = 0; + 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 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; + virtual ~Program(); + + 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::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 new file mode 100644 index 0000000..e49a47e --- /dev/null +++ b/src/backend/ProgramCache.cpp @@ -0,0 +1,85 @@ +#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::getProgram(const std::string& vertexShader, const std::string& fragmentShader) const +{ + std::string shaderSource = vertexShader + fragmentShader; + auto key = std::hash{}(shaderSource); + const auto& iter = ProgramCache::_cachedPrograms.find(key); + if (ProgramCache::_cachedPrograms.end() != iter) + { + return iter->second; + } + + return nullptr; +} + +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; + } + + 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 new file mode 100644 index 0000000..d4a4dc4 --- /dev/null +++ b/src/backend/ProgramCache.h @@ -0,0 +1,36 @@ +#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* 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; + virtual ~ProgramCache(); + + static std::unordered_map _cachedPrograms; +}; + +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..2f52316 100644 --- a/src/backend/RenderPipeline.h +++ b/src/backend/RenderPipeline.h @@ -6,11 +6,18 @@ #include "base/CCRef.h" CC_BACKEND_BEGIN - +class Program; class RenderPipeline : public cocos2d::Ref { +public: + virtual ~RenderPipeline(); + + virtual Program* getProgram() const { return _program; } + protected: - virtual ~RenderPipeline() = default; + RenderPipeline(Program* program); + + Program* _program = nullptr; }; CC_BACKEND_END diff --git a/src/backend/RenderPipelineDescriptor.h b/src/backend/RenderPipelineDescriptor.h index c5a60cd..fc823e7 100644 --- a/src/backend/RenderPipelineDescriptor.h +++ b/src/backend/RenderPipelineDescriptor.h @@ -11,11 +11,11 @@ CC_BACKEND_BEGIN class ShaderModule; class DepthStencilState; class BlendState; +class Program; struct RenderPipelineDescriptor { - ShaderModule* vertexShaderModule = nullptr; - ShaderModule* fragmentShaderModule = nullptr; + Program* program = nullptr; DepthStencilState* depthStencilState = nullptr; BlendState* blendState = nullptr; std::vector vertexLayouts; diff --git a/src/backend/metal/CommandBufferMTL.h b/src/backend/metal/CommandBufferMTL.h index 309488c..ece1d9d 100644 --- a/src/backend/metal/CommandBufferMTL.h +++ b/src/backend/metal/CommandBufferMTL.h @@ -2,6 +2,7 @@ #include "../CommandBuffer.h" #include "DeviceMTL.h" +#include CC_BACKEND_BEGIN @@ -19,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; @@ -29,9 +29,8 @@ 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; - uint32_t fillUniformBuffer(uint8_t* buffer, const std::vector& uniforms) const; void afterDraw(); id _mtlCommandBuffer = nil; @@ -41,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 385246a..43940ae 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,55 +265,53 @@ MTLCullMode toMTLCullMode(CullMode mode) void CommandBufferMTL::setTextures() const { - if (_bindGroup) + 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 = _bindGroup->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; + int location = textureInfo.second.location; + + //FIXME: should support texture array. + const auto& textures = textureInfo.second.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:location]; + [_mtlRenderEncoder setVertexSamplerState:mtlTexture->getMTLSamplerState() + atIndex:location]; } + else + { + [_mtlRenderEncoder setFragmentTexture:mtlTexture->getMTLTexture() + atIndex:location]; + [_mtlRenderEncoder setFragmentSamplerState:mtlTexture->getMTLSamplerState() + atIndex:location]; + } + + ++i; } } void CommandBufferMTL::setUniformBuffer() const { - if (_bindGroup) + if (_renderPipelineMTL->getProgram()) { // Uniform buffer is bound to index 1. const auto& vertexUniformBuffer = _renderPipelineMTL->getVertexUniformBuffer(); if (vertexUniformBuffer) { - uint32_t size = fillUniformBuffer(vertexUniformBuffer.get(), _renderPipelineMTL->getVertexUniforms()); + auto size = _renderPipelineMTL->getVertexUniformBufferSize(); [_mtlRenderEncoder setVertexBytes:vertexUniformBuffer.get() length:size atIndex:1]; } @@ -329,7 +319,7 @@ MTLCullMode toMTLCullMode(CullMode mode) const auto& fragUniformBuffer = _renderPipelineMTL->getFragmentUniformBuffer(); if (fragUniformBuffer) { - uint32_t size = fillUniformBuffer(fragUniformBuffer.get(), _renderPipelineMTL->getFragmentUniforms()); + auto size = _renderPipelineMTL->getFragUniformBufferSize(); [_mtlRenderEncoder setFragmentBytes:fragUniformBuffer.get() length:size atIndex:1]; @@ -337,21 +327,4 @@ MTLCullMode toMTLCullMode(CullMode mode) } } -uint32_t CommandBufferMTL::fillUniformBuffer(uint8_t* buffer, const std::vector& uniforms) const -{ - const auto& bindUniformInfos = _bindGroup->getUniformInfos(); - uint32_t offset = 0; - for (const auto& uniform : uniforms) - { - auto iter = bindUniformInfos.find(uniform); - if (bindUniformInfos.end() != iter) - { - const auto& bindUniformInfo = iter->second; - memcpy(buffer + offset, bindUniformInfo.data, bindUniformInfo.size); - offset += bindUniformInfo.size; - } - } - return offset; -} - CC_BACKEND_END diff --git a/src/backend/metal/DeviceMTL.h b/src/backend/metal/DeviceMTL.h index 0833a41..8ff9471 100644 --- a/src/backend/metal/DeviceMTL.h +++ b/src/backend/metal/DeviceMTL.h @@ -22,10 +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(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 7827c75..809e5ac 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 @@ -38,10 +39,12 @@ { _mtlDevice = DeviceMTL::_metalLayer.device; _mtlCommandQueue = [_mtlDevice newCommandQueue]; + ProgramCache::getInstance(); } DeviceMTL::~DeviceMTL() { + ProgramCache::destroyInstance(); } CommandBuffer* DeviceMTL::newCommandBuffer() @@ -59,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); @@ -91,4 +85,19 @@ return new (std::nothrow) RenderPipelineMTL(_mtlDevice, descriptor); } +Program* DeviceMTL::createProgram(const std::string& vertexShader, const std::string& fragmentShader) +{ + 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 new file mode 100644 index 0000000..3c28028 --- /dev/null +++ b/src/backend/metal/ProgramMTL.h @@ -0,0 +1,33 @@ +#pragma once + +#include "../Program.h" +#include +#import + +CC_BACKEND_BEGIN + +class ShaderModuleMTL; + +class ProgramMTL : public Program +{ +public: + ProgramMTL(id mtlDevice, const std::string& vertexShader, const std::string& fragmentShader); + ~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; + + 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; +}; + +CC_BACKEND_END diff --git a/src/backend/metal/ProgramMTL.mm b/src/backend/metal/ProgramMTL.mm new file mode 100644 index 0000000..0611725 --- /dev/null +++ b/src/backend/metal/ProgramMTL.mm @@ -0,0 +1,63 @@ +#include "ProgramMTL.h" +#include "ShaderModuleMTL.h" + +CC_BACKEND_BEGIN + +ProgramMTL::ProgramMTL(id mtlDevice, const std::string& vertexShader, const std::string& fragmentShader) +: Program(vertexShader, fragmentShader) +{ + _vertexShader = new (std::nothrow) ShaderModuleMTL(mtlDevice, backend::ShaderStage::VERTEX, vertexShader); + _fragmentShader = new (std::nothrow) ShaderModuleMTL(mtlDevice, backend::ShaderStage::FRAGMENT, fragmentShader); +} + +ProgramMTL::~ProgramMTL() +{ + CC_SAFE_RELEASE(_vertexShader); + CC_SAFE_RELEASE(_fragmentShader); +} + +int ProgramMTL::getVertexUniformLocation(const std::string& uniform) const +{ + 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; +} + +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) +{ + memcpy(buffer + offset, uniformData, uniformSize); +} + +CC_BACKEND_END diff --git a/src/backend/metal/RenderPipelineMTL.h b/src/backend/metal/RenderPipelineMTL.h index ba97649..e6e552c 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 { @@ -21,10 +22,8 @@ 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; } + inline uint32_t getVertexUniformBufferSize() const { return _vertexUniformBufferSize; } + inline uint32_t getFragUniformBufferSize() const { return _fragUniformBufferSize; } private: void setVertexLayout(MTLRenderPipelineDescriptor*, const RenderPipelineDescriptor&); @@ -36,13 +35,10 @@ 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 _vertexUniforms; - std::vector _vertexTextures; - std::shared_ptr _fragementUniformBuffer = nullptr; - std::vector _fragmentUniforms; - std::vector _fragmentTextures; MTLRenderPipelineDescriptor* _mtlRenderPipelineDescriptor = nil; BlendDescriptorMTL _blendDescriptorMTL; diff --git a/src/backend/metal/RenderPipelineMTL.mm b/src/backend/metal/RenderPipelineMTL.mm index 2508e60..ffbc540 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 "ProgramMTL.h" CC_BACKEND_BEGIN @@ -66,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]; @@ -134,17 +136,15 @@ MTLVertexFormat toMTLVertexFormat(VertexFormat vertexFormat) void RenderPipelineMTL::setShaderModules(const RenderPipelineDescriptor& descriptor) { - auto vertexShaderModule = static_cast(descriptor.vertexShaderModule); + auto vertexShaderModule = static_cast(descriptor.program)->getVertexShaderModule(); _mtlRenderPipelineDescriptor.vertexFunction = vertexShaderModule->getMTLFunction(); - _vertexUniforms = vertexShaderModule->getUniforms(); _vertexUniformBuffer = vertexShaderModule->getUniformBuffer(); - _vertexTextures = vertexShaderModule->getTextures(); + _vertexUniformBufferSize = vertexShaderModule->getUniformBufferSize(); - auto fragShaderModule = static_cast(descriptor.fragmentShaderModule); + auto fragShaderModule = static_cast(descriptor.program)->getFragmentShaderModule(); _mtlRenderPipelineDescriptor.fragmentFunction = fragShaderModule->getMTLFunction(); - _fragmentUniforms = fragShaderModule->getUniforms(); _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 de123c8..03c981a 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,8 +19,9 @@ 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::vector& getTextures() const { return _textures; } + inline const std::unordered_map& getUniforms() const { return _uniforms; } + inline uint32_t getUniformBufferSize() const { return _uniformBufferSize; } + inline uint32_t getUniformTextureCount() const { return _uniformTextureCount; } private: void parseUniform(id mtlDevice, glslopt_shader* shader); @@ -28,10 +30,9 @@ class ShaderModuleMTL : public ShaderModule id _mtlFunction = nil; std::shared_ptr _uniformBuffer = nullptr; - std::vector _uniforms; - - // Texture index is the same as vector index. - std::vector _textures; + std::unordered_map _uniforms; + uint32_t _uniformBufferSize = 0; + uint32_t _uniformTextureCount = 0; }; CC_BACKEND_END diff --git a/src/backend/metal/ShaderModuleMTL.mm b/src/backend/metal/ShaderModuleMTL.mm index 497b1bd..61de71f 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) @@ -84,21 +84,21 @@ 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; } } 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 ee54543..8b6baf7 100644 --- a/src/backend/opengl/CommandBufferGL.cpp +++ b/src/backend/opengl/CommandBufferGL.cpp @@ -3,8 +3,7 @@ #include "RenderPipelineGL.h" #include "TextureGL.h" #include "DepthStencilStateGL.h" -#include "../BindGroup.h" -#include "Program.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(); @@ -292,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); @@ -323,7 +315,7 @@ void CommandBufferGL::prepareDrawing() const } } -void CommandBufferGL::bindVertexBuffer(Program *program) const +void CommandBufferGL::bindVertexBuffer(const ProgramGL *program) const { // Bind vertex buffers and set the attributes. int i = 0; @@ -351,146 +343,49 @@ void CommandBufferGL::bindVertexBuffer(Program *program) const } } -void CommandBufferGL::setUniforms(Program* program) const +void CommandBufferGL::setUniforms(const ProgramGL* program) const { - if (_bindGroup) + if (program) { - const auto& texutreInfos = _bindGroup->getTextureInfos(); - const auto& bindUniformInfos = _bindGroup->getUniformInfos(); + const auto& texutreInfos = program->getFragmentTextureInfos(); const auto& activeUniformInfos = program->getUniformInfos(); - for (const auto& activeUinform : activeUniformInfos) + + // Bind textures. + for(const auto& textureInfo : texutreInfos) { - // Set normal uniforms. - const auto& bindUniformInfo = bindUniformInfos.find(activeUinform.name); - if (bindUniformInfos.end() != bindUniformInfo) + 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) { - setUniform(activeUinform.isArray, - activeUinform.location, - activeUinform.size, - activeUinform.type, - (*bindUniformInfo).second.data); + static_cast(texture)->apply(indices[i]); + ++i; } - // Bind textures. - const auto& bindUniformTextureInfo = texutreInfos.find(activeUinform.name); - if (texutreInfos.end() != bindUniformTextureInfo) - { - const auto& textures = (*bindUniformTextureInfo).second.textures; - const auto& indices = (*bindUniformTextureInfo).second.indices; - - int i = 0; - for (const auto& texture: textures) - { - static_cast(texture)->apply(indices[i]); - ++i; - } - - setUniform(activeUinform.isArray, - activeUinform.location, - activeUinform.size, - activeUinform.type, - (void*)indices.data()); + 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; } } } } -#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 b855d0e..bb0516b 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 { @@ -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; @@ -42,9 +41,8 @@ class CommandBufferGL : public CommandBuffer }; void prepareDrawing() const; - void bindVertexBuffer(Program* program) const; - void setUniforms(Program* program) const; - void setUniform(bool isArray, GLuint location, uint32_t size, GLenum uniformType, void* data) const; + void bindVertexBuffer(const ProgramGL* program) const; + void setUniforms(const ProgramGL* program) 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/DeviceGL.cpp b/src/backend/opengl/DeviceGL.cpp index 1b7848c..92e7526 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 @@ -14,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(); @@ -32,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); @@ -64,4 +66,19 @@ RenderPipeline* DeviceGL::newRenderPipeline(const RenderPipelineDescriptor& desc return new (std::nothrow) RenderPipelineGL(descriptor); } +Program* DeviceGL::createProgram(const std::string& vertexShader, const std::string& fragmentShader) +{ + 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 1dcf45e..2efd013 100644 --- a/src/backend/opengl/DeviceGL.h +++ b/src/backend/opengl/DeviceGL.h @@ -5,13 +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(const std::string& vertexShader, const std::string& fragmentShader) override; }; CC_BACKEND_END diff --git a/src/backend/opengl/Program.cpp b/src/backend/opengl/Program.cpp deleted file mode 100644 index 8eb8d4b..0000000 --- a/src/backend/opengl/Program.cpp +++ /dev/null @@ -1,191 +0,0 @@ -#include "Program.h" -#include "ShaderModuleGL.h" - -CC_BACKEND_BEGIN - -namespace -{ - GLenum toGLAttributeType(VertexFormat vertexFormat) - { - GLenum ret = GL_INT; - switch (vertexFormat) - { - case VertexFormat::FLOAT_R32G32B32A32: - case VertexFormat::FLOAT_R32G32B32: - case VertexFormat::FLOAT_R32G32: - case VertexFormat::FLOAT_R32: - ret = GL_FLOAT; - break; - case VertexFormat::INT_R32G32B32A32: - case VertexFormat::INT_R32G32B32: - case VertexFormat::INT_R32G32: - case VertexFormat::INT_R32: - ret = GL_INT; - break; - default: - break; - } - return ret; - } - - GLsizei getGLAttributeSize(VertexFormat vertexFormat) - { - GLsizei ret = 0; - switch (vertexFormat) - { - case VertexFormat::FLOAT_R32G32B32A32: - case VertexFormat::INT_R32G32B32A32: - ret = 4; - break; - case VertexFormat::FLOAT_R32G32B32: - case VertexFormat::INT_R32G32B32: - ret = 3; - break; - case VertexFormat::FLOAT_R32G32: - case VertexFormat::INT_R32G32: - ret = 2; - break; - case VertexFormat::FLOAT_R32: - case VertexFormat::INT_R32: - ret = 1; - break; - default: - break; - } - return ret; - } -} - -Program::Program(const RenderPipelineDescriptor& descriptor) -: _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(); -} - -Program::~Program() -{ - CC_SAFE_RELEASE(_vertexShaderModule); - CC_SAFE_RELEASE(_fragmentShaderModule); - if (_program) - glDeleteProgram(_program); -} - -void Program::compileProgram() -{ - if (_vertexShaderModule == nullptr || _fragmentShaderModule == nullptr) - return; - - auto vertShader = _vertexShaderModule->getShader(); - auto fragShader = _fragmentShaderModule->getShader(); - - assert (vertShader != 0 && fragShader != 0); - if (vertShader == 0 || fragShader == 0) - return; - - _program = glCreateProgram(); - if (!_program) - return; - - glAttachShader(_program, vertShader); - glAttachShader(_program, fragShader); - glLinkProgram(_program); - - GLint status = 0; - glGetProgramiv(_program, GL_LINK_STATUS, &status); - if (GL_FALSE == status) - { - printf("cocos2d: ERROR: %s: failed to link program ", __FUNCTION__); - glDeleteProgram(_program); - _program = 0; - } -} - -void Program::computeAttributeInfos(const RenderPipelineDescriptor& descriptor) -{ - const auto& vertexLayouts = descriptor.vertexLayouts; - for (const auto& vertexLayout : vertexLayouts) - { - if (! vertexLayout.isValid()) - continue; - - VertexAttributeArray vertexAttributeArray; - - const auto& attributes = vertexLayout.getAttributes(); - for (const auto& attribute : attributes) - { - AttributeInfo attributeInfo; - - if (!getAttributeLocation(attribute.name, attributeInfo.location)) - continue; - - attributeInfo.stride = vertexLayout.getStride(); - attributeInfo.offset = attribute.offset; - attributeInfo.type = toGLAttributeType(attribute.format); - attributeInfo.size = getGLAttributeSize(attribute.format); - - vertexAttributeArray.push_back(attributeInfo); - } - - _attributeInfos.push_back(std::move(vertexAttributeArray)); - } -} - -bool Program::getAttributeLocation(const std::string& attributeName, uint32_t& location) -{ - GLint loc = glGetAttribLocation(_program, attributeName.c_str()); - if (-1 == loc) - { - printf("Cocos2d: %s: can not find vertex attribute of %s", __FUNCTION__, attributeName.c_str()); - return false; - } - - location = GLuint(loc); - return true; -} - -void Program::computeUniformInfos() -{ - if (!_program) - return; - - GLint numOfUniforms = 0; - glGetProgramiv(_program, GL_ACTIVE_UNIFORMS, &numOfUniforms); - if (!numOfUniforms) - return; - -#define MAX_UNIFORM_NAME_LENGTH 256 - UniformInfo uniform; - GLint length = 0; - GLchar* uniformName = (GLchar*)malloc(MAX_UNIFORM_NAME_LENGTH + 1); - for (int i = 0; i < numOfUniforms; ++i) - { - glGetActiveUniform(_program, i, MAX_UNIFORM_NAME_LENGTH, &length, &uniform.size, &uniform.type, uniformName); - uniformName[length] = '\0'; - - if (length > 3) - { - char* c = strrchr(uniformName, '['); - if (c) - { - *c = '\0'; - uniform.isArray = true; - } - } - - uniform.name = uniformName; - uniform.location = glGetUniformLocation(_program, uniformName); - - _uniformInfos.push_back(uniform); - } - free(uniformName); -} - -CC_BACKEND_END diff --git a/src/backend/opengl/ProgramGL.cpp b/src/backend/opengl/ProgramGL.cpp new file mode 100644 index 0000000..69011e8 --- /dev/null +++ b/src/backend/opengl/ProgramGL.cpp @@ -0,0 +1,373 @@ +#include "ProgramGL.h" +#include "ShaderModuleGL.h" +#include "ccMacros.h" +#include "TextureGL.h" +#include +#include +#include + +CC_BACKEND_BEGIN + +namespace +{ + GLenum toGLAttributeType(VertexFormat vertexFormat) + { + GLenum ret = GL_INT; + switch (vertexFormat) + { + case VertexFormat::FLOAT_R32G32B32A32: + case VertexFormat::FLOAT_R32G32B32: + case VertexFormat::FLOAT_R32G32: + case VertexFormat::FLOAT_R32: + ret = GL_FLOAT; + break; + case VertexFormat::INT_R32G32B32A32: + case VertexFormat::INT_R32G32B32: + case VertexFormat::INT_R32G32: + case VertexFormat::INT_R32: + ret = GL_INT; + break; + default: + break; + } + return ret; + } + + GLsizei getGLAttributeSize(VertexFormat vertexFormat) + { + GLsizei ret = 0; + switch (vertexFormat) + { + case VertexFormat::FLOAT_R32G32B32A32: + case VertexFormat::INT_R32G32B32A32: + ret = 4; + break; + case VertexFormat::FLOAT_R32G32B32: + case VertexFormat::INT_R32G32B32: + ret = 3; + break; + case VertexFormat::FLOAT_R32G32: + case VertexFormat::INT_R32G32: + ret = 2; + break; + case VertexFormat::FLOAT_R32: + case VertexFormat::INT_R32: + ret = 1; + break; + default: + break; + } + 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(const std::string& vertexShader, const std::string& fragmentShader) +: Program(vertexShader, fragmentShader) +{ + _vertexShaderModule = new (std::nothrow) ShaderModuleGL(backend::ShaderStage::VERTEX, vertexShader); + _fragmentShaderModule = new (std::nothrow) ShaderModuleGL(backend::ShaderStage::FRAGMENT, fragmentShader); + + createProgram(); + computeUniformInfos(); +} + +ProgramGL::~ProgramGL() +{ + CC_SAFE_RELEASE(_vertexShaderModule); + CC_SAFE_RELEASE(_fragmentShaderModule); + if (_program) + glDeleteProgram(_program); +} + +void ProgramGL::createProgram() +{ + if (_vertexShaderModule == nullptr || _fragmentShaderModule == nullptr) + return; + + auto vertShader = _vertexShaderModule->getShader(); + auto fragShader = _fragmentShaderModule->getShader(); + + assert (vertShader != 0 && fragShader != 0); + if (vertShader == 0 || fragShader == 0) + return; + + _program = glCreateProgram(); + if (!_program) + return; + + glAttachShader(_program, vertShader); + glAttachShader(_program, fragShader); + glLinkProgram(_program); + + GLint status = 0; + glGetProgramiv(_program, GL_LINK_STATUS, &status); + if (GL_FALSE == status) + { + printf("cocos2d: ERROR: %s: failed to link program ", __FUNCTION__); + glDeleteProgram(_program); + _program = 0; + } +} + +void ProgramGL::computeAttributeInfos(const RenderPipelineDescriptor& descriptor) +{ + const auto& vertexLayouts = descriptor.vertexLayouts; + for (const auto& vertexLayout : vertexLayouts) + { + if (! vertexLayout.isValid()) + continue; + + VertexAttributeArray vertexAttributeArray; + + const auto& attributes = vertexLayout.getAttributes(); + for (const auto& attribute : attributes) + { + AttributeInfo attributeInfo; + + if (!getAttributeLocation(attribute.name, attributeInfo.location)) + continue; + + attributeInfo.stride = vertexLayout.getStride(); + attributeInfo.offset = attribute.offset; + attributeInfo.type = toGLAttributeType(attribute.format); + attributeInfo.size = getGLAttributeSize(attribute.format); + + vertexAttributeArray.push_back(attributeInfo); + } + + _attributeInfos.push_back(std::move(vertexAttributeArray)); + } +} + +bool ProgramGL::getAttributeLocation(const std::string& attributeName, uint32_t& location) +{ + GLint loc = glGetAttribLocation(_program, attributeName.c_str()); + if (-1 == loc) + { + printf("Cocos2d: %s: can not find vertex attribute of %s", __FUNCTION__, attributeName.c_str()); + return false; + } + + location = GLuint(loc); + return true; +} + +void ProgramGL::computeUniformInfos() +{ + if (!_program) + return; + + GLint numOfUniforms = 0; + glGetProgramiv(_program, GL_ACTIVE_UNIFORMS, &numOfUniforms); + if (!numOfUniforms) + return; + +#define MAX_UNIFORM_NAME_LENGTH 256 + UniformInfo uniform; + GLint length = 0; + GLchar* uniformName = (GLchar*)malloc(MAX_UNIFORM_NAME_LENGTH + 1); + for (int i = 0; i < numOfUniforms; ++i) + { + glGetActiveUniform(_program, i, MAX_UNIFORM_NAME_LENGTH, &length, &uniform.size, &uniform.type, uniformName); + uniformName[length] = '\0'; + + if (length > 3) + { + char* c = strrchr(uniformName, '['); + if (c) + { + *c = '\0'; + uniform.isArray = true; + } + } + + 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); + _uniformInfos[uniform.location] = uniform; + } + free(uniformName); +} + +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()); +} + +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); + 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)) +#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/Program.h b/src/backend/opengl/ProgramGL.h similarity index 55% rename from src/backend/opengl/Program.h rename to src/backend/opengl/ProgramGL.h index e44a14c..96740ca 100644 --- a/src/backend/opengl/Program.h +++ b/src/backend/opengl/ProgramGL.h @@ -5,8 +5,10 @@ #include "../RenderPipelineDescriptor.h" #include "base/CCRef.h" #include "platform/CCGL.h" +#include "../Program.h" #include +#include CC_BACKEND_BEGIN @@ -28,33 +30,41 @@ struct UniformInfo GLuint location = 0; GLenum type = GL_FLOAT; bool isArray = false; + std::shared_ptr buffer = nullptr; }; -class Program : public cocos2d::Ref +class ProgramGL : public Program { public: typedef std::vector VertexAttributeArray; - Program(const RenderPipelineDescriptor& descriptor); - ~Program(); + ProgramGL(const std::string& vertexShader, const std::string& fragmentShader); + ~ProgramGL(); + + 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 const std::unordered_map& getUniformInfos() const { return _uniformInfos; } inline GLuint getHandler() const { return _program; } + void computeAttributeInfos(const RenderPipelineDescriptor& descriptor); private: - void compileProgram(); - void computeAttributeInfos(const RenderPipelineDescriptor& descriptor); + void createProgram(); 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; GLuint _program = 0; ShaderModuleGL* _vertexShaderModule = nullptr; ShaderModuleGL* _fragmentShaderModule = nullptr; std::vector _attributeInfos; - std::vector _uniformInfos; + std::unordered_map _uniformInfos; }; CC_BACKEND_END diff --git a/src/backend/opengl/RenderPipelineGL.cpp b/src/backend/opengl/RenderPipelineGL.cpp index 6155f8c..8caf6bd 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 @@ -9,8 +9,11 @@ CC_BACKEND_BEGIN RenderPipelineGL::RenderPipelineGL(const RenderPipelineDescriptor& descriptor) +: RenderPipeline(descriptor.program) { - _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 +26,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..d429a31 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* getGLProgram() 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-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 786481c..e5b86aa 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 */; }; @@ -133,7 +132,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 */; }; @@ -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 */; }; @@ -190,8 +188,15 @@ 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 */; }; + 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 */; }; /* End PBXBuildFile section */ /* Begin PBXCopyFilesBuildPhase section */ @@ -375,8 +380,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 = ""; }; @@ -390,8 +393,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 = ""; }; @@ -469,10 +472,17 @@ 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 = ""; }; 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 = ""; }; + EDC86F5221DDA3F00086A0CA /* ProgramMTL.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = ProgramMTL.mm; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -828,11 +838,14 @@ 460373AF212FA9EB00DC9ED4 /* backend */ = { isa = PBXGroup; children = ( + ED1B08F521E2FDA000E1191B /* ProgramCache.h */, + ED1B08F621E3011500E1191B /* ProgramCache.cpp */, + 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 */, @@ -874,8 +887,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 +988,8 @@ 466BA3B5216C79C7006C15A5 /* DepthStencilStateMTL.h */, 46486F2F217077020078BE0E /* Utils.mm */, 46486F30217077020078BE0E /* Utils.h */, + EDC86F5121DDA3CE0086A0CA /* ProgramMTL.h */, + EDC86F5221DDA3F00086A0CA /* ProgramMTL.mm */, ); path = metal; sourceTree = ""; @@ -1220,6 +1235,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 */, @@ -1233,8 +1249,7 @@ 461DD0E72153845000A8E43F /* Device.cpp in Sources */, 461F45AF217719F700D83671 /* PostProcessBackend.cpp in Sources */, 1A255E3820034B0D00069420 /* CCFileUtils.cpp in Sources */, - 4603744C2148BA9900DC9ED4 /* Program.cpp in Sources */, - 46037413214247A700DC9ED4 /* BindGroup.cpp in Sources */, + 4603744C2148BA9900DC9ED4 /* ProgramGL.cpp in Sources */, 4603757E214FA82D00DC9ED4 /* BlendStateGL.cpp in Sources */, 461F45B32178570700D83671 /* SubImageBackend.cpp in Sources */, 1A255E6220034B0D00069420 /* ccRandom.cpp in Sources */, @@ -1254,8 +1269,10 @@ 4603744321479AFC00DC9ED4 /* DepthStencilStateGL.cpp in Sources */, 1A255E5620034B0D00069420 /* Vec4.cpp in Sources */, 1A255E6420034B0D00069420 /* ZipUtils.cpp in Sources */, + 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 */, @@ -1314,12 +1331,14 @@ 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 */, 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 */, @@ -1327,7 +1346,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 */, @@ -1339,6 +1357,8 @@ 1A255E4720034B0D00069420 /* MathUtil.cpp in Sources */, 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 */, @@ -1381,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)", @@ -1414,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/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 db307d2..ffb6281 100644 --- a/test/tests/backend/BasicBackend.cpp +++ b/test/tests/backend/BasicBackend.cpp @@ -29,8 +29,8 @@ #include "backend/RenderPipelineDescriptor.h" #include "backend/RenderPassDescriptor.h" -#include "backend/ShaderModule.h" #include "backend/VertexLayout.h" +#include "backend/ProgramCache.h" std::string test_unrollLoops(const std::string& text); @@ -62,12 +62,9 @@ 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.vertexShaderModule = vs; - renderPipelineDescriptor.fragmentShaderModule = fs; + renderPipelineDescriptor.program = device->createProgram(vert, frag); + _colorLocation = renderPipelineDescriptor.program->getFragmentUniformLocation("color"); backend::VertexLayout vertexLayout; vertexLayout.setAtrribute("a_position", 0, cocos2d::backend::VertexFormat::FLOAT_R32G32, 0); @@ -103,8 +100,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)); - _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 4ca6532..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,7 @@ 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 c519360..0fd55f4 100644 --- a/test/tests/backend/BlendingBackend.cpp +++ b/test/tests/backend/BlendingBackend.cpp @@ -66,10 +66,10 @@ 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.vertexShaderModule = vs; - renderPipelineDescriptor.fragmentShaderModule = fs; + renderPipelineDescriptor.program = device->createProgram(vert, frag); + _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); @@ -166,6 +166,10 @@ namespace CC_SAFE_RELEASE(indexBuffer); } + 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; backend::RenderPipeline* renderPipelineAddtive = nullptr; @@ -173,6 +177,10 @@ namespace backend::RenderPipeline* renderPipelineMultiply = nullptr; backend::Buffer* vertexBuffer = nullptr; backend::Buffer* indexBuffer = nullptr; + + int _modelLocation = -1; + int _projectionLocation = -1; + int _textureLocation = -1; }; struct BigTriangle @@ -210,10 +218,9 @@ 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.vertexShaderModule = vs; - renderPipelineDescriptor.fragmentShaderModule = fs; + renderPipelineDescriptor.program = device->createProgram(vert, frag); + _timeLocation = renderPipelineDescriptor.program->getFragmentUniformLocation("time"); + _textureLocation = renderPipelineDescriptor.program->getFragmentUniformLocation("texture"); backend::VertexLayout vertexLayout; vertexLayout.setAtrribute("a_position", 0, cocos2d::backend::VertexFormat::FLOAT_R32G32, 0); @@ -239,8 +246,13 @@ namespace CC_SAFE_RELEASE(vertexBuffer); } + inline int getTimeLocation() const { return _timeLocation; } + inline backend::Program* getProgram() { return renderPipeline->getProgram(); } + backend::RenderPipeline* renderPipeline = nullptr; backend::Buffer* vertexBuffer = nullptr; + int _timeLocation = -1; + int _textureLocation = -1; }; // rotation is not used @@ -283,6 +295,7 @@ BlendingBackend::BlendingBackend() textureDescriptorBackgroud.textureFormat = backend::TextureFormat::R8G8B8A8; _backgroud = device->newTexture(textureDescriptorBackgroud); _backgroud->updateData(utils::loadData("assets/background.png").getBytes()); + bigTriangle->getProgram()->setFragmentTexture(bigTriangle->_textureLocation, 0, _backgroud); backend::TextureDescriptor textureDescriptorSprite0; textureDescriptorSprite0.width = 128; @@ -290,6 +303,7 @@ BlendingBackend::BlendingBackend() textureDescriptorSprite0.textureFormat = backend::TextureFormat::R8G8B8A8; _sprite0 = device->newTexture(textureDescriptorSprite0); _sprite0->updateData(utils::loadData("assets/sprite0.png").getBytes()); + quad->getProgram()->setFragmentTexture(quad->_textureLocation, 0, _sprite0); _commandBuffer = device->newCommandBuffer(); @@ -330,10 +344,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.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); @@ -354,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.setUniform("model", _model.m, sizeof(_model.m)); - _bindGroup.setUniform("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); @@ -373,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.setUniform("model", _model.m, sizeof(_model.m)); - _bindGroup.setUniform("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); @@ -392,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.setUniform("model", _model.m, sizeof(_model.m)); - _bindGroup.setUniform("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); @@ -411,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.setUniform("model", _model.m, sizeof(_model.m)); - _bindGroup.setUniform("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); @@ -430,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.setUniform("model", _model.m, sizeof(_model.m)); - _bindGroup.setUniform("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 e719ffe..95599ef 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/ProgramCache.h" using namespace cocos2d; @@ -81,11 +82,11 @@ 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.vertexShaderModule = vs; - renderPipelineDescriptor.fragmentShaderModule = fs; + renderPipelineDescriptor.program = device->createProgram(vert, frag); + _modelLocation = renderPipelineDescriptor.program->getVertexUniformLocation("model"); + _viewLocation = renderPipelineDescriptor.program->getVertexUniformLocation("view"); + _projectionLocation = renderPipelineDescriptor.program->getVertexUniformLocation("projection"); + _colorLocation = renderPipelineDescriptor.program->getFragmentUniformLocation("color"); _renderPipeline = device->newRenderPipeline(renderPipelineDescriptor); @@ -98,11 +99,11 @@ BunnyBackend::BunnyBackend() _renderPassDescriptor.needDepthAttachment = true; // bind group - _bindGroup.setUniform("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.setUniform("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.setUniform("color", color, sizeof(color)); + _renderPipeline->getProgram()->setFragmentUniform(_colorLocation, color, sizeof(color)); // vertex buffer _vertexBuffer = device->newBuffer(sizeof(bunny_positions), @@ -131,7 +132,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)); + + _renderPipeline->getProgram()->setVertexUniform(_viewLocation, _view.m, sizeof(_view.m)); _commandBuffer->beginFrame(); @@ -140,7 +142,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 f6a57ec..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; @@ -54,5 +52,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..e5dc169 100644 --- a/test/tests/backend/DepthTextureBackend.cpp +++ b/test/tests/backend/DepthTextureBackend.cpp @@ -75,10 +75,10 @@ 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.vertexShaderModule = vs; - renderPipelineDescriptor.fragmentShaderModule = fs; + renderPipelineDescriptor.program = device->createProgram(vert, frag); + _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); @@ -102,8 +102,16 @@ namespace CC_SAFE_RELEASE(vertexBuffer); } + 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; + + int _nearLocation = -1; + int _farLocation = -1; + int _textureLocation = -1; }; struct Bunny @@ -146,10 +154,10 @@ 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.vertexShaderModule = vs; - renderPipelineDescriptor.fragmentShaderModule =fs; + renderPipelineDescriptor.program = device->createProgram(vert, frag); + _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); @@ -186,9 +194,18 @@ namespace CC_SAFE_RELEASE(renderPipeline); } + 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; backend::RenderPipeline* renderPipeline = nullptr; + + int _modelLocation = -1; + int _viewLocation = -1; + int _projectionLocation = -1; }; BigTriangle* bg; @@ -198,6 +215,8 @@ namespace DepthTextureBackend::DepthTextureBackend() : _t(0.0f) { + bunny = new Bunny(); + bg = new BigTriangle(); auto device = backend::Device::getInstance(); // depth texture @@ -213,6 +232,7 @@ DepthTextureBackend::DepthTextureBackend() textureDescriptor.samplerDescriptor = samplerDescriptor; textureDescriptor.textureFormat = backend::TextureFormat::D24S8; _depthTexture = device->newTexture(textureDescriptor); + bg->getProgram()->setFragmentTexture(bg->_textureLocation, 0, _depthTexture); // render pass Bunny 1 _renderPassBunny1.clearDepthValue = 1; @@ -235,9 +255,6 @@ DepthTextureBackend::DepthTextureBackend() _renderPassBigTriangle.needColorAttachment = true; _commandBuffer = device->newCommandBuffer(); - - bunny = new Bunny(); - bg = new BigTriangle(); } DepthTextureBackend::~DepthTextureBackend() @@ -271,10 +288,10 @@ 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)); - _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, @@ -288,10 +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)); - _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, @@ -304,12 +320,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.setUniform("near", &near, sizeof(float)); - _bindGroupBigTriangle.setUniform("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 e7b7d02..b09b1bb 100644 --- a/test/tests/backend/GuiProjectionBackend.cpp +++ b/test/tests/backend/GuiProjectionBackend.cpp @@ -66,10 +66,11 @@ 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.vertexShaderModule = vs; - renderPipelineDescriptor.fragmentShaderModule = fs; + renderPipelineDescriptor.program = device->createProgram(vert, frag); + _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 @@ -98,6 +99,7 @@ GuiProjectionBackend::GuiProjectionBackend() textureDescriptor.height = img->getHeight(); _texture = device->newTexture(textureDescriptor); _texture->updateData(data.getBytes()); + _renderPipeline->getProgram()->setFragmentTexture(_textureLocation, 0, _texture); img->release(); @@ -142,19 +144,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.setUniform("color", redColor, sizeof(redColor)); - _bindGroup.setUniform("projection", _projection.m, sizeof(_projection.m)); - _bindGroup.setUniform("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 @@ -162,11 +161,10 @@ 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)); + 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); @@ -175,11 +173,10 @@ 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)); + 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 789586b..d701ec1 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; @@ -49,6 +48,11 @@ class GuiProjectionBackend : public TestBaseI cocos2d::Mat4 _translantion; cocos2d::Mat4 _rotation; cocos2d::Mat4 _scale; + + 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 f9adbe0..7e8f5d8 100644 --- a/test/tests/backend/MultiTexturesBackend.cpp +++ b/test/tests/backend/MultiTexturesBackend.cpp @@ -67,10 +67,11 @@ 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.vertexShaderModule = vs; - renderPipelineDescriptor.fragmentShaderModule = fs; + renderPipelineDescriptor.program = device->createProgram(vert, frag); + _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); @@ -93,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()->setFragmentTexture(_texture2Location, 7, _texture1); int dataSize = 512 * 512 * 3; uint8_t data[dataSize]; @@ -108,6 +110,7 @@ MultiTexturesBackend::MultiTexturesBackend() textureDescriptor2.textureFormat = backend::TextureFormat::R8G8B8; _background = device->newTexture(textureDescriptor2); _background->updateData(data); + _renderPipeline->getProgram()->setFragmentTexture(_texture1Location, 6, _background); _transform = cocos2d::Mat4::IDENTITY; _transform.translate(0, 0, 0); @@ -142,12 +145,9 @@ 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.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 07ca567..7743cbb 100644 --- a/test/tests/backend/MultiTexturesBackend.h +++ b/test/tests/backend/MultiTexturesBackend.h @@ -43,7 +43,11 @@ 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; + + 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 c55d1cf..ce87562 100644 --- a/test/tests/backend/ParticleBackend.cpp +++ b/test/tests/backend/ParticleBackend.cpp @@ -75,10 +75,11 @@ 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.vertexShaderModule = vs; - renderPipelineDescriptor.fragmentShaderModule = fs; + renderPipelineDescriptor.program = device->createProgram(vert, frag); + _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 @@ -129,6 +130,7 @@ ParticleBackend::ParticleBackend() textureDescriptor.samplerDescriptor.mipmapEnabled = true; _texture = device->newTexture(textureDescriptor); _texture->updateData(imageData.getBytes()); + _renderPipelineWithBlend->getProgram()->setFragmentTexture(_textureLocation, 0, _texture); _commandBuffer = device->newCommandBuffer(); _vertexBuffer = device->newBuffer(sizeof(_vbufferArray), backend::BufferType::VERTEX, backend::BufferUsage::READ); @@ -225,12 +227,10 @@ 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.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 9ad4031..a5d7eb7 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; @@ -66,5 +65,10 @@ class ParticleBackend : public TestBaseI #define particleCount 100 ParticleData _particles[particleCount]; + + 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 6914085..58dcd4f 100644 --- a/test/tests/backend/PostProcessBackend.cpp +++ b/test/tests/backend/PostProcessBackend.cpp @@ -90,12 +90,10 @@ 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.vertexShaderModule = vs; - renderPipelineDescriptor.fragmentShaderModule = fs; - + + renderPipelineDescriptor.program = device->createProgram(vert, frag); + _textureLocation = renderPipelineDescriptor.program->getFragmentUniformLocation("texture"); + backend::VertexLayout vertexLayout; vertexLayout.setAtrribute("a_position", 0, backend::VertexFormat::FLOAT_R32G32, 0); vertexLayout.setLayout(2 * sizeof(float), backend::VertexStepMode::VERTEX); @@ -115,8 +113,11 @@ namespace CC_SAFE_RELEASE(_renderPipeline); } + inline cocos2d::backend::Program* getProgram() { return _renderPipeline->getProgram(); } + backend::Buffer* _vertexBuffer = nullptr; backend::RenderPipeline* _renderPipeline = nullptr; + int _textureLocation = -1; }; struct Bunny @@ -161,10 +162,11 @@ 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.vertexShaderModule = vs; - renderPipelineDescriptor.fragmentShaderModule = fs; + renderPipelineDescriptor.program = device->createProgram(vert, frag); + _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); @@ -197,9 +199,20 @@ 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; } + inline backend::Program* getProgram() { return _renderPipeline->getProgram(); } + 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; @@ -209,6 +222,9 @@ namespace PostProcessBackend::PostProcessBackend() : _t(0.0f) { + bunny = new Bunny(); + bg = new BigTriangle(); + auto device = backend::Device::getInstance(); backend::TextureDescriptor textureDescriptor; @@ -249,9 +265,6 @@ PostProcessBackend::PostProcessBackend() _renderPassDescriptorBg.needDepthAttachment = true; _commandBuffer = device->newCommandBuffer(); - - bunny = new Bunny(); - bg = new BigTriangle(); } PostProcessBackend::~PostProcessBackend() @@ -290,13 +303,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)); + 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.setUniform("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])); @@ -311,12 +322,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)); + 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.setUniform("color", color2 , sizeof(color2)); - _commandBuffer->setBindGroup(&_bindGroup); + bunny->getProgram()->setFragmentUniform(bunny->getColorLocaiton(), color2 , sizeof(color2)); _commandBuffer->drawElements(backend::PrimitiveType::TRIANGLE, backend::IndexFormat::U_SHORT, @@ -326,10 +336,7 @@ void PostProcessBackend::tick(float dt) // Draw bg. _commandBuffer->beginRenderPass(_renderPassDescriptorBg); - - _bindGroup.setTexture("texture", 0, _colorTexture); - _commandBuffer->setBindGroup(&_bindGroup); - + 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/PostProcessBackend.h b/test/tests/backend/PostProcessBackend.h index 87ed70e..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" @@ -38,12 +38,13 @@ 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; 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..bb4c90b 100644 --- a/test/tests/backend/StencilBackend.cpp +++ b/test/tests/backend/StencilBackend.cpp @@ -91,10 +91,11 @@ 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.vertexShaderModule = vs; - renderPipelineDescriptor.fragmentShaderModule = fs; + renderPipelineDescriptor.program = device->createProgram(vert, frag); + _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); vertexLayout.setLayout(2 * sizeof(float), cocos2d::backend::VertexStepMode::VERTEX); @@ -185,10 +186,10 @@ 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.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()->setFragmentTexture(_textureLocation, 0, _canvasTexture); _commandBuffer->drawArrays(cocos2d::backend::PrimitiveType::TRIANGLE, 0, 6); @@ -205,10 +206,10 @@ 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)); - _commandBuffer->setBindGroup(&_bindGroup); + _renderPipeline->getProgram()->setFragmentTexture(_textureLocation, 0, _texture); + _renderPipeline->getProgram()->setVertexUniform(_transformLocation, _transform1.m, sizeof(_transform1.m)); + _commandBuffer->drawArrays(cocos2d::backend::PrimitiveType::TRIANGLE, 0, 6); _commandBuffer->endRenderPass(); } @@ -225,9 +226,8 @@ void StencilBackend::tick(float dt) _commandBuffer->setStencilReferenceValue(0x1); _commandBuffer->setRenderPipeline(_renderPipelineCavasTexture); - _bindGroup.setUniform("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()->setFragmentTexture(_textureLocation, 0, _canvasTexture); _commandBuffer->drawArrays(cocos2d::backend::PrimitiveType::TRIANGLE, 0, 6); _commandBuffer->endRenderPass(); } @@ -240,10 +240,9 @@ void StencilBackend::tick(float dt) _commandBuffer->setVertexBuffer(0, _vertexBuffer); _commandBuffer->setCullMode(backend::CullMode::NONE); - _bindGroup.setTexture("texture", 0, _texture); - _bindGroup.setUniform("transform", _transform1.m, sizeof(_transform1.m)); - _commandBuffer->setBindGroup(&_bindGroup); - + _renderPipeline->getProgram()->setFragmentTexture(_textureLocation, 0, _texture); + _renderPipeline->getProgram()->setVertexUniform(_transformLocation, _transform1.m, sizeof(_transform1.m)); + _commandBuffer->drawArrays(cocos2d::backend::PrimitiveType::TRIANGLE, 0, 6); _commandBuffer->endRenderPass(); } @@ -259,9 +258,8 @@ void StencilBackend::tick(float dt) _commandBuffer->setStencilReferenceValue(0x1); _commandBuffer->setRenderPipeline(_renderPipelineCavasTexture); - _bindGroup.setUniform("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()->setFragmentTexture(_textureLocation, 0, _canvasTexture); _commandBuffer->drawArrays(cocos2d::backend::PrimitiveType::TRIANGLE, 0, 6); _commandBuffer->endRenderPass(); } @@ -274,10 +272,9 @@ void StencilBackend::tick(float dt) _commandBuffer->setVertexBuffer(0, _vertexBuffer); _commandBuffer->setCullMode(backend::CullMode::NONE); - _bindGroup.setTexture("texture", 0, _texture); - _bindGroup.setUniform("transform", _transform1.m, sizeof(_transform1.m)); - _commandBuffer->setBindGroup(&_bindGroup); - + _renderPipeline->getProgram()->setFragmentTexture(_textureLocation, 0, _texture); + _renderPipeline->getProgram()->setVertexUniform(_transformLocation, _transform1.m, sizeof(_transform1.m)); + _commandBuffer->drawArrays(cocos2d::backend::PrimitiveType::TRIANGLE, 0, 6); _commandBuffer->endRenderPass(); } @@ -292,9 +289,8 @@ void StencilBackend::tick(float dt) _commandBuffer->setStencilReferenceValue(0x1); _commandBuffer->setRenderPipeline(_renderPipelineCavasTexture); - _bindGroup.setUniform("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()->setFragmentTexture(_textureLocation, 0, _canvasTexture); _commandBuffer->drawArrays(cocos2d::backend::PrimitiveType::TRIANGLE, 0, 6); _commandBuffer->endRenderPass(); } @@ -307,9 +303,8 @@ void StencilBackend::tick(float dt) _commandBuffer->setStencilReferenceValue(0x1); _commandBuffer->setCullMode(backend::CullMode::NONE); - _bindGroup.setTexture("texture", 0, _texture); - _bindGroup.setUniform("transform", _transform1.m, sizeof(_transform1.m)); - _commandBuffer->setBindGroup(&_bindGroup); + _renderPipeline->getProgram()->setFragmentTexture(_textureLocation, 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 4d031f9..02dc5ed 100644 --- a/test/tests/backend/StencilBackend.h +++ b/test/tests/backend/StencilBackend.h @@ -45,13 +45,16 @@ 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; cocos2d::backend::RenderPipeline* _renderPipelineTextureBackAndFront = nullptr; cocos2d::backend::RenderPipeline* _renderPipelineTextureBack = nullptr; cocos2d::backend::RenderPipeline* _renderPipelineTextureFront = nullptr; + + int _transformLocation = -1; + int _colorLocation = -1; + int _textureLocation = -1; }; diff --git a/test/tests/backend/SubImageBackend.cpp b/test/tests/backend/SubImageBackend.cpp index 3e21e93..630d956 100644 --- a/test/tests/backend/SubImageBackend.cpp +++ b/test/tests/backend/SubImageBackend.cpp @@ -36,11 +36,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; } )"; @@ -50,7 +49,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); @@ -60,10 +58,8 @@ 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.vertexShaderModule = vs; - renderPipelineDescriptor.fragmentShaderModule = fs; + renderPipelineDescriptor.program = device->createProgram(vert, frag); + _textureLocation = renderPipelineDescriptor.program->getFragmentUniformLocation("texture"); backend::VertexLayout vertexLayout; vertexLayout.setAtrribute("a_position", 0, backend::VertexFormat::FLOAT_R32G32, 0); @@ -133,12 +129,7 @@ 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.setTexture("texture", 0, _texture); - _commandBuffer->setBindGroup(&_bindGroup); + _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 8a107d2..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 { @@ -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,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 762a1d9..68ae531 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/ProgramCache.h" #include @@ -117,10 +118,10 @@ 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.vertexShaderModule = vs; - renderPipelineDescriptor.fragmentShaderModule = fs; + renderPipelineDescriptor.program = device->createProgram(vert, frag); + _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); @@ -133,16 +134,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.setUniform("color", color, sizeof(color)); - _bindGroupCanvas.setUniform("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)); - // render pass _renderPassDescriptor.clearColorValue = {0.1f, 0.1f, 0.1f, 0.1f}; _renderPassDescriptor.needClearColor = true; @@ -163,6 +154,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; @@ -170,7 +163,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()->setFragmentTexture(_textureLocation, 0, _canvasTexture); + _commandBuffer->drawArrays(cocos2d::backend::PrimitiveType::TRIANGLE, 0, 6); _commandBuffer->endRenderPass(); } @@ -182,7 +177,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()->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 ddc2d8b..5b644fc 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,11 +49,13 @@ 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; + + int _transformLocation = -1; + int _colorLocation = -1; + int _textureLocation = -1; };