From 9d06c9962adfade0811f36d3b04b21fe7865a226 Mon Sep 17 00:00:00 2001 From: "adam.b" Date: Wed, 4 Apr 2018 15:25:18 +0100 Subject: [PATCH] [Vulkan] Factories and general controller cleanup - Added working texture factory ( some features are still missing ) - Started work on the shaders factory in order to instatiate custom pipeline - Textures are created with the factory - Added shader factory - API::Shader is more like old Program rather than VkShaderModule - Added support for binary and text shader source - For now only SPIRV language is supported - Only vertex and fragment shader stages supported Known issue: - Due to not being cached, shaders are being created again when mouse enters the window area Change-Id: Ie03bf9e9c866f9b3ac3c51c7c1839049357663d9 --- build/tizen/dali-core/graphics/Makefile.am | 5 +- dali/graphics-api/graphics-api-accessor.h | 29 ++- dali/graphics-api/graphics-api-controller.h | 18 +- dali/graphics-api/graphics-api-render-command.h | 49 ++++ dali/graphics-api/graphics-api-shader-details.h | 81 ++++++- dali/graphics-api/graphics-api-shader-factory.h | 8 +- dali/graphics-api/graphics-api-texture-factory.h | 12 +- dali/graphics-api/graphics-api-texture.h | 2 +- dali/graphics/file.list | 4 + dali/graphics/graphics-controller.h | 1 - .../vulkan/api/vulkan-api-shader-factory.cpp | 74 ++++++ .../vulkan/api/vulkan-api-shader-factory.h | 91 ++++++++ dali/graphics/vulkan/api/vulkan-api-shader.cpp | 130 +++++++++++ dali/graphics/vulkan/api/vulkan-api-shader.h | 74 ++++++ .../vulkan/api/vulkan-api-texture-factory.cpp | 150 ++++++++++++ .../vulkan/api/vulkan-api-texture-factory.h | 84 +++++++ dali/graphics/vulkan/api/vulkan-api-texture.cpp | 108 +++++++++ dali/graphics/vulkan/api/vulkan-api-texture.h | 57 +++++ .../graphics/vulkan/api/vulkan-texture-factory.cpp | 40 ---- .../graphics/vulkan/vulkan-graphics-controller.cpp | 254 ++++++++++++++++----- dali/graphics/vulkan/vulkan-graphics-controller.h | 8 +- dali/graphics/vulkan/vulkan-graphics-texture.cpp | 8 +- dali/graphics/vulkan/vulkan-graphics-texture.h | 2 +- dali/graphics/vulkan/vulkan-pipeline.cpp | 38 +++ dali/graphics/vulkan/vulkan-pipeline.h | 19 +- dali/internal/render/renderers/render-renderer.cpp | 4 +- dali/internal/render/renderers/render-texture.cpp | 6 +- dali/internal/render/renderers/render-texture.h | 17 +- .../internal/render/shaders/scene-graph-shader.cpp | 13 +- dali/internal/render/shaders/scene-graph-shader.h | 9 +- .../update/graphics/graphics-algorithms.cpp | 14 +- dali/internal/update/manager/update-manager.cpp | 54 ++++- 32 files changed, 1311 insertions(+), 152 deletions(-) create mode 100644 dali/graphics/vulkan/api/vulkan-api-shader-factory.cpp create mode 100644 dali/graphics/vulkan/api/vulkan-api-shader-factory.h create mode 100644 dali/graphics/vulkan/api/vulkan-api-shader.cpp create mode 100644 dali/graphics/vulkan/api/vulkan-api-shader.h create mode 100644 dali/graphics/vulkan/api/vulkan-api-texture-factory.cpp create mode 100644 dali/graphics/vulkan/api/vulkan-api-texture-factory.h create mode 100644 dali/graphics/vulkan/api/vulkan-api-texture.cpp create mode 100644 dali/graphics/vulkan/api/vulkan-api-texture.h delete mode 100644 dali/graphics/vulkan/api/vulkan-texture-factory.cpp diff --git a/build/tizen/dali-core/graphics/Makefile.am b/build/tizen/dali-core/graphics/Makefile.am index f32b797..361e827 100644 --- a/build/tizen/dali-core/graphics/Makefile.am +++ b/build/tizen/dali-core/graphics/Makefile.am @@ -46,14 +46,15 @@ gcc_flags = -Wno-return-local-addr -Wsuggest-final-types -Wsuggest-final-methods # -Wfloat-equal causes issues with vulkan.hpp, removed for now cxx_more_warnings = -Wold-style-cast -Woverloaded-virtual -Wdouble-promotion -Wswitch-enum \ -Wshadow \ - -Wlarger-than=1024 -Wframe-larger-than=256 \ + -Wlarger-than=1024 \ -Wcast-qual -Wcast-align \ -Wconversion -Wsign-conversion # the following warnings should not be enforced cxx_warnings_to_remove = \ -Wno-c++98-compat \ - -Wno-unused-parameter + -Wno-unused-parameter \ + -Wno-unknown-warning-option #the following warnings should be added back when possible cxx_warnings_to_preserve = \ diff --git a/dali/graphics-api/graphics-api-accessor.h b/dali/graphics-api/graphics-api-accessor.h index 8f69225..10c80f5 100644 --- a/dali/graphics-api/graphics-api-accessor.h +++ b/dali/graphics-api/graphics-api-accessor.h @@ -34,15 +34,22 @@ class Accessor { public: Accessor(ObjectOwner< T >& owner, typename ObjectOwner< T >::Handle handle) - : mOwner(owner), // save owner to access object + : mOwner(&owner), // save owner to access object mHandle(handle) // handle to the object { } + Accessor(std::nullptr_t) + : mOwner( nullptr ), + mHandle( 0u ) + { + } + bool Exists() const { - return mOwner.Contains(mHandle); + return GetOwner().Contains(mHandle); } + operator bool() const { return Exists(); @@ -50,12 +57,17 @@ public: T& Get() { - return mOwner[mHandle]; + return (GetOwner())[mHandle]; } const T& Get() const { - return mOwner[mHandle]; + return (GetOwner())[mHandle]; + } + + typename ObjectOwner< T >::Handle GetHandle() const + { + return mHandle; } Accessor(const Accessor&) = default; @@ -65,7 +77,14 @@ public: Accessor& operator=(Accessor&&) = default; private: - ObjectOwner< T >& mOwner; + + ObjectOwner< T >& GetOwner() const + { + assert( mOwner ); + return *mOwner; + } + + ObjectOwner< T >* mOwner; typename ObjectOwner< T >::Handle mHandle; }; diff --git a/dali/graphics-api/graphics-api-controller.h b/dali/graphics-api/graphics-api-controller.h index 6f4667c..cd06dd4 100644 --- a/dali/graphics-api/graphics-api-controller.h +++ b/dali/graphics-api/graphics-api-controller.h @@ -28,6 +28,8 @@ #include #include #include +#include +#include #include #include #include @@ -40,6 +42,7 @@ namespace Graphics { namespace API { +class ShaderFactory; /** * @brief Interface class for Manager types in the graphics API. */ @@ -90,15 +93,16 @@ public: virtual void GetRenderItemList() = 0; /** - * Temporary way of instantiating new texture through controller - * @param width - * @param height + * @brief Returns texture factory * @return */ - virtual void* CreateTextureRGBA32( void* data, size_t sizeInBytes, uint32_t width, uint32_t height ) - { - return 0; - } + virtual TextureFactory& GetTextureFactory() const = 0; + + /** + * @brief Returns shader factory + * @return + */ + virtual ShaderFactory& GetShaderFactory() const = 0; /** * @brief Create a buffer diff --git a/dali/graphics-api/graphics-api-render-command.h b/dali/graphics-api/graphics-api-render-command.h index 3f74a93..d46dfc4 100644 --- a/dali/graphics-api/graphics-api-render-command.h +++ b/dali/graphics-api/graphics-api-render-command.h @@ -27,6 +27,8 @@ #include #include #include +#include +#include namespace Dali { @@ -34,9 +36,13 @@ namespace Graphics { namespace API { +class Shader; +class Texture; using PrimitiveCount = Utility::StrongType; using BufferInfo = std::unique_ptr; using BufferList = Utility::StrongType, struct BufferListTag>; +using ShaderList = std::vector>; +using TextureList = std::vector>; /** * @brief Interface class for RenderCommand types in the graphics API. @@ -69,9 +75,52 @@ public: return mBufferList; } + const auto& GetTextures() const + { + return mTextureList; + } + + Accessor GetShader( ShaderDetails::PipelineStage shaderStage ) const + { + using ShaderDetails::PipelineStage; + + auto retval = Accessor{nullptr}; + + size_t index = mShaders.size(); + switch( shaderStage ) + { + case PipelineStage::VERTEX: + { + index = 0; + break; + } + case PipelineStage::FRAGMENT: + { + index = 1; + break; + } + case PipelineStage::GEOMETRY: + case PipelineStage::COMPUTE: + case PipelineStage::TESSELATION_CONTROL: + case PipelineStage::TESSELATION_EVALUATION: + { + break; + } + } + if(index < mShaders.size()) + { + retval = mShaders[index]; + } + return retval; + } + + + private: PrimitiveCount mPrimitiveCount; BufferList mBufferList; + TextureList mTextureList; + ShaderList mShaders; }; using RenderCommandBuilder = Utility::Builder; diff --git a/dali/graphics-api/graphics-api-shader-details.h b/dali/graphics-api/graphics-api-shader-details.h index 3940c5d..984577a 100644 --- a/dali/graphics-api/graphics-api-shader-details.h +++ b/dali/graphics-api/graphics-api-shader-details.h @@ -1,5 +1,5 @@ -#ifndef DALI_GRAPHICS_API_TEXTURE_DETAILS_H -#define DALI_GRAPHICS_API_TEXTURE_DETAILS_H +#ifndef DALI_GRAPHICS_API_SHADER_DETAILS_H +#define DALI_GRAPHICS_API_SHADER_DETAILS_H /* * Copyright (c) 2017 Samsung Electronics Co., Ltd. @@ -19,6 +19,7 @@ */ #include +#include namespace Dali { @@ -29,7 +30,79 @@ namespace API namespace ShaderDetails { -using ShaderSource = std::string; +enum class ShaderSourceType +{ + STRING, + BINARY +}; + +struct ShaderSource +{ + /** + * Creates shader source object from source string + * @param sourceString + */ + explicit ShaderSource( const std::string& sourceString ) + { + source = sourceString; + type = ShaderSourceType::STRING; + } + + /** + * Creates shader source object from vector + * @param sourceBinary + */ + template + explicit ShaderSource( const std::vector& sourceBinary ) + { + code.resize( sourceBinary.size() * sizeof(T) ); + auto begin = reinterpret_cast(&*sourceBinary.begin()); + auto end = reinterpret_cast(&*sourceBinary.end()); + std::copy( begin, end, code.begin() ); + type = ShaderSourceType::BINARY; + } + + template + explicit ShaderSource( const std::vector& sourceBinary ) + { + code = sourceBinary; + type = ShaderSourceType::BINARY; + } + + /** + * Creates shader source object from C-Style binary data + * @param pBinary + * @param size + */ + explicit ShaderSource( const void* pBinary, uint32_t size ) + { + code.resize( size ); + auto begin = reinterpret_cast(pBinary); + auto end = begin + size; + std::copy( begin, end, code.begin() ); + type = ShaderSourceType::BINARY; + } + + ShaderSource( const ShaderSource& shaderSource ) = default; + + /** + * Tests whether the shader module has been set + * @return + */ + bool IsSet() const + { + if( (type == ShaderSourceType::BINARY && code.empty()) || + (type == ShaderSourceType::STRING && source.empty()) ) + { + return false; + } + return true; + } + + std::string source; + std::vector code; + ShaderSourceType type; +}; enum class Language { GLSL_1, @@ -53,4 +126,4 @@ enum class PipelineStage { } // namespace Graphics } // namespace Dali -#endif // DALI_GRAPHICS_API_TEXTURE_DETAILS_H +#endif // DALI_GRAPHICS_API_SHADER_DETAILS_H diff --git a/dali/graphics-api/graphics-api-shader-factory.h b/dali/graphics-api/graphics-api-shader-factory.h index fd8011c..301e4ce 100644 --- a/dali/graphics-api/graphics-api-shader-factory.h +++ b/dali/graphics-api/graphics-api-shader-factory.h @@ -32,15 +32,15 @@ namespace API /** * @brief Interface class for ShaderFactory types in the graphics API. */ -class ShaderFactory : BaseFactory< Shader > +class ShaderFactory : public BaseFactory { public: /** * @brief Set the source for a pipeline stage */ - virtual void SetSize(ShaderDetails::PipelineStage pipelineStage, - ShaderDetails::Language language, - const ShaderDetails::ShaderSource& source) = 0; + virtual ShaderFactory& SetShaderModule(ShaderDetails::PipelineStage pipelineStage, + ShaderDetails::Language language, + const ShaderDetails::ShaderSource& source) = 0; // not copyable ShaderFactory(const ShaderFactory&) = delete; diff --git a/dali/graphics-api/graphics-api-texture-factory.h b/dali/graphics-api/graphics-api-texture-factory.h index 1c2a604..3ed87b1 100644 --- a/dali/graphics-api/graphics-api-texture-factory.h +++ b/dali/graphics-api/graphics-api-texture-factory.h @@ -33,13 +33,15 @@ namespace API /** * @brief Interface class for TextureFactory types in the graphics API. */ -class TextureFactory : BaseFactory< Texture > +class TextureFactory : public BaseFactory { public: - virtual void SetType(TextureDetails::Type type) = 0; - virtual void SetSize(const RectSize& size) = 0; - virtual void SetFormat(TextureDetails::Format format) = 0; - virtual void SetMipMapFlag(TextureDetails::MipMapFlag mipMSapFlag) = 0; + virtual TextureFactory& SetType(TextureDetails::Type type) = 0; + virtual TextureFactory& SetSize(const RectSize& size) = 0; + virtual TextureFactory& SetFormat(TextureDetails::Format format) = 0; + virtual TextureFactory& SetMipMapFlag(TextureDetails::MipMapFlag mipMSapFlag) = 0; + virtual TextureFactory& SetData( void* pData ) = 0; + virtual TextureFactory& SetDataSize( uint32_t dataSizeInBytes ) = 0; // not copyable TextureFactory(const TextureFactory&) = delete; diff --git a/dali/graphics-api/graphics-api-texture.h b/dali/graphics-api/graphics-api-texture.h index f1b66f9..1d8f84b 100644 --- a/dali/graphics-api/graphics-api-texture.h +++ b/dali/graphics-api/graphics-api-texture.h @@ -39,7 +39,7 @@ public: virtual ~Texture() = default; protected: - // derived types should not be moved direcly to prevent slicing + // derived types should not be moved directly to prevent slicing Texture(Texture&&) = default; Texture& operator=(Texture&&) = default; diff --git a/dali/graphics/file.list b/dali/graphics/file.list index a602549..bd90075 100644 --- a/dali/graphics/file.list +++ b/dali/graphics/file.list @@ -20,6 +20,10 @@ graphics_src_files = \ $(graphics_src_dir)/vulkan/vulkan-sampler.cpp \ $(graphics_src_dir)/vulkan/vulkan-graphics-controller.cpp \ $(graphics_src_dir)/vulkan/vulkan-graphics-texture.cpp \ + $(graphics_src_dir)/vulkan/api/vulkan-api-shader.cpp \ + $(graphics_src_dir)/vulkan/api/vulkan-api-texture.cpp \ + $(graphics_src_dir)/vulkan/api/vulkan-api-texture-factory.cpp \ + $(graphics_src_dir)/vulkan/api/vulkan-api-shader-factory.cpp \ $(graphics_src_dir)/vulkan/spirv/vulkan-spirv.cpp \ $(graphics_src_dir)/graphics-controller.cpp diff --git a/dali/graphics/graphics-controller.h b/dali/graphics/graphics-controller.h index 9a8e3ce..270e257 100644 --- a/dali/graphics/graphics-controller.h +++ b/dali/graphics/graphics-controller.h @@ -66,7 +66,6 @@ public: ~Controller() override; - protected: ObjectOwner< API::Shader > mShaders; ObjectOwner< API::Texture > mTextures; diff --git a/dali/graphics/vulkan/api/vulkan-api-shader-factory.cpp b/dali/graphics/vulkan/api/vulkan-api-shader-factory.cpp new file mode 100644 index 0000000..c97548a --- /dev/null +++ b/dali/graphics/vulkan/api/vulkan-api-shader-factory.cpp @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include +#include +#include +#include + +namespace Dali +{ +namespace Graphics +{ +namespace VulkanAPI +{ +ShaderFactory::ShaderFactory( Vulkan::Graphics& graphics ) : +mGraphics( graphics ) +{ +} + +ShaderFactory::~ShaderFactory() = default; + +ShaderFactory& ShaderFactory::SetShaderModule( Graphics::API::ShaderDetails::PipelineStage pipelineStage, + Graphics::API::ShaderDetails::Language language, + const Graphics::API::ShaderDetails::ShaderSource& source ) +{ + using PipelineStage = Graphics::API::ShaderDetails::PipelineStage; + if( pipelineStage == PipelineStage::VERTEX ) + { + mVertexShader = ShaderModuleInfo( pipelineStage, language, source ); + } + else if( pipelineStage == PipelineStage::FRAGMENT ) + { + mFragmentShader = ShaderModuleInfo( pipelineStage, language, source ); + } + return *this; +} + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wframe-larger-than=" +std::unique_ptr ShaderFactory::Create() const +{ + if( !(mVertexShader.source.IsSet() && mFragmentShader.source.IsSet()) ) + { + return nullptr; + } + + auto retval = std::make_unique( mGraphics ); + + // add vertex shader + retval->AddShaderModule( mVertexShader.pipelineStage, mVertexShader.language, mVertexShader.source ); + + // add fragment shader + retval->AddShaderModule( mFragmentShader.pipelineStage, mFragmentShader.language, mFragmentShader.source ); + + return std::move(retval); +} +#pragma GCC diagnostic pop +} // namespace VulkanAPI +} // namespace Graphics +} // namespace Dali diff --git a/dali/graphics/vulkan/api/vulkan-api-shader-factory.h b/dali/graphics/vulkan/api/vulkan-api-shader-factory.h new file mode 100644 index 0000000..fb87fb9 --- /dev/null +++ b/dali/graphics/vulkan/api/vulkan-api-shader-factory.h @@ -0,0 +1,91 @@ +#ifndef DALI_GRAPHICS_VULKAN_API_SHADER_FACTORY_H +#define DALI_GRAPHICS_VULKAN_API_SHADER_FACTORY_H + +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#include +#include +#include + +#include + +namespace Dali +{ +namespace Graphics +{ +namespace Vulkan +{ +class Graphics; +} +namespace VulkanAPI +{ + +class ShaderFactory : public Dali::Graphics::API::ShaderFactory +{ +public: + explicit ShaderFactory( Vulkan::Graphics& graphics ); + + ShaderFactory& SetShaderModule(Graphics::API::ShaderDetails::PipelineStage pipelineStage, + Graphics::API::ShaderDetails::Language language, + const Graphics::API::ShaderDetails::ShaderSource& source) override; + + PointerType Create() const override; + + ~ShaderFactory() override; + +private: + + struct ShaderModuleInfo + { + using PipelineStage = Graphics::API::ShaderDetails::PipelineStage; + using Language = Graphics::API::ShaderDetails::Language; + using ShaderSource = Graphics::API::ShaderDetails::ShaderSource; + + PipelineStage pipelineStage; + Language language; + ShaderSource source; + + ShaderModuleInfo( PipelineStage stage, Language shaderLanguage, const ShaderSource& shaderSource ) + : pipelineStage( stage ), + language( shaderLanguage ), + source( shaderSource ) + { + } + + ShaderModuleInfo() + : pipelineStage( PipelineStage::VERTEX ), + language( Language::SPIRV_1_0 ), + source( ShaderSource(std::vector()) ) + { + } + + ShaderModuleInfo( const ShaderModuleInfo& info ) = default; + + ~ShaderModuleInfo() = default; + }; + + Vulkan::Graphics& mGraphics; + ShaderModuleInfo mVertexShader; + ShaderModuleInfo mFragmentShader; +}; + + +} +} +} + +#endif // DALI_GRAPHICS_VULKAN_API_SHADER_FACTORY_H diff --git a/dali/graphics/vulkan/api/vulkan-api-shader.cpp b/dali/graphics/vulkan/api/vulkan-api-shader.cpp new file mode 100644 index 0000000..160b17e --- /dev/null +++ b/dali/graphics/vulkan/api/vulkan-api-shader.cpp @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include +#include +#include +#include +namespace Dali +{ +namespace Graphics +{ +namespace VulkanAPI +{ +using namespace Dali::Graphics::API; +using namespace Dali::Graphics::Vulkan; + +using ShaderLanguage = Dali::Graphics::API::ShaderDetails::Language; +using ShaderPipelineStage = Dali::Graphics::API::ShaderDetails::PipelineStage; +using ShaderSource = Dali::Graphics::API::ShaderDetails::ShaderSource; + +Shader::Shader( Vulkan::Graphics& graphics ) : +mGraphics( graphics ) +{ + +} + +ShaderRef Shader::GetShader( vk::ShaderStageFlagBits shaderStage ) const +{ + switch( shaderStage ) + { + case vk::ShaderStageFlagBits::eVertex: + { + return mVertexShader; + } + case vk::ShaderStageFlagBits::eFragment: + { + return mFragmentShader; + } + case vk::ShaderStageFlagBits::eTessellationControl: + case vk::ShaderStageFlagBits::eTessellationEvaluation: + case vk::ShaderStageFlagBits::eGeometry: + case vk::ShaderStageFlagBits::eCompute: + case vk::ShaderStageFlagBits::eAllGraphics: + case vk::ShaderStageFlagBits::eAll: + { + } + } + return ShaderRef(); +} + +Shader& Shader::DownCast( Dali::Graphics::API::Shader& shader ) +{ + return *( dynamic_cast( &shader ) ); +} + +Vulkan::ShaderRef Shader::GetShaderRef( vk::ShaderStageFlagBits shaderStage ) const +{ + if(shaderStage == vk::ShaderStageFlagBits::eVertex) + { + return mVertexShader; + } + else if(shaderStage == vk::ShaderStageFlagBits::eFragment) + { + return mFragmentShader; + } + else + { + return Vulkan::ShaderRef( ); + } +} + +bool Shader::AddShaderModule( Dali::Graphics::API::ShaderDetails::PipelineStage pipelineStage, + Dali::Graphics::API::ShaderDetails::Language language, + Dali::Graphics::API::ShaderDetails::ShaderSource shaderSource ) + +{ + // TODO: AB: only supported language is SPIRV for now + if( language != ShaderLanguage::SPIRV_1_0 && language != ShaderLanguage::SPIRV_1_1 ) + { + // unsupported language + return false; + } + + // TODO: AB: only binary shader supported for now + if( shaderSource.type != ShaderDetails::ShaderSourceType::BINARY ) + { + return false; + } + + auto shaderRef = Vulkan::Shader::New( mGraphics, &shaderSource.code[0], shaderSource.code.size() ); + + if(!shaderRef) + { + return false; + } + + if(pipelineStage == ShaderPipelineStage::VERTEX ) + { + mVertexShader = shaderRef; + return true; + } + else if(pipelineStage == ShaderPipelineStage::FRAGMENT ) + { + mFragmentShader = shaderRef; + return true; + } + + // possibly unsupported pipeline stage + return false; +} + + + +} // namespace VulkanAPI +} // namespace Graphics +} // namespace Dali \ No newline at end of file diff --git a/dali/graphics/vulkan/api/vulkan-api-shader.h b/dali/graphics/vulkan/api/vulkan-api-shader.h new file mode 100644 index 0000000..f566228 --- /dev/null +++ b/dali/graphics/vulkan/api/vulkan-api-shader.h @@ -0,0 +1,74 @@ +#ifndef DALI_VULKAN_161117_VULKAN_API_SHADER_H +#define DALI_VULKAN_161117_VULKAN_API_SHADER_H + +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include +#include +#include + +namespace Dali +{ +namespace Graphics +{ +namespace VulkanAPI +{ +/** + * @brief API::Shader represents program conceptually + */ +class Shader : public Dali::Graphics::API::Shader +{ +public: + // not copyable + Shader( const Shader& ) = delete; + Shader& operator=( const Shader& ) = delete; + + ~Shader() override = default; + + explicit Shader( Vulkan::Graphics& graphics ); + + bool AddShaderModule( Graphics::API::ShaderDetails::PipelineStage pipelineStage, + Graphics::API::ShaderDetails::Language language, + Graphics::API::ShaderDetails::ShaderSource shaderSource ); + + Vulkan::ShaderRef GetShader( vk::ShaderStageFlagBits shaderStage ) const ; + + static Shader& DownCast( Dali::Graphics::API::Shader& shader ); + + Vulkan::ShaderRef GetShaderRef( vk::ShaderStageFlagBits shaderStage ) const; + +protected: + // derived types should not be moved direcly to prevent slicing + Shader( Shader&& ) = default; + Shader& operator=( Shader&& ) = default; + + Shader() = default; + +private: + + Vulkan::Graphics& mGraphics; + Vulkan::ShaderRef mVertexShader; + Vulkan::ShaderRef mFragmentShader; + + +}; + +} // namespace Vulkan +} // namespace Graphics +} // namespace Dali +#endif //DALI_VULKAN_161117_VULKAN_API_SHADER_H diff --git a/dali/graphics/vulkan/api/vulkan-api-texture-factory.cpp b/dali/graphics/vulkan/api/vulkan-api-texture-factory.cpp new file mode 100644 index 0000000..fa4fb9e --- /dev/null +++ b/dali/graphics/vulkan/api/vulkan-api-texture-factory.cpp @@ -0,0 +1,150 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include +#include +#include + +namespace Dali +{ +namespace Graphics +{ +namespace VulkanAPI +{ + +struct TextureFactory::Impl +{ + Impl( TextureFactory& api, Vulkan::Graphics& graphics ) + : mApi( api ), mGraphics( graphics ) + { + + } + + ~Impl() = default; + + std::unique_ptr Create() + { + auto retval = std::make_unique( static_cast(mApi) ); + + if(retval->Initialise()) + { + return std::move(retval); + } + + return nullptr; + } + + TextureFactory& mApi; + Vulkan::Graphics& mGraphics; + + API::TextureDetails::Type mType; + API::RectSize mSize; + API::TextureDetails::Format mFormat; + API::TextureDetails::MipMapFlag mMipmapFlags; + void* mData; + uint32_t mDataSizeInBytes; + +}; + +TextureFactory::TextureFactory( Vulkan::Graphics& graphics ) +{ + mImpl = std::make_unique( *this, graphics ); +} + +TextureFactory::~TextureFactory() = default; + +Graphics::API::TextureFactory& TextureFactory::SetType(API::TextureDetails::Type type) +{ + mImpl->mType = type; + return *this; +} + +Graphics::API::TextureFactory& TextureFactory::SetSize(const API::RectSize& size) +{ + mImpl->mSize = size; + return *this; +} + +Graphics::API::TextureFactory& TextureFactory::SetFormat(API::TextureDetails::Format format) +{ + mImpl->mFormat = format; + return *this; +} + +Graphics::API::TextureFactory& TextureFactory::SetMipMapFlag(API::TextureDetails::MipMapFlag mipMSapFlag) +{ + mImpl->mMipmapFlags = mipMSapFlag; + return *this; +} + +Graphics::API::TextureFactory& TextureFactory::SetData( void* pData ) +{ + mImpl->mData = pData; + return *this; +} + +Graphics::API::TextureFactory& TextureFactory::SetDataSize( uint32_t dataSizeInBytes ) +{ + mImpl->mDataSizeInBytes = dataSizeInBytes; + return *this; +} + +std::unique_ptr TextureFactory::Create() const +{ + return mImpl->Create(); +} + +const API::TextureDetails::Type& TextureFactory::GetType() const +{ + return mImpl->mType; +} + +const API::RectSize& TextureFactory::GetSize() const +{ + return mImpl->mSize; +} + +const API::TextureDetails::Format& TextureFactory::GetFormat() const +{ + return mImpl->mFormat; +} + +const API::TextureDetails::MipMapFlag& TextureFactory::GetMipMapFlag() const +{ + return mImpl->mMipmapFlags; +} + +const void* TextureFactory::GetData() const +{ + return mImpl->mData; +} + +uint32_t TextureFactory::GetDataSize() const +{ + return mImpl->mDataSizeInBytes; +} + +Vulkan::Graphics& TextureFactory::GetGraphics() const +{ + return mImpl->mGraphics; +} + + +} +} +} + diff --git a/dali/graphics/vulkan/api/vulkan-api-texture-factory.h b/dali/graphics/vulkan/api/vulkan-api-texture-factory.h new file mode 100644 index 0000000..ca0d926 --- /dev/null +++ b/dali/graphics/vulkan/api/vulkan-api-texture-factory.h @@ -0,0 +1,84 @@ +#ifndef DALI_GRAPHICS_VULKAN_API_TEXTURE_FACTORY_H +#define DALI_GRAPHICS_VULKAN_API_TEXTURE_FACTORY_H + +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include +#include + +namespace Dali +{ +namespace Graphics +{ +namespace Vulkan +{ +class Graphics; +} +namespace VulkanAPI +{ + +class TextureFactory : public Dali::Graphics::API::TextureFactory +{ +public: + + explicit TextureFactory( Vulkan::Graphics& graphics ); + + Graphics::API::TextureFactory& SetType(API::TextureDetails::Type type) override; + Graphics::API::TextureFactory& SetSize(const API::RectSize& size) override; + Graphics::API::TextureFactory& SetFormat(API::TextureDetails::Format format) override; + Graphics::API::TextureFactory& SetMipMapFlag(API::TextureDetails::MipMapFlag mipMSapFlag) override; + Graphics::API::TextureFactory& SetData( void* pData ) override; + Graphics::API::TextureFactory& SetDataSize( uint32_t dataSizeInBytes ) override; + + // not copyable + TextureFactory(const TextureFactory&) = delete; + TextureFactory& operator=(const TextureFactory&) = delete; + + ~TextureFactory() override; + + std::unique_ptr Create() const override; + + /** Internal interface */ + const API::TextureDetails::Type& GetType() const; + const API::RectSize& GetSize() const; + const API::TextureDetails::Format& GetFormat() const; + const API::TextureDetails::MipMapFlag& GetMipMapFlag() const; + const void* GetData() const; + uint32_t GetDataSize() const; + + Vulkan::Graphics& GetGraphics() const; + +protected: + /// @brief default constructor + TextureFactory() = default; + + // derived types should not be moved direcly to prevent slicing + TextureFactory(TextureFactory&&) = default; + TextureFactory& operator=(TextureFactory&&) = default; + +private: + + struct Impl; + std::unique_ptr mImpl; +}; + +} +} +} + +#endif //DALI_GRAPHICS_VULKAN_API_TEXTURE_FACTORY_H diff --git a/dali/graphics/vulkan/api/vulkan-api-texture.cpp b/dali/graphics/vulkan/api/vulkan-api-texture.cpp new file mode 100644 index 0000000..c91b01f --- /dev/null +++ b/dali/graphics/vulkan/api/vulkan-api-texture.cpp @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include + +#include +#include +#include +#include + + +namespace Dali +{ +namespace Graphics +{ +namespace VulkanAPI +{ +using namespace Dali::Graphics::Vulkan; + +struct Texture::Impl +{ + Impl( Texture& api, Dali::Graphics::API::TextureFactory& factory ) + : mTextureFactory( dynamic_cast( factory ) ), + mGraphics( mTextureFactory.GetGraphics() ) + { + } + + ~Impl() = default; + + bool Initialise() + { + //return mImpl->CreateTexture( data, sizeInBytes, width, height ); + // AB: yup, yet another hack + auto size = mTextureFactory.GetSize(); + auto width = size.width; + auto height = size.height; + auto sizeInBytes = mTextureFactory.GetDataSize(); + auto data = mTextureFactory.GetData(); + + auto textureRef = Dali::Graphics::Vulkan::Texture::New( mGraphics, U32(size.width), U32(size.height), vk::Format::eR8G8B8A8Unorm ); + + // check bpp, if 24bpp convert + if( sizeInBytes == width*height*3 ) + { + + auto inData = reinterpret_cast(data); + auto outData = new uint8_t[width*height*4]; + + auto outIdx = 0u; + for( auto i = 0u; i < sizeInBytes; i+= 3 ) + { + outData[outIdx] = inData[i]; + outData[outIdx+1] = inData[i+1]; + outData[outIdx+2] = inData[i+2]; + outData[outIdx+3] = 0xff; + outIdx += 4; + } + + data = outData; + sizeInBytes = U32(width*height*4); + } + + // Upload data immediately. Will stall the queue :( + textureRef->UploadData( data, sizeInBytes, TextureUploadMode::eImmediate ); + + mTexture = textureRef; + return true; + } + + Vulkan::TextureRef mTexture; + VulkanAPI::TextureFactory& mTextureFactory; + Vulkan::Graphics& mGraphics; +}; + +Texture::Texture( Dali::Graphics::API::TextureFactory& factory ) +{ + mImpl = std::make_unique( *this, factory ); +} + +Texture::~Texture() = default; + +Vulkan::TextureRef Texture::GetTextureRef() const +{ + return mImpl->mTexture; +} + +bool Texture::Initialise() +{ + return mImpl->Initialise(); +} + +} // namespace VulkanAPI +} // namespace Graphics +} // namespace Dali \ No newline at end of file diff --git a/dali/graphics/vulkan/api/vulkan-api-texture.h b/dali/graphics/vulkan/api/vulkan-api-texture.h new file mode 100644 index 0000000..a72e721 --- /dev/null +++ b/dali/graphics/vulkan/api/vulkan-api-texture.h @@ -0,0 +1,57 @@ +#ifndef DALI_GRAPHICS_VULKAN_API_TEXTURE_H +#define DALI_GRAPHICS_VULKAN_API_TEXTURE_H + +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +// INTERNAL INCLUDES +#include +#include +#include +#include +#include + +namespace Dali +{ +namespace Graphics +{ +namespace VulkanAPI +{ +/** + * This is temporary implementation. It should be using graphics-texture as base + * interface. + */ +class Texture : public Dali::Graphics::API::Texture +{ +public: + + explicit Texture( Dali::Graphics::API::TextureFactory& factory ); + ~Texture() override; + + bool Initialise(); + + Vulkan::TextureRef GetTextureRef() const; + +private: + struct Impl; + std::unique_ptr mImpl; +}; + +} // namespace VulkanAPI +} // namespace Graphics +} // namespace Dali +#endif // DALI_GRAPHICS_VULKAN_API_TEXTURE_H diff --git a/dali/graphics/vulkan/api/vulkan-texture-factory.cpp b/dali/graphics/vulkan/api/vulkan-texture-factory.cpp deleted file mode 100644 index 726e481..0000000 --- a/dali/graphics/vulkan/api/vulkan-texture-factory.cpp +++ /dev/null @@ -1,40 +0,0 @@ -#include -#include -#include - -namespace Dali -{ -namespace Graphics -{ -namespace API -{ - -std::unique_ptr TextureFactory::Create() const -{ - -} - -void TextureFactory::SetType(TextureDetails::Type type) -{ - -} - -void TextureFactory::SetSize(const RectSize& size) -{ - -} -void TextureFactory::SetFormat(TextureDetails::Format format) -{ - -} - -void TextureFactory::SetMipMapFlag(TextureDetails::MipMapFlag mipMSapFlag) -{ - -} - -} - -} - -} \ No newline at end of file diff --git a/dali/graphics/vulkan/vulkan-graphics-controller.cpp b/dali/graphics/vulkan/vulkan-graphics-controller.cpp index f0a3ca7..78fa886 100644 --- a/dali/graphics/vulkan/vulkan-graphics-controller.cpp +++ b/dali/graphics/vulkan/vulkan-graphics-controller.cpp @@ -21,6 +21,14 @@ #include #include #include +#include +#include + +// API +#include +#include +#include +#include using namespace glm; @@ -33,8 +41,103 @@ namespace Vulkan static const mat4 CLIP_MATRIX( 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f, 0.0f, 0.0f, 0.0f, 0.5f, 1.0f ); +/** + * Graphics pipeline state describes single batch-draw call state + */ +struct GraphicsPipelineState +{ + /** + * Internal Data structure collects only POD state + * details that are relevant to us + */ + struct Info + { + // blending + vk::Bool32 blendEnabled; + vk::BlendFactor srcColor, srcAlpha; + vk::BlendFactor dstColor, dstAlpha; + + // vertex input data + std::vector vertexAttributeDescription; + std::vector vertexInputBindingDescripton; + + // viewport size + vk::Rect2D viewport; + + // topology + vk::PrimitiveTopology topology; + + // depth/stencil + vk::Bool32 depthTestEnabled; + vk::Bool32 stencilTestEnabled; + + // shaders + ShaderRef vertexShader; + ShaderRef fragmentShader; + + bool operator==( const Info& src ) const + { + return false; // TODO + } + + } info; + + GraphicsPipelineState( GraphicsPipelineState& src ) + { + info = src.info; + } + + bool operator==( const GraphicsPipelineState::Info& _info ) + { + return (info == _info); + } + + // Resets state + void Reset() + { + pipeline.Reset(); + } + + void Initialise() + { + + } + + // Compiles state + static std::unique_ptr Compile(const GraphicsPipelineState::Info& info) + { + return nullptr; + } + + // state, created when compiled, immutable + // renders particular set of objects + PipelineRef pipeline; +}; + +struct GraphicsDrawCommand +{ + GraphicsPipelineState& pipelineState; + + // command buffer/pool + CommandPoolRef commandPool; + CommandBufferRef commandBuffer; + FenceRef fence; + + // resources + std::vector buffers; + std::vector images; + std::vector samplers; + std::vector imageViews; + + // descriptor sets and pool + std::vector descriptorSets; + DescriptorPoolRef descriptorPool; +}; + struct Controller::Impl { + + struct State { ShaderRef vertexShader; @@ -69,6 +172,10 @@ struct Controller::Impl #pragma GCC diagnostic ignored "-Wframe-larger-than=" bool Initialise() { + // Create factories + mShaderFactory = std::make_unique( mGraphics ); + mTextureFactory = std::make_unique( mGraphics ); + mDebugPipelineState.vertexShader = Shader::New( mGraphics, VSH_CODE.data(), VSH_CODE.size() ); mDebugPipelineState.fragmentShader = Shader::New( mGraphics, FSH_CODE.data(), FSH_CODE.size() ); @@ -84,15 +191,7 @@ struct Controller::Impl {-halfWidth, halfHeight, 0.0f}, {-halfWidth, -halfHeight, 0.0f}, }; -//#endif -#if 0 - const vec3 VERTICES[4] = { - {-halfWidth, -halfHeight, 0.0f}, - {halfWidth, -halfHeight, 0.0f}, - {halfWidth, halfHeight, 0.0f}, - {-halfWidth, halfHeight, 0.0f} - }; -#endif + mDebugPipelineState.vertexBuffer = Buffer::New( mGraphics, sizeof( VERTICES[0] ) * 4, Buffer::Type::VERTEX ); auto& defaultAllocator = mGraphics.GetDeviceMemoryManager().GetDefaultAllocator(); mDebugPipelineState.vertexBuffer->BindMemory( @@ -154,7 +253,7 @@ struct Controller::Impl return pipeline; } - void SubmitCommand( API::RenderCommand&& command ) + void SubmitCommand( Dali::Graphics::API::RenderCommand&& command ) { auto& state = mDebugPipelineState; @@ -216,10 +315,10 @@ struct Controller::Impl descriptorSets[0]->WriteUniformBuffer( 0, state.uniformBuffer0, i * uniformBlockOffsetStride, stride ); descriptorSets[0]->WriteUniformBuffer( 1, state.uniformBuffer1, 0, state.uniformBuffer1->GetSize() ); - if(inputData->samplerId > 0) + //if(inputData->samplerId >= 0) { - descriptorSets[0]->WriteCombinedImageSampler(2, mTextures[inputData->samplerId - 1]->GetSampler(), - mTextures[inputData->samplerId - 1]->GetImageView()); + descriptorSets[0]->WriteCombinedImageSampler(2, mTextures[inputData->samplerId]->GetSampler(), + mTextures[inputData->samplerId]->GetImageView()); } // record draw call @@ -274,50 +373,86 @@ struct Controller::Impl return pool; } - void* CreateTexture( void* data, size_t sizeInBytes, uint32_t width, uint32_t height ) + API::TextureFactory& GetTextureFactory() const { - // AB: yup, yet another hack - auto texture = Dali::Graphics::Vulkan::Texture::New( mGraphics, width, height, vk::Format::eR8G8B8A8Unorm ); - - // check bpp, if 24bpp convert - if( sizeInBytes == width*height*3 ) - { - uint8_t* inData = reinterpret_cast(data); - uint8_t* outData = new uint8_t[width*height*4]; - - auto outIdx = 0u; - for( auto i = 0u; i < sizeInBytes; i+= 3 ) - { - outData[outIdx] = inData[i]; - outData[outIdx+1] = inData[i+1]; - outData[outIdx+2] = inData[i+2]; - outData[outIdx+3] = 0xff; - outIdx += 4; - } - - data = outData; - sizeInBytes = width*height*4; - } - - // Upload data immediately. Will stall the queue :( - texture->UploadData( data, sizeInBytes, TextureUploadMode::eImmediate ); - - // push texture to the stack, return the buffer - mTextures.push_back( texture ); + return *(mTextureFactory.get()); + } - // return index for quick lookup - auto index = mTextures.size(); - return reinterpret_cast(index); + API::ShaderFactory& GetShaderFactory() const + { + return *(mShaderFactory.get()); } // resources std::vector mTextures; + std::vector mShaders; + + // owner objects + ObjectOwner mTexturesOwner; + ObjectOwner mShadersOwner; + Graphics& mGraphics; Controller& mOwner; GpuMemoryAllocator& mDefaultAllocator; State mDebugPipelineState; + + std::unique_ptr mTextureFactory; + std::unique_ptr mShaderFactory; + + /** + * NEW IMPLEMENTACIONE + */ + + void SubmitDraw( const Dali::Graphics::API::BufferInfo& buffer ) + { + // find pipeline state for this batch + auto info = GraphicsPipelineState::Info{}; + + //info.vertexShader = + } + + void SubmitCommandV2( Dali::Graphics::API::RenderCommand&& command ) + { + + auto vertexShader = command.GetShader( Dali::Graphics::API::ShaderDetails::PipelineStage::VERTEX ); + auto fragmentShader = command.GetShader( Dali::Graphics::API::ShaderDetails::PipelineStage::FRAGMENT ); + + // get shaders from backend + ShaderRef vsh, fsh; + if(vertexShader) + { + vsh = VulkanAPI::Shader::DownCast( vertexShader.Get() ).GetShader( vk::ShaderStageFlagBits::eVertex ); + } + + if(fragmentShader) + { + fsh = VulkanAPI::Shader::DownCast( vertexShader.Get() ).GetShader( vk::ShaderStageFlagBits::eFragment ); + } + +#if 0 + const auto& bufferList = command.GetBufferList(); + const auto& bufferVector = bufferList.Get(); + + for(const auto& bufferInfo : bufferVector ) + { + /* + const auto ptr = bufferInfo->GetDataBase(); + const auto size = bufferInfo->GetSize(); + + SubmitDraw( bufferInfo ); + */ + // new render state + + } +#endif + } + + + + std::vector mStatePerBatchCache; + }; // TODO: @todo temporarily ignore missing return type, will be fixed later @@ -325,10 +460,21 @@ struct Controller::Impl #pragma GCC diagnostic ignored "-Wreturn-type" API::Accessor Controller::CreateShader( const API::BaseFactory& factory ) { + auto handle = mImpl->mShadersOwner.CreateObject( factory ); + auto& apiShader = static_cast(mImpl->mShadersOwner[handle]); + auto vertexShaderRef = apiShader.GetShaderRef( vk::ShaderStageFlagBits::eVertex ); + auto fragmentShaderRef = apiShader.GetShaderRef( vk::ShaderStageFlagBits::eFragment ); + mImpl->mShaders.push_back( vertexShaderRef ); + mImpl->mShaders.push_back( fragmentShaderRef ); + return API::Accessor( mImpl->mShadersOwner, handle); } API::Accessor Controller::CreateTexture( const API::BaseFactory& factory ) { + auto handle = mImpl->mTexturesOwner.CreateObject( factory ); + auto textureRef = static_cast(mImpl->mTexturesOwner[handle]).GetTextureRef(); + mImpl->mTextures.push_back( textureRef ); + return API::Accessor( mImpl->mTexturesOwner, handle); } API::Accessor Controller::CreateTextureSet( const API::BaseFactory& factory ) @@ -351,11 +497,6 @@ API::Accessor Controller::CreateFramebuffer( const API::BaseFa { } -void* Controller::CreateTextureRGBA32( void* data, size_t sizeInBytes, uint32_t width, uint32_t height ) -{ - return mImpl->CreateTexture( data, sizeInBytes, width, height ); -} - std::unique_ptr Controller::CreateBuffer( size_t numberOfElements, size_t elementSize ) { return std::unique_ptr( new char[numberOfElements * elementSize] ); @@ -381,9 +522,10 @@ void Controller::GetRenderItemList() { } -void Controller::SubmitCommand( API::RenderCommand&& command ) +void Controller::SubmitCommand( Dali::Graphics::API::RenderCommand&& command ) { mImpl->SubmitCommand( std::move( command ) ); + //SubmitCommandTest( std::move( command ) ); } void Controller::BeginFrame() @@ -396,6 +538,16 @@ void Controller::EndFrame() mImpl->EndFrame(); } +API::TextureFactory& Controller::GetTextureFactory() const +{ + return mImpl->GetTextureFactory(); +} + +API::ShaderFactory& Controller::GetShaderFactory() const +{ + return mImpl->GetShaderFactory(); +} + } // namespace Vulkan } // namespace Graphics } // namespace Dali diff --git a/dali/graphics/vulkan/vulkan-graphics-controller.h b/dali/graphics/vulkan/vulkan-graphics-controller.h index de59270..7b8d4e4 100644 --- a/dali/graphics/vulkan/vulkan-graphics-controller.h +++ b/dali/graphics/vulkan/vulkan-graphics-controller.h @@ -82,8 +82,6 @@ public: std::unique_ptr CreateBuffer( size_t numberOfElements, size_t elementSize ) override; - void* CreateTextureRGBA32( void* data, size_t sizeInBytes, uint32_t width, uint32_t height ) override; - /** * @brief Get a render list */ @@ -96,6 +94,12 @@ public: void EndFrame() override; public: + + API::TextureFactory& GetTextureFactory() const override; + + API::ShaderFactory& GetShaderFactory() const override; + +public: // not copyable Controller( const Controller& ) = delete; Controller& operator=( const Controller& ) = delete; diff --git a/dali/graphics/vulkan/vulkan-graphics-texture.cpp b/dali/graphics/vulkan/vulkan-graphics-texture.cpp index f024901..59d1aa8 100644 --- a/dali/graphics/vulkan/vulkan-graphics-texture.cpp +++ b/dali/graphics/vulkan/vulkan-graphics-texture.cpp @@ -103,7 +103,7 @@ struct Texture::Impl } #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wframe-larger-than=" - bool UploadData( void* data, uint32_t offsetInBytes, uint32_t sizeInBytes ) + bool UploadData( const void* data, uint32_t offsetInBytes, uint32_t sizeInBytes ) { // create buffer auto& allocator = mGraphics.GetDeviceMemoryManager().GetDefaultAllocator(); @@ -118,8 +118,8 @@ struct Texture::Impl // copy pixels to the buffer auto ptr = buffer->GetMemoryHandle()->MapTyped(); - std::copy( reinterpret_cast(data), - reinterpret_cast(data) + sizeInBytes, + std::copy( reinterpret_cast(data), + reinterpret_cast(data) + sizeInBytes, ptr ); buffer->GetMemoryHandle()->Unmap(); @@ -274,7 +274,7 @@ Texture::Texture( Graphics& graphics, uint32_t width, uint32_t height, vk::Forma * @param size * @param mode */ -void Texture::UploadData( void* data, size_t size, TextureUploadMode mode ) +void Texture::UploadData( const void* data, size_t size, TextureUploadMode mode ) { mImpl->UploadData( data, 0, U32(size) ); } diff --git a/dali/graphics/vulkan/vulkan-graphics-texture.h b/dali/graphics/vulkan/vulkan-graphics-texture.h index 6962aa9..b9d4668 100644 --- a/dali/graphics/vulkan/vulkan-graphics-texture.h +++ b/dali/graphics/vulkan/vulkan-graphics-texture.h @@ -61,7 +61,7 @@ public: * @param size * @param mode */ - void UploadData( void* data, size_t size, TextureUploadMode mode ); + void UploadData( const void* data, size_t size, TextureUploadMode mode ); /** * diff --git a/dali/graphics/vulkan/vulkan-pipeline.cpp b/dali/graphics/vulkan/vulkan-pipeline.cpp index 48c98fb..5a6b574 100644 --- a/dali/graphics/vulkan/vulkan-pipeline.cpp +++ b/dali/graphics/vulkan/vulkan-pipeline.cpp @@ -70,6 +70,8 @@ struct Pipeline::Impl return mPipeline; } +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wframe-larger-than=" vk::Result Initialise() { if( !ValidateShaderModules() ) @@ -217,6 +219,7 @@ struct Pipeline::Impl mColorBlendState.setPAttachments( &mAttachementNoBlendState ); mInfo.setPColorBlendState(&mColorBlendState); } +#pragma GCC diagnostic pop /** * Sets the shader. Must be set before compiling the pipeline, compiled pipeline @@ -472,6 +475,41 @@ const std::vector& Pipeline::GetVkDescriptorSetLayouts( return mImpl->mDSLayoutArray; } +const vk::PipelineInputAssemblyStateCreateInfo& Pipeline::GetInputAssemblyState() const +{ + return mImpl->mInputAssemblyState; +} + +const vk::PipelineVertexInputStateCreateInfo& Pipeline::GetVertexInputState() const +{ + return mImpl->mVertexInputState; +} + +const vk::PipelineViewportStateCreateInfo& Pipeline::GetViewportState() const +{ + return mImpl->mViewportState; +} + +const vk::PipelineRasterizationStateCreateInfo& Pipeline::GetRasterizationState() const +{ + return mImpl->mRasterizationState; +} + +const vk::PipelineMultisampleStateCreateInfo& Pipeline::GetMultisamplingState() const +{ + return mImpl->mMultisampleState; +} + +const vk::PipelineDepthStencilStateCreateInfo& Pipeline::GetDepthStencilState() const +{ + return mImpl->mDepthStencilState; +} + +const vk::PipelineColorBlendStateCreateInfo& Pipeline::GetColorBlendState() const +{ + return mImpl->mColorBlendState; +} + } // namespace Vulkan } // namespace Graphics diff --git a/dali/graphics/vulkan/vulkan-pipeline.h b/dali/graphics/vulkan/vulkan-pipeline.h index a444af3..4494ca2 100644 --- a/dali/graphics/vulkan/vulkan-pipeline.h +++ b/dali/graphics/vulkan/vulkan-pipeline.h @@ -39,7 +39,7 @@ public: * @param info * @return */ - static Handle New( Graphics& graphics, const vk::GraphicsPipelineCreateInfo& info = vk::GraphicsPipelineCreateInfo{} ); + static PipelineRef New( Graphics& graphics, const vk::GraphicsPipelineCreateInfo& info = vk::GraphicsPipelineCreateInfo{} ); /** * Destructor @@ -96,6 +96,23 @@ public: */ const std::vector& GetVkDescriptorSetLayouts() const; + /** + * State getters from the pipeline + */ + + const vk::PipelineInputAssemblyStateCreateInfo& GetInputAssemblyState() const; + + const vk::PipelineVertexInputStateCreateInfo& GetVertexInputState() const; + + const vk::PipelineViewportStateCreateInfo& GetViewportState() const; + + const vk::PipelineRasterizationStateCreateInfo& GetRasterizationState() const; + + const vk::PipelineMultisampleStateCreateInfo& GetMultisamplingState() const; + + const vk::PipelineDepthStencilStateCreateInfo& GetDepthStencilState() const; + + const vk::PipelineColorBlendStateCreateInfo& GetColorBlendState() const; private: diff --git a/dali/internal/render/renderers/render-renderer.cpp b/dali/internal/render/renderers/render-renderer.cpp index 690ae55..a0a4f0f 100644 --- a/dali/internal/render/renderers/render-renderer.cpp +++ b/dali/internal/render/renderers/render-renderer.cpp @@ -531,11 +531,13 @@ void Renderer::Render( Context& context, const Vector3& size, bool blend ) { + // TODO: AB: no callig any GL now, to avoid asserts whole function commented out + return; + // Get the program to use: Program* program = mRenderDataProvider->GetShader().GetProgram(); if( !program ) { - DALI_LOG_ERROR( "Failed to get program for shader at address %p.\n", reinterpret_cast< void* >( &mRenderDataProvider->GetShader() ) ); return; } diff --git a/dali/internal/render/renderers/render-texture.cpp b/dali/internal/render/renderers/render-texture.cpp index 7cb2f8e..21bcbe9 100644 --- a/dali/internal/render/renderers/render-texture.cpp +++ b/dali/internal/render/renderers/render-texture.cpp @@ -637,7 +637,8 @@ Texture::Texture( Type type, Pixel::Format format, ImageDimensions size ) mMaxMipMapLevel( 0 ), mType( type ), mHasAlpha( HasAlpha( format ) ), - mIsCompressed( IsCompressedFormat( format ) ) + mIsCompressed( IsCompressedFormat( format ) ), + mGfxTexture( nullptr ) { PixelFormatToGl( format, mGlFormat, @@ -658,7 +659,8 @@ Texture::Texture( NativeImageInterfacePtr nativeImageInterface ) mMaxMipMapLevel( 0 ), mType( TextureType::TEXTURE_2D ), mHasAlpha( nativeImageInterface->RequiresBlending() ), - mIsCompressed( false ) + mIsCompressed( false ), + mGfxTexture( nullptr ) { } diff --git a/dali/internal/render/renderers/render-texture.h b/dali/internal/render/renderers/render-texture.h index 8b1fbaa..d0e2253 100644 --- a/dali/internal/render/renderers/render-texture.h +++ b/dali/internal/render/renderers/render-texture.h @@ -28,6 +28,8 @@ #include #include #include +#include +#include namespace Dali { @@ -136,9 +138,19 @@ public: return mNativeImage; } - void SetId( void* textureId ) + void SetId( uint32_t textureId ) { - mId = GLuint(size_t(textureId)); + mId = textureId; + } + + void SetGfxObject( Graphics::API::Accessor texture ) + { + mGfxTexture = texture; + } + + const Graphics::API::Accessor& GetGfxObject() const + { + return mGfxTexture; } private: @@ -164,6 +176,7 @@ private: bool mHasAlpha : 1; ///< Whether the format has an alpha channel bool mIsCompressed : 1; ///< Whether the format is compressed + Graphics::API::Accessor mGfxTexture; ///< TODO: find right place to store texture }; diff --git a/dali/internal/render/shaders/scene-graph-shader.cpp b/dali/internal/render/shaders/scene-graph-shader.cpp index dc78aed..9e0d795 100644 --- a/dali/internal/render/shaders/scene-graph-shader.cpp +++ b/dali/internal/render/shaders/scene-graph-shader.cpp @@ -38,7 +38,8 @@ namespace SceneGraph Shader::Shader( Dali::Shader::Hint::Value& hints ) : mHints( hints ), mProgram( NULL ), - mConnectionObservers() + mConnectionObservers(), + mGfxShader( nullptr ) { AddUniformMapObserver( *this ); } @@ -63,6 +64,16 @@ void Shader::SetProgram( Internal::ShaderDataPtr shaderData, mConnectionObservers.ConnectionsChanged(*this); } +void Shader::SetGfxObject( const Graphics::API::Accessor& shader ) +{ + mGfxShader = shader; +} + +const Graphics::API::Accessor& Shader::GetGfxObject() const +{ + return mGfxShader; +} + Program* Shader::GetProgram() { return mProgram; diff --git a/dali/internal/render/shaders/scene-graph-shader.h b/dali/internal/render/shaders/scene-graph-shader.h index 5caeda6..6176506 100644 --- a/dali/internal/render/shaders/scene-graph-shader.h +++ b/dali/internal/render/shaders/scene-graph-shader.h @@ -22,7 +22,8 @@ #include #include #include - +#include +#include namespace Dali { @@ -109,6 +110,10 @@ public: ProgramCache* programCache, bool modifiesGeometry ); + void SetGfxObject( const Graphics::API::Accessor& shader ); + + const Graphics::API::Accessor& GetGfxObject() const; + /** * Get the program built for this shader * @return The program built from the shader sources. @@ -140,6 +145,8 @@ private: // Data Program* mProgram; ConnectionChangePropagator mConnectionObservers; + + Graphics::API::Accessor mGfxShader; }; } // namespace SceneGraph diff --git a/dali/internal/update/graphics/graphics-algorithms.cpp b/dali/internal/update/graphics/graphics-algorithms.cpp index a6a7dd8..f365ff3 100644 --- a/dali/internal/update/graphics/graphics-algorithms.cpp +++ b/dali/internal/update/graphics/graphics-algorithms.cpp @@ -74,18 +74,12 @@ void SubmitRenderItemList( Graphics::API::Controller& graphics, if(item.mTextureSet) { - InternalTextureSet* textureSet = const_cast(reinterpret_cast(item.mTextureSet)); + auto textureSet = const_cast(reinterpret_cast(item.mTextureSet)); - auto textureId = textureSet->GetTexture(0)->GetId(); + auto& texture = textureSet->GetTexture(0)->GetGfxObject(); + auto textureId = texture.GetHandle(); - std::cout << "TextureCount: " << textureSet->GetTextureCount() << - ", texture id: " << textureId << - std::endl; - opaqueTextureId = textureId; - } - else - { - std::cout << "TextureCount: 0"; + opaqueTextureId = uint32_t(textureId); // TODO: AB: hack!!! } Matrix::Multiply( data[i].world, item.mModelMatrix, viewProjection ); data[i].color = item.mNode->GetWorldColor( bufferIndex ); diff --git a/dali/internal/update/manager/update-manager.cpp b/dali/internal/update/manager/update-manager.cpp index c55f1fd..fe0f3a3 100644 --- a/dali/internal/update/manager/update-manager.cpp +++ b/dali/internal/update/manager/update-manager.cpp @@ -15,6 +15,11 @@ * */ +#define DEBUG_OVERRIDE_VULKAN_SHADER +#ifdef DEBUG_OVERRIDE_VULKAN_SHADER +#include +#endif + // CLASS HEADER #include @@ -518,7 +523,35 @@ void UpdateManager::RemoveShader( Shader* shader ) void UpdateManager::SetShaderProgram( Shader* shader, Internal::ShaderDataPtr shaderData, bool modifiesGeometry ) { - return; + auto& controller = mImpl->graphics.GetController(); + + // TODO: for now we will use hardcoded binary SPIRV shaders which will replace anything + // that is passed by the caller +#ifdef DEBUG_OVERRIDE_VULKAN_SHADER + auto shaderRef = + controller.CreateShader( controller.GetShaderFactory() + .SetShaderModule( Graphics::API::ShaderDetails::PipelineStage::VERTEX, + Graphics::API::ShaderDetails::Language::SPIRV_1_0, + Graphics::API::ShaderDetails::ShaderSource( VSH_CODE )) + .SetShaderModule( Graphics::API::ShaderDetails::PipelineStage::FRAGMENT, + Graphics::API::ShaderDetails::Language::SPIRV_1_0, + Graphics::API::ShaderDetails::ShaderSource( FSH_CODE )) + ); + +#else + auto shaderRef = + controller.CreateShader( controller.GetShaderFactory() + .SetShaderModule( Graphics::API::ShaderDetails::PipelineStage::VERTEX, + Graphics::API::ShaderDetails::Language::SPIRV_1_0, + Graphics::API::ShaderDetails::ShaderSource( shaderData->GetVertexShader() )) + .SetShaderModule( Graphics::API::ShaderDetails::PipelineStage::FRAGMENT, + Graphics::API::ShaderDetails::Language::SPIRV_1_0, + Graphics::API::ShaderDetails::ShaderSource( shaderData->GetFragmentShader() )) + ); +#endif + shader->SetGfxObject( shaderRef ); + +#if 0 if( shaderData ) { @@ -530,6 +563,7 @@ void UpdateManager::SetShaderProgram( Shader* shader, // Construct message in the render queue memory; note that delete should not be called on the return value new (slot) DerivedType( shader, &Shader::SetProgram, shaderData, mImpl->renderManager.GetProgramCache(), modifiesGeometry ); } +#endif } void UpdateManager::SaveBinary( Internal::ShaderDataPtr shaderData ) @@ -1261,14 +1295,20 @@ void UpdateManager::UploadTextureV2( Render::Texture* texture, PixelDataPtr pixe //fixme: using controller directly in the update thread auto& controller = mImpl->graphics.GetController(); - // function returns an opaque object which has to be stored in the texture implementation - auto textureId = controller.CreateTextureRGBA32( pixelData->GetBuffer(), pixelData->GetBufferSize(), - pixelData->GetWidth(), pixelData->GetHeight()); + auto tex = controller.CreateTexture( controller.GetTextureFactory() + .SetFormat( Graphics::API::TextureDetails::Format::RGBA8 ) + .SetSize( { pixelData->GetWidth(), pixelData->GetHeight() } ) + .SetType( Graphics::API::TextureDetails::Type::TEXTURE_2D ) + .SetMipMapFlag( Graphics::API::TextureDetails::MipMapFlag::DISABLED ) + .SetData( pixelData->GetBuffer() ) + .SetDataSize( pixelData->GetBufferSize() ) + ); - // AB: workaround, assigning instantly texture Id to the render object - texture->SetId( textureId ); + // TODO: Render::Texture will be gone, however currently it's still in use + // so it carries the accessor to the texture object + texture->SetGfxObject( tex ); - std::cout << textureId << std::endl; + texture->SetId( static_cast(tex.GetHandle()) ); } void UpdateManager::GenerateMipmaps( Render::Texture* texture ) -- 2.7.4