diff --git a/.travis.yml b/.travis.yml index 652a864..5309da7 100755 --- a/.travis.yml +++ b/.travis.yml @@ -4,7 +4,6 @@ osx_image: xcode8.1 install: - brew install cmake - - git clone https://github.com/Tomicyo/kaleido3d_dep_prebuilt.git -b macos_debug Source/ThirdParty_Prebuilt/MacOS_Debug script: - - chmod 777 make_macos.sh && ./make_macos.sh \ No newline at end of file + - chmod 777 make_macos.sh && ./make_macos.sh diff --git a/Data/Test/TextRender.frag b/Data/Test/TextRender.frag new file mode 100644 index 0000000..c462a5f --- /dev/null +++ b/Data/Test/TextRender.frag @@ -0,0 +1,8 @@ +#version 430 +layout (location = 0) in vec2 inCoord; +layout (location = 0) out vec4 outFragColor; +uniform sampler2D fontTex; +void main() +{ + outFragColor = texture(fontTex, inCoord); +} diff --git a/Data/Test/TextRender.vert b/Data/Test/TextRender.vert new file mode 100644 index 0000000..e87620f --- /dev/null +++ b/Data/Test/TextRender.vert @@ -0,0 +1,13 @@ +#version 430 +layout (location = 0) in vec3 inPos; +layout (location = 1) in vec2 inCoord; +layout (location = 0) out vec2 outCoord; +out gl_PerVertex +{ + vec4 gl_Position; +}; +void main() +{ + outCoord = inCoord; + gl_Position = vec4(inPos, 1.0); +} \ No newline at end of file diff --git a/Data/Test/calibri.ttf b/Data/Test/calibri.ttf new file mode 100644 index 0000000..2cb5515 Binary files /dev/null and b/Data/Test/calibri.ttf differ diff --git a/Data/Test/cube.frag b/Data/Test/cube.frag index 7d63c45..ae85dee 100755 --- a/Data/Test/cube.frag +++ b/Data/Test/cube.frag @@ -1,3 +1,5 @@ +#define USE_GLSL 0 +#if USE_GLSL #version 400 #extension GL_ARB_separate_shader_objects : enable #extension GL_ARB_shading_language_420pack : enable @@ -10,4 +12,22 @@ layout (location = 1) in vec2 uv; layout (location = 0) out vec4 uFragColor; void main() { uFragColor = texture(tex, uv) * color; -} \ No newline at end of file +} +#else + +SamplerState samp : register(s1); +Texture2D tex : register(t1); + +struct PS_IN +{ +// float4 outPos: SV_POSITION; + float4 outColor: COLOR; + float2 outCoord: TEXCOORD0; +}; + +float4 main(PS_IN ps_in) : SV_TARGET +{ + return tex.Sample(samp, ps_in.outCoord); +} + +#endif \ No newline at end of file diff --git a/Data/Test/cube.vert b/Data/Test/cube.vert index 3aeb566..5ba68e5 100755 --- a/Data/Test/cube.vert +++ b/Data/Test/cube.vert @@ -1,3 +1,7 @@ +#define USE_GLSL 0 + +#if USE_GLSL + #version 400 #extension GL_ARB_separate_shader_objects : enable #extension GL_ARB_shading_language_420pack : enable @@ -20,4 +24,39 @@ void main() { color = vertColor; uv = vertUV; gl_Position = ubo.projectionMatrix * ubo.viewMatrix * ubo.modelMatrix * vec4(pos, 1.0f); -} \ No newline at end of file +} + +#else + +cbuffer UBO : register(b0) +{ + row_major matrix projectMatrix; + row_major matrix modelMatrix; + row_major matrix viewMatrix; +}; + +struct VS_IN +{ + float3 pos : POSITION; + float4 vertColor: COLOR; + float2 vertUV: TEXCOORD0; +}; + +struct VS_OUT +{ + float4 outPos: SV_POSITION; + float4 outColor: COLOR; + float2 outCoord: TEXCOORD0; +}; + +VS_OUT main(VS_IN vs_in) +{ + VS_OUT vs_out; + vs_out.outPos = projectMatrix * viewMatrix * modelMatrix * float4(vs_in.pos, 1.0); + vs_out.outColor = vs_in.vertColor; + vs_out.outCoord = vs_in.vertUV; + return vs_out; +} + + +#endif \ No newline at end of file diff --git a/Data/Test/particles.comp b/Data/Test/particles.comp new file mode 100644 index 0000000..4fe2c68 --- /dev/null +++ b/Data/Test/particles.comp @@ -0,0 +1,95 @@ +#define USE_GLSL 0 + +#if USE_GLSL + +#version 430 + +layout (std140, binding = 0) uniform attractor_block +{ + vec4 attractor[64]; // xyz = position, w = mass +}; + +layout (local_size_x = 1024) in; + +layout (rgba32f, binding = 0) uniform imageBuffer velocity_buffer; +layout (rgba32f, binding = 1) uniform imageBuffer position_buffer; + +uniform float dt = 1.0; + +void main(void) +{ + vec4 vel = imageLoad(velocity_buffer, int(gl_GlobalInvocationID.x)); + vec4 pos = imageLoad(position_buffer, int(gl_GlobalInvocationID.x)); + + int i; + + pos.xyz += vel.xyz * dt; + pos.w -= 0.0001 * dt; + + for (i = 0; i < 4; i++) + { + vec3 dist = (attractor[i].xyz - pos.xyz); + vel.xyz += dt * dt * attractor[i].w * normalize(dist) / (dot(dist, dist) + 10.0); + } + + if (pos.w <= 0.0) + { + pos.xyz = -pos.xyz * 0.01; + vel.xyz *= 0.01; + pos.w += 1.0f; + } + + imageStore(position_buffer, int(gl_GlobalInvocationID.x), pos); + imageStore(velocity_buffer, int(gl_GlobalInvocationID.x), vel); +} + +#else + +#define blocksize 64 + +groupshared float4 attractor[blocksize]; + +cbuffer cbCS : register(b0) +{ + float dt; +}; + +//RWStructuredBuffer velocity_buffer : register(u0); // UAV +//RWStructuredBuffer position_buffer : register(u1); // UAV + +RWTexture1D velocity_buffer : register(t0); +RWTexture1D position_buffer : register(t1); + +[numthreads(1024, 1, 1)] +void main( + uint3 Gid : SV_GroupID, + uint3 DTid : SV_DispatchThreadID, + uint3 GTid : SV_GroupThreadID, + uint GI : SV_GroupIndex) +{ + float4 vel = velocity_buffer.Load(DTid.x); + float4 pos = position_buffer.Load(DTid.x); + + int i; + + pos.xyz += vel.xyz * dt; + pos.w -= 0.0001 * dt; + + for (i = 0; i < 4; i++) + { + float3 dist = (attractor[i].xyz - pos.xyz); + vel.xyz += dt * dt * attractor[i].w * normalize(dist) / (dot(dist, dist) + 10.0); + } + + if (pos.w <= 0.0) + { + pos.xyz = -pos.xyz * 0.01; + vel.xyz *= 0.01; + pos.w += 1.0f; + } + + position_buffer[DTid.x] = pos; + velocity_buffer[DTid.x] = vel; +} + +#endif \ No newline at end of file diff --git a/Data/Test/particles.frag b/Data/Test/particles.frag new file mode 100644 index 0000000..6c0018e --- /dev/null +++ b/Data/Test/particles.frag @@ -0,0 +1,25 @@ +#define USE_GLSL 0 + +#if USE_GLSL + +#version 430 +layout (location = 0) out vec4 color; +in float intensity; +void main(void) +{ + color = mix(vec4(0.0f, 0.2f, 1.0f, 1.0f), vec4(0.2f, 0.05f, 0.0f, 1.0f), intensity); +} + +#else + +struct PS_IN +{ + float intensity : INTENSITY; +}; + +float4 main(PS_IN ps_in) : SV_Target +{ + return lerp(float4(0.0f, 0.2f, 1.0f, 1.0f), float4(0.2f, 0.05f, 0.0f, 1.0f), ps_in.intensity); +} + +#endif \ No newline at end of file diff --git a/Data/Test/particles.vert b/Data/Test/particles.vert new file mode 100644 index 0000000..bde9e36 --- /dev/null +++ b/Data/Test/particles.vert @@ -0,0 +1,41 @@ +#define USE_GLSL 0 + +#if USE_GLSL + +#version 430 +in vec4 vert; +uniform mat4 mvp; +out float intensity; +void main(void) +{ + intensity = vert.w; + gl_Position = mvp * vec4(vert.xyz, 1.0); +} + +#else + +struct VS_IN +{ + float4 vert : POSITION; +}; + +cbuffer mat : register(b0) +{ + row_major matrix mvp; +}; + +struct VS_OUT +{ + float4 outPos : SV_POSITION; + float intensity : INTENSITY; +}; + +VS_OUT main(VS_IN vs_in) +{ + VS_OUT vs_out; + vs_out.outPos = mvp * float4(vs_in.vert.xyz, 1.0); + vs_out.intensity = vs_in.vert.w; + return vs_out; +} + +#endif \ No newline at end of file diff --git a/Data/Test/triangle.frag b/Data/Test/triangle.frag index 2c0ed49..8bf5680 100755 --- a/Data/Test/triangle.frag +++ b/Data/Test/triangle.frag @@ -1,3 +1,7 @@ +#define USE_GLSL 0 + +#if USE_GLSL + #version 430 #extension GL_ARB_separate_shader_objects : enable @@ -11,3 +15,17 @@ void main() { outFragColor = vec4(inColor, 1.0); } + +#else + +struct VS_OUT +{ +// float4 outPos : SV_POSITION; + float3 outColor: COLOR; +}; + +float4 main(VS_OUT psIn) : SV_TARGET { + return float4(psIn.outColor, 1.0); +} + +#endif \ No newline at end of file diff --git a/Data/Test/triangle.vert b/Data/Test/triangle.vert index a88e5b0..1879fbb 100755 --- a/Data/Test/triangle.vert +++ b/Data/Test/triangle.vert @@ -1,3 +1,7 @@ +#define USE_GLSL 0 + +#if USE_GLSL + #version 430 #extension GL_ARB_separate_shader_objects : enable @@ -6,7 +10,7 @@ layout (location = 0) in vec3 inPos; layout (location = 1) in vec3 inColor; -layout (binding = 0) uniform UBO +layout (binding = 0) uniform UBO { mat4 projectionMatrix; mat4 modelMatrix; @@ -15,14 +19,46 @@ layout (binding = 0) uniform UBO layout (location = 0) out vec3 outColor; -out gl_PerVertex +out gl_PerVertex { - vec4 gl_Position; + vec4 gl_Position; }; -void main() +void main() { outColor = inColor; gl_Position = ubo.projectionMatrix * ubo.viewMatrix * ubo.modelMatrix * vec4(inPos.xyz, 1.0); -} \ No newline at end of file +} + +#else + +#pragma pack_matrix( row_major ) + +struct VS_IN +{ + float3 inPos : POSITION; + float3 inColor : COLOR; +}; + +struct VS_OUT +{ + float4 outPos : SV_POSITION; + float3 outColor : COLOR; +}; + +cbuffer UBO : register(b0) +{ + row_major matrix projectMatrix; + row_major matrix modelMatrix; + row_major matrix viewMatrix; +}; + +VS_OUT main(VS_IN vsin) +{ + VS_OUT vsout; + vsout.outPos = projectMatrix * viewMatrix * modelMatrix * float4(vsin.inPos.xyz, 1.0); + vsout.outColor = vsin.inColor; + return vsout; +} +#endif \ No newline at end of file diff --git a/Include/Config/ReadMe.md b/Include/Config/ReadMe.md new file mode 100644 index 0000000..bf3c66a --- /dev/null +++ b/Include/Config/ReadMe.md @@ -0,0 +1,2 @@ + +The "stdint.h" header is copied from llvm-3.5 diff --git a/Include/Config/note.txt b/Include/Config/note.txt deleted file mode 100755 index e2099e4..0000000 --- a/Include/Config/note.txt +++ /dev/null @@ -1 +0,0 @@ -this "stdint.h" is copied from llvm-3.5 diff --git a/Include/Core b/Include/Core deleted file mode 100755 index cba6077..0000000 --- a/Include/Core +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once - -#include "../Source/Core/Archive.h" -#include "../Source/Core/AssetManager.h" -#include "../Source/Core/AsynMeshTask.h" -#include "../Source/Core/Os.h" -#include "../Source/Core/Image.h" -#include "../Source/Core/LogUtil.h" -#include "../Source/Core/Window.h" -#include "../Source/Core/Mesh.h" -#include "../Source/Core/Message.h" -#include "../Source/Core/Looper.h" -#include "../Source/Core/Dispatch/WorkQueue.h" -#include "../Source/Core/Dispatch/WorkItem.h" -#include "../Source/Core/Dispatch/WorkGroup.h" \ No newline at end of file diff --git a/Source/RHI/ICrossShaderCompiler.h b/Include/Interface/ICrossShaderCompiler.h similarity index 97% rename from Source/RHI/ICrossShaderCompiler.h rename to Include/Interface/ICrossShaderCompiler.h index 7feb4d8..b3aa286 100755 --- a/Source/RHI/ICrossShaderCompiler.h +++ b/Include/Interface/ICrossShaderCompiler.h @@ -1,7 +1,7 @@ #pragma once #include "IRHIDefs.h" -#include +#include "IModule.h" namespace rhi { @@ -76,8 +76,10 @@ namespace rhi EUndefined = 0, EBlock = 0x1, ESampler = 0x1 << 1, - EStorageImage = 0x1 << 2, + ESampledImage = 0x1 << 2, + ESamplerImageCombine = (ESampler | ESampledImage), EStorageBuffer = 0x1 << 3, + EStorageImage = 0x1 << 4, EConstants = 0x000000010 }; @@ -305,3 +307,7 @@ result.Member.Append(ele);\ //virtual ::k3d::DynArray ListAvailableShaderLanguage() const = 0; }; } + +#if BUILD_STATIC_PLUGIN +K3D_STATIC_MODULE_DECLARE(ShaderCompiler); +#endif \ No newline at end of file diff --git a/Include/Interface/IIODevice.h b/Include/Interface/IIODevice.h index e704e9f..c66fee3 100755 --- a/Include/Interface/IIODevice.h +++ b/Include/Interface/IIODevice.h @@ -2,9 +2,9 @@ #define __IIODevice_H__ #pragma once -#include -#include -#include +#include "../Math/kTypeTrait.hpp" +#include "../Config/Config.h" +#include "../Config/PlatformTypes.h" #include enum IOFlag diff --git a/Include/Interface/IJob.h b/Include/Interface/IJob.h deleted file mode 100755 index 257535d..0000000 --- a/Include/Interface/IJob.h +++ /dev/null @@ -1,84 +0,0 @@ -#pragma once -#include -/** -struct ICondition { - virtual void Notify() = 0; - virtual void Wait() = 0; -}; - - -struct IJob { - - virtual ~IJob() {} - - virtual void OnRun() = 0; - - virtual void AddDependency(IJob *) = 0; - - virtual void OnComplete() { - if (m_JoinedJob != nullptr) { - JobList list = m_JoinedJob->GetDependencies(); - list.remove(this); - m_JoinedJob->GetPreqCondition()->Notify(); - } - } - - virtual void Execute() = 0; - - void SetJoinedJob(JoinedJob * joinedJob) { - m_JoinedJob = joinedJob; - } - - using JobList = std::list; - -protected: - JoinedJob * m_JoinedJob; -}; - - -struct JoinedJob : IJob { - virtual ~JoinedJob() {} - virtual void OnRun() = 0; - - void AddDependency(IJob * job) override { - job->SetJoinedJob(this); - m_DependJobs.push_back(job); - } - - void Execute() override { - while (m_PreqCondition!=nullptr && !m_DependJobs.empty()) { - m_PreqCondition->Wait(); - } - OnRun(); - } - - ICondition * GetPreqCondition() { - return m_PreqCondition; - } - - JobList & GetDependencies(); - -private: - JobList m_DependJobs; - ICondition * m_PreqCondition; -}; - -struct SerialJob : IJob { - - void AddDependency(IJob * job) override { - m_DependJobs.push_back(job); - } - - void Execute() override { - while (!m_DependJobs.empty()) { - IJob* job = m_DependJobs.back(); - job->OnRun(); - m_DependJobs.remove(job); - } - OnRun(); - } - -private: - JobList m_DependJobs; -}; -**/ \ No newline at end of file diff --git a/Source/Log/Public/ILog.h b/Include/Interface/ILog.h old mode 100755 new mode 100644 similarity index 96% rename from Source/Log/Public/ILog.h rename to Include/Interface/ILog.h index daef12e..747c394 --- a/Source/Log/Public/ILog.h +++ b/Include/Interface/ILog.h @@ -1,3 +1,4 @@ +#pragma once #ifndef __ILog_h__ #define __ILog_h__ diff --git a/Include/Interface/IMesh.h b/Include/Interface/IMesh.h index 1fcee9d..933cf8f 100755 --- a/Include/Interface/IMesh.h +++ b/Include/Interface/IMesh.h @@ -1,7 +1,8 @@ #pragma once -#include +#include "../Math/kGeometry.hpp" -enum class VtxFormat : uint32 { +enum class VtxFormat : uint32 +{ POS3_F32 = 0, POS4_F32, POS3_F32_UV2_F32, @@ -12,13 +13,15 @@ enum class VtxFormat : uint32 { PER_INSTANCE // all components are seperated }; -enum class PrimType : uint32 { +enum class PrimType : uint32 +{ POINTS = 0, TRIANGLES, TRIANGLE_STRIPS }; -struct K3D_API IMesh { +struct K3D_API IMesh +{ virtual ~IMesh() {} virtual kMath::AABB GetBoundingBox() const = 0; virtual uint32 GetMaterialID() const = 0; diff --git a/Include/Interface/IModule.h b/Include/Interface/IModule.h new file mode 100644 index 0000000..df06de2 --- /dev/null +++ b/Include/Interface/IModule.h @@ -0,0 +1,70 @@ +#pragma once +#include "Config/Config.h" +#include + +#if K3DPLATFORM_OS_WIN +#define PLUGIN_API_DECLARE __declspec(dllexport) +#else +#define PLUGIN_API_DECLARE __attribute__((visibility("default"))) +#endif + +#ifdef BUILD_SHARED_LIB +#ifdef BUILD_WITH_PLUGIN +#if K3DPLATFORM_OS_WIN +#define CORE_API __declspec(dllimport) +#else +#define CORE_API __attribute__((visibility("default"))) +#endif +#else +#if K3DPLATFORM_OS_WIN +#define CORE_API __declspec(dllexport) +#else +#define CORE_API __attribute__((visibility("default"))) +#endif +#endif +#else +#define CORE_API +#endif + +#define K3D_DYNAMIC_MODULE_IMPLEMENT(ModuleName, ModuleClass) \ +extern "C" PLUGIN_API_DECLARE ::k3d::IModule *Get##ModuleName##Module() { return new ModuleClass; } + +#define K3D_STATIC_MODULE_IMPLEMENT(ModuleName, MoudleClass) \ +extern "C" ::k3d::IModule *Get##ModuleName##Module() { \ +return new MoudleClass; \ +} +#define K3D_STATIC_MODULE_DECLARE(ModuleName) \ +extern "C" ::k3d::IModule *Get##ModuleName##Module() + +/** +* build dlls +*/ +#ifdef BUILD_SHARED_CORE +#define MODULE_IMPLEMENT(ModuleName, MoudleClass) K3D_DYNAMIC_MODULE_IMPLEMENT(ModuleName, MoudleClass) +#else +#define MODULE_IMPLEMENT(ModuleName, MoudleClass) K3D_STATIC_MODULE_IMPLEMENT(ModuleName, MoudleClass) +#endif + +#if BUILD_STATIC_PLUGIN +#define ACQUIRE_PLUGIN(PLUGIN) Get##PLUGIN##Module(); +#else +#define ACQUIRE_PLUGIN(PLUGIN) k3d::GlobalModuleManager.FindModule(#PLUGIN) +#endif + +K3D_COMMON_NS +{ + /** + * Module interface definition [RHI, ShaderCompiler, etc] + * @see ModuleManager [Core/ModuleManager] + */ + class IModule + { + public: + virtual void Start() = 0; + virtual void Shutdown() = 0; + virtual const char * Name() = 0; + virtual ~IModule() {} + }; + + typedef SharedPtr ModuleRef; +} \ No newline at end of file diff --git a/Include/Interface/IParameter.h b/Include/Interface/IParameter.h deleted file mode 100755 index ffe0899..0000000 --- a/Include/Interface/IParameter.h +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once -#include "IShader.h" - -struct IParameterManager -{ - virtual void SetVector4(const char * paramName, void *vector4) = 0; -}; \ No newline at end of file diff --git a/Source/RHI/IRHI.h b/Include/Interface/IRHI.h similarity index 89% rename from Source/RHI/IRHI.h rename to Include/Interface/IRHI.h index 9f05ca6..a4ffed5 100755 --- a/Source/RHI/IRHI.h +++ b/Include/Interface/IRHI.h @@ -1,19 +1,25 @@ #pragma once -#include #include "ICrossShaderCompiler.h" -#include "Tools/ShaderGen/Public/ShaderCompiler.h" namespace rhi { struct ICommandContext; typedef ::k3d::SharedPtr CommandContextRef; + struct IDeviceAdapter; + typedef ::k3d::SharedPtr DeviceAdapterRef; struct IDevice; typedef ::k3d::SharedPtr DeviceRef; struct IGpuResource; typedef ::k3d::SharedPtr GpuResourceRef; struct ITexture; typedef ::k3d::SharedPtr TextureRef; + struct IBuffer; + typedef ::k3d::SharedPtr BufferRef; + struct ITextureView; + typedef ::k3d::SharedPtr TextureViewRef; + struct IBufferView; + typedef ::k3d::SharedPtr BufferViewRef; struct IShaderResourceView; typedef ::k3d::SharedPtr ShaderResourceViewRef; struct IPipelineStateObject; @@ -55,20 +61,19 @@ namespace rhi struct K3D_API IGpuResource { - virtual ~IGpuResource() {} + virtual ~IGpuResource() {} virtual void * Map(uint64 start, uint64 size) = 0; virtual void UnMap() = 0; - virtual uint64 GetResourceLocation() const { return 0; } - virtual ResourceDesc GetResourceDesc() const = 0; + virtual uint64 GetLocation() const { return 0; } + virtual ResourceDesc GetDesc() const = 0; /** * Vulkan: texture uses image layout as resource state * D3D12: used for transition, maybe used as ShaderVisiblity determination in STATIC_SAMPLER and descriptor table */ - virtual EResourceState GetUsageState() const { return ERS_Unknown; } - virtual EGpuResourceType GetResourceType() const { return ResourceTypeNum; } - virtual uint64 GetResourceSize() const = 0; + virtual EResourceState GetState() const { return ERS_Unknown; } + virtual uint64 GetSize() const = 0; }; struct ISampler @@ -76,19 +81,18 @@ namespace rhi virtual SamplerState GetSamplerDesc() const = 0; virtual ~ISampler() {} }; - - struct ITexture; - + struct IShaderResourceView { + virtual ~IShaderResourceView() {} virtual GpuResourceRef GetResource() const = 0; virtual ResourceViewDesc GetDesc() const = 0; }; - struct ITexture : virtual public IGpuResource + struct ITexture : public IGpuResource { - virtual ~ITexture() {} - virtual SamplerCRef GetSampler() const = 0; + virtual ~ITexture() {} + virtual SamplerCRef GetSampler() const = 0; virtual void BindSampler(SamplerRef) = 0; virtual void SetResourceView(ShaderResourceViewRef) = 0; virtual ShaderResourceViewRef GetResourceView() const = 0; @@ -97,12 +101,15 @@ namespace rhi struct IDescriptor { virtual void Update(uint32 bindSet, GpuResourceRef) = 0; + virtual void Update(uint32 bindSet, SamplerRef) {}; + virtual uint32 GetSlotNum() const { return 0; } virtual ~IDescriptor() {} }; struct IDeviceAdapter { virtual DeviceRef GetDevice() = 0; + virtual ~IDeviceAdapter() {} }; /** @@ -156,9 +163,9 @@ namespace rhi DepthStencilState DepthStencil; // Shaders - ShaderBundle Shaders[ShaderTypeNum]; - // VertexAttributes - VertexInputLayout VertexLayout; + ShaderBundle Shaders[ShaderTypeNum]; + // Vertex Input State + VertexInputState InputState; // InputAssemblyState EPrimitiveType PrimitiveTopology = rhi::EPT_Triangles; }; @@ -177,6 +184,8 @@ namespace rhi virtual void SetVertexInputLayout(rhi::VertexDeclaration const*, uint32 Count) = 0; virtual void SetRenderTargetFormat(const RenderTargetFormat &) = 0; virtual void SetSampler(SamplerRef) = 0; + virtual void SavePSO(const char* /*path*/) {} + virtual void LoadPSO(const char*) {} }; struct IDescriptorPool @@ -212,12 +221,14 @@ namespace rhi struct K3D_API IDevice { - enum Result { + enum Result + { DeviceNotFound, DeviceFound }; virtual ~IDevice() {} + // @deprecated virtual Result Create(IDeviceAdapter *, bool withDebug) = 0; virtual CommandContextRef NewCommandContext(ECommandType) = 0; @@ -235,7 +246,7 @@ namespace rhi /* equal with d3d12's getcopyfootprint or vulkan's getImagesubreslayout. */ - virtual void QueryTextureSubResourceLayout(GpuResourceRef, TextureResourceSpec const& spec, SubResourceLayout *) {} + virtual void QueryTextureSubResourceLayout(TextureRef, TextureResourceSpec const& spec, SubResourceLayout *) {} }; struct K3D_API IRenderViewport diff --git a/Source/RHI/IRHIDefs.h b/Include/Interface/IRHIDefs.h similarity index 87% rename from Source/RHI/IRHIDefs.h rename to Include/Interface/IRHIDefs.h index ca32667..f2135e7 100755 --- a/Source/RHI/IRHIDefs.h +++ b/Include/Interface/IRHIDefs.h @@ -2,11 +2,11 @@ #ifndef __IRHIDefs_h__ #define __IRHIDefs_h__ -#include "Config/PlatformTypes.h" -#include -#include -#include -#include +#include "../Config/PlatformTypes.h" +#include "../KTL/DynArray.hpp" +#include "../KTL/SharedPtr.hpp" +#include "../KTL/String.hpp" +#include "../Math/kGeometry.hpp" namespace rhi { @@ -48,8 +48,11 @@ namespace rhi EPF_R11G11B10Float, EPF_D32Float, EPF_RGB32Float, - EPF_RGB8Unorm, - PixelFormatNum + EPF_RGB8Unorm, + EPF_BGRA8Unorm, // Apple Metal Layer uses it as default pixel format + EPF_BGRA8Unorm_sRGB, + EPF_RGBA16Float, + PixelFormatNum, }; enum EVertexFormat @@ -61,6 +64,12 @@ namespace rhi VertexFormatNum }; + enum EVertexInputRate + { + EVIR_PerVertex, + EVIR_PerInstance + }; + enum EMultiSampleFlag { EMS_1x, @@ -180,6 +189,12 @@ namespace rhi } }; + struct ColorAttachmentState + { + BlendState Blend; + uint32 ColorWriteMask; // z-pass + }; + struct RasterizerState { enum EFillMode @@ -440,6 +455,7 @@ namespace rhi float MinDepth; float MaxDepth; }; + /** * EVertexFormat, * Stride, @@ -455,6 +471,39 @@ namespace rhi uint32 OffSet; uint32 BindID; }; + + struct VertexInputState + { + enum { + kInvalidValue = -1, + kMaxVertexLayouts = 4, + kMaxVertexBindings = 8, + }; + + struct Attribute + { + Attribute(EVertexFormat const& format = EVF_Float3x32, uint32 offset = kInvalidValue, uint32 slot = kInvalidValue) + : Format(format), OffSet(offset), Slot(slot) + {} + + EVertexFormat Format = EVF_Float3x32; + uint32 OffSet = kInvalidValue; + uint32 Slot = kInvalidValue; + }; + + struct Layout + { + Layout(EVertexInputRate const& inputRate = EVIR_PerVertex, uint32 stride = kInvalidValue) + : Rate(inputRate), Stride(stride) + {} + + EVertexInputRate Rate = EVIR_PerVertex; + uint32 Stride = kInvalidValue; + }; + + Attribute Attribs[kMaxVertexBindings]; + Layout Layouts[kMaxVertexLayouts]; + }; struct VertexBufferView { @@ -513,6 +562,11 @@ namespace rhi EGRAF_HostCached = 0x1 << 5, }; + inline EGpuResourceAccessFlag operator | (EGpuResourceAccessFlag const& lhs, EGpuResourceAccessFlag const& rhs) + { + return EGpuResourceAccessFlag(uint32(lhs) | uint32(rhs)); + } + enum EGpuResourceCreationFlag { EGRCF_Dynamic = 0, @@ -521,6 +575,11 @@ namespace rhi EGRCF_TransferDst = 4 }; + inline EGpuResourceCreationFlag operator | (EGpuResourceCreationFlag const& lhs, EGpuResourceCreationFlag const& rhs) + { + return EGpuResourceCreationFlag(uint32(lhs) | uint32(rhs)); + } + /** * Format, Width, Height, Depth, MipLevel, Layers */ @@ -575,6 +634,11 @@ namespace rhi ETAF_METADATA = 1<<3, }; + inline ETextureAspectFlag operator|(ETextureAspectFlag const& lhs, ETextureAspectFlag const& rhs) + { + return ETextureAspectFlag(uint32(lhs) | uint32(rhs)); + } + /*same as VkImageSubresource */ struct TextureResourceSpec { diff --git a/Include/Interface/IRefObj.h b/Include/Interface/IRefObj.h deleted file mode 100755 index 8084c0e..0000000 --- a/Include/Interface/IRefObj.h +++ /dev/null @@ -1,9 +0,0 @@ -#pragma once - -class IRefObj -{ -public: - virtual uint32 AddRef() const = 0; - virtual uint32 Release() const = 0; - virtual uint32 GetRefCount() const = 0; -}; \ No newline at end of file diff --git a/Include/Interface/IReflectable.h b/Include/Interface/IReflectable.h deleted file mode 100755 index 2c27463..0000000 --- a/Include/Interface/IReflectable.h +++ /dev/null @@ -1,5 +0,0 @@ -#pragma once - -struct IReflectable { - virtual IReflectable * Reflect() = 0; -}; \ No newline at end of file diff --git a/Include/Interface/IRenderMesh.h b/Include/Interface/IRenderMesh.h index aee19de..1b1f181 100755 --- a/Include/Interface/IRenderMesh.h +++ b/Include/Interface/IRenderMesh.h @@ -2,7 +2,8 @@ struct IMesh; -struct IRenderMesh { +struct IRenderMesh +{ virtual ~IRenderMesh() {} virtual void Render(IMesh *) = 0; diff --git a/Include/Interface/IRenderer.h b/Include/Interface/IRenderer.h deleted file mode 100755 index a14968e..0000000 --- a/Include/Interface/IRenderer.h +++ /dev/null @@ -1,18 +0,0 @@ -#pragma once - -struct IRenderMesh; - -struct IRenderer { - - virtual ~IRenderer() {} - - virtual void PrepareFrame() = 0; - - virtual void DrawOneFrame() = 0; - - virtual void EndOneFrame() = 0; - - virtual void DrawMesh(IRenderMesh *) = 0; - - virtual void OnResize(int width, int height) = 0; -}; \ No newline at end of file diff --git a/Include/Interface/IRunnable.h b/Include/Interface/IRunnable.h deleted file mode 100755 index c09317b..0000000 --- a/Include/Interface/IRunnable.h +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef __ITask_H__ -#define __ITask_H__ - - -struct ITaskManager; -/*! - \class ITask -*/ -struct IRunnable -{ - virtual ~IRunnable () {} - virtual void OnRun() = 0; - - virtual void OnFinish() {} - virtual void OnStop() {} - virtual void OnResume() {} - virtual void OnCanceled() {} -}; - -enum class TaskPriority : uint32 { - RealTime, - BackGround, - Normal -}; - -#endif diff --git a/Include/Interface/IShader.h b/Include/Interface/IShader.h deleted file mode 100755 index 7561589..0000000 --- a/Include/Interface/IShader.h +++ /dev/null @@ -1,30 +0,0 @@ -#pragma once - -enum class ShaderType { - Vertex, - Pixel, - Domain, - Hull, - Geometry, - Compute -}; - - -struct IShader { -public: - virtual ~IShader() {} - - virtual void SaveCache() {} - virtual void LoadCache() {} -}; - - -template -class TShader -{ -public: - static const ShaderType type = ShaderInstType; - ShaderInstClass Get() { return ShaderInst; } -protected: - ShaderInstClass ShaderInst; -}; \ No newline at end of file diff --git a/Include/KTL/DynArray.hpp b/Include/KTL/DynArray.hpp index c0ff20a..10ed38f 100755 --- a/Include/KTL/DynArray.hpp +++ b/Include/KTL/DynArray.hpp @@ -6,11 +6,15 @@ #include "Allocator.hpp" #include "Archive.hpp" -#ifndef K3DPLATFORM_OS_MAC +#if (K3DPLATFORM_OS_WIN) || (K3DPLATFORM_OS_ANDROID) #include #else #include #endif + + + + #include #ifdef DYNARRAY_TEST_CASE @@ -19,7 +23,7 @@ typedef unsigned int uint32; typedef size_t uint64; #endif -namespace k3d +K3D_COMMON_NS { template < class T, @@ -83,12 +87,22 @@ namespace k3d m_pElement = (ElementType*)m_Allocator.allocate(m_Capacity*sizeof(ElementType), 0); __Initializer::DoInit(m_pElement, m_pElement+m_Capacity); } - + + DynArray(int size) K3D_NOEXCEPT + : m_ElementIndex(0), m_ElementCount(0), m_Capacity(size), m_pElement(nullptr) + { + m_pElement = (ElementType*)m_Allocator.allocate(m_Capacity*sizeof(ElementType), 0); + __Initializer::DoInit(m_pElement, m_pElement+m_Capacity); + } + DynArray(DynArray && rhs) : m_ElementCount(0), m_ElementIndex(0), m_pElement(nullptr) { m_ElementCount = rhs.m_ElementCount; m_Capacity = rhs.m_Capacity; m_pElement = rhs.m_pElement; + rhs.m_pElement = nullptr; + rhs.m_Capacity = 0; + rhs.m_ElementCount = 0; } DynArray(DynArray && rhs, TAllocator & alloc) : m_ElementCount(0), m_ElementIndex(0), m_pElement(nullptr), m_Allocator(alloc) @@ -103,7 +117,8 @@ namespace k3d m_ElementCount = rhs.m_ElementCount; m_Capacity = rhs.m_Capacity; m_pElement = (ElementType*)m_Allocator.allocate(m_Capacity*sizeof(ElementType), 0); - memcpy(m_pElement, rhs.m_pElement, rhs.m_ElementCount * sizeof(ElementType)); + __Initializer::DoInit(m_pElement, m_pElement + m_Capacity); + __Copier::DoCopy(m_pElement, rhs.m_pElement, rhs.m_ElementCount); } template @@ -206,6 +221,23 @@ namespace k3d } } + void Resize(int NewElementCount) + { + if(NewElementCount > m_Capacity) + { + ElementType* pElement = (ElementType*)m_Allocator.allocate(NewElementCount*sizeof(ElementType), 0); + __Initializer::DoInit(pElement, pElement + NewElementCount); + if(m_ElementCount > 0) + { + __Copier::DoCopy(pElement, m_pElement, m_ElementCount); + m_Allocator.deallocate(m_pElement, 0); + } + m_Capacity = NewElementCount; + m_pElement = pElement; + } + m_ElementCount = NewElementCount; + } + ElementType const& operator[](uint32 index) const { return m_pElement[index]; diff --git a/Include/KTL/IntrusiveList.hpp b/Include/KTL/IntrusiveList.hpp index c6a3508..f7f365e 100755 --- a/Include/KTL/IntrusiveList.hpp +++ b/Include/KTL/IntrusiveList.hpp @@ -8,7 +8,8 @@ #include #include -namespace kTL { +K3D_COMMON_NS +{ class _My_Intrusive_List_Base; class _My_Intrusive_List_Node_Base; diff --git a/Include/KTL/LockFreeQueue.hpp b/Include/KTL/LockFreeQueue.hpp index 2ae883d..4164541 100755 --- a/Include/KTL/LockFreeQueue.hpp +++ b/Include/KTL/LockFreeQueue.hpp @@ -1,4 +1,8 @@ #pragma once + +K3D_COMMON_NS +{ + template class LockFreeQueue { public: @@ -105,4 +109,6 @@ class LockFreeQueue { volatile int m_Size; Node *m_Head, *m_Tail; -}; \ No newline at end of file +}; + +} \ No newline at end of file diff --git a/Include/KTL/NonCopyable.hpp b/Include/KTL/NonCopyable.hpp index 3dd851a..d36bdb1 100755 --- a/Include/KTL/NonCopyable.hpp +++ b/Include/KTL/NonCopyable.hpp @@ -1,5 +1,7 @@ #pragma once +K3D_COMMON_NS +{ class NonCopyable { protected: @@ -8,4 +10,5 @@ class NonCopyable NonCopyable(const NonCopyable &); NonCopyable(const NonCopyable &&); NonCopyable& operator=(const NonCopyable &); -}; \ No newline at end of file +}; +} \ No newline at end of file diff --git a/Include/KTL/RefCount.hpp b/Include/KTL/RefCount.hpp index 646dbb6..8c8bb57 100755 --- a/Include/KTL/RefCount.hpp +++ b/Include/KTL/RefCount.hpp @@ -96,19 +96,28 @@ K3D_COMMON_NS } }; + template + struct AlignedStorage + { + typedef struct { + alignas(Align) unsigned char CharData[N]; + } Type; + }; + + template class TRefCountInstance : public RefCountBase { public: - T m_Memory; + typename AlignedStorage::Type m_Memory; // use storage substitude T* GetValue() { return static_cast(static_cast(&m_Memory)); } template TRefCountInstance(Args&&... args) : RefCountBase() - , m_Memory(std::forward(args)...) { + new (&m_Memory) T(std::forward(args)...); } void FreeValue() K3D_NOEXCEPT override diff --git a/Include/KTL/SharedPtr.hpp b/Include/KTL/SharedPtr.hpp index 7e6f53c..471bb5c 100755 --- a/Include/KTL/SharedPtr.hpp +++ b/Include/KTL/SharedPtr.hpp @@ -2,8 +2,17 @@ #include "RefCount.hpp" +#if K3DPLATFORM_OS_WIN && ENABLE_SHAREDPTR_TRACKER +#include +#include "String.hpp" +#endif + K3D_COMMON_NS { + template class WeakPtr; + template class SharedPtr; + template class EnableSharedFromThis; + template struct TSharedPtrBase { @@ -16,6 +25,17 @@ K3D_COMMON_NS }; + template + void __EnableSharedFromThis(const RefCountBase* pRefCount, const EnableSharedFromThis* pEnableSharedFromThis, const U* pValue) + { + if (pEnableSharedFromThis) + pEnableSharedFromThis->m_WeakPtr.Assign(const_cast(pValue), const_cast(pRefCount)); + } + + inline void __EnableSharedFromThis(const RefCountBase*, ...) + { + } + template class SharedPtr : TSharedPtrBase { @@ -29,7 +49,16 @@ K3D_COMMON_NS , m_pRefCount(sharedPtr.m_pRefCount) { if (m_pRefCount) + { m_pRefCount->AddRef(); + +#if K3DPLATFORM_OS_WIN && ENABLE_SHAREDPTR_TRACKER + String debugStr; + debugStr.AppendSprintf("SharedPtr Track (Assign Construct) [%s] --- Strong=%d Weak=%d .\n", + typeid(T).name(), m_pRefCount->m_RefCount, m_pRefCount->m_WeakRefCount); + OutputDebugStringA(debugStr.CStr()); +#endif + } } SharedPtr(decltype(nullptr)) @@ -44,7 +73,16 @@ K3D_COMMON_NS , m_pRefCount(sharedPtr.m_pRefCount) { if (m_pRefCount) + { m_pRefCount->AddRef(); + +#if K3DPLATFORM_OS_WIN && ENABLE_SHAREDPTR_TRACKER + String debugStr; + debugStr.AppendSprintf("SharedPtr Track (Assign Construct) [%s] --- Strong=%d Weak=%d .\n", + typeid(U).name(), m_pRefCount->m_RefCount, m_pRefCount->m_WeakRefCount); + OutputDebugStringA(debugStr.CStr()); +#endif + } } template @@ -64,10 +102,30 @@ K3D_COMMON_NS AllocInternal(pValue, DefaultDeletor()); } + template + explicit SharedPtr(const WeakPtr& weakPtr) + : m_pValue(weakPtr.m_pValue), + m_pRefCount(weakPtr.m_pRefCount ? weakPtr.m_pRefCount->Lock() : weakPtr.m_pRefCount) + { + if(!m_pRefCount) + { + m_pValue = nullptr; + } + } + ~SharedPtr() { - if (m_pRefCount) + if (m_pRefCount) + { m_pRefCount->Release(); + +#if K3DPLATFORM_OS_WIN && ENABLE_SHAREDPTR_TRACKER + String debugStr; + debugStr.AppendSprintf("SharedPtr Track (Release) [%s] --- Strong=%d Weak=%d .\n", + typeid(T).name(), m_pRefCount->m_RefCount, m_pRefCount->m_WeakRefCount); + OutputDebugStringA(debugStr.CStr()); +#endif + } m_pValue = nullptr; m_pRefCount = nullptr; } @@ -101,6 +159,13 @@ K3D_COMMON_NS { ThisType(sharedPtr).Swap(*this); } + +#if K3DPLATFORM_OS_WIN && ENABLE_SHAREDPTR_TRACKER + String debugStr; + debugStr.AppendSprintf("SharedPtr Track (Assign) [%s] --- Strong=%d Weak=%d .\n", + typeid(T).name(), m_pRefCount->m_RefCount, m_pRefCount->m_WeakRefCount); + OutputDebugStringA(debugStr.CStr()); +#endif return *this; } @@ -129,6 +194,7 @@ K3D_COMMON_NS { m_pRefCount = ::new(pMemory) RefCountT(pValue, Move(deleter)); m_pValue = pValue; + __EnableSharedFromThis(m_pRefCount, pValue, pValue); } else { @@ -148,6 +214,7 @@ K3D_COMMON_NS RCT* pRefCount = ::new(pMemory) RCT(Forward(args)...); sharedPtr.m_pRefCount = (RefCountBase*)pRefCount; sharedPtr.m_pValue = pRefCount->GetValue(); + __EnableSharedFromThis(pRefCount, pRefCount->GetValue(), pRefCount->GetValue()); } return sharedPtr; } @@ -168,6 +235,14 @@ K3D_COMMON_NS class WeakPtr { public: + typedef WeakPtr ThisType; + + WeakPtr(decltype(nullptr)) + : m_pValue(nullptr) + , m_pRefCount(nullptr) + { + } + WeakPtr() : m_pValue(nullptr), m_pRefCount(nullptr) {} template @@ -185,11 +260,85 @@ K3D_COMMON_NS m_pRefCount->ReleaseWeakRef(); } + T& operator*() const { return *m_pValue; } + + T* operator->() const { return m_pValue; } + + void Swap(WeakPtr& weakPtr) + { + T * const pValue = weakPtr.m_pValue; + weakPtr.m_pValue = m_pValue; + m_pValue = pValue; + RefCountBase* const pRefCount = weakPtr.m_pRefCount; + weakPtr.m_pRefCount = m_pRefCount; + m_pRefCount = pRefCount; + } + + WeakPtr& operator=(const WeakPtr& weakPtr) + { + if (&weakPtr != this) + { + WeakPtr(weakPtr).Swap(*this); + } + return *this; + } + + explicit operator bool() const + { + return m_pValue != nullptr; + } + + T* Get() const { return m_pValue; } + + void Assign(T* pValue, RefCountBase* pRefCount) + { + m_pValue = pValue; + + if (pRefCount != m_pRefCount) + { + if (m_pRefCount) + m_pRefCount->ReleaseWeakRef(); + + m_pRefCount = pRefCount; + + if (m_pRefCount) + m_pRefCount->AddWeakRef(); + } + } + protected: T* m_pValue; RefCountBase* m_pRefCount; template friend class SharedPtr; template friend class WeakPtr; + template friend class EnableSharedFromThis; + private: + }; + + template class EnableSharedFromThis + { + protected: + template friend class SharedPtr; + EnableSharedFromThis() {} + EnableSharedFromThis(EnableSharedFromThis const &) {} + EnableSharedFromThis & operator=(EnableSharedFromThis const &) + { + return *this; + } + ~EnableSharedFromThis() + { + } + public: + SharedPtr SharedFromThis() + { + return SharedPtr(m_WeakPtr); + } + SharedPtr SharedFromThis() const + { + return SharedPtr(m_WeakPtr); + } + public: + mutable WeakPtr m_WeakPtr; }; } \ No newline at end of file diff --git a/Include/KTL/Singleton.hpp b/Include/KTL/Singleton.hpp index bd2e3f0..c214da4 100755 --- a/Include/KTL/Singleton.hpp +++ b/Include/KTL/Singleton.hpp @@ -1,6 +1,8 @@ #pragma once #include +K3D_COMMON_NS +{ template class K3D_API Singleton { @@ -14,3 +16,4 @@ class K3D_API Singleton protected: Singleton(){} }; +} \ No newline at end of file diff --git a/Include/KTL/String.hpp b/Include/KTL/String.hpp new file mode 100644 index 0000000..b19ea9b --- /dev/null +++ b/Include/KTL/String.hpp @@ -0,0 +1,379 @@ +#pragma once + +#include "Allocator.hpp" +#include "Archive.hpp" + +K3D_COMMON_NS +{ +template +inline uint64 CharLength(const BaseChar* cStr) +{ + const BaseChar *eos = cStr; + while (*eos++); + return(eos - cStr - 1); +} + +extern K3D_API int Vsnprintf(char*, int n, const char* fmt, va_list); + +template +class StringBase +{ +public: + typedef BaseChar* CharPointer; + typedef const BaseChar* ConstCharPointer; + typedef StringBase ThisString; + typedef uint64 CharPosition; + + StringBase() K3D_NOEXCEPT + : m_pStringData(nullptr) + , m_StringLength(0) + , m_Capacity(0) + { + } + + StringBase(const void * pData, size_t szData) K3D_NOEXCEPT + : m_pStringData(nullptr) + , m_StringLength(0) + , m_Capacity(0) + { + uint64 calLength = szData / sizeof(BaseChar); + uint64 remain = szData % sizeof(BaseChar); + if (remain == 0) + { + m_StringLength = calLength; + m_Capacity = m_StringLength + 1; + m_pStringData = Allocate(m_Capacity); + memcpy(m_pStringData, pData, szData); + m_pStringData[m_StringLength] = 0; + } + } + + StringBase(ConstCharPointer pStr) K3D_NOEXCEPT + : m_pStringData(nullptr) + , m_StringLength(0) + , m_Capacity(0) + { + m_StringLength = CharLength(pStr); + if (m_StringLength) + { + m_Capacity = (uint64)(1.5f * m_StringLength + 0.5f); + m_pStringData = Allocate(m_Capacity); + memcpy(m_pStringData, pStr, m_StringLength * sizeof(BaseChar)); + m_pStringData[m_StringLength] = 0; + } + } + + StringBase(const ThisString & rhs) K3D_NOEXCEPT + : m_pStringData(nullptr) + , m_StringLength(0) + , m_Capacity(rhs.m_Capacity) + , m_StringAllocator(rhs.m_StringAllocator) + { + Assign(rhs); + } + + StringBase(ThisString && rhs) K3D_NOEXCEPT + : m_pStringData(nullptr) + , m_StringLength(0) + { + MoveAssign(Move(rhs)); + } + + ~StringBase() + { + if (m_pStringData) + { + Deallocate(); + } + m_pStringData = nullptr; + m_StringLength = 0; + } + + uint64 Length() const { return m_StringLength; } + ConstCharPointer Data() const { return m_pStringData; } + ConstCharPointer CStr() const { return m_pStringData; } + + ThisString& operator=(const ThisString& rhs) { Assign(rhs); return *this; } + ThisString& operator=(ThisString&& rhs) { MoveAssign(Move(rhs)); return *this; } + ThisString& operator+=(const ThisString& rhs); + ThisString& operator+=(const BaseChar& rhs); + BaseChar operator[](uint64 id) const; + ThisString& AppendSprintf(const BaseChar* fmt, ...); + void Swap(ThisString& rhs); + + void Resize(int newSize); + //CharPosition FindFirstOf(BaseChar _char); + + template + friend Archive& operator<<(Archive & ar, StringBase const& str); + + template + friend Archive& operator >> (Archive & ar, StringBase & str); + +protected: + CharPointer Allocate(uint64 stringLength); + void Deallocate(); + + void MoveAssign(ThisString && rhs); + void Assign(ThisString const& rhs); + +private: + CharPointer m_pStringData; + uint64 m_StringLength; + uint64 m_Capacity; + Allocator m_StringAllocator; +}; + +template +KFORCE_INLINE BaseChar* StringBase::Allocate(uint64 length) +{ + return reinterpret_cast(m_StringAllocator.allocate(sizeof(BaseChar)*length, 0)); +} + +template +KFORCE_INLINE void StringBase::Deallocate() +{ + m_StringAllocator.deallocate(m_pStringData, sizeof(BaseChar)*m_StringLength); +} + +template +KFORCE_INLINE void StringBase::MoveAssign(StringBase && rhs) +{ + m_pStringData = rhs.m_pStringData; + m_StringLength = rhs.m_StringLength; + m_Capacity = rhs.m_Capacity; + m_StringAllocator = Move(rhs.m_StringAllocator); + rhs.m_pStringData = nullptr; + rhs.m_StringLength = 0; + rhs.m_Capacity = 0; +} + +template +KFORCE_INLINE void StringBase::Assign(StringBase const & rhs) +{ + if (m_pStringData != rhs.m_pStringData) + { + if (m_pStringData) + { + Deallocate(); + } + m_Capacity = rhs.m_StringLength + 1; + m_pStringData = Allocate(m_Capacity); + m_StringLength = rhs.m_StringLength; + memcpy(m_pStringData, rhs.m_pStringData, rhs.m_StringLength * sizeof(BaseChar)); + m_pStringData[m_StringLength] = 0; + } +} + +template +KFORCE_INLINE StringBase& +StringBase::AppendSprintf(const BaseChar *fmt, ...) +{ + va_list va; + va_start(va, fmt); + int length = Vsnprintf(m_pStringData + m_StringLength, m_Capacity - m_StringLength, fmt, va); + va_end(va); + + auto newLen = length + m_StringLength; + if (newLen >= m_Capacity) + { + m_Capacity = (uint64)(1.33f * newLen + 1.0f); + BaseChar* newString = Allocate(m_Capacity); + memcpy(newString, m_pStringData, m_StringLength * sizeof(BaseChar)); + + va_list va; + va_start(va, fmt); + Vsnprintf(newString + m_StringLength, m_Capacity - m_StringLength, fmt, va); + va_end(va); + + Deallocate(); + m_pStringData = newString; + } + + m_StringLength = newLen; + + return *this; +} + +template +KFORCE_INLINE void StringBase::Swap(StringBase & rhs) +{ + BaseChar* p = rhs.m_pStringData; + rhs.m_pStringData = m_pStringData; + m_pStringData = p; + + uint64 l = rhs.m_StringLength; + rhs.m_StringLength = m_StringLength; + m_StringLength = l; +} + +template +KFORCE_INLINE void StringBase::Resize(int newSize) +{ + auto newCapacity = (uint64)(1.1f * newSize + 1.0f); + if (newCapacity > m_Capacity) + { + m_Capacity = newCapacity; + auto pStringData = Allocate(m_Capacity); + if (m_StringLength) + { + memcpy(pStringData, m_pStringData, sizeof(BaseChar) * m_StringLength); + pStringData[m_StringLength] = 0; + Deallocate(); + } + else + { + memset(pStringData, 0, sizeof(BaseChar) * m_Capacity); + } + m_pStringData = pStringData; + } +} + +template +KFORCE_INLINE BaseChar StringBase::operator[](uint64 id) const +{ + return m_pStringData[id]; +} + +template +KFORCE_INLINE StringBase& +StringBase::operator+=(StringBase const& rhs) +{ + auto rLen = rhs.m_StringLength; + auto newLen = m_StringLength + rLen; + if (newLen >= m_Capacity) + { + m_Capacity = uint64(1.5*newLen + 1); + auto pNewData = Allocate(m_Capacity); + if (m_pStringData) + { + memcpy(pNewData, m_pStringData, m_StringLength * sizeof(BaseChar)); + Deallocate(); + } + m_pStringData = pNewData; + } + memcpy(m_pStringData + m_StringLength, rhs.m_pStringData, rLen * sizeof(BaseChar)); + m_pStringData[newLen] = 0; + m_StringLength = newLen; + return *this; +} + +template +KFORCE_INLINE StringBase& +StringBase::operator+=(BaseChar const& rhs) +{ + auto newLen = m_StringLength + 1; + if (newLen >= m_Capacity) + { + m_Capacity = uint64(1.5*newLen + 1); + auto pNewData = Allocate(m_Capacity); + if (m_pStringData) + { + memcpy(pNewData, m_pStringData, m_StringLength * sizeof(BaseChar)); + Deallocate(); + } + m_pStringData = pNewData; + } + m_pStringData[m_StringLength] = rhs; + m_pStringData[newLen] = 0; + m_StringLength = newLen; + return *this; +} + +template +KFORCE_INLINE StringBase +operator+(StringBase const& lhs, StringBase const& rhs) +{ + StringBase ret(lhs); + ret += rhs; + return ret; +} + +template +KFORCE_INLINE bool operator==(StringBase const& lhs, StringBase const& rhs) K3D_NOEXCEPT +{ + if (&lhs == &rhs) + return true; + return ((lhs.Length() == rhs.Length()) + && (memcmp(lhs.Data(), rhs.Data(), lhs.Length() * sizeof(BaseChar)) == 0)); +} + +template +Archive& operator<<(Archive & ar, StringBase const& str) +{ + ar << str.m_Capacity << str.m_StringLength; + ar.ArrayIn(str.CStr(), str.Length()); + return ar; +} + +template +Archive& operator >> (Archive & ar, StringBase & str) +{ + ar >> str.m_Capacity >> str.m_StringLength; + str.m_pStringData = str.Allocate(str.m_Capacity); + ar.ArrayOut(str.m_pStringData, str.Length()); + str.m_pStringData[str.m_StringLength] = 0; + return ar; +} + +typedef StringBase String; + +extern K3D_API String Base64Encode(String const & in); +extern K3D_API String Base64Decode(String const& in); +extern K3D_API String MD5Encode(String const& in); +} + +#include + +namespace std +{ + template + struct _FNVHash + { + size_t operator()(const unsigned char *pData, size_t count); + }; + + template <> + struct _FNVHash<8> + { + inline size_t operator()(const unsigned char *pData, size_t count) + { + const size_t fnvOffsetBase = 14695981039346656037ULL; + const size_t fnvPrime = 1099511628211ULL; + size_t val = fnvOffsetBase; + for (size_t i = 0; i < count; ++i) + { // fold in another byte + val ^= (size_t)pData[i]; + val *= fnvPrime; + } + return (val); + } + }; + + template <> + struct _FNVHash<4> + { + inline size_t operator()(const unsigned char *pData, size_t count) + { + const size_t fnvOffsetBase = 2166136261U; + const size_t fnvPrime = 16777619U; + size_t val = fnvOffsetBase; + for (size_t i = 0; i < count; ++i) + { + val ^= (size_t)pData[i]; + val *= fnvPrime; + } + return (val); + } + }; + + template<> + struct hash + { + size_t operator()(const k3d::String& val) const + { + _FNVHash _Hasher; + return _Hasher((const unsigned char *)val.CStr(), val.Length()); + } + }; +} \ No newline at end of file diff --git a/Include/Math/IK.hpp b/Include/Math/IK.hpp new file mode 100644 index 0000000..43164cf --- /dev/null +++ b/Include/Math/IK.hpp @@ -0,0 +1,36 @@ +/*********************************************** + * Kaleido3D Math Library (Inverse Kinematics Solver) + * Implements Jacobian, CCD and FABRIK + * Author : Qin Zhou + * Date : 2017/2/18 + * Email : dsotsen@gmail.com + ***********************************************/ +#include "kMath.hpp" + +NS_MATHLIB_BEGIN + +class Joint +{ +private: + tMatrixNxN m_LocalMatrix; + tMatrixNxN m_WorldMatrix; + tVectorN m_Direction; + tVectorN m_Dof; +}; + +class IKSolver +{ + +}; + +class CCDIKSolver : public IKSolver +{ + +}; + +class FABRIKSolver : public IKSolver +{ + +}; + +NS_MATHLIB_END diff --git a/Include/Math/kMath.hpp b/Include/Math/kMath.hpp index 9314a39..d3a0eaa 100755 --- a/Include/Math/kMath.hpp +++ b/Include/Math/kMath.hpp @@ -13,7 +13,7 @@ #include "kTypeTrait.hpp" #include "../Kaleido3D.h" -#include +#include "../Config/OSHeaders.h" #if K3DCOMPILER_CLANG || K3DCOMPILER_GCC #include diff --git a/Include/Math/kMath_SSE.hpp b/Include/Math/kMath_SSE.hpp index b39cf8e..0c7f11b 100755 --- a/Include/Math/kMath_SSE.hpp +++ b/Include/Math/kMath_SSE.hpp @@ -2,7 +2,7 @@ #ifndef __kMath_SSE_hpp__ #define __kMath_SSE_hpp__ -#include +#include "../Config/Config.h" #include #define _MM_PERM2_X 0 diff --git a/Project/Common.cmake b/Project/Common.cmake index 7fa6f67..d41da4c 100755 --- a/Project/Common.cmake +++ b/Project/Common.cmake @@ -1,73 +1,229 @@ set(GLSLANG_LIBS glslang OGLCompiler OSDependent SPIRV) -set(UNITTEST_DEPENDS Core Render ShaderCompiler) + +set(UT_LINK_LIBS Core Engine Render) +set(UT_DEP_PLUGIN "") + +set(DEVELOPMENT_TEAM "8HY898Y2MS") +set(CODE_SIGN_IDENTITY "iPhone Developer") + +function(link_plugin PLUGIN_NAME) # current plugins: RHI_*, KawaLog, ShaderCompiler +if(BUILD_SHARED) +else() + target_link_libraries(${PLUGIN_NAME} ${ARGN}) +endif() +endfunction() + if(ANDROID) - set(UNITTEST_DEPENDS ${UNITTEST_DEPENDS} RHI_Vulkan) + list(APPEND UT_LINK_LIBS RHI_Vulkan ShaderCompiler) elseif(WIN32) - set(UNITTEST_DEPENDS ${UNITTEST_DEPENDS} Engine RHI_Vulkan - winmm comctl32 ${GLSLANG_LIBS}) + list(APPEND UT_LINK_LIBS RHI_Vulkan winmm comctl32 ${GLSLANG_LIBS}) if(BUILD_WITH_D3D12) - set(UNITTEST_DEPENDS ${UNITTEST_DEPENDS} RHI_D3D12 ${DXSDK_LIBRARIES}) + list(UT_LINK_LIBS RHI_D3D12 ${DXSDK_LIBRARIES}) endif() elseif(MACOS) - set(UNITTEST_DEPENDS ${UNITTEST_DEPENDS} "-framework AppKit") + list(APPEND UT_LINK_LIBS "-framework AppKit" RHI_Metal) +elseif(IOS) + list(APPEND UT_LINK_LIBS "-framework UIKit" RHI_Metal) + set(PLIST_GEN ${Kaleido3D_ROOT_DIR}/Project/plist_gen) endif() -function(add_plugin PLUGIN_NAME PLUGIN_FOLDER) +if(BUILD_SHARED) +else() # Static Build + list(APPEND UT_LINK_LIBS ShaderCompiler) +endif(BUILD_SHARED) + +function(add_ios_framework TARGET) + cmake_parse_arguments(${TARGET} + "" + "FOLDER;ID;PDN" + "SRCS;LIBS;PUBLIC" + ${ARGN} + ) + add_library(${TARGET} SHARED ${${TARGET}_SRCS}) + target_link_libraries(${TARGET} ${${TARGET}_LIBS}) + add_custom_command(TARGET ${TARGET} POST_BUILD COMMAND ${CMAKE_INSTALL_NAME_TOOL} -id "@executable_path/${TARGET}.framework/${TARGET}" $) + if(NOT ${TARGET}_ID) + set(${TARGET}_ID "com.tsinstudio.kaleido3d") + endif() + if(NOT ${TARGET}_PDN) + set(${TARGET}_PDN "${TARGET}") + endif() + execute_process(COMMAND ${PLIST_GEN} -t "framework" --be "${TARGET}" + --bid "${${TARGET}_ID}" --cr "\"Copyright 2016 Tsin Studio\"" + --bn "${${TARGET}_ID}" --bdn "${${TARGET}_PDN}" + --outdir "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${TARGET}.dir") ## generate Info.plist + set_target_properties(${TARGET} PROPERTIES + FRAMEWORK TRUE + FRAMEWORK_VERSION A + MACOSX_FRAMEWORK_INFO_PLIST ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${TARGET}.dir/Info.plist + # "current version" in semantic format in Mach-O binary file + VERSION 1.0.0 + # "compatibility version" in semantic format in Mach-O binary file + SOVERSION 1.0.0 + PUBLIC_HEADER "${${TARGET}_PUBLIC}" + XCODE_ATTRIBUTE_DEVELOPMENT_TEAM ${DEVELOPMENT_TEAM} + XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY ${CODE_SIGN_IDENTITY} + XCODE_ATTRIBUTE_PROVISIONING_STYLE Automatic + XCODE_ATTRIBUTE_ENABLE_BITCODE "NO" + ) +endfunction() + +function(k3d_add_lib TARGET) + cmake_parse_arguments(${TARGET} + "" + "FOLDER" + "SRCS;LIBS" + ${ARGN} + ) if(BUILD_SHARED) - add_definitions(-DBUILD_SHARED_LIB -DBUILD_WITH_PLUGIN) + add_definitions(-DBUILD_SHARED_LIB) + if(IOS) + add_ios_framework(${TARGET} SRCS ${${TARGET}_SRCS} LIBS ${${TARGET}_LIBS}) + else() + add_library(${TARGET} SHARED ${${TARGET}_SRCS}) + target_link_libraries(${TARGET} ${${TARGET}_LIBS}) + endif(IOS) + else() + add_library(${TARGET} STATIC ${${TARGET}_SRCS}) endif() - set(LINK_BEGINS FALSE) - foreach(ITEM IN LISTS ARGN) - if("${ITEM}" STREQUAL "LINKLIBS") - set(LINK_BEGINS TRUE) - continue() - endif() - if(NOT LINK_BEGINS) - list(APPEND SRCS ${ITEM}) - else() - list(APPEND LIBS ${ITEM}) - endif() - endforeach() - - add_library(${PLUGIN_NAME} ${LIB_TYPE} ${SRCS}) - set_target_properties(${PLUGIN_NAME} PROPERTIES FOLDER "${PLUGIN_FOLDER}") - target_link_libraries(${PLUGIN_NAME} Core ${LIBS}) + set_target_properties(${TARGET} PROPERTIES FOLDER "${${TARGET}_FOLDER}") +endfunction() + +function(add_plugin PLUGIN_NAME) + cmake_parse_arguments(${PLUGIN_NAME} + "" + "FOLDER" + "SRCS;LIBS" + ${ARGN} + ) + if(BUILD_SHARED) + add_definitions(-DBUILD_SHARED_LIB -DBUILD_WITH_PLUGIN) + if(IOS) # use framework + add_ios_framework(${PLUGIN_NAME} SRCS ${${PLUGIN_NAME}_SRCS} LIBS Core ${${PLUGIN_NAME}_LIBS}) + else() + add_library(${PLUGIN_NAME} ${LIB_TYPE} ${${PLUGIN_NAME}_SRCS}) + target_link_libraries(${PLUGIN_NAME} Core ${${PLUGIN_NAME}_LIBS}) + endif(IOS) + else() + add_library(${PLUGIN_NAME} ${LIB_TYPE} ${${PLUGIN_NAME}_SRCS}) + target_link_libraries(${PLUGIN_NAME} Core ${${PLUGIN_NAME}_LIBS}) + endif(BUILD_SHARED) + set_target_properties(${PLUGIN_NAME} PROPERTIES FOLDER "${${PLUGIN_NAME}_FOLDER}") endfunction() if(MACOS) - function(target_pack_depend_libraries EXE_NAME) - set(${EXE_NAME}_DIR $) - foreach(DEPEND_LIB IN LISTS ARGN) - message("${EXE_NAME}: Coping lib${DEPEND_LIB}") - set(${DEPEND_LIB}_PACK_PATH "${${EXE_NAME}_DIR}/../../Contents/Frameworks/lib${DEPEND_LIB}.dylib") - # Copy Dependency Libraries To XX.app/Contents/Frameworks - add_custom_command(TARGET ${EXE_NAME} PRE_BUILD COMMAND ${CMAKE_COMMAND} -E - copy "$" "${${DEPEND_LIB}_PACK_PATH}") - endforeach() + function(add_mac_app TARGET) + cmake_parse_arguments(${TARGET} + "" + "PDN;OS;LDPATH;ID" # product name, target OS, LD_RUNPATH_SEARCH_PATHS, bundle identifier + "SRCS;LIBS;PLUGINS" # sources, link libs + ${ARGN}) + add_executable(${TARGET} MACOSX_BUNDLE ${${TARGET}_SRCS}) + if(BUILD_SHARED) + if(${TARGET}_LIBS) + target_link_libraries(${TARGET} ${${TARGET}_LIBS}) + set(${TARGET}_FRAMEWORK_DIR "$/../../Contents/Frameworks") + foreach(DEPEND_LIB IN LISTS ${TARGET}_LIBS) + # Copy Dependency Libraries To XX.app/Contents/Frameworks + add_custom_command(TARGET ${TARGET} PRE_BUILD COMMAND ${CMAKE_COMMAND} -E + copy "$" "${${TARGET}_FRAMEWORK_DIR}/lib${DEPEND_LIB}.dylib") + endforeach() + endif() + if(${TARGET}_PLUGINS) + set(${TARGET}_PLUGIN_DIR "$/../PlugIns") + foreach(PLUGIN IN LISTS ${TARGET}_PLUGINS) + set(${PLUGIN}_INSTALL_DIR "${${TARGET}_PLUGIN_DIR}/lib${PLUGIN}.dylib") + add_custom_command(TARGET ${TARGET} POST_BUILD COMMAND ${CMAKE_COMMAND} -E + copy "$" "${${PLUGIN}_INSTALL_DIR}") + endforeach() + endif() + else(BUILD_SHARED) # Static Build + list(APPEND ${TARGET}_LINK_LIBS ${${TARGET}_LIBS}) + list(APPEND ${TARGET}_LINK_LIBS ${${TARGET}_PLUGINS}) + target_link_libraries(${TARGET} ${${TARGET}_LINK_LIBS}) + endif(BUILD_SHARED) endfunction() +endif() - function(target_pack_plugins EXE_NAME) - set(${EXE_NAME}_PLUGIN_DIR $/../PlugIns) - foreach(PLUGIN IN LISTS ARGN) - set(${PLUGIN}_INSTALL_DIR "${${EXE_NAME}_PLUGIN_DIR}/lib${PLUGIN}.dylib") - add_custom_command(TARGET ${EXE_NAME} POST_BUILD COMMAND ${CMAKE_COMMAND} -E - copy "$" "${${PLUGIN}_INSTALL_DIR}") - endforeach() +if(IOS) + function(add_ios_app TARGET) + cmake_parse_arguments(${TARGET} + "" + "PDN;OS;LDPATH;ID" # product name, target OS, LD_RUNPATH_SEARCH_PATHS, bundle identifier + "SRCS;LIBS;PLUGINS" # sources, link libs + ${ARGN}) + add_executable(${TARGET} MACOSX_BUNDLE ${${TARGET}_SRCS}) + if(NOT ${TARGET}_ID) + set(${TARGET}_ID "com.tsinstudio.kaleido3d") + endif() + if(NOT ${TARGET}_PDN) + set(${TARGET}_PDN "${TARGET}") + endif() + execute_process( + COMMAND ${PLIST_GEN} -t app --be "${TARGET}" --bid "${${TARGET}_ID}" + --cr "\"Copyright 2016 Tsin Studio\"" --bn "${${TARGET}_ID}" --bdn "${${TARGET}_PDN}" + --outdir "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${TARGET}.dir") ## generate Info.plist + if(${TARGET}_LIBS) + target_link_libraries(${TARGET} ${${TARGET}_LIBS}) + if(BUILD_SHARED) + foreach(DEPEND_LIB IN LISTS ${TARGET}_LIBS) + if(NOT (${DEPEND_LIB} MATCHES "-framework")) + # Copy Dependency Libraries To XX.app/Frameworks + add_custom_command(TARGET ${TARGET} POST_BUILD COMMAND ${CMAKE_COMMAND} -E + copy_directory "$" "$/${DEPEND_LIB}.framework") + endif() + endforeach() + endif(BUILD_SHARED) + endif() + set_target_properties(${TARGET} PROPERTIES + XCODE_ATTRIBUTE_DEBUG_INFORMATION_FORMAT "dwarf-with-dsym" + XCODE_ATTRIBUTE_IPHONEOS_DEPLOYMENT_TARGET ${${TARGET}_OS} + XCODE_ATTRIBUTE_TARGETED_DEVICE_FAMILY "1" + XCODE_ATTRIBUTE_CLANG_ENABLE_OBJC_ARC YES + XCODE_ATTRIBUTE_COMBINE_HIDPI_IMAGES "NO" + XCODE_ATTRIBUTE_DEVELOPMENT_TEAM ${DEVELOPMENT_TEAM} + XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY ${CODE_SIGN_IDENTITY} + XCODE_ATTRIBUTE_PROVISIONING_STYLE Automatic + XCODE_ATTRIBUTE_ENABLE_BITCODE "NO" + MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${TARGET}.dir/Info.plist" + XCODE_ATTRIBUTE_LD_RUNPATH_SEARCH_PATHS "${${TARGET}_LDPATH}") endfunction() -endif() +endif(IOS) + +if(ANDROID) + function(add_android_app TARGET) + cmake_parse_arguments(${TARGET} + "" + "" + "SRCS;LIBS" # sources, link libs + ${ARGN}) + add_library(${TARGET} SHARED ${${TARGET}_SRCS}) + target_link_libraries(${TARGET} ${${TARGET}_LIBS}) + endfunction() +endif(ANDROID) macro(add_unittest EXAMPLE_NAME) if(ANDROID) - add_library(${EXAMPLE_NAME} SHARED ${ARGN} ../Platform/Android/jni/RendererView.cpp ../Platform/Android/jni/RendererView_JNI.cpp) + add_android_app(${EXAMPLE_NAME} + SRCS ${ARGN} ${Kaleido3D_SOURCE_DIR}/Platform/Android/jni/RendererView.cpp ${Kaleido3D_SOURCE_DIR}/Platform/Android/jni/RendererView_JNI.cpp + LIBS ${UT_LINK_LIBS}) elseif(WIN32) - add_executable(${EXAMPLE_NAME} ${ARGN} ../Platform/Windows/win32icon.rc) + add_executable(${EXAMPLE_NAME} ${ARGN} ${Kaleido3D_SOURCE_DIR}/Platform/Windows/win32icon.rc) + target_link_libraries(${EXAMPLE_NAME} ${UT_LINK_LIBS}) elseif(MACOS) - add_executable(${EXAMPLE_NAME} MACOSX_BUNDLE ${ARGN} ../Platform/Windows/win32icon.rc) - target_pack_depend_libraries(${EXAMPLE_NAME} Core Render ShaderCompiler) - target_pack_plugins(${EXAMPLE_NAME} RHI_Metal KawaLog) + add_mac_app(${EXAMPLE_NAME} + SRCS ${ARGN} + LIBS Core Engine Render + PLUGINS RHI_Metal KawaLog ShaderCompiler) + elseif(IOS) + add_ios_app(${EXAMPLE_NAME} + SRCS ${ARGN} "${Kaleido3D_SOURCE_DIR}/Platform/Apple/iOS/App.mm" + LIBS ${UT_LINK_LIBS} + PDN ${EXAMPLE_NAME} + OS 8.0 + LDPATH "@executable_path") else() add_executable(${EXAMPLE_NAME} ${ARGN}) endif() - target_link_libraries(${EXAMPLE_NAME} ${UNITTEST_DEPENDS}) set_target_properties(${EXAMPLE_NAME} PROPERTIES FOLDER "Unit Test") endmacro() diff --git a/Project/pch.cmake b/Project/Compiler.cmake old mode 100755 new mode 100644 similarity index 100% rename from Project/pch.cmake rename to Project/Compiler.cmake diff --git a/Project/FindThirdParty.cmake b/Project/FindThirdParty.cmake index ff2c63e..440c5c2 100755 --- a/Project/FindThirdParty.cmake +++ b/Project/FindThirdParty.cmake @@ -1,13 +1,31 @@ message("ThirdParty includes vulkan, rapidjson, glslang, spirv2cross, freetype2. ") -message("build config = ${CMAKE_SYSTEM_NAME}_${CMAKE_BUILD_TYPE}") - +set(GIT_THIRDPARTY_REPO "https://github.com/Tomicyo/kaleido3d_dep_prebuilt") if(WIN32) - set(ThirdParty_PREBUILT_DIR ${K3D_THIRD_PARTY}/Win64_${CMAKE_BUILD_TYPE}) + set(ThirdParty_PREBUILT_DIR ${K3D_THIRD_PARTY}/Win64/${CMAKE_BUILD_TYPE}) + if(NOT (EXISTS ${ThirdParty_PREBUILT_DIR})) + message(AUTHOR_WARNING "cloning ${ThirdParty_PREBUILT_DIR} from ${GIT_THIRDPARTY_REPO}") + execute_process(COMMAND git clone ${GIT_THIRDPARTY_REPO} -b win64_${CMAKE_BUILD_TYPE} ${ThirdParty_PREBUILT_DIR}) + endif() elseif(ANDROID) - set(ThirdParty_PREBUILT_DIR ${K3D_THIRD_PARTY}/Android_ARM_${CMAKE_BUILD_TYPE}) + set(ThirdParty_PREBUILT_DIR ${K3D_THIRD_PARTY}/Android/${ANDROID_ABI}/${ANDROID_STL}/${CMAKE_BUILD_TYPE}) + if(NOT (EXISTS ${ThirdParty_PREBUILT_DIR})) + message(AUTHOR_WARNING "cloning ${ThirdParty_PREBUILT_DIR} from ${GIT_THIRDPARTY_REPO}") + execute_process(COMMAND git clone ${GIT_THIRDPARTY_REPO} -b android_${ANDROID_ABI}_${ANDROID_STL}_${CMAKE_BUILD_TYPE} ${ThirdParty_PREBUILT_DIR}) + endif() elseif(MACOS) - set(ThirdParty_PREBUILT_DIR ${K3D_THIRD_PARTY}/MacOS_${CMAKE_BUILD_TYPE}) + set(ThirdParty_PREBUILT_DIR ${K3D_THIRD_PARTY}/MacOS/${CMAKE_BUILD_TYPE}) + if(NOT (EXISTS ${ThirdParty_PREBUILT_DIR})) + message(AUTHOR_WARNING "cloning ${ThirdParty_PREBUILT_DIR} from ${GIT_THIRDPARTY_REPO}") + execute_process(COMMAND git clone ${GIT_THIRDPARTY_REPO} -b macos_${CMAKE_BUILD_TYPE} ${ThirdParty_PREBUILT_DIR}) + endif() +elseif(IOS) + set(ThirdParty_PREBUILT_DIR ${K3D_THIRD_PARTY}/iOS/${CMAKE_BUILD_TYPE}) + if(NOT (EXISTS ${ThirdParty_PREBUILT_DIR})) + message(AUTHOR_WARNING "cloning ${ThirdParty_PREBUILT_DIR} from ${GIT_THIRDPARTY_REPO}") + execute_process(COMMAND git clone ${GIT_THIRDPARTY_REPO} -b ios_${CMAKE_BUILD_TYPE} ${ThirdParty_PREBUILT_DIR}) + endif() endif() +message(STATUS "** 3rd party ** ${ThirdParty_PREBUILT_DIR}") unset(THIRDPARTY_FOUND CACHE) @@ -17,19 +35,33 @@ unset(GLSLANG_INCLUDE_DIR CACHE) unset(SPIRV2CROSS_INCLUDE_DIR CACHE) unset(FREETYPE2_INCLUDE_DIR CACHE) -set(FREETYPE2_LIBRARY freetyped) +set(FREETYPE2_LIBRARY freetype) set(GLSLANG_LIBRARIES glslang HLSL OGLCompiler OSDependent SPIRV SPVRemapper) -set(SPIRV2CROSS_LIBRARY Spirv2Cross) +set(SPIRV2CROSS_LIBRARY spirv-cross-core spirv-cross-msl spirv-cross-glsl) if(WIN32) unset(DXSDK_INCLUDE_DIR CACHE) endif() +if(WIN32 OR ANDROID) find_path(VULKANSDK_INCLUDE_DIR vulkan/vulkan.h PATH_SUFFIXES include PATHS ${ThirdParty_PREBUILT_DIR} ) +endif() + +if(WIN32) +find_library(VULKAN_LIB vulkan-1 + PATH_SUFFIXES lib/x64 + PATHS ${ThirdParty_PREBUILT_DIR}) +message(STATUS "** Vulkan \(Windows\) ** ${VULKAN_LIB}") +elseif(ANDROID) +find_library(VULKAN_LIB vulkan + PATH_SUFFIXES platforms/android-24/arch-${ANDROID_SYSROOT_ABI}/usr/lib + PATHS $ENV{ANDROID_NDK}) +message(STATUS "** Vulkan Lib \(Android\) ** ${VULKAN_LIB}") +endif() find_path(RAPIDJSON_INCLUDE_DIR rapidjson/rapidjson.h @@ -50,11 +82,55 @@ find_path(SPIRV2CROSS_INCLUDE_DIR ) find_path(FREETYPE2_INCLUDE_DIR - freetype2/ft2build.h - PATH_SUFFIXES include + ft2build.h + PATH_SUFFIXES include/freetype2 PATHS ${ThirdParty_PREBUILT_DIR} ) +find_library(FREETYPE2_LIBRARY + NAMES freetype + HINTS + $ENV{FREETYPE2_DIR} + PATH_SUFFIXES lib + PATHS + ${ThirdParty_PREBUILT_DIR} +) + +if(FREETYPE2_LIBRARY) +# Find dependencies + foreach (d ZLIB BZip2 PNG HarfBuzz) + string(TOUPPER "${d}" D) + + if (DEFINED WITH_${d} OR DEFINED WITH_${D}) + if (WITH_${d} OR WITH_${D}) + find_package(${d} QUIET REQUIRED) + endif () + else () + find_package(${d} QUIET) + endif () + + if (${d}_FOUND OR ${D}_FOUND) + message(STATUS "link FreeType with ${d}") + endif () + endforeach () + + include_directories(${FREETYPE2_INCLUDE_DIR}) + set(HAS_FREETYPE true) + + if (ZLIB_FOUND) + list(APPEND FREETYPE2_LIBRARY ${ZLIB_LIBRARIES}) + endif () + if (BZIP2_FOUND) + list(APPEND FREETYPE2_LIBRARY ${BZIP2_LIBRARIES}) + endif () + if (PNG_FOUND) + list(APPEND FREETYPE2_LIBRARY ${PNG_LIBRARIES}) + endif () + if (HARFBUZZ_FOUND) + list(APPEND FREETYPE2_LIBRARY ${HARFBUZZ_LIBRARIES}) + endif () +endif() + message("GLSLang = ${GLSLANG_INCLUDE_DIR}") if(WIN32) @@ -84,6 +160,7 @@ link_directories(${ThirdParty_PREBUILT_DIR}/lib) include(FindPackageHandleStandardArgs) +if(WIN32 OR ANDROID) find_package_handle_standard_args(ThirdParty DEFAULT_MSG VULKANSDK_INCLUDE_DIR RAPIDJSON_INCLUDE_DIR @@ -91,11 +168,24 @@ find_package_handle_standard_args(ThirdParty DEFAULT_MSG SPIRV2CROSS_INCLUDE_DIR FREETYPE2_INCLUDE_DIR ) - mark_as_advanced( VULKANSDK_INCLUDE_DIR RAPIDJSON_INCLUDE_DIR GLSLANG_INCLUDE_DIR SPIRV2CROSS_INCLUDE_DIR FREETYPE2_INCLUDE_DIR -) \ No newline at end of file +) +elseif(IOS OR MACOS) +find_package_handle_standard_args(ThirdParty DEFAULT_MSG + RAPIDJSON_INCLUDE_DIR + GLSLANG_INCLUDE_DIR + SPIRV2CROSS_INCLUDE_DIR + FREETYPE2_INCLUDE_DIR +) +mark_as_advanced( + RAPIDJSON_INCLUDE_DIR + GLSLANG_INCLUDE_DIR + SPIRV2CROSS_INCLUDE_DIR + FREETYPE2_INCLUDE_DIR +) +endif() \ No newline at end of file diff --git a/Project/NDKStlConfig.cmake b/Project/NDKStlConfig.cmake index 46b84d0..4dc9fda 100755 --- a/Project/NDKStlConfig.cmake +++ b/Project/NDKStlConfig.cmake @@ -7,13 +7,13 @@ # or # # find_package(ndk-stl REQUIRED PATHS ".") +if(ANDROID) if(NOT ${ANDROID_STL} MATCHES "_shared") return() endif() function(configure_shared_stl lib_path so_base) - message("Configuring STL ${so_base} for ${ANDROID_ABI}") configure_file( "${ANDROID_NDK}/sources/cxx-stl/${lib_path}/libs/${ANDROID_ABI}/lib${so_base}.so" "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/lib${so_base}.so" @@ -36,4 +36,6 @@ elseif("${ANDROID_STL}" STREQUAL "c++_shared") configure_shared_stl("llvm-libc++" "c++_shared") else() message(FATAL_ERROR "STL configuration ANDROID_STL=${ANDROID_STL} is not supported") -endif() \ No newline at end of file +endif() + +endif(ANDROID) \ No newline at end of file diff --git a/Project/Platform.cmake b/Project/Platform.cmake index 2f83a5f..58f2328 100755 --- a/Project/Platform.cmake +++ b/Project/Platform.cmake @@ -1,13 +1,24 @@ if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") - set(CMAKE_CXX_FLAGS "-x objective-c++ ${CMAKE_CXX_FLAGS}") + set(CMAKE_CXX_FLAGS "-fno-objc-arc -x objective-c++ ${CMAKE_CXX_FLAGS}") if(IOS) add_definitions(-DK3DPLATFORM_OS_IOS=1) + set(K3D_TARGET_SYSTEM "iOS") else() set(MACOS TRUE) add_definitions(-DK3DPLATFORM_OS_MAC=1) - + set(K3D_TARGET_SYSTEM "MacOS") set(MACOSX_BUNDLE_INFO_STRING "${PROJECT_NAME}") set(MACOSX_BUNDLE_GUI_IDENTIFIER "com.tsinstudio.kaleido3d") set(MACOSX_BUNDLE_COPYRIGHT "Copyright Tsin Studio 2016. All Rights Reserved.") endif() endif() + +if(WIN32) + set(K3D_TARGET_SYSTEM "Windows") +endif(WIN32) + +if(ANDROID) # Android will above vars + set(K3D_TARGET_SYSTEM "Android") +endif(ANDROID) + +message(STATUS "Host System = ${CMAKE_SYSTEM_NAME}, Target System = ${K3D_TARGET_SYSTEM}") \ No newline at end of file diff --git a/Project/Util.cmake b/Project/Util.cmake new file mode 100644 index 0000000..ecadef8 --- /dev/null +++ b/Project/Util.cmake @@ -0,0 +1,45 @@ +if(NOT WIN32) + string(ASCII 27 Esc) + set(ColourReset "${Esc}[m") + set(ColourBold "${Esc}[1m") + set(Red "${Esc}[31m") + set(Green "${Esc}[32m") + set(Yellow "${Esc}[33m") + set(Blue "${Esc}[34m") + set(Magenta "${Esc}[35m") + set(Cyan "${Esc}[36m") + set(White "${Esc}[37m") + set(BoldRed "${Esc}[1;31m") + set(BoldGreen "${Esc}[1;32m") + set(BoldYellow "${Esc}[1;33m") + set(BoldBlue "${Esc}[1;34m") + set(BoldMagenta "${Esc}[1;35m") + set(BoldCyan "${Esc}[1;36m") + set(BoldWhite "${Esc}[1;37m") +endif() + +function(message) + list(GET ARGV 0 MessageType) + if(MessageType STREQUAL FATAL_ERROR OR MessageType STREQUAL SEND_ERROR) + list(REMOVE_AT ARGV 0) + _message(${MessageType} "${BoldRed}${ARGV}${ColourReset}") + elseif(MessageType STREQUAL WARNING) + list(REMOVE_AT ARGV 0) + _message(${MessageType} "${BoldYellow}${ARGV}${ColourReset}") + elseif(MessageType STREQUAL AUTHOR_WARNING) + list(REMOVE_AT ARGV 0) + _message(${MessageType} "${BoldCyan}${ARGV}${ColourReset}") + elseif(MessageType STREQUAL STATUS) + list(REMOVE_AT ARGV 0) + _message(${MessageType} "${Green}${ARGV}${ColourReset}") + else() + _message("${ARGV}") + endif() +endfunction() + +#message("No colour at all.") +#message(STATUS "\"Colour\" is spelled correctly.") +#message(AUTHOR_WARNING "\"Color\" is misspelled.") +#message(WARNING "Final warning: spell \"color\" correctly.") +#message(SEND_ERROR "Game over. It's \"colour\", not \"color\".") +#message(FATAL_ERROR "And there's no \"z\" in \"colourise\" either.") \ No newline at end of file diff --git a/Project/build.gradle b/Project/build.gradle index c90d529..b7366a6 100755 --- a/Project/build.gradle +++ b/Project/build.gradle @@ -23,7 +23,7 @@ android { } ndk { - abiFilters 'armeabi-v7a' + abiFilters 'arm64-v8a' } } diff --git a/Project/iOS.cmake b/Project/iOS.cmake index 6b6106d..788d1ad 100755 --- a/Project/iOS.cmake +++ b/Project/iOS.cmake @@ -1,35 +1,3 @@ - -# This file is based off of the Platform/Darwin.cmake and Platform/UnixPaths.cmake -# files which are included with CMake 2.8.4 -# It has been altered for iOS development - -# Options: -# -# IOS_PLATFORM = OS (default) or SIMULATOR -# This decides if SDKS will be selected from the iPhoneOS.platform or iPhoneSimulator.platform folders -# OS - the default, used to build for iPhone and iPad physical devices, which have an arm arch. -# SIMULATOR - used to build for the Simulator platforms, which have an x86 arch. -# -# CMAKE_IOS_DEVELOPER_ROOT = automatic(default) or /path/to/platform/Developer folder -# By default this location is automatcially chosen based on the IOS_PLATFORM value above. -# If set manually, it will override the default location and force the user of a particular Developer Platform -# -# CMAKE_IOS_SDK_ROOT = automatic(default) or /path/to/platform/Developer/SDKs/SDK folder -# By default this location is automatcially chosen based on the CMAKE_IOS_DEVELOPER_ROOT value. -# In this case it will always be the most up-to-date SDK found in the CMAKE_IOS_DEVELOPER_ROOT path. -# If set manually, this will force the use of a specific SDK version - -# Macros: -# -# set_xcode_property (TARGET XCODE_PROPERTY XCODE_VALUE) -# A convenience macro for setting xcode specific properties on targets -# example: set_xcode_property (myioslib IPHONEOS_DEPLOYMENT_TARGET "3.1") -# -# find_host_package (PROGRAM ARGS) -# A macro used to find executable programs on the host system, not within the iOS environment. -# Thanks to the android-cmake project for providing the command - -# Standard settings set (CMAKE_SYSTEM_NAME Darwin) set (CMAKE_SYSTEM_VERSION 1) set (UNIX True) @@ -46,10 +14,10 @@ if (CMAKE_UNAME) string (REGEX REPLACE "^([0-9]+)\\.([0-9]+).*$" "\\1" DARWIN_MAJOR_VERSION "${CMAKE_HOST_SYSTEM_VERSION}") endif (CMAKE_UNAME) -# Force the compilers to gcc for iOS +# Force the compilers to Clang for iOS include (CMakeForceCompiler) -CMAKE_FORCE_C_COMPILER (/usr/bin/clang Apple) -CMAKE_FORCE_CXX_COMPILER (/usr/bin/clang++ Apple) +set(CMAKE_C_COMPILER /usr/bin/clang Clang) +set(CMAKE_CXX_COMPILER /usr/bin/clang++ Clang) set(CMAKE_AR ar CACHE FILEPATH "" FORCE) # Skip the platform compiler checks for cross compiling @@ -63,6 +31,7 @@ set (CMAKE_SHARED_MODULE_PREFIX "lib") set (CMAKE_SHARED_MODULE_SUFFIX ".so") set (CMAKE_MODULE_EXISTS 1) set (CMAKE_DL_LIBS "") +set (CMAKE_SYSTEM_PROCESSOR "A10") set (CMAKE_C_OSX_COMPATIBILITY_VERSION_FLAG "-compatibility_version ") set (CMAKE_C_OSX_CURRENT_VERSION_FLAG "-current_version ") @@ -71,7 +40,7 @@ set (CMAKE_CXX_OSX_CURRENT_VERSION_FLAG "${CMAKE_C_OSX_CURRENT_VERSION_FLAG}") # Hidden visibilty is required for cxx on iOS set (CMAKE_C_FLAGS_INIT "") -set (CMAKE_CXX_FLAGS_INIT "-fvisibility=hidden -fvisibility-inlines-hidden -isysroot ${CMAKE_OSX_SYSROOT}") +set (CMAKE_CXX_FLAGS_INIT "-fvisibility=hidden -fvisibility-inlines-hidden") set (CMAKE_C_LINK_FLAGS "-Wl,-search_paths_first ${CMAKE_C_LINK_FLAGS}") set (CMAKE_CXX_LINK_FLAGS "-Wl,-search_paths_first ${CMAKE_CXX_LINK_FLAGS}") @@ -97,6 +66,12 @@ if (NOT DEFINED IOS_PLATFORM) endif (NOT DEFINED IOS_PLATFORM) set (IOS_PLATFORM ${IOS_PLATFORM} CACHE STRING "Type of iOS Platform") +# Setup building for arm64 or not +if (NOT DEFINED BUILD_ARM64) + set (BUILD_ARM64 true) +endif (NOT DEFINED BUILD_ARM64) +set (BUILD_ARM64 ${BUILD_ARM64} CACHE STRING "Build arm64 arch or not") + # Check the platform selection and setup for developer root if (${IOS_PLATFORM} STREQUAL "OS") set (IOS_PLATFORM_LOCATION "iPhoneOS.platform") @@ -104,6 +79,13 @@ if (${IOS_PLATFORM} STREQUAL "OS") # This causes the installers to properly locate the output libraries set (CMAKE_XCODE_EFFECTIVE_PLATFORMS "-iphoneos") elseif (${IOS_PLATFORM} STREQUAL "SIMULATOR") + set (SIMULATOR true) + set (IOS_PLATFORM_LOCATION "iPhoneSimulator.platform") + + # This causes the installers to properly locate the output libraries + set (CMAKE_XCODE_EFFECTIVE_PLATFORMS "-iphonesimulator") +elseif (${IOS_PLATFORM} STREQUAL "SIMULATOR64") + set (SIMULATOR true) set (IOS_PLATFORM_LOCATION "iPhoneSimulator.platform") # This causes the installers to properly locate the output libraries @@ -143,11 +125,12 @@ set (CMAKE_IOS_SDK_ROOT ${CMAKE_IOS_SDK_ROOT} CACHE PATH "Location of the select set (CMAKE_OSX_SYSROOT ${CMAKE_IOS_SDK_ROOT} CACHE PATH "Sysroot used for iOS support") # set the architecture for iOS -# NOTE: Currently both ARCHS_STANDARD_32_BIT and ARCHS_UNIVERSAL_IPHONE_OS set armv7 only, so set both manually if (${IOS_PLATFORM} STREQUAL "OS") - set (IOS_ARCH armv6 armv7) -else (${IOS_PLATFORM} STREQUAL "OS") - set (IOS_ARCH i386) + set (IOS_ARCH armv7 armv7s arm64) +elseif (${IOS_PLATFORM} STREQUAL "SIMULATOR") + set (IOS_ARCH i386) +elseif (${IOS_PLATFORM} STREQUAL "SIMULATOR64") + set (IOS_ARCH x86_64) endif (${IOS_PLATFORM} STREQUAL "OS") set (CMAKE_OSX_ARCHITECTURES ${IOS_ARCH} CACHE string "Build architecture for iOS") @@ -190,4 +173,4 @@ macro (find_host_package) set (CMAKE_FIND_ROOT_PATH_MODE_PROGRAM ONLY) set (CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) set (CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) -endmacro (find_host_package) \ No newline at end of file +endmacro (find_host_package) diff --git a/Project/plist_gen b/Project/plist_gen new file mode 100755 index 0000000..cc46b87 Binary files /dev/null and b/Project/plist_gen differ diff --git a/README.md b/README.md index 32a4feb..aff0f50 100755 --- a/README.md +++ b/README.md @@ -1,12 +1,13 @@ Introduction ========= +**kaleido3d** is a cross-platform graphics library. > **Main Feature** > >* `Next Generation Graphics Library` ->* Modern C++ Code (**`C++ 11`**) ->* Modern Graphics Renderer (`Metal`, `Vulkan`, `Direct3D 12`) +>* Modern C++ Code +>* Modern Graphics Renderer (`Metal`, `Vulkan`, `Direct3D 12`, `OpenGL|ES`) >* **`Maya`** Digital Content Creation Tools >* **Task-Oriented**, support `multi-thread` rendering >* Support Windows, Android, iOS, MacOS & Linux. @@ -22,7 +23,7 @@ Prerequisites |CI Status|[![Build status](https://ci.appveyor.com/api/projects/status/bkqv6wbtyr4538hf?svg=true)](https://ci.appveyor.com/project/TsinStudio/kaleido3d)|[![Circle CI](https://circleci.com/gh/TsinStudio/kaleido3d.svg?style=svg)](https://circleci.com/gh/TsinStudio/kaleido3d) |[![Build Status](https://travis-ci.org/TsinStudio/kaleido3d.svg?branch=master)](https://travis-ci.org/TsinStudio/kaleido3d)| |IDE| VS2015+ | Android Studio 2.2+| Xcode 8.1+ | |OS Requirements| Win10 | Android 7.+| MacOS Sierra | -|Dependency| [ThirdParty][8]/CMake 3.4+ | [ThirdParty][8]/NDK r12+/Gradle | [ThirdParty][8]/CMake 3.4+ | +|Dependency| [ThirdParty](https://github.com/Tomicyo/kaleido3d_dep)/CMake 3.4+ | [ThirdParty](https://github.com/Tomicyo/kaleido3d_dep)/NDK r12+/Gradle | [ThirdParty](https://github.com/Tomicyo/kaleido3d_dep)/CMake 3.4+ | ---------- @@ -41,14 +42,14 @@ Current Status - RHI(Render Hardware Interface) * [x] Vulkan backend **ready**. - * [ ] DirectX 12 backend **WIP** - * [ ] Metal backend **WIP** + * [x] DirectX 12 backend **WIP** + * [x] Metal backend **WIP** - Core.Platform * [x] Windows implementation ready. * [x] Android RendererView. - * [ ] iOS/MacOS not initialized. + * [x] iOS/MacOS **WIP**. - Tools @@ -57,15 +58,18 @@ Current Status - Planned Samples - * [x] Triangle(vk) - * [x] Textured Cube - * [ ] Compute Shader - * [ ] Shadow Mapping - * [ ] Physically Based Shading - * [ ] Deferred Shading - * [ ] Multi-thread Rendering + * [x] Triangle + * [x] Textured Cube + * [x] Compute Shader (WIP) + * [ ] Physically Based Shading (Material Model) + * [ ] Skinned Skeleton Animation + * [ ] Shadow Mapping (Render To Texture, Z-Pass) + * [ ] Deferred Shading (Multi-RenderTarget) + * [ ] Tile-Based Cluster Lighting (Compute Shading) + * [ ] Multi-Thread Rendering * [ ] Multi-GPU/CrossAdapter Rendering - * [ ] Cross Shader Language Compiler + * [x] Cross Shader Language Compiler + * [ ] Hand-writing Recognition CNN Sample (GPGPU) --- @@ -90,6 +94,7 @@ Documents * [rapidJson][3] * [glslang][7] * [spir2cross][10] + * [freetype][11] * DXSDK @@ -144,14 +149,16 @@ Samples Contact ========= -> If you have any suggestion, please contact me via [**email**](mailto:dsotsen@gmail.com). + +If you have any suggestion, please contact me via [**email**][12] . + Discuss [![Join the chat at https://gitter.im/TsinStudio/kaleido3d](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/TsinStudio/kaleido3d?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) ========= -Please join the [gitter chat](https://gitter.im/TsinStudio/kaleido3d) to discuss on this project. +Please join the [gitter chat](https://gitter.im/TsinStudio/kaleido3d) or [QQ Group][13] to discuss on this project. Framework development discussions and thorough bug reports are collected on [Issues](https://github.com/TsinStudio/kaleido3d/issues). @@ -166,3 +173,6 @@ Framework development discussions and thorough bug reports are collected on [Iss [8]: https://github.com/Tomicyo/kaleido3d_dep [9]: https://vulkan.lunarg.com/ [10]: https://github.com/KhronosGroup/SPIRV-Cross +[11]: https://www.freetype.org +[12]: mailto:dsotsen@gmail.com +[13]: https://jq.qq.com/?_wv=1027&k=45tL869 diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt index 3636d67..85ec33d 100755 --- a/Source/CMakeLists.txt +++ b/Source/CMakeLists.txt @@ -6,23 +6,25 @@ if(POLICY CMP0054) endif() set(Kaleido3D_ROOT_DIR "${Kaleido3D_SOURCE_DIR}/..") +set(K3D_THIRD_PARTY "${Kaleido3D_SOURCE_DIR}/ThirdParty_Prebuilt") set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${Kaleido3D_SOURCE_DIR}/../Project") +set(CMAKE_FIND_ROOT_PATH "${K3D_THIRD_PARTY};${CMAKE_FIND_ROOT_PATH}") set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${Kaleido3D_ROOT_DIR}/Binary/") -#set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${Kaleido3D_ROOT_DIR}/Binary/") -set(K3D_THIRD_PARTY "${Kaleido3D_ROOT_DIR}/Source/ThirdParty_Prebuilt") -include(${Kaleido3D_ROOT_DIR}/Project/Platform.cmake) -include(${Kaleido3D_ROOT_DIR}/Project/FindThirdParty.cmake) +include(Util) +include(Platform) +include(Compiler) +include(Common) +include(NDKStlConfig) find_package(ThirdParty) option(BUILD_SHARED "Build runtime library as shared libs" ON) -option(BUILD_WITH_TBB "Build With Intel ThreadingBlocks" OFF) option(BUILD_WITH_EDITOR "Build With Editor" OFF) option(BUILD_WITH_D3D12 "Build With D3D12 RHI" OFF) option(BUILD_WITH_V8 "Build With V8 Script Module" OFF) - -include(${Kaleido3D_ROOT_DIR}/Project/Common.cmake) +option(BUILD_WITH_UNIT_TEST "Build With Unit Test" ON) +option(ENABLE_SHAREDPTR_TRACK "Enable SharedPtr Track" ON) if(IOS OR MACOS) set(LIB_DIR @loader_path/../Frameworks) @@ -35,13 +37,16 @@ set(LIB_TYPE STATIC) if(BUILD_SHARED) add_definitions(-DLIB_BUILD) add_definitions(-DBUILD_SHARED_CORE) + add_definitions(-DBUILD_STATIC_PLUGIN=0) set(LIB_TYPE SHARED) - message("----- All runtime lib will be built as shared library. \n\tLIB_BUILD defines,\n\tBUILD_SHARED_CORE defines") + message("----- All runtime lib will be built as shared library. \n\t${Yellow}LIB_BUILD${ColourReset} defines,\n\t${Red}BUILD_SHARED_CORE${ColourReset} defines") +else() + add_definitions(-DBUILD_STATIC_PLUGIN=1) + message("----- All runtime lib will be built as static library. \n\t${Yellow}BUILD_STATIC_PLUGIN=1${ColourReset}") endif() -if(BUILD_WITH_TBB) - add_definitions(-DUSE_TBB_MALLOC) - include_directories(${TBB_INCLUDE_DIR}) +if(ENABLE_SHAREDPTR_TRACK) + add_definitions(-DENABLE_SHAREDPTR_TRACKER=1) endif() message(STATUS "compiler is ${CMAKE_CXX_COMPILER_ID}" ) @@ -90,12 +95,7 @@ include_directories( ../Include ) -include(${Kaleido3D_ROOT_DIR}/Project/pch.cmake) - if(ANDROID) - include(${Kaleido3D_ROOT_DIR}/Project/NDKStlConfig.cmake) - include(${Kaleido3D_ROOT_DIR}/Project/FindVulkanSDK.cmake) - find_package(VulkanSDK) if(VULKANSDK_FOUND) add_definitions(-DUSEVULKANSDK) include_directories(${VULKANSDK_INCLUDE_DIR}) @@ -103,29 +103,14 @@ if(ANDROID) endif() if(WIN32) - set(TBB_INSTALL_DIR ${K3D_THIRD_PARTY}/tbb43_20150424) - #include(${Kaleido3D_ROOT_DIR}/Project/FindVulkanSDK.cmake) - include(${Kaleido3D_ROOT_DIR}/Project/FindMaya.cmake) - #include(${Kaleido3D_ROOT_DIR}/Project/FindTBB.cmake) - #include(${Kaleido3D_ROOT_DIR}/Project/FindDXSDK.cmake) - #include(${Kaleido3D_ROOT_DIR}/Project/FindV8.cmake) - #include(${Kaleido3D_ROOT_DIR}/Project/FindLua.cmake) - #include(${Kaleido3D_ROOT_DIR}/Project/FindFreeType.cmake) find_package(OpenGL) find_package(Maya) - #find_package(TBB) - #find_package(V8) - #find_package(Lua) - #find_package(DXSDK) - #find_package(FreeType) - #find_package(VulkanSDK) if(VULKANSDK_FOUND) include_directories(${VULKANSDK_INCLUDE_DIR}) endif() endif() if(MACOS) - include(${Kaleido3D_ROOT_DIR}/Project/FindMaya.cmake) find_package(Maya) endif() @@ -146,13 +131,6 @@ if(MAYA_FOUND) endif() add_subdirectory(Tools/ShaderGen) -#add_subdirectory(ThirdParty/glslang) -#add_subdirectory(ThirdParty/spir2cross) - -#add_subdirectory(ThirdParty/EASTL) - -add_subdirectory(UnitTest) -#add_subdirectory(Example) if(BUILD_WITH_EDITOR) set(CMAKE_AUTOMOC ON) @@ -162,5 +140,3 @@ if(BUILD_WITH_EDITOR) find_package(Qt5 COMPONENTS Core Widgets REQUIRED) add_subdirectory(Tools/Editor) endif() - -#file(copy ${K3D_THIRD_PARTY}/v8-5.5.1/vs2015/debug_x64/* DESTINATION Binary/Debug) diff --git a/Source/Core/App.cpp b/Source/Core/App.cpp index 1a1cfcb..9e89e08 100755 --- a/Source/Core/App.cpp +++ b/Source/Core/App.cpp @@ -1,6 +1,7 @@ #include "Kaleido3D.h" #include "App.h" #include "Message.h" +#include "LogUtil.h" namespace k3d { @@ -41,6 +42,7 @@ namespace k3d void App::OnDestroy() { + KLOG(Info, App, "Super::OnDestroy.."); } AppStatus App::Run() { @@ -222,6 +224,9 @@ namespace k3d lEnvVars[Environment::ENV_KEY_APP_NAME] = exeFilePath.substr(0, nPos - 4); } lEnvVars[Environment::ENV_KEY_LOG_DIR] = lEnvVars[Environment::ENV_KEY_MODULE_DIR]; +#elif K3DPLATFORM_OS_IOS + lEnvVars[Environment::ENV_KEY_MODULE_DIR] = KT("./"); + //lEnvVars[Environment::ENV_KEY_LOG_DIR] = KT("./"); #endif } diff --git a/Source/Core/App.h b/Source/Core/App.h index 2cd900e..076819e 100755 --- a/Source/Core/App.h +++ b/Source/Core/App.h @@ -114,6 +114,26 @@ namespace k3d className app(#className); \ return ::k3d::RunApplication(app, #className); \ } +#elif K3DPLATFORM_OS_IOS +#import +@interface AppDelegate : UIResponder +{ + k3d::App * m_App; +} +@end + +k3d::App * __entry_ios_main__(); + +#define K3D_APP_MAIN(className) \ +int main(int argc, char *argv[]) \ +{\ +@autoreleasepool {\ + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));\ +}}\ +k3d::App * __entry_ios_main__()\ +{\ +return new className(#className);\ +} #elif K3DPLATFORM_OS_WIN #define K3D_APP_MAIN(className) \ diff --git a/Source/Core/Archive.cpp b/Source/Core/Archive.cpp deleted file mode 100755 index 69a924b..0000000 --- a/Source/Core/Archive.cpp +++ /dev/null @@ -1,38 +0,0 @@ -#include "Kaleido3D.h" -#include "Archive.h" - - -#if 0 -kMemoryArchiveReader::kMemoryArchiveReader(const kByte *data) -{ - -} - -kMemoryArchiveReader::~kMemoryArchiveReader() -{ - -} - - -kMemoryArchiveWriter::kMemoryArchiveWriter(kByte *data, int dataLen) - : m_DataArchive(nullptr) - , m_DataLength(0) -{ - m_DataArchive = data; - m_DataLength = dataLen; -} - -kMemoryArchiveWriter::~kMemoryArchiveWriter() -{ - if(m_DataArchive) { - ::free(data); - m_DataArchive = nullptr; - m_DataLength = 0; - } -} - -void kMemoryArchiveWriter::WriteToFile(const char *fileName) -{ - assert( fileName && m_DataArchive && m_DataLength > 0); -} -#endif diff --git a/Source/Core/Archive.h b/Source/Core/Archive.h deleted file mode 100755 index e6194c4..0000000 --- a/Source/Core/Archive.h +++ /dev/null @@ -1,70 +0,0 @@ -#pragma once - -#include -#include -#include -#include - -#define ARCHIVEEXTENSION ".k3darch"; - -namespace k3d -{ - enum ArchiveVersion - { - VER_2014_4 = 0x201404 - }; - - struct ArchHeader - { - uint32 Version; - }; - - enum ArchiveChunkType - { - CHUNK_MESH, - CHUNK_PHYSICPROXY, - CHUNK_MATERIAL, - CHUNK_SHADER, - CHUNK_GLFX, - CHUNK_TEXTURE, - CHUNK_TERRIAN, - CHUNK_JSON, - CHUNK_UNKNOWN - }; - - struct ArchClassChunk { - char ClassName[64]; - uint32 ClassInternalSize; - }; - - struct ArchChunkTag - { - uint32 ChunkType; - uint32 ChunkSize; - }; -} - - -#if 0 -class kMemoryArchiveReader : public Archive { -public: - explicit kMemoryArchiveReader(const kByte *data); - virtual ~kMemoryArchiveReader(); - -private: - kByte *m_DataArchive; -}; - - -class kMemoryArchiveWriter : public Archive { -public: - explicit kMemoryArchiveWriter(kByte *data, int dataLen); - virtual ~kMemoryArchiveWriter(); - - void WriteToFile(const char * fileName); - -private: - uint32 m_DataLength; - kByte* m_DataArchive; -}; -#endif diff --git a/Source/Core/AssetManager.cpp b/Source/Core/AssetManager.cpp index 41e506f..b9816ce 100755 --- a/Source/Core/AssetManager.cpp +++ b/Source/Core/AssetManager.cpp @@ -4,7 +4,6 @@ #include "Core/LogUtil.h" #include "ImageData.h" #include "App.h" -#include "Variant.h" #include "ObjectMesh.h" #ifdef USE_TBB_MALLOC diff --git a/Source/Core/AssetManager.h b/Source/Core/AssetManager.h index 4646b07..43cf9d1 100755 --- a/Source/Core/AssetManager.h +++ b/Source/Core/AssetManager.h @@ -4,11 +4,12 @@ #include #include -#include + +#include "MeshData.h" + #include #include - namespace k3d { class ImageData; diff --git a/Source/Core/Bundle.cpp b/Source/Core/Bundle.cpp index 10dd24b..7115ad9 100755 --- a/Source/Core/Bundle.cpp +++ b/Source/Core/Bundle.cpp @@ -3,7 +3,6 @@ #include "MeshData.h" #include "CameraData.h" #include "ImageData.h" -#include "Archive.h" #include "Os.h" #include "LogUtil.h" #include "Utils/StringUtils.h" diff --git a/Source/Core/Bundle.h b/Source/Core/Bundle.h index 1bcb35f..dfa2e2b 100755 --- a/Source/Core/Bundle.h +++ b/Source/Core/Bundle.h @@ -1,5 +1,7 @@ #pragma once +#include + namespace k3d { enum class EAssetVersion : uint64 diff --git a/Source/Core/CMakeLists.txt b/Source/Core/CMakeLists.txt index 9f734ac..937a75e 100755 --- a/Source/Core/CMakeLists.txt +++ b/Source/Core/CMakeLists.txt @@ -1,8 +1,6 @@ include_directories(.. ../../Include) -add_definitions(-DBUILD_SHARED_LIB) - -set(SRC_ASSETMANAGER AssetManager.h AssetManager.cpp Bundle.h Bundle.cpp Archive.h Archive.cpp) +set(SRC_ASSETMANAGER AssetManager.h AssetManager.cpp Bundle.h Bundle.cpp) set(SRC_CAMERA CameraData.h CameraData.cpp) set(SRC_MESH MeshData.h MeshData.cpp ObjectMesh.h ObjectMesh.cpp RiggedMeshData.h RiggedMeshData.cpp) set(SRC_IMAGE ImageData.h ImageData.cpp) @@ -57,7 +55,6 @@ source_group("XPlatform\\Message" FILES ${MSG_SRCS}) set(COMMON_SRCS Timer.h Timer.cpp - Variant.h Os.h Os.cpp WebSocket.h @@ -68,8 +65,7 @@ set(COMMON_SRCS App.h App.cpp AllocatorImpl.cpp - String.h - String.cpp + StringImpl.cpp ) source_group(XPlatform FILES ${COMMON_SRCS}) @@ -85,27 +81,66 @@ elseif(ANDROID) file(GLOB ANDROID_SRCS "../Platform/Android/cpp/*.cpp" "../Platform/Android/cpp/*.h") source_group("XPlatform\\Android" FILES ${ANDROID_SRCS}) set(CORE_SRCS ${CORE_SRCS} ${ANDROID_SRCS}) + list(APPEND CORE_DEP_LIBS log android) elseif(IOS) - file(GLOB IOS_IMPL_SRCS "iOS/*.h" "iOS/*.mm") + #file(GLOB IOS_IMPL_SRCS "../Platform/Apple/iOS/*.mm" "../Platform/Apple/iOS/*.h") + set(IOS_IMPL_SRCS "../Platform/Apple/iOS/Window.mm" "../Platform/Apple/CpuUsage.mm") source_group("XPlatform\\iOS" FILES ${IOS_IMPL_SRCS}) set(CORE_SRCS ${CORE_SRCS} ${IOS_IMPL_SRCS}) + list(APPEND CORE_DEP_LIBS "-framework Foundation" "-framework UIKit" "-framework QuartzCore") elseif(MACOS) file(GLOB OSX_IMPL_SRCS "../Platform/Apple/MacOS/*.mm" "../Platform/Apple/MacOS/*.h") + list(APPEND OSX_IMPL_SRCS "../Platform/Apple/CpuUsage.mm") source_group("XPlatform\\OSX" FILES ${OSX_IMPL_SRCS}) set(CORE_SRCS ${CORE_SRCS} ${OSX_IMPL_SRCS}) + list(APPEND CORE_DEP_LIBS "-framework Cocoa" "-framework AppKit" "-framework QuartzCore" "-framework CoreData" "-framework Foundation") endif() -add_library(Core ${LIB_TYPE} ${CORE_SRCS}) +k3d_add_lib(Core SRCS ${CORE_SRCS} LIBS ${CORE_DEP_LIBS} FOLDER "Runtime") if(WIN32) - install(TARGETS Core ARCHIVE DESTINATION lib) add_precompiled_header(Core "Kaleido3D.h" "${Kaleido3D_ROOT_DIR}/Include" "${Kaleido3D_ROOT_DIR}/Source/Core/App.cpp") -elseif(ANDROID) - target_link_libraries(Core log android) elseif(MACOS) - target_link_libraries(Core "-framework Cocoa" "-framework AppKit" "-framework QuartzCore" "-framework CoreData" "-framework Foundation") - add_custom_command(TARGET Core POST_BUILD COMMAND - ${CMAKE_INSTALL_NAME_TOOL} -id "@loader_path/../Frameworks/libCore.dylib" $) + if(BUILD_SHARED) + add_custom_command(TARGET Core POST_BUILD COMMAND + ${CMAKE_INSTALL_NAME_TOOL} -id "@loader_path/../Frameworks/libCore.dylib" $) + endif() endif() -set_target_properties(Core PROPERTIES FOLDER "Runtime") +install(TARGETS Core + ARCHIVE DESTINATION lib + LIBRARY DESTINATION lib + RUNTIME DESTINATION bin) + +install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} + DESTINATION include/kaleido3d + FILES_MATCHING PATTERN "*.h" +) + +install(FILES ${Kaleido3D_ROOT_DIR}/Include/Kaleido3D.h + DESTINATION include/kaleido3d +) + +install(DIRECTORY ${Kaleido3D_ROOT_DIR}/Include/KTL + DESTINATION include/kaleido3d + FILES_MATCHING PATTERN "*.hpp" +) + +install(DIRECTORY ${Kaleido3D_ROOT_DIR}/Include/Math + DESTINATION include/kaleido3d + FILES_MATCHING PATTERN "*.hpp" +) + +install(DIRECTORY ${Kaleido3D_ROOT_DIR}/Include/Interface + DESTINATION include/kaleido3d + FILES_MATCHING PATTERN "*.h" +) + +install(DIRECTORY ${Kaleido3D_ROOT_DIR}/Include/Config + DESTINATION include/kaleido3d + FILES_MATCHING PATTERN "*.h" +) + +if(BUILD_WITH_UNIT_TEST) + add_subdirectory(UnitTest) +endif() \ No newline at end of file diff --git a/Source/Core/CameraData.cpp b/Source/Core/CameraData.cpp index 28e35cf..7f0aeaa 100755 --- a/Source/Core/CameraData.cpp +++ b/Source/Core/CameraData.cpp @@ -1,6 +1,5 @@ #include "Kaleido3D.h" #include "CameraData.h" -#include "Archive.h" namespace k3d { diff --git a/Source/Core/CameraData.h b/Source/Core/CameraData.h index 7dbadc5..bb121c6 100755 --- a/Source/Core/CameraData.h +++ b/Source/Core/CameraData.h @@ -3,6 +3,7 @@ #include "Bundle.h" #include #include +#include namespace k3d { diff --git a/Source/Core/Dispatch/WorkQueue.h b/Source/Core/Dispatch/WorkQueue.h index 96f3157..2d5ff2b 100755 --- a/Source/Core/Dispatch/WorkQueue.h +++ b/Source/Core/Dispatch/WorkQueue.h @@ -3,7 +3,6 @@ #include #include #include "../Os.h" -#include namespace Dispatch { diff --git a/Source/Core/InputDevice.cpp b/Source/Core/InputDevice.cpp index dd68ef8..af3a292 100755 --- a/Source/Core/InputDevice.cpp +++ b/Source/Core/InputDevice.cpp @@ -11,7 +11,7 @@ namespace k3d { bool Mouse::IsButtonPressed(Button button) { -#ifndef K3DPLATFORM_OS_MAC +#if K3DPLATFORM_OS_WIN || K3DPLATFORM_OS_ANDROID return InputDeviceImpl::isMouseButtonPressed(button); #else return true; @@ -20,7 +20,7 @@ namespace k3d Mouse::Vector2i Mouse::GetPosition() { -#ifndef K3DPLATFORM_OS_MAC +#if K3DPLATFORM_OS_WIN || K3DPLATFORM_OS_ANDROID return InputDeviceImpl::getMousePosition(); #else return Mouse::Vector2i(); @@ -29,7 +29,7 @@ namespace k3d Mouse::Vector2i Mouse::GetPosition(const IWindow& relativeTo) { -#ifndef K3DPLATFORM_OS_MAC +#if K3DPLATFORM_OS_WIN || K3DPLATFORM_OS_ANDROID return InputDeviceImpl::getMousePosition(relativeTo); #else return Mouse::Vector2i(); @@ -38,21 +38,21 @@ namespace k3d void Mouse::SetPosition(const Mouse::Vector2i& position) { -#ifndef K3DPLATFORM_OS_MAC +#if K3DPLATFORM_OS_WIN || K3DPLATFORM_OS_ANDROID return InputDeviceImpl::setMousePosition(position); #endif } void Mouse::SetPosition(const Mouse::Vector2i& position, const IWindow& relativeTo) { -#ifndef K3DPLATFORM_OS_MAC +#if K3DPLATFORM_OS_WIN || K3DPLATFORM_OS_ANDROID return InputDeviceImpl::setMousePosition(position, relativeTo); #endif } bool Keyboard::IsKeyPressed(Key key) { -#ifndef K3DPLATFORM_OS_MAC +#if K3DPLATFORM_OS_WIN || K3DPLATFORM_OS_ANDROID return InputDeviceImpl::isKeyPressed(key); #else return true; diff --git a/Source/Core/InputDevice.h b/Source/Core/InputDevice.h index bcf4fcb..72b1d39 100755 --- a/Source/Core/InputDevice.h +++ b/Source/Core/InputDevice.h @@ -1,8 +1,11 @@ #ifndef __InputDevice_h__ #define __InputDevice_h__ #pragma once + #include "Window.h" + #include + namespace k3d { class Mouse diff --git a/Source/Core/LogUtil.cpp b/Source/Core/LogUtil.cpp index 9c3ff29..1e05740 100755 --- a/Source/Core/LogUtil.cpp +++ b/Source/Core/LogUtil.cpp @@ -4,13 +4,14 @@ #include #include #include +#include "Log/Public/ILogModule.h" #include "../../Data/style.css.h" namespace k3d { void Log(ELogLevel const & Lv, const char * tag, const char * fmt, ...) { - static thread_local char dbgStr[2048] = { 0 }; + static /*thread_local*/ char dbgStr[2048] = { 0 }; va_list va; va_start(va, fmt); #if K3DPLATFORM_OS_ANDROID @@ -20,7 +21,7 @@ namespace k3d #endif va_end(va); - k3d::ILogModule* logModule = (k3d::ILogModule*)GlobalModuleManager.FindModule("KawaLog"); + auto logModule = StaticPointerCast(GlobalModuleManager.FindModule("KawaLog")); if (logModule) { int logType = (int)ELoggerType::EConsole; diff --git a/Source/Core/LogUtil.h b/Source/Core/LogUtil.h index 99ea4ac..e7a31cd 100755 --- a/Source/Core/LogUtil.h +++ b/Source/Core/LogUtil.h @@ -2,8 +2,10 @@ #ifndef __LogUtil_h__ #define __LogUtil_h__ #include "Utils/StringUtils.h" + #include -#include +#include + #include "Os.h" namespace k3d diff --git a/Source/Core/LogUtil.inl b/Source/Core/LogUtil.inl deleted file mode 100755 index 6f70f09..0000000 --- a/Source/Core/LogUtil.inl +++ /dev/null @@ -1 +0,0 @@ -#pragma once diff --git a/Source/Core/Looper.h b/Source/Core/Looper.h index cf1073f..78af73c 100755 --- a/Source/Core/Looper.h +++ b/Source/Core/Looper.h @@ -4,6 +4,7 @@ #include #include #include + #include "Os.h" namespace k3d { diff --git a/Source/Core/MeshData.cpp b/Source/Core/MeshData.cpp index 6d26014..9e4b546 100755 --- a/Source/Core/MeshData.cpp +++ b/Source/Core/MeshData.cpp @@ -1,6 +1,5 @@ #include "Kaleido3D.h" #include "MeshData.h" -#include "Archive.h" #include #include diff --git a/Source/Core/MeshData.h b/Source/Core/MeshData.h index 338384c..0467f48 100755 --- a/Source/Core/MeshData.h +++ b/Source/Core/MeshData.h @@ -4,7 +4,6 @@ #include #include -#include #include #include @@ -72,9 +71,7 @@ namespace k3d }; - class K3D_API MeshData : - public IMesh, - public IReflectable { + class K3D_API MeshData : public IMesh { public: MeshData(); @@ -110,8 +107,6 @@ namespace k3d void SetVertexBuffer(void* dataPtr); void SetVertexNum(int num) { m_NumVertices = num; } - MeshData * Reflect() override { return new MeshData; } - std::string DumpMeshInfo() { std::ostringstream meshInfo; diff --git a/Source/Core/Message.h b/Source/Core/Message.h index e4c6969..d0617bc 100755 --- a/Source/Core/Message.h +++ b/Source/Core/Message.h @@ -3,8 +3,8 @@ #define __Message_h__ #include "InputDevice.h" -namespace k3d { - +namespace k3d +{ class Message final { public: diff --git a/Source/Core/Module.cpp b/Source/Core/Module.cpp index 8caf2df..c339c56 100755 --- a/Source/Core/Module.cpp +++ b/Source/Core/Module.cpp @@ -2,6 +2,8 @@ #include "Module.h" #include "App.h" #include "Os.h" +#include "LogUtil.h" +#include #include #include #include @@ -11,86 +13,125 @@ namespace k3d { typedef IModule * (*PFN_GetModule)(); + class ModuleManagerPrivate + { + public: #if K3DPLATFORM_OS_WIN - std::list > g_ModuleList; + std::list > g_ModuleList; + std::unordered_map g_Win32ModuleMap; #endif + std::unordered_map g_ModuleMap; + mutable bool g_IsInited = false; + }; ModuleManager GlobalModuleManager; - static std::unordered_map g_ModuleMap; - -#if K3DPLATFORM_OS_WIN - static std::unordered_map g_Win32ModuleMap; -#endif ModuleManager::~ModuleManager() { - //g_ModuleMap.clear(); TODO crash + KLOG(Info, ModuleManager, "Destroyed"); + p->g_IsInited = false; + if (!p->g_ModuleMap.empty()) + { + p->g_ModuleMap.clear(); + } + //KLOG(Info, ModuleManager, "Destroyed"); + +#if K3DPLATFORM_OS_WIN + if (!p->g_Win32ModuleMap.empty()) + { + for (auto & entry : p->g_Win32ModuleMap) + { + ::FreeLibrary(entry.second); + } + p->g_Win32ModuleMap.clear(); + } +#endif } - void ModuleManager::AddModule(const char * name, IModule * module) + void ModuleManager::AddModule(const char * name, ModuleRef module) { - g_ModuleMap[name] = module; + if (!p->g_IsInited) + return; + p->g_ModuleMap[name] = module; } void ModuleManager::RemoveModule(const char * name) { - g_ModuleMap.erase(name); + if (!p->g_IsInited) + return; + p->g_ModuleMap.erase(name); } bool ModuleManager::LoadModule(const char * moduleName) { + if (!p->g_IsInited) + return nullptr; + String entryFunction; + entryFunction.AppendSprintf("Get%sModule", moduleName); #if K3DPLATFORM_OS_WIN std::string moduleDir = "./"; HMODULE hModule = LoadLibraryA((moduleDir + moduleName + ".dll").c_str()); if (hModule) { - std::string entryName("Get"); - entryName += moduleName; - entryName += "Module"; - PFN_GetModule pFn = (PFN_GetModule)::GetProcAddress((HMODULE)hModule, entryName.c_str()); - g_Win32ModuleMap[moduleName] = hModule; - g_ModuleMap[moduleName] = pFn(); + PFN_GetModule pFn = (PFN_GetModule)::GetProcAddress((HMODULE)hModule, entryFunction.CStr()); + p->g_Win32ModuleMap[moduleName] = hModule; + p->g_ModuleMap[moduleName] = ModuleRef(pFn()); return true; } #else - std::string entryName("Get"); - entryName += moduleName; - entryName += "Module"; + +#if !K3DPLATFORM_OS_IOS kString libDir = GetEnv()->GetEnvValue(Environment::ENV_KEY_MODULE_DIR) + "/lib" + moduleName + #if K3DPLATFORM_OS_MAC ".dylib"; #else ".so"; #endif - void* handle = ::dlopen(libDir.c_str(), RTLD_LAZY); - if(handle) { - PFN_GetModule fn = (PFN_GetModule)dlsym(handle, entryName.c_str()); - if(!fn) { + if(libDir.empty()) + { + return false; + } + void* handle = ::dlopen(libDir.c_str(), RTLD_LAZY); +#else + //kString libDir = kString(moduleName) + ".framework/" + moduleName; + String libDir; + libDir.AppendSprintf("%s.framework/%s", moduleName, moduleName); + void* handle = ::dlopen(libDir.CStr(), RTLD_LAZY); +#endif + if(handle) + { + PFN_GetModule fn = (PFN_GetModule)dlsym(handle, entryFunction.CStr()); + if(!fn) + { return false; } - g_ModuleMap[moduleName] = fn(); + auto mod = fn(); + //g_ModuleMap[moduleName] = mod; + p->g_ModuleMap.insert({moduleName, ModuleRef(mod)}); return true; } #endif return false; } - IModule * ModuleManager::FindModule(const char * moduleName) + ModuleRef ModuleManager::FindModule(const char * moduleName) { - std::string mName(moduleName); - if (g_ModuleMap.find(moduleName) != g_ModuleMap.end()) + if (!p->g_IsInited) + return nullptr; + if (p->g_ModuleMap.find(moduleName) != p->g_ModuleMap.end()) { - return g_ModuleMap[mName]; + return p->g_ModuleMap[moduleName]; } else { if(LoadModule(moduleName)) - return g_ModuleMap[mName]; + return p->g_ModuleMap[moduleName]; } return nullptr; } - ModuleManager::ModuleManager() + ModuleManager::ModuleManager() : p(new ModuleManagerPrivate) { + p->g_IsInited = true; } } diff --git a/Source/Core/Module.h b/Source/Core/Module.h index 695f815..c099566 100755 --- a/Source/Core/Module.h +++ b/Source/Core/Module.h @@ -1,74 +1,29 @@ #ifndef __Module_h__ #define __Module_h__ -#if K3DPLATFORM_OS_WIN -#define PLUGIN_API_DECLARE __declspec(dllexport) -#else -#define PLUGIN_API_DECLARE -#endif - -#ifdef BUILD_SHARED_LIB -#ifdef BUILD_WITH_PLUGIN -#if K3DPLATFORM_OS_WIN -#define CORE_API __declspec(dllimport) -#else -#define CORE_API __attribute__((visibility("default"))) -#endif -#else -#if K3DPLATFORM_OS_WIN -#define CORE_API __declspec(dllexport) -#else -#define CORE_API __attribute__((visibility("default"))) -#endif -#endif -#else -#define CORE_API -#endif - -#define K3D_DYNAMIC_MODULE_IMPLEMENT(ModuleName, ModuleClass) \ -extern "C" PLUGIN_API_DECLARE ::k3d::IModule *Get##ModuleName##Module() { return new ModuleClass; } - -#define K3D_STATIC_MODULE_IMPLEMENT(ModuleName, MoudleClass) \ -class MoudleName##StaticInitializer {\ -public:\ - MoudleName##StaticInitializer() { k3d::ModuleManager::Get().AddModule(#ModuleName, new MoudleClass); }\ - ~MoudleName##StaticInitializer() { k3d::ModuleManager::Get().RemoveModule(#ModuleName); }\ -}; \ -static MoudleName##StaticInitializer mInitializer; - -/** - * build dlls - */ -#ifdef BUILD_SHARED_CORE -#define MODULE_IMPLEMENT K3D_DYNAMIC_MODULE_IMPLEMENT -#else -#define MODULE_IMPLEMENT K3D_STATIC_MODULE_IMPLEMENT -#endif +#include namespace k3d { - class IModule - { - public: - virtual void Start() = 0; - virtual void Shutdown() = 0; - virtual const char * Name() = 0; - virtual ~IModule() {} - }; + class ModuleManagerPrivate; class CORE_API ModuleManager { public: ~ModuleManager(); - void AddModule(const char* name, IModule* module); + void AddModule(const char* name, ModuleRef module); void RemoveModule(const char * name); bool LoadModule(const char * moduleName); - IModule* FindModule(const char * moduleName); + ModuleRef FindModule(const char * moduleName); ModuleManager(); + + private: + ModuleManagerPrivate * p; }; + extern CORE_API ModuleManager GlobalModuleManager; } diff --git a/Source/Core/ObjectMesh.h b/Source/Core/ObjectMesh.h index 6881d48..27fafcf 100755 --- a/Source/Core/ObjectMesh.h +++ b/Source/Core/ObjectMesh.h @@ -1,7 +1,7 @@ #pragma once -namespace k3d { - +namespace k3d +{ struct ObjectLoadListener { virtual void OnLoad() = 0; }; diff --git a/Source/Core/Os.cpp b/Source/Core/Os.cpp index 9fb24a8..7323db2 100755 --- a/Source/Core/Os.cpp +++ b/Source/Core/Os.cpp @@ -212,7 +212,7 @@ namespace Os if (m_hFile) { ::CloseHandle(m_hFile); - m_hFile = INVALID_HANDLE_VALUE; + m_hFile = NULL; } #else if (m_fd) ::close(m_fd); @@ -615,6 +615,7 @@ namespace Os Mutex::~Mutex() { delete m_Impl; + m_Impl = nullptr; } void Mutex::Lock() diff --git a/Source/Core/Os.h b/Source/Core/Os.h index eaba44a..50f9c02 100755 --- a/Source/Core/Os.h +++ b/Source/Core/Os.h @@ -3,6 +3,7 @@ #include #include + #include #include @@ -120,6 +121,7 @@ namespace Os typedef void(*PFN_FileProcessRoutine)(const ::k3d::kchar * path, bool isDir); extern K3D_API bool ListFiles(const ::k3d::kchar * srcPath, PFN_FileProcessRoutine); extern K3D_API uint32 GetCpuCoreNum(); + extern K3D_API float* GetCpuUsage(); enum class ThreadPriority { @@ -167,6 +169,7 @@ namespace Os if (m_OnwerShipGot) { delete m_Mutex; + m_Mutex = nullptr; } } private: diff --git a/Source/Core/ReflectFactory.h b/Source/Core/ReflectFactory.h index 25997d7..b106322 100755 --- a/Source/Core/ReflectFactory.h +++ b/Source/Core/ReflectFactory.h @@ -5,8 +5,8 @@ #include #include -namespace k3d { - +namespace k3d +{ class ReflectFactory : public Singleton { public: //template diff --git a/Source/Core/String.cpp b/Source/Core/String.cpp deleted file mode 100755 index d187349..0000000 --- a/Source/Core/String.cpp +++ /dev/null @@ -1,12 +0,0 @@ -#include "Kaleido3D.h" -#include "String.h" -#include -#include - -K3D_COMMON_NS -{ - int Vsnprintf(char*dest, int n, const char* fmt, va_list list) - { - return ::vsnprintf(dest, n, fmt, list); - } -} diff --git a/Source/Core/String.h b/Source/Core/String.h deleted file mode 100755 index 2c38a2a..0000000 --- a/Source/Core/String.h +++ /dev/null @@ -1,264 +0,0 @@ -#pragma once -#include -#include "Archive.h" - -K3D_COMMON_NS -{ -template -inline uint64 CharLength(const BaseChar* cStr) -{ - const BaseChar *eos = cStr; - while (*eos++); - return(eos - cStr - 1); -} - -extern K3D_API int Vsnprintf(char*, int n, const char* fmt, va_list); - -template -class StringBase -{ -public: - typedef BaseChar* CharPointer; - typedef const BaseChar* ConstCharPointer; - typedef StringBase ThisString; - typedef uint64 CharPosition; - - StringBase() K3D_NOEXCEPT - : m_pStringData(nullptr) - , m_StringLength(0) - , m_Capacity(0) - { - } - - StringBase(const void * pData, size_t szData) - : m_pStringData(nullptr) - , m_StringLength(0) - , m_Capacity(0) - { - uint64 calLength = szData/sizeof(BaseChar); - uint64 remain = szData%sizeof(BaseChar); - if(remain == 0) - { - m_StringLength = calLength; - m_Capacity = m_StringLength + 1; - m_pStringData = Allocate(m_Capacity); - memcpy(m_pStringData, pData, szData); - m_pStringData[m_StringLength] = 0; - } - } - - StringBase(ConstCharPointer pStr) - : m_pStringData(nullptr) - , m_StringLength(0) - , m_Capacity(0) - { - m_StringLength = CharLength(pStr); - if(m_StringLength) - { - m_Capacity = (uint64)(1.5f * m_StringLength + 0.5f); - m_pStringData = Allocate(m_Capacity); - memcpy(m_pStringData, pStr, m_StringLength * sizeof(BaseChar)); - m_pStringData[m_StringLength] = 0; - } - } - - StringBase(const ThisString & rhs) - : m_pStringData(nullptr) - , m_StringLength(0) - , m_Capacity(rhs.m_Capacity) - , m_StringAllocator(rhs.m_StringAllocator) - { - Assign(rhs); - } - - StringBase(ThisString && rhs) - : m_pStringData(nullptr) - , m_StringLength(0) - { - MoveAssign(Move(rhs)); - } - - virtual ~StringBase() - { - if (m_pStringData) - { - Deallocate(); - m_pStringData = nullptr; - m_StringLength = 0; - } - } - - uint64 Length() const { return m_StringLength; } - ConstCharPointer Data() const { return m_pStringData; } - ConstCharPointer CStr() const { return m_pStringData; } - - ThisString& operator=(const ThisString& rhs) { Assign(rhs); return *this; } - ThisString& operator=(ThisString&& rhs) { MoveAssign(Move(rhs)); return *this; } - ThisString& operator+=(const ThisString& rhs); - ThisString& AppendSprintf(const BaseChar* fmt, ...); - void Swap(ThisString& rhs); - - //CharPosition FindFirstOf(BaseChar _char); - - template - friend Archive& operator<<(Archive & ar, StringBase const& str); - - template - friend Archive& operator>>(Archive & ar, StringBase & str); - -protected: - CharPointer Allocate(uint64 stringLength); - void Deallocate(); - - void MoveAssign(ThisString && rhs); - void Assign(ThisString const& rhs); - -private: - CharPointer m_pStringData; - uint64 m_StringLength; - uint64 m_Capacity; - Allocator m_StringAllocator; -}; - -template -KFORCE_INLINE BaseChar* StringBase::Allocate(uint64 length) -{ - return reinterpret_cast(m_StringAllocator.allocate(sizeof(BaseChar)*length, 0)); -} - -template -KFORCE_INLINE void StringBase::Deallocate() -{ - m_StringAllocator.deallocate(m_pStringData, sizeof(BaseChar)*m_StringLength); -} - -template -KFORCE_INLINE void StringBase::MoveAssign(StringBase && rhs) -{ - m_pStringData = rhs.m_pStringData; - m_StringLength = rhs.m_StringLength; - m_Capacity = rhs.m_Capacity; - m_StringAllocator = Move(rhs.m_StringAllocator); - rhs.m_pStringData = nullptr; - rhs.m_StringLength = 0; - rhs.m_Capacity = 0; -} - -template -KFORCE_INLINE void StringBase::Assign(StringBase const & rhs) -{ - if (m_pStringData != rhs.m_pStringData) - { - if (m_pStringData) - { - Deallocate(); - } - m_Capacity = rhs.m_StringLength + 1; - m_pStringData = Allocate(m_Capacity); - m_StringLength = rhs.m_StringLength; - memcpy(m_pStringData, rhs.m_pStringData, rhs.m_StringLength * sizeof(BaseChar)); - m_pStringData[m_StringLength] = 0; - } -} - -template -KFORCE_INLINE StringBase& -StringBase::AppendSprintf(const BaseChar *fmt, ...) -{ - va_list va; - va_start(va, fmt); - int length = Vsnprintf(m_pStringData + m_StringLength, m_Capacity-m_StringLength, fmt, va); - va_end(va); - - auto newLen = length + m_StringLength; - if(newLen >= m_Capacity) - { - m_Capacity = (uint64)( 1.33f * newLen + 1.0f ); - BaseChar* newString = Allocate(m_Capacity); - memcpy(newString, m_pStringData, m_StringLength*sizeof(BaseChar)); - - va_list va; - va_start(va, fmt); - Vsnprintf(newString + m_StringLength, m_Capacity-m_StringLength, fmt, va); - va_end(va); - - Deallocate(); - m_pStringData = newString; - } - - m_StringLength = newLen; - - return *this; -} - -template -KFORCE_INLINE void StringBase::Swap(StringBase & rhs) -{ - BaseChar* p = rhs.m_pStringData; - rhs.m_pStringData = m_pStringData; - m_pStringData = p; - - uint64 l = rhs.m_StringLength; - rhs.m_StringLength = m_StringLength; - m_StringLength = l; -} - -template -KFORCE_INLINE StringBase& -StringBase::operator+=(StringBase const& rhs) -{ - auto rLen = rhs.m_StringLength; - auto newLen = m_StringLength + rLen; - if(newLen>=m_Capacity) - { - m_Capacity = uint64(1.5*newLen + 1); - auto pNewData = Allocate(m_Capacity); - if(m_pStringData) - { - memcpy(pNewData, m_pStringData, m_StringLength*sizeof(BaseChar)); - Deallocate(); - } - m_pStringData = pNewData; - } - memcpy(m_pStringData + m_StringLength, rhs.m_pStringData, rLen*sizeof(BaseChar)); - m_pStringData[newLen] = 0; - m_StringLength = newLen; - return *this; -} - -template -KFORCE_INLINE StringBase -operator+(StringBase const& lhs, StringBase const& rhs) -{ - StringBase ret(lhs); - ret += rhs; - return ret; -} - -template -KFORCE_INLINE bool operator==(StringBase const& lhs, StringBase const& rhs) -{ - return ((lhs.Length() == rhs.Length()) && (memcmp(lhs.Data(), rhs.Data(), lhs.Length() * sizeof(BaseChar)) == 0)); -} - -template -Archive& operator<<(Archive & ar, StringBase const& str) -{ - ar << str.m_Capacity << str.m_StringLength; - ar.ArrayIn(str.CStr(), str.Length()); - return ar; -} - -template -Archive& operator>>(Archive & ar, StringBase & str) -{ - ar >> str.m_Capacity >> str.m_StringLength; - str.m_pStringData = str.Allocate(str.m_Capacity); - ar.ArrayOut(str.m_pStringData, str.Length()); - str.m_pStringData[str.m_StringLength] = 0; - return ar; -} - -typedef StringBase String; - -} diff --git a/Source/Core/StringImpl.cpp b/Source/Core/StringImpl.cpp new file mode 100644 index 0000000..a546698 --- /dev/null +++ b/Source/Core/StringImpl.cpp @@ -0,0 +1,133 @@ +#include "Kaleido3D.h" +#include +#include +#include +#include "Utils/MD5.h" + +K3D_COMMON_NS +{ +K3D_API int Vsnprintf(char*dest, int n, const char* fmt, va_list list) +{ + return ::vsnprintf(dest, n, fmt, list); +} + +// ------------------------------------------------------------------------------------------------------------- +// Base64 +//-------------------------------------------------------------------------------------------------------------- +static const char* base64_chars = +"ABCDEFGHIJKLMNOPQRSTUVWXYZ" +"abcdefghijklmnopqrstuvwxyz" +"0123456789+/"; + +K3D_API K3D_API String Base64Encode(String const & in) +{ + auto in_len = in.Length(); + auto bytes_to_encode = in.CStr(); + int reckon_len = ((4 * in_len / 3) + 3) & ~3; + String ret; + ret.Resize(reckon_len); + int i = 0; + int j = 0; + unsigned char char_array_3[3]; + unsigned char char_array_4[4]; + + while (in_len--) { + char_array_3[i++] = *(bytes_to_encode++); + if (i == 3) { + char_array_4[0] = (char_array_3[0] & 0xfc) >> 2; + char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4); + char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6); + char_array_4[3] = char_array_3[2] & 0x3f; + + for (i = 0; (i <4); i++) + ret += base64_chars[char_array_4[i]]; + i = 0; + } + } + + if (i) + { + for (j = i; j < 3; j++) + char_array_3[j] = '\0'; + + char_array_4[0] = (char_array_3[0] & 0xfc) >> 2; + char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4); + char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6); + char_array_4[3] = char_array_3[2] & 0x3f; + + for (j = 0; (j < i + 1); j++) + ret += base64_chars[char_array_4[j]]; + + while ((i++ < 3)) + ret += '='; + + } + return ret; +} + +static inline bool is_base64(unsigned char c) { + return (isalnum(c) || (c == '+') || (c == '/')); +} + +static inline int find_base64char(unsigned char c) +{ + for (int i = 0; i < 64; i++) + { + if (c == base64_chars[i]) + return i; + } + return -1; +} + +K3D_API String Base64Decode(String const& encoded_string) +{ + size_t in_len = encoded_string.Length(); + int i = 0; + int j = 0; + int in_ = 0; + unsigned char char_array_4[4], char_array_3[3]; + String ret; + ret.Resize(encoded_string.Length()); + + while (in_len-- && (encoded_string[in_] != '=') && is_base64(encoded_string[in_])) { + char_array_4[i++] = encoded_string[in_]; in_++; + if (i == 4) { + for (i = 0; i <4; i++) + char_array_4[i] = static_cast(find_base64char(char_array_4[i])); + + char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4); + char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2); + char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3]; + + for (i = 0; (i < 3); i++) + ret += char_array_3[i]; + i = 0; + } + } + + if (i) { + for (j = i; j <4; j++) + char_array_4[j] = 0; + + for (j = 0; j <4; j++) + char_array_4[j] = static_cast(find_base64char(char_array_4[j])); + + char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4); + char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2); + char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3]; + + for (j = 0; (j < i - 1); j++) ret += char_array_3[j]; + } + return ret; +} +// ------------------------------------------------------------------------------------------------------------- +// Base64 End +//-------------------------------------------------------------------------------------------------------------- + +K3D_API String MD5Encode(String const& in) +{ + MD5 md5; + md5.Update(in); + return md5.Str(); +} +} diff --git a/Source/Core/Timer.h b/Source/Core/Timer.h index 3f50df3..46b42b0 100755 --- a/Source/Core/Timer.h +++ b/Source/Core/Timer.h @@ -2,7 +2,8 @@ #define __k3dTimer_h__ #pragma once -namespace k3d { +namespace k3d +{ class K3D_API Timer { public: diff --git a/Source/Core/UnitTest/CMakeLists.txt b/Source/Core/UnitTest/CMakeLists.txt new file mode 100644 index 0000000..9add754 --- /dev/null +++ b/Source/Core/UnitTest/CMakeLists.txt @@ -0,0 +1,49 @@ +if(BUILD_SHARED) + add_definitions(-DBUILD_SHARED_LIB -DBUILD_WITH_PLUGIN) +endif() +################################## Unit Test For RHI ##################################### + +include_directories( + ${FREETYPE2_INCLUDE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR} +) + +add_unittest( + Core-UnitTest-1.Os + UTCore.Os.cpp +) + +add_unittest( + Core-UnitTest-2.Bundle + UTCore.Bundle.cpp +) + +add_unittest( + Core-UnitTest-3.WebSocket + UTCore.WebSocket.cpp +) + +add_unittest( + Core-UnitTest-4.SharedPtr + UTKTL.SharedPtr.cpp +) + +add_unittest( + Core-UnitTest-5.DynArray + UTKTL.DynArray.cpp +) + +add_unittest( + Core-UnitTest-6.String + UTCore.String.cpp +) + +add_unittest( + Core-UnitTest-7.ShaderCompiler + UTTools.ShaderCompiler.cpp +) + +add_unittest( + Core-UnitTest-8.UTFontLoader + UTFontLoader.cpp +) \ No newline at end of file diff --git a/Source/Core/UnitTest/Common.h b/Source/Core/UnitTest/Common.h new file mode 100644 index 0000000..5317e15 --- /dev/null +++ b/Source/Core/UnitTest/Common.h @@ -0,0 +1,19 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include + +#include +#include diff --git a/Source/UnitTest/Base/UTCore.Bundle.cpp b/Source/Core/UnitTest/UTCore.Bundle.cpp old mode 100755 new mode 100644 similarity index 86% rename from Source/UnitTest/Base/UTCore.Bundle.cpp rename to Source/Core/UnitTest/UTCore.Bundle.cpp index b0eb63e..3494276 --- a/Source/UnitTest/Base/UTCore.Bundle.cpp +++ b/Source/Core/UnitTest/UTCore.Bundle.cpp @@ -2,12 +2,15 @@ #include #include +#if K3DPLATFORM_OS_WIN +#pragma comment(linker,"/subsystem:console") +#endif + using namespace k3d; using namespace std; -threadptr TestBundle() +void TestBundle() { - auto ret = std::make_shared([]() { Os::File file("../../Data/Test/test.bundle"); file.Open(IORead); Archive arch; @@ -50,6 +53,10 @@ threadptr TestBundle() } file.Close(); - }); - return ret; +} + +int main(int argc, char**argv) +{ + TestBundle(); + return 0; } \ No newline at end of file diff --git a/Source/Core/UnitTest/UTCore.Os.cpp b/Source/Core/UnitTest/UTCore.Os.cpp new file mode 100644 index 0000000..c324aa3 --- /dev/null +++ b/Source/Core/UnitTest/UTCore.Os.cpp @@ -0,0 +1,36 @@ +#include "Common.h" +#include +#include + +#if K3DPLATFORM_OS_WIN +#pragma comment(linker,"/subsystem:console") +#endif + +using namespace std; +using namespace k3d; + +void TestOs() +{ + K3D_ASSERT(Os::MakeDir(KT("./TestOs"))); + K3D_ASSERT(Os::Remove(KT("./TestOs"))); + while (1) + { + Os::Sleep(1000); + int count = Os::GetCpuCoreNum(); + float * usage = Os::GetCpuUsage(); + stringstream str; + str << "usage: "; + for (int i = 0; i < count; i++) + { + str << usage[i] << ","; + } + cout << str.str() << endl; + } +} + + +int main(int argc, char**argv) +{ + TestOs(); + return 0; +} \ No newline at end of file diff --git a/Source/Core/UnitTest/UTCore.String.cpp b/Source/Core/UnitTest/UTCore.String.cpp new file mode 100644 index 0000000..7098e6b --- /dev/null +++ b/Source/Core/UnitTest/UTCore.String.cpp @@ -0,0 +1,55 @@ +#include "Common.h" +#include + +#if K3DPLATFORM_OS_WIN +#pragma comment(linker,"/subsystem:console") +#endif + +using namespace k3d; +using namespace std; + +String toBeRemoved("Love you later."); + +void TestString() +{ + String testString("HeyYou!"); + cout << testString.CStr() << endl; + String testStringBaby("BabyGirl!!"); + testStringBaby.Swap(testString); + cout << testString.CStr() << endl; + + testString += toBeRemoved; + testString += ".."; + cout << testString.CStr() << endl; + + testString.AppendSprintf("%d %s", 5, "fhdsfjdhjkfdhksfhdkjshfjkdshfk"); + testString += 'B'; + cout << testString.CStr() << endl; + + MD5 md5; + md5.Update(testString); + auto testMd5 = md5.Str(); + cout << "md5:" << testMd5.CStr() << endl; + + cout << "md5:" << MD5Encode(testString).CStr() << endl; + + //Archive ar; + //ar << testString; + + String testMoveString(Move(toBeRemoved)); + cout << "testMove:" << testMoveString.CStr() + << " original:" << (toBeRemoved.CStr()?toBeRemoved.CStr():"null") << endl; + + auto b64 = Base64Encode(testMoveString); + cout << "b64:" << b64.CStr() << endl; + + auto d64 = Base64Decode(b64); + cout << "d64:" << d64.CStr() << endl; + +} + +int main(int argc, char**argv) +{ + TestString(); + return 0; +} \ No newline at end of file diff --git a/Source/UnitTest/Base/UTCore.WebSocket.cpp b/Source/Core/UnitTest/UTCore.WebSocket.cpp old mode 100755 new mode 100644 similarity index 75% rename from Source/UnitTest/Base/UTCore.WebSocket.cpp rename to Source/Core/UnitTest/UTCore.WebSocket.cpp index 4a2612d..d646f6a --- a/Source/UnitTest/Base/UTCore.WebSocket.cpp +++ b/Source/Core/UnitTest/UTCore.WebSocket.cpp @@ -1,6 +1,10 @@ #include "Common.h" #include -#include +#include + +#if K3DPLATFORM_OS_WIN +#pragma comment(linker,"/subsystem:console") +#endif using namespace net; @@ -14,7 +18,7 @@ class TestServer : public WebSocket void BindAndListen() { Create(); - Os::IPv4Address addr(":7000"); + Os::IPv4Address addr("192.168.0.112:7000"); this->SetBlocking(true); Bind(addr); Listen(10); @@ -54,12 +58,16 @@ class TestServer : public WebSocket std::stringstream m_LogStream; }; -threadptr TestWebSocket() +void TestWebSocket() { - auto ret = std::make_shared([]() { - TestServer server; - server.BindAndListen(); + TestServer server; + server.BindAndListen(); server.Start(); - }); - return ret; } + +int main(int argc, char**argv) +{ + TestWebSocket(); + return 0; +} + diff --git a/Source/Core/UnitTest/UTFontLoader.cpp b/Source/Core/UnitTest/UTFontLoader.cpp new file mode 100644 index 0000000..ae64129 --- /dev/null +++ b/Source/Core/UnitTest/UTFontLoader.cpp @@ -0,0 +1,24 @@ +#include "Common.h" + +#if K3DPLATFORM_OS_WIN +#pragma comment(linker,"/subsystem:console") +#endif + +using namespace k3d; +using namespace std; +using namespace render; + +void TestFontManager() +{ + FontManager fm; + fm.LoadLib("../../Data/Test/calibri.ttf"); + fm.ChangeFontSize(64); + auto quads = fm.AcquireText("FuckYou"); + quads.Count(); +} + +int main(int argc, char**argv) +{ + TestFontManager(); + return 0; +} \ No newline at end of file diff --git a/Source/Core/UnitTest/UTKTL.DynArray.cpp b/Source/Core/UnitTest/UTKTL.DynArray.cpp new file mode 100644 index 0000000..85ce16c --- /dev/null +++ b/Source/Core/UnitTest/UTKTL.DynArray.cpp @@ -0,0 +1,75 @@ +#include "Common.h" + +#if K3DPLATFORM_OS_WIN +#pragma comment(linker,"/subsystem:console") +#endif + +using namespace std; +using namespace k3d; + +struct B +{ + B() : msg_(nullptr) + { + std::cout << "construct" << std::endl; + } + B(const char* msg) : msg_(msg) + { + std::cout << msg << std::endl; + } + + B& operator=(const B& rhs) + { + std::cout << "rhs " << rhs.msg_ + << " assigned to " << std::endl; + this->msg_ = rhs.msg_; + return *this; + } + + ~B() + { + std::cout << "deconstructB " << msg_ << std::endl; + } + const char *msg_; +}; + +void TestDynArrray() +{ + B b1{ "b1" }, b3{ "b3" }; + DynArray ints; + ints.Append(5).Append(6).Append(7).Append(0).Append(8); + std::cout << ints[3] << std::endl; + ints[3] = 0; + + std::cout << "for begin - end test start-----" << std::endl; + for (auto& iter : ints) + { + std::cout << iter << std::endl; + } + std::cout << "for begin - end test end-----" << std::endl; + + std::cout << ints[3] << std::endl; + std::cout << ints.Count() << std::endl; + { + B b2{ "b2" }; + DynArray bs; + bs.Append(b1) + .Append(std::move(b2)) + .Append(b3); + bs[2] = B("B modified"); + } + { + DynArray bs; + bs.Append(B("A1")) + .Append(B("A2")) + .Append(B("A3")) + .Append(B("A4")) + .Append(B("A5")); + } +} + +int main(int argc, char**argv) +{ + TestDynArrray(); + return 0; +} \ No newline at end of file diff --git a/Source/Core/UnitTest/UTKTL.SharedPtr.cpp b/Source/Core/UnitTest/UTKTL.SharedPtr.cpp new file mode 100644 index 0000000..d37729c --- /dev/null +++ b/Source/Core/UnitTest/UTKTL.SharedPtr.cpp @@ -0,0 +1,130 @@ +#include "Common.h" +#include +#include +#include + +#if K3DPLATFORM_OS_WIN +#pragma comment(linker,"/subsystem:console") +#endif + +using namespace std; +using namespace k3d; + +class SharedTest +{ +public: + SharedTest() + { + + } + ~SharedTest() + { + cout << "SharedTest Destroy. " << endl; + } +}; + +class ESFT; + +class ESFTChild1 +{ +public: + ESFTChild1(SharedPtr pERoot) + : Root(pERoot) + { + cout << "ESFTChild1 init .." << endl; +#if K3DPLATFORM_OS_WIN + OutputDebugStringA("ESFTChild1 init ..\n"); +#endif + } + ~ESFTChild1() + { + cout << "ESFTChild1 release .." << endl; +#if K3DPLATFORM_OS_WIN + OutputDebugStringA("ESFTChild1 release ..\n"); +#endif + } + SharedPtr Root; +}; + +class Root +{ +public: + static DynArray< SharedPtr< ESFT > > root; + static DynArray< SharedPtr > childrenTracker; +}; + +DynArray< SharedPtr< ESFT > > Root::root; +DynArray< SharedPtr > Root::childrenTracker; + +class ESFT : public EnableSharedFromThis +{ +public: + ESFT() + { +#if K3DPLATFORM_OS_WIN + OutputDebugStringA ("ESFT init ..\n"); +#endif + } + ~ESFT() + { +#if K3DPLATFORM_OS_WIN + OutputDebugStringA("ESFT release ..\n"); +#endif + cout << "ESFT release .." << endl; + } + SharedPtr NewChild1() + { + auto child = MakeShared(SharedFromThis()); + Root::childrenTracker.Append(child); + return child; + } +}; + +void TestSharedPtr() +{ + SharedPtr spFile(new Os::File); + cout << "file:" << spFile.UseCount() << endl; + + SharedPtr spCam(new CameraData); + spCam.UseCount(); + spCam->SetName("TestSharedPtr"); + + SharedPtr spTest(new SharedTest); + cout << "SharedTest:" << spTest.UseCount() << endl; + + SharedPtr ioFile = spFile; + K3D_ASSERT(ioFile.UseCount()==2); + + { + WeakPtr weakRef(ioFile); + cout << "weakREf:" << ioFile.UseCount() << endl; + } + + auto makeShared = MakeShared(); + makeShared->Open(KT("TestSharedPtr"), IOWrite); + + auto esft = MakeShared(); + Root::root. Append (esft); + { + auto child = esft->NewChild1(); + } + auto child2 = esft->NewChild1(); + auto refMakeShared = makeShared; + cout << "refMakeShared:" << refMakeShared.UseCount() << endl; + + refMakeShared->Close(); +} + +int atexit(void) +{ +#if K3DPLATFORM_OS_WIN + OutputDebugStringA("At Exit ..\n"); +#endif + return 0; +} + +int main(int argc, char**argv) +{ + TestSharedPtr(); + return 0; +} diff --git a/Source/Core/UnitTest/UTTools.ShaderCompiler.cpp b/Source/Core/UnitTest/UTTools.ShaderCompiler.cpp new file mode 100644 index 0000000..1463766 --- /dev/null +++ b/Source/Core/UnitTest/UTTools.ShaderCompiler.cpp @@ -0,0 +1,94 @@ +#include "Common.h" +#include +#include + +#if K3DPLATFORM_OS_WIN +#pragma comment(linker,"/subsystem:console") +#endif + +using namespace std; +using namespace k3d; + +void TestShaderCompiler() +{ + Os::MemMapFile vShFile; + vShFile.Open("../../Data/Test/testCompiler.glsl", IOFlag::IORead); + String vertexSource((const char*)vShFile.FileData()); + vShFile.Close(); + + auto shMod = StaticPointerCast(GlobalModuleManager.FindModule("ShaderCompiler")); + if (shMod) + { + // test compile + SharedPtr vkCompiler = shMod->CreateShaderCompiler(rhi::ERHI_Vulkan); + if (vkCompiler) + { + rhi::ShaderDesc desc = { rhi::EShFmt_Text, rhi::EShLang_GLSL, rhi::EShProfile_Modern, rhi::ES_Vertex, "main" }; + rhi::ShaderBundle bundle; + auto ret = vkCompiler->Compile(vertexSource, desc, bundle); + K3D_ASSERT(ret == rhi::shc::E_Ok); + + // test shader serialize + Os::File shBundle; + shBundle.Open(KT("shaderbundle.sh"), IOWrite); + Archive ar; + ar.SetIODevice(&shBundle); + ar << bundle; + shBundle.Close(); + + // write spirv to file + Os::File spirvFile; + spirvFile.Open(KT("triangle.spv"), IOWrite); + spirvFile.Write(bundle.RawData.Data(), bundle.RawData.Length()); + spirvFile.Close(); + + // test shader deserialize; + Os::File shBundleRead; + rhi::ShaderBundle bundleRead; + shBundleRead.Open(KT("shaderbundle.sh"), IORead); + Archive readar; + readar.SetIODevice(&shBundleRead); + readar >> bundleRead; + shBundleRead.Close(); + + // test hlsl compile + rhi::ShaderBundle hlslBundle; + Os::MemMapFile hlslVertFile; + hlslVertFile.Open("../../Data/Test/TestMaterial.hlsl", IOFlag::IORead); + rhi::ShaderDesc hlsldesc = { rhi::EShFmt_Text, rhi::EShLang_HLSL, rhi::EShProfile_Modern, rhi::ES_Vertex, "main" }; + auto hlslret = vkCompiler->Compile(String((const char*)hlslVertFile.FileData()), hlsldesc, hlslBundle); + K3D_ASSERT(hlslret == rhi::shc::E_Ok); + + // test spirv reflect + Os::MemMapFile spirvFileRead; + rhi::ShaderBundle spirvBundle; + spirvFileRead.Open(KT("triangle.spv"), IORead); + rhi::ShaderDesc spirvDesc = { rhi::EShFmt_ByteCode, rhi::EShLang_GLSL, rhi::EShProfile_Modern, rhi::ES_Vertex, "main" }; + auto spirvRet = vkCompiler->Compile(String(spirvFileRead.FileData(), spirvFileRead.GetSize()), spirvDesc, spirvBundle); + K3D_ASSERT(spirvRet == rhi::shc::E_Ok); + } + + SharedPtr mtlCompiler = shMod->CreateShaderCompiler(rhi::ERHI_Metal); + if(mtlCompiler) + { + rhi::ShaderDesc desc = { rhi::EShFmt_Text, rhi::EShLang_GLSL, rhi::EShProfile_Modern, rhi::ES_Vertex, "main" }; + rhi::ShaderBundle bundle; + auto ret = mtlCompiler->Compile(vertexSource, desc, bundle); + K3D_ASSERT(ret == rhi::shc::E_Ok); + + // test shader serialize + Os::File shBundle; + shBundle.Open(KT("metalshaderbundle.sh"), IOWrite); + Archive ar; + ar.SetIODevice(&shBundle); + ar << bundle; + shBundle.Close(); + } + } +} + +int main(int argc, char**argv) +{ + TestShaderCompiler(); + return 0; +} \ No newline at end of file diff --git a/Source/Core/Utils/MD5.cpp b/Source/Core/Utils/MD5.cpp index 267e42a..99b767d 100755 --- a/Source/Core/Utils/MD5.cpp +++ b/Source/Core/Utils/MD5.cpp @@ -1,8 +1,10 @@ #include "Kaleido3D.h" #include "MD5.h" - +#ifndef DISABLE_STL using namespace std; +#endif // !DISABLE_STL + /* Constants for MD5Transform routine. */ #define S11 7 @@ -79,6 +81,7 @@ MD5::MD5(const void* input, size_t length) { update(input, length); } +#ifndef DISABLE_STL /* Construct a MD5 object with a string. */ MD5::MD5(const string& str) { reset(); @@ -90,6 +93,7 @@ MD5::MD5(ifstream& in) { reset(); update(in); } +#endif /* Return the message-digest */ const byte* MD5::digest() { @@ -119,6 +123,7 @@ void MD5::update(const void* input, size_t length) { update((const byte*)input, length); } +#ifndef DISABLE_STL /* Updating the context with a string. */ void MD5::update(const string& str) { update((const byte*)str.c_str(), str.length()); @@ -142,6 +147,7 @@ void MD5::update(ifstream& in) { } in.close(); } +#endif /* MD5 block update operation. Continues an MD5 message-digest operation, processing another message block, and updating the @@ -326,9 +332,9 @@ void MD5::decode(const byte* input, uint32* output, size_t length) { } } +#ifndef DISABLE_STL /* Convert byte array to hex string. */ string MD5::bytesToHexString(const byte* input, size_t length) { - string str; str.reserve(length << 1); for (size_t i = 0; i < length; ++i) { @@ -344,4 +350,24 @@ string MD5::bytesToHexString(const byte* input, size_t length) { /* Convert digest to string value */ string MD5::toString() { return bytesToHexString(digest(), 16); +} +#endif + +k3d::String MD5::Str() +{ + k3d::String str; + str.Resize(32); + for (size_t i = 0; i < 16; ++i) { + int t = digest()[i]; + int a = t / 16; + int b = t % 16; + str += HEX[a]; + str += HEX[b]; + } + return str; +} + +void MD5::Update(const k3d::String & str) +{ + update((const byte*)str.CStr(), str.Length()); } \ No newline at end of file diff --git a/Source/Core/Utils/MD5.h b/Source/Core/Utils/MD5.h index 10b06a8..bf3ed0b 100755 --- a/Source/Core/Utils/MD5.h +++ b/Source/Core/Utils/MD5.h @@ -1,27 +1,36 @@ #pragma once +#ifndef DISABLE_STL #include #include +#endif + +#include /* Type define */ typedef unsigned char byte; typedef unsigned int uint32; -using std::string; -using std::ifstream; - /* MD5 declaration. */ -class K3D_API MD5 { +class K3D_API MD5 +{ public: MD5(); MD5(const void* input, size_t length); - MD5(const string& str); - MD5(ifstream& in); void update(const void* input, size_t length); - void update(const string& str); - void update(ifstream& in); + +#ifndef DISABLE_STL + MD5(const std::string& str); + MD5(std::ifstream& in); + void update(const std::string& str); + void update(std::ifstream& in); + std::string toString(); +#endif + void Update(const k3d::String& str); + + k3d::String Str(); + const byte* digest(); - string toString(); void reset(); private: @@ -30,7 +39,10 @@ class K3D_API MD5 { void transform(const byte block[64]); void encode(const uint32* input, byte* output, size_t length); void decode(const byte* input, uint32* output, size_t length); - string bytesToHexString(const byte* input, size_t length); + +#ifndef DISABLE_STL + std::string bytesToHexString(const byte* input, size_t length); +#endif /* class uncopyable */ MD5(const MD5&); diff --git a/Source/Core/Variant.h b/Source/Core/Variant.h deleted file mode 100755 index 51db399..0000000 --- a/Source/Core/Variant.h +++ /dev/null @@ -1,71 +0,0 @@ -/********************************************** -Variant is for Streamable Class -***********************************************/ -#pragma once -#ifndef __k3dVariant_h__ -#define __k3dVariant_h__ -#include -#include "Archive.h" - -namespace k3d { - /// Variant - /// \brief The Variant class - /// A class data Wrapper For all types - class Variant - { - public: - inline Variant() : m_DataSize(0), m_DataPtr(nullptr), m_isDeepCopied(false) - {} - - ~Variant() { - } - - inline void Release() { - if (m_DataSize != 0) - { - ::free(m_DataPtr); - m_DataSize = 0; - } - } - - inline void DeepCopy(void *data, int64 size, bool move = false) - { - if (m_DataPtr == nullptr) - { - m_DataPtr = malloc(size); - m_DataSize = size; - } - ::memcpy(m_DataPtr, data, size); - if (move) { - ::free(data); - } - m_isDeepCopied = true; - } - - inline Variant(void *data, int size) - { - m_DataPtr = data; m_DataSize = size; - m_isDeepCopied = false; - } - - const size_t Size() const { return m_DataSize; } - const void* ConstData() const { return static_cast(m_DataPtr); } - void* Data() { return m_DataPtr; } - - bool IsDeepCopied() const { return m_isDeepCopied; } - - typedef const char Type; - - private: - size_t m_DataSize; - void* m_DataPtr; - bool m_isDeepCopied; - }; - - inline Archive & operator << (Archive & arch, Variant const & data) { - arch.ArrayIn(static_cast(data.ConstData()), (uint32)data.Size()); - return arch; - } -} - -#endif diff --git a/Source/Core/WebSocket.h b/Source/Core/WebSocket.h index 02c737a..d801a3b 100755 --- a/Source/Core/WebSocket.h +++ b/Source/Core/WebSocket.h @@ -1,7 +1,8 @@ #ifndef __WebSocket_H__ #define __WebSocket_H__ -#include +#include "Os.h" + #include namespace net diff --git a/Source/Core/premake5.lua b/Source/Core/premake5.lua deleted file mode 100755 index 8182b72..0000000 --- a/Source/Core/premake5.lua +++ /dev/null @@ -1,38 +0,0 @@ -project "Core" - kind "StaticLib" - language "C++" - - includedirs { - "..", - "../../Include", - } - - pchheader "../../Include/Kaleido3D.h" - - defines { - "MAC_OSX=1" - } - - buildoptions "-std=c++14 -stdlib=libc++" - - files { - "App.h", - "MacOS/App.mm", - "MacOS/ModuleCore.mm", - "LogUtil.h", - "MacOS/LogUtil.mm", - "Utils/MD5.h", - "Utils/MD5.cpp", - "File.h", - "File.cpp", - "Mesh.h", - "Mesh.cpp", - "AssetManager.h", - "AssetManager.cpp", - "Image.h", - "Image.cpp", - "Window.h", - "MacOS/Window.mm", - "ModuleCore.h", - "ModuleCore.cpp" - } diff --git a/Source/Engine/CMakeLists.txt b/Source/Engine/CMakeLists.txt index 4d69e07..87f84eb 100755 --- a/Source/Engine/CMakeLists.txt +++ b/Source/Engine/CMakeLists.txt @@ -1,7 +1,4 @@ - -#if(BUILD_SHARED) - add_definitions(-DBUILD_SHARED_LIB) -#endif() +#include_directories(${RAPIDJSON_INCLUDE_DIR}) set(ENGINE_SRCS Engine.h @@ -84,20 +81,22 @@ source_group( ${PARAM_SRCS} ) -add_library( - Engine ${LIB_TYPE} +k3d_add_lib(Engine +SRCS ${CAMERA_SRCS} ${SCENE_SRCS} ${RENDERER_SRCS} ${ENGINE_SRCS} ${MAT_SRCS} - ${PARAM_SRCS} -) - -target_link_libraries( - Engine - Core -) - -set_target_properties(Engine PROPERTIES FOLDER "Runtime") -add_precompiled_header(Engine "Kaleido3D.h" "${Kaleido3D_ROOT_DIR}/Include" "${Kaleido3D_ROOT_DIR}/Source/Engine/Engine.cpp") \ No newline at end of file + ${PARAM_SRCS} +LIBS + Core +FOLDER + "Runtime") + +add_precompiled_header(Engine "Kaleido3D.h" "${Kaleido3D_ROOT_DIR}/Include" "${Kaleido3D_ROOT_DIR}/Source/Engine/Engine.cpp") + +install(TARGETS Engine + ARCHIVE DESTINATION lib + LIBRARY DESTINATION lib + RUNTIME DESTINATION bin) \ No newline at end of file diff --git a/Source/Engine/Engine.cpp b/Source/Engine/Engine.cpp index 91a9709..5272733 100755 --- a/Source/Engine/Engine.cpp +++ b/Source/Engine/Engine.cpp @@ -4,20 +4,10 @@ namespace k3d { Engine::Engine() { - pRenderer = nullptr; } Engine::~Engine() { - if (pRenderer != nullptr) { - delete pRenderer; - pRenderer = nullptr; - } - } - - void Engine::SetRenderer(IRenderer * renderer) - { - pRenderer = renderer; } void Engine::DoOnInitEngine() @@ -26,13 +16,6 @@ namespace k3d { void Engine::DoOnDrawFrame() { - assert(pRenderer != nullptr && "You should call \"SetRenderer\" method!!"); - pRenderer->PrepareFrame(); - //.... - pRenderer->DrawOneFrame(); - - //.... - pRenderer->EndOneFrame(); } diff --git a/Source/Engine/Engine.h b/Source/Engine/Engine.h index 27ee7f3..4a6aee1 100755 --- a/Source/Engine/Engine.h +++ b/Source/Engine/Engine.h @@ -1,6 +1,5 @@ #pragma once #include -#include namespace k3d { class Engine { @@ -8,8 +7,6 @@ namespace k3d { ~Engine(); - void SetRenderer(IRenderer * renderer); - void DoOnInitEngine(); void DoOnDrawFrame(); @@ -19,7 +16,6 @@ namespace k3d { Engine(); private: - IRenderer *pRenderer; - + }; } diff --git a/Source/Engine/RendererFactory.h b/Source/Engine/RendererFactory.h index 1b751d8..ff48a03 100755 --- a/Source/Engine/RendererFactory.h +++ b/Source/Engine/RendererFactory.h @@ -1,7 +1,5 @@ #pragma once -#include - namespace k3d { class IWindow; diff --git a/Source/Engine/ShaderParameter.h b/Source/Engine/ShaderParameter.h index 1d389ed..fc0483e 100755 --- a/Source/Engine/ShaderParameter.h +++ b/Source/Engine/ShaderParameter.h @@ -1,5 +1,4 @@ #pragma once -#include namespace k3d { diff --git a/Source/Log/CMakeLists.txt b/Source/Log/CMakeLists.txt index 0369c81..d265c28 100755 --- a/Source/Log/CMakeLists.txt +++ b/Source/Log/CMakeLists.txt @@ -1,6 +1,6 @@ set(MODULE_NAME KawaLog) include_directories(.. ../../Include .) -set(LOG_SRCS Public/ILog.h Public/ILogModule.h Private/LogImpl.cpp) +set(LOG_SRCS Public/ILogModule.h Private/LogImpl.cpp) source_group(Log FILES ${LOG_SRCS}) -add_plugin(KawaLog "Runtime/Plugins" ${LOG_SRCS}) +add_plugin(KawaLog FOLDER "Runtime/Plugins" SRCS ${LOG_SRCS}) add_precompiled_header(${MODULE_NAME} "Kaleido3D.h" "${Kaleido3D_ROOT_DIR}/Include" "${Kaleido3D_ROOT_DIR}/Source/Log/Private/LogImpl.cpp") \ No newline at end of file diff --git a/Source/Log/Private/LogImpl.cpp b/Source/Log/Private/LogImpl.cpp index 292eda5..777c2e9 100755 --- a/Source/Log/Private/LogImpl.cpp +++ b/Source/Log/Private/LogImpl.cpp @@ -5,7 +5,6 @@ #include #include -#include #include #include diff --git a/Source/Log/Public/ILogModule.h b/Source/Log/Public/ILogModule.h index 8c36330..c09ea9a 100755 --- a/Source/Log/Public/ILogModule.h +++ b/Source/Log/Public/ILogModule.h @@ -2,7 +2,7 @@ #define __ILogModule_h__ #include -#include "ILog.h" +#include namespace k3d { @@ -22,4 +22,7 @@ namespace k3d } +#if BUILD_STATIC_PLUGIN +K3D_STATIC_MODULE_DECLARE(KawaLog); +#endif #endif // !__ILogModule_h__ diff --git a/Source/Platform/Apple/CpuUsage.mm b/Source/Platform/Apple/CpuUsage.mm new file mode 100644 index 0000000..3ecf27a --- /dev/null +++ b/Source/Platform/Apple/CpuUsage.mm @@ -0,0 +1,88 @@ +#include "Kaleido3D.h" +#include +#include +#include +#include + +struct __CPU_Ticks +{ + uint64 usertime; + uint64 nicetime; + uint64 systemtime; + uint64 idletime; + + uint64 used() { return usertime + nicetime + systemtime; } + uint64 total() { return usertime + nicetime + systemtime + idletime; } +}; + +static k3d::DynArray usages; +static k3d::DynArray<__CPU_Ticks> ticks; +static k3d::DynArray<__CPU_Ticks> curTicks; +static int cpuCount = 0; + +int __UpdateCpuUsage(k3d::DynArray<__CPU_Ticks> & ticks) +{ + unsigned int cpu_count; + processor_cpu_load_info_t cpu_load; + mach_msg_type_number_t cpu_msg_count; + int rc = host_processor_info( + mach_host_self( ), + PROCESSOR_CPU_LOAD_INFO, + &cpu_count, + (processor_info_array_t *) &cpu_load, + &cpu_msg_count + ); + + if (rc != 0) + return 1; + + for(int core=0; core - -@interface AAPLAppDelegate : UIResponder - -@property (strong, nonatomic) UIWindow *window; - -@end diff --git a/Source/Platform/Apple/iOS/AAPLAppDelegate.mm b/Source/Platform/Apple/iOS/AAPLAppDelegate.mm deleted file mode 100755 index cef18cb..0000000 --- a/Source/Platform/Apple/iOS/AAPLAppDelegate.mm +++ /dev/null @@ -1,13 +0,0 @@ -/* - Copyright (C) 2015 Apple Inc. All Rights Reserved. - See LICENSE.txt for this sample’s licensing information - - Abstract: - Application delegate for Metal Sample Code - */ - -#import "AAPLAppDelegate.h" - -@implementation AAPLAppDelegate - -@end diff --git a/Source/Platform/Apple/iOS/App.mm b/Source/Platform/Apple/iOS/App.mm new file mode 100755 index 0000000..4352ee4 --- /dev/null +++ b/Source/Platform/Apple/iOS/App.mm @@ -0,0 +1,51 @@ +#include "Kaleido3D.h" +#include +#include + +@implementation AppDelegate +- (BOOL)application:(NSNotification*)notification didFinishLaunchingWithOptions:(NSDictionary*)launchOptions +{ + K3D_UNUSED(notification); + m_App = __entry_ios_main__(); + [self performSelector:@selector(postFinishLaunch) withObject:nil afterDelay:0.0]; + return YES; +} + +- (void)applicationWillResignActive:(NSNotification*)notification +{ + K3D_UNUSED(notification); +} + +- (void)applicationDidBecomeActive:(NSNotification*)notification +{ + K3D_UNUSED(notification); + if(m_App) + { + m_App->OnInit(); + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onFrame) name:@"RHIRender" object:nil]; + } +} + +- (void)applicationWillTerminate:(NSNotification*)notification +{ + K3D_UNUSED(notification); + if(m_App) + { + m_App->OnDestroy(); + [[NSNotificationCenter defaultCenter] removeObserver:self]; + } + } + +- (void) onFrame +{ + if(m_App) + { + k3d::Message msg; + m_App->OnProcess(msg); + } +} + +- (void)postFinishLaunch +{ +} +@end diff --git a/Source/Platform/Apple/iOS/Info.plist b/Source/Platform/Apple/iOS/Info.plist deleted file mode 100755 index 2938aef..0000000 --- a/Source/Platform/Apple/iOS/Info.plist +++ /dev/null @@ -1,37 +0,0 @@ - - - - - CFBundleDevelopmentRegion - en - CFBundleExecutable - ${EXECUTABLE_NAME} - CFBundleIdentifier - com.example.apple-samplecode.${PRODUCT_NAME:rfc1034identifier} - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - ${PRODUCT_NAME} - CFBundlePackageType - APPL - CFBundleShortVersionString - 1.0 - CFBundleSignature - ???? - CFBundleVersion - 1 - LSRequiresIPhoneOS - - UILaunchStoryboardName - LaunchScreen - UIMainStoryboardFile - Main - UIRequiredDeviceCapabilities - - metal - armv7 - - UIRequiresFullScreen - - - diff --git a/Source/Platform/Apple/iOS/LaunchScreen.xib b/Source/Platform/Apple/iOS/LaunchScreen.xib deleted file mode 100755 index 7960e4b..0000000 --- a/Source/Platform/Apple/iOS/LaunchScreen.xib +++ /dev/null @@ -1,44 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Source/Platform/Apple/iOS/Main.storyboard b/Source/Platform/Apple/iOS/Main.storyboard deleted file mode 100755 index 549cbbe..0000000 --- a/Source/Platform/Apple/iOS/Main.storyboard +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Source/Platform/Apple/iOS/ThreadImpl.h b/Source/Platform/Apple/iOS/ThreadImpl.h deleted file mode 100755 index 30f1f65..0000000 --- a/Source/Platform/Apple/iOS/ThreadImpl.h +++ /dev/null @@ -1,18 +0,0 @@ -#pragma once -#include -#include "../TaskManager.h" - -namespace k3d { - - namespace ThreadImpl - { - void getSysInfo(); - void createThread(IBaseThread & task, TaskPriority priority, WThread::ThreadFunctionPtr func); - void createThread(IBaseThread & task, TaskPriority priority, bool deferred, WThread::ThreadFunctionPtr func); - void sleep(uint32 milliSeconds); - void terminateThread(IBaseThread &); - void suspendThread(IBaseThread &); - void resumeThread(IBaseThread &); - } - -} \ No newline at end of file diff --git a/Source/Platform/Apple/iOS/ThreadImpl.mm b/Source/Platform/Apple/iOS/ThreadImpl.mm deleted file mode 100755 index 7697c0e..0000000 --- a/Source/Platform/Apple/iOS/ThreadImpl.mm +++ /dev/null @@ -1,58 +0,0 @@ -#include "ThreadImpl.h" - -#import - - -namespace k3d { - - namespace ThreadImpl - { - void getSysInfo() - { - - } - - void createThread(IBaseThread & task, TaskPriority priority, WThread::ThreadFunctionPtr func) - { - task.m_Handle = [[NSThread alloc] init]; - NSThread * instance = (NSThread*)task.m_Handle; - [instance setThreadPriority:0.0]; - [instance performSelector:@selector(func)]; - [instance start]; - } - - void createThread(IBaseThread & task, TaskPriority priority, bool deferred, WThread::ThreadFunctionPtr func) - { - task.m_Handle = [[NSThread alloc] init]; - NSThread * instance = (NSThread*)task.m_Handle; - [instance setThreadPriority:0.0]; - [instance performSelector:@selector(func)]; - if(!deferred) - [instance start]; - } - - void sleep(uint32 milliSeconds) - { - [NSThread sleepForTimeInterval:milliSeconds]; - } - - void suspendThread(IBaseThread & task) - { - NSThread* instance = (NSThread*)task.m_Handle; - [instance cancel]; - } - - void terminateThread(IBaseThread & task) - { - NSThread* instance = (NSThread*)task.m_Handle; - [instance cancel]; - } - - void resumeThread(IBaseThread & task) - { - NSThread* instance = (NSThread*)task.m_Handle; - [instance start]; - } - } - -} \ No newline at end of file diff --git a/Source/Platform/Apple/iOS/Window.mm b/Source/Platform/Apple/iOS/Window.mm new file mode 100755 index 0000000..6d2128c --- /dev/null +++ b/Source/Platform/Apple/iOS/Window.mm @@ -0,0 +1,165 @@ +#include "Kaleido3D.h" +#include +#include +#import +#import +#import + +@interface MetalView : UIView +@property (nonatomic) CAMetalLayer *metalLayer; +- (void) onRender; +@end + +namespace k3d +{ + namespace WindowImpl + { + class iOSWindow : public IWindow + { + public: + iOSWindow(const kchar *windowName, int width, int height); + ~iOSWindow(); + + int Init(); + void SetWindowCaption(const kchar * name) override; + void Show(WindowMode mode) override; + void Resize(int width, int height) override; + void Move(int x, int y) override; + + + bool IsOpen() override { return true;} + void* GetHandle() const override { return m_Window; }; + + bool PollMessage(Message & messge) override { return PopMessage(messge, true); }; + + uint32 Width() const override {return 0;} + uint32 Height() const override {return 0;} + + virtual void PushMessage(const Message & message); + virtual bool PopMessage(Message & message, bool block); + virtual void ProcessMessage(); + void * handle; + + private: + UIWindow* m_Window; + }; + + iOSWindow::iOSWindow(const kchar *windowName, int width, int height) + : m_Window(nil) + { + Init(); + SetWindowCaption(windowName); + Resize(width, height); + } + + iOSWindow::~iOSWindow() + { + if(nil!=m_Window) + { + [m_Window release]; + m_Window = nil; + } + } + + int iOSWindow::Init() + { + CGRect bounds = [[UIScreen mainScreen] bounds]; + UIViewController* view_controller = [[UIViewController alloc] initWithNibName:nil bundle:nil]; + // create window + UIWindow* window = [[UIWindow alloc] initWithFrame:bounds]; + MetalView * mtlView = [[MetalView alloc] initWithFrame:bounds]; [window setRootViewController:view_controller]; + [window setBackgroundColor:[UIColor blackColor]]; + [window addSubview:mtlView]; + [window makeKeyAndVisible]; + m_Window = window; + return 0; + } + + void iOSWindow::Move(int x, int y) + { + + } + + void iOSWindow::Resize(int width, int height) + { + + } + + void iOSWindow::Show(k3d::WindowMode mode) + { + + } + + void iOSWindow::SetWindowCaption(const kchar *name) + { + + } + + void iOSWindow::PushMessage(const k3d::Message &message) + { + + } + + void iOSWindow::ProcessMessage() + { + + } + + bool iOSWindow::PopMessage(k3d::Message &message, bool block) + { + return true; + } + + } + + IWindow::Ptr MakePlatformWindow(const kchar *windowName, int width, int height) + { + return std::make_shared(windowName, width, height); + } +} + +@implementation MetalView +{ + CADisplayLink *dispLink; +} +@synthesize metalLayer; + +- (BOOL) isOpaque { + return YES; +} + +- (void) onRender +{ + [[NSNotificationCenter defaultCenter] postNotificationName:@"RHIRender" object:nil]; +} + +-(instancetype) initWithFrame:(CGRect)frameRect { + self = [super initWithFrame: frameRect]; + dispLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(onRender)]; + [dispLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes]; + if (self) + { + metalLayer = (CAMetalLayer*)self.layer; + metalLayer.opaque = YES; + } + return self; +} + ++ (Class)layerClass +{ + return [CAMetalLayer class]; +} + +- (BOOL) wantsLayer { + return YES; +} + +- (BOOL) wantsUpdateLayer { + return YES; +} + +- (void)dealloc { + [dispLink invalidate]; +} + +@end diff --git a/Source/Platform/Apple/iOS/WindowImpl.h b/Source/Platform/Apple/iOS/WindowImpl.h deleted file mode 100755 index 984886f..0000000 --- a/Source/Platform/Apple/iOS/WindowImpl.h +++ /dev/null @@ -1,45 +0,0 @@ -#pragma once -#include -#include -#include "../Message.h" - -namespace k3d -{ - enum class WindowMode; - - namespace WindowImpl - { - class WindowPrivate { - public: - WindowPrivate() = default; - - union { - HWND handle; - }; - LONG_PTR callback; - - int Init(); - void SetCaption(const char * name); - void Show(WindowMode mode); - void Resize(int width, int height); - void Move(int x, int y); - - void PushMessage(const Message & message); - bool PopMessage(Message & message, bool block); - void ProcessMessage(); - - static LRESULT CALLBACK WindowProc(HWND hwnd, UINT32 msg, WPARAM wParam, LPARAM lParam); - - protected: - void RegisterWindowClass(); - void ProcessMessage(UINT message, WPARAM wParam, LPARAM lParam); - - std::queue m_MessageQueue; - }; - - extern int InitApp(); - - extern Keyboard::Key virtualKeyCodeToSF(WPARAM key, LPARAM flags); - } - -} \ No newline at end of file diff --git a/Source/Platform/Apple/iOS/WindowImpl.mm b/Source/Platform/Apple/iOS/WindowImpl.mm deleted file mode 100755 index 4521885..0000000 --- a/Source/Platform/Apple/iOS/WindowImpl.mm +++ /dev/null @@ -1 +0,0 @@ -#include "Kaleido3D.h" \ No newline at end of file diff --git a/Source/Platform/Apple/iOS/main.m b/Source/Platform/Apple/iOS/main.m deleted file mode 100755 index a5b047c..0000000 --- a/Source/Platform/Apple/iOS/main.m +++ /dev/null @@ -1,18 +0,0 @@ -// -// main.m -// MetalTemplate -// -// Created by Filip Iliescu on 5/13/14. -// Copyright (c) 2014 Apple Inc. All rights reserved. -// - -#import - -#import "AAPLAppDelegate.h" - -int main(int argc, char * argv[]) -{ - @autoreleasepool { - return UIApplicationMain(argc, argv, nil, NSStringFromClass([AAPLAppDelegate class])); - } -} diff --git a/Source/Platform/Windows/CpuUsage.cpp b/Source/Platform/Windows/CpuUsage.cpp new file mode 100644 index 0000000..bad5c91 --- /dev/null +++ b/Source/Platform/Windows/CpuUsage.cpp @@ -0,0 +1,139 @@ +#include "Kaleido3D.h" +#include + + +#include +#include +#define WIN32_NO_STATUS +#include +#include +#include + +#pragma comment(lib, "wbemuuid.lib") +#pragma comment(lib, "comsuppw.lib") + +static IWbemServices *s_service; +static IWbemLocator *s_locator; +static UINT64 *s_old_time_stamp; +static UINT64 *s_old_pproc_usage; +static UINT s_cores_count; +static float *s_cores_load_data; + +static float *__GetCpuUsage(void) +{ + HRESULT hr = NULL; + ULONG retVal; + UINT i; + + IWbemClassObject *pclassObj; + IEnumWbemClassObject *pEnumerator; + + hr = s_service->ExecQuery(bstr_t("WQL"), bstr_t("SELECT TimeStamp_Sys100NS, PercentProcessorTime, Frequency_PerfTime FROM Win32_PerfRawData_PerfOS_Processor"), + WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, NULL, &pEnumerator); + for (i = 0; i < s_cores_count; i++) { + hr = pEnumerator->Next(WBEM_INFINITE, 1, &pclassObj, &retVal); + if (!retVal) { + break; + } + + VARIANT vtPropTime; + VARIANT vtPropClock; + VariantInit(&vtPropTime); + VariantInit(&vtPropClock); + + hr = pclassObj->Get(L"TimeStamp_Sys100NS", 0, &vtPropTime, 0, 0); + UINT64 newTimeStamp = _wtoi64(vtPropTime.bstrVal); + + hr = pclassObj->Get(L"PercentProcessorTime", 0, &vtPropClock, 0, 0); + UINT64 newPProcUsage = _wtoi64(vtPropClock.bstrVal); + + s_cores_load_data[i] = (float)(1.0 - (((double)newPProcUsage - (double)s_old_pproc_usage[i]) / ((double)newTimeStamp - (double)s_old_time_stamp[i]))) * 100.0f; + + if (s_cores_load_data[i] < 0) s_cores_load_data[i] = 0.0; + else if (s_cores_load_data[i] > 100.0) s_cores_load_data[i] = 100.0; + + s_old_pproc_usage[i] = newPProcUsage; + s_old_time_stamp[i] = newTimeStamp; + + VariantClear(&vtPropTime); + VariantClear(&vtPropClock); + + pclassObj->Release(); + } + + pEnumerator->Release(); + return &s_cores_load_data[0]; +} + +int __Init(void) +{ + IWbemClassObject *pclassObj; + IEnumWbemClassObject *pEnumerator; + HRESULT hr; + ULONG retVal; + + s_service = NULL; + s_cores_count = 0; + + s_old_time_stamp = NULL; + s_old_pproc_usage = NULL; + s_locator = NULL; + + s_cores_load_data = NULL; + + CoInitializeEx(0, COINIT_MULTITHREADED); + CoInitializeSecurity(NULL, -1, NULL, NULL, RPC_C_AUTHN_DEFAULT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, NULL); + + hr = CoCreateInstance(CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER, IID_IWbemLocator, (LPVOID *)&s_locator); + if (FAILED(hr)) { + return 0; + } + hr = s_locator->ConnectServer(_bstr_t(L"ROOT\\CIMV2"), NULL, NULL, 0, NULL, 0, 0, &s_service); + if (FAILED(hr)) { + return 0; + } + + CoSetProxyBlanket(s_service, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL, + RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE); + + hr = s_service->ExecQuery(bstr_t("WQL"), bstr_t("SELECT * FROM Win32_Processor"), + WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, NULL, &pEnumerator); + hr = pEnumerator->Next(WBEM_INFINITE, 1, &pclassObj, &retVal); + if (retVal) { + VARIANT vtProp; + VariantInit(&vtProp); + hr = pclassObj->Get(L"NumberOfLogicalProcessors", 0, &vtProp, 0, 0); + s_cores_count = vtProp.uintVal; + + if (s_cores_count) { + s_old_time_stamp = new UINT64[s_cores_count]; + s_old_pproc_usage = new UINT64[s_cores_count]; + s_cores_load_data = new float[s_cores_count]; + float zeroFloat = 0.0; + memset(s_cores_load_data, *(int*)&zeroFloat, sizeof(float)*s_cores_count); + } + + VariantClear(&vtProp); + } + + pclassObj->Release(); + pEnumerator->Release(); + + // warm-up query engine + for (int i = 0; i < 16; ++i) { + __GetCpuUsage(); + } + return 1; +} + +namespace Os +{ +float* GetCpuUsage() +{ + if (!s_service) + { + __Init(); + } + return __GetCpuUsage(); +} +} diff --git a/Source/RHI/CMakeLists.txt b/Source/RHI/CMakeLists.txt index 3b9578e..2259c50 100755 --- a/Source/RHI/CMakeLists.txt +++ b/Source/RHI/CMakeLists.txt @@ -8,4 +8,9 @@ elseif(ANDROID) add_subdirectory(Vulkan) elseif(IOS OR MACOS) add_subdirectory(Metal) -endif() \ No newline at end of file + add_subdirectory(OpenGL) +endif() + +if(BUILD_WITH_UNIT_TEST) + add_subdirectory(UnitTest) +endif(BUILD_WITH_UNIT_TEST) \ No newline at end of file diff --git a/Source/RHI/Metal/CMakeLists.txt b/Source/RHI/Metal/CMakeLists.txt index 5071736..67057be 100755 --- a/Source/RHI/Metal/CMakeLists.txt +++ b/Source/RHI/Metal/CMakeLists.txt @@ -16,14 +16,18 @@ Private/MetalRHI.h set(INCS Public/IMetalRHI.h Public/MetalRHIResource.h -../IRHI.h -../IRHIDefs.h -../ICrossShaderCompiler.h ) source_group(Private FILES ${SRCS}) source_group(Public FILES ${INCS}) set(CMAKE_CXX_FLAGS "-fobjc-abi-version=2 -fobjc-arc ${CMAKE_CXX_FLAGS}") -add_plugin(${TARGET} "Runtime/RHI" ${SRCS} ${INCS}) +add_plugin(${TARGET} + FOLDER "Runtime/RHI" + SRCS ${SRCS} ${INCS}) + +if(MACOS) target_link_libraries(${TARGET} "-framework Metal" "-framework MetalKit" "-framework AppKit" "-framework Foundation") +elseif(IOS) +target_link_libraries(${TARGET} "-framework Metal" "-framework MetalKit" "-framework UIKit" "-framework Foundation") +endif() diff --git a/Source/RHI/Metal/Common.h b/Source/RHI/Metal/Common.h index 15a22f3..447384d 100755 --- a/Source/RHI/Metal/Common.h +++ b/Source/RHI/Metal/Common.h @@ -8,4 +8,10 @@ #import #include +#define MTLLOG(Level, ...) \ +::k3d::Log(::k3d::ELogLevel::Level, "kaleido3d::MetalRHI", __VA_ARGS__); + +#define MTLLOGI(...) MTLLOG(Info, __VA_ARGS__); +#define MTLLOGE(...) MTLLOG(Error, __VA_ARGS__); + #endif diff --git a/Source/RHI/Metal/Private/MetalBuffer.mm b/Source/RHI/Metal/Private/MetalBuffer.mm index 51a3858..dc2eb86 100755 --- a/Source/RHI/Metal/Private/MetalBuffer.mm +++ b/Source/RHI/Metal/Private/MetalBuffer.mm @@ -1,6 +1,58 @@ #include "Public/MetalRHIResource.h" +#include "Private/MetalRHI.h" NS_K3D_METAL_BEGIN +Buffer::Buffer(Device* device, rhi::ResourceDesc const & desc) +: m_Desc(desc) +, m_Device(device) +{ + m_Buf = [m_Device->GetDevice() + newBufferWithLength:desc.Size + options: MTLResourceStorageModeManaged]; +} + +Buffer::~Buffer() +{ + if(m_Buf) + { + [m_Buf release]; + m_Buf = nil; + } +} + +void * Buffer::Map(uint64 start, uint64 size) +{ + m_MapRange.location = start; + m_MapRange.length = size; + return [m_Buf contents]; +} + +void Buffer::UnMap() +{ +#if K3DPLATFORM_OS_MAC + [m_Buf didModifyRange:m_MapRange]; +#endif +} + +uint64 Buffer::GetLocation() const +{ + return (uint64)m_Buf; +} + +rhi::ResourceDesc Buffer::GetDesc() const +{ + return m_Desc; +} + +rhi::EResourceState Buffer::GetState() const +{ + return rhi::ERS_Unknown; +} + +uint64 Buffer::GetSize() const +{ + return m_Buf.length; +} NS_K3D_METAL_END diff --git a/Source/RHI/Metal/Private/MetalCommandContext.mm b/Source/RHI/Metal/Private/MetalCommandContext.mm index c50aa4e..33d5c0c 100755 --- a/Source/RHI/Metal/Private/MetalCommandContext.mm +++ b/Source/RHI/Metal/Private/MetalCommandContext.mm @@ -1,11 +1,14 @@ #include "Kaleido3D.h" +#include "Math/IK.hpp" #include "MetalRHI.h" +#include "MetalEnums.h" NS_K3D_METAL_BEGIN -CommandContext::CommandContext() +CommandContext::CommandContext(rhi::ECommandType const & cmdType, id cmdBuf) +: m_CommandType(cmdType) +, m_CmdBuffer(cmdBuf) { - } CommandContext::~CommandContext() @@ -18,6 +21,18 @@ } +void CommandContext::Begin() +{ + if(m_CommandType == rhi::ECMD_Compute) + { + m_ComputeEncoder = [m_CmdBuffer computeCommandEncoder]; + } + else if(m_CommandType == rhi::ECMD_Bundle) + { + m_ParallelRenderEncoder = [m_CmdBuffer parallelRenderCommandEncoderWithDescriptor:m_RenderpassDesc]; + } +} + void CommandContext::CopyTexture(const rhi::TextureCopyLocation& Dest, const rhi::TextureCopyLocation& Src) { @@ -30,53 +45,107 @@ void CommandContext::Execute(bool Wait) { - + [m_CmdBuffer commit]; } void CommandContext::Reset() { - +} + +void CommandContext::BeginRendering() +{ +} + +void CommandContext::SetRenderTarget(rhi::RenderTargetRef pRenderTarget) +{ + auto pRt = k3d::StaticPointerCast(pRenderTarget); + m_RenderpassDesc = pRt->m_RenderPassDescriptor; + m_RenderEncoder = [m_CmdBuffer renderCommandEncoderWithDescriptor:m_RenderpassDesc]; } void CommandContext::SetIndexBuffer(const rhi::IndexBufferView& IBView) { - + m_TmpIndexBuffer = (id)IBView.BufferLocation; } void CommandContext::SetVertexBuffer(uint32 Slot, const rhi::VertexBufferView& VBView) { - + [m_RenderEncoder setVertexBuffer:(id)VBView.BufferLocation offset:0 atIndex:Slot]; } -void CommandContext::SetPipelineState(uint32 HashCode, rhi::PipelineStateObjectRef) +void CommandContext::SetPipelineState(uint32 HashCode, rhi::PipelineStateObjectRef pPipelineState) { - + if(!pPipelineState) + { + MTLLOGE("CommandContext::setPipelineState pPipelineState==null!"); + return; + } + auto mtlPs = StaticPointerCast(pPipelineState); + if(pPipelineState->GetType() == rhi::EPSO_Graphics) + { + [m_RenderEncoder setRenderPipelineState: mtlPs->m_RenderPipelineState]; + [m_RenderEncoder setDepthStencilState: mtlPs->m_DepthStencilState]; + [m_RenderEncoder setCullMode: mtlPs->m_CullMode]; + m_CurPrimType = mtlPs->m_PrimitiveType; + } + else + { + [m_ComputeEncoder setComputePipelineState: mtlPs->m_ComputePipelineState]; + } } -void CommandContext::SetViewport(const rhi::ViewportDesc &) +void CommandContext::SetViewport(const rhi::ViewportDesc & vpDesc) { - + MTLViewport viewport = { vpDesc.Left, vpDesc.Top, vpDesc.Width, vpDesc.Height, vpDesc.MinDepth, vpDesc.MaxDepth }; + [m_RenderEncoder setViewport:viewport]; } -void CommandContext::SetPrimitiveType(rhi::EPrimitiveType) +void CommandContext::SetPrimitiveType(rhi::EPrimitiveType Type) { - + m_CurPrimType = g_PrimitiveType[Type]; } -void CommandContext::DrawInstanced(rhi::DrawInstancedParam) +void CommandContext::DrawInstanced(rhi::DrawInstancedParam param) { - + [m_RenderEncoder drawPrimitives:m_CurPrimType + vertexStart:param.StartVertexLocation + vertexCount:param.VertexCountPerInstance + instanceCount:param.InstanceCount + baseInstance:param.StartInstanceLocation]; } -void CommandContext::DrawIndexedInstanced(rhi::DrawIndexedInstancedParam) +void CommandContext::DrawIndexedInstanced(rhi::DrawIndexedInstancedParam param) { - + [m_RenderEncoder drawIndexedPrimitives:m_CurPrimType + indexCount:param.IndexCountPerInstance + indexType:MTLIndexTypeUInt32 + indexBuffer:m_TmpIndexBuffer + indexBufferOffset:param.StartIndexLocation]; +} + +void CommandContext::EndRendering() +{ + [m_RenderEncoder endEncoding]; } void CommandContext::Dispatch(uint32 x, uint32 y, uint32 z) +{ + [m_ComputeEncoder dispatchThreadgroups:MTLSizeMake(x, y, z) threadsPerThreadgroup:MTLSizeMake(x, y, z)]; +} + +void CommandContext::End() { } +void CommandContext::PresentInViewport(rhi::RenderViewportRef rvp) +{ + [m_CmdBuffer addCompletedHandler:^(id buffer) { + + }]; + auto vp = k3d::StaticPointerCast(rvp); + [m_CmdBuffer presentDrawable:vp->m_CurrentDrawable]; + [m_CmdBuffer commit]; +} NS_K3D_METAL_END diff --git a/Source/RHI/Metal/Private/MetalDevice.mm b/Source/RHI/Metal/Private/MetalDevice.mm index 5f86ffc..9219e7d 100755 --- a/Source/RHI/Metal/Private/MetalDevice.mm +++ b/Source/RHI/Metal/Private/MetalDevice.mm @@ -9,7 +9,12 @@ #include #include "MetalRHI.h" #include "MetalEnums.h" -#import +#if K3DPLATFORM_OS_MAC +#include +#else +#include +#endif + #import #define __debugbreak __builtin_trap @@ -20,6 +25,10 @@ { } +Device::Device(id pDevice) : m_Device(pDevice) +{ +} + Device::~Device() { } @@ -37,23 +46,14 @@ K3D_ASSERT(adapter!=nullptr); m_Device = static_cast(adapter)->m_Device; m_CommandQueue = [m_Device newCommandQueue]; -// m_MetalLayer = [CAMetalLayer layer]; -// m_MetalLayer.device = m_Device; -// m_MetalLayer.pixelFormat = MTLPixelFormatBGRA8Unorm; -// m_MetalLayer.framebufferOnly = YES; return Result::DeviceFound; } rhi::CommandContextRef Device::NewCommandContext(rhi::ECommandType Type) { - return nullptr; -} - -rhi::GpuResourceRef -Device::NewGpuResource(rhi::ResourceDesc const&) -{ - return nullptr; + id CmdBuf = [m_CommandQueue commandBuffer]; + return k3d::MakeShared(Type, CmdBuf); } rhi::ShaderResourceViewRef @@ -69,9 +69,9 @@ } rhi::PipelineStateObjectRef -Device::NewPipelineState(rhi::PipelineDesc const&,rhi::PipelineLayoutRef,rhi::EPipelineType) +Device::NewPipelineState(rhi::PipelineDesc const& desc,rhi::PipelineLayoutRef,rhi::EPipelineType type) { - return nullptr; + return k3d::MakeShared(m_Device, desc, type); } rhi::PipelineLayoutRef @@ -92,22 +92,50 @@ return nullptr; } +// The pixel format for a Metal layer must be bgra8Unorm, bgra8Unorm_srgb, or rgba16Float. +// The default value is bgra8Unorm. https://developer.apple.com/reference/quartzcore/cametallayer/1478155-pixelformat +MTLPixelFormat CorrectFormat(rhi::GfxSetting & setting) +{ + auto pf = g_PixelFormat[setting.ColorFormat]; + switch (pf) { + case MTLPixelFormatRGBA16Float: + case MTLPixelFormatBGRA8Unorm_sRGB: + case MTLPixelFormatBGRA8Unorm: + return pf; + default: + setting.ColorFormat = rhi::EPF_BGRA8Unorm; + break; + } + return g_PixelFormat[setting.ColorFormat]; +} + rhi::RenderViewportRef Device::NewRenderViewport(void * winHandle, rhi::GfxSetting & setting) { +#if K3DPLATFORM_OS_MAC NSWindow* nWindow = (__bridge NSWindow*)winHandle; NSView* view = nWindow.contentView; NSRect rect = [view frame]; +#else + UIWindow* nWindow = (__bridge UIWindow*)winHandle; + UIView* view = nWindow.subviews[0]; + CGRect rect = [view frame]; +#endif setting.Width = rect.size.width; setting.Height = rect.size.height; - CAMetalLayer* mtlayer = (CAMetalLayer*)nWindow.contentView.layer; - mtlayer.device = GetDevice(); + CAMetalLayer* mtlayer = (CAMetalLayer*)view.layer; + mtlayer.device = GetDevice(); + mtlayer.pixelFormat = CorrectFormat(setting); + mtlayer.framebufferOnly = YES; return k3d::MakeShared(mtlayer); } RenderViewport::RenderViewport(CAMetalLayer * mtlLayer) : m_Layer(mtlLayer) +, m_CurrentDrawable(nil) +, m_RenderPassDescriptor(nil) { + m_RenderPassDescriptor = [MTLRenderPassDescriptor renderPassDescriptor]; } RenderViewport::~RenderViewport() @@ -118,14 +146,156 @@ { m_Width = setting.Width; m_Height = setting.Height; - [m_Layer nextDrawable]; + m_CurrentDrawable = [m_Layer nextDrawable]; + id texture = m_CurrentDrawable.texture; + MTLRenderPassColorAttachmentDescriptor *colorAttachment = m_RenderPassDescriptor.colorAttachments[0]; + colorAttachment.texture = texture; + + // make sure to clear every frame for best performance + colorAttachment.loadAction = MTLLoadActionClear; + colorAttachment.clearColor = MTLClearColorMake(0.65f, 0.65f, 0.65f, 1.0f); + + // if sample count is greater than 1, render into using MSAA, then resolve into our color texture +// if(_sampleCount > 1) +// { +// BOOL doUpdate = ( _msaaTex.width != texture.width ) +// || ( _msaaTex.height != texture.height ) +// || ( _msaaTex.sampleCount != _sampleCount ); +// +// if(!_msaaTex || (_msaaTex && doUpdate)) +// { +// MTLTextureDescriptor* desc = [MTLTextureDescriptor texture2DDescriptorWithPixelFormat: MTLPixelFormatBGRA8Unorm +// width: texture.width +// height: texture.height +// mipmapped: NO]; +// desc.textureType = MTLTextureType2DMultisample; +// +// // sample count was specified to the view by the renderer. +// // this must match the sample count given to any pipeline state using this render pass descriptor +// desc.sampleCount = _sampleCount; +// +// _msaaTex = [_device newTextureWithDescriptor: desc]; +// } +// +// // When multisampling, perform rendering to _msaaTex, then resolve +// // to 'texture' at the end of the scene +// colorAttachment.texture = _msaaTex; +// colorAttachment.resolveTexture = texture; +// +// // set store action to resolve in this case +// colorAttachment.storeAction = MTLStoreActionMultisampleResolve; +// } +// else + { + // store only attachments that will be presented to the screen, as in this case + colorAttachment.storeAction = MTLStoreActionStore; + } // color0 + + // Now create the depth and stencil attachments + + if(setting.HasDepth) + { +// BOOL doUpdate = ( _depthTex.width != texture.width ) +// || ( _depthTex.height != texture.height ) +// || ( _depthTex.sampleCount != _sampleCount ); +// +// if(!_depthTex || doUpdate) +// { + // If we need a depth texture and don't have one, or if the depth texture we have is the wrong size + // Then allocate one of the proper size + MTLTextureDescriptor* desc = [MTLTextureDescriptor texture2DDescriptorWithPixelFormat: g_PixelFormat[setting.DepthStencilFormat] + width: texture.width + height: texture.height + mipmapped: NO]; + + desc.textureType = /*(_sampleCount > 1) ? MTLTextureType2DMultisample :*/ MTLTextureType2D; +#if K3DPLATFORM_OS_MAC + desc.resourceOptions = MTLResourceStorageModePrivate; + desc.usage = MTLTextureUsageRenderTarget; +#endif + //desc.sampleCount = _sampleCount; + + m_DepthTex = [m_Layer.device newTextureWithDescriptor: desc]; + + MTLRenderPassDepthAttachmentDescriptor *depthAttachment = m_RenderPassDescriptor.depthAttachment; + depthAttachment.texture = m_DepthTex; + depthAttachment.loadAction = MTLLoadActionClear; + depthAttachment.storeAction = MTLStoreActionDontCare; + depthAttachment.clearDepth = 1.0; +// } + } // depth + +// if(_stencilPixelFormat != MTLPixelFormatInvalid) +// { +// BOOL doUpdate = ( _stencilTex.width != texture.width ) +// || ( _stencilTex.height != texture.height ) +// || ( _stencilTex.sampleCount != _sampleCount ); +// +// if(!_stencilTex || doUpdate) +// { +// // If we need a stencil texture and don't have one, or if the depth texture we have is the wrong size +// // Then allocate one of the proper size +// MTLTextureDescriptor* desc = [MTLTextureDescriptor texture2DDescriptorWithPixelFormat: _stencilPixelFormat +// width: texture.width +// height: texture.height +// mipmapped: NO]; +// +// desc.textureType = (_sampleCount > 1) ? MTLTextureType2DMultisample : MTLTextureType2D; +// desc.sampleCount = _sampleCount; +// +// _stencilTex = [_device newTextureWithDescriptor: desc]; +// +// MTLRenderPassStencilAttachmentDescriptor* stencilAttachment = m_RenderPassDescriptor.stencilAttachment; +// stencilAttachment.texture = _stencilTex; +// stencilAttachment.loadAction = MTLLoadActionClear; +// stencilAttachment.storeAction = MTLStoreActionDontCare; +// stencilAttachment.clearStencil = 0; +// } +// } //stencil + return true; } +void RenderViewport::PrepareNextFrame() +{ + m_CurrentDrawable = [m_Layer nextDrawable]; +} + +rhi::RenderTargetRef +RenderViewport::GetCurrentBackRenderTarget() +{ + return k3d::MakeShared(m_RenderPassDescriptor, m_CurrentDrawable.texture); +} + rhi::RenderTargetRef Device::NewRenderTarget(rhi::RenderTargetLayout const&) { return nullptr; } +RenderTarget::RenderTarget(MTLRenderPassDescriptor* rpd, id color) +: m_RenderPassDescriptor(rpd) +, m_ColorTexture(color) +{ +} + +RenderTarget::~RenderTarget() +{ +} + +void RenderTarget::SetClearColor(kMath::Vec4f clrColor) +{ + +} + +void RenderTarget::SetClearDepthStencil(float depth, uint32 stencil) +{ + +} + +rhi::GpuResourceRef RenderTarget::GetBackBuffer() +{ + return nullptr; +} + NS_K3D_METAL_END diff --git a/Source/RHI/Metal/Private/MetalEnums.h b/Source/RHI/Metal/Private/MetalEnums.h index 3d0678c..68cca44 100755 --- a/Source/RHI/Metal/Private/MetalEnums.h +++ b/Source/RHI/Metal/Private/MetalEnums.h @@ -3,103 +3,150 @@ #define __MetalEnums_h__ #include "../Common.h" -#include +#include NS_K3D_METAL_BEGIN -/* - Points, - Lines, - Triangles, - TriangleStrip, - */ -MTLPrimitiveType g_PrimitiveType[] = { - MTLPrimitiveTypePoint, - MTLPrimitiveTypeLine, - MTLPrimitiveTypeTriangle, - MTLPrimitiveTypeTriangleStrip, -}; -/* - None, - Front, - Back, - */ -MTLCullMode g_CullMode[] = { - MTLCullModeNone, - MTLCullModeFront, - MTLCullModeBack -}; -/* - WireFrame, - Solid, - */ -MTLTriangleFillMode g_FillMode[] = { - MTLTriangleFillModeLines, - MTLTriangleFillModeFill -}; -/* - Add, - Sub, - */ -MTLBlendOperation g_BlendOperation[] = { - MTLBlendOperationAdd, - MTLBlendOperationSubtract -}; -/* - Zero, - One, - SrcColor, - DestColor, - SrcAlpha, - DestAlpha, - BlendTypeNum - */ -MTLBlendFactor g_BlendFactor[] = { - MTLBlendFactorZero, - MTLBlendFactorOne, - MTLBlendFactorSourceColor, - MTLBlendFactorDestinationColor, - MTLBlendFactorSourceAlpha, - MTLBlendFactorDestinationAlpha -}; -/* - Keep, - Zero, - Replace, - Invert, - Increment, - Decrement, - */ -MTLStencilOperation g_StencilOp[] = { - MTLStencilOperationKeep, - MTLStencilOperationZero, - MTLStencilOperationReplace, - MTLStencilOperationInvert, - MTLStencilOperationIncrementClamp, // TODO - MTLStencilOperationDecrementClamp // TODO -}; -/*Never, - Less, - Equal, - LessEqual, - Greater, - NotEqual, - GreaterEqual, - Always, - */ -MTLCompareFunction g_ComparisonFunc[] = { - MTLCompareFunctionLess, - MTLCompareFunctionEqual, - MTLCompareFunctionLessEqual, - MTLCompareFunctionGreater, - MTLCompareFunctionNotEqual, - MTLCompareFunctionGreaterEqual, - MTLCompareFunctionAlways -}; -/* - WriteZero, - WriteAll, -*/ + +namespace +{ + /** + EPF_RGBA16Uint, + EPF_RGBA32Float, + EPF_RGBA8Unorm, + EPF_RGBA8Unorm_sRGB, + EPF_R11G11B10Float, + EPF_D32Float, + EPF_RGB32Float, + EPF_RGB8Unorm, + */ + MTLPixelFormat g_PixelFormat[] = { + MTLPixelFormatRGBA16Uint, + MTLPixelFormatRGBA32Float, + MTLPixelFormatRGBA8Unorm, + MTLPixelFormatRGBA8Unorm_sRGB, + MTLPixelFormatRG11B10Float, + MTLPixelFormatDepth32Float, + MTLPixelFormatInvalid, + MTLPixelFormatInvalid, + MTLPixelFormatBGRA8Unorm, + MTLPixelFormatBGRA8Unorm_sRGB, + MTLPixelFormatRGBA16Float, + }; + + /* + Points, + Lines, + Triangles, + TriangleStrip, + */ + MTLPrimitiveType g_PrimitiveType[] = { + MTLPrimitiveTypePoint, + MTLPrimitiveTypeLine, + MTLPrimitiveTypeTriangle, + MTLPrimitiveTypeTriangleStrip, + }; + /* + None, + Front, + Back, + */ + MTLCullMode g_CullMode[] = { + MTLCullModeNone, + MTLCullModeFront, + MTLCullModeBack + }; + /* + WireFrame, + Solid, + */ + MTLTriangleFillMode g_FillMode[] = { + MTLTriangleFillModeLines, + MTLTriangleFillModeFill + }; + /* + Add, + Sub, + */ + MTLBlendOperation g_BlendOperation[] = { + MTLBlendOperationAdd, + MTLBlendOperationSubtract + }; + /* + Zero, + One, + SrcColor, + DestColor, + SrcAlpha, + DestAlpha, + BlendTypeNum + */ + MTLBlendFactor g_BlendFactor[] = { + MTLBlendFactorZero, + MTLBlendFactorOne, + MTLBlendFactorSourceColor, + MTLBlendFactorDestinationColor, + MTLBlendFactorSourceAlpha, + MTLBlendFactorDestinationAlpha + }; + /* + Keep, + Zero, + Replace, + Invert, + Increment, + Decrement, + */ + MTLStencilOperation g_StencilOp[] = { + MTLStencilOperationKeep, + MTLStencilOperationZero, + MTLStencilOperationReplace, + MTLStencilOperationInvert, + MTLStencilOperationIncrementClamp, // TODO + MTLStencilOperationDecrementClamp // TODO + }; + /*Never, + Less, + Equal, + LessEqual, + Greater, + NotEqual, + GreaterEqual, + Always, + */ + MTLCompareFunction g_ComparisonFunc[] = { + MTLCompareFunctionLess, + MTLCompareFunctionEqual, + MTLCompareFunctionLessEqual, + MTLCompareFunctionGreater, + MTLCompareFunctionNotEqual, + MTLCompareFunctionGreaterEqual, + MTLCompareFunctionAlways + }; + /* + WriteZero, + WriteAll, + */ + + /*enum EVertexFormat + { + EVF_Float1x32, + EVF_Float2x32, + EVF_Float3x32, + EVF_Float4x32, + */ + MTLVertexFormat g_VertexFormats[] = { + MTLVertexFormatFloat, + MTLVertexFormatFloat2, + MTLVertexFormatFloat3, + MTLVertexFormatFloat4, + }; + + MTLVertexStepFunction g_VertexInputRates[] = { + MTLVertexStepFunctionPerVertex, + MTLVertexStepFunctionPerInstance, + }; +} NS_K3D_METAL_END diff --git a/Source/RHI/Metal/Private/MetalPipelineState.mm b/Source/RHI/Metal/Private/MetalPipelineState.mm index 6558c9c..0b40cf6 100755 --- a/Source/RHI/Metal/Private/MetalPipelineState.mm +++ b/Source/RHI/Metal/Private/MetalPipelineState.mm @@ -1,12 +1,33 @@ #include "Kaleido3D.h" #include "MetalRHI.h" +#include "MetalEnums.h" #include NS_K3D_METAL_BEGIN -PipelineState::PipelineState() +MTLPrimitiveTopologyClass ConvertPrimTopology(rhi::EPrimitiveType const& type) { + switch(type) + { + case rhi::EPT_Triangles: + case rhi::EPT_TriangleStrip: + return MTLPrimitiveTopologyClassTriangle; + case rhi::EPT_Points: + return MTLPrimitiveTopologyClassPoint; + case rhi::EPT_Lines: + return MTLPrimitiveTopologyClassLine; + } + return MTLPrimitiveTopologyClassUnspecified; +} +PipelineState::PipelineState(id pDevice, rhi::PipelineDesc const & desc, rhi::EPipelineType const& type) +: m_DepthStencilDesc(nil) +, m_RenderPipelineDesc(nil) +, m_Type(type) +, m_Device(pDevice) +{ + InitPSO(desc); + Finalize(); } PipelineState::~PipelineState() @@ -14,6 +35,114 @@ } +void PipelineState::InitPSO(const rhi::PipelineDesc &desc) +{ + if(m_Type==rhi::EPSO_Graphics) + { + m_RenderPipelineDesc = [[MTLRenderPipelineDescriptor alloc] init]; + // depth stencil setup + m_DepthStencilDesc = [[MTLDepthStencilDescriptor alloc] init]; + m_DepthStencilDesc.depthCompareFunction = g_ComparisonFunc[desc.DepthStencil.DepthFunc]; + m_DepthStencilDesc.depthWriteEnabled = desc.DepthStencil.DepthEnable; + + MTLStencilDescriptor * stencilFront = m_DepthStencilDesc.frontFaceStencil; + stencilFront.depthStencilPassOperation = g_StencilOp[desc.DepthStencil.FrontFace.StencilPassOp]; + stencilFront.depthFailureOperation = g_StencilOp[desc.DepthStencil.FrontFace.DepthStencilFailOp]; + stencilFront.stencilFailureOperation = g_StencilOp[desc.DepthStencil.FrontFace.StencilFailOp]; + stencilFront.stencilCompareFunction = g_ComparisonFunc[desc.DepthStencil.FrontFace.StencilFunc]; + + MTLStencilDescriptor * stencilBack = m_DepthStencilDesc.backFaceStencil; + stencilBack.depthStencilPassOperation = g_StencilOp[desc.DepthStencil.BackFace.StencilPassOp]; + stencilBack.depthFailureOperation = g_StencilOp[desc.DepthStencil.BackFace.DepthStencilFailOp]; + stencilBack.stencilFailureOperation = g_StencilOp[desc.DepthStencil.BackFace.StencilFailOp]; + stencilBack.stencilCompareFunction = g_ComparisonFunc[desc.DepthStencil.BackFace.StencilFunc]; + + m_DepthBias = desc.Rasterizer.DepthBias; + m_DepthBiasClamp = desc.Rasterizer.DepthBiasClamp; + m_CullMode = g_CullMode[desc.Rasterizer.CullMode]; + m_RenderPipelineDesc.inputPrimitiveTopology = ConvertPrimTopology(desc.PrimitiveTopology); + m_PrimitiveType = g_PrimitiveType[desc.PrimitiveTopology]; + // blending setup + MTLRenderPipelineColorAttachmentDescriptor *renderbufferAttachment = m_RenderPipelineDesc.colorAttachments[0]; + + renderbufferAttachment.pixelFormat = MTLPixelFormatBGRA8Unorm; + + renderbufferAttachment.blendingEnabled = desc.Blend.Enable?YES:NO; + renderbufferAttachment.rgbBlendOperation = g_BlendOperation[desc.Blend.Op]; + renderbufferAttachment.alphaBlendOperation = g_BlendOperation[desc.Blend.BlendAlphaOp]; + renderbufferAttachment.sourceRGBBlendFactor = g_BlendFactor[desc.Blend.Src]; + renderbufferAttachment.sourceAlphaBlendFactor = g_BlendFactor[desc.Blend.SrcBlendAlpha]; + renderbufferAttachment.destinationRGBBlendFactor = g_BlendFactor[desc.Blend.Dest]; + renderbufferAttachment.destinationAlphaBlendFactor = g_BlendFactor[desc.Blend.DestBlendAlpha]; + + m_RenderPipelineDesc.depthAttachmentPixelFormat = MTLPixelFormatDepth32Float; + + + // vertex descriptor setup + for(uint32 i = 0; i lib = [m_Device newLibraryWithData:data error:&error]; + if(error) + { + MTLLOGE("Failed to AssignShader, error: %s, occured %s@%d.", [[error localizedFailureReason] UTF8String], __FILE__, __LINE__); + } + NSString *entryName = [NSString stringWithFormat:@"%@0", + [NSString stringWithUTF8String:shaderBundle.Desc.EntryFunction.CStr()]]; + id function = [lib newFunctionWithName:entryName]; + switch(shaderBundle.Desc.Stage) + { + case rhi::ES_Vertex: + m_RenderPipelineDesc.vertexFunction = function; + break; + case rhi::ES_Fragment: + m_RenderPipelineDesc.fragmentFunction = function; + break; + } + } + } +} + void PipelineState::SetLayout(rhi::PipelineLayoutRef) { @@ -61,7 +190,20 @@ void PipelineState::Finalize() { - + NSError *error = NULL; + if(m_Type==rhi::EPSO_Graphics) + { + m_DepthStencilState = [m_Device newDepthStencilStateWithDescriptor:m_DepthStencilDesc]; + m_RenderPipelineState = [m_Device newRenderPipelineStateWithDescriptor:m_RenderPipelineDesc error:&error]; + if (error) + { + MTLLOGE("Failed to created render pipeline state, error: %s", [error.localizedDescription cStringUsingEncoding:NSASCIIStringEncoding]); + } + } + else + { +// m_ComputePipelineState = [m_Device newCom] + } } NS_K3D_METAL_END diff --git a/Source/RHI/Metal/Private/MetalRHI.h b/Source/RHI/Metal/Private/MetalRHI.h index d50e2f4..4a10fd8 100755 --- a/Source/RHI/Metal/Private/MetalRHI.h +++ b/Source/RHI/Metal/Private/MetalRHI.h @@ -10,7 +10,7 @@ #define __CommandContext_h__ #include "../Common.h" -#include +#include NS_K3D_METAL_BEGIN @@ -54,6 +54,8 @@ class Device : public rhi::IDevice void Destroy(); private: + Device(id device); + friend class DeviceAdapter; id m_Device; id m_CommandQueue; @@ -65,7 +67,9 @@ inline rhi::DeviceRef DeviceAdapter::GetDevice() { if(!m_pRHIDevice) { - m_pRHIDevice = k3d::MakeShared(); + auto pDevice = new Device(m_Device); + pDevice->Create(this, false); + m_pRHIDevice = rhi::DeviceRef(pDevice); } return m_pRHIDevice; } @@ -74,8 +78,9 @@ inline rhi::DeviceRef DeviceAdapter::GetDevice() class PipelineState : public rhi::IPipelineStateObject { friend class Device; + friend class CommandContext; public: - PipelineState(); + PipelineState(id pDevice, rhi::PipelineDesc const & desc, rhi::EPipelineType const& type); ~PipelineState(); rhi::EPipelineType GetType () override { return m_Type; } @@ -93,18 +98,59 @@ class PipelineState : public rhi::IPipelineStateObject void Finalize() override; private: + void InitPSO(rhi::PipelineDesc const & desc); + void AssignShader(rhi::ShaderBundle const& shaderBundle); + rhi::EPipelineType m_Type; id m_Device; + id m_ComputePipelineState; + MTLComputePipelineDescriptor* m_ComputePipelineDesc; + id m_RenderPipelineState; MTLRenderPipelineDescriptor* m_RenderPipelineDesc; + + MTLDepthStencilDescriptor* m_DepthStencilDesc; + MTLCullMode m_CullMode; + float m_DepthBias; + float m_DepthBiasClamp; + + MTLPrimitiveType m_PrimitiveType; + + MTLRenderPipelineReflection* m_RenderReflection; + MTLComputePipelineReflection* m_ComputeReflection; + id m_DepthStencilState; }; +class DescriptorSet : public rhi::IDescriptor +{ +public: + DescriptorSet() + {} + + void Update(uint32 bindSet, rhi::GpuResourceRef res) override; + +private: + +}; + +class PipelineLayout : public rhi::IPipelineLayout +{ +public: + PipelineLayout(rhi::PipelineLayoutDesc const&); + ~PipelineLayout(); + + rhi::DescriptorRef GetDescriptorSet() const override; + +private: + +}; + class CommandContext : public rhi::ICommandContext { public: - CommandContext(); + CommandContext(rhi::ECommandType const & cmdType, id cmdBuf); ~CommandContext() override; @@ -112,27 +158,48 @@ class CommandContext : public rhi::ICommandContext void CopyTexture(const rhi::TextureCopyLocation& Dest, const rhi::TextureCopyLocation& Src) override; void CopyBuffer(rhi::IGpuResource& Dest, rhi::IGpuResource& Src, rhi::CopyBufferRegion const & Region) override; + void TransitionResourceBarrier(rhi::GpuResourceRef resource, /*EPipelineStage stage,*/ rhi::EResourceState dstState) override {} void Execute(bool Wait) override; void Reset() override; - void SetIndexBuffer(const rhi::IndexBufferView& IBView) override; - void SetVertexBuffer(uint32 Slot, const rhi::VertexBufferView& VBView) override; + void Begin() override; + + void ClearColorBuffer(rhi::GpuResourceRef, kMath::Vec4f const&) override {} + void ClearDepthBuffer(rhi::IDepthBuffer*) override {} + + void BeginRendering() override; + void SetRenderTargets(uint32 NumColorBuffer, rhi::IColorBuffer*, rhi::IDepthBuffer*, bool ReadOnlyDepth = false) override {} + void SetRenderTarget(rhi::RenderTargetRef) override; void SetPipelineState(uint32 HashCode, rhi::PipelineStateObjectRef) override; + void SetPipelineLayout(rhi::PipelineLayoutRef) override {} + void SetScissorRects(uint32, const rhi::Rect*) override {} void SetViewport(const rhi::ViewportDesc &) override; void SetPrimitiveType(rhi::EPrimitiveType) override; + void SetIndexBuffer(const rhi::IndexBufferView& IBView) override; + void SetVertexBuffer(uint32 Slot, const rhi::VertexBufferView& VBView) override; void DrawInstanced(rhi::DrawInstancedParam) override; void DrawIndexedInstanced(rhi::DrawIndexedInstancedParam) override; + void EndRendering() override; + void PresentInViewport(rhi::RenderViewportRef rvp) override; + void Dispatch(uint32 X = 1, uint32 Y =1, uint32 Z = 1) override; + void ExecuteBundle(rhi::ICommandContext*) override {} + + void End() override; + protected: private: + MTLRenderPassDescriptor* m_RenderpassDesc; rhi::ECommandType m_CommandType; + MTLPrimitiveType m_CurPrimType; id m_ComputeEncoder; id m_RenderEncoder; - + id m_ParallelRenderEncoder; id m_CmdBuffer; - id m_CmdQueue; + + id m_TmpIndexBuffer; }; class RenderViewport : public rhi::IRenderViewport @@ -141,26 +208,58 @@ class RenderViewport : public rhi::IRenderViewport RenderViewport(CAMetalLayer * mtlLayer = nil); ~RenderViewport() override; - bool InitViewport(void *windowHandle, - rhi::IDevice * pDevice, - rhi::GfxSetting & - ) override; + bool InitViewport(void *windowHandle, rhi::IDevice * pDevice, rhi::GfxSetting &) override; + void PrepareNextFrame() override; + bool Present(bool vSync) override { return false; } + + rhi::RenderTargetRef GetRenderTarget(uint32 index) override { return nullptr; } + + rhi::RenderTargetRef GetCurrentBackRenderTarget() override; + uint32 GetSwapChainCount()override { return 0; } + uint32 GetSwapChainIndex()override { return 0; } + + uint32 GetWidth() const override { return m_Width; } + uint32 GetHeight() const override { return m_Height; } - void PrepareNextFrame() override {} - bool Present(bool vSync) override { return false; } + friend class Device; + friend class CommandContext; +private: + + CAMetalLayer * m_Layer; + id m_CurrentDrawable; + MTLRenderPassDescriptor*m_RenderPassDescriptor; + id m_DepthTex; + uint32 m_Width; + uint32 m_Height; +}; + +class RenderTarget : public rhi::IRenderTarget +{ +public: + RenderTarget() {} + RenderTarget(MTLRenderPassDescriptor* rpd, id color); + ~RenderTarget() override; - rhi::RenderTargetRef GetRenderTarget(uint32 index) override { return nullptr; } + void SetClearColor(kMath::Vec4f clrColor) override; + void SetClearDepthStencil(float depth, uint32 stencil) override; + rhi::GpuResourceRef GetBackBuffer() override; + + friend class CommandContext; +private: + MTLRenderPassDescriptor*m_RenderPassDescriptor = nil; + id m_ColorTexture; +}; + +class Sampler : public rhi::ISampler +{ +public: + explicit Sampler(rhi::SamplerState const & state); + ~Sampler() override; - rhi::RenderTargetRef GetCurrentBackRenderTarget() override { return nullptr; } - uint32 GetSwapChainCount()override { return 0; } - uint32 GetSwapChainIndex()override { return 0; } + rhi::SamplerState GetSamplerDesc() const override; - uint32 GetWidth() const override { return m_Width; } - uint32 GetHeight() const override { return m_Height; } private: - CAMetalLayer * m_Layer; - uint32 m_Width; - uint32 m_Height; + id m_SampleState; }; NS_K3D_METAL_END diff --git a/Source/RHI/Metal/Private/MetalRHI.mm b/Source/RHI/Metal/Private/MetalRHI.mm index 9479841..d0678c3 100755 --- a/Source/RHI/Metal/Private/MetalRHI.mm +++ b/Source/RHI/Metal/Private/MetalRHI.mm @@ -20,15 +20,14 @@ void Start()override { KLOG(Info, MetalRHI, "Starting..."); +#if K3DPLATFORM_OS_MAC NSArray> * deviceList = MTLCopyAllDevices(); m_Adapters.resize(deviceList.count); -#if K3DPLATFORM_OS_MAC MTLFeatureSet fSets[] = { MTLFeatureSet_OSX_ReadWriteTextureTier2, MTLFeatureSet_OSX_GPUFamily1_v2, MTLFeatureSet_OSX_GPUFamily1_v1 }; -#endif for (uint32 i = 0; i device = [deviceList objectAtIndex:i]; @@ -38,6 +37,24 @@ void Start()override [device supportsFeatureSet:fSets[0]], [device supportsFeatureSet:fSets[1]]); } +#else + MTLFeatureSet fSets[] = { + MTLFeatureSet_iOS_GPUFamily2_v1, + MTLFeatureSet_iOS_GPUFamily1_v2, + MTLFeatureSet_iOS_GPUFamily2_v2, + MTLFeatureSet_iOS_GPUFamily3_v1, + MTLFeatureSet_iOS_GPUFamily1_v3, + MTLFeatureSet_iOS_GPUFamily2_v3, + MTLFeatureSet_iOS_GPUFamily3_v2 + }; + id device = MTLCreateSystemDefaultDevice(); + m_Adapters.resize(1); + m_Adapters[0] = new metal::DeviceAdapter(device); + KLOG(Info, MetalRHI, "DeviceName: %s ReadWriteTextureTier2:%d GPUv2:%d", + [[device name] UTF8String], + [device supportsFeatureSet:fSets[0]], + [device supportsFeatureSet:fSets[1]]); +#endif } void Shutdown()override diff --git a/Source/RHI/Metal/Private/MetalResource.mm b/Source/RHI/Metal/Private/MetalResource.mm index 8c4f340..8130fcf 100755 --- a/Source/RHI/Metal/Private/MetalResource.mm +++ b/Source/RHI/Metal/Private/MetalResource.mm @@ -4,5 +4,18 @@ NS_K3D_METAL_BEGIN +rhi::GpuResourceRef +Device::NewGpuResource(rhi::ResourceDesc const& desc) +{ + switch (desc.Type) { + case rhi::EGT_Buffer: + return k3d::MakeShared(this, desc); + case rhi::EGT_Texture2D: + return k3d::MakeShared(this, desc); + default: + break; + } + return nullptr; +} NS_K3D_METAL_END diff --git a/Source/RHI/Metal/Private/MetalTexture.mm b/Source/RHI/Metal/Private/MetalTexture.mm index 51a3858..3157ffe 100755 --- a/Source/RHI/Metal/Private/MetalTexture.mm +++ b/Source/RHI/Metal/Private/MetalTexture.mm @@ -1,6 +1,130 @@ #include "Public/MetalRHIResource.h" +#include "MetalRHI.h" +#include "MetalEnums.h" NS_K3D_METAL_BEGIN +MTLTextureType RHIMTLTextureType(rhi::EGpuResourceType const & type) +{ + switch(type) + { + case rhi::EGT_Texture1D: + return MTLTextureType1D; + case rhi::EGT_Texture1DArray: + return MTLTextureType1DArray; + case rhi::EGT_Texture2D: + return MTLTextureType2D; + case rhi::EGT_Texture3D: + return MTLTextureType3D; + case rhi::EGT_Texture2DArray: + return MTLTextureType2DArray; + } + return MTLTextureType2D; +} + +MTLTextureUsage RHIMTLTexUsage(rhi::EGpuMemViewType const & viewType, rhi::EGpuResourceAccessFlag const & accessType) +{ + MTLTextureUsage usage = MTLTextureUsageUnknown; + switch (viewType) { + case rhi::EGVT_SRV: + usage |= MTLTextureUsagePixelFormatView; + break; + case rhi::EGVT_RTV: + usage |= MTLTextureUsageRenderTarget; + break; + default: + break; + } + switch (accessType) { + case rhi::EGRAF_Read: + usage |= MTLTextureUsageShaderRead; + break; + case rhi::EGRAF_Write: + usage |= MTLTextureUsageShaderWrite; + break; + case rhi::EGRAF_ReadAndWrite: + usage |= (MTLTextureUsageShaderRead | MTLTextureUsageShaderWrite); + break; + default: + break; + } + return usage; +} + +MTLTextureDescriptor * RHIMTLTexDesc(rhi::ResourceDesc const & desc) +{ + MTLTextureDescriptor* texDesc = [MTLTextureDescriptor new]; + texDesc.width = desc.TextureDesc.Width; + texDesc.height = desc.TextureDesc.Height; + texDesc.depth = desc.TextureDesc.Depth; + texDesc.pixelFormat = g_PixelFormat[desc.TextureDesc.Format]; + texDesc.mipmapLevelCount = desc.TextureDesc.MipLevels; + texDesc.arrayLength = desc.TextureDesc.Layers; + texDesc.textureType = RHIMTLTextureType(desc.Type); + texDesc.usage = RHIMTLTexUsage(desc.ViewType, desc.Flag); + texDesc.resourceOptions; + texDesc.cpuCacheMode; + texDesc.storageMode; + return texDesc; +} + +Texture::Texture(Device * device, rhi::ResourceDesc const & desc) +: m_Device(device) +, m_Desc(desc) +, m_TexDesc(nil) +{ + m_TexDesc = RHIMTLTexDesc(desc); + m_Tex = [m_Device->GetDevice() newTextureWithDescriptor:m_TexDesc]; +} + +Texture::~Texture() +{ +} + +void * Texture::Map(uint64 start, uint64 size) +{ + return nullptr; +} + +void Texture::UnMap() +{ + +} + +uint64 Texture::GetLocation() const +{ + return 0; +} + +rhi::ResourceDesc Texture::GetDesc() const +{ + return m_Desc; +} + +uint64 Texture::GetSize() const +{ + return 0; +} + +rhi::SamplerCRef Texture::GetSampler() const +{ + return nullptr; +} + +void Texture::BindSampler(rhi::SamplerRef) +{ + +} + +void Texture::SetResourceView(rhi::ShaderResourceViewRef) +{ + +} + +rhi::ShaderResourceViewRef +Texture::GetResourceView() const +{ + return nullptr; +} NS_K3D_METAL_END diff --git a/Source/RHI/Metal/Public/IMetalRHI.h b/Source/RHI/Metal/Public/IMetalRHI.h index 298e3c5..c76b3bd 100755 --- a/Source/RHI/Metal/Public/IMetalRHI.h +++ b/Source/RHI/Metal/Public/IMetalRHI.h @@ -1,6 +1,6 @@ #pragma once #include -#include +#include namespace k3d { @@ -10,3 +10,7 @@ namespace k3d virtual rhi::DeviceRef GetPrimaryDevice() = 0; }; } + +#if BUILD_STATIC_PLUGIN +K3D_STATIC_MODULE_DECLARE(RHI_Metal); +#endif diff --git a/Source/RHI/Metal/Public/MetalRHIResource.h b/Source/RHI/Metal/Public/MetalRHIResource.h index 1e512e6..52de015 100755 --- a/Source/RHI/Metal/Public/MetalRHIResource.h +++ b/Source/RHI/Metal/Public/MetalRHIResource.h @@ -3,22 +3,96 @@ #define __MetalRHIResource_h__ #include "../Common.h" -#include +#include NS_K3D_METAL_BEGIN +class Device; + +class BufferRef +{ +public: + BufferRef(id iBuf) + : m_InterCnt(0) + , m_ExtCnt(0) + { + m_iBuffer = iBuf; + } + + ~BufferRef() + { + } + + void Retain() + { + + } + + void Release() + { + + } + +private: + id m_iBuffer; + int m_InterCnt; + int m_ExtCnt; +}; + class Buffer : public rhi::IGpuResource { public: + Buffer(Device* device, rhi::ResourceDesc const & desc); + ~Buffer(); + void * Map(uint64 start, uint64 size) override; + void UnMap() override; + + uint64 GetLocation() const override; + rhi::ResourceDesc GetDesc() const override; + rhi::EResourceState GetState() const override; +// rhi::EGpuResourceType GetType() const override; + uint64 GetSize() const override; + +private: + NSRange m_MapRange; + id m_Buf; + + rhi::ResourceDesc m_Desc; + Device* m_Device; }; class Texture : public rhi::ITexture { public: + Texture(Device* device, rhi::ResourceDesc const & desc); + ~Texture(); + + void * Map(uint64 start, uint64 size) override; + void UnMap() override; + uint64 GetLocation() const override; + rhi::ResourceDesc GetDesc() const override; + rhi::EResourceState GetState() const override { return rhi::ERS_Unknown; } +// rhi::EGpuResourceType GetResourceType() const override { return rhi::ResourceTypeNum; } + uint64 GetSize() const override; + + rhi::SamplerCRef GetSampler() const override; + void BindSampler(rhi::SamplerRef) override; + void SetResourceView(rhi::ShaderResourceViewRef) override; + rhi::ShaderResourceViewRef GetResourceView() const override; + +private: + id m_Tex; + MTLTextureDescriptor* m_TexDesc; + rhi::ResourceDesc m_Desc; + MTLStorageMode storageMode; + + MTLTextureUsage usage; + Device* m_Device; }; + NS_K3D_METAL_END #endif diff --git a/Source/RHI/OpenGL/CMakeLists.txt b/Source/RHI/OpenGL/CMakeLists.txt index 0588958..c580a80 100755 --- a/Source/RHI/OpenGL/CMakeLists.txt +++ b/Source/RHI/OpenGL/CMakeLists.txt @@ -11,7 +11,6 @@ elseif(ANDROID OR IOS) endif() set(RHI_HEADERS - ../IRHI.h OpenGLCommon.h Public/IOpenGLRHI.h ) @@ -30,10 +29,10 @@ source_group( ${RHI_IMPL_SRCS} ) -add_plugin(RHI_OpenGL "Runtime/RHI" ${OGLRHI_SRC_LIST} ${RHI_HEADERS} ${RHI_IMPL_SRCS}) +add_plugin(RHI_OpenGL FOLDER "Runtime/RHI" SRCS ${OGLRHI_SRC_LIST} ${RHI_HEADERS} ${RHI_IMPL_SRCS}) if(NOT ANDROID) - install(TARGETS RHI_OpenGL ARCHIVE DESTINATION lib) + #install(TARGETS RHI_OpenGL ARCHIVE DESTINATION lib) add_precompiled_header(RHI_OpenGL "OpenGLCommon.h" "${Kaleido3D_ROOT_DIR}/Source/RHI/OpenGL" "${Kaleido3D_ROOT_DIR}/Source/RHI/OpenGL/Private/OpenGLRHI.cpp") endif() diff --git a/Source/RHI/OpenGL/OpenGLCommon.h b/Source/RHI/OpenGL/OpenGLCommon.h index 47be7cb..726851d 100755 --- a/Source/RHI/OpenGL/OpenGLCommon.h +++ b/Source/RHI/OpenGL/OpenGLCommon.h @@ -1,6 +1,6 @@ #pragma once #include -#include +#include #define NS_GLRHI_BEGIN K3D_COMMON_NS { namespace opengl { #define NS_GLRHI_END }} diff --git a/Source/RHI/UnitTest/1.Device.cpp b/Source/RHI/UnitTest/1.Device.cpp new file mode 100644 index 0000000..feabc94 --- /dev/null +++ b/Source/RHI/UnitTest/1.Device.cpp @@ -0,0 +1,70 @@ +#include +#include +#include +#include +#include +#include +#include + +using namespace k3d; + +class UnitTestRHIDevice : public App +{ +public: + explicit UnitTestRHIDevice(kString const & appName) + : App(appName, 1920, 1080) + {} + + UnitTestRHIDevice(kString const & appName, uint32 width, uint32 height) + : App(appName, width, height) + {} + + bool OnInit() override; + void OnDestroy() override; + void OnProcess(Message & msg) override; + +private: + +#if K3DPLATFORM_OS_WIN || K3DPLATFORM_OS_ANDROID + SharedPtr m_pRHI; +#else + SharedPtr m_pRHI; +#endif + rhi::DeviceRef m_TestDevice; +}; + +K3D_APP_MAIN(UnitTestRHIDevice); + +using namespace rhi; +using namespace k3d; + +bool UnitTestRHIDevice::OnInit() +{ + App::OnInit(); +#if K3DPLATFORM_OS_WIN || K3DPLATFORM_OS_ANDROID + m_pRHI = StaticPointerCast(ACQUIRE_PLUGIN(RHI_Vulkan)); + if (m_pRHI) + { + m_pRHI->Initialize("UnitTestRHIDevice", false); + m_pRHI->Start(); + m_TestDevice = m_pRHI->GetPrimaryDevice(); + } +#else + auto pMtlRHI = StaticPointerCast(ACQUIRE_PLUGIN(RHI_Metal)); + if(pMtlRHI) + { + pMtlRHI->Start(); + m_TestDevice = pMtlRHI->GetPrimaryDevice(); + } +#endif + return true; +} + +void UnitTestRHIDevice::OnDestroy() +{ + App::OnDestroy(); +} + +void UnitTestRHIDevice::OnProcess(Message & msg) +{ +} diff --git a/Source/UnitTest/2.SwapChain/SwapChainPresent.cpp b/Source/RHI/UnitTest/2.SwapChainPresent.cpp old mode 100755 new mode 100644 similarity index 77% rename from Source/UnitTest/2.SwapChain/SwapChainPresent.cpp rename to Source/RHI/UnitTest/2.SwapChainPresent.cpp index a7bdcd0..f6610f5 --- a/Source/UnitTest/2.SwapChain/SwapChainPresent.cpp +++ b/Source/RHI/UnitTest/2.SwapChainPresent.cpp @@ -1,13 +1,13 @@ #include #include #include -#include +#include #include using namespace k3d; using namespace render; -rhi::GfxSetting setting{ 1920, 1080, rhi::EPF_RGBA8Unorm, rhi::EPF_RGBA8Unorm, true, 2 }; +rhi::GfxSetting setting{ 1920, 1080, rhi::EPF_RGBA8Unorm, rhi::EPF_D32Float, true, 2 }; class VkSwapChainPresent : public App { @@ -15,6 +15,9 @@ class VkSwapChainPresent : public App explicit VkSwapChainPresent(kString const & appName) : App(appName, 1920, 1080) {} + VkSwapChainPresent(kString const & appName, uint32 width, uint32 height) + : App(appName, width, height) + {} bool OnInit() override; void OnDestroy() override; @@ -32,7 +35,11 @@ K3D_APP_MAIN(VkSwapChainPresent); bool VkSwapChainPresent::OnInit() { App::OnInit(); - m_RenderContext.Init(RHIType::ERTVulkan); +#if K3DPLATFORM_OS_IOS || K3DPLATFORM_OS_MAC + m_RenderContext.Init(RHIType::ERTMetal); +#else + m_RenderContext.Init(RHIType::ERTVulkan); +#endif m_pDevice = m_RenderContext.GetDevice(); m_RenderVp = m_pDevice->NewRenderViewport(HostWindow()->GetHandle(), setting); m_RenderVp->InitViewport(nullptr, nullptr, setting); diff --git a/Source/UnitTest/3.Triangle/Triangle.cpp b/Source/RHI/UnitTest/3.Triangle.cpp old mode 100755 new mode 100644 similarity index 50% rename from Source/UnitTest/3.Triangle/Triangle.cpp rename to Source/RHI/UnitTest/3.Triangle.cpp index e7fdf0f..9c6023c --- a/Source/UnitTest/3.Triangle/Triangle.cpp +++ b/Source/RHI/UnitTest/3.Triangle.cpp @@ -1,9 +1,10 @@ #include +#include #include #include #include #include -#include +#include #include #include @@ -18,55 +19,15 @@ struct ConstantBuffer { Mat4f modelMatrix; Mat4f viewMatrix; }; -const char* vertSource = "#version 430\n" - "\n" - "#extension GL_ARB_separate_shader_objects : enable\n" - "#extension GL_ARB_shading_language_420pack : enable\n" - "\n" - "layout (location = 0) in vec3 inPos;\n" - "layout (location = 1) in vec3 inColor;\n" - "\n" - "layout (binding = 0) uniform UBO \n" - "{\n" - "\tmat4 projectionMatrix;\n" - "\tmat4 modelMatrix;\n" - "\tmat4 viewMatrix;\n" - "} ubo;\n" - "\n" - "layout (location = 0) out vec3 outColor;\n" - "\n" - "out gl_PerVertex \n" - "{\n" - " vec4 gl_Position; \n" - "};\n" - "\n" - "\n" - "void main() \n" - "{\n" - "\toutColor = inColor;\n" - "\tgl_Position = ubo.projectionMatrix * ubo.viewMatrix * ubo.modelMatrix * vec4(inPos.xyz, 1.0);\n" - "}"; -const char* fragSource = "#version 430\n" - "\n" - "#extension GL_ARB_separate_shader_objects : enable\n" - "#extension GL_ARB_shading_language_420pack : enable\n" - "\n" - "layout (location = 0) in vec3 inColor;\n" - "\n" - "layout (location = 0) out vec4 outFragColor;\n" - "\n" - "void main()\n" - "{\n" - " outFragColor = vec4(inColor, 1.0);\n" - "}"; -class VkTriangleUnitTest : public App + +class VkTriangleUnitTest : public RHIAppBase { public: VkTriangleUnitTest(kString const & appName, uint32 width, uint32 height) - : App(appName, width, height), m_Width(width), m_Height(height) + : RHIAppBase(appName, width, height) {} explicit VkTriangleUnitTest(kString const & appName) - : App(appName, 1920, 1080), m_Width(1920), m_Height(1080) + : RHIAppBase(appName, 1920, 1080) {} bool OnInit() override; @@ -76,8 +37,6 @@ class VkTriangleUnitTest : public App void OnUpdate() override; protected: - void LoadGlslangCompiler(); - void compile(const char *shaderSource, rhi::EShaderType const& type, rhi::ShaderBundle & shader); void PrepareResource(); void PreparePipeline(); @@ -90,15 +49,10 @@ class VkTriangleUnitTest : public App rhi::GpuResourceRef m_ConstBuffer; ConstantBuffer m_HostBuffer; - RenderContext m_RenderContext; - rhi::RenderViewportRef m_Viewport; rhi::PipelineStateObjectRef m_pPso; rhi::PipelineLayoutRef m_pl; std::vector m_Cmds; rhi::SyncFenceRef m_pFence; - - uint32 m_Width; - uint32 m_Height; }; K3D_APP_MAIN(VkTriangleUnitTest) @@ -117,16 +71,19 @@ class TriangleMesh { m_szVBuf = sizeof(TriangleMesh::Vertex)*m_VertexBuffer.size(); m_szIBuf = sizeof(uint32)*m_IndexBuffer.size(); - m_VertDecs[0] = { rhi::EVF_Float3x32, sizeof(Vertex), 0,0,0 }; /* Position */ - m_VertDecs[1] = { rhi::EVF_Float3x32, sizeof(Vertex), 1,sizeof(float)*3,0 }; /* Color */ + + m_IAState.Attribs[0] = {rhi::EVF_Float3x32, 0, 0}; + m_IAState.Attribs[1] = {rhi::EVF_Float3x32, sizeof(float)*3, 0}; + + m_IAState.Layouts[0] = {rhi::EVIR_PerVertex, sizeof(Vertex)}; } ~TriangleMesh() { } - - const rhi::VertexDeclaration * GetVertDec() const { return m_VertDecs; } - + + const rhi::VertexInputState & GetInputState() const { return m_IAState;} + void Upload(); void SetLoc(uint64 ibo, uint64 vbo) @@ -141,7 +98,7 @@ class TriangleMesh private: - rhi::VertexDeclaration m_VertDecs[2]; + rhi::VertexInputState m_IAState; uint64 m_szVBuf; uint64 m_szIBuf; @@ -166,7 +123,7 @@ void TriangleMesh::Upload() rhi::ResourceDesc stageDesc; stageDesc.ViewType = rhi::EGpuMemViewType::EGVT_Undefined; stageDesc.CreationFlag = rhi::EGpuResourceCreationFlag::EGRCF_TransferSrc; - stageDesc.Flag = (rhi::EGpuResourceAccessFlag) (rhi::EGpuResourceAccessFlag::EGRAF_HostCoherent | rhi::EGpuResourceAccessFlag::EGRAF_HostVisible); + stageDesc.Flag = rhi::EGpuResourceAccessFlag::EGRAF_HostCoherent | rhi::EGpuResourceAccessFlag::EGRAF_HostVisible; stageDesc.Size = m_szVBuf; auto vStageBuf = m_pDevice->NewGpuResource(stageDesc); void * ptr = vStageBuf->Map(0, m_szVBuf); @@ -197,9 +154,9 @@ void TriangleMesh::Upload() cmd->CopyBuffer(*ibuf, *iStageBuf, region); cmd->End(); cmd->Execute(true); -// m_pDevice->WaitIdle(); - uint64 vboLoc = vbuf->GetResourceLocation(); - uint64 iboLoc = ibuf->GetResourceLocation(); +// m_m_pDevice->WaitIdle(); + uint64 vboLoc = vbuf->GetLocation(); + uint64 iboLoc = ibuf->GetLocation(); SetLoc(iboLoc, vboLoc); KLOG(Info, TriangleMesh, "finish buffer upload.."); } @@ -207,14 +164,12 @@ void TriangleMesh::Upload() bool VkTriangleUnitTest::OnInit() { - bool inited = App::OnInit(); + bool inited = RHIAppBase::OnInit(); if(!inited) return inited; - m_RenderContext.Init(RHIType::ERTVulkan, m_Width, m_Height); - m_RenderContext.Attach(HostWindow()); - m_Viewport = m_RenderContext.GetViewport(); - LoadGlslangCompiler(); + KLOG(Info, Test, __K3D_FUNC__); + PrepareResource(); PreparePipeline(); PrepareCommandBuffer(); @@ -222,117 +177,66 @@ bool VkTriangleUnitTest::OnInit() return true; } -void VkTriangleUnitTest::LoadGlslangCompiler() -{ - rhi::IShModule* shMod = (rhi::IShModule*)GlobalModuleManager.FindModule("ShaderCompiler"); - if (shMod) - { - m_Compiler = shMod->CreateShaderCompiler(rhi::ERHI_Vulkan); - } -} - -void VkTriangleUnitTest::compile(const char * shaderPath, rhi::EShaderType const & type, rhi::ShaderBundle & shader) -{ - auto pDevice = m_RenderContext.GetDevice(); - IAsset * shaderFile = AssetManager::Open(shaderPath); - if (!shaderFile) - { - KLOG(Fatal, "VkTriangle", "Error opening %s.", shaderPath); - return; - } - std::vector buffer; - uint64 len = shaderFile->GetLength(); - buffer.resize(len+1); - shaderFile->Read(buffer.data(), shaderFile->GetLength()); - buffer[len] = 0; - String src(buffer.data()); - rhi::ShaderDesc desc = { rhi::EShFmt_Text, rhi::EShLang_GLSL, rhi::EShProfile_Modern, type, "main" }; - m_Compiler->Compile(src, desc, shader); -} - void VkTriangleUnitTest::PrepareResource() { KLOG(Info, Test, __K3D_FUNC__); - m_TriMesh = std::make_unique(m_RenderContext.GetDevice()); + m_TriMesh = std::make_unique(m_pDevice); m_TriMesh->Upload(); - auto pDevice = m_RenderContext.GetDevice(); rhi::ResourceDesc desc; desc.Flag = rhi::EGpuResourceAccessFlag::EGRAF_HostVisible; desc.ViewType = rhi::EGpuMemViewType::EGVT_CBV; desc.Size = sizeof(ConstantBuffer); - m_ConstBuffer = pDevice->NewGpuResource(desc); + m_ConstBuffer = m_pDevice->NewGpuResource(desc); OnUpdate(); -// pDevice->WaitIdle(); TOFIX: this may cause crash on Android N +// m_pDevice->WaitIdle(); TOFIX: this may cause crash on Android N } void VkTriangleUnitTest::PreparePipeline() { - auto pDevice = m_RenderContext.GetDevice(); rhi::ShaderBundle vertSh, fragSh; - compile("asset://Test/triangle.vert", rhi::ES_Vertex, vertSh); - compile("asset://Test/triangle.frag", rhi::ES_Fragment, fragSh); + Compile("asset://Test/triangle.vert", rhi::ES_Vertex, vertSh); + Compile("asset://Test/triangle.frag", rhi::ES_Fragment, fragSh); rhi::PipelineLayoutDesc ppldesc = vertSh.BindingTable; - m_pl = pDevice->NewPipelineLayout(ppldesc); - auto descriptor = m_pl->GetDescriptorSet(); - descriptor->Update(0, m_ConstBuffer); + m_pl = m_pDevice->NewPipelineLayout(ppldesc); + if(m_pl) + { + auto descriptor = m_pl->GetDescriptorSet(); + descriptor->Update(0, m_ConstBuffer); + } auto attrib = vertSh.Attributes; rhi::PipelineDesc desc; desc.Shaders[rhi::ES_Vertex] = vertSh; desc.Shaders[rhi::ES_Fragment] = fragSh; - desc.VertexLayout.Append(m_TriMesh->GetVertDec()[0]).Append(m_TriMesh->GetVertDec()[1]); - m_pPso = pDevice->NewPipelineState(desc, m_pl, rhi::EPSO_Graphics); - + desc.InputState = m_TriMesh->GetInputState(); + m_pPso = m_pDevice->NewPipelineState(desc, m_pl, rhi::EPSO_Graphics); + //m_pPso->LoadPSO("triagle.psocache"); } void VkTriangleUnitTest::PrepareCommandBuffer() { - auto pDevice = m_RenderContext.GetDevice(); - m_pFence = pDevice->NewFence(); - /* - for (uint32 i = 0; i < m_Viewport->GetSwapChainCount(); i++) - { - auto pRT = m_Viewport->GetRenderTarget(i); - auto gfxCmd = pDevice->NewCommandContext(rhi::ECMD_Graphics); - gfxCmd->Begin(); - gfxCmd->TransitionResourceBarrier(pRT->GetBackBuffer(), rhi::EPS_All, rhi::ERS_RenderTarget); - gfxCmd->SetPipelineLayout(m_pl); - rhi::Rect rect{ 0,0, (long)m_Viewport->GetWidth(), (long)m_Viewport->GetHeight() }; - gfxCmd->SetRenderTarget(pRT); - gfxCmd->SetScissorRects(1, &rect); - gfxCmd->SetViewport(rhi::ViewportDesc(m_Viewport->GetWidth(), m_Viewport->GetHeight())); - gfxCmd->SetPipelineState(0, m_pPso); - gfxCmd->SetIndexBuffer(m_TriMesh->IBO()); - gfxCmd->SetVertexBuffer(0, m_TriMesh->VBO()); - gfxCmd->DrawIndexedInstanced(rhi::DrawIndexedInstancedParam(3, 1)); - gfxCmd->EndRendering(); - gfxCmd->TransitionResourceBarrier(pRT->GetBackBuffer(), rhi::EPS_All, rhi::ERS_Present); - gfxCmd->End(); - m_Cmds.push_back(gfxCmd); - } - */ + m_pFence = m_pDevice->NewFence(); } void VkTriangleUnitTest::OnDestroy() { + App::OnDestroy(); m_TriMesh->~TriangleMesh(); - m_RenderContext.Destroy(); } void VkTriangleUnitTest::OnProcess(Message& msg) { - KLOG(Info, VkTriangleUnitTest, __K3D_FUNC__); - m_Viewport->PrepareNextFrame(); - auto curRt = m_Viewport->GetCurrentBackRenderTarget(); - auto pDevice = m_RenderContext.GetDevice(); - auto renderCmd = pDevice->NewCommandContext(rhi::ECMD_Graphics); +// KLOG(Info, VkTriangleUnitTest, __K3D_FUNC__); + m_pViewport->PrepareNextFrame(); + auto curRt = m_pViewport->GetCurrentBackRenderTarget(); + auto renderCmd = m_pDevice->NewCommandContext(rhi::ECMD_Graphics); renderCmd->Begin(); renderCmd->TransitionResourceBarrier(curRt->GetBackBuffer(), rhi::ERS_RenderTarget); renderCmd->SetPipelineLayout(m_pl); - rhi::Rect rect{ 0,0, (long)m_Viewport->GetWidth(), (long)m_Viewport->GetHeight() }; + rhi::Rect rect{ 0,0, (long)m_pViewport->GetWidth(), (long)m_pViewport->GetHeight() }; renderCmd->SetRenderTarget(curRt); renderCmd->SetScissorRects(1, &rect); - renderCmd->SetViewport(rhi::ViewportDesc(m_Viewport->GetWidth(), m_Viewport->GetHeight())); + renderCmd->SetViewport(rhi::ViewportDesc(m_pViewport->GetWidth(), m_pViewport->GetHeight())); renderCmd->SetPipelineState(0, m_pPso); renderCmd->SetIndexBuffer(m_TriMesh->IBO()); renderCmd->SetVertexBuffer(0, m_TriMesh->VBO()); @@ -340,12 +244,12 @@ void VkTriangleUnitTest::OnProcess(Message& msg) renderCmd->EndRendering(); renderCmd->TransitionResourceBarrier(curRt->GetBackBuffer(), rhi::ERS_Present); renderCmd->End(); - renderCmd->PresentInViewport(m_Viewport); + renderCmd->PresentInViewport(m_pViewport); } void VkTriangleUnitTest::OnUpdate() { - m_HostBuffer.projectionMatrix = Perspective(60.0f, (float)m_Viewport->GetWidth() / (float)m_Viewport->GetHeight(), 0.1f, 256.0f); + m_HostBuffer.projectionMatrix = Perspective(60.0f, (float)m_pViewport->GetWidth() / (float)m_pViewport->GetHeight(), 0.1f, 256.0f); m_HostBuffer.viewMatrix = Translate(Vec3f(0.0f, 0.0f, -2.5f), MakeIdentityMatrix()); m_HostBuffer.modelMatrix = MakeIdentityMatrix(); m_HostBuffer.modelMatrix = Rotate(Vec3f(1.0f, 0.0f, 0.0f), 0.f, m_HostBuffer.modelMatrix); diff --git a/Source/UnitTest/4.TexturedCube/TexturedCube.cpp b/Source/RHI/UnitTest/4.TexturedCube.cpp old mode 100755 new mode 100644 similarity index 61% rename from Source/UnitTest/4.TexturedCube/TexturedCube.cpp rename to Source/RHI/UnitTest/4.TexturedCube.cpp index 1ae69b0..ea835c2 --- a/Source/UnitTest/4.TexturedCube/TexturedCube.cpp +++ b/Source/RHI/UnitTest/4.TexturedCube.cpp @@ -1,12 +1,12 @@ #include +#include #include #include #include #include -#include #include #include -#include "TextureObject.h" +#include using namespace k3d; using namespace render; @@ -20,17 +20,21 @@ struct ConstantBuffer { Mat4f viewMatrix; }; -class TCubeUnitTest : public App +class TCubeUnitTest : public RHIAppBase { public: TCubeUnitTest(kString const & appName, uint32 width, uint32 height) - : App(appName, width, height), m_Width(width), m_Height(height) + : RHIAppBase(appName, width, height) {} explicit TCubeUnitTest(kString const & appName) - : App(appName, 1920, 1080) + : RHIAppBase(appName, 1920, 1080) {} - + + ~TCubeUnitTest() + { + KLOG(Info, CubeTest, "Destroying.."); + } bool OnInit() override; void OnDestroy() override; void OnProcess(Message & msg) override; @@ -38,8 +42,7 @@ class TCubeUnitTest : public App void OnUpdate() override; protected: - void LoadGlslangCompiler(); - void compile(const char *shaderPath, rhi::EShaderType const& type, rhi::ShaderBundle & bundle); + rhi::GpuResourceRef CreateStageBuffer(uint64 size); void LoadTexture(); void PrepareResource(); @@ -48,21 +51,15 @@ class TCubeUnitTest : public App private: - rhi::IShCompiler::Ptr m_Compiler; - std::unique_ptr m_TriMesh; - + SharedPtr m_CubeMesh; rhi::GpuResourceRef m_ConstBuffer; - TextureObject* m_Texture; + SharedPtr m_Texture; ConstantBuffer m_HostBuffer; - RenderContext m_RenderContext; - rhi::RenderViewportRef m_Viewport; rhi::PipelineStateObjectRef m_pPso; rhi::PipelineLayoutRef m_pl; std::vector m_Cmds; rhi::SyncFenceRef m_pFence; - uint32 m_Width; - uint32 m_Height; }; K3D_APP_MAIN(TCubeUnitTest); @@ -81,16 +78,18 @@ class CubeMesh explicit CubeMesh(rhi::DeviceRef device) : m_pDevice (device), vbuf(nullptr) { m_szVBuf = sizeof(CubeMesh::Vertex)*m_VertexBuffer.size(); - m_VertDecs[0] = { rhi::EVF_Float3x32, sizeof(Vertex), 0,0,0 }; /* Position */ - m_VertDecs[1] = { rhi::EVF_Float4x32, sizeof(Vertex), 1,sizeof(float)*3,0 }; /* Color */ - m_VertDecs[2] = { rhi::EVF_Float2x32, sizeof(Vertex), 2,sizeof(float)*7,0 }; /* UV */ + m_IAState.Attribs[0] = {rhi::EVF_Float3x32, 0, 0}; + m_IAState.Attribs[1] = {rhi::EVF_Float4x32, sizeof(float)*3, 0}; + m_IAState.Attribs[2] = {rhi::EVF_Float2x32, sizeof(float)*7, 0}; + + m_IAState.Layouts[0] = {rhi::EVIR_PerVertex, sizeof(Vertex)}; } ~CubeMesh() { } - - const rhi::VertexDeclaration * GetVertDec() const { return m_VertDecs; } + + const rhi::VertexInputState & GetInputState() const { return m_IAState;} void Upload(); @@ -102,42 +101,41 @@ class CubeMesh const rhi::VertexBufferView VBO() const { return rhi::VertexBufferView{ vboLoc, 0, 0 }; } private: - - rhi::VertexDeclaration m_VertDecs[3]; + rhi::VertexInputState m_IAState; uint64 m_szVBuf; VertexList m_VertexBuffer = { //left - { -1.0f,-1.0f,-1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f }, - { -1.0f,-1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f }, - { -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f }, + { -1.0f,-1.0f,-1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f }, + { -1.0f,-1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f }, + { -1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f }, - { -1.0f,-1.0f,-1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f }, + { -1.0f,-1.0f,-1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f }, { -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f }, { -1.0f, 1.0f,-1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f }, //back { 1.0f, 1.0f,-1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f }, - { -1.0f,-1.0f,-1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f }, + { -1.0f,-1.0f,-1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f }, { -1.0f, 1.0f,-1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f }, { 1.0f, 1.0f,-1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f }, { 1.0f,-1.0f,-1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f }, - { -1.0f,-1.0f,-1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f }, + { -1.0f,-1.0f,-1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f }, //top { 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f }, - { -1.0f,-1.0f,-1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f }, + { -1.0f,-1.0f,-1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f }, { 1.0f, -1.0f,-1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f }, { 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f }, - { -1.0f,-1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f }, - { -1.0f,-1.0f,-1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f }, + { -1.0f,-1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f }, + { -1.0f,-1.0f,-1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f }, //front { -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f }, - { -1.0f,-1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f }, + { -1.0f,-1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f }, { 1.0f,-1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f }, { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f }, @@ -174,7 +172,7 @@ void CubeMesh::Upload() rhi::ResourceDesc stageDesc; stageDesc.ViewType = rhi::EGpuMemViewType::EGVT_Undefined; stageDesc.CreationFlag = rhi::EGpuResourceCreationFlag::EGRCF_TransferSrc; - stageDesc.Flag = (rhi::EGpuResourceAccessFlag) (rhi::EGpuResourceAccessFlag::EGRAF_HostCoherent | rhi::EGpuResourceAccessFlag::EGRAF_HostVisible); + stageDesc.Flag = rhi::EGpuResourceAccessFlag::EGRAF_HostCoherent | rhi::EGpuResourceAccessFlag::EGRAF_HostVisible; stageDesc.Size = m_szVBuf; auto vStageBuf = m_pDevice->NewGpuResource(stageDesc); void * ptr = vStageBuf->Map(0, m_szVBuf); @@ -195,65 +193,31 @@ void CubeMesh::Upload() cmd->End(); cmd->Execute(true); // m_pDevice->WaitIdle(); - SetLoc(vbuf->GetResourceLocation()); + SetLoc(vbuf->GetLocation()); KLOG(Info, TCubeMesh, "finish buffer upload.."); } -bool TCubeUnitTest::OnInit() +bool TCubeUnitTest::OnInit() { - bool inited = App::OnInit(); + bool inited = RHIAppBase::OnInit(); if(!inited) return inited; - LoadGlslangCompiler(); - m_RenderContext.Init(RHIType::ERTVulkan, m_Width, m_Height); - m_RenderContext.Attach(HostWindow()); - m_Viewport = m_RenderContext.GetViewport(); - KLOG(Info, Test, __K3D_FUNC__); PrepareResource(); PreparePipeline(); PrepareCommandBuffer(); - return true; } -void TCubeUnitTest::LoadGlslangCompiler() -{ - rhi::IShModule* shMod = (rhi::IShModule*)GlobalModuleManager.FindModule("ShaderCompiler"); - if (shMod) - { - m_Compiler = shMod->CreateShaderCompiler(rhi::ERHI_Vulkan); - } -} - -void TCubeUnitTest::compile(const char * shaderPath, rhi::EShaderType const & type, rhi::ShaderBundle & bundle) -{ - IAsset * shaderFile = AssetManager::Open(shaderPath); - if (!shaderFile) - { - KLOG(Fatal, "TCube", "Error opening %s.", shaderPath); - return; - } - std::vector buffer; - uint64 len = shaderFile->GetLength(); - buffer.resize(len+1); - shaderFile->Read(buffer.data(), shaderFile->GetLength()); - buffer[len] = 0; - - String src(buffer.data()); - rhi::ShaderDesc desc = { rhi::EShFmt_Text, rhi::EShLang_GLSL, rhi::EShProfile_Modern, type, "main" }; - m_Compiler->Compile(src, desc, bundle); -} - rhi::GpuResourceRef TCubeUnitTest::CreateStageBuffer(uint64 size) { rhi::ResourceDesc stageDesc; stageDesc.ViewType = rhi::EGpuMemViewType::EGVT_Undefined; stageDesc.CreationFlag = rhi::EGpuResourceCreationFlag::EGRCF_TransferSrc; - stageDesc.Flag = (rhi::EGpuResourceAccessFlag) (rhi::EGpuResourceAccessFlag::EGRAF_HostCoherent | rhi::EGpuResourceAccessFlag::EGRAF_HostVisible); + stageDesc.Flag = rhi::EGpuResourceAccessFlag::EGRAF_HostCoherent | rhi::EGpuResourceAccessFlag::EGRAF_HostVisible; stageDesc.Size = size; - return m_RenderContext.GetDevice()->NewGpuResource(stageDesc); + return m_pDevice->NewGpuResource(stageDesc); } void TCubeUnitTest::LoadTexture() @@ -264,75 +228,69 @@ void TCubeUnitTest::LoadTexture() uint64 length = textureFile->GetLength(); uint8* data = new uint8[length]; textureFile->Read(data, length); - m_Texture = new TextureObject(m_RenderContext.GetDevice(), data); + m_Texture = MakeShared(m_pDevice, data, false); auto texStageBuf = CreateStageBuffer(m_Texture->GetSize()); m_Texture->MapIntoBuffer(texStageBuf); m_Texture->CopyAndInitTexture(texStageBuf); rhi::ResourceViewDesc viewDesc; - auto pDevice = m_RenderContext.GetDevice(); - auto srv = pDevice->NewShaderResourceView(m_Texture->GetResource(), viewDesc); - auto texure = DynamicPointerCast(m_Texture->GetResource()); - texure->SetResourceView(srv); + auto srv = m_pDevice->NewShaderResourceView(m_Texture->GetResource(), viewDesc); // TODO: Fix circle ref of `m_Texture->m_Resource` + auto texure = StaticPointerCast(m_Texture->GetResource()); // + texure->SetResourceView(Move(srv)); // here rhi::SamplerState samplerDesc; - auto sampler2D = pDevice->NewSampler(samplerDesc); - texure->BindSampler(sampler2D); + auto sampler2D = m_pDevice->NewSampler(samplerDesc); + texure->BindSampler(Move(sampler2D)); } } void TCubeUnitTest::PrepareResource() { KLOG(Info, Test, __K3D_FUNC__); - m_TriMesh = std::make_unique(m_RenderContext.GetDevice()); - m_TriMesh->Upload(); + m_CubeMesh = MakeShared(m_pDevice); + m_CubeMesh->Upload(); LoadTexture(); - auto pDevice = m_RenderContext.GetDevice(); rhi::ResourceDesc desc; desc.Flag = rhi::EGpuResourceAccessFlag::EGRAF_HostVisible; desc.ViewType = rhi::EGpuMemViewType::EGVT_CBV; desc.Size = sizeof(ConstantBuffer); - m_ConstBuffer = pDevice->NewGpuResource(desc); + m_ConstBuffer = m_pDevice->NewGpuResource(desc); OnUpdate(); } void TCubeUnitTest::PreparePipeline() { - auto pDevice = m_RenderContext.GetDevice(); rhi::ShaderBundle vertSh, fragSh; - compile("asset://Test/cube.vert", rhi::ES_Vertex, vertSh); - compile("asset://Test/cube.frag", rhi::ES_Fragment, fragSh); + Compile("asset://Test/cube.vert", rhi::ES_Vertex, vertSh); + Compile("asset://Test/cube.frag", rhi::ES_Fragment, fragSh); auto vertBinding = vertSh.BindingTable; auto fragBinding = fragSh.BindingTable; auto mergedBindings = vertBinding | fragBinding; - m_pl = pDevice->NewPipelineLayout(mergedBindings); + m_pl = m_pDevice->NewPipelineLayout(mergedBindings); auto descriptor = m_pl->GetDescriptorSet(); descriptor->Update(0, m_ConstBuffer); descriptor->Update(1, m_Texture->GetResource()); - //auto attrib = vertSh->GetAttributes(); rhi::PipelineDesc desc; desc.Shaders[rhi::ES_Vertex] = vertSh; desc.Shaders[rhi::ES_Fragment] = fragSh; - desc.VertexLayout.Append(m_TriMesh->GetVertDec()[0]).Append(m_TriMesh->GetVertDec()[1]).Append(m_TriMesh->GetVertDec()[2]); - m_pPso = pDevice->NewPipelineState(desc, m_pl, rhi::EPSO_Graphics); - + desc.InputState = m_CubeMesh->GetInputState(); + m_pPso = m_pDevice->NewPipelineState(desc, m_pl, rhi::EPSO_Graphics); } void TCubeUnitTest::PrepareCommandBuffer() { - auto pDevice = m_RenderContext.GetDevice(); - m_pFence = pDevice->NewFence(); - for (uint32 i = 0; i < m_Viewport->GetSwapChainCount(); i++) + m_pFence = m_pDevice->NewFence(); + for (uint32 i = 0; i < m_pViewport->GetSwapChainCount(); i++) { - auto pRT = m_Viewport->GetRenderTarget(i); - auto gfxCmd = pDevice->NewCommandContext(rhi::ECMD_Graphics); + auto pRT = m_pViewport->GetRenderTarget(i); + auto gfxCmd = m_pDevice->NewCommandContext(rhi::ECMD_Graphics); gfxCmd->Begin(); gfxCmd->TransitionResourceBarrier(pRT->GetBackBuffer(), rhi::ERS_RenderTarget); gfxCmd->SetPipelineLayout(m_pl); - rhi::Rect rect{ 0,0, (long)m_Viewport->GetWidth(), (long)m_Viewport->GetHeight() }; + rhi::Rect rect{ 0,0, (long)m_pViewport->GetWidth(), (long)m_pViewport->GetHeight() }; gfxCmd->SetRenderTarget(pRT); gfxCmd->SetScissorRects(1, &rect); - gfxCmd->SetViewport(rhi::ViewportDesc(1.f*m_Viewport->GetWidth(), 1.f*m_Viewport->GetHeight())); + gfxCmd->SetViewport(rhi::ViewportDesc(1.f*m_pViewport->GetWidth(), 1.f*m_pViewport->GetHeight())); gfxCmd->SetPipelineState(0, m_pPso); - gfxCmd->SetVertexBuffer(0, m_TriMesh->VBO()); + gfxCmd->SetVertexBuffer(0, m_CubeMesh->VBO()); gfxCmd->DrawInstanced(rhi::DrawInstancedParam(36, 1)); gfxCmd->EndRendering(); gfxCmd->TransitionResourceBarrier(pRT->GetBackBuffer(), rhi::ERS_Present); @@ -344,20 +302,20 @@ void TCubeUnitTest::PrepareCommandBuffer() void TCubeUnitTest::OnDestroy() { - m_TriMesh->~CubeMesh(); - m_RenderContext.Destroy(); + m_pFence->WaitFor(1000); + RHIAppBase::OnDestroy(); } void TCubeUnitTest::OnProcess(Message& msg) { KLOG(Info, TCubeUnitTest, __K3D_FUNC__); - m_Viewport->PrepareNextFrame(); - m_Cmds[m_Viewport->GetSwapChainIndex()]->PresentInViewport(m_Viewport); + m_pViewport->PrepareNextFrame(); + m_Cmds[m_pViewport->GetSwapChainIndex()]->PresentInViewport(m_pViewport); } void TCubeUnitTest::OnUpdate() { - m_HostBuffer.projectionMatrix = Perspective(60.0f, (float)m_Viewport->GetWidth() / (float)m_Viewport->GetHeight(), 0.1f, 256.0f); + m_HostBuffer.projectionMatrix = Perspective(60.0f, (float)m_pViewport->GetWidth() / (float)m_pViewport->GetHeight(), 0.1f, 256.0f); m_HostBuffer.viewMatrix = Translate(Vec3f(0.0f, 0.0f, -4.5f), MakeIdentityMatrix()); m_HostBuffer.modelMatrix = MakeIdentityMatrix(); static auto angle = 60.f; diff --git a/Source/RHI/UnitTest/5.ComputeParticles.cpp b/Source/RHI/UnitTest/5.ComputeParticles.cpp new file mode 100644 index 0000000..acfb857 --- /dev/null +++ b/Source/RHI/UnitTest/5.ComputeParticles.cpp @@ -0,0 +1,84 @@ +#include +#include +#include +#include +#include +#include +#include + +using namespace k3d; +using namespace kMath; + +class UTComputeParticles : public RHIAppBase +{ +public: + UTComputeParticles(kString const & appName, uint32 width, uint32 height) + : RHIAppBase(appName, width, height) + {} + explicit UTComputeParticles(kString const & appName) + : RHIAppBase(appName, 1920, 1080) + {} + + bool OnInit() override; + void OnDestroy() override; + void OnProcess(Message & msg) override; + + void OnUpdate() override; + +protected: + void PreparePipeline(); + +private: + rhi::PipelineStateObjectRef m_pGfxPso; + rhi::PipelineLayoutRef m_pGfxPl; + rhi::PipelineStateObjectRef m_pCompPso; + rhi::PipelineLayoutRef m_pCompPl; +}; + +K3D_APP_MAIN(UTComputeParticles); + +bool UTComputeParticles::OnInit() +{ + bool inited = RHIAppBase::OnInit(); + if(!inited) + return inited; + PreparePipeline(); + return true; +} + +void UTComputeParticles::PreparePipeline() +{ + rhi::ShaderBundle vertSh, fragSh, compSh; + Compile("asset://Test/particles.vert", rhi::ES_Vertex, vertSh); + Compile("asset://Test/particles.frag", rhi::ES_Fragment, fragSh); + Compile("asset://Test/particles.comp", rhi::ES_Compute, compSh); + auto vertBinding = vertSh.BindingTable; + auto fragBinding = fragSh.BindingTable; + auto mergedBindings = vertBinding | fragBinding; + m_pGfxPl = m_pDevice->NewPipelineLayout(mergedBindings); + m_pCompPl = m_pDevice->NewPipelineLayout(compSh.BindingTable); + + rhi::PipelineDesc gfxDesc; + gfxDesc.Shaders[rhi::ES_Vertex] = vertSh; + gfxDesc.Shaders[rhi::ES_Fragment] = fragSh; + //gfxDesc.InputState = m_CubeMesh->GetInputState(); + rhi::PipelineDesc compDesc; + compDesc.Shaders[rhi::ES_Compute] = compSh; + m_pGfxPso = m_pDevice->NewPipelineState(gfxDesc, m_pGfxPl, rhi::EPSO_Graphics); + m_pCompPso = m_pDevice->NewPipelineState(compDesc, m_pCompPl, rhi::EPSO_Compute); +} + +void UTComputeParticles::OnUpdate() +{ + +} + +void UTComputeParticles::OnProcess(Message & msg) +{ + +} + +void UTComputeParticles::OnDestroy() +{ + +} \ No newline at end of file diff --git a/Source/UnitTest/Android/TexturedCube/build.gradle b/Source/RHI/UnitTest/Android/TexturedCube/build.gradle old mode 100755 new mode 100644 similarity index 83% rename from Source/UnitTest/Android/TexturedCube/build.gradle rename to Source/RHI/UnitTest/Android/TexturedCube/build.gradle index b4ce206..50d81f9 --- a/Source/UnitTest/Android/TexturedCube/build.gradle +++ b/Source/RHI/UnitTest/Android/TexturedCube/build.gradle @@ -16,17 +16,17 @@ android { '-DANDROID_TOOLCHAIN=clang', '-DANDROID_STL=gnustl_shared', '-DANDROID_CPP_FEATURES=rtti' - targets '4.TexturedCube','KawaLog','RHI_Vulkan' + targets 'RHI-UnitTest-4.TexturedCube','KawaLog','RHI_Vulkan' } } ndk { - abiFilters 'armeabi-v7a' + abiFilters 'arm64-v8a' } } sourceSets { main { - assets.srcDirs '../../../../Data' + assets.srcDirs '../../../../../Data' } } @@ -38,7 +38,7 @@ android { } externalNativeBuild { cmake { - path "../../../CMakeLists.txt" + path "../../../../CMakeLists.txt" } } } diff --git a/Source/UnitTest/Android/TexturedCube/src/main/AndroidManifest.xml b/Source/RHI/UnitTest/Android/TexturedCube/src/main/AndroidManifest.xml old mode 100755 new mode 100644 similarity index 100% rename from Source/UnitTest/Android/TexturedCube/src/main/AndroidManifest.xml rename to Source/RHI/UnitTest/Android/TexturedCube/src/main/AndroidManifest.xml diff --git a/Source/UnitTest/Android/TexturedCube/src/main/java/com/tsinstudio/app/MainActivity.java b/Source/RHI/UnitTest/Android/TexturedCube/src/main/java/com/tsinstudio/app/MainActivity.java old mode 100755 new mode 100644 similarity index 90% rename from Source/UnitTest/Android/TexturedCube/src/main/java/com/tsinstudio/app/MainActivity.java rename to Source/RHI/UnitTest/Android/TexturedCube/src/main/java/com/tsinstudio/app/MainActivity.java index 285ae5d..0e757fe --- a/Source/UnitTest/Android/TexturedCube/src/main/java/com/tsinstudio/app/MainActivity.java +++ b/Source/RHI/UnitTest/Android/TexturedCube/src/main/java/com/tsinstudio/app/MainActivity.java @@ -27,6 +27,6 @@ public void onDestroy() { } static { - System.loadLibrary("4.TexturedCube"); + System.loadLibrary("RHI-UnitTest-4.TexturedCube"); } } diff --git a/Source/UnitTest/Android/TexturedCube/src/main/res/layout/activity_k.xml b/Source/RHI/UnitTest/Android/TexturedCube/src/main/res/layout/activity_k.xml old mode 100755 new mode 100644 similarity index 100% rename from Source/UnitTest/Android/TexturedCube/src/main/res/layout/activity_k.xml rename to Source/RHI/UnitTest/Android/TexturedCube/src/main/res/layout/activity_k.xml diff --git a/Source/UnitTest/Android/TexturedCube/src/main/res/mipmap-xhdpi/ic_launcher.png b/Source/RHI/UnitTest/Android/TexturedCube/src/main/res/mipmap-xhdpi/ic_launcher.png old mode 100755 new mode 100644 similarity index 100% rename from Source/UnitTest/Android/TexturedCube/src/main/res/mipmap-xhdpi/ic_launcher.png rename to Source/RHI/UnitTest/Android/TexturedCube/src/main/res/mipmap-xhdpi/ic_launcher.png diff --git a/Source/UnitTest/Android/TexturedCube/src/main/res/values-w820dp/dimens.xml b/Source/RHI/UnitTest/Android/TexturedCube/src/main/res/values-w820dp/dimens.xml old mode 100755 new mode 100644 similarity index 100% rename from Source/UnitTest/Android/TexturedCube/src/main/res/values-w820dp/dimens.xml rename to Source/RHI/UnitTest/Android/TexturedCube/src/main/res/values-w820dp/dimens.xml diff --git a/Source/UnitTest/Android/TexturedCube/src/main/res/values/colors.xml b/Source/RHI/UnitTest/Android/TexturedCube/src/main/res/values/colors.xml old mode 100755 new mode 100644 similarity index 100% rename from Source/UnitTest/Android/TexturedCube/src/main/res/values/colors.xml rename to Source/RHI/UnitTest/Android/TexturedCube/src/main/res/values/colors.xml diff --git a/Source/UnitTest/Android/TexturedCube/src/main/res/values/dimens.xml b/Source/RHI/UnitTest/Android/TexturedCube/src/main/res/values/dimens.xml old mode 100755 new mode 100644 similarity index 100% rename from Source/UnitTest/Android/TexturedCube/src/main/res/values/dimens.xml rename to Source/RHI/UnitTest/Android/TexturedCube/src/main/res/values/dimens.xml diff --git a/Source/UnitTest/Android/TexturedCube/src/main/res/values/strings.xml b/Source/RHI/UnitTest/Android/TexturedCube/src/main/res/values/strings.xml old mode 100755 new mode 100644 similarity index 100% rename from Source/UnitTest/Android/TexturedCube/src/main/res/values/strings.xml rename to Source/RHI/UnitTest/Android/TexturedCube/src/main/res/values/strings.xml diff --git a/Source/UnitTest/Android/TexturedCube/src/main/res/values/styles.xml b/Source/RHI/UnitTest/Android/TexturedCube/src/main/res/values/styles.xml old mode 100755 new mode 100644 similarity index 100% rename from Source/UnitTest/Android/TexturedCube/src/main/res/values/styles.xml rename to Source/RHI/UnitTest/Android/TexturedCube/src/main/res/values/styles.xml diff --git a/Source/UnitTest/Android/Triangle/build.gradle b/Source/RHI/UnitTest/Android/Triangle/build.gradle old mode 100755 new mode 100644 similarity index 84% rename from Source/UnitTest/Android/Triangle/build.gradle rename to Source/RHI/UnitTest/Android/Triangle/build.gradle index 9fd0373..b505390 --- a/Source/UnitTest/Android/Triangle/build.gradle +++ b/Source/RHI/UnitTest/Android/Triangle/build.gradle @@ -16,17 +16,17 @@ android { '-DANDROID_TOOLCHAIN=clang', '-DANDROID_STL=gnustl_shared', '-DANDROID_CPP_FEATURES=rtti' - targets '3.Triangle','RHI_Vulkan' + targets 'RHI-UnitTest-3.Triangle','RHI_Vulkan' } } ndk { - abiFilters 'armeabi-v7a' + abiFilters 'arm64-v8a' } } sourceSets { main { - assets.srcDirs '../../../../Data' + assets.srcDirs '../../../../../Data' } } @@ -38,7 +38,7 @@ android { } externalNativeBuild { cmake { - path "../../../CMakeLists.txt" + path "../../../../CMakeLists.txt" } } } diff --git a/Source/UnitTest/Android/Triangle/src/main/AndroidManifest.xml b/Source/RHI/UnitTest/Android/Triangle/src/main/AndroidManifest.xml old mode 100755 new mode 100644 similarity index 100% rename from Source/UnitTest/Android/Triangle/src/main/AndroidManifest.xml rename to Source/RHI/UnitTest/Android/Triangle/src/main/AndroidManifest.xml diff --git a/Source/UnitTest/Android/Triangle/src/main/java/com/tsinstudio/app/MainActivity.java b/Source/RHI/UnitTest/Android/Triangle/src/main/java/com/tsinstudio/app/MainActivity.java old mode 100755 new mode 100644 similarity index 91% rename from Source/UnitTest/Android/Triangle/src/main/java/com/tsinstudio/app/MainActivity.java rename to Source/RHI/UnitTest/Android/Triangle/src/main/java/com/tsinstudio/app/MainActivity.java index bb8c3aa..0aafc0b --- a/Source/UnitTest/Android/Triangle/src/main/java/com/tsinstudio/app/MainActivity.java +++ b/Source/RHI/UnitTest/Android/Triangle/src/main/java/com/tsinstudio/app/MainActivity.java @@ -27,6 +27,6 @@ public void onDestroy() { } static { - System.loadLibrary("3.Triangle"); + System.loadLibrary("RHI-UnitTest-3.Triangle"); } } diff --git a/Source/UnitTest/Android/Triangle/src/main/res/layout/activity_k.xml b/Source/RHI/UnitTest/Android/Triangle/src/main/res/layout/activity_k.xml old mode 100755 new mode 100644 similarity index 100% rename from Source/UnitTest/Android/Triangle/src/main/res/layout/activity_k.xml rename to Source/RHI/UnitTest/Android/Triangle/src/main/res/layout/activity_k.xml diff --git a/Source/UnitTest/Android/Triangle/src/main/res/mipmap-xhdpi/ic_launcher.png b/Source/RHI/UnitTest/Android/Triangle/src/main/res/mipmap-xhdpi/ic_launcher.png old mode 100755 new mode 100644 similarity index 100% rename from Source/UnitTest/Android/Triangle/src/main/res/mipmap-xhdpi/ic_launcher.png rename to Source/RHI/UnitTest/Android/Triangle/src/main/res/mipmap-xhdpi/ic_launcher.png diff --git a/Source/UnitTest/Android/Triangle/src/main/res/values-w820dp/dimens.xml b/Source/RHI/UnitTest/Android/Triangle/src/main/res/values-w820dp/dimens.xml old mode 100755 new mode 100644 similarity index 100% rename from Source/UnitTest/Android/Triangle/src/main/res/values-w820dp/dimens.xml rename to Source/RHI/UnitTest/Android/Triangle/src/main/res/values-w820dp/dimens.xml diff --git a/Source/UnitTest/Android/Triangle/src/main/res/values/colors.xml b/Source/RHI/UnitTest/Android/Triangle/src/main/res/values/colors.xml old mode 100755 new mode 100644 similarity index 100% rename from Source/UnitTest/Android/Triangle/src/main/res/values/colors.xml rename to Source/RHI/UnitTest/Android/Triangle/src/main/res/values/colors.xml diff --git a/Source/UnitTest/Android/Triangle/src/main/res/values/dimens.xml b/Source/RHI/UnitTest/Android/Triangle/src/main/res/values/dimens.xml old mode 100755 new mode 100644 similarity index 100% rename from Source/UnitTest/Android/Triangle/src/main/res/values/dimens.xml rename to Source/RHI/UnitTest/Android/Triangle/src/main/res/values/dimens.xml diff --git a/Source/UnitTest/Android/Triangle/src/main/res/values/strings.xml b/Source/RHI/UnitTest/Android/Triangle/src/main/res/values/strings.xml old mode 100755 new mode 100644 similarity index 100% rename from Source/UnitTest/Android/Triangle/src/main/res/values/strings.xml rename to Source/RHI/UnitTest/Android/Triangle/src/main/res/values/strings.xml diff --git a/Source/UnitTest/Android/Triangle/src/main/res/values/styles.xml b/Source/RHI/UnitTest/Android/Triangle/src/main/res/values/styles.xml old mode 100755 new mode 100644 similarity index 100% rename from Source/UnitTest/Android/Triangle/src/main/res/values/styles.xml rename to Source/RHI/UnitTest/Android/Triangle/src/main/res/values/styles.xml diff --git a/Source/UnitTest/4.TexturedCube/TextureObject.cpp b/Source/RHI/UnitTest/Base/TextureObject.cpp old mode 100755 new mode 100644 similarity index 80% rename from Source/UnitTest/4.TexturedCube/TextureObject.cpp rename to Source/RHI/UnitTest/Base/TextureObject.cpp index 634d72d..0591746 --- a/Source/UnitTest/4.TexturedCube/TextureObject.cpp +++ b/Source/RHI/UnitTest/Base/TextureObject.cpp @@ -1,22 +1,29 @@ +#include #include "TextureObject.h" -#include "RHI/IRHI.h" +#include /////////////////////////////////////////////////////////////////////////////// -TextureObject::TextureObject(rhi::DeviceRef pDevice, const uint8_t * dataInMemory) - : m_pDevice(pDevice), m_width(0), m_height(0), m_format(rhi::EPF_RGB8Unorm), m_pBits(nullptr), m_DataSize(0) +TextureObject::TextureObject(rhi::DeviceRef pDevice, const uint8_t * dataInMemory, bool useStaging) + : m_pDevice(pDevice), m_width(0), m_height(0), m_format(rhi::EPF_RGB8Unorm), m_pBits(nullptr), m_DataSize(0), m_UseStaging(useStaging) { InitData(dataInMemory); - InitTexture(); + if (!useStaging) + { + InitTexture(); + } } TextureObject::~TextureObject() { + KLOG(Info, TextureObject, "Destroying.."); Destroy(); } void TextureObject::MapIntoBuffer(rhi::GpuResourceRef stageBuff) { + if (!m_UseStaging) + return; void * pData = stageBuff->Map(0, GetSize()); memcpy(pData, m_pBits, GetSize()); stageBuff->UnMap(); @@ -24,6 +31,8 @@ void TextureObject::MapIntoBuffer(rhi::GpuResourceRef stageBuff) void TextureObject::CopyAndInitTexture(rhi::GpuResourceRef stageBuff) { + if (!m_UseStaging) + return; rhi::ResourceDesc texDesc; texDesc.Type = rhi::EGT_Texture2D; texDesc.ViewType = rhi::EGpuMemViewType::EGVT_SRV; @@ -93,11 +102,10 @@ void TextureObject::InitData(const uint8* dataInMemory) void TextureObject::InitTexture() { - /*rhi::ResourceDesc texDesc; + rhi::ResourceDesc texDesc; texDesc.Type = rhi::EGT_Texture2D; texDesc.ViewType = rhi::EGpuMemViewType::EGVT_SRV; - texDesc.CreationFlag = rhi::EGpuResourceCreationFlag::EGRCF_TransferDst; - texDesc.Flag = rhi::EGpuResourceAccessFlag::EGRAF_DeviceVisible; + texDesc.Flag = rhi::EGpuResourceAccessFlag::EGRAF_HostVisible; texDesc.TextureDesc.Format = rhi::EPF_RGBA8Unorm; texDesc.TextureDesc.Width = m_width; texDesc.TextureDesc.Height = m_height; @@ -106,26 +114,33 @@ void TextureObject::InitTexture() texDesc.TextureDesc.Depth = 1; m_Resource = m_pDevice->NewGpuResource(texDesc); - m_pContext = m_pDevice->NewCommandContext(rhi::ECMD_Graphics); - m_pContext->Begin(); - m_pContext->TransitionResourceBarrier(m_Resource, rhi::ERS_Unknown, rhi::ERS_ShaderResource); - m_pContext->End(); - m_pContext->Execute(false); - uint64 sz = m_Resource->GetResourceSize(); + uint64 sz = m_Resource->GetSize(); void * pData = m_Resource->Map(0, sz); rhi::SubResourceLayout layout = {}; rhi::TextureResourceSpec spec = { rhi::ETAF_COLOR,0,0 }; - m_pDevice->QueryTextureSubResourceLayout(m_Resource, spec, &layout); - - for (int y = 0; y < m_height; y++) + m_pDevice->QueryTextureSubResourceLayout(k3d::StaticPointerCast(m_Resource), spec, &layout); + if (m_width * 4 == layout.RowPitch) // directly upload + { + memcpy(pData, m_pBits, sz); + } + else { - uint32_t *row = (uint32_t *)((char *)pData + layout.RowPitch * y); - for (int x = 0; x < m_width; x++) + for (int y = 0; y < m_height; y++) { - row[x] = m_pBits[x + y * m_width]; + uint32_t *row = (uint32_t *)((char *)pData + layout.RowPitch * y); + for (int x = 0; x < m_width; x++) + { + row[x] = m_pBits[x + y * m_width]; + } } } - m_Resource->UnMap();*/ + m_Resource->UnMap(); + + m_pContext = m_pDevice->NewCommandContext(rhi::ECMD_Graphics); + m_pContext->Begin(); + m_pContext->TransitionResourceBarrier(m_Resource, rhi::ERS_ShaderResource); + m_pContext->End(); + m_pContext->Execute(false); } diff --git a/Source/UnitTest/4.TexturedCube/TextureObject.h b/Source/RHI/UnitTest/Base/TextureObject.h old mode 100755 new mode 100644 similarity index 93% rename from Source/UnitTest/4.TexturedCube/TextureObject.h rename to Source/RHI/UnitTest/Base/TextureObject.h index 00045c9..6ef5236 --- a/Source/UnitTest/4.TexturedCube/TextureObject.h +++ b/Source/RHI/UnitTest/Base/TextureObject.h @@ -1,7 +1,7 @@ #ifndef __TextureObject_h__ #define __TextureObject_h__ -#include +#include /* * Defines a simple object for creating and holding Vulkan texture objects. * Supports loading from TGA files in Android Studio asset folder. @@ -11,7 +11,7 @@ class TextureObject { public: - TextureObject(rhi::DeviceRef pDevice, const uint8_t* dataInMemory); + TextureObject(rhi::DeviceRef pDevice, const uint8_t* dataInMemory, bool useStaging = true); ~TextureObject(); uint64 GetSize() const { return m_DataSize; } @@ -39,6 +39,7 @@ class TextureObject rhi::GpuResourceRef m_Resource; rhi::SamplerRef m_sampler; rhi::EPixelFormat m_format; + bool m_UseStaging; uint64 m_DataSize; uint32_t m_width; uint32_t m_height; diff --git a/Source/RHI/UnitTest/Base/UTRHIAppBase.h b/Source/RHI/UnitTest/Base/UTRHIAppBase.h new file mode 100644 index 0000000..8878014 --- /dev/null +++ b/Source/RHI/UnitTest/Base/UTRHIAppBase.h @@ -0,0 +1,131 @@ +#ifndef __UTRHIBaseApp_h__ +#define __UTRHIBaseApp_h__ + +#include +#include +#include +#include +#include +#include + +#if K3DPLATFORM_OS_WIN +#include +#include +#elif K3DPLATFORM_OS_MAC||K3DPLATFORM_OS_IOS +#include +#include +#else +#include +#include +#endif + +using namespace k3d; +using namespace kMath; + +class RHIAppBase : public App +{ +public: + RHIAppBase(kString const & appName, uint32 width, uint32 height) + : App(appName, width, height), m_Width(width), m_Height(height) + { + + } + + virtual ~RHIAppBase() override + { + } + + virtual bool OnInit() override + { + bool inited = App::OnInit(); + if(!inited) + return inited; + LoadGlslangCompiler(); + LoadRHI(); + InitViewport(); + return true; + } + + void Compile(const char * shaderPath, rhi::EShaderType const & type, rhi::ShaderBundle & shader); + +protected: + SharedPtr m_ShaderModule; + rhi::IShCompiler::Ptr m_RHICompiler; + SharedPtr m_RHIModule; + + rhi::DeviceRef m_pDevice; + rhi::RenderViewportRef m_pViewport; + + uint32 m_Width; + uint32 m_Height; + +private: + void LoadGlslangCompiler(); + void LoadRHI(); + void InitViewport(); + +private: + rhi::GfxSetting m_Setting{m_Width, m_Height, rhi::EPF_RGBA8Unorm, rhi::EPF_D32Float, true, 2 }; +}; + +void RHIAppBase::LoadGlslangCompiler() +{ + m_ShaderModule = k3d::StaticPointerCast(ACQUIRE_PLUGIN(ShaderCompiler)); + if (m_ShaderModule) + { +#if K3DPLATFORM_OS_MAC + m_RHICompiler = m_ShaderModule->CreateShaderCompiler(rhi::ERHI_Metal); +#else + m_RHICompiler = m_ShaderModule->CreateShaderCompiler(rhi::ERHI_Vulkan); +#endif + } +} + +void RHIAppBase::LoadRHI() +{ +#if !(K3DPLATFORM_OS_MAC || K3DPLATFORM_OS_IOS) + m_RHIModule = SharedPtr( ACQUIRE_PLUGIN(RHI_Vulkan) ); + auto pRHI = StaticPointerCast(m_RHIModule); + pRHI->Initialize("RenderContext", true); + pRHI->Start(); + m_pDevice = pRHI->GetPrimaryDevice(); +#else + m_RHIModule = ACQUIRE_PLUGIN(RHI_Metal); + auto pRHI = StaticPointerCast(m_RHIModule); + if(pRHI) + { + pRHI->Start(); + m_pDevice = pRHI->GetPrimaryDevice(); + } +#endif +} + +void RHIAppBase::Compile(const char * shaderPath, rhi::EShaderType const & type, rhi::ShaderBundle & shader) +{ + IAsset * shaderFile = AssetManager::Open(shaderPath); + if (!shaderFile) + { + KLOG(Fatal, "RHIAppBase", "Error opening %s.", shaderPath); + return; + } + std::vector buffer; + uint64 len = shaderFile->GetLength(); + buffer.resize(len+1); + shaderFile->Read(buffer.data(), shaderFile->GetLength()); + buffer[len] = 0; + String src(buffer.data()); + rhi::ShaderDesc desc = { rhi::EShFmt_Text, rhi::EShLang_HLSL, rhi::EShProfile_Modern, type, "main" }; + m_RHICompiler->Compile(src, desc, shader); +} + +void RHIAppBase::InitViewport() +{ + if (!m_pViewport) + { + rhi::GfxSetting setting{m_Width, m_Height, rhi::EPF_RGBA8Unorm, rhi::EPF_D32Float, true, 2 }; + m_pViewport = m_pDevice->NewRenderViewport(HostWindow()->GetHandle(), setting); + m_pViewport->InitViewport(nullptr, nullptr, setting); + } +} + +#endif diff --git a/Source/RHI/UnitTest/CMakeLists.txt b/Source/RHI/UnitTest/CMakeLists.txt new file mode 100644 index 0000000..e82aae8 --- /dev/null +++ b/Source/RHI/UnitTest/CMakeLists.txt @@ -0,0 +1,36 @@ +if(BUILD_SHARED) + add_definitions(-DBUILD_SHARED_LIB -DBUILD_WITH_PLUGIN) +endif() +################################## Unit Test For RHI ##################################### + +include_directories( + ${FREETYPE2_INCLUDE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR} +) + +add_unittest( + RHI-UnitTest-1.Device + 1.Device.cpp +) + +add_unittest( + RHI-UnitTest-2.SwapChainPresent + 2.SwapChainPresent.cpp +) + +add_unittest( + RHI-UnitTest-3.Triangle + 3.Triangle.cpp +) + +add_unittest( + RHI-UnitTest-4.TexturedCube + 4.TexturedCube.cpp + Base/TextureObject.h + Base/TextureObject.cpp +) + +add_unittest( + RHI-UnitTest-5.ComputeParticles + 5.ComputeParticles.cpp +) \ No newline at end of file diff --git a/Source/RHI/Vulkan/CMakeLists.txt b/Source/RHI/Vulkan/CMakeLists.txt index ab7abb5..500fb1d 100755 --- a/Source/RHI/Vulkan/CMakeLists.txt +++ b/Source/RHI/Vulkan/CMakeLists.txt @@ -11,7 +11,6 @@ elseif(ANDROID) endif() set(RHI_HEADERS - ../IRHI.h VkCommon.h Public/IVkRHI.h ) @@ -29,11 +28,8 @@ set(RHI_IMPL_SRCS Private/VkCommandContext.cpp Private/VkResource.cpp Private/VkPipelineState.cpp - Private/VkSampler.cpp - Private/VkPipelineLayout.cpp Private/VkDescriptor.cpp Private/VkSwapChain.cpp - Private/VkFrameBuffer.cpp Private/VkRenderPass.cpp Private/VkDebug.cpp Private/VkImpl.cpp @@ -51,10 +47,16 @@ source_group( ${RHI_IMPL_SRCS} ) -add_plugin(RHI_Vulkan "Runtime/RHI" ${VKRHI_SRC_LIST} ${RHI_HEADERS} ${RHI_IMPL_SRCS} LINKLIBS ShaderCompiler) +add_plugin(RHI_Vulkan + FOLDER "Runtime/RHI" + SRCS ${VKRHI_SRC_LIST} ${RHI_HEADERS} ${RHI_IMPL_SRCS} + LIBS ShaderCompiler ${VULKAN_LIB}) if(NOT ANDROID) - install(TARGETS RHI_Vulkan ARCHIVE DESTINATION lib) add_precompiled_header(RHI_Vulkan "VkCommon.h" "${Kaleido3D_ROOT_DIR}/Source/RHI/Vulkan" "${Kaleido3D_ROOT_DIR}/Source/RHI/Vulkan/Private/VkRHI.cpp") endif() +install(TARGETS RHI_Vulkan + ARCHIVE DESTINATION lib + LIBRARY DESTINATION lib + RUNTIME DESTINATION bin) \ No newline at end of file diff --git a/Source/RHI/Vulkan/Private/DynVulkanLoader.cpp b/Source/RHI/Vulkan/Private/DynVulkanLoader.cpp index 52403e1..c7c7e5b 100755 --- a/Source/RHI/Vulkan/Private/DynVulkanLoader.cpp +++ b/Source/RHI/Vulkan/Private/DynVulkanLoader.cpp @@ -15,7 +15,9 @@ static const char* LIBVULKAN = "libvulkan.so"; namespace dynlib { Lib::Lib(const char* libName) - : m_LibHandle(NULL) + : m_pUserData(nullptr) + , m_LibHandle(nullptr) + , m_CallBack(nullptr) { #if K3DPLATFORM_OS_WIN m_LibHandle = LoadLibrary(libName); @@ -28,8 +30,14 @@ namespace dynlib { if (m_LibHandle) { + if (m_CallBack) + { + m_CallBack(m_pUserData); + m_CallBack = nullptr; + } + VKLOG(Warn, "Vulkan Library will be freed, any vk-call after here(%s@%d) would be dangerous!", __FILE__, __LINE__); #if K3DPLATFORM_OS_WIN - ::FreeLibrary((HMODULE)m_LibHandle); + //::FreeLibrary((HMODULE)m_LibHandle); #else dlclose(m_LibHandle); #endif @@ -46,12 +54,14 @@ namespace dynlib #endif } - Lib & GetVulkanLib() { - static Lib vkLib(LIBVULKAN); - return vkLib; + void Lib::SetDestroyCallBack(void * userData, CallBack callback) + { + m_pUserData = userData; + m_CallBack = callback; } } +#ifdef VK_NO_PROTOTYPES _DEF_VK_FUNC_(GetInstanceProcAddr); _DEF_VK_FUNC_(GetDeviceProcAddr); @@ -203,14 +213,11 @@ _DEF_VK_FUNC_(CmdNextSubpass); _DEF_VK_FUNC_(CmdEndRenderPass); _DEF_VK_FUNC_(CmdExecuteCommands); _DEF_VK_FUNC_(AcquireNextImageKHR); +#endif int LoadVulkan(VkInstance instance, VkDevice device) { - vkGetInstanceProcAddr = (PFN_vkGetInstanceProcAddr)dynlib::GetVulkanLib().ResolveEntry("vkGetInstanceProcAddr"); - vkEnumerateInstanceLayerProperties = (PFN_vkEnumerateInstanceLayerProperties)dynlib::GetVulkanLib().ResolveEntry("vkEnumerateInstanceLayerProperties"); - vkEnumerateInstanceExtensionProperties = (PFN_vkEnumerateInstanceExtensionProperties)dynlib::GetVulkanLib().ResolveEntry("vkEnumerateInstanceExtensionProperties"); - vkGetPhysicalDeviceSurfaceSupportKHR = (PFN_vkGetPhysicalDeviceSurfaceSupportKHR)dynlib::GetVulkanLib().ResolveEntry("vkGetPhysicalDeviceSurfaceSupportKHR"); - vkGetPhysicalDeviceSurfaceCapabilitiesKHR = (PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR)dynlib::GetVulkanLib().ResolveEntry("vkGetPhysicalDeviceSurfaceCapabilitiesKHR"); +#ifdef VK_NO_PROTOTYPES #if K3DPLATFORM_OS_WIN _VK_GET_INSTANCE_POINTER_(instance, CreateWin32SurfaceKHR); @@ -353,7 +360,7 @@ int LoadVulkan(VkInstance instance, VkDevice device) _VK_GET_DEVICE_POINTER_(device, CmdEndRenderPass); _VK_GET_DEVICE_POINTER_(device, CmdExecuteCommands); _VK_GET_DEVICE_POINTER_(device, AcquireNextImageKHR); - +#endif return 0; } @@ -494,7 +501,7 @@ VkResult vkCmd::CreateGraphicsPipelines(VkDevice Device, VkPipelineCache Pipelin { std::stringstream param; param << "vkCmd::CreateGraphicsPipelines() device=" << std::hex << std::setfill('0') << Device << ", cache=" << std::hex << std::setfill('0') << PipelineCache << ", CreateInfoCount=" << CreateInfoCount; - if (CreateInfoCount) + if (CreateInfoCount && CreateInfos) { for (int i = 0; i < CreateInfoCount; i++) param << ", \n\tCreateInfos[" << i << "]=" << DumpGraphicsPipelineCreateInfo(CreateInfos[i]); diff --git a/Source/RHI/Vulkan/Private/DynVulkanLoader.h b/Source/RHI/Vulkan/Private/DynVulkanLoader.h index 6e3ff8c..518b301 100755 --- a/Source/RHI/Vulkan/Private/DynVulkanLoader.h +++ b/Source/RHI/Vulkan/Private/DynVulkanLoader.h @@ -3,16 +3,30 @@ #ifndef __DynVulkanLoader_h__ #define __DynVulkanLoader_h__ -#define VK_NO_PROTOTYPES +//#define VK_NO_PROTOTYPES #if K3DPLATFORM_OS_WIN #define VK_USE_PLATFORM_WIN32_KHR 1 #elif K3DPLATFORM_OS_ANDROID #define VK_USE_PLATFORM_ANDROID_KHR 1 #endif #include +#include +#include + +#ifdef VK_NO_PROTOTYPES -#define _VK_GET_FUNCTION_FROM_LIB_(funcName) vk##funcName = (PFN_vk##funcName)dynlib::GetVulkanLib().ResolveEntry("vk" K3D_STRINGIFY(funcName)); #define _VK_GET_INSTANCE_POINTER_(instance, funcName) vk##funcName = (PFN_vk##funcName)vkGetInstanceProcAddr(instance, "vk" K3D_STRINGIFY(funcName)); + +// Macro to get a procedure address based on a vulkan instance +#define GET_INSTANCE_PROC_ADDR(inst, entrypoint) \ +{ \ + fp##entrypoint = (PFN_vk##entrypoint) gpGetInstanceProcAddr(inst, "vk"#entrypoint); \ + if (fp##entrypoint == NULL) \ + { \ + exit(1); \ + } \ +} + #define _VK_GET_DEVICE_POINTER_(device, funcName) vk##funcName = (PFN_vk##funcName)vkGetDeviceProcAddr(device, "vk" K3D_STRINGIFY(funcName)); #define _DEF_VK_FUNC_(funcName) PFN_vk##funcName vk##funcName = NULL #define _PREDEF_VK_FUNC_(funcName) extern K3D_API PFN_vk##funcName vk##funcName @@ -174,21 +188,26 @@ _PREDEF_VK_FUNC_(CmdEndRenderPass); _PREDEF_VK_FUNC_(CmdExecuteCommands); _PREDEF_VK_FUNC_(AcquireNextImageKHR); +#endif + namespace dynlib { + typedef void(*CallBack)(void* pUserData); class Lib { public: - Lib(const char* libName); + Lib(const char* libName = nullptr); ~Lib(); - void* ResolveEntry(const char* functionName); + void* ResolveEntry(const char* functionName); + void SetDestroyCallBack(void *userData, CallBack callback); private: - void*m_LibHandle; + void* m_pUserData; + void* m_LibHandle; + CallBack m_CallBack; }; - - Lib & GetVulkanLib(); + using LibRef = ::k3d::SharedPtr; } extern int LoadVulkan(VkInstance instance, VkDevice device); diff --git a/Source/RHI/Vulkan/Private/VkCommandContext.cpp b/Source/RHI/Vulkan/Private/VkCommandContext.cpp index d797b51..cd61932 100755 --- a/Source/RHI/Vulkan/Private/VkCommandContext.cpp +++ b/Source/RHI/Vulkan/Private/VkCommandContext.cpp @@ -10,8 +10,8 @@ K3D_VK_BEGIN using namespace Os; -CommandQueue::CommandQueue(Device::Ptr pDevice, VkQueueFlags queueTypes, uint32 queueFamilyIndex, uint32 queueIndex) - : DeviceChild(pDevice) +CommandQueue::CommandQueue(VkDevice pDevice, VkQueueFlags queueTypes, uint32 queueFamilyIndex, uint32 queueIndex) + : m_Device(pDevice) { Initialize(queueTypes, queueFamilyIndex, queueIndex); } @@ -45,7 +45,7 @@ VkResult CommandQueue::Submit(const std::vector& submits, VkFence K3D_ASSERT(!submits.empty()); uint32_t submitCount = static_cast(submits.size()); const VkSubmitInfo* pSubmits = submits.data(); - VkResult err = vkCmd::QueueSubmit(m_Queue, submitCount, pSubmits, fence); + VkResult err = vkQueueSubmit(m_Queue, submitCount, pSubmits, fence); K3D_ASSERT((err == VK_SUCCESS) || (err == VK_ERROR_DEVICE_LOST)); return err; } @@ -59,7 +59,7 @@ void CommandQueue::Initialize(VkQueueFlags queueTypes, uint32 queueFamilyIndex, { m_QueueFamilyIndex = queueFamilyIndex; m_QueueIndex = queueIndex; - vkGetDeviceQueue(GetRawDevice(), m_QueueFamilyIndex, m_QueueIndex, &m_Queue); + vkGetDeviceQueue(m_Device, m_QueueFamilyIndex, m_QueueIndex, &m_Queue); } void CommandQueue::Destroy() @@ -76,10 +76,10 @@ CommandContextPool::CommandContextPool(Device::Ptr pDevice) CommandContextPool::~CommandContextPool() { - VKLOG(Info, "CommandContextPool-Destroying...."); + VKLOG(Info, "CommandContextPool Destroying...."); } -CommandContext* CommandContextPool::RequestContext(rhi::ECommandType type) +rhi::CommandContextRef CommandContextPool::RequestContext(rhi::ECommandType type) { ::Os::Mutex::AutoLock lock(&m_ContextMutex); PtrCmdAlloc pAllocator = RequestCommandAllocator(); @@ -94,7 +94,7 @@ CommandContext* CommandContextPool::RequestContext(rhi::ECommandType type) } VkCommandBuffer cmdBuffer; K3D_VK_VERIFY(vkAllocateCommandBuffers(GetRawDevice(), &info, &cmdBuffer)); - auto context = new CommandContext(GetDevice(), cmdBuffer, pAllocator->GetCommandPool(), type); + auto context = rhi::CommandContextRef(new CommandContext(GetDevice(), cmdBuffer, pAllocator->GetCommandPool(), type)); //uint32 tid = Thread::GetId(); //m_ContextList[tid].push_back(context); VKLOG(Info, "CommandContextPool::RequestContext() called in thread [%s], (cmdBuf=0x%x, type=%d).", Thread::GetCurrentThreadName().c_str(), cmdBuffer, type); @@ -121,14 +121,16 @@ CommandContext::CommandContext(Device::Ptr pDevice) } CommandContext::CommandContext(Device::Ptr pDevice, VkCommandBuffer cmdBuf, VkCommandPool pool, rhi::ECommandType type) - : DeviceChild(pDevice), m_CommandBuffer(cmdBuf), m_CommandPool(pool), m_CmdType(type) + : DeviceChild(pDevice), m_CommandBuffer(cmdBuf),/* m_CommandPool(pool),*/ m_CmdType(type) { } CommandContext::~CommandContext() { - VKRHI_METHOD_TRACE - vkFreeCommandBuffers(GetRawDevice(), m_CommandPool, 1, &m_CommandBuffer); + GetDevice()->WaitIdle(); + VKLOG(Info, "CommandContext destroy.. -- %0x. ", m_CommandBuffer); + //vkFreeCommandBuffers(GetRawDevice(), m_CommandPool, 1, &m_CommandBuffer); + //m_CommandBuffer = VK_NULL_HANDLE; } void CommandContext::Detach(rhi::IDevice * pDevice) @@ -138,13 +140,13 @@ void CommandContext::Detach(rhi::IDevice * pDevice) void CommandContext::CopyBuffer(rhi::IGpuResource& Dest, rhi::IGpuResource& Src, rhi::CopyBufferRegion const& Region) { - vkCmd::CopyBuffer(m_CommandBuffer, (VkBuffer)Src.GetResourceLocation(), (VkBuffer)Dest.GetResourceLocation(), 1, (const VkBufferCopy*)&Region); + vkCmdCopyBuffer(m_CommandBuffer, (VkBuffer)Src.GetLocation(), (VkBuffer)Dest.GetLocation(), 1, (const VkBufferCopy*)&Region); } void CommandContext::CopyTexture(const rhi::TextureCopyLocation & Dest, const rhi::TextureCopyLocation & Src) { K3D_ASSERT(Dest.pResource && Src.pResource); - if (Src.pResource->GetResourceType() == rhi::EGT_Buffer && Dest.pResource->GetResourceType() != rhi::EGT_Buffer) + if (Src.pResource->GetDesc().Type == rhi::EGT_Buffer && Dest.pResource->GetDesc().Type != rhi::EGT_Buffer) { DynArray Copies; for (auto footprint : Src.SubResourceFootPrints) @@ -156,7 +158,7 @@ void CommandContext::CopyTexture(const rhi::TextureCopyLocation & Dest, const rh bImgCpy.imageSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1 }; Copies.Append(bImgCpy); } - vkCmdCopyBufferToImage(m_CommandBuffer, (VkBuffer)Src.pResource->GetResourceLocation(), (VkImage)Dest.pResource->GetResourceLocation(), + vkCmdCopyBufferToImage(m_CommandBuffer, (VkBuffer)Src.pResource->GetLocation(), (VkImage)Dest.pResource->GetLocation(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, Copies.Count(), Copies.Data()); } } @@ -238,7 +240,7 @@ void CommandContext::SubmitAndWait(PtrSemaphore wait, PtrSemaphore signal, PtrFe q = GetImmCmdQueue(); break; } - q->Submit({ submitInfo }, fence ? fence->m_Fence : VK_NULL_HANDLE); + q->Submit({ submitInfo }, fence ? fence->NativeHandle() : VK_NULL_HANDLE); } void CommandContext::InitCommandBufferPool() @@ -347,6 +349,11 @@ void CommandContext::PipelineBarrierImageMemory(const ImageMemoryBarrierParams & VkImageMemoryBarrier barrier = params.m_Barrier; switch (params.m_Barrier.oldLayout) { + case VK_IMAGE_LAYOUT_PRESENT_SRC_KHR: + { + barrier.srcAccessMask = VK_ACCESS_MEMORY_READ_BIT; + break; + } case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL: { barrier.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; @@ -390,7 +397,11 @@ void CommandContext::PipelineBarrierImageMemory(const ImageMemoryBarrierParams & barrier.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; break; } - + case VK_IMAGE_LAYOUT_PRESENT_SRC_KHR: + { + barrier.dstAccessMask = VK_ACCESS_MEMORY_READ_BIT; + break; + } case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL: { barrier.dstAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; @@ -406,7 +417,6 @@ void CommandContext::PipelineBarrierImageMemory(const ImageMemoryBarrierParams & barrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT; break; } - case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL: { barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; @@ -434,8 +444,8 @@ void CommandContext::SetScissorRects(uint32 count, VkRect2D * pRects) void CommandContext::ClearColorBuffer(rhi::GpuResourceRef gpuRes, kMath::Vec4f const& color) { VkImageSubresourceRange image_subresource_range = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1}; - vkCmdClearColorImage(m_CommandBuffer, (VkImage)gpuRes->GetResourceLocation(), - g_ResourceState[ gpuRes->GetUsageState() ], (const VkClearColorValue*)&color, 1, &image_subresource_range); + vkCmdClearColorImage(m_CommandBuffer, (VkImage)gpuRes->GetLocation(), + g_ResourceState[ gpuRes->GetState() ], (const VkClearColorValue*)&color, 1, &image_subresource_range); } void CommandContext::ClearDepthBuffer(rhi::IDepthBuffer* iDepthBuffer) @@ -499,7 +509,7 @@ void CommandContext::SetPipelineLayout(rhi::PipelineLayoutRef pRHIPipelineLayout K3D_ASSERT(pRHIPipelineLayout); auto pipelineLayout = StaticPointerCast(pRHIPipelineLayout); VkDescriptorSet sets[] = { pipelineLayout->GetNativeDescriptorSet() }; - vkCmdBindDescriptorSets(m_CommandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout->GetNativeLayout(), 0, 1, sets, 0, NULL); + vkCmdBindDescriptorSets(m_CommandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout->NativeHandle(), 0, 1, sets, 0, NULL); } void CommandContext::SetPrimitiveType(rhi::EPrimitiveType) @@ -557,16 +567,16 @@ void CommandContext::Dispatch(uint32 x, uint32 y, uint32 z) void CommandContext::TransitionResourceBarrier(rhi::GpuResourceRef resource,/* rhi::EPipelineStage stage,*/ rhi::EResourceState dstState) { - VKRHI_METHOD_TRACE - auto pTex = k3d::DynamicPointerCast(resource); + //VKRHI_METHOD_TRACE + auto pTex = k3d::StaticPointerCast(resource); if (pTex) { - VkImageLayout srcLayout = g_ResourceState[resource->GetUsageState()]; + VkImageLayout srcLayout = g_ResourceState[resource->GetState()]; VkImageLayout dstLayout = g_ResourceState[dstState]; ImageMemoryBarrierParams param(pTex->Get(), srcLayout, dstLayout); VkImageSubresourceRange texSubRange = pTex->GetSubResourceRange(); param.SrcStageMask(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT).DstStageMask(VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT).SubResourceRange(texSubRange); - if (dstState == rhi::ERS_TransferDst || resource->GetUsageState() == rhi::ERS_TransferDst) + if (dstState == rhi::ERS_TransferDst || resource->GetState() == rhi::ERS_TransferDst) { param.SrcStageMask(VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT).DstStageMask(VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT); } diff --git a/Source/RHI/Vulkan/Private/VkConfig.h b/Source/RHI/Vulkan/Private/VkConfig.h index cac6481..a8a57ff 100755 --- a/Source/RHI/Vulkan/Private/VkConfig.h +++ b/Source/RHI/Vulkan/Private/VkConfig.h @@ -14,7 +14,6 @@ namespace { "VK_LAYER_LUNARG_standard_validation", }; - } #ifdef DEBUG_MARKER diff --git a/Source/RHI/Vulkan/Private/VkDebug.cpp b/Source/RHI/Vulkan/Private/VkDebug.cpp index 79da241..8a8717d 100755 --- a/Source/RHI/Vulkan/Private/VkDebug.cpp +++ b/Source/RHI/Vulkan/Private/VkDebug.cpp @@ -1,11 +1,9 @@ #include "VkCommon.h" #include "VkConfig.h" +#include "VkObjects.h" K3D_VK_BEGIN -_DEF_VK_FUNC_(CreateDebugReportCallbackEXT); -_DEF_VK_FUNC_(DestroyDebugReportCallbackEXT); - PFN_vkDebugReportMessageEXT dbgBreakCallback; static VkDebugReportCallbackEXT msgCallback = NULL; @@ -53,39 +51,39 @@ VKAPI_ATTR VkBool32 VKAPI_CALL DebugReportCallback( return VK_TRUE; } -void SetupDebugging(VkInstance instance, VkDebugReportFlagsEXT flags, VkDebugReportCallbackEXT callBack) -{ - VKRHI_METHOD_TRACE - _VK_GET_FUNCTION_FROM_LIB_(CreateDebugReportCallbackEXT); - if (!vkCreateDebugReportCallbackEXT) - _VK_GET_INSTANCE_POINTER_(instance, CreateDebugReportCallbackEXT); - _VK_GET_FUNCTION_FROM_LIB_(DestroyDebugReportCallbackEXT); - if (!vkDestroyDebugReportCallbackEXT) - _VK_GET_INSTANCE_POINTER_(instance, DestroyDebugReportCallbackEXT); +#define __VK_GLOBAL_PROC_GET__(name, functor) fp##name = reinterpret_cast(functor("vk" K3D_STRINGIFY(name))) +void Instance::SetupDebugging(VkDebugReportFlagsEXT flags, PFN_vkDebugReportCallbackEXT callBack) +{ + if (!m_Instance) + { + VKLOG(Error, "SetupDebugging Failed. (m_Instance == null)"); + return; + } +// __VK_GLOBAL_PROC_GET__(CreateDebugReportCallbackEXT, m_VulkanLib->ResolveEntry); +// if (!vkCreateDebugReportCallbackEXT) +// GET_INSTANCE_PROC_ADDR(m_Instance, CreateDebugReportCallbackEXT); +// __VK_GLOBAL_PROC_GET__(DestroyDebugReportCallbackEXT, m_VulkanLib->ResolveEntry); +// if (!fpDestroyDebugReportCallbackEXT) +// GET_INSTANCE_PROC_ADDR(m_Instance, DestroyDebugReportCallbackEXT); VkDebugReportCallbackCreateInfoEXT dbgCreateInfo; dbgCreateInfo.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT; dbgCreateInfo.pNext = NULL; - dbgCreateInfo.pfnCallback = &DebugReportCallback; + dbgCreateInfo.pfnCallback = callBack; dbgCreateInfo.pUserData = NULL; - dbgCreateInfo.flags = VK_DEBUG_REPORT_ERROR_BIT_EXT | - VK_DEBUG_REPORT_WARNING_BIT_EXT | - VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT; - K3D_VK_VERIFY(vkCreateDebugReportCallbackEXT( - instance, - &dbgCreateInfo, - NULL, - &msgCallback)); + dbgCreateInfo.flags = flags; + //K3D_VK_VERIFY(vkCreateDebugReportCallbackEXT(m_Instance, &dbgCreateInfo, NULL, &m_DebugMsgCallback)); } -void FreeDebugCallback(VkInstance instance) +void Instance::FreeDebugCallback() { - if (msgCallback != NULL) + if (m_Instance && m_DebugMsgCallback) { - vkDestroyDebugReportCallbackEXT(instance, msgCallback, nullptr); - KLOG(Info, kaleido3d::VulkanRHI, "free debug callback.."); + //vkDestroyDebugReportCallbackEXT(m_Instance, m_DebugMsgCallback, nullptr); + m_DebugMsgCallback = VK_NULL_HANDLE; } } + #ifdef DEBUG_MARKER namespace DebugMarker { diff --git a/Source/RHI/Vulkan/Private/VkDescriptor.cpp b/Source/RHI/Vulkan/Private/VkDescriptor.cpp index eaa2513..15393f0 100755 --- a/Source/RHI/Vulkan/Private/VkDescriptor.cpp +++ b/Source/RHI/Vulkan/Private/VkDescriptor.cpp @@ -21,6 +21,10 @@ VkDescriptorType RHIDataType2VkType(rhi::shc::EBindType const & type) case rhi::shc::EBindType::EBlock: return VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; case rhi::shc::EBindType::ESampler: + return VK_DESCRIPTOR_TYPE_SAMPLER; + case rhi::shc::EBindType::ESampledImage: + return VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE; + case rhi::shc::EBindType::ESamplerImageCombine: return VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; case rhi::shc::EBindType::EStorageImage: return VK_DESCRIPTOR_TYPE_STORAGE_IMAGE; @@ -90,7 +94,7 @@ void DescriptorAllocator::Initialize(uint32 maxSets, BindingArray const& binding void DescriptorAllocator::Destroy() { - if (VK_NULL_HANDLE == m_Pool) + if (VK_NULL_HANDLE == m_Pool || !GetRawDevice() ) return; vkDestroyDescriptorPool(GetRawDevice(), m_Pool, nullptr); m_Pool = VK_NULL_HANDLE; @@ -106,7 +110,7 @@ DescriptorSetLayout::DescriptorSetLayout(Device::Ptr pDevice, BindingArray const DescriptorSetLayout::~DescriptorSetLayout() { - Destroy(); + //Destroy(); } void DescriptorSetLayout::Initialize(BindingArray const & bindings) @@ -114,19 +118,19 @@ void DescriptorSetLayout::Initialize(BindingArray const & bindings) VkDescriptorSetLayoutCreateInfo createInfo = { VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO }; createInfo.bindingCount = bindings.Count(); createInfo.pBindings = bindings.Count()==0 ? nullptr : bindings.Data(); - K3D_VK_VERIFY(vkCmd::CreateDescriptorSetLayout( GetRawDevice(), &createInfo, nullptr, &m_DescriptorSetLayout )); + K3D_VK_VERIFY(vkCreateDescriptorSetLayout( GetRawDevice(), &createInfo, nullptr, &m_DescriptorSetLayout )); } void DescriptorSetLayout::Destroy() { - if( VK_NULL_HANDLE == m_DescriptorSetLayout ) + if( VK_NULL_HANDLE == m_DescriptorSetLayout || !GetRawDevice() ) return; vkDestroyDescriptorSetLayout( GetRawDevice(), m_DescriptorSetLayout, nullptr ); + VKLOG(Info, "DescriptorSetLayout destroying... -- %0x.", m_DescriptorSetLayout); m_DescriptorSetLayout = VK_NULL_HANDLE; - VKLOG(Info, "DescriptorSetLayout-destroying vkDescriptorSetLayout..."); } -DescriptorSet::DescriptorSet( DescriptorAllocator *descriptorAllocator, VkDescriptorSetLayout layout, BindingArray const & bindings, Device::Ptr pDevice ) +DescriptorSet::DescriptorSet( DescriptorAllocRef descriptorAllocator, VkDescriptorSetLayout layout, BindingArray const & bindings, Device::Ptr pDevice ) : DeviceChild( pDevice ) , m_DescriptorAllocator( descriptorAllocator ) , m_Bindings(bindings) @@ -135,7 +139,7 @@ DescriptorSet::DescriptorSet( DescriptorAllocator *descriptorAllocator, VkDescri } -DescriptorSet * DescriptorSet::CreateDescSet(DescriptorAllocator * descriptorPool, VkDescriptorSetLayout layout, BindingArray const & bindings, Device::Ptr pDevice) +DescriptorSet * DescriptorSet::CreateDescSet(DescriptorAllocRef descriptorPool, VkDescriptorSetLayout layout, BindingArray const & bindings, Device::Ptr pDevice) { return new DescriptorSet(descriptorPool, layout, bindings, pDevice); } @@ -145,40 +149,53 @@ DescriptorSet::~DescriptorSet() Destroy(); } +void DescriptorSet::Update(uint32 bindSet, rhi::SamplerRef pRHISampler) +{ + auto pSampler = StaticPointerCast(pRHISampler); + VkDescriptorImageInfo imageInfo = { pSampler->NativeHandle(), VK_NULL_HANDLE, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL }; + m_BoundDescriptorSet[bindSet].pImageInfo = &imageInfo; + vkUpdateDescriptorSets(GetRawDevice(), 1, &m_BoundDescriptorSet[bindSet], 0, NULL); + VKLOG(Info, "%s , Set (0x%0x) updated with sampler(location:0x%x).", __K3D_FUNC__, m_DescriptorSet, pSampler->NativeHandle()); +} + void DescriptorSet::Update(uint32 bindSet, rhi::GpuResourceRef gpuResource) { - auto desc = gpuResource->GetResourceDesc(); + auto desc = gpuResource->GetDesc(); switch(desc.Type) { case rhi::EGT_Buffer: { - VkDescriptorBufferInfo bufferInfo = { (VkBuffer)gpuResource->GetResourceLocation(), 0, gpuResource->GetResourceSize() }; + VkDescriptorBufferInfo bufferInfo = { (VkBuffer)gpuResource->GetLocation(), 0, gpuResource->GetSize() }; m_BoundDescriptorSet[bindSet].pBufferInfo = &bufferInfo; vkUpdateDescriptorSets(GetRawDevice(), 1, &m_BoundDescriptorSet[bindSet], 0, NULL); VKLOG(Info, "%s , Set (0x%0x) updated with buffer(location:0x%x, size:%d).", __K3D_FUNC__, m_DescriptorSet, - gpuResource->GetResourceLocation(), gpuResource->GetResourceSize()); + gpuResource->GetLocation(), gpuResource->GetSize()); break; } case rhi::EGT_Texture1D: case rhi::EGT_Texture2D: case rhi::EGT_Texture3D: - case rhi::EGT_Texture2DArray: + case rhi::EGT_Texture2DArray: // combined/seperated image sampler should be considered { - auto pTex = k3d::DynamicPointerCast(gpuResource); + auto pTex = k3d::StaticPointerCast(gpuResource); auto rSampler = k3d::StaticPointerCast(pTex->GetSampler()); assert(rSampler); auto srv = k3d::StaticPointerCast(pTex->GetResourceView()); - VkDescriptorImageInfo imageInfo = { rSampler->NativePtr(), srv->NativeImageView(), pTex->GetImageLayout() }; //TODO : sampler shouldn't be null - VKLOG(Warn, "pTex->GetSampler return null!"); + VkDescriptorImageInfo imageInfo = { rSampler->NativeHandle(), srv->NativeImageView(), pTex->GetImageLayout() }; //TODO : sampler shouldn't be null m_BoundDescriptorSet[bindSet].pImageInfo = &imageInfo; vkUpdateDescriptorSets(GetRawDevice(), 1, &m_BoundDescriptorSet[bindSet], 0, NULL); VKLOG(Info, "%s , Set (0x%0x) updated with image(location:0x%x, size:%d).", __K3D_FUNC__, m_DescriptorSet, - gpuResource->GetResourceLocation(), gpuResource->GetResourceSize()); + gpuResource->GetLocation(), gpuResource->GetSize()); break; } } } +uint32 DescriptorSet::GetSlotNum() const +{ + return (uint32)m_BoundDescriptorSet.size(); +} + void DescriptorSet::Initialize( VkDescriptorSetLayout layout, BindingArray const & bindings) { std::vector layouts = { layout }; @@ -186,7 +203,7 @@ void DescriptorSet::Initialize( VkDescriptorSetLayout layout, BindingArray const allocInfo.descriptorPool = m_DescriptorAllocator->m_Pool; allocInfo.descriptorSetCount = static_cast( layouts.size() ); allocInfo.pSetLayouts = layouts.empty() ? nullptr : layouts.data(); - K3D_VK_VERIFY( vkAllocateDescriptorSets( GetRawDevice(), &allocInfo, &m_DescriptorSet ) ); + K3D_VK_VERIFY(vkAllocateDescriptorSets( GetRawDevice(), &allocInfo, &m_DescriptorSet ) ); VKLOG(Info, "%s , Set (0x%0x) created.", __K3D_FUNC__, m_DescriptorSet); for (auto& binding : m_Bindings) @@ -203,19 +220,18 @@ void DescriptorSet::Initialize( VkDescriptorSetLayout layout, BindingArray const void DescriptorSet::Destroy() { - if( VK_NULL_HANDLE == m_DescriptorSet ) + if( VK_NULL_HANDLE == m_DescriptorSet || !GetRawDevice() ) return; - if( nullptr != m_DescriptorAllocator ) + if (m_DescriptorAllocator) { //const auto& options = m_DescriptorAllocator->m_Options; //if( options.hasFreeDescriptorSetFlag() ) { VkDescriptorSet descSets[1] = { m_DescriptorSet }; vkFreeDescriptorSets( GetRawDevice(), m_DescriptorAllocator->m_Pool, 1, descSets ); + m_DescriptorSet = VK_NULL_HANDLE; //} } - m_DescriptorSet = VK_NULL_HANDLE; - m_DescriptorAllocator = nullptr; VKRHI_METHOD_TRACE } diff --git a/Source/RHI/Vulkan/Private/VkDevice.cpp b/Source/RHI/Vulkan/Private/VkDevice.cpp index b4e4414..ba7cd79 100755 --- a/Source/RHI/Vulkan/Private/VkDevice.cpp +++ b/Source/RHI/Vulkan/Private/VkDevice.cpp @@ -7,17 +7,42 @@ using namespace rhi; K3D_VK_BEGIN -DeviceRef DeviceAdapter::GetDevice() +::k3d::DynArray Instance::EnumGpus() { - if (!m_pDevice) + DynArray gpus; + DynArray gpuDevices; + uint32_t gpuCount = 0; + K3D_VK_VERIFY(vkEnumeratePhysicalDevices(m_Instance, &gpuCount, nullptr)); + //gpus.Resize(gpuCount); + gpuDevices.Resize(gpuCount); + K3D_VK_VERIFY(vkEnumeratePhysicalDevices(m_Instance, &gpuCount, gpuDevices.Data())); + for (auto gpu : gpuDevices) { - m_pDevice = MakeShared(); + auto gpuRef = GpuRef(new Gpu(gpu, SharedFromThis())); + gpus.Append(gpuRef); } - return m_pDevice; + return gpus; } +//DeviceAdapter::DeviceAdapter(GpuRef const & gpu) +// : m_Gpu(gpu) +//{ +// m_pDevice = MakeShared(); +// m_pDevice->Create(this, gpu->m_Inst->WithValidation()); +// //m_Gpu->m_Inst->AppendLogicalDevice(m_pDevice); +//} +// +//DeviceAdapter::~DeviceAdapter() +//{ +//} +// +//DeviceRef DeviceAdapter::GetDevice() +//{ +// return m_pDevice; +//} + Device::Device() - : m_pGpu(nullptr) + : m_Gpu(nullptr) , m_Device(VK_NULL_HANDLE) { } @@ -31,164 +56,105 @@ void Device::Destroy() { if (VK_NULL_HANDLE == m_Device) return; - for (auto pll : m_CachedPipelineLayout) - { - pll.second->~PipelineLayout(); - } - m_CachedPipelineLayout.clear(); - - for (auto dsl : m_CachedDescriptorSetLayout) - { - dsl.second->~DescriptorSetLayout(); - } - - for (auto alloc : m_CachedDescriptorPool) + vkDeviceWaitIdle(m_Device); + VKLOG(Info, "Device Destroying . -- %0x.", m_Device); + ///*if (!m_CachedDescriptorSetLayout.empty()) + //{ + // m_CachedDescriptorSetLayout.erase(m_CachedDescriptorSetLayout.begin(), + // m_CachedDescriptorSetLayout.end()); + //} + //if (!m_CachedDescriptorPool.empty()) + //{ + // m_CachedDescriptorPool.erase(m_CachedDescriptorPool.begin(), + // m_CachedDescriptorPool.end()); + //} + //if (!m_CachedPipelineLayout.empty()) + //{ + // m_CachedPipelineLayout.erase(m_CachedPipelineLayout.begin(), + // m_CachedPipelineLayout.end()); + //}*/ + //m_PendingPass.~vector(); + //m_ResourceManager->~ResourceManager(); + //m_ContextPool->~CommandContextPool(); + if (m_CmdBufManager) { - alloc.second->~DescriptorAllocator(); + m_CmdBufManager->~CommandBufferManager(); } - - m_CachedDescriptorSetLayout.clear(); - m_PendingPass.~vector(); - m_ResourceManager->~ResourceManager(); - m_ContextPool->~CommandContextPool(); - vkDestroyDevice(m_Device, nullptr); - VKLOG(Info, "Device-Destroyed"); + VKLOG(Info, "Device Destroyed . -- %0x.", m_Device); m_Device = VK_NULL_HANDLE; } IDevice::Result Device::Create(rhi::IDeviceAdapter* pAdapter, bool withDbg) { - m_pGpu = static_cast(pAdapter)->m_pGpu; - VkPhysicalDevice& Gpu = *static_cast(pAdapter)->m_pGpu; - vkGetPhysicalDeviceMemoryProperties(Gpu, &m_MemoryProperties); - VkResult err = CreateDevice(Gpu, withDbg, &m_Device); - if (err) - { - VKLOG(Fatal, "Device-Create: Could not create Vulkan Device : %s.", ErrorString(err).c_str()); - return rhi::IDevice::DeviceNotFound; - } - else + //m_Gpu = static_cast(pAdapter)->m_Gpu; + //m_Device = m_Gpu->CreateLogicDevice(withDbg); + //if(m_Device) + //{ + // //LoadVulkan(m_Gpu->m_Inst->m_Instance, m_Device); + // if (withDbg) + // { + // RHIRoot::SetupDebug(VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT + // | VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT, DebugReportCallback); + // } + // //m_ResourceManager = std::make_unique(SharedFromThis(), 1024, 1024); + // //m_ContextPool = std::make_unique(SharedFromThis()); + // m_DefCmdQueue = InitCmdQueue(VK_QUEUE_GRAPHICS_BIT, m_Gpu->m_GraphicsQueueIndex, 0); + // m_ComputeCmdQueue = InitCmdQueue(VK_QUEUE_COMPUTE_BIT, m_Gpu->m_ComputeQueueIndex, 0); + // return rhi::IDevice::DeviceFound; + //} + return rhi::IDevice::DeviceNotFound; +} + +IDevice::Result +Device::Create(GpuRef const & gpu, bool withDebug) +{ + m_Gpu = gpu; + m_Device = m_Gpu->CreateLogicDevice(withDebug); + if (m_Device) { - LoadVulkan(RHIRoot::GetInstance(), m_Device); -#if K3DPLATFORM_OS_WIN && _DEBUG - if (withDbg) + //LoadVulkan(m_Gpu->m_Inst->m_Instance, m_Device); + if (withDebug) { - SetupDebugging(RHIRoot::GetInstance(), VK_DEBUG_REPORT_ERROR_BIT_EXT | - VK_DEBUG_REPORT_WARNING_BIT_EXT | - VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT, nullptr); + RHIRoot::SetupDebug(VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT + | VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT, DebugReportCallback); } -#endif - m_ResourceManager = std::make_unique(this, 1024, 1024); - m_ContextPool = std::make_unique(this); - m_DefCmdQueue = InitCmdQueue(VK_QUEUE_GRAPHICS_BIT, m_GraphicsQueueIndex, 0); - m_ComputeCmdQueue = InitCmdQueue(VK_QUEUE_COMPUTE_BIT, m_ComputeQueueIndex, 0); + //m_ResourceManager = std::make_unique(SharedFromThis(), 1024, 1024); + //m_ContextPool = std::make_unique(SharedFromThis()); + m_DefCmdQueue = InitCmdQueue(VK_QUEUE_GRAPHICS_BIT, m_Gpu->m_GraphicsQueueIndex, 0); + m_ComputeCmdQueue = InitCmdQueue(VK_QUEUE_COMPUTE_BIT, m_Gpu->m_ComputeQueueIndex, 0); return rhi::IDevice::DeviceFound; } + return rhi::IDevice::DeviceNotFound; } RenderTargetRef Device::NewRenderTarget(rhi::RenderTargetLayout const & layout) { - return RenderTargetRef(new RenderTarget(this, layout)); + return RenderTargetRef(new RenderTarget(SharedFromThis(), layout)); } uint64 Device::GetMaxAllocationCount() { - return m_PhysicalDeviceProperties.limits.maxMemoryAllocationCount; + return m_Gpu->m_Prop.limits.maxMemoryAllocationCount; } SpCmdQueue Device::InitCmdQueue(VkQueueFlags queueTypes, uint32 queueFamilyIndex, uint32 queueIndex) { - return std::make_shared(this, queueTypes, queueFamilyIndex, queueIndex); -} - -VkResult Device::CreateDevice(VkPhysicalDevice gpu, bool withDebug, VkDevice * pDevice) -{ - // get all device queues and find graphics queue - GetDeviceQueueProps(gpu); - - // get device limits - vkGetPhysicalDeviceProperties(gpu, &m_PhysicalDeviceProperties); - - std::array queuePriorities = { 0.0f }; - VkDeviceQueueCreateInfo queueCreateInfo = {}; - queueCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; - queueCreateInfo.queueFamilyIndex = m_GraphicsQueueIndex; - queueCreateInfo.queueCount = 1; - queueCreateInfo.pQueuePriorities = queuePriorities.data(); - - std::vector enabledExtensions = { VK_KHR_SWAPCHAIN_EXTENSION_NAME }; - VkDeviceCreateInfo deviceCreateInfo = {}; - deviceCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO; - deviceCreateInfo.pNext = NULL; - deviceCreateInfo.queueCreateInfoCount = 1; - deviceCreateInfo.pQueueCreateInfos = &queueCreateInfo; - deviceCreateInfo.pEnabledFeatures = NULL; - - if (withDebug) - { - deviceCreateInfo.enabledLayerCount = (uint32)RHIRoot::s_LayerNames.size(); - deviceCreateInfo.ppEnabledLayerNames = RHIRoot::s_LayerNames.data(); - } - - if (enabledExtensions.size() > 0) - { - deviceCreateInfo.enabledExtensionCount = (uint32_t)enabledExtensions.size(); - deviceCreateInfo.ppEnabledExtensionNames = enabledExtensions.data(); - } - return vkCreateDevice(gpu, &deviceCreateInfo, nullptr, pDevice); -} - -bool Device::GetDeviceQueueProps(VkPhysicalDevice gpu) -{ - vkGetPhysicalDeviceQueueFamilyProperties(gpu, &m_QueueCount, NULL); - if(m_QueueCount < 1) - return false; - VKLOG(Info, "Device-PhysicDeviceQueue count = %d.", m_QueueCount); - queueProps.resize(m_QueueCount); - vkGetPhysicalDeviceQueueFamilyProperties(gpu, &m_QueueCount, queueProps.data()); - uint32 qId = 0; - for (qId = 0; qId < m_QueueCount; qId++) - { - if (queueProps[qId].queueFlags & VK_QUEUE_GRAPHICS_BIT) - { - m_GraphicsQueueIndex = qId; - VKLOG(Info, "Device-graphicsQueueIndex(%d) queueFlags(%d).", m_GraphicsQueueIndex, queueProps[qId].queueFlags); - break; - } - } - for (qId = 0; qId < m_QueueCount; qId++) - { - if (queueProps[qId].queueFlags & VK_QUEUE_COMPUTE_BIT) - { - m_ComputeQueueIndex = qId; - VKLOG(Info, "Device::ComputeQueueIndex(%d).", m_ComputeQueueIndex); - break; - } - } - for (qId = 0; qId < m_QueueCount; qId++) - { - if (queueProps[qId].queueFlags & VK_QUEUE_TRANSFER_BIT) - { - m_CopyQueueIndex = qId; - VKLOG(Info, "Device::CopyQueueIndex(%d).", m_CopyQueueIndex); - break; - } - } - return qId < m_QueueCount; + return std::make_shared(m_Device, queueTypes, queueFamilyIndex, queueIndex); } -bool Device::FindMemoryType(uint32_t typeBits, VkFlags requirementsMask, uint32_t *typeIndex) const +bool Device::FindMemoryType(uint32 typeBits, VkFlags requirementsMask, uint32 *typeIndex) const { #ifdef max #undef max *typeIndex = std::numeric_limits::type>::max(); #endif - for (uint32_t i = 0; i < m_MemoryProperties.memoryTypeCount; ++i) { + auto memProp = m_Gpu->m_MemProp; + for (uint32_t i = 0; i < memProp.memoryTypeCount; ++i) { if (typeBits & 0x00000001) { - if (requirementsMask == (m_MemoryProperties.memoryTypes[i].propertyFlags & requirementsMask)) { + if (requirementsMask == (memProp.memoryTypes[i].propertyFlags & requirementsMask)) { *typeIndex = i; return true; } @@ -202,49 +168,58 @@ bool Device::FindMemoryType(uint32_t typeBits, VkFlags requirementsMask, uint32_ CommandContextRef Device::NewCommandContext(rhi::ECommandType Type) { - return CommandContextRef(m_ContextPool->RequestContext(Type)); + if (!m_CmdBufManager) + { + m_CmdBufManager = CmdBufManagerRef(new CommandBufferManager(m_Device, VK_COMMAND_BUFFER_LEVEL_PRIMARY, m_Gpu->m_GraphicsQueueIndex)); + } + return rhi::CommandContextRef(new CommandContext(SharedFromThis(), m_CmdBufManager->RequestCommandBuffer(), VK_NULL_HANDLE, Type)); + //return m_ContextPool->RequestContext(Type); } SamplerRef Device::NewSampler(const rhi::SamplerState& samplerDesc) { - return MakeShared(this, samplerDesc); + return MakeShared(SharedFromThis(), samplerDesc); } -PipelineLayoutRef +rhi::PipelineLayoutRef Device::NewPipelineLayout(rhi::PipelineLayoutDesc const & table) { // Hash the table parameter here, // Lookup the layout by hash code - rhi::PipelineLayoutKey key = HashPipelineLayoutDesc(table); + /*rhi::PipelineLayoutKey key = HashPipelineLayoutDesc(table); if (m_CachedPipelineLayout.find(key) == m_CachedPipelineLayout.end()) { - m_CachedPipelineLayout[key] = new PipelineLayout(this, table);; - } - return PipelineLayoutRef(m_CachedPipelineLayout[key]); + auto plRef = rhi::PipelineLayoutRef(new PipelineLayout(this, table)); + m_CachedPipelineLayout.insert({ key, plRef }); + }*/ + return rhi::PipelineLayoutRef(new PipelineLayout(SharedFromThis(), table)); } -DescriptorAllocator * +DescriptorAllocRef Device::NewDescriptorAllocator(uint32 maxSets, BindingArray const & bindings) { uint32 key = util::Hash32((const char*)bindings.Data(), bindings.Count() * sizeof(VkDescriptorSetLayoutBinding)); - if (m_CachedDescriptorPool.find(key) == m_CachedDescriptorPool.end()) + /*if (m_CachedDescriptorPool.find(key) == m_CachedDescriptorPool.end()) { - DescriptorAllocator::Options options = {}; - m_CachedDescriptorPool[key] = new DescriptorAllocator(this, options, maxSets, bindings); - } - return m_CachedDescriptorPool[key]; + DescriptorAllocator::Options options = {}; + auto descAllocRef = DescriptorAllocRef(new DescriptorAllocator(this, options, maxSets, bindings)); + m_CachedDescriptorPool.insert({ key, descAllocRef }); + }*/ + DescriptorAllocator::Options options = {}; + return DescriptorAllocRef(new DescriptorAllocator(SharedFromThis(), options, maxSets, bindings)); } -DescriptorSetLayout * +DescriptorSetLayoutRef Device::NewDescriptorSetLayout(BindingArray const & bindings) { uint32 key = util::Hash32((const char*)bindings.Data(), bindings.Count() * sizeof(VkDescriptorSetLayoutBinding)); - if (m_CachedDescriptorSetLayout.find(key) == m_CachedDescriptorSetLayout.end()) + /*if (m_CachedDescriptorSetLayout.find(key) == m_CachedDescriptorSetLayout.end()) { - m_CachedDescriptorSetLayout[key] = new DescriptorSetLayout(this, bindings); - } - return m_CachedDescriptorSetLayout[key]; + auto descSetLayoutRef = DescriptorSetLayoutRef(new DescriptorSetLayout(this, bindings)); + m_CachedDescriptorSetLayout.insert({ key, descSetLayoutRef }); + }*/ + return DescriptorSetLayoutRef(new DescriptorSetLayout(SharedFromThis(), bindings)); } PipelineStateObjectRef @@ -256,13 +231,13 @@ Device::NewPipelineState(rhi::PipelineDesc const & desc, rhi::PipelineLayoutRef PipelineStateObjectRef Device::CreatePipelineStateObject(rhi::PipelineDesc const & desc, rhi::PipelineLayoutRef ppl) { - return MakeShared(this, desc, static_cast(ppl.Get())); + return MakeShared(SharedFromThis(), desc, static_cast(ppl.Get())); } SyncFenceRef Device::NewFence() { - return MakeShared(this); + return MakeShared(SharedFromThis()); } GpuResourceRef @@ -272,12 +247,12 @@ Device::NewGpuResource(rhi::ResourceDesc const& Desc) switch (Desc.Type) { case rhi::EGT_Buffer: - resource = new Buffer(this, Desc); + resource = new Buffer(SharedFromThis(), Desc); break; case rhi::EGT_Texture1D: break; case rhi::EGT_Texture2D: - resource = new Texture(this, Desc); + resource = new Texture(SharedFromThis(), Desc); break; default: break; @@ -288,7 +263,7 @@ Device::NewGpuResource(rhi::ResourceDesc const& Desc) ShaderResourceViewRef Device::NewShaderResourceView(rhi::GpuResourceRef pRes, rhi::ResourceViewDesc const & desc) { - return MakeShared(desc, pRes.Get()); + return MakeShared(SharedFromThis(), desc, pRes); } rhi::IDescriptorPool * @@ -300,29 +275,32 @@ Device::NewDescriptorPool() RenderViewportRef Device::NewRenderViewport(void * winHandle, rhi::GfxSetting& setting) { - return MakeShared(this, winHandle, setting); + auto pViewport = MakeShared(SharedFromThis(), winHandle, setting); + RHIRoot::AddViewport(pViewport); + return pViewport; } PtrCmdAlloc Device::NewCommandAllocator(bool transient) { - return CommandAllocator::CreateAllocator(m_GraphicsQueueIndex, false, this); + return CommandAllocator::CreateAllocator(m_Gpu->m_GraphicsQueueIndex, transient, SharedFromThis()); } PtrSemaphore Device::NewSemaphore() { - return std::make_shared(this); + return std::make_shared(SharedFromThis()); } -void Device::QueryTextureSubResourceLayout(rhi::GpuResourceRef resource, rhi::TextureResourceSpec const & spec, rhi::SubResourceLayout * layout) +void Device::QueryTextureSubResourceLayout(rhi::TextureRef resource, rhi::TextureResourceSpec const & spec, rhi::SubResourceLayout * layout) { - K3D_ASSERT(resource && resource->GetResourceType() != rhi::EGT_Buffer); - vkGetImageSubresourceLayout(m_Device, (VkImage)resource->GetResourceLocation(), (const VkImageSubresource*)&spec, (VkSubresourceLayout*)layout); + K3D_ASSERT(resource); + auto texture = StaticPointerCast(resource); + vkGetImageSubresourceLayout(m_Device, (VkImage)resource->GetLocation(), (const VkImageSubresource*)&spec, (VkSubresourceLayout*)layout); } SwapChainRef Device::NewSwapChain(rhi::GfxSetting const & setting) { - return k3d::MakeShared(this); + return k3d::MakeShared(SharedFromThis()); } K3D_VK_END \ No newline at end of file diff --git a/Source/RHI/Vulkan/Private/VkEnums.h b/Source/RHI/Vulkan/Private/VkEnums.h index 60acef1..cfd7af9 100755 --- a/Source/RHI/Vulkan/Private/VkEnums.h +++ b/Source/RHI/Vulkan/Private/VkEnums.h @@ -24,6 +24,11 @@ namespace VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, }; + VkVertexInputRate g_InputRates[] = { + VK_VERTEX_INPUT_RATE_VERTEX, + VK_VERTEX_INPUT_RATE_INSTANCE, + }; + VkCullModeFlagBits g_CullMode[rhi::RasterizerState::CullModeNum] = { VK_CULL_MODE_NONE, VK_CULL_MODE_FRONT_BIT, diff --git a/Source/RHI/Vulkan/Private/VkFrameBuffer.cpp b/Source/RHI/Vulkan/Private/VkFrameBuffer.cpp deleted file mode 100755 index 9a216d7..0000000 --- a/Source/RHI/Vulkan/Private/VkFrameBuffer.cpp +++ /dev/null @@ -1,69 +0,0 @@ -#include "VkCommon.h" -#include "VkRHI.h" -#include "VkUtils.h" - -K3D_VK_BEGIN - -FrameBuffer::FrameBuffer(Device::Ptr pDevice, VkRenderPass renderPass, FrameBuffer::Option const& op) - : DeviceChild(pDevice) - , m_RenderPass(renderPass) - , m_Width(op.Width) - , m_Height(op.Height) -{ - VKRHI_METHOD_TRACE - for (auto& elem : op.Attachments) - { - if (elem.ImageAttachment) - { - continue; - } - } - - std::vector attachments; - for (const auto& elem : op.Attachments) { - attachments.push_back(elem.ImageAttachment); - } - - VkFramebufferCreateInfo createInfo = {}; - createInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO; - createInfo.pNext = nullptr; - createInfo.renderPass = m_RenderPass; - createInfo.attachmentCount = static_cast(op.Attachments.size()); - createInfo.pAttachments = attachments.data(); - createInfo.width = m_Width; - createInfo.height = m_Height; - createInfo.layers = 1; - createInfo.flags = 0; - K3D_VK_VERIFY(vkCreateFramebuffer(GetRawDevice(), &createInfo, nullptr, &m_FrameBuffer)); -} - -FrameBuffer::FrameBuffer(Device::Ptr pDevice, RenderPass * renderPass, RenderTargetLayout const &) - : DeviceChild(pDevice) -{ -} - -FrameBuffer::~FrameBuffer() -{ - if (VK_NULL_HANDLE == m_FrameBuffer) - { - return; - } - vkDestroyFramebuffer(GetRawDevice(), m_FrameBuffer, nullptr); - m_FrameBuffer = VK_NULL_HANDLE; - VKRHI_METHOD_TRACE -} - -FrameBuffer::Attachment::Attachment(VkFormat format, VkSampleCountFlagBits samples) -{ - VkImageAspectFlags aspectMask = DetermineAspectMask(Format); - if (VK_IMAGE_ASPECT_COLOR_BIT == aspectMask) - { - FormatFeatures = VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT; - } - else - { - FormatFeatures = VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT; - } -} - -K3D_VK_END \ No newline at end of file diff --git a/Source/RHI/Vulkan/Private/VkImpl.cpp b/Source/RHI/Vulkan/Private/VkImpl.cpp index da664c3..4d499ec 100755 --- a/Source/RHI/Vulkan/Private/VkImpl.cpp +++ b/Source/RHI/Vulkan/Private/VkImpl.cpp @@ -31,7 +31,7 @@ void VkLog(k3d::ELogLevel const& Lv, const char * tag, const char * fmt, ...) vsprintf(logContent, fmt, va); va_end(va); - k3d::ILogModule* logModule = (k3d::ILogModule*)k3d::GlobalModuleManager.FindModule("KawaLog"); + auto logModule = k3d::StaticPointerCast(k3d::GlobalModuleManager.FindModule("KawaLog")); if (logModule) { k3d::ILogger* logger = logModule->GetLogger(k3d::ELoggerType::EWebsocket); diff --git a/Source/RHI/Vulkan/Private/VkObjects.cpp b/Source/RHI/Vulkan/Private/VkObjects.cpp index 89244b3..b10087c 100755 --- a/Source/RHI/Vulkan/Private/VkObjects.cpp +++ b/Source/RHI/Vulkan/Private/VkObjects.cpp @@ -1,6 +1,8 @@ #include "VkCommon.h" #include "VkObjects.h" #include "VkEnums.h" +#include "VkConfig.h" +#include K3D_VK_BEGIN @@ -207,6 +209,22 @@ std::pair ImageViewInfo::CreateColorImageVie return std::make_pair(std::move(imageView), std::move(info)); } +std::pair ImageViewInfo::CreateColorImageView(GpuRef device, VkFormat colorFmt, VkImage colorImage, VkImageAspectFlags aspectMask) +{ + VkImageView imageView = VK_NULL_HANDLE; + VkImageViewCreateInfo info = CreateColorImageInfo(colorFmt, colorImage); + K3D_ASSERT(0 != info.subresourceRange.aspectMask); + if (VK_IMAGE_ASPECT_COLOR_BIT == info.subresourceRange.aspectMask) + { + info.components.r = VK_COMPONENT_SWIZZLE_R; + info.components.g = VK_COMPONENT_SWIZZLE_G; + info.components.b = VK_COMPONENT_SWIZZLE_B; + info.components.a = VK_COMPONENT_SWIZZLE_A; + } + K3D_VK_VERIFY(vkCreateImageView(device->m_LogicalDevice, &info, nullptr, &imageView)); + return std::make_pair(std::move(imageView), std::move(info)); +} + std::pair ImageViewInfo::CreateDepthStencilImageView(VkDevice device, VkFormat colorFmt, VkImage colorImage, VkImageAspectFlags aspectMask) { VkImageView imageView = VK_NULL_HANDLE; @@ -230,4 +248,613 @@ ImageViewInfo ImageViewInfo::From(ImageInfo const & info, VkImage image) return imageViewInfo; } -K3D_VK_END +void * VkObjectAllocator::Allocation(void * pUserData, size_t size, size_t alignment, VkSystemAllocationScope allocationScope) +{ + return static_cast(pUserData)->Allocation(size, alignment, allocationScope); +} + +void * VkObjectAllocator::Reallocation(void * pUserData, void * pOriginal, size_t size, size_t alignment, VkSystemAllocationScope allocationScope) +{ + return static_cast(pUserData)->Reallocation(pOriginal, size, alignment, allocationScope); +} + +void VkObjectAllocator::Free(void * pUserData, void * pMemory) +{ + return static_cast(pUserData)->Free(pMemory); +} + +void * VkObjectAllocator::Allocation(size_t size, size_t alignment, VkSystemAllocationScope allocationScope) +{ + return __k3d_malloc__(size); +} + +void * VkObjectAllocator::Reallocation(void * pOriginal, size_t size, size_t alignment, VkSystemAllocationScope allocationScope) +{ + return __k3d_malloc__(size); +} + +void VkObjectAllocator::Free(void * pMemory) +{ + __k3d_free__(pMemory, 0); +} + + +CommandBufferManager::CommandBufferManager(VkDevice gpu, VkCommandBufferLevel bufferLevel, + unsigned graphicsQueueIndex) + : m_Device(gpu) + , m_CommandBufferLevel(bufferLevel) + , m_Count(0) +{ + // RESET_COMMAND_BUFFER_BIT allows command buffers to be reset individually. + VkCommandPoolCreateInfo info = { VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO }; + info.queueFamilyIndex = graphicsQueueIndex; + info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT; + K3D_VK_VERIFY(vkCreateCommandPool(m_Device, &info, nullptr, &m_Pool)); +} + +CommandBufferManager::~CommandBufferManager() +{ + Destroy(); +} + +void CommandBufferManager::Destroy() +{ + if (!m_Pool) + return; + vkDeviceWaitIdle(m_Device); + VKLOG(Info, "CommandBufferManager destroy. -- 0x%0x.", m_Pool); + vkFreeCommandBuffers(m_Device, m_Pool, m_Buffers.size(), m_Buffers.data()); + vkDestroyCommandPool(m_Device, m_Pool, nullptr); + m_Pool = VK_NULL_HANDLE; +} + +void CommandBufferManager::BeginFrame() +{ + m_Count = 0; +} + +VkCommandBuffer CommandBufferManager::RequestCommandBuffer() +{ + // Either we recycle a previously allocated command buffer, or create a new one. + VkCommandBuffer ret = VK_NULL_HANDLE; + if (m_Count < m_Buffers.size()) + { + ret = m_Buffers[m_Count++]; + K3D_VK_VERIFY(vkResetCommandBuffer(ret, VK_COMMAND_BUFFER_RESET_RELEASE_RESOURCES_BIT)); + } + else + { + VkCommandBufferAllocateInfo info = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO }; + info.commandPool = m_Pool; + info.level = m_CommandBufferLevel; + info.commandBufferCount = 1; + K3D_VK_VERIFY(vkAllocateCommandBuffers(m_Device, &info, &ret)); + m_Buffers.push_back(ret); + + m_Count++; + } + + return ret; +} + +Gpu::Gpu(VkPhysicalDevice const& gpu, InstanceRef const& pInst) + : m_Inst(pInst) + , m_LogicalDevice(VK_NULL_HANDLE) + , m_PhysicalGpu(gpu) +{ + vkGetPhysicalDeviceProperties(m_PhysicalGpu, &m_Prop); + vkGetPhysicalDeviceMemoryProperties(m_PhysicalGpu, &m_MemProp); + VKLOG(Info, "Gpu: %s", m_Prop.deviceName); + QuerySupportQueues(); +} + +void Gpu::QuerySupportQueues() +{ + uint32 queueCount = 0; + vkGetPhysicalDeviceQueueFamilyProperties(m_PhysicalGpu, &queueCount, NULL); + if (queueCount < 1) + return; + m_QueueProps.Resize(queueCount); + vkGetPhysicalDeviceQueueFamilyProperties(m_PhysicalGpu, &queueCount, m_QueueProps.Data()); + uint32 qId = 0; + for (qId = 0; qId < queueCount; qId++) + { + if (m_QueueProps[qId].queueFlags & VK_QUEUE_GRAPHICS_BIT) + { + m_GraphicsQueueIndex = qId; + VKLOG(Info, "Device::graphicsQueueIndex(%d) queueFlags(%d).", m_GraphicsQueueIndex, m_QueueProps[qId].queueFlags); + break; + } + } + for (qId = 0; qId < queueCount; qId++) + { + if (m_QueueProps[qId].queueFlags & VK_QUEUE_COMPUTE_BIT) + { + m_ComputeQueueIndex = qId; + VKLOG(Info, "Device::ComputeQueueIndex(%d).", m_ComputeQueueIndex); + break; + } + } + for (qId = 0; qId < queueCount; qId++) + { + if (m_QueueProps[qId].queueFlags & VK_QUEUE_TRANSFER_BIT) + { + m_CopyQueueIndex = qId; + VKLOG(Info, "Device::CopyQueueIndex(%d).", m_CopyQueueIndex); + break; + } + } +} + +#define __VK_GET_DEVICE_PROC__(name, getDeviceProc, device) \ +if(!vk##name) \ +{\ +vk##name = (PFN_vk##name)getDeviceProc(device, "vk" K3D_STRINGIFY(name)); \ +if (!vk##name) \ +{\ +VKLOG(Fatal, "LoadDeviceProcs::" K3D_STRINGIFY(name) " not exist!" );\ +exit(-1);\ +}\ +} + +void Gpu::LoadDeviceProcs() +{ +#ifdef VK_NO_PROTOTYPES + if (!fpDestroyDevice) + { + fpDestroyDevice = (PFN_vkDestroyDevice)m_Inst->fpGetDeviceProcAddr(m_LogicalDevice, "vkDestroyDevice"); + } + if (!fpFreeCommandBuffers) + { + fpFreeCommandBuffers = (PFN_vkFreeCommandBuffers)m_Inst->fpGetDeviceProcAddr(m_LogicalDevice, "vkFreeCommandBuffers"); + } + if (!fpCreateCommandPool) + { + fpCreateCommandPool = (PFN_vkCreateCommandPool)m_Inst->fpGetDeviceProcAddr(m_LogicalDevice, "vkCreateCommandPool"); + } + if (!fpAllocateCommandBuffers) + { + fpAllocateCommandBuffers = (PFN_vkAllocateCommandBuffers)m_Inst->fpGetDeviceProcAddr(m_LogicalDevice, "vkAllocateCommandBuffers"); + } + __VK_GET_DEVICE_PROC__(DestroyDevice, m_Inst->fpGetDeviceProcAddr, m_LogicalDevice); + __VK_GET_DEVICE_PROC__(GetDeviceQueue, m_Inst->fpGetDeviceProcAddr, m_LogicalDevice); + __VK_GET_DEVICE_PROC__(QueueSubmit, m_Inst->fpGetDeviceProcAddr, m_LogicalDevice); + __VK_GET_DEVICE_PROC__(QueueWaitIdle, m_Inst->fpGetDeviceProcAddr, m_LogicalDevice); + __VK_GET_DEVICE_PROC__(QueuePresentKHR, m_Inst->fpGetDeviceProcAddr, m_LogicalDevice); + __VK_GET_DEVICE_PROC__(DeviceWaitIdle, m_Inst->fpGetDeviceProcAddr, m_LogicalDevice); + __VK_GET_DEVICE_PROC__(AllocateMemory, m_Inst->fpGetDeviceProcAddr, m_LogicalDevice); + __VK_GET_DEVICE_PROC__(FreeMemory, m_Inst->fpGetDeviceProcAddr, m_LogicalDevice); + __VK_GET_DEVICE_PROC__(MapMemory, m_Inst->fpGetDeviceProcAddr, m_LogicalDevice); + __VK_GET_DEVICE_PROC__(UnmapMemory, m_Inst->fpGetDeviceProcAddr, m_LogicalDevice); + __VK_GET_DEVICE_PROC__(FlushMappedMemoryRanges, m_Inst->fpGetDeviceProcAddr, m_LogicalDevice); + __VK_GET_DEVICE_PROC__(InvalidateMappedMemoryRanges, m_Inst->fpGetDeviceProcAddr, m_LogicalDevice); + __VK_GET_DEVICE_PROC__(GetDeviceMemoryCommitment, m_Inst->fpGetDeviceProcAddr, m_LogicalDevice); + __VK_GET_DEVICE_PROC__(BindBufferMemory, m_Inst->fpGetDeviceProcAddr, m_LogicalDevice); + __VK_GET_DEVICE_PROC__(BindImageMemory, m_Inst->fpGetDeviceProcAddr, m_LogicalDevice); + __VK_GET_DEVICE_PROC__(GetBufferMemoryRequirements, m_Inst->fpGetDeviceProcAddr, m_LogicalDevice); + __VK_GET_DEVICE_PROC__(GetImageMemoryRequirements, m_Inst->fpGetDeviceProcAddr, m_LogicalDevice); + __VK_GET_DEVICE_PROC__(GetImageSparseMemoryRequirements, m_Inst->fpGetDeviceProcAddr, m_LogicalDevice); + __VK_GET_DEVICE_PROC__(QueueBindSparse, m_Inst->fpGetDeviceProcAddr, m_LogicalDevice); + __VK_GET_DEVICE_PROC__(CreateFence, m_Inst->fpGetDeviceProcAddr, m_LogicalDevice); + __VK_GET_DEVICE_PROC__(DestroyFence, m_Inst->fpGetDeviceProcAddr, m_LogicalDevice); + __VK_GET_DEVICE_PROC__(ResetFences, m_Inst->fpGetDeviceProcAddr, m_LogicalDevice); + __VK_GET_DEVICE_PROC__(GetFenceStatus, m_Inst->fpGetDeviceProcAddr, m_LogicalDevice); + __VK_GET_DEVICE_PROC__(WaitForFences, m_Inst->fpGetDeviceProcAddr, m_LogicalDevice); + __VK_GET_DEVICE_PROC__(CreateSemaphore, m_Inst->fpGetDeviceProcAddr, m_LogicalDevice); + __VK_GET_DEVICE_PROC__(DestroySemaphore, m_Inst->fpGetDeviceProcAddr, m_LogicalDevice); + __VK_GET_DEVICE_PROC__(CreateEvent, m_Inst->fpGetDeviceProcAddr, m_LogicalDevice); + __VK_GET_DEVICE_PROC__(DestroyEvent, m_Inst->fpGetDeviceProcAddr, m_LogicalDevice); + __VK_GET_DEVICE_PROC__(GetEventStatus, m_Inst->fpGetDeviceProcAddr, m_LogicalDevice); + __VK_GET_DEVICE_PROC__(SetEvent, m_Inst->fpGetDeviceProcAddr, m_LogicalDevice); + __VK_GET_DEVICE_PROC__(ResetEvent, m_Inst->fpGetDeviceProcAddr, m_LogicalDevice); + __VK_GET_DEVICE_PROC__(CreateQueryPool, m_Inst->fpGetDeviceProcAddr, m_LogicalDevice); + __VK_GET_DEVICE_PROC__(DestroyQueryPool, m_Inst->fpGetDeviceProcAddr, m_LogicalDevice); + __VK_GET_DEVICE_PROC__(GetQueryPoolResults, m_Inst->fpGetDeviceProcAddr, m_LogicalDevice); + __VK_GET_DEVICE_PROC__(CreateBuffer, m_Inst->fpGetDeviceProcAddr, m_LogicalDevice); + __VK_GET_DEVICE_PROC__(DestroyBuffer, m_Inst->fpGetDeviceProcAddr, m_LogicalDevice); + __VK_GET_DEVICE_PROC__(CreateBufferView, m_Inst->fpGetDeviceProcAddr, m_LogicalDevice); + __VK_GET_DEVICE_PROC__(DestroyBufferView, m_Inst->fpGetDeviceProcAddr, m_LogicalDevice); + __VK_GET_DEVICE_PROC__(CreateImage, m_Inst->fpGetDeviceProcAddr, m_LogicalDevice); + __VK_GET_DEVICE_PROC__(DestroyImage, m_Inst->fpGetDeviceProcAddr, m_LogicalDevice); + __VK_GET_DEVICE_PROC__(GetImageSubresourceLayout, m_Inst->fpGetDeviceProcAddr, m_LogicalDevice); + __VK_GET_DEVICE_PROC__(CreateImageView, m_Inst->fpGetDeviceProcAddr, m_LogicalDevice); + __VK_GET_DEVICE_PROC__(DestroyImageView, m_Inst->fpGetDeviceProcAddr, m_LogicalDevice); + __VK_GET_DEVICE_PROC__(CreateShaderModule, m_Inst->fpGetDeviceProcAddr, m_LogicalDevice); + __VK_GET_DEVICE_PROC__(DestroyShaderModule, m_Inst->fpGetDeviceProcAddr, m_LogicalDevice); + __VK_GET_DEVICE_PROC__(CreatePipelineCache, m_Inst->fpGetDeviceProcAddr, m_LogicalDevice); + __VK_GET_DEVICE_PROC__(DestroyPipelineCache, m_Inst->fpGetDeviceProcAddr, m_LogicalDevice); + __VK_GET_DEVICE_PROC__(GetPipelineCacheData, m_Inst->fpGetDeviceProcAddr, m_LogicalDevice); + __VK_GET_DEVICE_PROC__(MergePipelineCaches, m_Inst->fpGetDeviceProcAddr, m_LogicalDevice); + __VK_GET_DEVICE_PROC__(CreateGraphicsPipelines, m_Inst->fpGetDeviceProcAddr, m_LogicalDevice); + __VK_GET_DEVICE_PROC__(CreateComputePipelines, m_Inst->fpGetDeviceProcAddr, m_LogicalDevice); + __VK_GET_DEVICE_PROC__(DestroyPipeline, m_Inst->fpGetDeviceProcAddr, m_LogicalDevice); + __VK_GET_DEVICE_PROC__(CreatePipelineLayout, m_Inst->fpGetDeviceProcAddr, m_LogicalDevice); + __VK_GET_DEVICE_PROC__(DestroyPipelineLayout, m_Inst->fpGetDeviceProcAddr, m_LogicalDevice); + __VK_GET_DEVICE_PROC__(CreateSampler, m_Inst->fpGetDeviceProcAddr, m_LogicalDevice); + __VK_GET_DEVICE_PROC__(DestroySampler, m_Inst->fpGetDeviceProcAddr, m_LogicalDevice); + __VK_GET_DEVICE_PROC__(CreateDescriptorSetLayout, m_Inst->fpGetDeviceProcAddr, m_LogicalDevice); + __VK_GET_DEVICE_PROC__(DestroyDescriptorSetLayout, m_Inst->fpGetDeviceProcAddr, m_LogicalDevice); + __VK_GET_DEVICE_PROC__(CreateDescriptorPool, m_Inst->fpGetDeviceProcAddr, m_LogicalDevice); + __VK_GET_DEVICE_PROC__(DestroyDescriptorPool, m_Inst->fpGetDeviceProcAddr, m_LogicalDevice); + __VK_GET_DEVICE_PROC__(ResetDescriptorPool, m_Inst->fpGetDeviceProcAddr, m_LogicalDevice); + __VK_GET_DEVICE_PROC__(AllocateDescriptorSets, m_Inst->fpGetDeviceProcAddr, m_LogicalDevice); + __VK_GET_DEVICE_PROC__(FreeDescriptorSets, m_Inst->fpGetDeviceProcAddr, m_LogicalDevice); + __VK_GET_DEVICE_PROC__(UpdateDescriptorSets, m_Inst->fpGetDeviceProcAddr, m_LogicalDevice); + __VK_GET_DEVICE_PROC__(CreateFramebuffer, m_Inst->fpGetDeviceProcAddr, m_LogicalDevice); + __VK_GET_DEVICE_PROC__(DestroyFramebuffer, m_Inst->fpGetDeviceProcAddr, m_LogicalDevice); + __VK_GET_DEVICE_PROC__(CreateRenderPass, m_Inst->fpGetDeviceProcAddr, m_LogicalDevice); + __VK_GET_DEVICE_PROC__(DestroyRenderPass, m_Inst->fpGetDeviceProcAddr, m_LogicalDevice); + __VK_GET_DEVICE_PROC__(GetRenderAreaGranularity, m_Inst->fpGetDeviceProcAddr, m_LogicalDevice); + __VK_GET_DEVICE_PROC__(CreateCommandPool, m_Inst->fpGetDeviceProcAddr, m_LogicalDevice); + __VK_GET_DEVICE_PROC__(DestroyCommandPool, m_Inst->fpGetDeviceProcAddr, m_LogicalDevice); + __VK_GET_DEVICE_PROC__(ResetCommandPool, m_Inst->fpGetDeviceProcAddr, m_LogicalDevice); + __VK_GET_DEVICE_PROC__(AllocateCommandBuffers, m_Inst->fpGetDeviceProcAddr, m_LogicalDevice); + __VK_GET_DEVICE_PROC__(FreeCommandBuffers, m_Inst->fpGetDeviceProcAddr, m_LogicalDevice); + __VK_GET_DEVICE_PROC__(BeginCommandBuffer, m_Inst->fpGetDeviceProcAddr, m_LogicalDevice); + __VK_GET_DEVICE_PROC__(EndCommandBuffer, m_Inst->fpGetDeviceProcAddr, m_LogicalDevice); + __VK_GET_DEVICE_PROC__(ResetCommandBuffer, m_Inst->fpGetDeviceProcAddr, m_LogicalDevice); + __VK_GET_DEVICE_PROC__(CmdBindPipeline, m_Inst->fpGetDeviceProcAddr, m_LogicalDevice); + __VK_GET_DEVICE_PROC__(CmdSetViewport, m_Inst->fpGetDeviceProcAddr, m_LogicalDevice); + __VK_GET_DEVICE_PROC__(CmdSetScissor, m_Inst->fpGetDeviceProcAddr, m_LogicalDevice); + __VK_GET_DEVICE_PROC__(CmdSetLineWidth, m_Inst->fpGetDeviceProcAddr, m_LogicalDevice); + __VK_GET_DEVICE_PROC__(CmdSetDepthBias, m_Inst->fpGetDeviceProcAddr, m_LogicalDevice); + __VK_GET_DEVICE_PROC__(CmdSetBlendConstants, m_Inst->fpGetDeviceProcAddr, m_LogicalDevice); + __VK_GET_DEVICE_PROC__(CmdSetDepthBounds, m_Inst->fpGetDeviceProcAddr, m_LogicalDevice); + __VK_GET_DEVICE_PROC__(CmdSetStencilCompareMask, m_Inst->fpGetDeviceProcAddr, m_LogicalDevice); + __VK_GET_DEVICE_PROC__(CmdSetStencilWriteMask, m_Inst->fpGetDeviceProcAddr, m_LogicalDevice); + __VK_GET_DEVICE_PROC__(CmdSetStencilReference, m_Inst->fpGetDeviceProcAddr, m_LogicalDevice); + __VK_GET_DEVICE_PROC__(CmdBindDescriptorSets, m_Inst->fpGetDeviceProcAddr, m_LogicalDevice); + __VK_GET_DEVICE_PROC__(CmdBindIndexBuffer, m_Inst->fpGetDeviceProcAddr, m_LogicalDevice); + __VK_GET_DEVICE_PROC__(CmdBindVertexBuffers, m_Inst->fpGetDeviceProcAddr, m_LogicalDevice); + __VK_GET_DEVICE_PROC__(CmdDraw, m_Inst->fpGetDeviceProcAddr, m_LogicalDevice); + __VK_GET_DEVICE_PROC__(CmdDrawIndexed, m_Inst->fpGetDeviceProcAddr, m_LogicalDevice); + __VK_GET_DEVICE_PROC__(CmdDrawIndirect, m_Inst->fpGetDeviceProcAddr, m_LogicalDevice); + __VK_GET_DEVICE_PROC__(CmdDrawIndexedIndirect, m_Inst->fpGetDeviceProcAddr, m_LogicalDevice); + __VK_GET_DEVICE_PROC__(CmdDispatch, m_Inst->fpGetDeviceProcAddr, m_LogicalDevice); + __VK_GET_DEVICE_PROC__(CmdDispatchIndirect, m_Inst->fpGetDeviceProcAddr, m_LogicalDevice); + __VK_GET_DEVICE_PROC__(CmdCopyBuffer, m_Inst->fpGetDeviceProcAddr, m_LogicalDevice); + __VK_GET_DEVICE_PROC__(CmdCopyImage, m_Inst->fpGetDeviceProcAddr, m_LogicalDevice); + __VK_GET_DEVICE_PROC__(CmdBlitImage, m_Inst->fpGetDeviceProcAddr, m_LogicalDevice); + __VK_GET_DEVICE_PROC__(CmdCopyBufferToImage, m_Inst->fpGetDeviceProcAddr, m_LogicalDevice); + __VK_GET_DEVICE_PROC__(CmdCopyImageToBuffer, m_Inst->fpGetDeviceProcAddr, m_LogicalDevice); + __VK_GET_DEVICE_PROC__(CmdUpdateBuffer, m_Inst->fpGetDeviceProcAddr, m_LogicalDevice); + __VK_GET_DEVICE_PROC__(CmdFillBuffer, m_Inst->fpGetDeviceProcAddr, m_LogicalDevice); + __VK_GET_DEVICE_PROC__(CmdClearColorImage, m_Inst->fpGetDeviceProcAddr, m_LogicalDevice); + __VK_GET_DEVICE_PROC__(CmdClearDepthStencilImage, m_Inst->fpGetDeviceProcAddr, m_LogicalDevice); + __VK_GET_DEVICE_PROC__(CmdClearAttachments, m_Inst->fpGetDeviceProcAddr, m_LogicalDevice); + __VK_GET_DEVICE_PROC__(CmdResolveImage, m_Inst->fpGetDeviceProcAddr, m_LogicalDevice); + __VK_GET_DEVICE_PROC__(CmdSetEvent, m_Inst->fpGetDeviceProcAddr, m_LogicalDevice); + __VK_GET_DEVICE_PROC__(CmdResetEvent, m_Inst->fpGetDeviceProcAddr, m_LogicalDevice); + __VK_GET_DEVICE_PROC__(CmdWaitEvents, m_Inst->fpGetDeviceProcAddr, m_LogicalDevice); + __VK_GET_DEVICE_PROC__(CmdPipelineBarrier, m_Inst->fpGetDeviceProcAddr, m_LogicalDevice); + __VK_GET_DEVICE_PROC__(CmdBeginQuery, m_Inst->fpGetDeviceProcAddr, m_LogicalDevice); + __VK_GET_DEVICE_PROC__(CmdEndQuery, m_Inst->fpGetDeviceProcAddr, m_LogicalDevice); + __VK_GET_DEVICE_PROC__(CmdResetQueryPool, m_Inst->fpGetDeviceProcAddr, m_LogicalDevice); + __VK_GET_DEVICE_PROC__(CmdWriteTimestamp, m_Inst->fpGetDeviceProcAddr, m_LogicalDevice); + __VK_GET_DEVICE_PROC__(CmdCopyQueryPoolResults, m_Inst->fpGetDeviceProcAddr, m_LogicalDevice); + __VK_GET_DEVICE_PROC__(CmdPushConstants, m_Inst->fpGetDeviceProcAddr, m_LogicalDevice); + __VK_GET_DEVICE_PROC__(CmdBeginRenderPass, m_Inst->fpGetDeviceProcAddr, m_LogicalDevice); + __VK_GET_DEVICE_PROC__(CmdNextSubpass, m_Inst->fpGetDeviceProcAddr, m_LogicalDevice); + __VK_GET_DEVICE_PROC__(CmdEndRenderPass, m_Inst->fpGetDeviceProcAddr, m_LogicalDevice); + __VK_GET_DEVICE_PROC__(CmdExecuteCommands, m_Inst->fpGetDeviceProcAddr, m_LogicalDevice); + __VK_GET_DEVICE_PROC__(AcquireNextImageKHR, m_Inst->fpGetDeviceProcAddr, m_LogicalDevice); + __VK_GET_DEVICE_PROC__(CreateSwapchainKHR, m_Inst->fpGetDeviceProcAddr, m_LogicalDevice); + __VK_GET_DEVICE_PROC__(DestroySwapchainKHR, m_Inst->fpGetDeviceProcAddr, m_LogicalDevice); + __VK_GET_DEVICE_PROC__(GetSwapchainImagesKHR, m_Inst->fpGetDeviceProcAddr, m_LogicalDevice); +#endif +} + +Gpu::~Gpu() +{ + VKLOG(Info, "Gpu Destroyed...."); + if (m_PhysicalGpu) + { + m_PhysicalGpu = VK_NULL_HANDLE; + } +} + +VkDevice Gpu::CreateLogicDevice(bool enableValidation) +{ + if (!m_LogicalDevice) + { + std::array queuePriorities = { 0.0f }; + VkDeviceQueueCreateInfo queueCreateInfo = {}; + queueCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; + queueCreateInfo.queueFamilyIndex = m_GraphicsQueueIndex; + queueCreateInfo.queueCount = 1; + queueCreateInfo.pQueuePriorities = queuePriorities.data(); + + std::vector enabledExtensions = { VK_KHR_SWAPCHAIN_EXTENSION_NAME }; + VkDeviceCreateInfo deviceCreateInfo = {}; + deviceCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO; + deviceCreateInfo.pNext = NULL; + deviceCreateInfo.queueCreateInfoCount = 1; + deviceCreateInfo.pQueueCreateInfos = &queueCreateInfo; + deviceCreateInfo.pEnabledFeatures = NULL; + + if (enableValidation) + { + deviceCreateInfo.enabledLayerCount = 1; + deviceCreateInfo.ppEnabledLayerNames = g_ValidationLayerNames; + } + + if (enabledExtensions.size() > 0) + { + deviceCreateInfo.enabledExtensionCount = (uint32_t)enabledExtensions.size(); + deviceCreateInfo.ppEnabledExtensionNames = enabledExtensions.data(); + } + K3D_VK_VERIFY(vkCreateDevice(m_PhysicalGpu, &deviceCreateInfo, nullptr, &m_LogicalDevice)); + + LoadDeviceProcs(); + } + return m_LogicalDevice; +} + +VkBool32 Gpu::GetSupportedDepthFormat(VkFormat * depthFormat) +{ + // Since all depth formats may be optional, we need to find a suitable depth format to use + // Start with the highest precision packed format + std::vector depthFormats = { + VK_FORMAT_D32_SFLOAT_S8_UINT, + VK_FORMAT_D32_SFLOAT, + VK_FORMAT_D24_UNORM_S8_UINT, + VK_FORMAT_D16_UNORM_S8_UINT, + VK_FORMAT_D16_UNORM + }; + + for (auto& format : depthFormats) + { + VkFormatProperties formatProps; + vkGetPhysicalDeviceFormatProperties(m_PhysicalGpu, format, &formatProps); + // Format must support depth stencil attachment for optimal tiling + if (formatProps.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) + { + *depthFormat = format; + return true; + } + } + + return false; +} + +VkResult Gpu::GetSurfaceSupportKHR(uint32_t queueFamilyIndex, VkSurfaceKHR surface, VkBool32 * pSupported) +{ + return vkGetPhysicalDeviceSurfaceSupportKHR(m_PhysicalGpu, queueFamilyIndex, surface, pSupported); +} + +VkResult Gpu::GetSurfaceCapabilitiesKHR(VkSurfaceKHR surface, VkSurfaceCapabilitiesKHR * pSurfaceCapabilities) +{ + return vkGetPhysicalDeviceSurfaceCapabilitiesKHR(m_PhysicalGpu, surface, pSurfaceCapabilities); +} + +VkResult Gpu::GetSurfaceFormatsKHR(VkSurfaceKHR surface, uint32_t * pSurfaceFormatCount, VkSurfaceFormatKHR * pSurfaceFormats) +{ + return vkGetPhysicalDeviceSurfaceFormatsKHR(m_PhysicalGpu, surface, pSurfaceFormatCount, pSurfaceFormats); +} + +VkResult Gpu::GetSurfacePresentModesKHR(VkSurfaceKHR surface, uint32_t * pPresentModeCount, VkPresentModeKHR * pPresentModes) +{ + return vkGetPhysicalDeviceSurfacePresentModesKHR(m_PhysicalGpu, surface, pPresentModeCount, pPresentModes); +} + +void Gpu::DestroyDevice() +{ + vkDestroyDevice(m_LogicalDevice, nullptr); +} + +void Gpu::FreeCommandBuffers(VkCommandPool pool, uint32 count, VkCommandBuffer * cmd) +{ + vkFreeCommandBuffers(m_LogicalDevice, pool, count, cmd); +} + +VkResult Gpu::CreateCommdPool(const VkCommandPoolCreateInfo * pCreateInfo, const VkAllocationCallbacks * pAllocator, VkCommandPool * pCommandPool) +{ + return vkCreateCommandPool(m_LogicalDevice, pCreateInfo, pAllocator, pCommandPool); +} + +VkResult Gpu::AllocateCommandBuffers(const VkCommandBufferAllocateInfo * pAllocateInfo, VkCommandBuffer * pCommandBuffers) +{ + return vkAllocateCommandBuffers(m_LogicalDevice, pAllocateInfo, pCommandBuffers); +} + + +#if K3DPLATFORM_OS_WIN +#define PLATFORM_SURFACE_EXT VK_KHR_WIN32_SURFACE_EXTENSION_NAME +#elif defined(K3DPLATFORM_OS_LINUX) && !defined(K3DPLATFORM_OS_ANDROID) +#define PLATFORM_SURFACE_EXT VK_KHR_XCB_SURFACE_EXTENSION_NAME +#elif defined(K3DPLATFORM_OS_ANDROID) +#define PLATFORM_SURFACE_EXT VK_KHR_ANDROID_SURFACE_EXTENSION_NAME +#endif + +::k3d::DynArray gVkLayerProps; +::k3d::DynArray gVkExtProps; + + +Instance::Instance(const::k3d::String & engineName, const::k3d::String & appName, bool enableValidation) + : m_EnableValidation(enableValidation) + , m_Instance(VK_NULL_HANDLE) + , m_DebugMsgCallback(VK_NULL_HANDLE) +{ + LoadGlobalProcs(); + EnumExtsAndLayers(); + ExtractEnabledExtsAndLayers(); + + VkApplicationInfo appInfo = {}; + appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO; + appInfo.pApplicationName = appName.CStr(); + appInfo.pEngineName = engineName.CStr(); + appInfo.apiVersion = VK_MAKE_VERSION(1, 0, 1); + appInfo.engineVersion = 1; + appInfo.applicationVersion = 0; + + VkInstanceCreateInfo instanceCreateInfo = {}; + instanceCreateInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; + instanceCreateInfo.pNext = NULL; + instanceCreateInfo.pApplicationInfo = &appInfo; + instanceCreateInfo.enabledExtensionCount = m_EnabledExtsRaw.Count(); + instanceCreateInfo.ppEnabledExtensionNames = m_EnabledExtsRaw.Data(); + instanceCreateInfo.enabledLayerCount = m_EnabledLayersRaw.Count(); + instanceCreateInfo.ppEnabledLayerNames = m_EnabledLayersRaw.Data(); + + VkResult err = vkCreateInstance(&instanceCreateInfo, nullptr, &m_Instance); + if (err == VK_ERROR_INCOMPATIBLE_DRIVER) + { + VKLOG(Error, "Cannot find a compatible Vulkan installable client driver: vkCreateInstance Failure"); + } + else if (err == VK_ERROR_EXTENSION_NOT_PRESENT) + { + VKLOG(Error, "Cannot find a specified extension library: vkCreateInstance Failure"); + } + else + { + LoadInstanceProcs(); + EnumGpus(); + } +} + +Instance::~Instance() +{ + VKLOG(Info, "Instance Destroying... -- %0x. (tid:%d)", m_Instance, Os::Thread::GetId()); + //if (!m_Gpus.empty()) + //{ + // m_Gpus.~DynArray(); + //} + //if (!m_GpuAdapters.empty()) + //{ + // m_GpuAdapters.~DynArray(); + //} + //if (!m_LogicDevices.empty()) + //{ + // m_LogicDevices.~DynArray(); + //} + if (m_Instance) + { + FreeDebugCallback(); + vkDestroyInstance(m_Instance, nullptr); + VKLOG(Info, "Instance Destroyed . -- %0x.", m_Instance); + m_Instance = VK_NULL_HANDLE; + } +} + +#define __VK_GLOBAL_PROC_GET__(name, functor) gp##name = reinterpret_cast(functor("vk" K3D_STRINGIFY(name))) + +void Instance::LoadGlobalProcs() +{ +#ifdef K3DPLATFORM_OS_WIN + static const char* LIBVULKAN = "vulkan-1.dll"; +#elif defined(K3DPLATFORM_OS_MAC) + static const char* LIBVULKAN = "libvulkan.dylib"; +#else + static const char* LIBVULKAN = "libvulkan.so"; +#endif + +#ifdef VK_NO_PROTOTYPES + m_VulkanLib = MakeShared(LIBVULKAN); + // load global functions + __VK_GLOBAL_PROC_GET__(CreateInstance, m_VulkanLib->ResolveEntry); + __VK_GLOBAL_PROC_GET__(DestroyInstance, m_VulkanLib->ResolveEntry); + __VK_GLOBAL_PROC_GET__(EnumerateInstanceExtensionProperties, m_VulkanLib->ResolveEntry); + __VK_GLOBAL_PROC_GET__(EnumerateInstanceLayerProperties, m_VulkanLib->ResolveEntry); + __VK_GLOBAL_PROC_GET__(GetInstanceProcAddr, m_VulkanLib->ResolveEntry); +#endif +} + +void Instance::EnumExtsAndLayers() +{ + uint32 layerCount = 0; + K3D_VK_VERIFY(vkEnumerateInstanceLayerProperties(&layerCount, nullptr)); + if (layerCount > 0) + { + gVkLayerProps.Resize(layerCount); + K3D_VK_VERIFY(vkEnumerateInstanceLayerProperties(&layerCount, gVkLayerProps.Data())); + } + uint32 extCount = 0; + K3D_VK_VERIFY(vkEnumerateInstanceExtensionProperties(nullptr, &extCount, nullptr)); + if (extCount > 0) + { + gVkExtProps.Resize(extCount); + K3D_VK_VERIFY(vkEnumerateInstanceExtensionProperties(nullptr, &extCount, gVkExtProps.Data())); + } + VKLOG(Info, ">> Instance::EnumLayersAndExts <<\n\n" + "=================================>> layerCount = %d.\n" + "=================================>> extensionCount = %d.\n", layerCount, extCount); +} + +void Instance::ExtractEnabledExtsAndLayers() +{ + VkBool32 surfaceExtFound = 0; + VkBool32 platformSurfaceExtFound = 0; + + for (uint32_t i = 0; i < gVkExtProps.Count(); i++) + { + if (!strcmp(VK_KHR_SURFACE_EXTENSION_NAME, gVkExtProps[i].extensionName)) + { + surfaceExtFound = 1; + m_EnabledExts.Append(VK_KHR_SURFACE_EXTENSION_NAME); + m_EnabledExtsRaw.Append(VK_KHR_SURFACE_EXTENSION_NAME); + } + if (!strcmp(PLATFORM_SURFACE_EXT, gVkExtProps[i].extensionName)) + { + platformSurfaceExtFound = 1; + m_EnabledExts.Append(PLATFORM_SURFACE_EXT); + m_EnabledExtsRaw.Append(PLATFORM_SURFACE_EXT); + } + if (m_EnableValidation) + { + m_EnabledExts.Append(VK_EXT_DEBUG_REPORT_EXTENSION_NAME); + m_EnabledExtsRaw.Append(VK_EXT_DEBUG_REPORT_EXTENSION_NAME); + } + VKLOG(Info, "available extension : %s .", gVkExtProps[i].extensionName); + } + if (!surfaceExtFound) + { + VKLOG(Error, "vkEnumerateInstanceExtensionProperties failed to find the " VK_KHR_SURFACE_EXTENSION_NAME" extension."); + } + if (!platformSurfaceExtFound) + { + VKLOG(Error, "vkEnumerateInstanceExtensionProperties failed to find the " PLATFORM_SURFACE_EXT " extension."); + } + + if (m_EnableValidation && !gVkLayerProps.empty()) + { + for (auto prop : gVkLayerProps) + { + if (strcmp(prop.layerName, g_ValidationLayerNames[0]) == 0 /*|| strcmp(prop.layerName, g_ValidationLayerNames[1])==0*/) + { + m_EnabledLayers.Append(prop.layerName); + m_EnabledLayersRaw.Append(g_ValidationLayerNames[0]); + VKLOG(Info, "enable validation layer [%s].", prop.layerName); + break; + } + } + } + +} + +void Instance::LoadInstanceProcs() +{ +#ifdef VK_NO_PROTOTYPES + GET_INSTANCE_PROC_ADDR(m_Instance, GetPhysicalDeviceSurfaceSupportKHR); + GET_INSTANCE_PROC_ADDR(m_Instance, GetPhysicalDeviceSurfaceCapabilitiesKHR); + GET_INSTANCE_PROC_ADDR(m_Instance, GetPhysicalDeviceSurfaceFormatsKHR); + GET_INSTANCE_PROC_ADDR(m_Instance, GetPhysicalDeviceSurfacePresentModesKHR); + + GET_INSTANCE_PROC_ADDR(m_Instance, EnumeratePhysicalDevices); + GET_INSTANCE_PROC_ADDR(m_Instance, GetPhysicalDeviceFeatures); + GET_INSTANCE_PROC_ADDR(m_Instance, GetPhysicalDeviceProperties); + GET_INSTANCE_PROC_ADDR(m_Instance, GetPhysicalDeviceMemoryProperties); + GET_INSTANCE_PROC_ADDR(m_Instance, GetPhysicalDeviceFormatProperties); + GET_INSTANCE_PROC_ADDR(m_Instance, GetPhysicalDeviceQueueFamilyProperties); + GET_INSTANCE_PROC_ADDR(m_Instance, CreateDevice); + GET_INSTANCE_PROC_ADDR(m_Instance, GetDeviceProcAddr); + +#if K3DPLATFORM_OS_WIN + GET_INSTANCE_PROC_ADDR(m_Instance, CreateWin32SurfaceKHR); +#elif K3DPLATFORM_OS_ANDROID + GET_INSTANCE_PROC_ADDR(m_Instance, CreateAndroidSurfaceKHR); +#endif + GET_INSTANCE_PROC_ADDR(m_Instance, DestroySurfaceKHR); +#endif +} + +K3D_VK_END \ No newline at end of file diff --git a/Source/RHI/Vulkan/Private/VkObjects.h b/Source/RHI/Vulkan/Private/VkObjects.h index fed88f2..1063792 100755 --- a/Source/RHI/Vulkan/Private/VkObjects.h +++ b/Source/RHI/Vulkan/Private/VkObjects.h @@ -5,8 +5,50 @@ K3D_VK_BEGIN +template +struct ResTrait +{ +}; + +template <> +struct ResTrait +{ + typedef VkBufferView View; + typedef VkBufferUsageFlags UsageFlags; + typedef VkBufferCreateInfo CreateInfo; + typedef VkBufferViewCreateInfo ViewCreateInfo; + typedef VkDescriptorBufferInfo DescriptorInfo; + static decltype(vkCreateBufferView)* CreateView; + static decltype(vkDestroyBufferView)* DestroyView; + static decltype(vkCreateBuffer)* Create; + static decltype(vkDestroyBuffer)* Destroy; + static decltype(vkGetBufferMemoryRequirements)* GetMemoryInfo; + static decltype(vkBindBufferMemory)* BindMemory; +}; + +template <> +struct ResTrait +{ + typedef VkImageView View; + typedef VkImageUsageFlags UsageFlags; + typedef VkImageCreateInfo CreateInfo; + typedef VkImageViewCreateInfo ViewCreateInfo; + typedef VkDescriptorImageInfo DescriptorInfo; + static decltype(vkCreateImageView)* CreateView; + static decltype(vkDestroyImageView)* DestroyView; + static decltype(vkCreateImage)* Create; + static decltype(vkDestroyImage)* Destroy; + static decltype(vkGetImageMemoryRequirements)* GetMemoryInfo; + static decltype(vkBindImageMemory)* BindMemory; +}; + struct ImageInfo; +class Gpu; +using GpuRef = SharedPtr; +class Instance; +using InstanceRef = SharedPtr; + class RenderTargetLayout { public: @@ -386,6 +428,9 @@ class ImageViewInfo : public VkImageViewCreateInfo static std::pair CreateColorImageView( VkDevice device, VkFormat colorFmt, VkImage colorImage, VkImageAspectFlags aspectMask = VK_IMAGE_ASPECT_COLOR_BIT); + static std::pair CreateColorImageView( + GpuRef device, VkFormat colorFmt, VkImage colorImage, + VkImageAspectFlags aspectMask = VK_IMAGE_ASPECT_COLOR_BIT); static ImageViewInfo CreateDepthStencilImageInfo( VkFormat format, VkImage image, @@ -541,6 +586,341 @@ struct ImageInfo : VkImageCreateInfo static ImageInfo FromRHI(rhi::TextureDesc const & desc); }; +class VkObjectAllocator +{ +public: + + inline operator VkAllocationCallbacks() const + { + VkAllocationCallbacks result; + result.pUserData = (void*)this; +// result.pfnAllocation = VkObjectAllocator::Allocation; +// result.pfnReallocation = VkObjectAllocator::Reallocation; +// result.pfnFree = VkObjectAllocator::Free; + result.pfnInternalAllocation = nullptr; + result.pfnInternalFree = nullptr; + return result; + }; + +private: + static void* VKAPI_CALL Allocation( void* pUserData, size_t size, size_t alignment, VkSystemAllocationScope allocationScope); + static void* VKAPI_CALL Reallocation( void* pUserData, void* pOriginal, size_t size, size_t alignment, VkSystemAllocationScope allocationScope); + static void VKAPI_CALL Free( void* pUserData, void* pMemory); + void* Allocation( size_t size, size_t alignment, VkSystemAllocationScope allocationScope); + void* Reallocation(void* pOriginal, size_t size, size_t alignment, VkSystemAllocationScope allocationScope); + void Free(void* pMemory); +}; + +class CommandBufferManager +{ +public: + CommandBufferManager(VkDevice pDevice, VkCommandBufferLevel bufferLevel, unsigned graphicsQueueIndex); + ~CommandBufferManager(); + void Destroy(); + VkCommandBuffer RequestCommandBuffer(); + void BeginFrame(); + +private: + VkDevice m_Device = VK_NULL_HANDLE; + VkCommandPool m_Pool = VK_NULL_HANDLE; + std::vector m_Buffers; + VkCommandBufferLevel m_CommandBufferLevel; + uint32 m_Count = 0; +}; + +using CmdBufManagerRef = SharedPtr; + +extern ::k3d::DynArray gVkLayerProps; +extern ::k3d::DynArray gVkExtProps; + +class Instance; + +#define __VK_DEVICE_PROC__(name) PFN_vk##name vk##name = NULL + +class Gpu : public EnableSharedFromThis +{ +public: + ~Gpu(); + + VkDevice CreateLogicDevice(bool enableValidation); + VkBool32 GetSupportedDepthFormat(VkFormat * depthFormat); + + VkResult GetSurfaceSupportKHR(uint32_t queueFamilyIndex, VkSurfaceKHR surface, VkBool32* pSupported); + VkResult GetSurfaceCapabilitiesKHR(VkSurfaceKHR surface, VkSurfaceCapabilitiesKHR* pSurfaceCapabilities); + VkResult GetSurfaceFormatsKHR(VkSurfaceKHR surface, uint32_t* pSurfaceFormatCount, VkSurfaceFormatKHR* pSurfaceFormats); + VkResult GetSurfacePresentModesKHR(VkSurfaceKHR surface, uint32_t* pPresentModeCount, VkPresentModeKHR* pPresentModes); + + void DestroyDevice(); + void FreeCommandBuffers(VkCommandPool,uint32,VkCommandBuffer*); + VkResult CreateCommdPool(const VkCommandPoolCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkCommandPool* pCommandPool); + VkResult AllocateCommandBuffers(const VkCommandBufferAllocateInfo* pAllocateInfo, VkCommandBuffer* pCommandBuffers); + + InstanceRef GetInstance() const { return m_Inst; } + +#ifdef VK_NO_PROTOTYPES + __VK_DEVICE_PROC__(DestroyDevice); + __VK_DEVICE_PROC__(GetDeviceQueue); + __VK_DEVICE_PROC__(QueueSubmit); + __VK_DEVICE_PROC__(QueueWaitIdle); + __VK_DEVICE_PROC__(QueuePresentKHR); + __VK_DEVICE_PROC__(DeviceWaitIdle); + __VK_DEVICE_PROC__(AllocateMemory); + __VK_DEVICE_PROC__(FreeMemory); + __VK_DEVICE_PROC__(MapMemory); + __VK_DEVICE_PROC__(UnmapMemory); + __VK_DEVICE_PROC__(FlushMappedMemoryRanges); + __VK_DEVICE_PROC__(InvalidateMappedMemoryRanges); + __VK_DEVICE_PROC__(GetDeviceMemoryCommitment); + __VK_DEVICE_PROC__(BindBufferMemory); + __VK_DEVICE_PROC__(BindImageMemory); + __VK_DEVICE_PROC__(GetBufferMemoryRequirements); + __VK_DEVICE_PROC__(GetImageMemoryRequirements); + __VK_DEVICE_PROC__(GetImageSparseMemoryRequirements); + __VK_DEVICE_PROC__(QueueBindSparse); + __VK_DEVICE_PROC__(CreateFence); + __VK_DEVICE_PROC__(DestroyFence); + __VK_DEVICE_PROC__(ResetFences); + __VK_DEVICE_PROC__(GetFenceStatus); + __VK_DEVICE_PROC__(WaitForFences); + __VK_DEVICE_PROC__(CreateSemaphore); + __VK_DEVICE_PROC__(DestroySemaphore); + __VK_DEVICE_PROC__(CreateEvent); + __VK_DEVICE_PROC__(DestroyEvent); + __VK_DEVICE_PROC__(GetEventStatus); + __VK_DEVICE_PROC__(SetEvent); + __VK_DEVICE_PROC__(ResetEvent); + __VK_DEVICE_PROC__(CreateQueryPool); + __VK_DEVICE_PROC__(DestroyQueryPool); + __VK_DEVICE_PROC__(GetQueryPoolResults); + __VK_DEVICE_PROC__(CreateBuffer); + __VK_DEVICE_PROC__(DestroyBuffer); + __VK_DEVICE_PROC__(CreateBufferView); + __VK_DEVICE_PROC__(DestroyBufferView); + __VK_DEVICE_PROC__(CreateImage); + __VK_DEVICE_PROC__(DestroyImage); + __VK_DEVICE_PROC__(GetImageSubresourceLayout); + __VK_DEVICE_PROC__(CreateImageView); + __VK_DEVICE_PROC__(DestroyImageView); + __VK_DEVICE_PROC__(CreateShaderModule); + __VK_DEVICE_PROC__(DestroyShaderModule); + __VK_DEVICE_PROC__(CreatePipelineCache); + __VK_DEVICE_PROC__(DestroyPipelineCache); + __VK_DEVICE_PROC__(GetPipelineCacheData); + __VK_DEVICE_PROC__(MergePipelineCaches); + __VK_DEVICE_PROC__(CreateGraphicsPipelines); + __VK_DEVICE_PROC__(CreateComputePipelines); + __VK_DEVICE_PROC__(DestroyPipeline); + __VK_DEVICE_PROC__(CreatePipelineLayout); + __VK_DEVICE_PROC__(DestroyPipelineLayout); + __VK_DEVICE_PROC__(CreateSampler); + __VK_DEVICE_PROC__(DestroySampler); + __VK_DEVICE_PROC__(CreateDescriptorSetLayout); + __VK_DEVICE_PROC__(DestroyDescriptorSetLayout); + __VK_DEVICE_PROC__(CreateDescriptorPool); + __VK_DEVICE_PROC__(DestroyDescriptorPool); + __VK_DEVICE_PROC__(ResetDescriptorPool); + __VK_DEVICE_PROC__(AllocateDescriptorSets); + __VK_DEVICE_PROC__(FreeDescriptorSets); + __VK_DEVICE_PROC__(UpdateDescriptorSets); + __VK_DEVICE_PROC__(CreateFramebuffer); + __VK_DEVICE_PROC__(DestroyFramebuffer); + __VK_DEVICE_PROC__(CreateRenderPass); + __VK_DEVICE_PROC__(DestroyRenderPass); + __VK_DEVICE_PROC__(GetRenderAreaGranularity); + __VK_DEVICE_PROC__(CreateCommandPool); + __VK_DEVICE_PROC__(DestroyCommandPool); + __VK_DEVICE_PROC__(ResetCommandPool); + __VK_DEVICE_PROC__(AllocateCommandBuffers); + __VK_DEVICE_PROC__(FreeCommandBuffers); + __VK_DEVICE_PROC__(BeginCommandBuffer); + __VK_DEVICE_PROC__(EndCommandBuffer); + __VK_DEVICE_PROC__(ResetCommandBuffer); + __VK_DEVICE_PROC__(CmdBindPipeline); + __VK_DEVICE_PROC__(CmdSetViewport); + __VK_DEVICE_PROC__(CmdSetScissor); + __VK_DEVICE_PROC__(CmdSetLineWidth); + __VK_DEVICE_PROC__(CmdSetDepthBias); + __VK_DEVICE_PROC__(CmdSetBlendConstants); + __VK_DEVICE_PROC__(CmdSetDepthBounds); + __VK_DEVICE_PROC__(CmdSetStencilCompareMask); + __VK_DEVICE_PROC__(CmdSetStencilWriteMask); + __VK_DEVICE_PROC__(CmdSetStencilReference); + __VK_DEVICE_PROC__(CmdBindDescriptorSets); + __VK_DEVICE_PROC__(CmdBindIndexBuffer); + __VK_DEVICE_PROC__(CmdBindVertexBuffers); + __VK_DEVICE_PROC__(CmdDraw); + __VK_DEVICE_PROC__(CmdDrawIndexed); + __VK_DEVICE_PROC__(CmdDrawIndirect); + __VK_DEVICE_PROC__(CmdDrawIndexedIndirect); + __VK_DEVICE_PROC__(CmdDispatch); + __VK_DEVICE_PROC__(CmdDispatchIndirect); + __VK_DEVICE_PROC__(CmdCopyBuffer); + __VK_DEVICE_PROC__(CmdCopyImage); + __VK_DEVICE_PROC__(CmdBlitImage); + __VK_DEVICE_PROC__(CmdCopyBufferToImage); + __VK_DEVICE_PROC__(CmdCopyImageToBuffer); + __VK_DEVICE_PROC__(CmdUpdateBuffer); + __VK_DEVICE_PROC__(CmdFillBuffer); + __VK_DEVICE_PROC__(CmdClearColorImage); + __VK_DEVICE_PROC__(CmdClearDepthStencilImage); + __VK_DEVICE_PROC__(CmdClearAttachments); + __VK_DEVICE_PROC__(CmdResolveImage); + __VK_DEVICE_PROC__(CmdSetEvent); + __VK_DEVICE_PROC__(CmdResetEvent); + __VK_DEVICE_PROC__(CmdWaitEvents); + __VK_DEVICE_PROC__(CmdPipelineBarrier); + __VK_DEVICE_PROC__(CmdBeginQuery); + __VK_DEVICE_PROC__(CmdEndQuery); + __VK_DEVICE_PROC__(CmdResetQueryPool); + __VK_DEVICE_PROC__(CmdWriteTimestamp); + __VK_DEVICE_PROC__(CmdCopyQueryPoolResults); + __VK_DEVICE_PROC__(CmdPushConstants); + __VK_DEVICE_PROC__(CmdBeginRenderPass); + __VK_DEVICE_PROC__(CmdNextSubpass); + __VK_DEVICE_PROC__(CmdEndRenderPass); + __VK_DEVICE_PROC__(CmdExecuteCommands); + __VK_DEVICE_PROC__(AcquireNextImageKHR); + __VK_DEVICE_PROC__(CreateSwapchainKHR); + __VK_DEVICE_PROC__(DestroySwapchainKHR); + __VK_DEVICE_PROC__(GetSwapchainImagesKHR); + + PFN_vkDestroyDevice fpDestroyDevice = NULL; + PFN_vkFreeCommandBuffers fpFreeCommandBuffers = NULL; + PFN_vkCreateCommandPool fpCreateCommandPool = NULL; + PFN_vkAllocateCommandBuffers fpAllocateCommandBuffers = NULL; +#endif + + VkDevice m_LogicalDevice; + +private: + friend class Instance; + friend class Device; + friend class DeviceAdapter; + + Gpu(VkPhysicalDevice const&, InstanceRef const& inst); + + void QuerySupportQueues(); + void LoadDeviceProcs(); + + InstanceRef m_Inst; + VkPhysicalDevice m_PhysicalGpu; + VkPhysicalDeviceProperties m_Prop; + VkPhysicalDeviceMemoryProperties m_MemProp; + uint32 m_GraphicsQueueIndex = 0; + uint32 m_ComputeQueueIndex = 0; + uint32 m_CopyQueueIndex = 0; + DynArray m_QueueProps; +}; + +VKAPI_ATTR VkBool32 VKAPI_CALL DebugReportCallback( + VkDebugReportFlagsEXT flags, + VkDebugReportObjectTypeEXT objectType, + uint64_t object, size_t location, int32_t messageCode, + const char * pLayerPrefix, + const char * pMessage, void * pUserData); + +#define __VK_GLOBAL_LEVEL_PROC__(name) PFN_vk##name gp##name = NULL; +#define __VK_INSTANCE_LEVEL_PROC__(name) PFN_vk##name fp##name = NULL + +class Instance : public EnableSharedFromThis +{ +public: + Instance(const ::k3d::String& engineName, const ::k3d::String& appName, bool enableValidation = true); + ~Instance(); + + //uint32 GetHostGpuCount() const { return m_Gpus.Count(); } + //GpuRef GetHostGpuByIndex(uint32 i) const { return m_Gpus[i]; } + //rhi::DeviceRef GetDeviceByIndex(uint32 i) const { return m_LogicDevices[i]; } + + void SetupDebugging(VkDebugReportFlagsEXT flags, PFN_vkDebugReportCallbackEXT callBack); + void FreeDebugCallback(); + + bool WithValidation() const { return m_EnableValidation; } + //void AppendLogicalDevice(rhi::DeviceRef logicalDevice); + + ::k3d::DynArray EnumGpus(); + +#ifdef VK_NO_PROTOTYPES + VkResult CreateSurfaceKHR(const +#if K3DPLATFORM_OS_WIN + VkWin32SurfaceCreateInfoKHR +#elif K3DPLATFORM_OS_ANDROID + VkAndroidSurfaceCreateInfoKHR +#endif + * pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface) + { +#if K3DPLATFORM_OS_WIN + return fpCreateWin32SurfaceKHR(m_Instance, pCreateInfo, pAllocator, pSurface); +#elif K3DPLATFORM_OS_ANDROID + return fpCreateAndroidSurfaceKHR(m_Instance, pCreateInfo, pAllocator, pSurface); +#endif + } + + void DestroySurfaceKHR(VkSurfaceKHR surface, VkAllocationCallbacks* pAllocator) + { + fpDestroySurfaceKHR(m_Instance, surface, pAllocator); + } +#endif + + friend class Gpu; + friend class Device; + friend class SwapChain; + friend struct RHIRoot; + +private: + void LoadGlobalProcs(); + void EnumExtsAndLayers(); + void ExtractEnabledExtsAndLayers(); + void LoadInstanceProcs(); + + bool m_EnableValidation; + ::k3d::DynArray<::k3d::String> m_EnabledExts; + ::k3d::DynArray m_EnabledExtsRaw; + ::k3d::DynArray<::k3d::String> m_EnabledLayers; + ::k3d::DynArray m_EnabledLayersRaw; + + VkInstance m_Instance; + VkDebugReportCallbackEXT m_DebugMsgCallback; + //::k3d::DynArray m_Gpus; + //::k3d::DynArray m_GpuAdapters; + //::k3d::DynArray m_LogicDevices; + +#ifdef VK_NO_PROTOTYPES + + PFN_vkGetPhysicalDeviceSurfaceSupportKHR fpGetPhysicalDeviceSurfaceSupportKHR; + PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR fpGetPhysicalDeviceSurfaceCapabilitiesKHR; + PFN_vkGetPhysicalDeviceSurfaceFormatsKHR fpGetPhysicalDeviceSurfaceFormatsKHR; + PFN_vkGetPhysicalDeviceSurfacePresentModesKHR fpGetPhysicalDeviceSurfacePresentModesKHR; + + __VK_GLOBAL_LEVEL_PROC__(CreateInstance); + __VK_GLOBAL_LEVEL_PROC__(EnumerateInstanceExtensionProperties); + __VK_GLOBAL_LEVEL_PROC__(EnumerateInstanceLayerProperties); + __VK_GLOBAL_LEVEL_PROC__(GetInstanceProcAddr); + __VK_GLOBAL_LEVEL_PROC__(DestroyInstance); + + __VK_INSTANCE_LEVEL_PROC__(CreateDebugReportCallbackEXT); + __VK_INSTANCE_LEVEL_PROC__(DestroyDebugReportCallbackEXT); + +#if K3DPLATFORM_OS_WIN + __VK_INSTANCE_LEVEL_PROC__(CreateWin32SurfaceKHR); +#elif K3DPLATFORM_OS_ANDROID + __VK_INSTANCE_LEVEL_PROC__(CreateAndroidSurfaceKHR); +#endif + __VK_INSTANCE_LEVEL_PROC__(DestroySurfaceKHR); + + __VK_INSTANCE_LEVEL_PROC__(EnumeratePhysicalDevices); + __VK_INSTANCE_LEVEL_PROC__(GetPhysicalDeviceProperties); + __VK_INSTANCE_LEVEL_PROC__(GetPhysicalDeviceFeatures); + __VK_INSTANCE_LEVEL_PROC__(GetPhysicalDeviceMemoryProperties); + __VK_INSTANCE_LEVEL_PROC__(GetPhysicalDeviceQueueFamilyProperties); + __VK_INSTANCE_LEVEL_PROC__(GetPhysicalDeviceFormatProperties); + __VK_INSTANCE_LEVEL_PROC__(CreateDevice); + __VK_INSTANCE_LEVEL_PROC__(GetDeviceProcAddr); + + dynlib::LibRef m_VulkanLib; +#endif +}; + K3D_VK_END #endif \ No newline at end of file diff --git a/Source/RHI/Vulkan/Private/VkPipelineLayout.cpp b/Source/RHI/Vulkan/Private/VkPipelineLayout.cpp deleted file mode 100755 index 8d27a52..0000000 --- a/Source/RHI/Vulkan/Private/VkPipelineLayout.cpp +++ /dev/null @@ -1,50 +0,0 @@ -#include "VkCommon.h" -#include "VkRHI.h" -#include "Private/VkUtils.h" - -K3D_VK_BEGIN - -PipelineLayout::PipelineLayout(Device::Ptr pDevice, rhi::PipelineLayoutDesc const & desc) - : DeviceChild(pDevice) - , m_PipelineLayout(VK_NULL_HANDLE) - , m_DescSetLayout(nullptr) - , m_DescSet() -{ - InitWithDesc(desc); -} - -PipelineLayout::~PipelineLayout() -{ - Destroy(); -} - -void PipelineLayout::Destroy() -{ - if (m_PipelineLayout == VK_NULL_HANDLE) - return; - vkDestroyPipelineLayout(GetRawDevice(), m_PipelineLayout, nullptr); - VKLOG(Info, "PipelineLayout-destroying vkPipelineLayout..."); -} - -void PipelineLayout::InitWithDesc(rhi::PipelineLayoutDesc const & desc) -{ - DescriptorAllocator::Options options; - BindingArray array; - for (auto & rhibinding : desc.Bindings) - { - array.Append(RHIBinding2VkBinding(rhibinding)); - } - - DescriptorAllocator* alloc = GetDevice()->NewDescriptorAllocator(16, array); - m_DescSetLayout = GetDevice()->NewDescriptorSetLayout(array); - m_DescSet = rhi::DescriptorRef( DescriptorSet::CreateDescSet(alloc, m_DescSetLayout->GetNativeHandle(), array, GetDevice()) ); - - VkPipelineLayoutCreateInfo pPipelineLayoutCreateInfo = {}; - pPipelineLayoutCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; - pPipelineLayoutCreateInfo.pNext = NULL; - pPipelineLayoutCreateInfo.setLayoutCount = 1; - pPipelineLayoutCreateInfo.pSetLayouts = &m_DescSetLayout->m_DescriptorSetLayout; - K3D_VK_VERIFY(vkCreatePipelineLayout(GetRawDevice(), &pPipelineLayoutCreateInfo, nullptr, &m_PipelineLayout)); -} - -K3D_VK_END \ No newline at end of file diff --git a/Source/RHI/Vulkan/Private/VkPipelineState.cpp b/Source/RHI/Vulkan/Private/VkPipelineState.cpp index f3179bc..4c654ab 100755 --- a/Source/RHI/Vulkan/Private/VkPipelineState.cpp +++ b/Source/RHI/Vulkan/Private/VkPipelineState.cpp @@ -2,8 +2,13 @@ #include "VkRHI.h" #include "VkEnums.h" #include "VkUtils.h" +#include #include +#include + +using namespace rhi::shc; +using namespace std; K3D_VK_BEGIN @@ -22,7 +27,7 @@ PipelineStateObject::PipelineStateObject(Device::Ptr pDevice, rhi::PipelineDesc /** * @class PipelineStateObject */ -PipelineStateObject::PipelineStateObject(Device* pDevice) +PipelineStateObject::PipelineStateObject(Device::Ptr pDevice) : DeviceChild(pDevice) , m_Pipeline(VK_NULL_HANDLE) , m_PipelineCache(VK_NULL_HANDLE) @@ -58,7 +63,7 @@ VkShaderModule CreateShaderModule(VkDevice Device, rhi::IDataBlob * ShaderBytes) return shaderModule; } -VkShaderModule CreateShaderModule(VkDevice Device, String ShaderBytes) +VkShaderModule CreateShaderModule(GpuRef Device, String ShaderBytes) { VkShaderModule shaderModule; VkShaderModuleCreateInfo moduleCreateInfo; @@ -69,13 +74,13 @@ VkShaderModule CreateShaderModule(VkDevice Device, String ShaderBytes) moduleCreateInfo.codeSize = ShaderBytes.Length(); moduleCreateInfo.pCode = (const uint32_t*)ShaderBytes.Data(); moduleCreateInfo.flags = 0; - K3D_VK_VERIFY(vkCreateShaderModule(Device, &moduleCreateInfo, NULL, &shaderModule)); + K3D_VK_VERIFY(vkCreateShaderModule(Device->m_LogicalDevice, &moduleCreateInfo, NULL, &shaderModule)); return shaderModule; } void PipelineStateObject::SetShader(rhi::EShaderType ShaderType, rhi::ShaderBundle const& ShaderBytes) { - auto sm = CreateShaderModule(GetRawDevice(), ShaderBytes.RawData); + auto sm = CreateShaderModule(GetGpuRef(), ShaderBytes.RawData); VkPipelineShaderStageCreateInfo shaderStage = {}; shaderStage.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; shaderStage.stage = g_ShaderType[ShaderType]; @@ -94,12 +99,12 @@ void PipelineStateObject::Finalize() { if (VK_NULL_HANDLE != m_Pipeline) return; - /*VkPipelineCacheCreateInfo pipelineCacheCreateInfo = {}; + VkPipelineCacheCreateInfo pipelineCacheCreateInfo = {}; pipelineCacheCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO; - K3D_VK_VERIFY(vkCreatePipelineCache(GetRawDevice(), &pipelineCacheCreateInfo, nullptr, &m_PipelineCache));*/ + K3D_VK_VERIFY(vkCreatePipelineCache(GetRawDevice(), &pipelineCacheCreateInfo, nullptr, &m_PipelineCache)); if (GetType() == rhi::EPSO_Graphics) { - K3D_VK_VERIFY(vkCmd::CreateGraphicsPipelines(GetRawDevice(), VK_NULL_HANDLE, 1, &m_GfxCreateInfo, nullptr, &m_Pipeline)); + K3D_VK_VERIFY(vkCreateGraphicsPipelines(GetRawDevice(), m_PipelineCache, 1, &m_GfxCreateInfo, nullptr, &m_Pipeline)); } else { @@ -108,6 +113,33 @@ void PipelineStateObject::Finalize() } } +void PipelineStateObject::SavePSO(const char * path) +{ + size_t szPSO = 0; + K3D_VK_VERIFY(vkGetPipelineCacheData(GetRawDevice(), m_PipelineCache, &szPSO, nullptr)); + if (!szPSO || !path) + return; + DynArray dataBlob; + dataBlob.Resize(szPSO); + vkGetPipelineCacheData(GetRawDevice(), m_PipelineCache, &szPSO, dataBlob.Data()); + Os::File psoCacheFile(path); + psoCacheFile.Open(IOWrite); + psoCacheFile.Write(dataBlob.Data(), szPSO); + psoCacheFile.Close(); +} + +void PipelineStateObject::LoadPSO(const char * path) +{ + Os::MemMapFile psoFile; + if(!path || !psoFile.Open(path, IORead)) + return; + VkPipelineCacheCreateInfo pipelineCacheCreateInfo = {}; + pipelineCacheCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO; + pipelineCacheCreateInfo.pInitialData = psoFile.FileData(); + pipelineCacheCreateInfo.initialDataSize = psoFile.GetSize(); + K3D_VK_VERIFY(vkCreatePipelineCache(GetRawDevice(), &pipelineCacheCreateInfo, nullptr, &m_PipelineCache)); +} + void PipelineStateObject::SetRasterizerState(const rhi::RasterizerState& rasterState) { m_RasterizationState.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO; @@ -190,7 +222,7 @@ void PipelineStateObject::SetRenderTargetFormat(const rhi::RenderTargetFormat &) // Init Shaders std::vector -GetShaderStageInfo(VkDevice device, rhi::PipelineDesc const & desc) +GetShaderStageInfo(GpuRef device, rhi::PipelineDesc const & desc) { std::vector infos; for (uint32 i = 0; i < rhi::EShaderType::ShaderTypeNum; i++) @@ -209,9 +241,35 @@ GetShaderStageInfo(VkDevice device, rhi::PipelineDesc const & desc) return infos; } +DynArray RHIInputAttribs(rhi::VertexInputState ia) +{ + DynArray iad; + for(uint32 i = 0; i RHIInputLayouts(rhi::VertexInputState const& ia) +{ + DynArray ibd; + for(uint32 i = 0; iGetRenderPass(); this->m_GfxCreateInfo.renderPass = m_RenderPass; - this->m_GfxCreateInfo.layout = m_PipelineLayout->m_PipelineLayout; + this->m_GfxCreateInfo.layout = m_PipelineLayout->NativeHandle(); // Finalize Finalize(); @@ -318,9 +378,96 @@ void PipelineStateObject::Destroy() vkDestroyShaderModule(GetRawDevice(), iter.module, nullptr); } } - //vkDestroyPipelineCache(GetRawDevice(), m_PipelineCache, nullptr); - vkDestroyPipeline(GetRawDevice(), m_Pipeline, nullptr); - VKLOG(Info, "PipelineStateObject-Destroyed.."); + if (m_PipelineCache) + { + vkDestroyPipelineCache(GetRawDevice(), m_PipelineCache, nullptr); + VKLOG(Info, "PipelineCache Destroyed.. -- %0x.", m_PipelineCache); + m_PipelineCache = VK_NULL_HANDLE; + } + if (m_Pipeline) + { + vkDestroyPipeline(GetRawDevice(), m_Pipeline, nullptr); + VKLOG(Info, "PipelineStateObject Destroyed.. -- %0x.", m_Pipeline); + m_Pipeline = VK_NULL_HANDLE; + } +} + +PipelineLayout::PipelineLayout(Device::Ptr pDevice, rhi::PipelineLayoutDesc const & desc) + : PipelineLayout::ThisObj(pDevice) + , m_DescSetLayout(nullptr) + , m_DescSet() +{ + InitWithDesc(desc); +} + +PipelineLayout::~PipelineLayout() +{ + Destroy(); +} + +void PipelineLayout::Destroy() +{ + if (m_NativeObj == VK_NULL_HANDLE) + return; + vkDestroyPipelineLayout(NativeDevice(), m_NativeObj, nullptr); + VKLOG(Info, "PipelineLayout Destroyed . -- %0x.", m_NativeObj); + m_NativeObj = VK_NULL_HANDLE; +} + +uint64 BindingHash(Binding const& binding) +{ + return (uint64)(1 << (3 + binding.VarNumber)) | binding.VarStage; +} + +bool operator<(Binding const &lhs, Binding const &rhs) +{ + return rhs.VarStage < lhs.VarStage && rhs.VarNumber < lhs.VarNumber; +} + +BindingArray ExtractBindingsFromTable(::k3d::DynArray const& bindings) +{ + // merge image sampler + std::map bindingMap; + for (auto const & binding : bindings) + { + uint64 hash = BindingHash(binding); + if (bindingMap.find(hash) == bindingMap.end()) + { + bindingMap.insert({ hash, binding }); + } + else // binding slot override + { + auto & overrideBinding = bindingMap[hash]; + if (EBindType((uint32)overrideBinding.VarType | (uint32)binding.VarType) + == EBindType::ESamplerImageCombine) + { + overrideBinding.VarType = EBindType::ESamplerImageCombine; + } + } + } + + BindingArray array; + for (auto & p : bindingMap) + { + array.Append(RHIBinding2VkBinding(p.second)); + } + return array; +} + +void PipelineLayout::InitWithDesc(rhi::PipelineLayoutDesc const & desc) +{ + DescriptorAllocator::Options options; + BindingArray array = ExtractBindingsFromTable(desc.Bindings); + auto alloc = m_Device->NewDescriptorAllocator(16, array); + m_DescSetLayout = m_Device->NewDescriptorSetLayout(array); + m_DescSet = rhi::DescriptorRef(DescriptorSet::CreateDescSet(alloc, m_DescSetLayout->GetNativeHandle(), array, m_Device)); + + VkPipelineLayoutCreateInfo pPipelineLayoutCreateInfo = {}; + pPipelineLayoutCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; + pPipelineLayoutCreateInfo.pNext = NULL; + pPipelineLayoutCreateInfo.setLayoutCount = 1; + pPipelineLayoutCreateInfo.pSetLayouts = &m_DescSetLayout->m_DescriptorSetLayout; + K3D_VK_VERIFY(vkCreatePipelineLayout(NativeDevice(), &pPipelineLayoutCreateInfo, nullptr, &m_NativeObj)); } K3D_VK_END \ No newline at end of file diff --git a/Source/RHI/Vulkan/Private/VkRHI.cpp b/Source/RHI/Vulkan/Private/VkRHI.cpp index 5da4798..fc0e58a 100755 --- a/Source/RHI/Vulkan/Private/VkRHI.cpp +++ b/Source/RHI/Vulkan/Private/VkRHI.cpp @@ -20,225 +20,117 @@ namespace k3d namespace vk { -//void EnumAllDeviceAdapter(rhi::IDeviceAdapter** & adapterList, uint32* count) -//{ -// *count = (uint32)RHIRoot::GetPhysicDevices().size(); -// adapterList = new rhi::IDeviceAdapter*[*count]; -// for (size_t i = 0; i < *count; i++) -// { -// VkPhysicalDeviceProperties properties; -// vkGetPhysicalDeviceProperties(RHIRoot::GetPhysicDevices()[i], &properties); -// adapterList[i] = new DeviceAdapter(&(RHIRoot::GetPhysicDevices()[i])); -// VKLOG(Info, "DeviceName is %s, VendorId is %d.", properties.deviceName, properties.vendorID); -// } -//} +InstanceRef RHIRoot::s_InstanceRef; +DynArray RHIRoot::s_GpuRefs; +DynArray RHIRoot::s_DeviceRefs; +RenderViewportSp RHIRoot::s_Vp; -void EnumAndInitAllDeviceAdapter(rhi::IDeviceAdapter** & adapterList, uint32* count, bool debug) +void dFunc(void*) { - *count = (uint32)RHIRoot::GetPhysicDevices().size(); - adapterList = new rhi::IDeviceAdapter*[*count]; - for (size_t i = 0; i < *count; i++) + RHIRoot::Destroy(); +} + +void RHIRoot::Initialize(const char * appName, bool debug) +{ + // create instance + s_InstanceRef = InstanceRef(new vk::Instance(appName, appName, debug)); + s_GpuRefs = s_InstanceRef->EnumGpus(); + for (auto & gpu : s_GpuRefs) { - auto& gpu = RHIRoot::GetPhysicDevices()[i]; - VkPhysicalDeviceProperties properties = {}; - vkGetPhysicalDeviceProperties(gpu, &properties); - auto da = new DeviceAdapter(&gpu); - adapterList[i] = da; - auto dev = da->GetDevice(); - auto ret = dev->Create(da, debug); - K3D_ASSERT(ret == rhi::IDevice::DeviceFound); - VKLOG(Info, "DeviceName is %s, VendorId is %d.", properties.deviceName, properties.vendorID); + auto pDevice = new Device; + pDevice->Create(gpu->SharedFromThis(), s_InstanceRef->WithValidation()); + s_DeviceRefs.Append(rhi::DeviceRef( pDevice )); } } -std::vector RHIRoot::s_LayerProps; -std::vector RHIRoot::s_LayerNames; -RenderViewport * RHIRoot::s_Vp = nullptr; -VkInstance RHIRoot::Instance; -RHIRoot::DeviceList RHIRoot::PhysicalDevices; - -void RHIRoot::Initialize(const char * appName, bool debug) +void RHIRoot::Destroy() { - vkCreateInstance = reinterpret_cast(dynlib::GetVulkanLib().ResolveEntry("vkCreateInstance")); - vkDestroyInstance = reinterpret_cast(dynlib::GetVulkanLib().ResolveEntry("vkDestroyInstance")); - vkEnumeratePhysicalDevices = reinterpret_cast(dynlib::GetVulkanLib().ResolveEntry("vkEnumeratePhysicalDevices")); - vkEnumerateInstanceLayerProperties = (PFN_vkEnumerateInstanceLayerProperties)dynlib::GetVulkanLib().ResolveEntry("vkEnumerateInstanceLayerProperties"); - vkEnumerateInstanceExtensionProperties = (PFN_vkEnumerateInstanceExtensionProperties)dynlib::GetVulkanLib().ResolveEntry("vkEnumerateInstanceExtensionProperties"); - vkGetPhysicalDeviceProperties = (PFN_vkGetPhysicalDeviceProperties)dynlib::GetVulkanLib().ResolveEntry("vkGetPhysicalDeviceProperties"); - vkGetPhysicalDeviceMemoryProperties = (PFN_vkGetPhysicalDeviceMemoryProperties)dynlib::GetVulkanLib().ResolveEntry("vkGetPhysicalDeviceMemoryProperties"); - vkGetPhysicalDeviceQueueFamilyProperties = (PFN_vkGetPhysicalDeviceQueueFamilyProperties)dynlib::GetVulkanLib().ResolveEntry("vkGetPhysicalDeviceQueueFamilyProperties"); - vkCreateDevice = (PFN_vkCreateDevice)dynlib::GetVulkanLib().ResolveEntry("vkCreateDevice"); - - EnumLayers(); + VKLOG(Info, "RHIRoot::Destroy"); +} - VkResult err = CreateInstance(debug, appName); - if (err == VK_ERROR_INCOMPATIBLE_DRIVER) { - VKLOG(Error, "Cannot find a compatible Vulkan installable client driver: vkCreateInstance Failure"); - } - else if (err == VK_ERROR_EXTENSION_NOT_PRESENT) { - VKLOG(Error, "Cannot find a specified extension library: vkCreateInstance Failure"); - } - else { - K3D_VK_VERIFY(err); +void RHIRoot::SetupDebug(VkDebugReportFlagsEXT flags, PFN_vkDebugReportCallbackEXT callBack) +{ + if (s_InstanceRef) + { + s_InstanceRef->SetupDebugging(flags, callBack); } +} - uint32_t gpuCount = 0; - K3D_VK_VERIFY(vkEnumeratePhysicalDevices(Instance, &gpuCount, nullptr)); - VKLOG(Info, "RHIRoot::Initializer Device Count : %u .", gpuCount); - std::vector deviceList(gpuCount); - err = vkEnumeratePhysicalDevices(Instance, &gpuCount, deviceList.data()); - VkPhysicalDeviceProperties physicalDeviceProperties = {}; - vkGetPhysicalDeviceProperties(deviceList[0], &physicalDeviceProperties); - VKLOG(Info, "Vulkan First Device: %s", physicalDeviceProperties.deviceName); - PhysicalDevices.swap(deviceList); +uint32 RHIRoot::GetHostGpuCount() +{ + return s_GpuRefs.Count(); +} +GpuRef RHIRoot::GetHostGpuById(uint32 id) +{ + return s_GpuRefs[id]; } -void RHIRoot::Destroy() +VkInstance RHIRoot::GetInstance() { -#if _DEBUG - FreeDebugCallback(Instance); -#endif - vkDestroyInstance(Instance, nullptr); - VKLOG(Info, "RHIRoot: Destroy Instance."); + return s_InstanceRef ? s_InstanceRef->m_Instance : VK_NULL_HANDLE; } -void RHIRoot::AddViewport(RenderViewport * vp) +rhi::DeviceRef RHIRoot::GetDeviceById(uint32 id) +{ + return s_DeviceRefs[id]; +} + +void RHIRoot::AddViewport(RenderViewportSp vp) { s_Vp = vp; } -RenderViewport * RHIRoot::GetViewport(int index) +RenderViewportSp +RHIRoot::GetViewport(int index) { return s_Vp; } -void RHIRoot::EnumLayers() +void RHIRoot::EnumLayersAndExts() { + // Enum Layers uint32 layerCount = 0; K3D_VK_VERIFY(vkEnumerateInstanceLayerProperties(&layerCount, nullptr)); - if(layerCount>0) - { - s_LayerProps.resize(layerCount); - K3D_VK_VERIFY(vkEnumerateInstanceLayerProperties(&layerCount, s_LayerProps.data())); - } - VKLOG(Info, "layerCount = %d. ", layerCount); -} - -VkResult RHIRoot::CreateInstance(bool enableValidation, std::string name) -{ -#if K3DPLATFORM_OS_WIN -#define PLATFORM_SURFACE_EXT VK_KHR_WIN32_SURFACE_EXTENSION_NAME -#elif defined(K3DPLATFORM_OS_LINUX) && !defined(K3DPLATFORM_OS_ANDROID) -#define PLATFORM_SURFACE_EXT VK_KHR_XCB_SURFACE_EXTENSION_NAME -#elif defined(K3DPLATFORM_OS_ANDROID) -#define PLATFORM_SURFACE_EXT VK_KHR_ANDROID_SURFACE_EXTENSION_NAME -#endif - uint32_t instanceExtensionCount = 0; - K3D_VK_VERIFY(vkEnumerateInstanceExtensionProperties(nullptr, &instanceExtensionCount, nullptr)); - VKLOG(Info, "extension num : %d.", instanceExtensionCount); - VkBool32 surfaceExtFound = 0; - VkBool32 platformSurfaceExtFound = 0; - VkExtensionProperties* instanceExtensions = new VkExtensionProperties[instanceExtensionCount]; - K3D_VK_VERIFY(vkEnumerateInstanceExtensionProperties(nullptr, &instanceExtensionCount, instanceExtensions)); - std::vector enabledExtensions; - for (uint32_t i = 0; i < instanceExtensionCount; i++) { - if (!strcmp(VK_KHR_SURFACE_EXTENSION_NAME, instanceExtensions[i].extensionName)) - { - surfaceExtFound = 1; - enabledExtensions.push_back( VK_KHR_SURFACE_EXTENSION_NAME ); - } - if (!strcmp(PLATFORM_SURFACE_EXT, instanceExtensions[i].extensionName)) - { - platformSurfaceExtFound = 1; - enabledExtensions.push_back( PLATFORM_SURFACE_EXT ); - } - if (enableValidation) - { - enabledExtensions.push_back( VK_EXT_DEBUG_REPORT_EXTENSION_NAME ); - } - VKLOG(Info, "available extension : %s .", instanceExtensions[i].extensionName); - } - if (!surfaceExtFound) - { - VKLOG(Error, "vkEnumerateInstanceExtensionProperties failed to find the " VK_KHR_SURFACE_EXTENSION_NAME" extension."); - } - if (!platformSurfaceExtFound) + if(layerCount > 0) { - VKLOG(Error, "vkEnumerateInstanceExtensionProperties failed to find the " PLATFORM_SURFACE_EXT " extension."); + gVkLayerProps.Resize(layerCount); + K3D_VK_VERIFY(vkEnumerateInstanceLayerProperties(&layerCount, gVkLayerProps.Data())); } - VkApplicationInfo appInfo = {}; - appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO; - appInfo.pApplicationName = name.c_str(); - appInfo.pEngineName = name.c_str(); - appInfo.apiVersion = VK_MAKE_VERSION(1,0,1); - appInfo.engineVersion = 1; - appInfo.applicationVersion = 0; - - VkInstanceCreateInfo instanceCreateInfo = {}; - instanceCreateInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; - instanceCreateInfo.pNext = NULL; - instanceCreateInfo.pApplicationInfo = &appInfo; - instanceCreateInfo.enabledExtensionCount = (uint32_t)enabledExtensions.size(); - instanceCreateInfo.ppEnabledExtensionNames = enabledExtensions.data(); - if (enableValidation && !s_LayerProps.empty()) + // Enum Extensions + uint32 extCount = 0; + K3D_VK_VERIFY(vkEnumerateInstanceExtensionProperties(nullptr, &extCount, nullptr)); + if (extCount > 0) { - for (auto prop : s_LayerProps) - { - if (strcmp(prop.layerName, g_ValidationLayerNames[0]) == 0 /*|| strcmp(prop.layerName, g_ValidationLayerNames[1])==0*/) - { - s_LayerNames.push_back(prop.layerName); - instanceCreateInfo.enabledLayerCount = s_LayerNames.size(); - instanceCreateInfo.ppEnabledLayerNames = s_LayerNames.data(); - VKLOG(Info, "enable validation layer [%s].", prop.layerName); - break; - } - } + gVkExtProps.Resize(extCount); + K3D_VK_VERIFY(vkEnumerateInstanceExtensionProperties(nullptr, &extCount, gVkExtProps.Data())); } - return vkCreateInstance(&instanceCreateInfo, nullptr, &Instance); -} - -// Macro to get a procedure address based on a vulkan instance -#define GET_INSTANCE_PROC_ADDR(inst, entrypoint) \ -{ \ - fp##entrypoint = (PFN_vk##entrypoint) vkGetInstanceProcAddr(inst, "vk"#entrypoint); \ - if (fp##entrypoint == NULL) \ - { \ - exit(1); \ - } \ + VKLOG(Info, ">> RHIRoot::EnumLayersAndExts <<\n\n" + "=================================>> layerCount = %d.\n" + "=================================>> extensionCount = %d.\n", layerCount, extCount); } -// Macro to get a procedure address based on a vulkan device -#define GET_DEVICE_PROC_ADDR(dev, entrypoint) \ -{ \ - fp##entrypoint = (PFN_vk##entrypoint) vkGetDeviceProcAddr(dev, "vk"#entrypoint); \ - if (fp##entrypoint == NULL) \ - { \ - exit(1); \ - } \ -} +} // End NS -- vk -void SwapChain::InitProcs() -{ - GET_INSTANCE_PROC_ADDR(RHIRoot::GetInstance(), GetPhysicalDeviceSurfaceSupportKHR); - GET_INSTANCE_PROC_ADDR(RHIRoot::GetInstance(), GetPhysicalDeviceSurfaceCapabilitiesKHR); - GET_INSTANCE_PROC_ADDR(RHIRoot::GetInstance(), GetPhysicalDeviceSurfaceFormatsKHR); - GET_INSTANCE_PROC_ADDR(RHIRoot::GetInstance(), GetPhysicalDeviceSurfacePresentModesKHR); - GET_DEVICE_PROC_ADDR(GetRawDevice(), CreateSwapchainKHR); - GET_DEVICE_PROC_ADDR(GetRawDevice(), DestroySwapchainKHR); - GET_DEVICE_PROC_ADDR(GetRawDevice(), GetSwapchainImagesKHR); - GET_DEVICE_PROC_ADDR(GetRawDevice(), AcquireNextImageKHR); - GET_DEVICE_PROC_ADDR(GetRawDevice(), QueuePresentKHR); -} -} // End NS -- vk +#ifdef K3DPLATFORM_OS_WIN +static const char* LIBVULKAN = "vulkan-1.dll"; +#elif defined(K3DPLATFORM_OS_MAC) +static const char* LIBVULKAN = "libvulkan.dylib"; +#else +static const char* LIBVULKAN = "libvulkan.so"; +#endif class VkRHI : public IVkRHI { public: - VkRHI() {} - ~VkRHI() override {} + VkRHI()/* : m_VkLib(LIBVULKAN) */{} + ~VkRHI() override + { + VKLOG(Info, "Destroying.."); + Shutdown(); + } void Initialize(const char* appName, bool debug) override { @@ -252,20 +144,14 @@ class VkRHI : public IVkRHI rhi::DeviceRef GetPrimaryDevice() override { - if (!m_pMainDevice && m_ppAdapters && GetDeviceCount() > 0) - { - m_pMainDevice = m_ppAdapters[0]->GetDevice(); - } - return m_pMainDevice; + return GetDeviceById(0); } uint32 GetDeviceCount() override { return m_DeviceCount; } rhi::DeviceRef GetDeviceById(uint32 id) override { - if (!m_ppAdapters || id >= m_DeviceCount) - return nullptr; - return m_ppAdapters[id]->GetDevice(); + return vk::RHIRoot::GetDeviceById(id); } void Destroy() override @@ -280,22 +166,21 @@ class VkRHI : public IVkRHI VKLOG(Fatal, "RHI Module uninitialized!! You should call Initialize first!"); return; } - k3d::vk::EnumAndInitAllDeviceAdapter(m_ppAdapters, &m_DeviceCount, m_ConfigDebug); } void Shutdown() override { + KLOG(Info, VKRHI, "Shuting down..."); Destroy(); } const char * Name() { return "RHI_Vulkan"; } private: + //dynlib::Lib m_VkLib; bool m_IsInitialized = false; uint32 m_DeviceCount = 0; - rhi::IDeviceAdapter ** m_ppAdapters = nullptr; - rhi::DeviceRef m_pMainDevice = nullptr; bool m_ConfigDebug = false; }; diff --git a/Source/RHI/Vulkan/Private/VkRHI.h b/Source/RHI/Vulkan/Private/VkRHI.h index b493f6b..ce1b626 100755 --- a/Source/RHI/Vulkan/Private/VkRHI.h +++ b/Source/RHI/Vulkan/Private/VkRHI.h @@ -23,6 +23,7 @@ namespace k3d K3D_VK_BEGIN class Device; +using VkDeviceRef = SharedPtr; using RefDevice = std::shared_ptr; class ResourceManager; @@ -73,58 +74,67 @@ class Sampler; class ShaderResourceView; using BindingArray = DynArray; -//extern K3D_API void EnumAllDeviceAdapter(rhi::IDeviceAdapter** &, uint32*); -extern K3D_API void EnumAndInitAllDeviceAdapter(rhi::IDeviceAdapter** &, uint32*, bool debug); +class DescriptorAllocator; +using DescriptorAllocRef = SharedPtr; + +class DescriptorSetLayout; +using DescriptorSetLayoutRef = SharedPtr; + +class DescriptorSet; +using DescriptorSetRef = SharedPtr; + +class RenderViewport; +using RenderViewportSp = SharedPtr; + +typedef std::map MapPipelineLayout; +typedef std::unordered_map MapDescriptorSetLayout; +typedef std::unordered_map MapDescriptorAlloc; struct RHIRoot { - using DeviceList = std::vector; - static void Initialize(const char* appName, bool debug); static void Destroy(); + static void SetupDebug(VkDebugReportFlagsEXT flags, PFN_vkDebugReportCallbackEXT callBack); + static uint32 GetHostGpuCount(); + static GpuRef GetHostGpuById(uint32 id); + static VkInstance GetInstance(); - static DeviceList& GetPhysicDevices() { return PhysicalDevices; } - static VkInstance& GetInstance() { return Instance; } - - static void AddViewport(RenderViewport *); - static RenderViewport * GetViewport(int index); - - using LayerNames = std::vector; - static LayerNames s_LayerNames; + static rhi::DeviceRef GetDeviceById(uint32 id); + static void AddViewport(RenderViewportSp); + static RenderViewportSp GetViewport(int index); private: - static RenderViewport* s_Vp; - using LayerProps = std::vector; + static InstanceRef s_InstanceRef; + static DynArray s_GpuRefs; + static DynArray s_DeviceRefs; + static RenderViewportSp s_Vp; - static void EnumLayers(); - static VkResult CreateInstance(bool enableValidation, std::string name); - - static LayerProps s_LayerProps; - static VkInstance Instance; - static DeviceList PhysicalDevices; - friend class Device; -}; - -class DeviceAdapter : public rhi::IDeviceAdapter -{ - friend class Device; -public: - explicit DeviceAdapter(VkPhysicalDevice * pDevice) : m_pGpu(pDevice) {} - rhi::DeviceRef GetDevice() override; -private: - friend K3D_API void EnumAndInitAllDeviceAdapter(rhi::IDeviceAdapter** &, uint32*, bool debug); - VkPhysicalDevice * m_pGpu = nullptr; - rhi::DeviceRef m_pDevice; + static void EnumLayersAndExts(); + friend class Device; }; -class Device : public rhi::IDevice +//class DeviceAdapter : public rhi::IDeviceAdapter +//{ +// friend class Device; +//public: +// typedef SharedPtr Ptr; +// explicit DeviceAdapter(GpuRef const& gpu); +// ~DeviceAdapter() override; +// rhi::DeviceRef GetDevice() override; +//private: +// GpuRef m_Gpu; +// rhi::DeviceRef m_pDevice; +//}; + +class Device : public rhi::IDevice, public k3d::EnableSharedFromThis { public: - typedef Device * Ptr; + typedef k3d::SharedPtr Ptr; Device(); ~Device() override; Result Create(rhi::IDeviceAdapter *, bool withDebug) override; + Result Create(GpuRef const& gpu, bool withDebug); void Destroy(); rhi::CommandContextRef NewCommandContext(rhi::ECommandType)override; @@ -134,8 +144,8 @@ class Device : public rhi::IDevice rhi::PipelineLayoutRef NewPipelineLayout(rhi::PipelineLayoutDesc const & table) override; - DescriptorAllocator* NewDescriptorAllocator(uint32 maxSets, BindingArray const& bindings); - DescriptorSetLayout* NewDescriptorSetLayout(BindingArray const& bindings); + DescriptorAllocRef NewDescriptorAllocator(uint32 maxSets, BindingArray const& bindings); + DescriptorSetLayoutRef NewDescriptorSetLayout(BindingArray const& bindings); rhi::PipelineStateObjectRef NewPipelineState(rhi::PipelineDesc const & desc, rhi::PipelineLayoutRef ppl,rhi::EPipelineType)override; rhi::PipelineStateObjectRef CreatePipelineStateObject(rhi::PipelineDesc const & desc, rhi::PipelineLayoutRef ppl); @@ -143,23 +153,20 @@ class Device : public rhi::IDevice rhi::SyncFenceRef NewFence()override; rhi::IDescriptorPool * NewDescriptorPool() override; rhi::RenderViewportRef NewRenderViewport(void * winHandle, rhi::GfxSetting&) override; - void QueryTextureSubResourceLayout(rhi::GpuResourceRef, rhi::TextureResourceSpec const& spec, rhi::SubResourceLayout *) override; + void QueryTextureSubResourceLayout(rhi::TextureRef, rhi::TextureResourceSpec const& spec, rhi::SubResourceLayout *) override; SwapChainRef NewSwapChain(rhi::GfxSetting const& setting); - //VkQueue const& GetRawDeviceQueue() const { return m_DefaultQueue; } SpCmdQueue const& GetDefaultCmdQueue() const { return m_DefCmdQueue; } VkDevice const& GetRawDevice() const { return m_Device; } - VkPhysicalDevice const* GetGpuRef() const { return m_pGpu; } - PtrResManager const & GetMemoryManager() const { return m_ResourceManager; } + //PtrResManager const & GetMemoryManager() const { return m_ResourceManager; } PtrCmdAlloc NewCommandAllocator(bool transient); + bool FindMemoryType(uint32 typeBits, VkFlags requirementsMask, uint32 *typeIndex) const; PtrSemaphore NewSemaphore(); void WaitIdle() override { vkDeviceWaitIdle(m_Device); } - bool FindMemoryType(uint32_t typeBits, VkFlags requirementsMask, uint32 *typeIndex) const; - - uint32 GetQueueCount() const { return m_QueueCount; } + uint32 GetQueueCount() const { return m_Gpu->m_QueueProps.Count(); } SpRenderpass const & GetTopPass() const { return m_PendingPass.back(); } void PushRenderPass(SpRenderpass renderPass) { m_PendingPass.push_back(renderPass); } @@ -172,46 +179,33 @@ class Device : public rhi::IDevice SpCmdQueue InitCmdQueue(VkQueueFlags queueTypes, uint32 queueFamilyIndex, uint32 queueIndex); private: - - VkResult CreateDevice(VkPhysicalDevice gpu, bool withDebug, VkDevice * pDevice); - bool GetDeviceQueueProps(VkPhysicalDevice gpu); - - typedef std::map CachePipelineLayout; - - PtrResManager m_ResourceManager; - std::unique_ptr m_ContextPool; + CmdBufManagerRef m_CmdBufManager; + //PtrResManager m_ResourceManager; + //std::unique_ptr m_ContextPool; std::vector m_PendingPass; - CachePipelineLayout m_CachedPipelineLayout; - std::map m_CachedDescriptorPool; - std::map m_CachedDescriptorSetLayout; + //MapPipelineLayout m_CachedPipelineLayout; + //MapDescriptorAlloc m_CachedDescriptorPool; + //MapDescriptorSetLayout m_CachedDescriptorSetLayout; private: - // following is init params - std::vector queueProps; - VkPhysicalDeviceMemoryProperties m_MemoryProperties = {}; - VkPhysicalDeviceProperties m_PhysicalDeviceProperties = {}; + SpCmdQueue m_DefCmdQueue; SpCmdQueue m_ComputeCmdQueue; VkDevice m_Device = VK_NULL_HANDLE; - VkPhysicalDevice * m_pGpu = nullptr; - uint32 m_GraphicsQueueIndex = 0; - uint32 m_ComputeQueueIndex = 0; - uint32 m_CopyQueueIndex = 0; - uint32 m_QueueCount = 0; + GpuRef m_Gpu; }; class DeviceChild { public: - explicit DeviceChild(Device *pDevice) : m_pDevice(pDevice) {} - virtual ~DeviceChild() {} + explicit DeviceChild(Device::Ptr pDevice) : m_pDevice(pDevice) {} + virtual ~DeviceChild() { } VkDevice const & GetRawDevice() const { return m_pDevice->GetRawDevice(); } - VkPhysicalDevice const & GetPhysicalDevice() const { return *(m_pDevice->GetGpuRef()); } - //VkQueue const & GetRawQueue() const { return m_pDevice->GetRawDeviceQueue(); } + GpuRef GetGpuRef() const { return m_pDevice->m_Gpu; } Device::Ptr const GetDevice() const { return m_pDevice; } SpCmdQueue const& GetImmCmdQueue() const { return m_pDevice->GetDefaultCmdQueue(); } @@ -220,6 +214,25 @@ class DeviceChild Device::Ptr m_pDevice; }; +template +class TVkRHIObjectBase : public RHIRoot, public TRHIObj +{ +public: + using ThisObj = TVkRHIObjectBase; + + explicit TVkRHIObjectBase(VkDeviceRef const& refDevice) + : m_Device(refDevice), m_NativeObj(VK_NULL_HANDLE) {} + + virtual ~TVkRHIObjectBase() {} + + TVkObj NativeHandle() const { return m_NativeObj; } + VkDevice NativeDevice() const { return m_Device->GetRawDevice(); } + +protected: + SharedPtr m_Device; + TVkObj m_NativeObj; +}; + #define DEVICE_CHILD_CONSTRUCT(className) \ explicit className(Device::Ptr ptr) : DeviceChild(ptr) {} #define DEVICE_CHILD_CONSTRUCT_DECLARE(className) \ @@ -228,37 +241,57 @@ class DeviceChild /** * Fences are signaled by the system when work invoked by vkQueueSubmit completes. */ -class Fence : public rhi::ISyncFence, public DeviceChild +class Fence : public TVkRHIObjectBase { public: Fence(Device::Ptr pDevice, VkFenceCreateInfo const & info = FenceCreateInfo::Create()) - : DeviceChild(pDevice) + : ThisObj(pDevice) { if (pDevice) { - K3D_VK_VERIFY(vkCreateFence(GetRawDevice(), &info, nullptr, &m_Fence)); + K3D_VK_VERIFY(vkCreateFence(NativeDevice(), &info, nullptr, &m_NativeObj)); } } - ~Fence() override { vkDestroyFence(GetRawDevice(), m_Fence, nullptr); } + ~Fence() override + { + if (m_NativeObj) + { + vkDestroyFence(NativeDevice(), m_NativeObj, nullptr); + VKLOG(Info, "Fence Destroyed. -- %0x.", m_NativeObj); + m_NativeObj = VK_NULL_HANDLE; + } + } void Signal(int32 val) override {} bool IsSignaled() { - return VK_SUCCESS==vkGetFenceStatus(GetRawDevice(), m_Fence); + return VK_SUCCESS== vkGetFenceStatus(NativeDevice(), m_NativeObj); } - void Reset() override { vkResetFences(GetRawDevice(), 1, &m_Fence); } + void Reset() override { vkResetFences(NativeDevice(), 1, &m_NativeObj); } + void WaitFor(uint64 time) override { - vkWaitForFences(GetRawDevice(), 1, &m_Fence, VK_TRUE, time); + vkWaitForFences(NativeDevice(), 1, &m_NativeObj, VK_TRUE, time); } + private: friend class SwapChain; friend class CommandContext; +}; + +class Sampler : public TVkRHIObjectBase +{ +public: + explicit Sampler(Device::Ptr pDevice, rhi::SamplerState const & sampleDesc); + ~Sampler() override; + rhi::SamplerState GetSamplerDesc() const; - VkFence m_Fence = VK_NULL_HANDLE; +protected: + VkSamplerCreateInfo m_SamplerCreateInfo = {}; + rhi::SamplerState m_SamplerState; }; /** @@ -318,16 +351,18 @@ class DescriptorSetLayout : public DeviceChild class DescriptorSet : public DeviceChild, public rhi::IDescriptor { public: - static DescriptorSet* CreateDescSet(DescriptorAllocator *descriptorPool, VkDescriptorSetLayout layout, BindingArray const & bindings, Device::Ptr pDevice); + static DescriptorSet* CreateDescSet(DescriptorAllocRef descriptorPool, VkDescriptorSetLayout layout, BindingArray const & bindings, Device::Ptr pDevice); virtual ~DescriptorSet(); + void Update(uint32 bindSet, rhi::SamplerRef) override; void Update(uint32 bindSet, rhi::GpuResourceRef) override; + uint32 GetSlotNum() const override; VkDescriptorSet GetNativeHandle() const { return m_DescriptorSet; } private: - DescriptorSet( DescriptorAllocator *descriptorPool, VkDescriptorSetLayout layout, BindingArray const & bindings, Device::Ptr pDevice ); + DescriptorSet( DescriptorAllocRef descriptorPool, VkDescriptorSetLayout layout, BindingArray const & bindings, Device::Ptr pDevice ); VkDescriptorSet m_DescriptorSet = VK_NULL_HANDLE; - DescriptorAllocator* m_DescriptorAllocator = nullptr; + DescriptorAllocRef m_DescriptorAllocator = nullptr; BindingArray m_Bindings; std::vector m_BoundDescriptorSet; @@ -335,7 +370,6 @@ class DescriptorSet : public DeviceChild, public rhi::IDescriptor void Destroy(); }; - class Resource : virtual public rhi::IGpuResource, public DeviceChild { public: @@ -350,9 +384,9 @@ class Resource : virtual public rhi::IGpuResource, public DeviceChild VkDeviceMemory GetDeviceMemory() const { return m_DeviceMem; } Resource::Ptr Map(uint64 offset, uint64 size) override; - void UnMap() override { vkUnmapMemory(GetRawDevice(), m_DeviceMem); } - uint64 GetResourceSize() const override { return m_Size; } - rhi::ResourceDesc GetResourceDesc() const override { return m_Desc; } + void UnMap() override { vkUnmapMemory(GetRawDevice(), m_DeviceMem); } + uint64 GetSize() const override { return m_Size; } + rhi::ResourceDesc GetDesc() const override { return m_Desc; } protected: VkMemoryAllocateInfo m_MemAllocInfo; @@ -366,32 +400,124 @@ class Resource : virtual public rhi::IGpuResource, public DeviceChild rhi::ResourceDesc m_Desc; }; -class Buffer : public Resource +template +class TResource : public TVkRHIObjectBase +{ +public: + using ThisResourceType = TResource; + using TVkRHIObjectBase::m_NativeObj; + using TVkRHIObjectBase::NativeDevice; + using TVkRHIObjectBase::m_Device; + + explicit TResource(VkDeviceRef const & refDevice) + : TVkRHIObjectBase(refDevice) + , m_MemAllocInfo{} + , m_HostMemAddr(nullptr) + , m_DeviceMem{ VK_NULL_HANDLE } + , m_ResView(VK_NULL_HANDLE) + , m_ResDesc{} + {} + + TResource(VkDeviceRef const & refDevice, rhi::ResourceDesc const &desc) + : TVkRHIObjectBase(refDevice) + , m_MemAllocInfo{} + , m_HostMemAddr(nullptr) + , m_DeviceMem{} + , m_ResView(VK_NULL_HANDLE) + , m_ResDesc(desc) + {} + + virtual ~TResource() + { + if (VK_NULL_HANDLE != m_ResView) + { + ResTrait::DestroyView(NativeDevice(), m_ResView, nullptr); + VKLOG(Info, "TResourceView Destroying.. -- %p.", m_ResView); + m_ResView = VK_NULL_HANDLE; + } + if (VK_NULL_HANDLE != m_NativeObj) + { + VKLOG(Info, "TResource Destroying.. -- %p.", m_NativeObj); + ResTrait::Destroy(NativeDevice(), m_NativeObj, nullptr); + m_NativeObj = VK_NULL_HANDLE; + } + if (VK_NULL_HANDLE != m_DeviceMem) + { + VKLOG(Info, "TResource Freeing Memory. -- 0x%0x, tid:%d", m_DeviceMem, Os::Thread::GetId()); + vkFreeMemory(NativeDevice(), m_DeviceMem, nullptr); + m_DeviceMem = VK_NULL_HANDLE; + } + } + + void* Map(uint64 offset, uint64 size) + { + K3D_VK_VERIFY(vkMapMemory(NativeDevice(), m_DeviceMem, offset, size, 0, &m_HostMemAddr)); + return m_HostMemAddr; + } + + void UnMap() + { + vkUnmapMemory(NativeDevice(), m_DeviceMem); + } + +protected: + typedef typename ResTrait::CreateInfo CreateInfo; + typedef typename ResTrait::View ResourceView; + typedef typename ResTrait::DescriptorInfo ResourceDescriptorInfo; + typedef typename ResTrait::UsageFlags ResourceUsageFlags; + + VkMemoryAllocateInfo m_MemAllocInfo; + VkMemoryRequirements m_MemReq; + VkDeviceMemory m_DeviceMem; + VkMemoryPropertyFlags m_MemoryBits = 0; + void* m_HostMemAddr; + ResourceView m_ResView; + ResourceUsageFlags m_ResUsageFlags = 0; + ResourceDescriptorInfo m_ResDescInfo{}; + rhi::ResourceDesc m_ResDesc; + +protected: + + void Allocate(CreateInfo const& info) + { + K3D_VK_VERIFY(ResTrait::Create(NativeDevice(), &info, nullptr, &m_NativeObj)); + m_MemAllocInfo = {}; + m_MemAllocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; + ResTrait::GetMemoryInfo(NativeDevice(), m_NativeObj, &m_MemReq); + + m_MemAllocInfo.allocationSize = m_MemReq.size; + m_Device->FindMemoryType(m_MemReq.memoryTypeBits, m_MemoryBits, &m_MemAllocInfo.memoryTypeIndex); + K3D_VK_VERIFY(vkAllocateMemory(NativeDevice(), &m_MemAllocInfo, nullptr, &m_DeviceMem)); + m_MemAllocInfo.allocationSize; + + /*K3D_VK_VERIFY(vkBindBufferMemory(NativeDevice(), m_Buffer, m_DeviceMem, m_AllocationOffset));*/ + } +}; + +class Buffer : public TResource { public: typedef Buffer * Ptr; - explicit Buffer(Device::Ptr pDevice) : Resource(pDevice) {} + explicit Buffer(Device::Ptr pDevice) : ThisResourceType(pDevice) {} Buffer(Device::Ptr pDevice, rhi::ResourceDesc const & desc); virtual ~Buffer(); void Create(size_t size); - uint64 GetResourceLocation() const override { return (uint64)m_Buffer; } - rhi::EGpuResourceType GetResourceType() const override { return rhi::EGT_Buffer; } -private: - VkDescriptorBufferInfo m_BufferInfo; - VkBufferView m_BufferView = VK_NULL_HANDLE; - VkBuffer m_Buffer = VK_NULL_HANDLE; - VkBufferUsageFlags m_Usage = 0; - VkMemoryPropertyFlags m_MemoryBits = 0; + uint64 GetLocation() const override { return (uint64)m_NativeObj; } + uint64 GetSize() const override { return m_MemAllocInfo.allocationSize; } + rhi::ResourceDesc GetDesc() const override { return m_ResDesc; } + + void* Map(uint64 offset, uint64 size) override { return ThisResourceType::Map(offset, size); } + void UnMap() override { return ThisResourceType::UnMap(); } }; -class Texture : public rhi::ITexture, public Resource +class Texture : public TResource { public: typedef ::k3d::SharedPtr TextureRef; - explicit Texture(Device::Ptr pDevice) : Resource(pDevice) {} + explicit Texture(Device::Ptr pDevice) : ThisResourceType(pDevice) {} Texture(Device::Ptr pDevice, rhi::ResourceDesc const&); Texture(VkImage image, VkImageView imageView, VkImageViewCreateInfo info, Device::Ptr pDevice, bool selfOwnShip = true); ~Texture() override; @@ -399,13 +525,17 @@ class Texture : public rhi::ITexture, public Resource static TextureRef CreateFromSwapChain(VkImage image, VkImageView view, VkImageViewCreateInfo info, Device::Ptr pDevice); const VkImageViewCreateInfo&GetViewInfo() const { return m_ImageViewInfo; } - const VkImageView & GetView() const { return m_ImageView; } - const VkImage& Get() const { return m_Image; } + const VkImageView & GetView() const { return m_ResView; } + const VkImage& Get() const { return m_NativeObj; } VkImageLayout GetImageLayout() const { return m_ImageLayout; } VkImageSubresourceRange GetSubResourceRange() const { return m_SubResRange; } - uint64 GetResourceLocation() const override { return (uint64)m_Image; } - rhi::EResourceState GetUsageState() const override { return m_UsageState; } + uint64 GetLocation() const override { return (uint64)m_NativeObj; } + uint64 GetSize() const override { return m_MemAllocInfo.allocationSize; } + rhi::EResourceState GetState() const override { return m_UsageState; } + rhi::ResourceDesc GetDesc() const override { return m_ResDesc; } + void* Map(uint64 offset, uint64 size) override { return ThisResourceType::Map(offset, size); } + void UnMap() override { return ThisResourceType::UnMap(); } void BindSampler(rhi::SamplerRef sampler) override; rhi::SamplerCRef GetSampler() const override; @@ -431,14 +561,13 @@ class Texture : public rhi::ITexture, public Resource ::k3d::SharedPtr m_ImageSampler; VkImageViewCreateInfo m_ImageViewInfo = {}; rhi::ShaderResourceViewRef m_SRV; - VkImageView m_ImageView = VK_NULL_HANDLE; + //VkImageView m_ImageView = VK_NULL_HANDLE; ImageInfo m_ImageInfo; - VkImage m_Image = VK_NULL_HANDLE; + //VkImage m_Image = VK_NULL_HANDLE; rhi::EResourceState m_UsageState = rhi::ERS_Unknown; VkImageLayout m_ImageLayout = VK_IMAGE_LAYOUT_UNDEFINED; VkImageMemoryBarrier m_Barrier; - VkImageUsageFlags m_ImageUsage = 0; - VkMemoryPropertyFlags m_MemoryBits = 0; + VkSubresourceLayout m_SubResourceLayout = {}; VkImageSubresourceRange m_SubResRange = {}; bool m_SelfOwn = true; @@ -536,7 +665,7 @@ class CommandContextPool : public DeviceChild CommandContextPool(Device::Ptr pDevice); ~CommandContextPool() override; - CommandContext* RequestContext(rhi::ECommandType type); + rhi::CommandContextRef RequestContext(rhi::ECommandType type); PtrCmdAlloc RequestCommandAllocator(); @@ -656,7 +785,7 @@ class CommandContext : public rhi::ICommandContext, public DeviceChild protected: VkCommandBuffer m_CommandBuffer; - VkCommandPool m_CommandPool; + //VkCommandPool m_CommandPool; VkRenderPass m_RenderPass; bool m_IsRenderPassActive = false; RenderTarget* m_CurrentRenderTarget = nullptr; @@ -665,10 +794,10 @@ class CommandContext : public rhi::ICommandContext, public DeviceChild void InitCommandBufferPool(); }; -class CommandQueue : public DeviceChild +class CommandQueue { public: - CommandQueue(Device::Ptr pDevice, VkQueueFlags queueTypes, uint32 queueFamilyIndex, uint32 queueIndex); + CommandQueue(VkDevice pDevice, VkQueueFlags queueTypes, uint32 queueFamilyIndex, uint32 queueIndex); virtual ~CommandQueue(); void Submit( @@ -689,6 +818,7 @@ class CommandQueue : public DeviceChild void Destroy(); private: + VkDevice m_Device = VK_NULL_HANDLE; VkQueue m_Queue = VK_NULL_HANDLE; VkQueueFlags m_QueueTypes = 0; uint32 m_QueueFamilyIndex = UINT32_MAX; @@ -736,21 +866,7 @@ class SwapChain : public DeviceChild VkFormat m_ColorAttachFmt = VK_FORMAT_UNDEFINED; private: - - void InitProcs(); - void Destroy(); - - /** private functions */ - PFN_vkGetPhysicalDeviceSurfaceSupportKHR fpGetPhysicalDeviceSurfaceSupportKHR; - PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR fpGetPhysicalDeviceSurfaceCapabilitiesKHR; - PFN_vkGetPhysicalDeviceSurfaceFormatsKHR fpGetPhysicalDeviceSurfaceFormatsKHR; - PFN_vkGetPhysicalDeviceSurfacePresentModesKHR fpGetPhysicalDeviceSurfacePresentModesKHR; - PFN_vkCreateSwapchainKHR fpCreateSwapchainKHR; - PFN_vkDestroySwapchainKHR fpDestroySwapchainKHR; - PFN_vkGetSwapchainImagesKHR fpGetSwapchainImagesKHR; - PFN_vkAcquireNextImageKHR fpAcquireNextImageKHR; - PFN_vkQueuePresentKHR fpQueuePresentKHR; }; class RenderViewport : public rhi::IRenderViewport, public DeviceChild @@ -882,7 +998,7 @@ class RenderPass : public DeviceChild class PipelineStateObject : public rhi::IPipelineStateObject, public DeviceChild { public: - explicit PipelineStateObject(Device* pDevice); + explicit PipelineStateObject(Device::Ptr pDevice); PipelineStateObject(Device::Ptr pDevice, rhi::PipelineDesc const& desc, PipelineLayout * ppl); virtual ~PipelineStateObject(); @@ -900,6 +1016,8 @@ class PipelineStateObject : public rhi::IPipelineStateObject, public DeviceChild VkPipeline GetPipeline() const { return m_Pipeline; } void Finalize() override; + void SavePSO(const char* path) override; + void LoadPSO(const char* path) override; /** * TOFIX @@ -938,28 +1056,27 @@ class PipelineStateObject : public rhi::IPipelineStateObject, public DeviceChild PipelineLayout * m_PipelineLayout; }; -class ShaderResourceView : public rhi::IShaderResourceView +class ShaderResourceView : public TVkRHIObjectBase { public: - ShaderResourceView(rhi::ResourceViewDesc const &desc, rhi::IGpuResource * pGpuResource); - ~ShaderResourceView(); - rhi::GpuResourceRef GetResource() const override { return m_Resource; } + ShaderResourceView(Device::Ptr pDevice, rhi::ResourceViewDesc const &desc, rhi::GpuResourceRef gpuResource); + ~ShaderResourceView() override; + rhi::GpuResourceRef GetResource() const override { return rhi::GpuResourceRef(m_WeakResource); } rhi::ResourceViewDesc GetDesc() const override { return m_Desc; } - VkImageView NativeImageView() const { return m_TextureView; } + VkImageView NativeImageView() const { return m_NativeObj; } private: - rhi::GpuResourceRef m_Resource; + //rhi::GpuResourceRef m_Resource; + WeakPtr m_WeakResource; rhi::ResourceViewDesc m_Desc; VkImageViewCreateInfo m_TextureViewInfo; - VkImageView m_TextureView; }; -class PipelineLayout : public rhi::IPipelineLayout, public DeviceChild +class PipelineLayout : public TVkRHIObjectBase { public: PipelineLayout(Device::Ptr pDevice, rhi::PipelineLayoutDesc const &desc); - ~PipelineLayout()override; + ~PipelineLayout() override; - VkPipelineLayout GetNativeLayout() const { return m_PipelineLayout; } VkDescriptorSet GetNativeDescriptorSet() const { return static_cast(m_DescSet.Get())->GetNativeHandle(); } rhi::DescriptorRef GetDescriptorSet()const override{ return m_DescSet; } @@ -970,21 +1087,7 @@ class PipelineLayout : public rhi::IPipelineLayout, public DeviceChild friend class PipelineStateObject; private: rhi::DescriptorRef m_DescSet; - DescriptorSetLayout * m_DescSetLayout; - VkPipelineLayout m_PipelineLayout; -}; - -class Sampler : public rhi::ISampler, public DeviceChild -{ -public: - explicit Sampler(Device::Ptr pDevice, rhi::SamplerState const & sampleDesc); - ~Sampler() override; - rhi::SamplerState GetSamplerDesc() const; - VkSampler NativePtr() const { return m_Sampler; } -protected: - VkSampler m_Sampler = VK_NULL_HANDLE; - VkSamplerCreateInfo m_SamplerCreateInfo = {}; - rhi::SamplerState m_SamplerState; + DescriptorSetLayoutRef m_DescSetLayout; }; K3D_VK_END diff --git a/Source/RHI/Vulkan/Private/VkRenderPass.cpp b/Source/RHI/Vulkan/Private/VkRenderPass.cpp index 5d237a2..6b07804 100755 --- a/Source/RHI/Vulkan/Private/VkRenderPass.cpp +++ b/Source/RHI/Vulkan/Private/VkRenderPass.cpp @@ -2,6 +2,8 @@ #include "VkRHI.h" #include "VkUtils.h" +//#include "Public/VkCommandWrapper.hpp" + K3D_VK_BEGIN RenderPass::RenderPass(Device::Ptr pDevice, RenderpassOptions const & options) @@ -207,8 +209,71 @@ void RenderPass::Destroy() { return; } + VKLOG(Info, "RenderPass destroy... -- %0x.", m_RenderPass); vkDestroyRenderPass(GetRawDevice(), m_RenderPass, nullptr); m_RenderPass = VK_NULL_HANDLE; } +FrameBuffer::FrameBuffer(Device::Ptr pDevice, VkRenderPass renderPass, FrameBuffer::Option const& op) + : DeviceChild(pDevice) + , m_RenderPass(renderPass) + , m_Width(op.Width) + , m_Height(op.Height) +{ + VKRHI_METHOD_TRACE + for (auto& elem : op.Attachments) + { + if (elem.ImageAttachment) + { + continue; + } + } + + std::vector attachments; + for (const auto& elem : op.Attachments) { + attachments.push_back(elem.ImageAttachment); + } + + VkFramebufferCreateInfo createInfo = {}; + createInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO; + createInfo.pNext = nullptr; + createInfo.renderPass = m_RenderPass; + createInfo.attachmentCount = static_cast(op.Attachments.size()); + createInfo.pAttachments = attachments.data(); + createInfo.width = m_Width; + createInfo.height = m_Height; + createInfo.layers = 1; + createInfo.flags = 0; + K3D_VK_VERIFY(vkCreateFramebuffer(GetRawDevice(), &createInfo, nullptr, &m_FrameBuffer)); +} + +FrameBuffer::FrameBuffer(Device::Ptr pDevice, RenderPass * renderPass, RenderTargetLayout const &) + : DeviceChild(pDevice) +{ +} + +FrameBuffer::~FrameBuffer() +{ + if (VK_NULL_HANDLE == m_FrameBuffer) + { + return; + } + VKLOG(Info, "FrameBuffer destroy... -- %0x.", m_FrameBuffer); + vkDestroyFramebuffer(GetRawDevice(), m_FrameBuffer, nullptr); + m_FrameBuffer = VK_NULL_HANDLE; +} + +FrameBuffer::Attachment::Attachment(VkFormat format, VkSampleCountFlagBits samples) +{ + VkImageAspectFlags aspectMask = DetermineAspectMask(Format); + if (VK_IMAGE_ASPECT_COLOR_BIT == aspectMask) + { + FormatFeatures = VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT; + } + else + { + FormatFeatures = VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT; + } +} + K3D_VK_END \ No newline at end of file diff --git a/Source/RHI/Vulkan/Private/VkRenderViewport.cpp b/Source/RHI/Vulkan/Private/VkRenderViewport.cpp index f54a0cb..b268441 100755 --- a/Source/RHI/Vulkan/Private/VkRenderViewport.cpp +++ b/Source/RHI/Vulkan/Private/VkRenderViewport.cpp @@ -9,7 +9,7 @@ K3D_VK_BEGIN RenderViewport::RenderViewport( - Device * pDevice, + Device::Ptr pDevice, void * windowHandle, rhi::GfxSetting & setting) : m_NumBufferCount(-1) @@ -25,7 +25,6 @@ RenderViewport::RenderViewport( setting.Width, setting.Height, m_NumBufferCount); m_PresentSemaphore = GetDevice()->NewSemaphore(); m_RenderSemaphore = GetDevice()->NewSemaphore(); - RHIRoot::AddViewport(this); } } @@ -95,7 +94,7 @@ void RenderViewport::AllocateDefaultRenderPass(rhi::GfxSetting & gfxSetting) if (gfxSetting.HasDepth) { VkFormat depthFormat = g_FormatTable[gfxSetting.DepthStencilFormat]; - GetSupportedDepthFormat(GetPhysicalDevice(), &depthFormat); + GetGpuRef()->GetSupportedDepthFormat(&depthFormat); RenderpassAttachment depthAttach = RenderpassAttachment::CreateDepthStencil(depthFormat); depthAttach.GetDescription().InitialLayout(VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL) @@ -112,7 +111,7 @@ void RenderViewport::AllocateRenderTargets(rhi::GfxSetting & gfxSetting) if (m_RenderPass) { VkFormat depthFormat = g_FormatTable[gfxSetting.DepthStencilFormat]; - GetSupportedDepthFormat(GetPhysicalDevice(), &depthFormat); + GetGpuRef()->GetSupportedDepthFormat(&depthFormat); VkImage depthImage; VkImageCreateInfo image = {}; image.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; @@ -173,7 +172,7 @@ void RenderViewport::AllocateRenderTargets(rhi::GfxSetting & gfxSetting) for (uint32_t i = 0; i < m_NumBufferCount; ++i) { VkImage colorImage = m_pSwapChain->GetBackImage(i); - auto colorImageInfo = ImageViewInfo::CreateColorImageView(GetRawDevice(), colorFmt, colorImage); + auto colorImageInfo = ImageViewInfo::CreateColorImageView(GetGpuRef(), colorFmt, colorImage); VKLOG(Info, "swapchain imageView created . (0x%0x).", colorImageInfo.first); colorImageInfo.second.components = { VK_COMPONENT_SWIZZLE_R, diff --git a/Source/RHI/Vulkan/Private/VkResource.cpp b/Source/RHI/Vulkan/Private/VkResource.cpp index 700a7d5..46db774 100755 --- a/Source/RHI/Vulkan/Private/VkResource.cpp +++ b/Source/RHI/Vulkan/Private/VkResource.cpp @@ -17,23 +17,26 @@ Resource::Ptr Resource::Map(uint64 offset, uint64 size) Resource::~Resource() { - VKLOG(Info, "Resource-Destroying Resource.."); - //vkFreeMemory(GetRawDevice(), m_DeviceMem, nullptr); + if (!m_DeviceMem) + return; + VKLOG(Info, "Resource freeing gpu memory. -- 0x%0x, tid:%d", m_DeviceMem, Os::Thread::GetId()); + vkFreeMemory(GetRawDevice(), m_DeviceMem, nullptr); + m_DeviceMem = VK_NULL_HANDLE; } Buffer::Buffer(Device::Ptr pDevice, rhi::ResourceDesc const &desc) -: Resource(pDevice, desc) +: TResource(pDevice, desc) { - m_Usage = g_ResourceViewFlag[desc.ViewType]; + m_ResUsageFlags = g_ResourceViewFlag[desc.ViewType]; if (desc.CreationFlag & rhi::EGRCF_TransferSrc) { - m_Usage |= VK_BUFFER_USAGE_TRANSFER_SRC_BIT; + m_ResUsageFlags |= VK_BUFFER_USAGE_TRANSFER_SRC_BIT; } if (desc.CreationFlag & rhi::EGRCF_TransferDst) { - m_Usage |= VK_BUFFER_USAGE_TRANSFER_DST_BIT; + m_ResUsageFlags |= VK_BUFFER_USAGE_TRANSFER_DST_BIT; } if (desc.Flag & rhi::EGRAF_HostVisible) @@ -53,17 +56,7 @@ Buffer::Buffer(Device::Ptr pDevice, rhi::ResourceDesc const &desc) Buffer::~Buffer() { - VKLOG(Info, "Buffer-Destroying Resource.."); - if (VK_NULL_HANDLE != m_BufferView) - { - vkDestroyBufferView(GetRawDevice(), m_BufferView, nullptr); - m_BufferView = VK_NULL_HANDLE; - } - if (VK_NULL_HANDLE != m_Buffer) - { - vkDestroyBuffer(GetRawDevice(), m_Buffer, nullptr); - m_Buffer = VK_NULL_HANDLE; - } + VKLOG(Info, "Buffer Destroying.."); } void Buffer::Create(size_t size) @@ -72,42 +65,27 @@ void Buffer::Create(size_t size) createInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; createInfo.pNext = nullptr; createInfo.size = size; - createInfo.usage = m_Usage; + createInfo.usage = m_ResUsageFlags; createInfo.flags = 0; createInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE; createInfo.queueFamilyIndexCount = 0; createInfo.pQueueFamilyIndices = nullptr; - K3D_VK_VERIFY(vkCreateBuffer(GetRawDevice(), &createInfo, nullptr, &m_Buffer)); - ResourceManager::Allocation alloc = GetDevice()->GetMemoryManager()->AllocateBuffer(m_Buffer, false, m_MemoryBits); - K3D_ASSERT(VK_NULL_HANDLE != alloc.Memory); - m_DeviceMem = alloc.Memory; - m_AllocationOffset = alloc.Offset; - m_AllocationSize = alloc.Size; - m_Size = size; + TResource::Allocate(createInfo); - VKLOG(Info, "Buffer reqSize:(%d) allocated:(%d) offset:(%d) address:(0x%0x).", - m_Size, m_AllocationSize, m_AllocationOffset, m_DeviceMem); - - m_BufferInfo.buffer = m_Buffer; - m_BufferInfo.offset = 0; - m_BufferInfo.range = m_Size; + m_ResDescInfo.buffer = m_NativeObj; + m_ResDescInfo.offset = 0; + m_ResDescInfo.range = m_MemAllocInfo.allocationSize; - K3D_VK_VERIFY(vkCmd::BindBufferMemory(GetRawDevice(), m_Buffer, m_DeviceMem, m_AllocationOffset)); + K3D_VK_VERIFY(vkBindBufferMemory(NativeDevice(), m_NativeObj, m_DeviceMem, 0)); } -/*Texture::Texture(Device::Ptr pDevice, rhi::TextureDesc const &desc) -: Resource(pDevice) -{ - Create(desc); -}*/ - Texture::Texture(Device::Ptr pDevice, rhi::ResourceDesc const & desc) - : Resource(pDevice, desc) + : Texture::ThisResourceType(pDevice, desc) { if (desc.CreationFlag & rhi::EGRCF_TransferDst) { - m_ImageUsage |= VK_IMAGE_USAGE_TRANSFER_DST_BIT; + m_ResUsageFlags |= VK_IMAGE_USAGE_TRANSFER_DST_BIT; } if (desc.Flag & rhi::EGRAF_HostVisible) { @@ -139,9 +117,7 @@ Texture::Texture(Device::Ptr pDevice, rhi::ResourceDesc const & desc) } Texture::Texture(VkImage image, VkImageView imageView, VkImageViewCreateInfo info, Device::Ptr pDevice, bool selfOwnShip) - : Resource(pDevice) - , m_ImageView(imageView) - , m_Image(image) + : Texture::ThisResourceType(pDevice) , m_ImageViewInfo(info) , m_SelfOwn(selfOwnShip) { @@ -160,27 +136,21 @@ SamplerCRef Texture::GetSampler() const void Texture::CreateResourceView() { - m_ImageViewInfo = ImageViewInfo::From(m_ImageInfo, m_Image); - K3D_VK_VERIFY(vkCreateImageView(GetRawDevice(), &m_ImageViewInfo, nullptr, &m_ImageView)); + m_ImageViewInfo = ImageViewInfo::From(m_ImageInfo, m_NativeObj); + K3D_VK_VERIFY(vkCreateImageView(NativeDevice(), &m_ImageViewInfo, nullptr, &m_ResView)); } void Texture::CreateRenderTexture(TextureDesc const & desc) { m_ImageInfo = ImageInfo::FromRHI(desc); - K3D_VK_VERIFY(vkCreateImage(GetRawDevice(), &m_ImageInfo, nullptr, &m_Image)); + m_MemoryBits = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT; - ResourceManager::Allocation alloc = GetDevice()->GetMemoryManager()->AllocateImage(m_Image, false, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT); - K3D_ASSERT(VK_NULL_HANDLE != alloc.Memory); + ThisResourceType::Allocate(m_ImageInfo); - m_DeviceMem = alloc.Memory; - m_AllocationOffset = alloc.Offset; - m_AllocationSize = alloc.Size; - m_Size = alloc.Size; + K3D_VK_VERIFY(vkBindImageMemory(NativeDevice(), m_NativeObj, m_DeviceMem, 0)); - K3D_VK_VERIFY(vkBindImageMemory(GetRawDevice(), m_Image, m_DeviceMem, m_AllocationOffset)); - - m_ImageViewInfo = ImageViewInfo::From(m_ImageInfo, m_Image); - K3D_VK_VERIFY(vkCreateImageView(GetRawDevice(), &m_ImageViewInfo, nullptr, &m_ImageView)); + m_ImageViewInfo = ImageViewInfo::From(m_ImageInfo, m_NativeObj); + K3D_VK_VERIFY(vkCreateImageView(NativeDevice(), &m_ImageViewInfo, nullptr, &m_ResView)); VkImageSubresource subres; subres.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; @@ -189,7 +159,7 @@ void Texture::CreateRenderTexture(TextureDesc const & desc) // query texture memory layout info here // image must have been created with tiling equal to VK_IMAGE_TILING_LINEAR // The aspectMask member of pSubresource must only have a single bit set - vkGetImageSubresourceLayout(GetRawDevice(), m_Image, &subres, &m_SubResourceLayout); + vkGetImageSubresourceLayout(NativeDevice(), m_NativeObj, &subres, &m_SubResourceLayout); } void Texture::CreateDepthStencilTexture(TextureDesc const & desc) @@ -199,40 +169,27 @@ void Texture::CreateDepthStencilTexture(TextureDesc const & desc) void Texture::CreateSampledTexture(TextureDesc const & desc) { m_ImageInfo = ImageInfo::FromRHI(desc); - m_ImageInfo.usage = m_ImageUsage | VK_IMAGE_USAGE_SAMPLED_BIT; - m_ImageInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; - m_ImageInfo.tiling = VK_IMAGE_TILING_OPTIMAL; + m_ImageInfo.usage = m_ResUsageFlags | VK_IMAGE_USAGE_SAMPLED_BIT; + if (m_ResUsageFlags & VK_IMAGE_USAGE_TRANSFER_DST_BIT) // texture upload use staging + { + m_ImageInfo.tiling = VK_IMAGE_TILING_OPTIMAL; + m_ImageInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; + } + else // directly upload + { + m_ImageInfo.tiling = VK_IMAGE_TILING_LINEAR; + m_ImageInfo.initialLayout = VK_IMAGE_LAYOUT_PREINITIALIZED; + } m_SubResRange = { VK_IMAGE_ASPECT_COLOR_BIT, 0, desc.MipLevels, 0, desc.Layers }; - K3D_VK_VERIFY(vkCreateImage(GetRawDevice(), &m_ImageInfo, nullptr, &m_Image)); - - ResourceManager::Allocation alloc = GetDevice()->GetMemoryManager()->AllocateImage(m_Image, false, m_MemoryBits); - K3D_ASSERT(VK_NULL_HANDLE != alloc.Memory); - - m_DeviceMem = alloc.Memory; - m_AllocationOffset = alloc.Offset; - m_AllocationSize = alloc.Size; - m_Size = alloc.Size; + ThisResourceType::Allocate(m_ImageInfo); - K3D_VK_VERIFY(vkBindImageMemory(GetRawDevice(), m_Image, m_DeviceMem, m_AllocationOffset)); + K3D_VK_VERIFY(vkBindImageMemory(NativeDevice(), m_NativeObj, m_DeviceMem, 0)); } Texture::~Texture() { - if (GetRawDevice() == VK_NULL_HANDLE) - return; - if (VK_NULL_HANDLE != m_ImageView) - { - vkDestroyImageView(GetRawDevice(), m_ImageView, nullptr); - m_ImageView = VK_NULL_HANDLE; - } - if (VK_NULL_HANDLE != m_Image && m_SelfOwn) - { - vkDestroyImage(GetRawDevice(), m_Image, nullptr); - m_Image = VK_NULL_HANDLE; - } - VKLOG(Info, "Texture-Destroyed.."); } Texture::TextureRef Texture::CreateFromSwapChain(VkImage image, VkImageView view, VkImageViewCreateInfo info, Device::Ptr pDevice) @@ -240,31 +197,85 @@ Texture::TextureRef Texture::CreateFromSwapChain(VkImage image, VkImageView view return k3d::MakeShared(image, view, info, pDevice, false); } -ShaderResourceView::ShaderResourceView(rhi::ResourceViewDesc const &desc, rhi::IGpuResource * pGpuResource) - : m_Desc(desc), m_Resource(pGpuResource), m_TextureViewInfo{}, m_TextureView(VK_NULL_HANDLE) +ShaderResourceView::ShaderResourceView(Device::Ptr pDevice, rhi::ResourceViewDesc const &desc, rhi::GpuResourceRef pGpuResource) + : ShaderResourceView::ThisObj(pDevice) + , m_Desc(desc), m_WeakResource(pGpuResource), m_TextureViewInfo{} { - auto resourceDesc = m_Resource->GetResourceDesc(); + auto resourceDesc = m_WeakResource->GetDesc(); + m_TextureViewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; + m_TextureViewInfo.components = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A }; switch(resourceDesc.Type) { + case rhi::EGT_Texture1D: + m_TextureViewInfo.viewType = VK_IMAGE_VIEW_TYPE_1D; + break; case rhi::EGT_Texture2D: - m_TextureViewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; - m_TextureViewInfo.components = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A }; m_TextureViewInfo.viewType = VK_IMAGE_VIEW_TYPE_2D; - m_TextureViewInfo.format = g_FormatTable[resourceDesc.TextureDesc.Format]; - m_TextureViewInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; - m_TextureViewInfo.subresourceRange.baseMipLevel = 0; - m_TextureViewInfo.subresourceRange.baseArrayLayer = 0; - m_TextureViewInfo.subresourceRange.layerCount = 1; - m_TextureViewInfo.subresourceRange.levelCount = resourceDesc.TextureDesc.MipLevels; - m_TextureViewInfo.image = (VkImage)m_Resource->GetResourceLocation(); - K3D_VK_VERIFY(vkCreateImageView(dynamic_cast(m_Resource.Get())->GetRawDevice(), &m_TextureViewInfo, nullptr, &m_TextureView)); + break; + case rhi::EGT_Texture3D: + m_TextureViewInfo.viewType = VK_IMAGE_VIEW_TYPE_3D; + break; + case rhi::EGT_Texture2DArray: + m_TextureViewInfo.viewType = VK_IMAGE_VIEW_TYPE_2D_ARRAY; break; } + m_TextureViewInfo.format = g_FormatTable[resourceDesc.TextureDesc.Format]; + m_TextureViewInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + m_TextureViewInfo.subresourceRange.baseMipLevel = 0; + m_TextureViewInfo.subresourceRange.baseArrayLayer = 0; + m_TextureViewInfo.subresourceRange.layerCount = 1; + m_TextureViewInfo.subresourceRange.levelCount = resourceDesc.TextureDesc.MipLevels; + m_TextureViewInfo.image = (VkImage)m_WeakResource->GetLocation(); + + K3D_VK_VERIFY(vkCreateImageView(NativeDevice(), &m_TextureViewInfo, nullptr, &m_NativeObj)); } ShaderResourceView::~ShaderResourceView() { // destroy view + VKLOG(Info, "ShaderResourceView destroying..."); + if (m_NativeObj) + { + vkDestroyImageView(NativeDevice(), m_NativeObj, nullptr); + m_NativeObj = VK_NULL_HANDLE; + } +} + +Sampler::Sampler(Device::Ptr pDevice, rhi::SamplerState const & samplerDesc) + : ThisObj(pDevice) + , m_SamplerState(samplerDesc) +{ + if (pDevice) + { + m_SamplerCreateInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO; + m_SamplerCreateInfo.magFilter = g_Filters[samplerDesc.Filter.MagFilter]; + m_SamplerCreateInfo.minFilter = g_Filters[samplerDesc.Filter.MinFilter]; + m_SamplerCreateInfo.mipmapMode = g_MipMapModes[samplerDesc.Filter.MipMapFilter]; + m_SamplerCreateInfo.addressModeU = g_AddressModes[samplerDesc.U]; + m_SamplerCreateInfo.addressModeV = g_AddressModes[samplerDesc.V]; + m_SamplerCreateInfo.addressModeW = g_AddressModes[samplerDesc.W]; + m_SamplerCreateInfo.mipLodBias = samplerDesc.MipLODBias; + m_SamplerCreateInfo.compareOp = g_ComparisonFunc[samplerDesc.ComparisonFunc]; + m_SamplerCreateInfo.minLod = samplerDesc.MinLOD; + // Max level-of-detail should match mip level count + m_SamplerCreateInfo.maxLod = samplerDesc.MaxLOD; + // Enable anisotropic filtering + m_SamplerCreateInfo.maxAnisotropy = samplerDesc.MaxAnistropy; + m_SamplerCreateInfo.anisotropyEnable = VK_TRUE; + m_SamplerCreateInfo.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE; // cannot convert... + vkCreateSampler(NativeDevice(), &m_SamplerCreateInfo, nullptr, &m_NativeObj); + } +} + +Sampler::~Sampler() +{ + VKLOG(Info, "Sampler Destroying %p...", m_NativeObj); + vkDestroySampler(NativeDevice(), m_NativeObj, nullptr); +} + +rhi::SamplerState Sampler::GetSamplerDesc() const +{ + return m_SamplerState; } template @@ -338,6 +349,8 @@ ResourceManager::PoolManager::~PoolManager() template void ResourceManager::PoolManager::Destroy() { + if (!GetRawDevice()) + return; ::Os::Mutex::AutoLock lock(&m_Mutex); for (auto& pool : m_Pools) { vkFreeMemory(GetRawDevice(), pool->m_Memory, nullptr); diff --git a/Source/RHI/Vulkan/Private/VkSampler.cpp b/Source/RHI/Vulkan/Private/VkSampler.cpp deleted file mode 100755 index f59a134..0000000 --- a/Source/RHI/Vulkan/Private/VkSampler.cpp +++ /dev/null @@ -1,44 +0,0 @@ -#include "VkCommon.h" -#include "VkRHI.h" -#include "VkEnums.h" - -K3D_VK_BEGIN - -Sampler::Sampler(Device::Ptr pDevice, rhi::SamplerState const & samplerDesc) - : DeviceChild(pDevice) - , m_SamplerState(samplerDesc) -{ - if (pDevice) - { - m_SamplerCreateInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO; - m_SamplerCreateInfo.magFilter = g_Filters[samplerDesc.Filter.MagFilter]; - m_SamplerCreateInfo.minFilter = g_Filters[samplerDesc.Filter.MinFilter]; - m_SamplerCreateInfo.mipmapMode = g_MipMapModes[samplerDesc.Filter.MipMapFilter]; - m_SamplerCreateInfo.addressModeU = g_AddressModes[samplerDesc.U]; - m_SamplerCreateInfo.addressModeV = g_AddressModes[samplerDesc.V]; - m_SamplerCreateInfo.addressModeW = g_AddressModes[samplerDesc.W]; - m_SamplerCreateInfo.mipLodBias = samplerDesc.MipLODBias; - m_SamplerCreateInfo.compareOp = g_ComparisonFunc[samplerDesc.ComparisonFunc]; - m_SamplerCreateInfo.minLod = samplerDesc.MinLOD; - // Max level-of-detail should match mip level count - m_SamplerCreateInfo.maxLod = samplerDesc.MaxLOD; - // Enable anisotropic filtering - m_SamplerCreateInfo.maxAnisotropy = samplerDesc.MaxAnistropy; - m_SamplerCreateInfo.anisotropyEnable = VK_TRUE; - m_SamplerCreateInfo.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE; // cannot convert... - vkCreateSampler(GetRawDevice(), &m_SamplerCreateInfo, nullptr, &m_Sampler); - } -} - -Sampler::~Sampler() -{ - VKLOG(Info, "Sampler-Destroying ..."); - vkDestroySampler(GetRawDevice(), m_Sampler, nullptr); -} - -rhi::SamplerState Sampler::GetSamplerDesc() const -{ - return m_SamplerState; -} - -K3D_VK_END \ No newline at end of file diff --git a/Source/RHI/Vulkan/Private/VkSwapChain.cpp b/Source/RHI/Vulkan/Private/VkSwapChain.cpp index d3e3dc9..6deb0b2 100755 --- a/Source/RHI/Vulkan/Private/VkSwapChain.cpp +++ b/Source/RHI/Vulkan/Private/VkSwapChain.cpp @@ -7,10 +7,6 @@ K3D_VK_BEGIN SwapChain::SwapChain(Device::Ptr pDevice) : DeviceChild(pDevice), m_ReserveBackBufferCount(0) { - if(pDevice) - { - InitProcs(); - } } SwapChain::~SwapChain() @@ -26,7 +22,7 @@ void SwapChain::Initialize(void * WindowHandle, rhi::GfxSetting & gfxSetting) m_SelectedPresentQueueFamilyIndex = ChooseQueueIndex(); m_SwapchainExtent = { gfxSetting.Width, gfxSetting.Height }; VkSurfaceCapabilitiesKHR surfProperties; - K3D_VK_VERIFY(vkGetPhysicalDeviceSurfaceCapabilitiesKHR(GetPhysicalDevice(), m_Surface, &surfProperties)); + K3D_VK_VERIFY(GetGpuRef()->GetSurfaceCapabilitiesKHR(m_Surface, &surfProperties)); m_SwapchainExtent = surfProperties.currentExtent; /*gfxSetting.Width = m_SwapchainExtent.width; gfxSetting.Height = m_SwapchainExtent.height;*/ @@ -36,9 +32,9 @@ void SwapChain::Initialize(void * WindowHandle, rhi::GfxSetting & gfxSetting) surfProperties.maxImageCount); m_DesiredBackBufferCount = desiredNumBuffers; InitSwapChain(m_DesiredBackBufferCount, chosenFormat, swapchainPresentMode, surfProperties.currentTransform); - K3D_VK_VERIFY(fpGetSwapchainImagesKHR(GetRawDevice(), m_SwapChain, &m_ReserveBackBufferCount, nullptr)); + K3D_VK_VERIFY(vkGetSwapchainImagesKHR(GetRawDevice(), m_SwapChain, &m_ReserveBackBufferCount, nullptr)); m_ColorImages.resize(m_ReserveBackBufferCount); - K3D_VK_VERIFY(fpGetSwapchainImagesKHR(GetRawDevice(), m_SwapChain, &m_ReserveBackBufferCount, m_ColorImages.data())); + K3D_VK_VERIFY(vkGetSwapchainImagesKHR(GetRawDevice(), m_SwapChain, &m_ReserveBackBufferCount, m_ColorImages.data())); gfxSetting.BackBufferCount = m_ReserveBackBufferCount; VKLOG(Info, "[SwapChain::Initialize] desired imageCount=%d, reserved imageCount = %d.", m_DesiredBackBufferCount, m_ReserveBackBufferCount); } @@ -46,9 +42,9 @@ void SwapChain::Initialize(void * WindowHandle, rhi::GfxSetting & gfxSetting) uint32 SwapChain::AcquireNextImage(PtrSemaphore presentSemaphore, PtrFence pFence) { uint32 imageIndex; - VkResult result = fpAcquireNextImageKHR(GetRawDevice(), m_SwapChain, UINT64_MAX, + VkResult result = vkAcquireNextImageKHR(GetRawDevice(), m_SwapChain, UINT64_MAX, presentSemaphore ? presentSemaphore->m_Semaphore:VK_NULL_HANDLE, - pFence ? pFence->m_Fence : VK_NULL_HANDLE, + pFence ? pFence->NativeHandle() : VK_NULL_HANDLE, &imageIndex); switch (result) { @@ -73,7 +69,7 @@ VkResult SwapChain::Present(uint32 imageIndex, PtrSemaphore renderingFinishSemap presentInfo.pSwapchains = &m_SwapChain; presentInfo.waitSemaphoreCount = renderSem ? 1 : 0; presentInfo.pWaitSemaphores = &renderSem; - return fpQueuePresentKHR(GetImmCmdQueue()->GetNativeHandle(), &presentInfo); + return vkQueuePresentKHR(GetImmCmdQueue()->GetNativeHandle(), &presentInfo); } void SwapChain::InitSurface(void * WindowHandle) @@ -83,21 +79,21 @@ void SwapChain::InitSurface(void * WindowHandle) SurfaceCreateInfo.sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR; SurfaceCreateInfo.hinstance = GetModuleHandle(nullptr); SurfaceCreateInfo.hwnd = (HWND)WindowHandle; - K3D_VK_VERIFY(vkCreateWin32SurfaceKHR(RHIRoot::GetInstance(), &SurfaceCreateInfo, nullptr, &m_Surface)); + K3D_VK_VERIFY(vkCreateWin32SurfaceKHR(GetGpuRef()->GetInstance()->m_Instance, &SurfaceCreateInfo, nullptr, &m_Surface)); #elif K3DPLATFORM_OS_ANDROID VkAndroidSurfaceCreateInfoKHR SurfaceCreateInfo = {}; SurfaceCreateInfo.sType = VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR; SurfaceCreateInfo.window = (ANativeWindow*)WindowHandle; - K3D_VK_VERIFY(vkCreateAndroidSurfaceKHR(RHIRoot::GetInstance(), &SurfaceCreateInfo, nullptr, &m_Surface)); + K3D_VK_VERIFY(vkCreateAndroidSurfaceKHR(GetGpuRef()->GetInstance()->m_Instance, &SurfaceCreateInfo, nullptr, &m_Surface)); #endif } VkPresentModeKHR SwapChain::ChoosePresentMode() { uint32_t presentModeCount; - K3D_VK_VERIFY(fpGetPhysicalDeviceSurfacePresentModesKHR(GetPhysicalDevice(), m_Surface, &presentModeCount, NULL)); + K3D_VK_VERIFY(GetGpuRef()->GetSurfacePresentModesKHR(m_Surface, &presentModeCount, NULL)); std::vector presentModes(presentModeCount); - K3D_VK_VERIFY(fpGetPhysicalDeviceSurfacePresentModesKHR(GetPhysicalDevice(), m_Surface, &presentModeCount, presentModes.data())); + K3D_VK_VERIFY(GetGpuRef()->GetSurfacePresentModesKHR(m_Surface, &presentModeCount, presentModes.data())); VkPresentModeKHR swapchainPresentMode = VK_PRESENT_MODE_FIFO_KHR; for (size_t i = 0; i < presentModeCount; i++) { @@ -117,9 +113,9 @@ VkPresentModeKHR SwapChain::ChoosePresentMode() std::pair SwapChain::ChooseFormat(rhi::GfxSetting & gfxSetting) { uint32_t formatCount; - K3D_VK_VERIFY(fpGetPhysicalDeviceSurfaceFormatsKHR(GetPhysicalDevice(), m_Surface, &formatCount, NULL)); + K3D_VK_VERIFY(GetGpuRef()->GetSurfaceFormatsKHR(m_Surface, &formatCount, NULL)); std::vector surfFormats(formatCount); - K3D_VK_VERIFY(fpGetPhysicalDeviceSurfaceFormatsKHR(GetPhysicalDevice(), m_Surface, &formatCount, surfFormats.data())); + K3D_VK_VERIFY(GetGpuRef()->GetSurfaceFormatsKHR(m_Surface, &formatCount, surfFormats.data())); VkFormat colorFormat; VkColorSpaceKHR colorSpace; if (formatCount == 1 && surfFormats[0].format == VK_FORMAT_UNDEFINED) @@ -142,7 +138,7 @@ int SwapChain::ChooseQueueIndex() for (uint32_t i = 0; i < GetDevice()->GetQueueCount(); ++i) { - vkGetPhysicalDeviceSurfaceSupportKHR(GetPhysicalDevice(), i, m_Surface, &queuePresentSupport[i]); + GetGpuRef()->GetSurfaceSupportKHR(i, m_Surface, &queuePresentSupport[i]); if (queuePresentSupport[i]) { chosenIndex = i; @@ -172,20 +168,21 @@ void SwapChain::InitSwapChain(uint32 numBuffers, std::pairGetInstance()->m_Instance, m_Surface, nullptr); m_Surface = VK_NULL_HANDLE; } } diff --git a/Source/RHI/Vulkan/Private/VkUtils.cpp b/Source/RHI/Vulkan/Private/VkUtils.cpp index 6047a62..2b7ee4c 100755 --- a/Source/RHI/Vulkan/Private/VkUtils.cpp +++ b/Source/RHI/Vulkan/Private/VkUtils.cpp @@ -4,6 +4,21 @@ K3D_VK_BEGIN +// Buffer functors +decltype(vkCreateBufferView)* ResTrait::CreateView = &vkCreateBufferView; +decltype(vkDestroyBufferView)* ResTrait::DestroyView = &vkDestroyBufferView; +decltype(vkCreateBuffer)* ResTrait::Create = &vkCreateBuffer; +decltype(vkDestroyBuffer)* ResTrait::Destroy = &vkDestroyBuffer; +decltype(vkGetBufferMemoryRequirements)* ResTrait::GetMemoryInfo = &vkGetBufferMemoryRequirements; +decltype(vkBindBufferMemory)* ResTrait::BindMemory = &vkBindBufferMemory; + +decltype(vkCreateImageView)* ResTrait::CreateView = &vkCreateImageView; +decltype(vkDestroyImageView)* ResTrait::DestroyView = &vkDestroyImageView; +decltype(vkCreateImage)* ResTrait::Create = &vkCreateImage; +decltype(vkDestroyImage)* ResTrait::Destroy = &vkDestroyImage; +decltype(vkGetImageMemoryRequirements)* ResTrait::GetMemoryInfo = &vkGetImageMemoryRequirements; +decltype(vkBindImageMemory)* ResTrait::BindMemory = &vkBindImageMemory; + VkDeviceSize CalcAlignedOffset(VkDeviceSize offset, VkDeviceSize align) { VkDeviceSize n = offset / align; @@ -137,10 +152,11 @@ void CommandAllocator::Initialize() void CommandAllocator::Destroy() { - if (VK_NULL_HANDLE == m_Pool) + if (VK_NULL_HANDLE == m_Pool || !GetRawDevice() ) { return; } + VKLOG(Info, "CommandAllocator destroy.. -- %d. (device:0x%0x)", m_Pool, GetRawDevice()); vkDestroyCommandPool(GetRawDevice(), m_Pool, nullptr); m_Pool = VK_NULL_HANDLE; } diff --git a/Source/RHI/Vulkan/Private/VkUtils.h b/Source/RHI/Vulkan/Private/VkUtils.h index 329aad8..1c56b9e 100755 --- a/Source/RHI/Vulkan/Private/VkUtils.h +++ b/Source/RHI/Vulkan/Private/VkUtils.h @@ -9,8 +9,7 @@ extern K3D_API VkDeviceSize CalcAlignedOffset(VkDeviceSize offset, VkDeviceSi extern K3D_API VkImageAspectFlags DetermineAspectMask(VkFormat format); extern K3D_API std::string ErrorString(VkResult errorCode); extern K3D_API VkBool32 GetSupportedDepthFormat(VkPhysicalDevice physicalDevice, VkFormat * depthFormat); -extern K3D_API void SetupDebugging(VkInstance instance, VkDebugReportFlagsEXT flags, VkDebugReportCallbackEXT callBack); -extern K3D_API void FreeDebugCallback(VkInstance instance); + extern K3D_API rhi::PipelineLayoutKey HashPipelineLayoutDesc(rhi::PipelineLayoutDesc const& desc); class CommandAllocator; @@ -27,9 +26,11 @@ class CommandAllocator : public DeviceChild ~CommandAllocator(); VkCommandPool GetCommandPool() const { return m_Pool; } + + void Destroy(); + protected: void Initialize(); - void Destroy(); private: CommandAllocator(uint32 queueFamilyIndex, bool transient, Device::Ptr device); @@ -48,7 +49,11 @@ class Semaphore : public DeviceChild K3D_VK_VERIFY(vkCreateSemaphore(GetRawDevice(), &info, nullptr, &m_Semaphore)); VKLOG(Info, "Semaphore Created. (0x%0x).", m_Semaphore); } - ~Semaphore() { vkDestroySemaphore(GetRawDevice(), m_Semaphore, nullptr); } + ~Semaphore() + { + VKLOG(Info, "Semaphore Destroyed. (0x%0x).", m_Semaphore); + vkDestroySemaphore(GetRawDevice(), m_Semaphore, nullptr); + } VkSemaphore GetNativeHandle() const { return m_Semaphore; } diff --git a/Source/RHI/Vulkan/Public/IVkRHI.h b/Source/RHI/Vulkan/Public/IVkRHI.h index 19905e9..30aa758 100755 --- a/Source/RHI/Vulkan/Public/IVkRHI.h +++ b/Source/RHI/Vulkan/Public/IVkRHI.h @@ -1,7 +1,7 @@ #ifndef __IVkRHI_h__ #define __IVkRHI_h__ #include -#include +#include namespace k3d { @@ -21,4 +21,8 @@ namespace k3d }; } +#if BUILD_STATIC_PLUGIN +K3D_STATIC_MODULE_DECLARE(RHI_Vulkan); +#endif + #endif \ No newline at end of file diff --git a/Source/RHI/Vulkan/VkCommon.h b/Source/RHI/Vulkan/VkCommon.h index 166746e..fbb4062 100755 --- a/Source/RHI/Vulkan/VkCommon.h +++ b/Source/RHI/Vulkan/VkCommon.h @@ -5,7 +5,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/Source/Renderer/CMakeLists.txt b/Source/Renderer/CMakeLists.txt index 506f9b2..0a30434 100755 --- a/Source/Renderer/CMakeLists.txt +++ b/Source/Renderer/CMakeLists.txt @@ -5,10 +5,6 @@ ${DXSDK_INCLUDE_DIR} ${V8_INCLUDE_DIR} ) -if(BUILD_SHARED) - add_definitions(-DBUILD_SHARED_LIB -DBUILD_WITH_PLUGIN) -endif() - set(RENDER_SRCS Render.h Render.cpp @@ -16,6 +12,10 @@ MeshRender.cpp RenderContext.cpp ) +if(BUILD_SHARED) + add_definitions(-DBUILD_WITH_PLUGIN) +endif() + source_group(Render FILES ${RENDER_SRCS}) set(RENDER_DEPLIB Core) @@ -27,13 +27,14 @@ if(HAS_FREETYPE) set(RENDER_DEPLIB ${RENDER_DEPLIB} ${FREETYPE2_LIBRARY}) endif() -add_library(Render ${LIB_TYPE} ${RENDER_SRCS}) -target_link_libraries(Render ${RENDER_DEPLIB}) -set_target_properties(Render PROPERTIES FOLDER "Runtime") +k3d_add_lib(Render SRCS ${RENDER_SRCS} LIBS ${RENDER_DEPLIB} FOLDER "Runtime") -if(WIN32) - install(TARGETS Render ARCHIVE DESTINATION lib) -elseif(MACOS) - add_custom_command(TARGET Render POST_BUILD COMMAND - ${CMAKE_INSTALL_NAME_TOOL} -id "@loader_path/../Frameworks/libRender.dylib" $) +if(MACOS AND BUILD_SHARED) + add_custom_command(TARGET Render POST_BUILD COMMAND + ${CMAKE_INSTALL_NAME_TOOL} -id "@loader_path/../Frameworks/libRender.dylib" $) endif() + +install(TARGETS Render + ARCHIVE DESTINATION lib + LIBRARY DESTINATION lib + RUNTIME DESTINATION bin) \ No newline at end of file diff --git a/Source/Renderer/FontRenderer.cpp b/Source/Renderer/FontRenderer.cpp index 9b98fa0..7698815 100755 --- a/Source/Renderer/FontRenderer.cpp +++ b/Source/Renderer/FontRenderer.cpp @@ -1 +1,200 @@ -#include "FontRenderer.h" \ No newline at end of file +#include "Kaleido3D.h" +#include "FontRenderer.h" +#include +#include +#include FT_FREETYPE_H + +namespace render +{ + FontManager::FontManager() + : m_PixelSize(0) + , m_Color(0xffffffff) + , m_pFontLib(nullptr) + , m_pFontFace(nullptr) + { + FT_Init_FreeType((FT_Library*)&m_pFontLib); + } + + FontManager::~FontManager() + { + if (m_pFontFace) + { + FT_Done_Face((FT_Face)m_pFontFace); + m_pFontFace = nullptr; + } + if (m_pFontLib) + { + FT_Done_FreeType((FT_Library)m_pFontLib); + m_pFontLib = nullptr; + } + } + + void FontManager::LoadLib(const char * fontPath) + { + if (m_pFontFace) + { + FT_Done_Face((FT_Face)m_pFontFace); + m_pFontFace = nullptr; + } + FT_New_Face((FT_Library)m_pFontLib, fontPath, 0, (FT_Face*)&m_pFontFace); + } + + void FontManager::ChangeFontSize(int height) + { + FT_Set_Pixel_Sizes((FT_Face)m_pFontFace, 0, height); + m_PixelSize = height; + } + + void FontManager::SetPaintColor(int color) + { + m_Color = color; + } + + unsigned int* GlyphTexture(const FT_Bitmap& bitmap, const unsigned int& color) + { + unsigned int* buffer = new unsigned int[bitmap.width * bitmap.rows * 4]; + for (int y = 0; y< bitmap.rows; y++) + { + for (int x = 0; x < bitmap.width; x++) + { + unsigned int pixel = (color & 0xffffff00); + unsigned int alpha = bitmap.buffer[(y * bitmap.pitch) + x]; + pixel |= alpha; + buffer[(y*bitmap.width) + x] = pixel; + } + } + return buffer; + } + + TextQuads FontManager::AcquireText(const::k3d::String & text) + { + if(text.Length()==0 || !m_pFontFace) + return TextQuads(); + FT_Face face = (FT_Face)m_pFontFace; + TextQuads quadlist; + for (unsigned int i = 0; i < text.Length(); i++) + { + FT_Load_Char(face, text[i], FT_LOAD_RENDER | FT_LOAD_NO_HINTING); + unsigned int *bytes = GlyphTexture(face->glyph->bitmap, m_Color); + int width = face->glyph->bitmap.width; + int height = face->glyph->bitmap.rows; + int x = face->glyph->metrics.horiBearingX / m_PixelSize; + int y = face->glyph->metrics.horiBearingY / m_PixelSize; + int next = face->glyph->metrics.horiAdvance / m_PixelSize; + quadlist.Append({ x,y, width, height, next, bytes}); + } + return quadlist; + } + + CharTexture::CharTexture(rhi::DeviceRef device, TextQuad const & quad) + { + rhi::ResourceDesc texDesc; + texDesc.Type = rhi::EGT_Texture2D; + texDesc.ViewType = rhi::EGpuMemViewType::EGVT_SRV; + texDesc.Flag = rhi::EGpuResourceAccessFlag::EGRAF_HostVisible; + texDesc.TextureDesc.Format = rhi::EPF_RGBA8Unorm; // TODO font color fmt inconsistent + texDesc.TextureDesc.Width = quad.W; + texDesc.TextureDesc.Height = quad.H; + texDesc.TextureDesc.Layers = 1; + texDesc.TextureDesc.MipLevels = 1; + texDesc.TextureDesc.Depth = 1; + m_Texture = ::k3d::DynamicPointerCast(device->NewGpuResource(texDesc)); + + uint64 sz = m_Texture->GetSize(); + void * pData = m_Texture->Map(0, sz); + rhi::SubResourceLayout layout = {}; + rhi::TextureResourceSpec spec = { rhi::ETAF_COLOR,0,0 }; + device->QueryTextureSubResourceLayout(m_Texture, spec, &layout); + if (quad.W * 4 == layout.RowPitch) + { + memcpy(pData, quad.Pixels, sz); + } + else + { + for (int y = 0; y < quad.H; y++) + { + uint32_t *row = (uint32_t *)((char *)pData + layout.RowPitch * y); + for (int x = 0; x < quad.W; x++) + { + row[x] = quad.Pixels[x + y * quad.W]; + } + } + } + m_Texture->UnMap(); + + auto cmd = device->NewCommandContext(rhi::ECMD_Graphics); + cmd->Begin(); + cmd->TransitionResourceBarrier(m_Texture, rhi::ERS_ShaderResource); + cmd->End(); + cmd->Execute(false); + } + + short CharRenderer::s_Indices[] = { 0, 1, 3, 2 }; + + float CharRenderer::s_Vertices[] = { + 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, // 0 + 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, // 1 + 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, // 3 + 1.0f, 1.0f, 0.0f, 1.0f, 0.0f // 2 + }; + + CharRenderer::CharRenderer() + { + } + + CharRenderer::~CharRenderer() + { + } + + + void CharRenderer::InitVertexBuffers(rhi::DeviceRef const & device) + { + rhi::ResourceDesc vboDesc; + vboDesc.ViewType = rhi::EGpuMemViewType::EGVT_VBV; + vboDesc.Flag = (rhi::EGpuResourceAccessFlag) (rhi::EGpuResourceAccessFlag::EGRAF_HostCoherent | rhi::EGpuResourceAccessFlag::EGRAF_HostVisible); + vboDesc.Size = sizeof(s_Vertices); + m_VertexBuffer = device->NewGpuResource(vboDesc); + void * ptr = m_VertexBuffer->Map(0, vboDesc.Size); + memcpy(ptr, s_Vertices, vboDesc.Size); + m_VertexBuffer->UnMap(); + + rhi::ResourceDesc iboDesc; + iboDesc.ViewType = rhi::EGpuMemViewType::EGVT_IBV; + iboDesc.Flag = (rhi::EGpuResourceAccessFlag) (rhi::EGpuResourceAccessFlag::EGRAF_HostCoherent | rhi::EGpuResourceAccessFlag::EGRAF_HostVisible); + iboDesc.Size = sizeof(s_Indices); + m_IndexBuffer = device->NewGpuResource(iboDesc); + ptr = m_IndexBuffer->Map(0, iboDesc.Size); + memcpy(ptr, s_Indices, iboDesc.Size); + m_IndexBuffer->UnMap(); + } + + CharTexture::~CharTexture() + { + } + + FontRenderer::FontRenderer(rhi::DeviceRef const& device) + : m_Device(device) + { + } + + FontRenderer::~FontRenderer() + { + } + + void FontRenderer::InitPSO() + { + auto shMod = k3d::StaticPointerCast(ACQUIRE_PLUGIN(ShaderCompiler)); + if (!shMod) + return; + auto glslc = shMod->CreateShaderCompiler(rhi::ERHI_Vulkan); + } + + void FontRenderer::DrawText2D(rhi::CommandContextRef const & cmd, const::k3d::String & text, float x, float y) + { + auto quads = m_FontManager.AcquireText(text); + for (auto quad : quads) + { + CharTexture * tex = new CharTexture(m_Device, quad); + } + } +} \ No newline at end of file diff --git a/Source/Renderer/FontRenderer.h b/Source/Renderer/FontRenderer.h index 6f70f09..1c4026d 100755 --- a/Source/Renderer/FontRenderer.h +++ b/Source/Renderer/FontRenderer.h @@ -1 +1,85 @@ #pragma once +#include +#include +#include + +#include + +namespace render +{ + class TextQuad + { + public: + int X; + int Y; + int W; + int H; + int HSpace; + unsigned int* Pixels; + }; + + typedef ::k3d::DynArray TextQuads; + + class K3D_API FontManager + { + public: + FontManager(); + ~FontManager(); + + void LoadLib(const char * fontPath); + void ChangeFontSize(int height); + void SetPaintColor(int color); + + TextQuads AcquireText(const ::k3d::String & text); + + private: + int m_PixelSize; + int m_Color; + void* m_pFontLib; + void* m_pFontFace; + // Cache + }; + + class CharTexture + { + public: + CharTexture(rhi::DeviceRef device, TextQuad const& quad); + ~CharTexture(); + rhi::TextureRef GetTexture() const { return m_Texture; } + private: + rhi::TextureRef m_Texture; + }; + + class CharRenderer + { + public: + CharRenderer(); + ~CharRenderer(); + + void InitVertexBuffers(rhi::DeviceRef const& device); + + private: + static short s_Indices[]; + static float s_Vertices[]; + static float s_CharTexCoords[]; + + private: + rhi::GpuResourceRef m_VertexBuffer; + rhi::GpuResourceRef m_IndexBuffer; + }; + + class FontRenderer + { + public: + explicit FontRenderer(rhi::DeviceRef const & device); + ~FontRenderer(); + void InitPSO(); + void DrawText2D(rhi::CommandContextRef const& cmd, const ::k3d::String & text, float x, float y); + + private: + rhi::DeviceRef m_Device; + rhi::PipelineStateObjectRef m_TextRenderPSO; + FontManager m_FontManager; + std::unordered_map m_TexCache; + }; +} \ No newline at end of file diff --git a/Source/Renderer/Render.h b/Source/Renderer/Render.h index 8c1eb2d..9cccc02 100755 --- a/Source/Renderer/Render.h +++ b/Source/Renderer/Render.h @@ -1,6 +1,6 @@ #pragma once #include "Engine/SceneManager.h" -#include "RHI/IRHI.h" +#include #include #include #include diff --git a/Source/Renderer/RenderContext.cpp b/Source/Renderer/RenderContext.cpp index dbab4fc..fd6ae06 100755 --- a/Source/Renderer/RenderContext.cpp +++ b/Source/Renderer/RenderContext.cpp @@ -3,7 +3,7 @@ #if K3DPLATFORM_OS_WIN #include #include -#elif K3DPLATFORM_OS_MAC +#elif K3DPLATFORM_OS_MAC||K3DPLATFORM_OS_IOS #include #include #else @@ -29,13 +29,13 @@ namespace render m_Width = w; m_Height = h; m_RhiType = type; -#ifndef K3DPLATFORM_OS_MAC - IVkRHI* pVkRHI = (IVkRHI*)GlobalModuleManager.FindModule("RHI_Vulkan"); +#if !(K3DPLATFORM_OS_MAC || K3DPLATFORM_OS_IOS) + auto pVkRHI = k3d::StaticPointerCast(ACQUIRE_PLUGIN(RHI_Vulkan)); pVkRHI->Initialize("RenderContext", true); pVkRHI->Start(); m_pDevice = pVkRHI->GetPrimaryDevice(); #else - IMetalRHI* pMtlRHI = (IMetalRHI*)GlobalModuleManager.FindModule("RHI_Metal"); + auto pMtlRHI = k3d::StaticPointerCast(ACQUIRE_PLUGIN(RHI_Metal)); if(pMtlRHI) { pMtlRHI->Start(); @@ -77,6 +77,7 @@ namespace render void RenderContext::Destroy() { + m_pDevice->WaitIdle(); KLOG(Info, "RenderContext", "Destroyed Render Context."); } diff --git a/Source/Tools/MayaDCC/DCTranslator.h b/Source/Tools/MayaDCC/DCTranslator.h index 665d3f2..7ed8e9f 100755 --- a/Source/Tools/MayaDCC/DCTranslator.h +++ b/Source/Tools/MayaDCC/DCTranslator.h @@ -5,7 +5,7 @@ #include "MayaCommon.h" #include -#include +#include #include #include #include diff --git a/Source/Tools/ShaderGen/CMakeLists.txt b/Source/Tools/ShaderGen/CMakeLists.txt index fbe4adc..ba5a9f5 100755 --- a/Source/Tools/ShaderGen/CMakeLists.txt +++ b/Source/Tools/ShaderGen/CMakeLists.txt @@ -1,7 +1,6 @@ -add_definitions(-DUSE_GLSLANG=1) - +add_definitions(-DUSE_GLSLANG=1 -DAMD_EXTENSIONS) include_directories(${DXSDK_INCLUDE_DIR} .) -ADD_DEFINITIONS(-DAMD_EXTENSIONS) + set(COMPILER_SRCS Private/ShaderCompiler.cc Private/DXCompiler.cc Private/GLSLCompiler.cc Private/DXCompiler.h Private/GLSLCompiler.h @@ -14,10 +13,17 @@ source_group("Compiler\\Private" FILES ${COMPILER_SRCS}) set(PUB_SRCS Public/ShaderCompiler.h) source_group("Compiler\\Public" FILES ${PUB_SRCS}) -add_plugin(ShaderCompiler "Tools" ${COMPILER_SRCS} ${PUB_SRCS}) -target_link_libraries(ShaderCompiler ${GLSLANG_LIBRARIES} ${SPIRV2CROSS_LIBRARY}) +add_plugin(ShaderCompiler + FOLDER "Tools" + SRCS ${COMPILER_SRCS} ${PUB_SRCS} + LIBS ${GLSLANG_LIBRARIES} ${SPIRV2CROSS_LIBRARY}) -if(MACOS) +if(MACOS AND BUILD_SHARED) add_custom_command(TARGET ShaderCompiler POST_BUILD COMMAND ${CMAKE_INSTALL_NAME_TOOL} -id "@loader_path/../Frameworks/libShaderCompiler.dylib" $) endif() + +install(TARGETS ShaderCompiler + ARCHIVE DESTINATION lib + LIBRARY DESTINATION lib + RUNTIME DESTINATION bin) diff --git a/Source/Tools/ShaderGen/Private/GLSLCompiler.cc b/Source/Tools/ShaderGen/Private/GLSLCompiler.cc index d8d9604..32b4417 100755 --- a/Source/Tools/ShaderGen/Private/GLSLCompiler.cc +++ b/Source/Tools/ShaderGen/Private/GLSLCompiler.cc @@ -34,28 +34,6 @@ namespace k3d { return ESemantic::ENumSemanics; } - - static void sInitializeGlSlang() - { -#if USE_GLSLANG - static bool sGlSlangIntialized = false; - if (!sGlSlangIntialized) { - glslang::InitializeProcess(); - sGlSlangIntialized = true; - } -#endif - } - - static void sFinializeGlSlang() - { -#if USE_GLSLANG - static bool sGlSlangFinalized = false; - if (!sGlSlangFinalized) { - glslang::FinalizeProcess(); - //sGlSlangFinalized = true; - } -#endif - } GLSLangCompiler::GLSLangCompiler() { diff --git a/Source/Tools/ShaderGen/Private/GLSLangUtils.cc b/Source/Tools/ShaderGen/Private/GLSLangUtils.cc index ea03776..a6478be 100755 --- a/Source/Tools/ShaderGen/Private/GLSLangUtils.cc +++ b/Source/Tools/ShaderGen/Private/GLSLangUtils.cc @@ -4,6 +4,28 @@ using namespace ::glslang; +void sInitializeGlSlang() +{ +#if USE_GLSLANG + static bool sGlSlangIntialized = false; + if (!sGlSlangIntialized) { + glslang::InitializeProcess(); + sGlSlangIntialized = true; + } +#endif +} + +void sFinializeGlSlang() +{ +#if USE_GLSLANG + static bool sGlSlangFinalized = false; + if (!sGlSlangFinalized) { + glslang::FinalizeProcess(); + sGlSlangFinalized = true; + } +#endif +} + rhi::shc::EDataType glTypeToRHIAttribType(int glType) { using namespace rhi::shc; @@ -315,7 +337,25 @@ void ExtractUniformData(rhi::EShaderType const& stype, const glslang::TProgram& auto qualifier = type->getQualifier(); if (qualifier.hasBinding()) { - outUniformLayout.AddBinding({ glslangTypeToRHIType(baseType), name, stype, qualifier.layoutBinding }); + rhi::shc::EBindType bind = glslangTypeToRHIType(baseType); + if (baseType == EbtSampler) + { + if (type->getSampler().isCombined()) + { + bind = rhi::shc::EBindType::ESamplerImageCombine; + } + switch (type->getSampler().dim) + { + case Esd1D: + case Esd2D: + case Esd3D: + case EsdCube: + case EsdRect: + bind = rhi::shc::EBindType::ESampledImage; + break; + } + } + outUniformLayout.AddBinding({ bind, name, stype, qualifier.layoutBinding }); } if (qualifier.hasSet()) { @@ -356,4 +396,4 @@ void ExtractUniformData(rhi::EShaderType const& stype, const glslang::TProgram& break; } } -} \ No newline at end of file +} diff --git a/Source/Tools/ShaderGen/Private/GLSLangUtils.h b/Source/Tools/ShaderGen/Private/GLSLangUtils.h index 15b8f12..9a31827 100755 --- a/Source/Tools/ShaderGen/Private/GLSLangUtils.h +++ b/Source/Tools/ShaderGen/Private/GLSLangUtils.h @@ -1,7 +1,10 @@ #pragma once -#include +#include #include +void sInitializeGlSlang(); +void sFinializeGlSlang(); + void initResources(TBuiltInResource &resources); EShLanguage findLanguage(const rhi::EShaderType shader_type); rhi::shc::EDataType glTypeToRHIAttribType(int glType); @@ -10,4 +13,4 @@ rhi::shc::EDataType glslangDataTypeToRHIDataType(const glslang::TType& type); rhi::shc::EBindType glslangTypeToRHIType(const glslang::TBasicType& type); void ExtractAttributeData(const glslang::TProgram& program, rhi::shc::Attributes& shAttributes); -void ExtractUniformData(rhi::EShaderType const& type, const glslang::TProgram& program, rhi::shc::BindingTable& outUniformLayout); \ No newline at end of file +void ExtractUniformData(rhi::EShaderType const& type, const glslang::TProgram& program, rhi::shc::BindingTable& outUniformLayout); diff --git a/Source/Tools/ShaderGen/Private/MetalCompiler.cc b/Source/Tools/ShaderGen/Private/MetalCompiler.cc index 1e80071..aad39b5 100755 --- a/Source/Tools/ShaderGen/Private/MetalCompiler.cc +++ b/Source/Tools/ShaderGen/Private/MetalCompiler.cc @@ -19,6 +19,16 @@ namespace k3d { EResult mtlCompile(string const& source, String & metalIR); + MetalCompiler::MetalCompiler() + { + sInitializeGlSlang(); + } + + MetalCompiler::~MetalCompiler() + { + sFinializeGlSlang(); + } + EResult MetalCompiler::Compile(String const& src, rhi::ShaderDesc const& inOp, rhi::ShaderBundle & bundle) { if(inOp.Format == rhi::EShFmt_Text) @@ -87,10 +97,46 @@ namespace k3d } std::vector spirv; glslang::GlslangToSpv(*program.getIntermediate(stage), spirv); - + + if(program.buildReflection()) + { + ExtractAttributeData(program, bundle.Attributes); + ExtractUniformData(inOp.Stage, program, bundle.BindingTable); + } + else + { + return rhi::shc::E_Failed; + } + uint32 bufferLoc = 0; + std::vector vertAttrs; + for(auto & attr : bundle.Attributes) + { + spirv_cross::MSLVertexAttr vAttrib; + vAttrib.location = attr.VarLocation; + vAttrib.msl_buffer = attr.VarBindingPoint; + vertAttrs.push_back(vAttrib); + bufferLoc = attr.VarBindingPoint; + } + std::vector resBindings; + for(auto & binding : bundle.BindingTable.Bindings) + { + if(binding.VarType == EBindType::EBlock) + { + bufferLoc ++; + spirv_cross::MSLResourceBinding resBind; + resBind.stage = rhiShaderStageToSpvModel(binding.VarStage); + resBind.desc_set = 0; + resBind.binding = binding.VarNumber; + resBind.msl_buffer = bufferLoc; + resBindings.push_back(resBind); + } + } auto metalc = make_unique(spirv); - auto result = metalc->compile(); - + spirv_cross::MSLConfiguration config; + config.flip_vert_y = false; + config.flip_frag_y = false; + config.entry_point_name = inOp.EntryFunction.CStr(); + auto result = metalc->compile(config, &vertAttrs, &resBindings); if(m_IsMac) { auto ret = mtlCompile(result, bundle.RawData); @@ -162,7 +208,7 @@ namespace k3d bcFile.Open(tmpLib.c_str(), IORead); metalIR = { bcFile.FileData(), (size_t)bcFile.GetSize() }; bcFile.Close(); - Os::Remove(intermediate.c_str()); + //Os::Remove(intermediate.c_str()); #endif return E_Ok; } diff --git a/Source/Tools/ShaderGen/Private/MetalCompiler.h b/Source/Tools/ShaderGen/Private/MetalCompiler.h index bd3d945..5da68e5 100755 --- a/Source/Tools/ShaderGen/Private/MetalCompiler.h +++ b/Source/Tools/ShaderGen/Private/MetalCompiler.h @@ -7,8 +7,8 @@ namespace k3d class MetalCompiler : public rhi::IShCompiler { public: - MetalCompiler() {} - ~MetalCompiler() override {} + MetalCompiler(); + ~MetalCompiler() override; rhi::shc::EResult Compile(String const& src, rhi::ShaderDesc const& inOp, rhi::ShaderBundle & bundle) override; diff --git a/Source/Tools/ShaderGen/Private/SPIRVCrossUtils.cc b/Source/Tools/ShaderGen/Private/SPIRVCrossUtils.cc index 0bfcf18..f2d47b3 100755 --- a/Source/Tools/ShaderGen/Private/SPIRVCrossUtils.cc +++ b/Source/Tools/ShaderGen/Private/SPIRVCrossUtils.cc @@ -61,6 +61,17 @@ rhi::shc::EDataType spirTypeToRHIAttribType(const spirv_cross::SPIRType& spirTyp return result; } +spv::ExecutionModel rhiShaderStageToSpvModel(rhi::EShaderType const& type) +{ + switch(type) + { + case rhi::ES_Vertex: + return spv::ExecutionModelVertex; + case rhi::ES_Fragment: + return spv::ExecutionModelFragment; + } + return spv::ExecutionModelVertex; +} rhi::shc::EDataType spirTypeToGlslUniformDataType(const spirv_cross::SPIRType& spirType) { diff --git a/Source/Tools/ShaderGen/Private/SPIRVCrossUtils.h b/Source/Tools/ShaderGen/Private/SPIRVCrossUtils.h index 98a09e8..d2f94c3 100755 --- a/Source/Tools/ShaderGen/Private/SPIRVCrossUtils.h +++ b/Source/Tools/ShaderGen/Private/SPIRVCrossUtils.h @@ -1,11 +1,11 @@ #pragma once -#include +#include #include #include #include rhi::shc::EDataType spirTypeToRHIAttribType(const spirv_cross::SPIRType& spirType); rhi::shc::EDataType spirTypeToGlslUniformDataType(const spirv_cross::SPIRType& spirType); - +spv::ExecutionModel rhiShaderStageToSpvModel(rhi::EShaderType const& type); void ExtractAttributeData(spirv_cross::CompilerGLSL const& backCompiler, rhi::shc::Attributes & outShaderAttributes); void ExtractUniformData(rhi::EShaderType shaderStage, spirv_cross::CompilerGLSL const& backCompiler, rhi::shc::BindingTable& outUniformLayout); \ No newline at end of file diff --git a/Source/Tools/ShaderGen/Private/ShaderCompiler.cc b/Source/Tools/ShaderGen/Private/ShaderCompiler.cc index d1bf903..fe7f1e9 100755 --- a/Source/Tools/ShaderGen/Private/ShaderCompiler.cc +++ b/Source/Tools/ShaderGen/Private/ShaderCompiler.cc @@ -1,4 +1,6 @@ +#include #include "Public/ShaderCompiler.h" +#include #include "GLSLCompiler.h" #if _WIN32 #include "DXCompiler.h" @@ -12,7 +14,10 @@ class ShaderCompilerModule : public rhi::IShModule { public: ShaderCompilerModule() {} - ~ShaderCompilerModule() override {} + ~ShaderCompilerModule() override + { + KLOG(Info, ShaderCompilerModule, "Destroying.."); + } void Start() override {} void Shutdown() override {} diff --git a/Source/Tools/ShaderGen/Public/ShaderCompiler.h b/Source/Tools/ShaderGen/Public/ShaderCompiler.h index 5324392..0bb2230 100755 --- a/Source/Tools/ShaderGen/Public/ShaderCompiler.h +++ b/Source/Tools/ShaderGen/Public/ShaderCompiler.h @@ -1,8 +1,8 @@ #ifndef __ShaderGen_h__ #define __ShaderGen_h__ -#include -#include +#include +#include #include #include diff --git a/Source/UnitTest/1.Device/UnitTestRHIDevice.cpp b/Source/UnitTest/1.Device/UnitTestRHIDevice.cpp deleted file mode 100755 index 810579a..0000000 --- a/Source/UnitTest/1.Device/UnitTestRHIDevice.cpp +++ /dev/null @@ -1,37 +0,0 @@ -#include "UnitTestRHIDevice.h" -#include -#include -#include - -K3D_APP_MAIN(UnitTestRHIDevice); - -using namespace rhi; -using namespace k3d; - -bool UnitTestRHIDevice::OnInit() -{ - App::OnInit(); -#if K3DPLATFORM_OS_WIN || K3DPLATFORM_OS_ANDROID - IVkRHI* pVkRHI = (IVkRHI*)GlobalModuleManager.FindModule("RHI_Vulkan"); - pVkRHI->Initialize("UnitTestRHIDevice", false); - pVkRHI->Start(); - m_TestDevice = pVkRHI->GetPrimaryDevice(); -#else - IMetalRHI* pMtlRHI = (IMetalRHI*)GlobalModuleManager.FindModule("RHI_Metal"); - if(pMtlRHI) - { - pMtlRHI->Start(); - m_TestDevice = pMtlRHI->GetPrimaryDevice(); - } -#endif - return true; -} - -void UnitTestRHIDevice::OnDestroy() -{ - App::OnDestroy(); -} - -void UnitTestRHIDevice::OnProcess(Message & msg) -{ -} diff --git a/Source/UnitTest/1.Device/UnitTestRHIDevice.h b/Source/UnitTest/1.Device/UnitTestRHIDevice.h deleted file mode 100755 index e1b21b9..0000000 --- a/Source/UnitTest/1.Device/UnitTestRHIDevice.h +++ /dev/null @@ -1,23 +0,0 @@ -#pragma once -#include -#include -#include -#include - -using namespace k3d; - -class UnitTestRHIDevice : public App -{ -public: - explicit UnitTestRHIDevice(kString const & appName) - : App(appName, 1920, 1080) - {} - - bool OnInit() override; - void OnDestroy() override; - void OnProcess(Message & msg) override; - -private: - - rhi::DeviceRef m_TestDevice; -}; \ No newline at end of file diff --git a/Source/UnitTest/Base/Common.h b/Source/UnitTest/Base/Common.h deleted file mode 100755 index 0f19794..0000000 --- a/Source/UnitTest/Base/Common.h +++ /dev/null @@ -1,41 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include - -#include -#include - -using threadptr = std::shared_ptr; - -#define JOIN_TESTS(...) \ -threadptr tests[] = { __VA_ARGS__ }; \ -for (auto t : tests) \ -{ \ - t->join(); \ -} - - -extern threadptr TestBundle(); - -extern threadptr TestOs(); - -extern threadptr TestString(); - -extern threadptr TestWebSocket(); - -extern threadptr TestShaderCompiler(); - -extern threadptr TestSharedPtr(); - -extern threadptr TestDynArrray(); diff --git a/Source/UnitTest/Base/Main.cpp b/Source/UnitTest/Base/Main.cpp deleted file mode 100755 index 6b6cc64..0000000 --- a/Source/UnitTest/Base/Main.cpp +++ /dev/null @@ -1,11 +0,0 @@ -#include "Common.h" - -#if K3DPLATFORM_OS_WIN -#pragma comment(linker,"/subsystem:console") -#endif - -int main(int argc, char**argv) -{ - JOIN_TESTS(TestBundle(), TestOs(), TestShaderCompiler(), TestWebSocket(), TestSharedPtr(), TestString(), TestDynArrray()); - return 0; -} diff --git a/Source/UnitTest/Base/UTCore.Os.cpp b/Source/UnitTest/Base/UTCore.Os.cpp deleted file mode 100755 index 5045f62..0000000 --- a/Source/UnitTest/Base/UTCore.Os.cpp +++ /dev/null @@ -1,12 +0,0 @@ -#include "Common.h" - -using namespace k3d; - -threadptr TestOs() -{ - auto ret = std::make_shared([]() { - K3D_ASSERT(Os::MakeDir(KT("./TestOs"))); - K3D_ASSERT(Os::Remove(KT("./TestOs"))); - }); - return ret; -} diff --git a/Source/UnitTest/Base/UTCore.String.cpp b/Source/UnitTest/Base/UTCore.String.cpp deleted file mode 100755 index c729fa9..0000000 --- a/Source/UnitTest/Base/UTCore.String.cpp +++ /dev/null @@ -1,32 +0,0 @@ -#include "Common.h" - -using namespace k3d; -using namespace std; - -String toBeRemoved("Love you later."); - -threadptr TestString() -{ - auto ret = std::make_shared([]() { - String testString("HeyYou!"); - cout << testString.CStr() << endl; - String testStringBaby("BabyGirl!!"); - testStringBaby.Swap(testString); - cout << testString.CStr() << endl; - - testString += toBeRemoved; - testString += ".."; - cout << testString.CStr() << endl; - - testString.AppendSprintf("%d %s", 5, "fhdsfjdhjkfdhksfhdkjshfjkdshfk"); - cout << testString.CStr() << endl; - - //Archive ar; - //ar << testString; - - String testMoveString(Move(toBeRemoved)); - cout << "testMove:" << testMoveString.CStr() - << " original:" << (toBeRemoved.CStr()?toBeRemoved.CStr():"null") << endl; - }); - return ret; -} diff --git a/Source/UnitTest/Base/UTKTL.DynArray.cpp b/Source/UnitTest/Base/UTKTL.DynArray.cpp deleted file mode 100755 index 658f9c3..0000000 --- a/Source/UnitTest/Base/UTKTL.DynArray.cpp +++ /dev/null @@ -1,68 +0,0 @@ -#include "Common.h" - -using namespace std; -using namespace k3d; - -struct B -{ - B() : msg_(nullptr) - { - std::cout << "construct" << std::endl; - } - B(const char* msg) : msg_(msg) - { - std::cout << msg << std::endl; - } - - B& operator=(const B& rhs) - { - std::cout << "rhs " << rhs.msg_ - << " assigned to " << std::endl; - this->msg_ = rhs.msg_; - return *this; - } - - ~B() - { - std::cout << "deconstructB " << msg_ << std::endl; - } - const char *msg_; -}; - -threadptr TestDynArrray() -{ - auto ret = std::make_shared([]() { - B b1{ "b1" }, b3{ "b3" }; - DynArray ints; - ints.Append(5).Append(6).Append(7).Append(0).Append(8); - std::cout << ints[3] << std::endl; - ints[3] = 0; - - std::cout << "for begin - end test start-----" << std::endl; - for (auto& iter : ints) - { - std::cout << iter << std::endl; - } - std::cout << "for begin - end test end-----" << std::endl; - - std::cout << ints[3] << std::endl; - std::cout << ints.Count() << std::endl; - { - B b2{ "b2" }; - DynArray bs; - bs.Append(b1) - .Append(std::move(b2)) - .Append(b3); - bs[2] = B("B modified"); - } - { - DynArray bs; - bs.Append(B("A1")) - .Append(B("A2")) - .Append(B("A3")) - .Append(B("A4")) - .Append(B("A5")); - } - }); - return ret; -} diff --git a/Source/UnitTest/Base/UTKTL.SharedPtr.cpp b/Source/UnitTest/Base/UTKTL.SharedPtr.cpp deleted file mode 100755 index f6cffbd..0000000 --- a/Source/UnitTest/Base/UTKTL.SharedPtr.cpp +++ /dev/null @@ -1,47 +0,0 @@ -#include "Common.h" -#include -#include -#include - -using namespace std; -using namespace k3d; - -class SharedTest -{ -public: - SharedTest() - { - - } - ~SharedTest() - { - cout << "SharedTest Destroy. " << endl; - } -}; - -threadptr TestSharedPtr() -{ - auto ret = std::make_shared([]() { - SharedPtr spFile(new Os::File); - cout << "file:" << spFile.UseCount() << endl; - - SharedPtr spCam(new CameraData); - spCam.UseCount(); - spCam->SetName("TestSharedPtr"); - - SharedPtr spTest(new SharedTest); - cout << "SharedTest:" << spTest.UseCount() << endl; - - SharedPtr ioFile = spFile; - K3D_ASSERT(ioFile.UseCount()==2); - - auto makeShared = MakeShared(); - makeShared->Open(KT("TestSharedPtr"), IOWrite); - - auto refMakeShared = makeShared; - cout << "refMakeShared:" << refMakeShared.UseCount() << endl; - - refMakeShared->Close(); - }); - return ret; -} diff --git a/Source/UnitTest/Base/UTTools.ShaderCompiler.cpp b/Source/UnitTest/Base/UTTools.ShaderCompiler.cpp deleted file mode 100755 index 7b8285a..0000000 --- a/Source/UnitTest/Base/UTTools.ShaderCompiler.cpp +++ /dev/null @@ -1,88 +0,0 @@ -#include "Common.h" -#include -#include - -using namespace std; -using namespace k3d; - -threadptr TestShaderCompiler() -{ - auto ret = std::make_shared([]() { - - Os::MemMapFile vShFile; - vShFile.Open("../../Data/Test/testCompiler.glsl", IOFlag::IORead); - String vertexSource((const char*)vShFile.FileData()); - vShFile.Close(); - - rhi::IShModule* shMod = (rhi::IShModule*)GlobalModuleManager.FindModule("ShaderCompiler"); - if (shMod) - { - // test compile - SharedPtr vkCompiler = shMod->CreateShaderCompiler(rhi::ERHI_Vulkan); - if (vkCompiler) - { - rhi::ShaderDesc desc = { rhi::EShFmt_Text, rhi::EShLang_GLSL, rhi::EShProfile_Modern, rhi::ES_Vertex, "main" }; - rhi::ShaderBundle bundle; - auto ret = vkCompiler->Compile(vertexSource, desc, bundle); - K3D_ASSERT(ret == rhi::shc::E_Ok); - - // test shader serialize - Os::File shBundle; - shBundle.Open(KT("shaderbundle.sh"), IOWrite); - Archive ar; - ar.SetIODevice(&shBundle); - ar << bundle; - shBundle.Close(); - - // write spirv to file - Os::File spirvFile; - spirvFile.Open(KT("triangle.spv"), IOWrite); - spirvFile.Write(bundle.RawData.Data(), bundle.RawData.Length()); - spirvFile.Close(); - - // test shader deserialize; - Os::File shBundleRead; - rhi::ShaderBundle bundleRead; - shBundleRead.Open(KT("shaderbundle.sh"), IORead); - Archive readar; - readar.SetIODevice(&shBundleRead); - readar >> bundleRead; - shBundleRead.Close(); - - // test hlsl compile - rhi::ShaderBundle hlslBundle; - Os::MemMapFile hlslVertFile; - hlslVertFile.Open("../../Data/Test/TestMaterial.hlsl", IOFlag::IORead); - rhi::ShaderDesc hlsldesc = { rhi::EShFmt_Text, rhi::EShLang_HLSL, rhi::EShProfile_Modern, rhi::ES_Vertex, "main" }; - auto hlslret = vkCompiler->Compile(String((const char*)hlslVertFile.FileData()), hlsldesc, hlslBundle); - K3D_ASSERT(hlslret == rhi::shc::E_Ok); - - // test spirv reflect - Os::MemMapFile spirvFileRead; - rhi::ShaderBundle spirvBundle; - spirvFileRead.Open(KT("triangle.spv"), IORead); - rhi::ShaderDesc spirvDesc = { rhi::EShFmt_ByteCode, rhi::EShLang_GLSL, rhi::EShProfile_Modern, rhi::ES_Vertex, "main" }; - auto spirvRet = vkCompiler->Compile(String(spirvFileRead.FileData(), spirvFileRead.GetSize()), spirvDesc, spirvBundle); - K3D_ASSERT(spirvRet == rhi::shc::E_Ok); - } - - SharedPtr mtlCompiler = shMod->CreateShaderCompiler(rhi::ERHI_Metal); - if(mtlCompiler) - { - rhi::ShaderDesc desc = { rhi::EShFmt_Text, rhi::EShLang_GLSL, rhi::EShProfile_Modern, rhi::ES_Vertex, "main" }; - rhi::ShaderBundle bundle; - auto ret = mtlCompiler->Compile(vertexSource, desc, bundle); - K3D_ASSERT(ret == rhi::shc::E_Ok); - - // test shader serialize - Os::File shBundle; - shBundle.Open(KT("metalshaderbundle.sh"), IOWrite); - Archive ar; - ar.SetIODevice(&shBundle); - ar << bundle; - shBundle.Close(); - } - } - }); - return ret; -} diff --git a/Source/UnitTest/CMakeLists.txt b/Source/UnitTest/CMakeLists.txt deleted file mode 100755 index d891cc0..0000000 --- a/Source/UnitTest/CMakeLists.txt +++ /dev/null @@ -1,39 +0,0 @@ -add_definitions(-DBUILD_SHARED_LIB -DBUILD_WITH_PLUGIN) - -################################## Unit Test For RHI ##################################### - -add_unittest( - 1.Device - 1.Device/UnitTestRHIDevice.h - 1.Device/UnitTestRHIDevice.cpp -) - -add_unittest( - 2.SwapChainPresent - 2.SwapChain/SwapChainPresent.cpp -) - -add_unittest( - 3.Triangle - 3.Triangle/Triangle.cpp -) - -add_unittest( - 4.TexturedCube - 4.TexturedCube/TexturedCube.cpp - 4.TexturedCube/TextureObject.h - 4.TexturedCube/TextureObject.cpp -) - -add_unittest( - 0.BaseComponents - Base/Common.h - Base/UTCore.Bundle.cpp - Base/UTCore.Os.cpp - Base/UTCore.WebSocket.cpp - Base/UTTools.ShaderCompiler.cpp - Base/UTKTL.SharedPtr.cpp - Base/UTKTL.DynArray.cpp - Base/UTCore.String.cpp - Base/Main.cpp -) diff --git a/Source/UnitTest/RHI_Metal/Assets.xcassets/AppIcon.appiconset/Contents.json b/Source/UnitTest/RHI_Metal/Assets.xcassets/AppIcon.appiconset/Contents.json deleted file mode 100755 index 2db2b1c..0000000 --- a/Source/UnitTest/RHI_Metal/Assets.xcassets/AppIcon.appiconset/Contents.json +++ /dev/null @@ -1,58 +0,0 @@ -{ - "images" : [ - { - "idiom" : "mac", - "size" : "16x16", - "scale" : "1x" - }, - { - "idiom" : "mac", - "size" : "16x16", - "scale" : "2x" - }, - { - "idiom" : "mac", - "size" : "32x32", - "scale" : "1x" - }, - { - "idiom" : "mac", - "size" : "32x32", - "scale" : "2x" - }, - { - "idiom" : "mac", - "size" : "128x128", - "scale" : "1x" - }, - { - "idiom" : "mac", - "size" : "128x128", - "scale" : "2x" - }, - { - "idiom" : "mac", - "size" : "256x256", - "scale" : "1x" - }, - { - "idiom" : "mac", - "size" : "256x256", - "scale" : "2x" - }, - { - "idiom" : "mac", - "size" : "512x512", - "scale" : "1x" - }, - { - "idiom" : "mac", - "size" : "512x512", - "scale" : "2x" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} \ No newline at end of file diff --git a/Source/UnitTest/RHI_Metal/Base.lproj/MainMenu.xib b/Source/UnitTest/RHI_Metal/Base.lproj/MainMenu.xib deleted file mode 100755 index e084772..0000000 --- a/Source/UnitTest/RHI_Metal/Base.lproj/MainMenu.xib +++ /dev/null @@ -1,686 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Default - - - - - - - Left to Right - - - - - - - Right to Left - - - - - - - - - - - Default - - - - - - - Left to Right - - - - - - - Right to Left - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Source/UnitTest/RHI_Metal/Info.plist b/Source/UnitTest/RHI_Metal/Info.plist deleted file mode 100755 index 6b49211..0000000 --- a/Source/UnitTest/RHI_Metal/Info.plist +++ /dev/null @@ -1,34 +0,0 @@ - - - - - CFBundleDevelopmentRegion - en - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIconFile - - CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - $(PRODUCT_NAME) - CFBundlePackageType - APPL - CFBundleShortVersionString - 1.0 - CFBundleSignature - ???? - CFBundleVersion - 1 - LSMinimumSystemVersion - $(MACOSX_DEPLOYMENT_TARGET) - NSHumanReadableCopyright - Copyright © 2015年 TsinStudio. All rights reserved. - NSMainNibFile - MainMenu - NSPrincipalClass - NSApplication - - diff --git a/Source/UnitTest/RHI_Metal/Shaders.metal b/Source/UnitTest/RHI_Metal/Shaders.metal deleted file mode 100755 index 65b71ea..0000000 --- a/Source/UnitTest/RHI_Metal/Shaders.metal +++ /dev/null @@ -1,52 +0,0 @@ -// -// Shaders.metal -// mdemo -// -// Created by QinZhou on 15/9/1. -// Copyright (c) 2015年 TsinStudio. All rights reserved. -// - -#include -#include -#include "SharedStructures.h" - -using namespace metal; - -// Variables in constant address space -constant float3 light_position = float3(0.0, 1.0, -1.0); -constant float4 ambient_color = float4(0.18, 0.24, 0.8, 1.0); -constant float4 diffuse_color = float4(0.4, 0.4, 1.0, 1.0); - -typedef struct -{ - float3 position [[attribute(0)]]; - float3 normal [[attribute(1)]]; -} vertex_t; - -typedef struct { - float4 position [[position]]; - half4 color; -} ColorInOut; - -// Vertex shader function -vertex ColorInOut lighting_vertex(vertex_t vertex_array [[stage_in]], - constant uniforms_t& uniforms [[ buffer(1) ]]) -{ - ColorInOut out; - - float4 in_position = float4(vertex_array.position, 1.0); - out.position = uniforms.modelview_projection_matrix * in_position; - - float4 eye_normal = normalize(uniforms.normal_matrix * float4(vertex_array.normal, 0.0)); - float n_dot_l = dot(eye_normal.rgb, normalize(light_position)); - n_dot_l = fmax(0.0, n_dot_l); - - out.color = half4(ambient_color + diffuse_color * n_dot_l); - return out; -} - -// Fragment shader function -fragment half4 lighting_fragment(ColorInOut in [[stage_in]]) -{ - return in.color; -} \ No newline at end of file diff --git a/Source/UnitTest/RHI_Metal/SharedStructures.h b/Source/UnitTest/RHI_Metal/SharedStructures.h deleted file mode 100755 index 7ebee47..0000000 --- a/Source/UnitTest/RHI_Metal/SharedStructures.h +++ /dev/null @@ -1,21 +0,0 @@ -// -// SharedStructures.h -// mdemo -// -// Created by QinZhou on 15/9/1. -// Copyright (c) 2015年 TsinStudio. All rights reserved. -// - -#ifndef SharedStructures_h -#define SharedStructures_h - -#include - -typedef struct __attribute__((__aligned__(256))) -{ - matrix_float4x4 modelview_projection_matrix; - matrix_float4x4 normal_matrix; -} uniforms_t; - -#endif /* SharedStructures_h */ - diff --git a/Source/UnitTest/RHI_Metal/UnitTestRHICommandContext.mm b/Source/UnitTest/RHI_Metal/UnitTestRHICommandContext.mm deleted file mode 100755 index 9700e7d..0000000 --- a/Source/UnitTest/RHI_Metal/UnitTestRHICommandContext.mm +++ /dev/null @@ -1,6 +0,0 @@ -#import -#include - -int main(int argc, const char * argv[]) { - return NSApplicationMain(argc, argv); -} diff --git a/Source/UnitTest/RHI_Metal/premake5.lua b/Source/UnitTest/RHI_Metal/premake5.lua deleted file mode 100755 index 62769ad..0000000 --- a/Source/UnitTest/RHI_Metal/premake5.lua +++ /dev/null @@ -1,31 +0,0 @@ -project "UnitTestRHICommandContext" - - language "C++" - - kind "WindowedApp" - - includedirs { - ".", - "../..", - "../../RHI", - "../../../Include" - } - - libdirs { - "../../../Bin" - } - - links { - "Core", "RHI_Metal" - } - - targetdir "../../../Bin" - - files { - "Info.plist", - "Base.lproj/MainMenu.xib", - "**.metal", - "**.mm", - "**.h" - } - linkoptions { "-framework MetalKit", "-framework Cocoa", "-framework Metal", "-framework ModelIO" } \ No newline at end of file diff --git a/Tools/VisualStudioVisualizer/kaleido3d.natvis b/Tools/VisualStudioVisualizer/kaleido3d.natvis new file mode 100644 index 0000000..c26ad51 --- /dev/null +++ b/Tools/VisualStudioVisualizer/kaleido3d.natvis @@ -0,0 +1,17 @@ + + + + {{ size={m_ElementCount} capacity={m_Capacity} }} + + m_Capacity + m_Allocator + + m_ElementCount + m_pElement + + + + + {m_pStringData} + + \ No newline at end of file diff --git a/Tools/WebConsole/index.html b/Tools/WebConsole/index.html new file mode 100644 index 0000000..05c531d --- /dev/null +++ b/Tools/WebConsole/index.html @@ -0,0 +1,22 @@ + + + + + WebConsole - Kaleido3D + + + + + + + + + + + + + +
+
+ + \ No newline at end of file diff --git a/circle.yml b/circle.yml index 775357a..b204505 100755 --- a/circle.yml +++ b/circle.yml @@ -17,7 +17,6 @@ dependencies: - unzip cmake.zip -d /usr/local/android-sdk-linux/cmake - /usr/local/android-sdk-linux/cmake/bin/cmake --version - git clone https://github.com/TsinStudio/android-ndk.git /usr/local/android-sdk-linux/ndk-bundle - - git clone https://github.com/Tomicyo/kaleido3d_dep_prebuilt.git -b android_arm_debug Source/ThirdParty_Prebuilt/Android_ARM_Debug - export ANDROID_NDK_HOME=/usr/local/android-sdk-linux/ndk-bundle - export NDK=/usr/local/android-sdk-linux/ndk-bundle - echo y | android update sdk --no-ui --all --filter tools,platform-tools,build-tools-23.0.2,android-23,extra-google-m2repository,extra-android-support diff --git a/make.cmd b/make.cmd index 9d7130b..9e6e839 100755 --- a/make.cmd +++ b/make.cmd @@ -8,7 +8,7 @@ goto BUILD_BY_CMAKE :CHECK_DEPENDENCIES echo Checkout Dependencies From Github -git clone https://github.com/Tomicyo/kaleido3d_dep_prebuilt.git -b win64_debug Source\ThirdParty_Prebuilt\Win64_Debug +git clone https://github.com/Tomicyo/kaleido3d_dep_prebuilt.git -b win64_Debug Source\ThirdParty_Prebuilt\Win64\Debug goto BUILD_BY_CMAKE @@ -30,30 +30,20 @@ pause exit :BUILD_BY_CMAKE -echo Now build by CMake -if not exist BuildCMakeProj mkdir BuildCMakeProj -pushd %~dp0 -cd BuildCMakeProj - -if defined VS140COMNTOOLS (goto MS2015Build) -if defined VS120COMNTOOLS (goto MS2013Build) else (goto NotSupport) - -:MS2015Build -echo Build By Visual Studio 2015 -cmake -G"Visual Studio 14 2015 Win64" ..\Source -DCMAKE_BUILD_TYPE=Debug -call "%VS140COMNTOOLS%\..\..\VC\vcvarsall.bat" x86_amd64 -msbuild Kaleido3D.sln -goto End +echo Now Generate Project by CMake (VS 2017) +cmake -G"Visual Studio 15 2017 Win64" -HSource -BBuild\Win64\Debug -DCMAKE_BUILD_TYPE=Debug +if "%ERRORLEVEL%"=="0" (goto BUILD_CMAKE) +RD /S /Q Build + +echo Now Generate Project by CMake (VS 2015) +cmake -G"Visual Studio 14 2015 Win64" -HSource -BBuild\Win64\Debug -DCMAKE_BUILD_TYPE=Debug +if "%ERRORLEVEL%"=="0" (goto BUILD_CMAKE) else (goto NotSupport) -:MS2013Build -echo Build By Visual Studio 2013 -cmake -G"Visual Studio 12 2013 Win64" ..\Source -call "%VS120COMNTOOLS%\..\..\VC\vcvarsall.bat" x86_amd64 -msbuild Kaleido3D.sln +:BUILD_CMAKE +cmake --build Build\Win64\Debug --config Debug goto End :NotSupport echo Visual Studio Version not supported! -:End -popd \ No newline at end of file +:End \ No newline at end of file diff --git a/make_android.cmd b/make_android.cmd new file mode 100644 index 0000000..22c5cf3 --- /dev/null +++ b/make_android.cmd @@ -0,0 +1,15 @@ +for /f %%i in ('dir /b %ANDROID_HOME%\cmake') do set CMAKE_DIR=%ANDROID_HOME%\cmake\%%i +set CMAKE_BIN=%CMAKE_DIR%\bin\cmake +set CMAKE_NINJA=%CMAKE_DIR%\bin\ninja +set CMAKE_TOOLCHAIN=%ANDROID_NDK_HOME%\build\cmake\android.toolchain.cmake +set STL=gnustl_shared +set CMAKE_NDK_DEFINES=-DANDROID_NDK=%ANDROID_NDK_HOME% +set CMAKE_ANDROID_DEFINES=%CMAKE_NDK_DEFINES% -DCMAKE_MAKE_PROGRAM=%CMAKE_NINJA% -DANDROID_ABI=armeabi-v7a -DANDROID_NATIVE_API_LEVEL=24 -DANDROID_PLATFORM=android-24 -DANDROID_TOOLCHAIN=clang -DANDROID_STL=%STL% -DANDROID_CPP_FEATURES=rtti;exceptions + +call :Build Debug +exit /b %errorlevel% + +:Build +%CMAKE_BIN% -G"Android Gradle - Ninja" -DCMAKE_TOOLCHAIN_FILE=%CMAKE_TOOLCHAIN% -HSource -BBuild\Android\%~1\%STL% -DCMAKE_BUILD_TYPE=%~1 %CMAKE_ANDROID_DEFINES% +%CMAKE_BIN% --build Build\Android\%~1\%STL% --config %~1 +:End diff --git a/make_android.sh b/make_android.sh new file mode 100755 index 0000000..f1f8485 --- /dev/null +++ b/make_android.sh @@ -0,0 +1,17 @@ +CMAKE_VERSION=`ls $android_home/cmake` +CMAKE_DIR=$android_home/cmake/$CMAKE_VERSION +CMAKE_BIN=$CMAKE_DIR/bin/cmake +CMAKE_NINJA=$CMAKE_DIR/bin/ninja +CMAKE_TOOLCHAIN=$ANDROID_NDK_HOME/build/cmake/android.toolchain.cmake +STL=gnustl_shared +CMAKE_NDK_DEFINES="-DANDROID_NDK=$ANDROID_NDK_HOME" +CMAKE_ANDROID_DEFINES="$CMAKE_NDK_DEFINES -DCMAKE_MAKE_PROGRAM=$CMAKE_NINJA -DANDROID_ABI=armeabi-v7a -DANDROID_NATIVE_API_LEVEL=24 -DANDROID_PLATFORM=android-24 -DANDROID_TOOLCHAIN=clang -DANDROID_STL=$STL -DANDROID_CPP_FEATURES=rtti;exceptions" + +function build() +{ + set -e + $CMAKE_BIN -G"Android Gradle - Ninja" -DCMAKE_TOOLCHAIN_FILE=$CMAKE_TOOLCHAIN -DCMAKE_BUILD_TYPE=$1 $CMAKE_ANDROID_DEFINES -HSource -BBuild/Android/$STL/$1 -DCMAKE_LIBRARY_OUTPUT_DIRECTORY=STL_$1 + $CMAKE_BIN --build Build/Android/$STL/$1 --config $1 --target RHI-UnitTest-3.Triangle +} + +build Debug; \ No newline at end of file diff --git a/make_ios.sh b/make_ios.sh new file mode 100755 index 0000000..302dedf --- /dev/null +++ b/make_ios.sh @@ -0,0 +1,3 @@ +# build projects +cmake -DCMAKE_TOOLCHAIN_FILE=../Project/ios.cmake -DIOS_PLATFORM=OS -HSource -BBuild/IOS/Debug -GXcode -DCMAKE_BUILD_TYPE=Debug +cmake --build Build/IOS/Debug --config Debug \ No newline at end of file diff --git a/make_macos.sh b/make_macos.sh index 5106bca..57bfb17 100755 --- a/make_macos.sh +++ b/make_macos.sh @@ -1,6 +1,2 @@ -if [ ! -d Build ]; then - mkdir Build -fi -cd Build -cmake -G"Xcode" ../Source -DCMAKE_BUILD_TYPE=Debug -xcodebuild \ No newline at end of file +cmake -HSource -BBuild/Mac/Debug -GXcode -DCMAKE_BUILD_TYPE=Debug +cmake --build Build/Mac/Debug --config Debug \ No newline at end of file diff --git a/settings.gradle b/settings.gradle index f87c20a..5f03016 100755 --- a/settings.gradle +++ b/settings.gradle @@ -1,3 +1,3 @@ include ':Project' -include ':Source:UnitTest:Android:Triangle' -include ':Source:UnitTest:Android:TexturedCube' \ No newline at end of file +include ':Source:RHI:UnitTest:Android:Triangle' +include ':Source:RHI:UnitTest:Android:TexturedCube' \ No newline at end of file