diff --git a/.gitignore b/.gitignore index b6b1689e..83de64c9 100644 --- a/.gitignore +++ b/.gitignore @@ -14,3 +14,4 @@ *.lib *.ninja *.check_cache +/out diff --git a/.gitmodules b/.gitmodules index 0d8040fe..abaf2dcd 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,9 +1,3 @@ -[submodule "3rdpty/MathGeoLib"] - path = 3rdpty/MathGeoLib - url = https://github.com/juj/MathGeoLib.git -[submodule "3rdpty/jsoncpp"] - path = 3rdpty/jsoncpp - url = https://github.com/open-source-parsers/jsoncpp [submodule "CMCMakeModule"] path = CMCMakeModule url = https://github.com/hyzboy/CMCMakeModule @@ -22,3 +16,6 @@ [submodule "CMSceneGraph"] path = CMSceneGraph url = https://github.com/hyzboy/CMSceneGraph.git +[submodule "CMUtil"] + path = CMUtil + url = https://github.com/hyzboy/CMUtil.git diff --git a/3rdpty/MathGeoLib b/3rdpty/MathGeoLib deleted file mode 160000 index 47599c77..00000000 --- a/3rdpty/MathGeoLib +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 47599c77c46034c1cd78dbb93ba5f5495c27b185 diff --git a/3rdpty/jsoncpp b/3rdpty/jsoncpp deleted file mode 160000 index 9be58959..00000000 --- a/3rdpty/jsoncpp +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 9be589598595963f94ba264d7b416d0533421106 diff --git a/BUILD.md b/BUILD.md new file mode 100644 index 00000000..ce8f2b36 --- /dev/null +++ b/BUILD.md @@ -0,0 +1,48 @@ +# Build on Windows + +Tested with Visual Studio 2019/2022 and Windows 11 + +please first install [Git](https://git-scm.com/download/win) and [CMake](https://cmake.org/download/) + +and then clone [vcpkg package manager](https://docs.microsoft.com/en-us/cpp/build/vcpkg?view=vs-2022) by git: + + git clone https://github.com/Microsoft/vcpkg.git + cd vcpkg + bootstrap-vcpkg.bat + + +Install [vcpkg package manager](https://docs.microsoft.com/en-us/cpp/build/vcpkg?view=vs-2022) to build required libraries: + + vcpkg install glm:x64-windows jsoncpp:x64-windows expat:x64-windows + vcpkg integrate install + +finish step you can use "cmake" create project file with vcpkg toolchain: + + cmake . -DCMAKE_TOOLCHAIN_FILE=\????\vcpkg\scripts\buildsystems\vcpkg.cmake + +or use "cmake-gui" with "Specify toolchain file for cross-compiling." + +# + +# 在Windows下编译工程 + +以下在Windows 11以及Visual Studio 2019/2022下测试通过 + +首先请安装[Git](https://git-scm.com/download/win)和[CMake](https://cmake.org/download/) + +然后使用git安装[vcpkg package manager](https://docs.microsoft.com/en-us/cpp/build/vcpkg?view=vs-2022) + + git clone https://github.com/Microsoft/vcpkg.git + cd vcpkg + bootstrap-vcpkg.bat + +接着使用[vcpkg package manager](https://docs.microsoft.com/en-us/cpp/build/vcpkg?view=vs-2022)来安装我们所需要的第三方依赖库: + + vcpkg install glm:x64-windows jsoncpp:x64-windows expat:x64-windows + vcpkg integrate install + +最后你就可以使用CMake创建工程文件了: + + cmake . -DCMAKE_TOOLCHAIN_FILE=\????\vcpkg\scripts\buildsystems\vcpkg.cmake + +或是使用cmake-gui以图形界面形式创建,但请在第一个界面选择“Specify toolchain file for cross-compiling”并指定使用vcpkg.cmake做为工具链。 diff --git a/CMakeLists.txt b/CMakeLists.txt index e89d61ed..894c0211 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,36 +8,26 @@ set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/CMCMakeModule) set(ULRE_3RDPTY_ROOT_PATH ${CMAKE_CURRENT_SOURCE_DIR}/3rdpty) -include(vulkan) - include(math) -use_mgl(${ULRE_3RDPTY_ROOT_PATH}/MathGeoLib) - +include(vulkan) include(use_cm_module) + use_cm_module(Core) +use_cm_module(Util) use_cm_module(Platform) use_cm_module(AssetsManage) use_cm_module(SceneGraph) -OPTION(SUPPORT_QT_VULKAN OFF) - -if(CMAKE_SYSTEM_NAME STREQUAL "Windows") - include_directories(${ULRE_3RDPTY_ROOT_PATH}/jsoncpp/include) - add_subdirectory(3rdpty/jsoncpp) - SET(JSONCPP_LIBRARY jsoncpp_lib) -ELSE() - SET(JSONCPP_LIBRARY jsoncpp) -ENDIF() +OPTION(SUPPORT_QT_VULKAN OFF) SET(ULRE CMCore CMPlatform CMAssetsManage CMSceneGraph + CMUtil ULRE.Util - ULRE.RenderDevice.Vulkan ULRE.SceneGraph - MathGeoLib - ${JSONCPP_LIBRARY} + ${HGL_GLM_LIB} ${RENDER_LIBRARY} ${Vulkan_LIBRARIES}) @@ -46,7 +36,7 @@ include_directories(${CMAKE_CURRENT_SOURCE_DIR}/inc) SET(ROOT_INCLUDE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/inc) -SET(ULRE_RUNTIME_PATH ${CMAKE_CURRENT_SOURCE_DIR}) +SET(ULRE_RUNTIME_PATH ${CMAKE_CURRENT_SOURCE_DIR}) add_subdirectory(src) @@ -55,4 +45,4 @@ add_subdirectory(example) IF(SUPPORT_QT_VULKAN) fix_project_version(1,1) add_project_meta(META_FILES_TO_INCLUDE) -ENDIF(SUPPORT_QT_VULKAN) \ No newline at end of file +ENDIF(SUPPORT_QT_VULKAN) diff --git a/README.md b/README.md index a987aa1e..0b391649 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # ULRE -experiment project - Ultra Lightweight Rendering Engine +experiment project - Ultra Lazy Rendering Engine ULRE is a project of experimental nature,Used to experiment with various rendering related techniques,And do some examples. @@ -9,9 +9,7 @@ Platform: Windows,Linux (WIP: Android) Graphics API: Vulkan -'master' branches will not be updated, please try to follow the latest branches or tags. - - +# ULRE是一个试验性质的工程,用于试验各种渲染相关的技术,以及做一些范例。在未来它的复杂化版本会被整合到CMGameEngine中,用于替代旧的渲染引擎。 平台: Windows,Linux (开发中: Android) @@ -21,5 +19,3 @@ ULRE是一个试验性质的工程,用于试验各种渲染相关的技术, ULRE是一个试验性质的工程,用于试验各种渲染相关的技术,以及做一些范例。在未来它的复杂化版本会被整合到CMGameEngine中,用于替代旧的渲染引擎。 -'master'分支不会得到更新,请尽量跟随最新分支或标记 - diff --git a/example/2dVector/CMakeLists.txt b/example/2dVector/CMakeLists.txt new file mode 100644 index 00000000..32a84bf6 --- /dev/null +++ b/example/2dVector/CMakeLists.txt @@ -0,0 +1,12 @@ +macro(CreateProject name) + add_executable(${name} ${ARGN}) + target_link_libraries(${name} ${ULRE}) + + IF(WIN32) + set_target_properties(${name} PROPERTIES VS_DEBUGGER_WORKING_DIRECTORY ${ULRE_RUNTIME_PATH}) + ENDIF() + + set_property(TARGET ${name} PROPERTY FOLDER "ULRE/Example/2dVector") +endmacro() + +CreateProject(00.line line.cpp) diff --git a/example/2dVector/line.cpp b/example/2dVector/line.cpp new file mode 100644 index 00000000..14aa55c3 --- /dev/null +++ b/example/2dVector/line.cpp @@ -0,0 +1,169 @@ +#include"VulkanAppFramework.h" +#include +#include +#include + +using namespace hgl; +using namespace hgl::graph; + +constexpr uint32_t SCREEN_WIDTH=1280; +constexpr uint32_t SCREEN_HEIGHT=720; + +constexpr uint32_t VERTEX_COUNT=4; + +constexpr float vertex_data[VERTEX_COUNT][2]= +{ + {SCREEN_WIDTH*0.5, SCREEN_HEIGHT*0.25}, + {SCREEN_WIDTH*0.75, SCREEN_HEIGHT*0.75}, + {SCREEN_WIDTH*0.25, SCREEN_HEIGHT*0.75}, + {SCREEN_WIDTH*0.5, SCREEN_HEIGHT*0.25}, +}; + +static Vector4f color(1,1,1,1); + +struct Line2DConfig +{ + float width=20.0f; + float border=5.0f; +}; + +static Line2DConfig line_2d_config; + +class TestApp:public VulkanApplicationFramework +{ +private: + + Camera cam; + + MaterialInstance * material_instance =nullptr; + RenderableInstance *render_instance =nullptr; + GPUBuffer * ubo_camera_info =nullptr; + GPUBuffer * ubo_color_material =nullptr; + GPUBuffer * ubo_line_config =nullptr; + + Pipeline * pipeline =nullptr; + +private: + + bool InitMaterial() + { + material_instance=db->CreateMaterialInstance(OS_TEXT("res/material/Line2D")); + + if(!material_instance) + return(false); + +// pipeline=db->CreatePipeline(material_instance,sc_render_target,OS_TEXT("res/pipeline/solid2d")); + pipeline=CreatePipeline(material_instance,OS_TEXT("res/pipeline/alpha2d"),Prim::LineStrip); //等同上一行,为Framework重载,默认使用swapchain的render target + //pipeline=CreatePipeline(material_instance,InlinePipeline::Alpha2D,Prim::LineStrip); //等同上一行,为Framework重载,默认使用swapchain的render target + + if(!pipeline) + return(false); + + return(true); + } + + GPUBuffer *CreateUBO(const AnsiString &name,const VkDeviceSize size,void *data) + { + GPUBuffer *ubo=db->CreateUBO(size,data); + + if(!ubo) + return(nullptr); + + return ubo; + } + + bool InitUBO() + { + const VkExtent2D extent=sc_render_target->GetExtent(); + + cam.width=extent.width; + cam.height=extent.height; + + cam.Refresh(); + + { + MaterialParameters *mp_global=material_instance->GetMP(DescriptorSetsType::Global); + + if(!mp_global) + return(false); + + ubo_camera_info =db->CreateUBO(sizeof(CameraInfo), &cam.info); + + mp_global->BindUBO("g_camera",ubo_camera_info); + mp_global->Update(); + } + + { + + MaterialParameters *mp_value=material_instance->GetMP(DescriptorSetsType::Value); + + if(!mp_value) + return(false); + + ubo_color_material =db->CreateUBO(sizeof(Vector4f), &color); + ubo_line_config =db->CreateUBO(sizeof(Line2DConfig), &line_2d_config); + + mp_value->BindUBO("color_material",ubo_color_material); + mp_value->BindUBO("line2d_config",ubo_line_config); + mp_value->Update(); + } + + return(true); + } + + bool InitVBO() + { + Renderable *render_obj=db->CreateRenderable(VERTEX_COUNT); + if(!render_obj)return(false); + + if(!render_obj->Set(VAN::Position, db->CreateVBO(VF_V2F,VERTEX_COUNT,vertex_data)))return(false); + + render_instance=db->CreateRenderableInstance(render_obj,material_instance,pipeline); + return(true); + } + +public: + + bool Init() + { + if(!VulkanApplicationFramework::Init(SCREEN_WIDTH,SCREEN_HEIGHT)) + return(false); + + if(!InitMaterial()) + return(false); + + if(!InitUBO()) + return(false); + + if(!InitVBO()) + return(false); + + BuildCommandBuffer(render_instance); + + return(true); + } + + void Resize(int w,int h)override + { + cam.width=w; + cam.height=h; + + cam.Refresh(); + + ubo_camera_info->Write(&cam.info); + + BuildCommandBuffer(render_instance); + } +};//class TestApp:public VulkanApplicationFramework + +int main(int,char **) +{ + TestApp app; + + if(!app.Init()) + return(-1); + + while(app.Run()); + + return 0; +} diff --git a/example/CMakeLists.txt b/example/CMakeLists.txt index 1f19bdb7..d1ce92ac 100644 --- a/example/CMakeLists.txt +++ b/example/CMakeLists.txt @@ -1 +1,7 @@ -add_subdirectory(Vulkan) +include_directories(${CMAKE_CURRENT_SOURCE_DIR}/common) + +SET(VULKAN_APP_FRAMEWORK ${CMAKE_CURRENT_SOURCE_DIR}/common/VulkanAppFramework.h) + +add_subdirectory(Vulkan) +add_subdirectory(2dVector) +add_subdirectory(GUI) diff --git a/example/GUI/CMakeLists.txt b/example/GUI/CMakeLists.txt new file mode 100644 index 00000000..20d143bd --- /dev/null +++ b/example/GUI/CMakeLists.txt @@ -0,0 +1,13 @@ +macro(CreateProject name) + add_executable(${name} ${ARGN} GUIAppFramework.h) + target_link_libraries(${name} ${ULRE}) + + IF(WIN32) + set_target_properties(${name} PROPERTIES VS_DEBUGGER_WORKING_DIRECTORY ${ULRE_RUNTIME_PATH}) + ENDIF() + + set_property(TARGET ${name} PROPERTY FOLDER "ULRE/Example/GUI") +endmacro() + +CreateProject(00.control_point_2d control_point_2d.cpp) +CreateProject(01.align_test align_test.cpp) diff --git a/example/GUI/GUIAppFramework.h b/example/GUI/GUIAppFramework.h new file mode 100644 index 00000000..e69de29b diff --git a/example/GUI/align_test.cpp b/example/GUI/align_test.cpp new file mode 100644 index 00000000..e69de29b diff --git a/example/GUI/control_point_2d.cpp b/example/GUI/control_point_2d.cpp new file mode 100644 index 00000000..e69de29b diff --git a/example/Vulkan/Atmosphere.cpp b/example/Vulkan/Atmosphere.cpp new file mode 100644 index 00000000..c3727f4b --- /dev/null +++ b/example/Vulkan/Atmosphere.cpp @@ -0,0 +1,139 @@ +// 8.大气渲染 +// 画一个球,纯粹使用shader计算出颜色 + +#include"VulkanAppFramework.h" +#include +#include +#include +#include +#include + +using namespace hgl; +using namespace hgl::graph; + +constexpr uint32_t SCREEN_WIDTH=512; +constexpr uint32_t SCREEN_HEIGHT=512; + +struct AtmosphereData +{ + Vector3f position; + float intensity; + float scattering_direction; + +public: + + AtmosphereData() + { + position=Vector3f(0,0.1f,-1.0f); + intensity=22.0f; + scattering_direction=0.758f; + } +};//struct AtmosphereData + +class TestApp:public CameraAppFramework +{ +private: + + SceneNode render_root; + RenderList * render_list=nullptr; + + MaterialInstance * material_instance =nullptr; + Pipeline * pipeline_solid =nullptr; + + GPUBuffer * ubo_atomsphere =nullptr; + AtmosphereData atomsphere_data; + + Renderable * ro_sphere =nullptr; + +private: + + bool InitMaterial() + { + material_instance=db->CreateMaterialInstance(OS_TEXT("res/material/Atmosphere")); //不需要优先创建Material,也不需要写扩展名 + if(!material_instance)return(false); + +// pipeline_solid=db->CreatePipeline(material_instance,sc_render_target,OS_TEXT("res/pipeline/sky")); + pipeline_solid=CreatePipeline(material_instance,InlinePipeline::Sky,Prim::Triangles); //等同上一行,为Framework重载,默认使用swapchain的render target + if(!pipeline_solid)return(false); + + return(true); + } + + bool InitUBO() + { + ubo_atomsphere=db->CreateUBO(sizeof(AtmosphereData),&atomsphere_data); + + if(!ubo_atomsphere) + return(false); + + { + MaterialParameters *mp=material_instance->GetMP(DescriptorSetsType::Value); + + if(!mp)return(false); + + if(!mp->BindUBO("sun",ubo_atomsphere)) + return(false); + + mp->Update(); + } + return(true); + } + + bool InitScene() + { + ro_sphere=CreateRenderableSphere(db,material_instance->GetVAB(),128); + + render_root.CreateSubNode(scale(100),db->CreateRenderableInstance(ro_sphere,material_instance,pipeline_solid)); + + render_root.RefreshMatrix(); + render_list->Expend(GetCameraInfo(),&render_root); + + return(true); + } + +public: + + ~TestApp() + { + SAFE_CLEAR(render_list); + } + + bool Init() + { + if(!CameraAppFramework::Init(SCREEN_WIDTH,SCREEN_HEIGHT)) + return(false); + + render_list=new RenderList(device); + + if(!InitMaterial()) + return(false); + + if(!InitUBO()) + return(false); + + if(!InitScene()) + return(false); + + return(true); + } + + void BuildCommandBuffer(uint32_t index) override + { + render_root.RefreshMatrix(); + render_list->Expend(GetCameraInfo(),&render_root); + + VulkanApplicationFramework::BuildCommandBuffer(index,render_list); + } +};//class TestApp:public CameraAppFramework + +int main(int,char **) +{ + TestApp app; + + if(!app.Init()) + return(-1); + + while(app.Run()); + + return 0; +} diff --git a/example/Vulkan/Atomsphere.cpp b/example/Vulkan/Atomsphere.cpp deleted file mode 100644 index b5150fe6..00000000 --- a/example/Vulkan/Atomsphere.cpp +++ /dev/null @@ -1,158 +0,0 @@ -// 8.大气渲染 -// 画一个球,纯粹使用shader计算出颜色 - -#include"VulkanAppFramework.h" -#include -#include -#include -#include -#include - -using namespace hgl; -using namespace hgl::graph; - -constexpr uint32_t SCREEN_WIDTH=128; -constexpr uint32_t SCREEN_HEIGHT=128; - -struct AtomsphereData -{ - Vector3f position; - float intensity; - float scattering_direction; -};// - -class TestApp:public CameraAppFramework -{ -private: - - SceneNode render_root; - RenderList render_list; - - vulkan::Material * material =nullptr; - vulkan::MaterialInstance * material_instance =nullptr; - - vulkan::Renderable * ro_sphere =nullptr; - - vulkan::Pipeline * pipeline_solid =nullptr; - - vulkan::Buffer * ubo_atomsphere =nullptr; - AtomsphereData atomsphere_data; - -private: - - bool InitMaterial() - { - material=shader_manage->CreateMaterial(OS_TEXT("res/material/Atmosphere")); - if(!material) - return(false); - - material_instance=material->CreateInstance(); - - db->Add(material); - db->Add(material_instance); - return(true); - } - - void CreateRenderObject() - { - ro_sphere=CreateRenderableSphere(db,material,128); - } - - bool InitAtomsphereUBO(vulkan::MaterialInstance *mi,const AnsiString &sun_node_name) - { - atomsphere_data.position.Set(0,0.1f,-1.0f); - atomsphere_data.intensity=22.0f; - atomsphere_data.scattering_direction=0.758f; - - ubo_atomsphere=db->CreateUBO(sizeof(AtomsphereData),&atomsphere_data); - - if(!ubo_atomsphere) - return(false); - - return mi->BindUBO(sun_node_name,ubo_atomsphere); - } - - bool InitUBO() - { - if(!material_instance->BindUBO("world",GetCameraMatrixBuffer())) - return(false); - - if(!InitAtomsphereUBO(material_instance,"sun")) - return(false); - - material_instance->Update(); - return(true); - } - - bool InitPipeline() - { - AutoDelete - pipeline_creater=new vulkan::PipelineCreater(device,material,sc_render_target); - pipeline_creater->SetDepthTest(true); - pipeline_creater->SetDepthWrite(true); - pipeline_creater->SetCullMode(VK_CULL_MODE_NONE); - pipeline_creater->Set(Prim::Triangles); - pipeline_solid=pipeline_creater->Create(); - - if(!pipeline_solid) - return(false); - - db->Add(pipeline_solid); - return(true); - } - - bool InitScene() - { - render_root.Add(db->CreateRenderableInstance(pipeline_solid,material_instance,ro_sphere),scale(100)); - - render_root.RefreshMatrix(); - render_root.ExpendToList(&render_list); - - return(true); - } - -public: - - bool Init() - { - if(!CameraAppFramework::Init(SCREEN_WIDTH,SCREEN_HEIGHT)) - return(false); - - if(!InitMaterial()) - return(false); - - CreateRenderObject(); - - if(!InitUBO()) - return(false); - - if(!InitPipeline()) - return(false); - - if(!InitScene()) - return(false); - - return(true); - } - - void BuildCommandBuffer(uint32_t index) override - { - render_root.RefreshMatrix(); - render_list.Clear(); - render_root.ExpendToList(&render_list); - - VulkanApplicationFramework::BuildCommandBuffer(index,&render_list); - } -};//class TestApp:public CameraAppFramework - -int main(int,char **) -{ - TestApp app; - - if(!app.Init()) - return(-1); - - while(app.Run()); - - return 0; -} diff --git a/example/Vulkan/CMakeLists.txt b/example/Vulkan/CMakeLists.txt index b29a4f48..26b8accb 100644 --- a/example/Vulkan/CMakeLists.txt +++ b/example/Vulkan/CMakeLists.txt @@ -1,5 +1,5 @@ macro(CreateProject name) - add_executable(${name} ${ARGN} VulkanAppFramework.h) + add_executable(${name} ${ARGN} ${VULKAN_APP_FRAMEWORK}) target_link_libraries(${name} ${ULRE}) IF(WIN32) @@ -12,7 +12,7 @@ endmacro() macro(CreateQtProject name) add_executable(${name} ${ARGN} VulkanAppFramework.h) - set(IDENTIFIER "com.hyzgame.texconv") + set(IDENTIFIER "com.hyzgame.example") target_link_libraries(${name} ${ULRE} Qt5::Core Qt5::Gui Qt5::Widgets) @@ -24,17 +24,18 @@ macro(CreateQtProject name) endmacro() CreateProject(00.triangle first_triangle.cpp) -CreateProject(01.FragCoord FragCoordTest.cpp) -CreateProject(02.indices_rect indices_rect.cpp) -CreateProject(03.TextureFormat TextureFormat.cpp) -CreateProject(04.texture_rect texture_rect.cpp) -CreateProject(05.HQFilterTexture HQFilterTexture.cpp) -CreateProject(06.Geometry2D Geometry2D.cpp) -CreateProject(07.Geometry3D Geometry3D.cpp) -CreateProject(08.SceneTree SceneTree.cpp) -CreateProject(09.LoadStaticMesh LoadStaticMesh.cpp LoadScene.cpp) +CreateProject(01.two_triangle two_triangle.cpp) +CreateProject(02.FragCoord FragCoordTest.cpp) +CreateProject(03.indices_rect indices_rect.cpp) +CreateProject(04.TextureFormat TextureFormat.cpp) +CreateProject(05.texture_rect texture_rect.cpp) +#CreateProject(05.HQFilterTexture HQFilterTexture.cpp) +#CreateProject(06.Geometry2D Geometry2D.cpp) +CreateProject(06.Geometry3D Geometry3D.cpp) +#CreateProject(08.SceneTree SceneTree.cpp) +#CreateProject(09.LoadStaticMesh LoadStaticMesh.cpp LoadScene.cpp) CreateProject(10.InlineGeometryScene InlineGeometryScene.cpp) -CreateProject(11.Atomsphere Atomsphere.cpp) +CreateProject(11.Atmosphere Atmosphere.cpp) CreateProject(12.RectanglePrimitive RectanglePrimitive.cpp) @@ -42,17 +43,13 @@ CreateProject(13.DrawTile DrawTile.cpp) CreateProject(14.DrawText DrawText.cpp) -IF(SUPPORT_QT_VULKAN) -include(QtCommon) -CreateQtProject(14.VulkanQT VulkanQtApp.cpp - QtVulkanWindow.cpp - QtVulkanWindow.h - QtVulkanMainWindow.h - QtVulkanMainWindow.cpp) -ENDIF(SUPPORT_QT_VULKAN) +CreateProject(15.OffscreenRender OffscreenRender.cpp) #CreateProject(12.PBRBasic PBRBasic.cpp) #CreateProject(12.Deferred Deferred.cpp) -#CreateProject(13.DeferredModel DeferredModel.cpp) +CreateProject(16.DeferredRenderMultiCmdBuffer DeferredRenderMultiCmdBuffer.cpp) #CreateProject(14.AutoMaterial auto_material.cpp) +CreateProject(17.Cubemap Cubemap.cpp) +CreateProject(17.EquirectangularMap EquirectangularMap.cpp) +CreateProject(18.RayPicking RayPicking.cpp) \ No newline at end of file diff --git a/example/Vulkan/CubeNormal.cpp b/example/Vulkan/CubeNormal.cpp new file mode 100644 index 00000000..e69de29b diff --git a/example/Vulkan/Cubemap.cpp b/example/Vulkan/Cubemap.cpp new file mode 100644 index 00000000..e8bc80ca --- /dev/null +++ b/example/Vulkan/Cubemap.cpp @@ -0,0 +1,243 @@ +// Cubemap +// Cube贴图测试 + +#include"VulkanAppFramework.h" +#include +#include +#include +#include +#include +#include + +using namespace hgl; +using namespace hgl::graph; + +constexpr uint32_t SCREEN_WIDTH=1280; +constexpr uint32_t SCREEN_HEIGHT=720; + +class TestApp:public CameraAppFramework +{ +private: + + SceneNode render_root; + RenderList * render_list =nullptr; + + Material * sky_material =nullptr; + MaterialInstance * sky_mi =nullptr; + + Material * axis_material =nullptr; + MaterialInstance * axis_mi =nullptr; + + Material * envmap_material =nullptr; + MaterialInstance * envmap_mi =nullptr; + + Pipeline * axis_pipeline =nullptr; + Pipeline * sky_pipeline =nullptr; + Pipeline * solid_pipeline =nullptr; + + GPUBuffer * ubo_light =nullptr; + GPUBuffer * ubo_phong =nullptr; + + Sampler * sampler =nullptr; + TextureCube * texture =nullptr; + + Renderable * ro_axis =nullptr; + Renderable * ro_cube =nullptr; + Renderable * ro_sphere =nullptr; + +private: + + bool InitMaterial() + { + { + axis_material=db->CreateMaterial(OS_TEXT("res/material/VertexColor3D")); + if(!axis_material)return(false); + + axis_mi=db->CreateMaterialInstance(axis_material); + if(!axis_mi)return(false); + + axis_pipeline=CreatePipeline(axis_mi,InlinePipeline::Solid3D,Prim::Lines); + if(!axis_pipeline)return(false); + } + + { + texture =db->LoadTextureCube(OS_TEXT("res/cubemap/Storforsen4.TexCube"),false); + + if(!texture) + return(false); + + VkSamplerCreateInfo sampler_create_info= + { + VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, + nullptr, + 0, + VK_FILTER_LINEAR, + VK_FILTER_LINEAR, + VK_SAMPLER_MIPMAP_MODE_LINEAR, + VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, + VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, + VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, + 0.0f, + VK_FALSE, + 0, + false, + VK_COMPARE_OP_NEVER, + 0.0f, + 0, + VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK, + false + }; + + sampler =db->CreateSampler(&sampler_create_info); + } + + { + sky_material=db->CreateMaterial(OS_TEXT("res/material/Skybox")); + if(!sky_material)return(false); + + sky_mi=db->CreateMaterialInstance(sky_material); + if(!sky_mi)return(false); + + { + MaterialParameters *mp_texture=sky_mi->GetMP(DescriptorSetsType::Value); + + if(!mp_texture) + return(false); + + if(!mp_texture->BindSampler("tex" ,texture, sampler)) + return(false); + + mp_texture->Update(); + } + + sky_pipeline=CreatePipeline(sky_mi,InlinePipeline::Sky,Prim::Triangles); + if(!sky_pipeline)return(false); + } + + { + envmap_material=db->CreateMaterial(OS_TEXT("res/material/EnvCubemap")); + if(!envmap_material)return(false); + + envmap_mi=db->CreateMaterialInstance(envmap_material); + if(!envmap_mi)return(false); + + { + MaterialParameters *mp_texture=envmap_mi->GetMP(DescriptorSetsType::Value); + + if(!mp_texture) + return(false); + + if(!mp_texture->BindSampler("EnvCubemap" ,texture, sampler)) + return(false); + + mp_texture->Update(); + } + + solid_pipeline=CreatePipeline(envmap_mi,InlinePipeline::Solid3D,Prim::Triangles); + } + + return(true); + } + + void CreateRenderObject() + { + { + struct AxisCreateInfo aci; + + aci.size=GetCameraInfo().zfar; + + ro_axis=CreateRenderableAxis(db,axis_mi->GetVAB(),&aci); + } + + { + struct CubeCreateInfo cci; + + ro_cube=CreateRenderableCube(db,sky_mi->GetVAB(),&cci); + } + + { + ro_sphere=CreateRenderableSphere(db,envmap_mi->GetVAB(),64); + } + } + + bool InitUBO() + { + if(!BindCameraUBO(sky_mi))return(false); + if(!BindCameraUBO(envmap_mi))return(false); + + return(true); + } + + SceneNode *Add(Renderable *r,MaterialInstance *mi,Pipeline *pl) + { + auto ri=db->CreateRenderableInstance(r,mi,pl); + + return render_root.CreateSubNode(ri); + } + + bool InitScene() + { + Add(ro_axis,axis_mi,axis_pipeline); + Add(ro_cube,sky_mi,sky_pipeline); + Add(ro_sphere,envmap_mi,solid_pipeline)->SetLocalMatrix(scale(5,5,5)); + + render_root.RefreshMatrix(); + render_list->Expend(GetCameraInfo(),&render_root); + + return(true); + } + +public: + + ~TestApp() + { + SAFE_CLEAR(render_list); + } + + bool Init() + { + if(!CameraAppFramework::Init(SCREEN_WIDTH,SCREEN_HEIGHT)) + return(false); + + camera->pos=Vector3f(10,10,0); + + camera_control->SetTarget(Vector3f(0,0,0)); + + //camera->Refresh(); //更新矩阵计算 + + render_list=new RenderList(device); + + if(!InitMaterial()) + return(false); + + if(!InitUBO()) + return(false); + + CreateRenderObject(); + + if(!InitScene()) + return(false); + + return(true); + } + + void BuildCommandBuffer(uint32_t index) override + { + render_root.RefreshMatrix(); + render_list->Expend(GetCameraInfo(),&render_root); + + VulkanApplicationFramework::BuildCommandBuffer(index,render_list); + } +};//class TestApp:public CameraAppFramework + +int main(int,char **) +{ + TestApp app; + + if(!app.Init()) + return(-1); + + while(app.Run()); + + return 0; +} diff --git a/example/Vulkan/DeferredModel.cpp b/example/Vulkan/DeferredModel.cpp deleted file mode 100644 index 7826ccbe..00000000 --- a/example/Vulkan/DeferredModel.cpp +++ /dev/null @@ -1,483 +0,0 @@ -// 9.延迟渲染 -// 简单的延迟渲染测试,仅一个太阳光 - -#include"VulkanAppFramework.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include - -using namespace hgl; -using namespace hgl::graph; - -VK_NAMESPACE_BEGIN -Texture2D *CreateTextureFromFile(Device *device,const OSString &filename); -VK_NAMESPACE_END - -constexpr uint32_t SCREEN_WIDTH=256; -constexpr uint32_t SCREEN_HEIGHT=256; - -using Texture2DPointer=vulkan::Texture2D *; - -constexpr VkFormat position_candidate_format[]={FMT_RGBA32F,FMT_RGBA16F}; -constexpr VkFormat color_candidate_format []={FMT_RGBA32F, - FMT_RGBA16F, - FMT_RGBA8UN,FMT_RGBA8SN,FMT_RGBA8U, - FMT_BGRA8UN,FMT_BGRA8SN,FMT_BGRA8U, - FMT_ABGR8UN,FMT_ABGR8SN,FMT_ABGR8U, - FMT_RGB565,FMT_BGR565}; -constexpr VkFormat normal_candidate_format []={FMT_RGBA32F, - FMT_RGBA16F, - FMT_A2RGB10UN,FMT_A2RGB10SN,FMT_A2BGR10UN, - FMT_A2BGR10SN}; -constexpr VkFormat depth_candidate_format []={FMT_D32F,FMT_D32F_S8U,FMT_X8_D24UN,FMT_D24UN_S8U,FMT_D16UN,FMT_D16UN_S8U}; - -class TestApp:public CameraAppFramework -{ -private: - - SceneNode render_root; - RenderList render_list; - - struct DeferredGBuffer - { - vulkan::Semaphore *render_complete_semaphore =nullptr; - - vulkan::RenderTarget *rt; - - VkExtent2D extent; - vulkan::Framebuffer *framebuffer; - vulkan::RenderPass *renderpass; - - union - { - struct - { - Texture2DPointer position,normal,color,depth; - }; - - Texture2DPointer texture_list[4]; - }; - - List gbuffer_format_list; - List image_view_list; - - struct - { - List desc_list; - List color_ref_list; - VkAttachmentReference depth_ref; - }attachment; - - struct - { - List desc; - List dependency; - }subpass; - }gbuffer;// - - struct SubpassParam - { - vulkan::Material * material; - vulkan::MaterialInstance * material_instance; - vulkan::Pipeline * pipeline_fan; - vulkan::Pipeline * pipeline_triangles; - };// - - SubpassParam sp_gbuffer; - SubpassParam sp_composition; - - vulkan::Renderable *ro_plane, - *ro_cube, - *ro_sphere, - *ro_torus, - *ro_cylinder, - *ro_cone, - - *ro_gbc_plane; - - vulkan::Sampler * sampler=nullptr; - - struct - { - Texture2DPointer color=nullptr; - Texture2DPointer normal=nullptr; - }texture; - - vulkan::CommandBuffer *gbuffer_cmd=nullptr; - -public: - - ~TestApp() - { - SAFE_CLEAR(gbuffer_cmd); - SAFE_CLEAR(texture.normal); - SAFE_CLEAR(texture.color); - SAFE_CLEAR(sampler); - } -private: - - const VkFormat GetCandidateFormat(const VkFormat *fmt_list,const uint count) - { - auto pd=device->GetPhysicalDevice(); - - for(uint i=0;iIsColorAttachmentOptimal(fmt_list[i])) - return fmt_list[i]; - - for(uint i=0;iIsColorAttachmentLinear(fmt_list[i])) - return fmt_list[i]; - - return FMT_UNDEFINED; - } - - const VkFormat GetDepthCandidateFormat() - { - auto pd=device->GetPhysicalDevice(); - - for(VkFormat fmt:depth_candidate_format) - if(pd->IsDepthAttachmentOptimal(fmt)) - return fmt; - - for(VkFormat fmt:depth_candidate_format) - if(pd->IsDepthAttachmentLinear(fmt)) - return fmt; - - return FMT_UNDEFINED; - } - - bool InitGBuffer() - { - gbuffer.extent.width =1024; - gbuffer.extent.height =1024; - - gbuffer.render_complete_semaphore =device->CreateSem(); - - //根据候选格式表选择格式 - //const VkFormat position_format =GetCandidateFormat(position_candidate_format, sizeof(position_candidate_format)); - //const VkFormat color_format =GetCandidateFormat(color_candidate_format, sizeof(color_candidate_format)); - //const VkFormat normal_format =GetCandidateFormat(normal_candidate_format, sizeof(normal_candidate_format)); - //const VkFormat depth_format =GetDepthCandidateFormat(); - - //if(position_format ==FMT_UNDEFINED - // ||color_format ==FMT_UNDEFINED - // ||normal_format ==FMT_UNDEFINED - // ||depth_format ==FMT_UNDEFINED) - // return(false); - - const VkFormat position_format =FMT_RGBA32F; - const VkFormat color_format =FMT_RGBA32F; - const VkFormat normal_format =FMT_RGBA32F; - const VkFormat depth_format =FMT_D32F; - - gbuffer.position=device->CreateAttachmentTextureColor(position_format, gbuffer.extent.width,gbuffer.extent.height); - gbuffer.color =device->CreateAttachmentTextureColor(color_format, gbuffer.extent.width,gbuffer.extent.height); - gbuffer.normal =device->CreateAttachmentTextureColor(normal_format, gbuffer.extent.width,gbuffer.extent.height); - gbuffer.depth =device->CreateAttachmentTextureDepth(depth_format, gbuffer.extent.width,gbuffer.extent.height); - - for(uint i=0;i<3;i++) - { - gbuffer.gbuffer_format_list.Add(gbuffer.texture_list[i]->GetFormat()); - gbuffer.image_view_list.Add(gbuffer.texture_list[i]->GetImageView()); - } - - device->CreateColorAttachmentReference(gbuffer.attachment.color_ref_list,0,3); - device->CreateDepthAttachmentReference(&gbuffer.attachment.depth_ref,3); - - if(!device->CreateAttachment( gbuffer.attachment.desc_list, - gbuffer.gbuffer_format_list, - gbuffer.depth->GetFormat())) - return(false); - - VkSubpassDescription desc; - - device->CreateSubpassDescription(desc, - gbuffer.attachment.color_ref_list, - &gbuffer.attachment.depth_ref); - - gbuffer.subpass.desc.Add(desc); - - device->CreateSubpassDependency(gbuffer.subpass.dependency,2); //为啥要2个还不清楚 - - gbuffer.renderpass=device->CreateRenderPass(gbuffer.attachment.desc_list, - gbuffer.subpass.desc, - gbuffer.subpass.dependency, - gbuffer.gbuffer_format_list, - gbuffer.depth->GetFormat()); - - if(!gbuffer.renderpass) - return(false); - - gbuffer.framebuffer=vulkan::CreateFramebuffer(device,gbuffer.renderpass,gbuffer.image_view_list,gbuffer.depth->GetImageView()); - - if(!gbuffer.framebuffer) - return(false); - - gbuffer.rt=device->CreateRenderTarget(gbuffer.framebuffer); - - return(true); - } - - bool InitSubpass(SubpassParam *sp,const OSString &vs,const OSString &fs) - { - sp->material=shader_manage->CreateMaterial(vs,fs); - - if(!sp->material) - return(false); - - sp->material_instance=sp->material->CreateInstance(); - - db->Add(sp->material); - db->Add(sp->material_instance); - return(true); - } - - bool InitGBufferPipeline(SubpassParam *sp) - { - AutoDelete pipeline_creater=new vulkan::PipelineCreater(device,sp->material,gbuffer.rt); - - { - pipeline_creater->Set(PRIM_TRIANGLES); - - sp->pipeline_triangles=pipeline_creater->Create(); - - if(!sp->pipeline_triangles) - return(false); - - db->Add(sp->pipeline_triangles); - } - - { - pipeline_creater->Set(PRIM_TRIANGLE_FAN); - - sp->pipeline_fan=pipeline_creater->Create(); - - if(!sp->pipeline_fan) - return(false); - - db->Add(sp->pipeline_fan); - } - return(true); - } - - bool InitCompositionPipeline(SubpassParam *sp) - { - AutoDelete pipeline_creater=new vulkan::PipelineCreater(device,sp->material,sc_render_target); - pipeline_creater->SetDepthTest(false); - pipeline_creater->SetDepthWrite(false); - pipeline_creater->SetCullMode(VK_CULL_MODE_NONE); - pipeline_creater->Set(PRIM_TRIANGLE_FAN); - - sp->pipeline_triangles=pipeline_creater->Create(); - - if(!sp->pipeline_triangles) - return(false); - - db->Add(sp->pipeline_triangles); - return(true); - } - - bool InitMaterial() - { - if(!InitSubpass(&sp_gbuffer, OS_TEXT("res/shader/gbuffer_opaque.vert.spv"),OS_TEXT("res/shader/gbuffer_opaque.frag.spv")))return(false); - if(!InitSubpass(&sp_composition,OS_TEXT("res/shader/gbuffer_composition.vert.spv"),OS_TEXT("res/shader/gbuffer_composition.frag.spv")))return(false); - - if(!InitGBufferPipeline(&sp_gbuffer))return(false); - if(!InitCompositionPipeline(&sp_composition))return(false); - - texture.color =vulkan::CreateTextureFromFile(device,OS_TEXT("res/image/Brickwall/Albedo.Tex2D")); - texture.normal =vulkan::CreateTextureFromFile(device,OS_TEXT("res/image/Brickwall/Normal.Tex2D")); - - VkSamplerCreateInfo sampler_create_info; - - sampler_create_info.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO; - sampler_create_info.pNext = nullptr; - sampler_create_info.flags = 0; - sampler_create_info.magFilter = VK_FILTER_LINEAR; - sampler_create_info.minFilter = VK_FILTER_LINEAR; - sampler_create_info.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR; - sampler_create_info.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; - sampler_create_info.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; - sampler_create_info.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; - sampler_create_info.mipLodBias = 0.0f; - sampler_create_info.anisotropyEnable = false; - sampler_create_info.maxAnisotropy = 0; - sampler_create_info.compareEnable = false; - sampler_create_info.compareOp = VK_COMPARE_OP_NEVER; - sampler_create_info.minLod = 0.0f; - sampler_create_info.maxLod = 1.0f; - sampler_create_info.borderColor = VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK; - sampler_create_info.unnormalizedCoordinates = false; - - sampler=device->CreateSampler(&sampler_create_info); - - InitCameraUBO(sp_gbuffer.material_instance,"world"); - - sp_gbuffer.material_instance->BindSampler("TextureColor" ,texture.color, sampler); - sp_gbuffer.material_instance->BindSampler("TextureNormal" ,texture.normal, sampler); - sp_gbuffer.material_instance->Update(); - - sp_composition.material_instance->BindSampler("GB_Position" ,gbuffer.position, sampler); - sp_composition.material_instance->BindSampler("GB_Normal" ,gbuffer.normal, sampler); - sp_composition.material_instance->BindSampler("GB_Color" ,gbuffer.color, sampler); - sp_composition.material_instance->Update(); - - return(true); - } - - void CreateRenderObject(vulkan::Material *mtl) - { - { - struct PlaneCreateInfo pci; - - ro_plane=CreateRenderablePlane(db,mtl,&pci); - } - - { - struct CubeCreateInfo cci; - ro_cube=CreateRenderableCube(db,mtl,&cci); - } - - { - ro_sphere=CreateRenderableSphere(db,mtl,64); - } - - { - TorusCreateInfo tci; - - tci.innerRadius=50; - tci.outerRadius=70; - - tci.numberSlices=32; - tci.numberStacks=16; - - ro_torus=CreateRenderableTorus(db,mtl,&tci); - } - - { - CylinderCreateInfo cci; - - cci.halfExtend=10; - cci.radius=10; - cci.numberSlices=16; - - ro_cylinder=CreateRenderableCylinder(db,mtl,&cci); - } - - { - ConeCreateInfo cci; - - cci.halfExtend=10; - cci.radius=10; - cci.numberSlices=16; - cci.numberStacks=1; - - ro_cone=CreateRenderableCone(db,mtl,&cci); - } - } - - bool InitCompositionRenderable() - { - ro_gbc_plane=CreateRenderableGBufferComposition(db,sp_composition.material); - - return ro_gbc_plane; - } - - bool InitScene(SubpassParam *sp) - { - CreateRenderObject(sp->material); - render_root.Add(db->CreateRenderableInstance(sp->pipeline_fan, sp->material_instance,ro_plane ),scale(100,100,1)); - render_root.Add(db->CreateRenderableInstance(sp->pipeline_triangles,sp->material_instance,ro_torus ),translate(0,0,0)); - render_root.Add(db->CreateRenderableInstance(sp->pipeline_triangles,sp->material_instance,ro_sphere ),scale(20,20,20)); - render_root.Add(db->CreateRenderableInstance(sp->pipeline_triangles,sp->material_instance,ro_cube ),translate(-30, 0,10)*scale(10,10,10)); - render_root.Add(db->CreateRenderableInstance(sp->pipeline_triangles,sp->material_instance,ro_cylinder ),translate( 30, 30,10)*scale(1,1,2)); - render_root.Add(db->CreateRenderableInstance(sp->pipeline_triangles,sp->material_instance,ro_cone ),translate( 0,-30, 0)*scale(1,1,2)); - - render_root.RefreshMatrix(); - render_root.ExpendToList(&render_list); - - return(true); - } - - bool InitGBufferCommandBuffer() - { - gbuffer_cmd=device->CreateCommandBuffer(gbuffer.extent,gbuffer.attachment.desc_list.GetCount()); - - if(!gbuffer_cmd) - return(false); - - gbuffer_cmd->Begin(); - if(!gbuffer_cmd->BeginRenderPass(gbuffer.rt)) - return(false); - - render_list.Render(gbuffer_cmd); - - gbuffer_cmd->EndRenderPass(); - gbuffer_cmd->End(); - - return(true); - } - -public: - - bool Init() - { - if(!CameraAppFramework::Init(SCREEN_WIDTH,SCREEN_HEIGHT)) - return(false); - - if(!InitGBuffer()) - return(false); - - if(!InitMaterial()) - return(false); - - if(!InitScene(&sp_gbuffer)) - return(false); - - if(!InitGBufferCommandBuffer()) - return(false); - - if(!InitCompositionRenderable()) - return(false); - - return(true); - } - - virtual void SubmitDraw(int index) override - { - gbuffer.rt->Submit(*gbuffer_cmd,present_complete_semaphore,gbuffer.render_complete_semaphore); - - VkCommandBuffer cb=*cmd_buf[index]; - - sc_render_target->Submit(cb,gbuffer.render_complete_semaphore,render_complete_semaphore); - sc_render_target->PresentBackbuffer(render_complete_semaphore); - sc_render_target->Wait(); - gbuffer.rt->Wait(); - } - - void BuildCommandBuffer(uint32_t index) override - { - VulkanApplicationFramework::BuildCommandBuffer( index, - sp_composition.pipeline_triangles, - sp_composition.material_instance, - ro_gbc_plane); - } -};//class TestApp:public CameraAppFramework - -int main(int,char **) -{ - TestApp app; - - if(!app.Init()) - return(-1); - - while(app.Run()); - - return 0; -} diff --git a/example/Vulkan/DeferredRenderMultiCmdBuffer.cpp b/example/Vulkan/DeferredRenderMultiCmdBuffer.cpp new file mode 100644 index 00000000..115ddbf3 --- /dev/null +++ b/example/Vulkan/DeferredRenderMultiCmdBuffer.cpp @@ -0,0 +1,454 @@ +// 简单传统延迟渲染,使用多个RenderPass,多个CommandBuffer + +#include"VulkanAppFramework.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace hgl; +using namespace hgl::graph; + +VK_NAMESPACE_BEGIN +Texture2D *CreateTexture2DFromFile(GPUDevice *device,const OSString &filename); +VK_NAMESPACE_END + +constexpr uint32_t SCREEN_WIDTH=1280; +constexpr uint32_t SCREEN_HEIGHT=SCREEN_WIDTH/16*9; + +using Texture2DPointer=Texture2D *; + +enum class GBufferAttachment +{ + Color=0, + Normal, + + ENUM_CLASS_RANGE(Color,Normal) +};// + +constexpr VkFormat gbuffer_color_format[size_t(GBufferAttachment::RANGE_SIZE)]={UPF_RGB565,UPF_RG8}; +constexpr VkFormat gbuffer_depth_format=PF_D16UN; + +struct alignas(16) PhongPointLight +{ + Vector4f color; + Vector4f position; + float radius; +};// + +class TestApp:public CameraAppFramework +{ +private: + + SceneNode render_root; + RenderList *render_list=nullptr; + + struct + { + RenderTarget *rt=nullptr; + RenderPass *rp=nullptr; + RenderCmdBuffer *cmd=nullptr; + + Sampler *sampler=nullptr; + + public: + + bool Submit(GPUSemaphore *sem) + { + return rt->Submit(cmd,sem); + } + }gbuffer; + + PhongPointLight lights; + + GPUBuffer *ubo_lights; + + struct SubpassParam + { + Material * material; + MaterialInstance * material_instance; + Pipeline * pipeline_fan; + Pipeline * pipeline_triangles; + };// + + SubpassParam sp_gbuffer; + SubpassParam sp_composition; + + Renderable *ro_plane, + *ro_cube, + *ro_sphere, + *ro_torus, + *ro_cylinder, + *ro_cone, + *ro_gbc_plane, + *ro_axis; + + RenderableInstance *ro_gbc_plane_ri; + + struct + { + Texture2DPointer color=nullptr; + Texture2DPointer normal=nullptr; + + Sampler * color_sampler=nullptr; + Sampler * normal_sampler=nullptr; + }texture; + +public: + + ~TestApp() + { + SAFE_CLEAR(render_list); + SAFE_CLEAR(gbuffer.cmd); + SAFE_CLEAR(gbuffer.rt); + } + +private: + + void CreateGBufferSampler() + { + VkSamplerCreateInfo sci= + { + VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, + nullptr, + 0, + VK_FILTER_LINEAR, + VK_FILTER_LINEAR, + VK_SAMPLER_MIPMAP_MODE_NEAREST, + VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, + VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, + VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, + 0.0f, + false, + 1.0f, + false, + VK_COMPARE_OP_NEVER, + 0.0f, + 0.0f, + VK_BORDER_COLOR_INT_OPAQUE_BLACK, + false + }; + + gbuffer.sampler=db->CreateSampler(&sci); + } + + bool InitGBuffer() + { + FramebufferInfo fbi(gbuffer_color_format,size_t(GBufferAttachment::RANGE_SIZE),gbuffer_depth_format); + + fbi.SetExtent(SCREEN_WIDTH,SCREEN_HEIGHT); + + gbuffer.rt=device->CreateRenderTarget(&fbi); + + if(!gbuffer.rt)return(false); + + gbuffer.cmd=device->CreateRenderCommandBuffer(); + + gbuffer.rp=gbuffer.rt->GetRenderPass(); + + CreateGBufferSampler(); + + return(gbuffer.rt); + } + + bool InitMaterial(SubpassParam *sp,const OSString &material_filename) + { + sp->material=db->CreateMaterial(material_filename); + + if(!sp->material) + return(false); + + sp->material_instance=db->CreateMaterialInstance(sp->material); + return(true); + } + + bool InitGBufferPipeline(SubpassParam *sp) + { + sp->pipeline_triangles =gbuffer.rp->CreatePipeline(sp->material_instance,InlinePipeline::Solid3D,Prim::Triangles); + if(!sp->pipeline_triangles) + return(false); + + sp->pipeline_fan =gbuffer.rp->CreatePipeline(sp->material_instance,InlinePipeline::Solid3D,Prim::Fan); + + return sp->pipeline_fan; + } + + bool InitCompositionPipeline(SubpassParam *sp) + { + sp->pipeline_fan=device_render_pass->CreatePipeline(sp->material_instance,InlinePipeline::Solid2D,Prim::Fan); + + return sp->pipeline_fan; + } + + bool InitLightsUBO() + { + ubo_lights=db->CreateUBO(sizeof(lights),&lights); + return ubo_lights; + } + + Sampler *CreateSampler(Texture *tex) + { + VkSamplerCreateInfo sci= + { + VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, + nullptr, + 0, + VK_FILTER_LINEAR, + VK_FILTER_LINEAR, + VK_SAMPLER_MIPMAP_MODE_LINEAR, + VK_SAMPLER_ADDRESS_MODE_REPEAT, + VK_SAMPLER_ADDRESS_MODE_REPEAT, + VK_SAMPLER_ADDRESS_MODE_REPEAT, + 0.0f, + false, + 1.0f, + false, + VK_COMPARE_OP_NEVER, + 0.0f, + 0.0f, + VK_BORDER_COLOR_INT_OPAQUE_BLACK, + false + }; + + sci.maxLod=tex->GetMipLevel(); + + return db->CreateSampler(&sci); + } + + bool InitMaterial() + { + if(!InitLightsUBO())return(false); + + if(!InitMaterial(&sp_gbuffer, OS_TEXT("res/material/opaque")))return(false); + if(!InitMaterial(&sp_composition,OS_TEXT("res/material/composition")))return(false); + + if(!InitGBufferPipeline(&sp_gbuffer))return(false); + if(!InitCompositionPipeline(&sp_composition))return(false); + + texture.color =db->LoadTexture2D(OS_TEXT("res/image/Brickwall/Albedo.Tex2D")); + texture.normal =db->LoadTexture2D(OS_TEXT("res/image/Brickwall/Normal.Tex2D")); + + texture.color_sampler=CreateSampler(texture.color); + texture.normal_sampler=CreateSampler(texture.normal); + + BindCameraUBO(sp_gbuffer.material_instance); + + { + MaterialParameters *mp=sp_gbuffer.material_instance->GetMP(DescriptorSetsType::Value); + + if(!mp) + return(false); + + mp->BindSampler("TexColor" ,texture.color, texture.color_sampler); + mp->BindSampler("TexNormal" ,texture.normal, texture.normal_sampler); + mp->Update(); + } + + BindCameraUBO(sp_composition.material_instance); + + { + MaterialParameters *mp=sp_composition.material_instance->GetMP(DescriptorSetsType::Value); + + if(!mp) + return(false); + + mp->BindUBO("lights",ubo_lights); + mp->BindSampler("GB_Color" ,gbuffer.rt->GetColorTexture((uint)GBufferAttachment::Color),gbuffer.sampler); + mp->BindSampler("GB_Normal" ,gbuffer.rt->GetColorTexture((uint)GBufferAttachment::Normal),gbuffer.sampler); + mp->BindSampler("GB_Depth" ,gbuffer.rt->GetDepthTexture(),gbuffer.sampler); + mp->Update(); + } + + return(true); + } + + void CreateRenderObject(const VAB *vab) + { + { + struct PlaneCreateInfo pci; + ro_plane=CreateRenderablePlane(db,vab,&pci); + } + + { + struct CubeCreateInfo cci; + ro_cube=CreateRenderableCube(db,vab,&cci); + } + + { + ro_sphere=CreateRenderableSphere(db,vab,64); + } + + { + TorusCreateInfo tci; + + tci.innerRadius=50; + tci.outerRadius=70; + + tci.numberSlices=128; + tci.numberStacks=64; + + tci.uv_scale.x=4; + tci.uv_scale.y=1; + + ro_torus=CreateRenderableTorus(db,vab,&tci); + } + + { + CylinderCreateInfo cci; + + cci.halfExtend=10; + cci.radius=10; + cci.numberSlices=32; + + ro_cylinder=CreateRenderableCylinder(db,vab,&cci); + } + + { + ConeCreateInfo cci; + + cci.halfExtend=10; + cci.radius=10; + cci.numberSlices=128; + cci.numberStacks=32; + + ro_cone=CreateRenderableCone(db,vab,&cci); + } + } + + bool InitCompositionRenderable() + { + ro_gbc_plane=CreateRenderableGBufferComposition(db,sp_composition.material_instance->GetVAB()); + if(!ro_gbc_plane)return(false); + + ro_gbc_plane_ri=db->CreateRenderableInstance(ro_gbc_plane,sp_composition.material_instance,sp_composition.pipeline_fan); + if(!ro_gbc_plane_ri)return(false); + + return(true); + } + + bool InitScene(SubpassParam *sp) + { + CreateRenderObject(sp->material_instance->GetVAB()); + render_root.CreateSubNode( scale(100,100,1), db->CreateRenderableInstance(ro_plane ,sp->material_instance,sp->pipeline_fan )); + render_root.CreateSubNode( db->CreateRenderableInstance(ro_torus ,sp->material_instance,sp->pipeline_triangles)); + render_root.CreateSubNode( scale(20,20,20), db->CreateRenderableInstance(ro_sphere ,sp->material_instance,sp->pipeline_triangles)); + render_root.CreateSubNode(translate(-30, 0,10)*scale(10,10,10), db->CreateRenderableInstance(ro_cube ,sp->material_instance,sp->pipeline_triangles)); + render_root.CreateSubNode(translate( 30, 30,10)*scale(1,1,2), db->CreateRenderableInstance(ro_cylinder ,sp->material_instance,sp->pipeline_triangles)); + render_root.CreateSubNode(translate( 0,-30, 0)*scale(1,1,2), db->CreateRenderableInstance(ro_cone ,sp->material_instance,sp->pipeline_triangles)); + + render_root.RefreshMatrix(); + render_list->Expend(GetCameraInfo(),&render_root); + + return(true); + } + + bool InitGBufferCommandBuffer() + { + if(!gbuffer.cmd) + return(false); + + gbuffer.cmd->Begin(); + if(!gbuffer.cmd->BindFramebuffer(gbuffer.rt->GetRenderPass(),gbuffer.rt->GetFramebuffer())) + return(false); + + if(!gbuffer.cmd->BeginRenderPass()) + return(false); + + render_list->Render(gbuffer.cmd); + + gbuffer.cmd->EndRenderPass(); + gbuffer.cmd->End(); + + return(true); + } + +public: + + bool Init() + { + if(!CameraAppFramework::Init(SCREEN_WIDTH,SCREEN_HEIGHT)) + return(false); + + render_list=new RenderList(device); + + if(!InitGBuffer()) + return(false); + + if(!InitMaterial()) + return(false); + + if(!InitScene(&sp_gbuffer)) + return(false); + + if(!InitGBufferCommandBuffer()) + return(false); + + if(!InitCompositionRenderable()) + return(false); + + return(true); + } + + void UpdateLights() + { + const double timer=GetDoubleTime(); + + // White + lights.position = Vector4f(0.0f, 0.0f, 25.0f, 0.0f); + lights.color = Vector4f(15.0f); + lights.radius = 155.0f; + + lights.position.x = sin(rad2deg(timer/100)) * 100.0f; + lights.position.y = cos(rad2deg(timer/100)) * 100.0f; + + ubo_lights->Write(&lights); + } + + virtual void SubmitDraw(int index) override + { + gbuffer.Submit(sc_render_target->GetPresentCompleteSemaphore()); + + VkCommandBuffer cb=*cmd_buf[index]; + + sc_render_target->Submit(cb,gbuffer.rt->GetRenderCompleteSemaphore()); + sc_render_target->PresentBackbuffer(); + sc_render_target->WaitQueue(); + sc_render_target->WaitFence(); + + gbuffer.rt->WaitQueue(); + gbuffer.rt->WaitFence(); + } + + void BuildCommandBuffer(uint32_t index) override + { + VulkanApplicationFramework::BuildCommandBuffer(index,ro_gbc_plane_ri); + } + + void Draw()override + { + UpdateLights(); + + render_root.RefreshMatrix(); + render_list->Expend(GetCameraInfo(),&render_root); + + CameraAppFramework::Draw(); + } +};//class TestApp:public CameraAppFramework + +int main(int,char **) +{ + TestApp app; + + if(!app.Init()) + return(-1); + + while(app.Run()); + + return 0; +} diff --git a/example/Vulkan/DrawText.cpp b/example/Vulkan/DrawText.cpp index d700ac9d..47a16716 100644 --- a/example/Vulkan/DrawText.cpp +++ b/example/Vulkan/DrawText.cpp @@ -1,7 +1,4 @@ -// DrawTile -// 该示例使用TileData,演示多个tile图片在一张纹理上 - -#include +#include #include #include #include @@ -9,8 +6,8 @@ #include #include"VulkanAppFramework.h" -#include -#include +#include +#include #include using namespace hgl; @@ -29,24 +26,25 @@ class TestApp:public VulkanApplicationFramework private: - vulkan::Material * material =nullptr; - vulkan::Sampler * sampler =nullptr; - vulkan::MaterialInstance * material_instance =nullptr; - vulkan::Buffer * ubo_world_matrix =nullptr; - vulkan::Buffer * ubo_color =nullptr; + Sampler * sampler =nullptr; + Material * material =nullptr; + MaterialInstance * material_instance =nullptr; + GPUBuffer * ubo_camera_info =nullptr; + GPUBuffer * ubo_color =nullptr; - vulkan::Pipeline * pipeline =nullptr; + Pipeline * pipeline =nullptr; private: - FontSource * eng_fs =nullptr; - FontSource * chs_fs =nullptr; - FontSourceMulti * font_source =nullptr; + FontSource * eng_fs =nullptr; + FontSource * chs_fs =nullptr; + FontSourceMulti * font_source =nullptr; - TileFont * tile_font =nullptr; - TextLayout tl_engine; ///<文本排版引擎 + TileFont * tile_font =nullptr; + TextLayout tl_engine; ///<文本排版引擎 - TextRenderable * text_render_obj =nullptr; + TextRenderable * text_render_obj =nullptr; + RenderableInstance *render_instance =nullptr; public: @@ -59,23 +57,51 @@ private: bool InitMaterial() { - material=shader_manage->CreateMaterial( OS_TEXT("res/shader/DrawRect2D.vert"), - OS_TEXT("res/shader/DrawRect2D.geom"), - OS_TEXT("res/shader/FlatLumTexture.frag")); - if(!material) - return(false); + material=db->CreateMaterial(OS_TEXT("res/material/LumTextureRect2D")); - material_instance=material->CreateInstance(); + //文本渲染Position坐标全部是使用整数,这里强制要求Position输入流使用RGBA16I格式 + { + VABConfigInfo vab_config; + VAConfig va_cfg; + + va_cfg.format=VF_V4I16; + va_cfg.instance=false; + + vab_config.Add("Position",va_cfg); + + material_instance=db->CreateMaterialInstance(material,&vab_config); + if(!material_instance)return(false); + } + + pipeline=CreatePipeline(material_instance,InlinePipeline::Solid2D,Prim::SolidRectangles); + if(!pipeline)return(false); sampler=db->CreateSampler(); + + { + MaterialParameters *mp_global=material_instance->GetMP(DescriptorSetsType::Global); + + if(!mp_global) + return(false); + + if(!mp_global->BindUBO("g_camera",ubo_camera_info))return(false); + + mp_global->Update(); + } + + { + MaterialParameters *mp=material_instance->GetMP(DescriptorSetsType::Value); + + if(!mp) + return(false); + + if(!mp->BindSampler("lum_texture",tile_font->GetTexture(),sampler))return(false); + if(!mp->BindUBO("color_material",ubo_color))return(false); + + mp->Update(); + } - material_instance->BindSampler("tex",tile_font->GetTexture(),sampler); - material_instance->BindUBO("world",ubo_world_matrix); - material_instance->BindUBO("color_material",ubo_color); - material_instance->Update(); - db->Add(material); - db->Add(material_instance); return(true); } @@ -88,9 +114,9 @@ private: cam.RefreshCameraInfo(); - ubo_world_matrix=db->CreateUBO(sizeof(WorldMatrix),&cam.matrix); + ubo_camera_info=db->CreateUBO(sizeof(CameraInfo),&cam.info); - if(!ubo_world_matrix) + if(!ubo_camera_info) return(false); color.One(); @@ -103,19 +129,6 @@ private: return(true); } - bool InitPipeline() - { - AutoDelete - pipeline_creater=new vulkan::PipelineCreater(device,material,sc_render_target); - pipeline_creater->CloseCullFace(); - pipeline_creater->Set(Prim::Rectangles); - - pipeline=pipeline_creater->Create(); - - db->Add(pipeline); - return pipeline; - } - bool InitTileFont() { Font eng_fnt(OS_TEXT("Source Code Pro"),0,CHAR_BITMAP_SIZE); @@ -156,11 +169,15 @@ private: { UTF16String str; - LoadStringFromTextFile(str,OS_TEXT("README.md")); + LoadStringFromTextFile(str,OS_TEXT("res/text/DaoDeBible.txt")); - text_render_obj=db->CreateTextRenderable(material); + text_render_obj=db->CreateTextRenderable(material_instance->GetMaterial()); - return(tl_engine.SimpleLayout(text_render_obj,tile_font,str)>0); + if(tl_engine.SimpleLayout(text_render_obj,tile_font,str)<=0)return(false); + + render_instance=db->CreateRenderableInstance(text_render_obj,material_instance,pipeline); + + return(render_instance); } public: @@ -179,16 +196,13 @@ public: if(!InitMaterial()) return(false); - if(!InitPipeline()) - return(false); - if(!InitTextLayoutEngine()) return(false); if(!InitTextRenderable()) return(false); - BuildCommandBuffer(pipeline,material_instance,text_render_obj); + BuildCommandBuffer(render_instance); return(true); } @@ -200,9 +214,9 @@ public: cam.RefreshCameraInfo(); - ubo_world_matrix->Write(&cam.matrix); - - BuildCommandBuffer(pipeline,material_instance,text_render_obj); + ubo_camera_info->Write(&cam.info); + + BuildCommandBuffer(render_instance); } };//class TestApp:public VulkanApplicationFramework diff --git a/example/Vulkan/DrawTile.cpp b/example/Vulkan/DrawTile.cpp index e2b51458..18e34ef6 100644 --- a/example/Vulkan/DrawTile.cpp +++ b/example/Vulkan/DrawTile.cpp @@ -2,12 +2,12 @@ // 该示例使用TileData,演示多个tile图片在一张纹理上 #include -#include +#include #include #include"VulkanAppFramework.h" -#include -#include +#include +#include #include using namespace hgl; @@ -17,6 +17,7 @@ constexpr uint32_t SCREEN_WIDTH =1024; constexpr uint32_t SCREEN_HEIGHT=512; constexpr float BORDER=2; +constexpr uint TILE_COLS=10; struct TileBitmap { @@ -30,30 +31,27 @@ class TestApp:public VulkanApplicationFramework ObjectList tile_list; - TileData *tile_data; + TileData *tile_data=nullptr; float *vertex_data=nullptr; float *tex_coord_data=nullptr; + VkFormat tile_texture_format=PF_UNDEFINED; + private: - vulkan::Material * material =nullptr; - vulkan::Sampler * sampler =nullptr; - vulkan::MaterialInstance * material_instance =nullptr; - vulkan::Renderable * render_obj =nullptr; - vulkan::Buffer * ubo_world_matrix =nullptr; + Sampler * sampler =nullptr; + MaterialInstance * material_instance =nullptr; + Renderable * render_obj =nullptr; + RenderableInstance *render_instance =nullptr; + GPUBuffer * ubo_camera_info =nullptr; - vulkan::Pipeline * pipeline =nullptr; - - vulkan::VAB *vertex_buffer =nullptr; - vulkan::VAB *tex_coord_buffer =nullptr; + Pipeline * pipeline =nullptr; public: ~TestApp() { - SAFE_CLEAR_ARRAY(vertex_data); - SAFE_CLEAR_ARRAY(tex_coord_data); SAFE_CLEAR(tile_data); } @@ -71,7 +69,17 @@ private: int result=0; - for(int i=0;iformat; + + for(int i=1;iCreateTileData( FMT_BC1_RGBAUN, //纹理格式,因VK不支持实时转换,所以提交的数据格式必须与此一致 + tile_data=device->CreateTileData( tile_texture_format, //纹理格式,不支持实时转换,所以提交的数据格式必须与此一致 512,512, //TILE大小 tile_list.GetCount()); //TILE需求数量 @@ -109,7 +117,7 @@ private: int col=0; int row=0; - float size =SCREEN_WIDTH/10; + float size =SCREEN_WIDTH/TILE_COLS; float view_size =size-BORDER*2; float left =0; float top =0; @@ -118,7 +126,7 @@ private: for(int i=0;ito=tile_data->Commit((*tb)->bmp); //添加一个tile图片 + (*tb)->to=tile_data->Commit((*tb)->bmp); //添加一个tile图片 vp=WriteRect(vp,left+BORDER, //产生绘制顶点信息 top +BORDER, @@ -128,7 +136,7 @@ private: tp=WriteRect(tp,(*tb)->to->uv_float); //产生绘制纹理坐标信息 ++col; - if(col==10) + if(col==TILE_COLS) { left=0; top+=size; @@ -150,22 +158,36 @@ private: bool InitMaterial() { - material=shader_manage->CreateMaterial( OS_TEXT("res/shader/DrawRect2D.vert"), - OS_TEXT("res/shader/DrawRect2D.geom"), - OS_TEXT("res/shader/FlatTexture.frag")); - if(!material) + material_instance=db->CreateMaterialInstance(OS_TEXT("res/material/TextureRect2D")); + if(!material_instance) return(false); - material_instance=material->CreateInstance(); + pipeline=CreatePipeline(material_instance,InlinePipeline::Solid2D,Prim::SolidRectangles); - sampler=db->CreateSampler(); + sampler=db->CreateSampler(); - material_instance->BindSampler("tex",tile_data->GetTexture(),sampler); - material_instance->BindUBO("world",ubo_world_matrix); - material_instance->Update(); + { + MaterialParameters *mp_global=material_instance->GetMP(DescriptorSetsType::Global); + + if(!mp_global) + return(false); + + if(!mp_global->BindUBO("g_camera",ubo_camera_info))return(false); + + mp_global->Update(); + } + + { + MaterialParameters *mp_texture=material_instance->GetMP(DescriptorSetsType::Value); + + if(!mp_texture) + return(false); + + if(!mp_texture->BindSampler("tex",tile_data->GetTexture(),sampler))return(false); + + mp_texture->Update(); + } - db->Add(material); - db->Add(material_instance); return(true); } @@ -178,38 +200,27 @@ private: cam.Refresh(); - ubo_world_matrix=db->CreateUBO(sizeof(WorldMatrix),&cam.matrix); + ubo_camera_info=db->CreateUBO(sizeof(CameraInfo),&cam.info); - if(!ubo_world_matrix) + if(!ubo_camera_info) return(false); return(true); } - void InitVBO() + bool InitVBO() { - const int tile_count=tile_list.GetCount(); + const uint tile_count=tile_list.GetCount(); - render_obj=db->CreateRenderable(material,tile_count); + render_obj=db->CreateRenderable(tile_count); + if(!render_obj)return(false); - vertex_buffer =db->CreateVAB(VAF_VEC4,tile_count,vertex_data); - tex_coord_buffer=db->CreateVAB(VAF_VEC4,tile_count,tex_coord_data); + render_obj->Set(VAN::Position,db->CreateVBO(VF_V4F,tile_count,vertex_data)); + render_obj->Set(VAN::TexCoord,db->CreateVBO(VF_V4F,tile_count,tex_coord_data)); - render_obj->Set("Vertex",vertex_buffer); - render_obj->Set("TexCoord",tex_coord_buffer); - } + render_instance=db->CreateRenderableInstance(render_obj,material_instance,pipeline); - bool InitPipeline() - { - AutoDelete - pipeline_creater=new vulkan::PipelineCreater(device,material,sc_render_target); - pipeline_creater->CloseCullFace(); - pipeline_creater->Set(Prim::Rectangles); - - pipeline=pipeline_creater->Create(); - - db->Add(pipeline); - return pipeline; + return(render_instance); } public: @@ -231,12 +242,10 @@ public: if(!InitMaterial()) return(false); - InitVBO(); - - if(!InitPipeline()) + if(!InitVBO()) return(false); - BuildCommandBuffer(pipeline,material_instance,render_obj); + BuildCommandBuffer(render_instance); return(true); } @@ -248,9 +257,9 @@ public: cam.Refresh(); - ubo_world_matrix->Write(&cam.matrix); - - BuildCommandBuffer(pipeline,material_instance,render_obj); + ubo_camera_info->Write(&cam.info); + + BuildCommandBuffer(render_instance); } };//class TestApp:public VulkanApplicationFramework diff --git a/example/Vulkan/EquirectangularMap.cpp b/example/Vulkan/EquirectangularMap.cpp new file mode 100644 index 00000000..f9f462fa --- /dev/null +++ b/example/Vulkan/EquirectangularMap.cpp @@ -0,0 +1,182 @@ +// Equirectangular ( or spherical) +// 等距矩形(或球形)贴图反射测试 + +#include"VulkanAppFramework.h" +#include +#include +#include +#include +#include +#include + +using namespace hgl; +using namespace hgl::graph; + +constexpr uint32_t SCREEN_WIDTH=1280; +constexpr uint32_t SCREEN_HEIGHT=512; + +class TestApp:public CameraAppFramework +{ +private: + + SceneNode render_root; + RenderList * render_list =nullptr; + + Material * envmap_material =nullptr; + MaterialInstance * envmap_mi =nullptr; + + Pipeline * solid_pipeline =nullptr; + + GPUBuffer * ubo_light =nullptr; + GPUBuffer * ubo_phong =nullptr; + + Sampler * sampler =nullptr; + Texture2D * texture =nullptr; + + Renderable * ro_sphere =nullptr; + +private: + + bool InitMaterial() + { + { + // photo source: https://www.hqreslib.com + // license: CY-BY + + texture =db->LoadTexture2D(OS_TEXT("res/equirectangular/jifu.Tex2D"),false); + + if(!texture) + return(false); + + VkSamplerCreateInfo sampler_create_info= + { + VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, + nullptr, + 0, + VK_FILTER_LINEAR, + VK_FILTER_LINEAR, + VK_SAMPLER_MIPMAP_MODE_LINEAR, + VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, + VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, + VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, + 0.0f, + VK_FALSE, + 0, + false, + VK_COMPARE_OP_NEVER, + 0.0f, + 0, + VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK, + false + }; + + sampler =db->CreateSampler(&sampler_create_info); + } + + { + envmap_material=db->CreateMaterial(OS_TEXT("res/material/EnvEquirectangularMap")); + if(!envmap_material)return(false); + + envmap_mi=db->CreateMaterialInstance(envmap_material); + if(!envmap_mi)return(false); + + { + MaterialParameters *mp_texture=envmap_mi->GetMP(DescriptorSetsType::Value); + + if(!mp_texture) + return(false); + + if(!mp_texture->BindSampler("Envmap" ,texture, sampler)) + return(false); + + mp_texture->Update(); + } + + solid_pipeline=CreatePipeline(envmap_mi,InlinePipeline::Solid3D,Prim::Triangles); + } + + return(true); + } + + void CreateRenderObject() + { + ro_sphere=CreateRenderableSphere(db,envmap_mi->GetVAB(),64); + } + + bool InitUBO() + { + if(!BindCameraUBO(envmap_mi))return(false); + + return(true); + } + + SceneNode *Add(Renderable *r,MaterialInstance *mi,Pipeline *pl) + { + auto ri=db->CreateRenderableInstance(r,mi,pl); + + return render_root.CreateSubNode(ri); + } + + bool InitScene() + { + auto sn_sphere=Add(ro_sphere,envmap_mi,solid_pipeline); + sn_sphere->SetLocalMatrix(scale(5,5,5)); + + render_root.RefreshMatrix(); + render_list->Expend(GetCameraInfo(),&render_root); + + return(true); + } + +public: + + ~TestApp() + { + SAFE_CLEAR(render_list); + } + + bool Init() + { + if(!CameraAppFramework::Init(SCREEN_WIDTH,SCREEN_HEIGHT)) + return(false); + + camera->pos=Vector3f(10,10,0); + + camera_control->SetTarget(Vector3f(0,0,0)); + + render_list=new RenderList(device); + + if(!InitMaterial()) + return(false); + + if(!InitUBO()) + return(false); + + CreateRenderObject(); + + if(!InitScene()) + return(false); + + return(true); + } + + void BuildCommandBuffer(uint32_t index) override + { + render_root.RefreshMatrix(); + render_list->Expend(GetCameraInfo(),&render_root); + + VulkanApplicationFramework::BuildCommandBuffer(index,render_list); + } +};//class TestApp:public CameraAppFramework + +int main(int,char **) +{ + TestApp app; + + if(!app.Init()) + return(-1); + + while(app.Run()); + + return 0; +} diff --git a/example/Vulkan/FragCoordTest.cpp b/example/Vulkan/FragCoordTest.cpp index 76558c9f..bace6033 100644 --- a/example/Vulkan/FragCoordTest.cpp +++ b/example/Vulkan/FragCoordTest.cpp @@ -7,11 +7,8 @@ using namespace hgl; using namespace hgl::graph; -bool SaveToFile(const OSString &filename,VK_NAMESPACE::PipelineCreater *pc); -bool LoadFromFile(const OSString &filename,VK_NAMESPACE::PipelineCreater *pc); - -constexpr uint32_t SCREEN_WIDTH=128; -constexpr uint32_t SCREEN_HEIGHT=128; +constexpr uint32_t SCREEN_WIDTH=256; +constexpr uint32_t SCREEN_HEIGHT=256; constexpr uint32_t VERTEX_COUNT=4; @@ -29,39 +26,24 @@ private: Camera cam; - vulkan::Material * material =nullptr; - vulkan::MaterialInstance * material_instance =nullptr; - vulkan::Renderable * render_obj =nullptr; - vulkan::Buffer * ubo_world_matrix =nullptr; + MaterialInstance * material_instance =nullptr; + RenderableInstance *renderable_instance =nullptr; + GPUBuffer * ubo_camera_info =nullptr; - vulkan::Pipeline * pipeline =nullptr; - - vulkan::VAB * vertex_buffer =nullptr; - -public: - - ~TestApp() - { - SAFE_CLEAR(vertex_buffer); - SAFE_CLEAR(pipeline); - SAFE_CLEAR(ubo_world_matrix); - SAFE_CLEAR(render_obj); - SAFE_CLEAR(material_instance); - SAFE_CLEAR(material); - } + Pipeline * pipeline =nullptr; private: bool InitMaterial() { - material=shader_manage->CreateMaterial(OS_TEXT("res/shader/OnlyPosition.vert"), - OS_TEXT("res/shader/FragCoord.frag")); - if(!material) - return(false); + material_instance=db->CreateMaterialInstance(OS_TEXT("res/material/FragColor")); - render_obj=material->CreateRenderable(VERTEX_COUNT); - material_instance=material->CreateInstance(); - return(true); + if(!material_instance) + return(false); + + pipeline=CreatePipeline(material_instance,InlinePipeline::Solid2D,Prim::TriangleStrip); + + return pipeline; } bool InitUBO() @@ -73,35 +55,33 @@ private: cam.Refresh(); - ubo_world_matrix=device->CreateUBO(sizeof(WorldMatrix),&cam.matrix); + ubo_camera_info=db->CreateUBO(sizeof(CameraInfo),&cam.info); - if(!ubo_world_matrix) + if(!ubo_camera_info) return(false); - material_instance->BindUBO("world",ubo_world_matrix); - material_instance->BindUBO("fragment_world",ubo_world_matrix); + { + MaterialParameters *mp_global=material_instance->GetMP(DescriptorSetsType::Global); + + if(!mp_global) + return(false); - material_instance->Update(); + if(!mp_global->BindUBO("g_camera",ubo_camera_info))return(false); + + mp_global->Update(); + } return(true); } - void InitVBO() + bool InitVBO() { - vertex_buffer =device->CreateVAB(FMT_RG32F, VERTEX_COUNT,vertex_data); + auto render_obj=db->CreateRenderable(VERTEX_COUNT); + if(!render_obj)return(false); - render_obj->Set("Vertex", vertex_buffer); - } + if(!render_obj->Set(VAN::Position,db->CreateVBO(VF_V2F,VERTEX_COUNT,vertex_data)))return(false); - bool InitPipeline() - { - AutoDelete - pipeline_creater=new vulkan::PipelineCreater(device,material,sc_render_target); - pipeline_creater->CloseCullFace(); - pipeline_creater->Set(PRIM_TRIANGLE_STRIP); - - pipeline=pipeline_creater->Create(); - - return pipeline; + renderable_instance=db->CreateRenderableInstance(render_obj,material_instance,pipeline); + return(true); } public: @@ -117,26 +97,26 @@ public: if(!InitUBO()) return(false); - InitVBO(); - - if(!InitPipeline()) + if(!InitVBO()) return(false); - BuildCommandBuffer(pipeline,material_instance,render_obj); + BuildCommandBuffer(renderable_instance); return(true); } void Resize(int w,int h)override { + cam.width=w; + cam.height=h; cam.vp_width=w; cam.vp_height=h; cam.Refresh(); - ubo_world_matrix->Write(&cam.matrix); + ubo_camera_info->Write(&cam.info); - BuildCommandBuffer(pipeline,material_instance,render_obj); + BuildCommandBuffer(renderable_instance); } };//class TestApp:public VulkanApplicationFramework diff --git a/example/Vulkan/Geometry2D.cpp b/example/Vulkan/Geometry2D.cpp index 51ea0cc3..06b6945a 100644 --- a/example/Vulkan/Geometry2D.cpp +++ b/example/Vulkan/Geometry2D.cpp @@ -7,18 +7,15 @@ #include"VulkanAppFramework.h" #include #include -#include -#include +#include +#include #include using namespace hgl; using namespace hgl::graph; -bool SaveToFile(const OSString &filename,VK_NAMESPACE::PipelineCreater *pc); -bool LoadFromFile(const OSString &filename,VK_NAMESPACE::PipelineCreater *pc); - -constexpr uint32_t SCREEN_WIDTH=128; -constexpr uint32_t SCREEN_HEIGHT=128; +constexpr uint32_t SCREEN_WIDTH=256; +constexpr uint32_t SCREEN_HEIGHT=256; static Vector4f color(1,1,0,1); @@ -28,35 +25,41 @@ class TestApp:public VulkanApplicationFramework private: - SceneNode render_root; - RenderList render_list; + SceneNode render_root; + RenderList render_list; - vulkan::Material * material =nullptr; - vulkan::MaterialInstance * material_instance =nullptr; + Material * material =nullptr; + MaterialInstance * material_instance =nullptr; - vulkan::Renderable *ro_rectangle =nullptr, - *ro_circle =nullptr, - *ro_round_rectangle =nullptr; + Renderable * ro_rectangle =nullptr; + Renderable * ro_circle =nullptr; + Renderable * ro_round_rectangle =nullptr; - vulkan::Buffer * ubo_world_matrix =nullptr; - vulkan::Buffer * ubo_color_material =nullptr; + GPUBuffer * ubo_camera_info =nullptr; + GPUBuffer * ubo_color_material =nullptr; - vulkan::Pipeline * pipeline =nullptr; + Pipeline * pipeline =nullptr; private: + bool RecreatePipeline() + { + pipeline=CreatePipeline(material,InlinePipeline::Solid2D,Prim::Fan); + + return pipeline; + } + bool InitMaterial() { - material=shader_manage->CreateMaterial(OS_TEXT("res/shader/OnlyPosition.vert"), - OS_TEXT("res/shader/FlatColor.frag")); - if(!material) - return(false); - - material_instance=material->CreateInstance(); + material=db->CreateMaterial(OS_TEXT("res/material/PureColor2D")); - db->Add(material); - db->Add(material_instance); - return(true); + if(!material)return(false); + + material_instance=db->CreateMaterialInstance(material); + + if(!material_instance)return(false); + + return RecreatePipeline(); } void CreateRenderObject() @@ -94,21 +97,20 @@ private: } } - vulkan::Buffer *CreateUBO(const AnsiString &name,const VkDeviceSize size,void *data) + GPUBuffer *CreateUBO(const AnsiString &name,const VkDeviceSize size,void *data) { - vulkan::Buffer *ubo=device->CreateUBO(size,data); + GPUBuffer *ubo=db->CreateUBO(size,data); if(!ubo) return(nullptr); if(!material_instance->BindUBO(name,ubo)) { + std::cerr<<"Bind UBO<"< to material failed!"<Add(ubo); - return ubo; } @@ -121,32 +123,18 @@ private: cam.Refresh(); - ubo_world_matrix =CreateUBO("world", sizeof(WorldMatrix),&cam.matrix); - ubo_color_material =CreateUBO("color_material",sizeof(Vector4f),&color); + ubo_camera_info =CreateUBO("camera", sizeof(CameraInfo),&cam.info); + ubo_color_material =CreateUBO("color_material", sizeof(Vector4f),&color); material_instance->Update(); return(true); } - bool InitPipeline() - { - AutoDelete - pipeline_creater=new vulkan::PipelineCreater(device,material,sc_render_target); - pipeline_creater->CloseCullFace(); - pipeline_creater->Set(Prim::Fan); - - pipeline=pipeline_creater->Create(); - if(!pipeline)return(false); - - db->Add(pipeline); - return(true); - } - bool InitScene() { - render_root.Add(db->CreateRenderableInstance(pipeline,material_instance,ro_rectangle)); - render_root.Add(db->CreateRenderableInstance(pipeline,material_instance,ro_round_rectangle)); - render_root.Add(db->CreateRenderableInstance(pipeline,material_instance,ro_circle)); + render_root.Add(db->CreateRenderableInstance(ro_rectangle, material_instance,pipeline)); + render_root.Add(db->CreateRenderableInstance(ro_round_rectangle,material_instance,pipeline)); + render_root.Add(db->CreateRenderableInstance(ro_circle, material_instance,pipeline)); render_root.ExpendToList(&render_list); BuildCommandBuffer(&render_list); @@ -168,9 +156,6 @@ public: if(!InitUBO()) return(false); - if(!InitPipeline()) - return(false); - if(!InitScene()) return(false); @@ -184,7 +169,10 @@ public: cam.Refresh(); - ubo_world_matrix->Write(&cam.matrix); + ubo_camera_info->Write(&cam.info); + + RecreatePipeline(); + renderable_instance->UpdatePipeline(pipeline); BuildCommandBuffer(&render_list); } diff --git a/example/Vulkan/Geometry3D.cpp b/example/Vulkan/Geometry3D.cpp index adc04a1b..4cbe187f 100644 --- a/example/Vulkan/Geometry3D.cpp +++ b/example/Vulkan/Geometry3D.cpp @@ -3,9 +3,9 @@ #include"VulkanAppFramework.h" #include #include -#include -#include +#include #include +#include using namespace hgl; using namespace hgl::graph; @@ -17,159 +17,110 @@ class TestApp:public CameraAppFramework { Color4f color; - vulkan::Buffer *ubo_color=nullptr; + GPUBuffer *ubo_color=nullptr; private: SceneNode render_root; - RenderList render_list; + RenderList *render_list=nullptr; - struct MDP - { - vulkan::Material * material =nullptr; - vulkan::MaterialInstance * material_instance =nullptr; - vulkan::Pipeline * pipeline =nullptr; - }m3d,m2d; + Material * material =nullptr; + MaterialInstance * material_instance =nullptr; + Pipeline * pipeline =nullptr; - vulkan::Renderable *ro_plane_grid[3], - *ro_round_rectangle =nullptr; + Renderable * ro_plane_grid[3]; private: - bool InitMaterial(MDP *mdp,const OSString &vs,const OSString &fs) + bool InitMDP() { - mdp->material=shader_manage->CreateMaterial(vs,fs); + material=db->CreateMaterial(OS_TEXT("res/material/VertexColor3D")); + if(!material)return(false); + + material_instance=db->CreateMaterialInstance(material); + if(!material_instance)return(false); - if(!mdp->material) - return(false); - - mdp->material_instance=mdp->material->CreateInstance(); - - db->Add(mdp->material); - db->Add(mdp->material_instance); - return(true); - } - - bool InitUBO(MDP *mdp) - { - if(!mdp->material_instance->BindUBO("world",GetCameraMatrixBuffer())) - return(false); - - mdp->material_instance->Update(); - return(true); - } - - bool InitPipeline(MDP *mdp,const Prim primitive) - { - AutoDelete - pipeline_creater=new vulkan::PipelineCreater(device,mdp->material,sc_render_target); - pipeline_creater->CloseCullFace(); - pipeline_creater->Set(primitive); - - mdp->pipeline=pipeline_creater->Create(); - - if(!mdp->pipeline) - return(false); - - db->Add(mdp->pipeline); - return(true); - } - - bool InitMDP(MDP *mdp,const Prim primitive,const OSString &vs,const OSString &fs) - { - if(!InitMaterial(mdp,vs,fs)) - return(false); - - if(!InitUBO(mdp)) - return(false); - - if(!InitPipeline(mdp,primitive)) + pipeline=CreatePipeline(material_instance,InlinePipeline::Solid3D,Prim::Lines); + if(!pipeline) return(false); return(true); } - - bool InitScene() + + RenderableInstance *Add(Renderable *r,const Matrix4f &mat) { - render_root.Add(db->CreateRenderableInstance(m2d.pipeline,m2d.material_instance,ro_round_rectangle)); + RenderableInstance *ri=db->CreateRenderableInstance(r,material_instance,pipeline); - render_root.Add(db->CreateRenderableInstance(m3d.pipeline,m3d.material_instance,ro_plane_grid[0])); - render_root.Add(db->CreateRenderableInstance(m3d.pipeline,m3d.material_instance,ro_plane_grid[1]),rotate(HGL_RAD_90,0,1,0)); - render_root.Add(db->CreateRenderableInstance(m3d.pipeline,m3d.material_instance,ro_plane_grid[2]),rotate(HGL_RAD_90,1,0,0)); + render_root.CreateSubNode(mat,ri); - render_root.RefreshMatrix(); - render_root.ExpendToList(&render_list); - - return(true); + return ri; } void CreateRenderObject() { struct PlaneGridCreateInfo pgci; - pgci.coord[0].Set(-100,-100,0); - pgci.coord[1].Set( 100,-100,0); - pgci.coord[2].Set( 100, 100,0); - pgci.coord[3].Set(-100, 100,0); + pgci.coord[0]=Vector3f(-100,-100,0); + pgci.coord[1]=Vector3f( 100,-100,0); + pgci.coord[2]=Vector3f( 100, 100,0); + pgci.coord[3]=Vector3f(-100, 100,0); - pgci.step.u=20; - pgci.step.v=20; + pgci.step.x=32; + pgci.step.y=32; - pgci.side_step.u=10; - pgci.side_step.v=10; + pgci.side_step.x=8; + pgci.side_step.y=8; - pgci.color.Set(0.75,0,0,1); + pgci.color.Set(0.5,0,0,1); pgci.side_color.Set(1,0,0,1); - ro_plane_grid[0]=CreateRenderablePlaneGrid(db,m3d.material,&pgci); + const VAB *vab=material_instance->GetVAB(); - pgci.color.Set(0,0.75,0,1); + ro_plane_grid[0]=CreateRenderablePlaneGrid(db,vab,&pgci); + + pgci.color.Set(0,0.5,0,1); pgci.side_color.Set(0,1,0,1); - ro_plane_grid[1]=CreateRenderablePlaneGrid(db,m3d.material,&pgci); + ro_plane_grid[1]=CreateRenderablePlaneGrid(db,vab,&pgci); - pgci.color.Set(0,0,0.75,1); + pgci.color.Set(0,0,0.5,1); pgci.side_color.Set(0,0,1,1); - ro_plane_grid[2]=CreateRenderablePlaneGrid(db,m3d.material,&pgci); + ro_plane_grid[2]=CreateRenderablePlaneGrid(db,vab,&pgci); + } - { - struct RoundRectangleCreateInfo rrci; + bool InitScene() + { + Add(ro_plane_grid[0],Matrix4f(1.0f)); + Add(ro_plane_grid[1],rotate(HGL_RAD_90,0,1,0)); + Add(ro_plane_grid[2],rotate(HGL_RAD_90,1,0,0)); - rrci.scope.Set(SCREEN_WIDTH-30,10,20,20); - rrci.radius=5; - rrci.round_per=5; + camera->pos=Vector3f(200,200,200); + camera_control->SetTarget(Vector3f(0,0,0)); + camera_control->Refresh(); - ro_round_rectangle=CreateRenderableRoundRectangle(db,m2d.material,&rrci); - } + render_root.RefreshMatrix(); + render_list->Expend(camera->info,&render_root); - camera.eye.Set(200,200,200,1.0); + return(true); } public: + ~TestApp() + { + SAFE_CLEAR(render_list); + } + bool Init() { if(!CameraAppFramework::Init(SCREEN_WIDTH,SCREEN_HEIGHT)) return(false); + + render_list=new RenderList(device); - if(!InitMDP(&m3d,Prim::Lines,OS_TEXT("res/shader/PositionColor3D.vert"), - OS_TEXT("res/shader/VertexColor.frag"))) + if(!InitMDP()) return(false); - if(!InitMDP(&m2d,Prim::Fan, OS_TEXT("res/shader/OnlyPosition.vert"), - OS_TEXT("res/shader/FlatColor.frag"))) - return(false); - - { - color.Set(1,1,0,1); - ubo_color=device->CreateUBO(sizeof(Vector4f),&color); - - m2d.material_instance->BindUBO("color_material",ubo_color); - m2d.material_instance->Update(); - - db->Add(ubo_color); - } - CreateRenderObject(); if(!InitScene()) @@ -180,7 +131,17 @@ public: void BuildCommandBuffer(uint32 index) { - VulkanApplicationFramework::BuildCommandBuffer(index,&render_list); + render_root.RefreshMatrix(); + render_list->Expend(GetCameraInfo(),&render_root); + + VulkanApplicationFramework::BuildCommandBuffer(index,render_list); + } + + void Resize(int w,int h)override + { + CameraAppFramework::Resize(w,h); + + VulkanApplicationFramework::BuildCommandBuffer(render_list); } };//class TestApp:public CameraAppFramework diff --git a/example/Vulkan/HQFilterTexture.cpp b/example/Vulkan/HQFilterTexture.cpp index e92947da..b1b50c28 100644 --- a/example/Vulkan/HQFilterTexture.cpp +++ b/example/Vulkan/HQFilterTexture.cpp @@ -2,28 +2,23 @@ // 测试高质量纹理过滤函数 #include"VulkanAppFramework.h" -#include -#include +#include +#include #include using namespace hgl; using namespace hgl::graph; -VK_NAMESPACE_BEGIN -Texture2D *CreateTextureFromFile(Device *device,const OSString &filename); -VK_NAMESPACE_END - -constexpr uint32_t SCREEN_WIDTH=512; -constexpr uint32_t SCREEN_HEIGHT=512; +constexpr uint32_t SCREEN_SIZE=512; constexpr uint32_t VERTEX_COUNT=4; constexpr float vertex_data[VERTEX_COUNT][2]= { - {0,0}, - {1,0}, - {0,1}, - {1,1} + {0, 0}, + {1, 0}, + {0, 1}, + {1, 1} }; constexpr float tex_coord_data[VERTEX_COUNT][2]= @@ -42,74 +37,77 @@ constexpr uint16 index_data[INDEX_COUNT]= 0,3,2 }; -class TestApp:public VulkanApplicationFramework +class TestApp:public CameraAppFramework { private: - struct MPD + PipelineData * pipeline_data =nullptr; + Renderable * render_obj =nullptr; + Sampler * sampler_linear =nullptr; + Sampler * sampler_nearest =nullptr; + + struct MP { - vulkan::Material * material =nullptr; - vulkan::Pipeline * pipeline =nullptr; - vulkan::MaterialInstance * material_instance =nullptr; - vulkan::Renderable * render_obj =nullptr; + Material * material =nullptr; + Pipeline * pipeline =nullptr; + }mp_normal,mp_hq; - public: - - ~MPD() - { - delete material; - delete render_obj; - delete material_instance; - delete pipeline; - } - }nearest,linear,nearest_hq,linear_hq; + struct MIR + { + MaterialInstance * material_instance =nullptr; + RenderableInstance *renderable_instance =nullptr; + }mir_nearest,mir_linear,mir_nearest_hq,mir_linear_hq; - vulkan::Texture2D * texture =nullptr; + Texture2D * texture =nullptr; - vulkan::Sampler * sampler_linear =nullptr; - vulkan::Sampler * sampler_nearest =nullptr; - - vulkan::VAB * vertex_buffer =nullptr; - vulkan::VAB * tex_coord_buffer =nullptr; - vulkan::IndexBuffer * index_buffer =nullptr; + VAB * vertex_buffer =nullptr; + VAB * tex_coord_buffer =nullptr; + IndexBuffer * index_buffer =nullptr; - SceneNode render_root; - RenderList render_list; + SceneNode render_root; + RenderList *render_list =nullptr; + public: ~TestApp() { - SAFE_CLEAR(index_buffer); - SAFE_CLEAR(tex_coord_buffer); - SAFE_CLEAR(vertex_buffer); - SAFE_CLEAR(sampler_nearest); - SAFE_CLEAR(sampler_linear); - SAFE_CLEAR(texture); + SAFE_CLEAR(render_list); } private: bool InitVBO() { - vertex_buffer =device->CreateVAB(FMT_RG32F,VERTEX_COUNT,vertex_data); + vertex_buffer =db->CreateVAB(VF_VEC2,VERTEX_COUNT,vertex_data); if(!vertex_buffer)return(false); - tex_coord_buffer=device->CreateVAB(FMT_RG32F,VERTEX_COUNT,tex_coord_data); + tex_coord_buffer=db->CreateVAB(VF_VEC2,VERTEX_COUNT,tex_coord_data); if(!tex_coord_buffer)return(false); - index_buffer =device->CreateIBO16(INDEX_COUNT,index_data); + index_buffer =db->CreateIBO16(INDEX_COUNT,index_data); if(!index_buffer)return(false); return(true); } - vulkan::Sampler *InitSampler(VkFilter filter) + bool InitRenderObject() { - VkSamplerCreateInfo sampler_create_info; + render_obj=db->CreateRenderable(VERTEX_COUNT); + if(!render_obj)return(false); + + render_obj->Set(VAN::Position,vertex_buffer); + render_obj->Set(VAN::TexCoord,tex_coord_buffer); + render_obj->Set(index_buffer); + + render_list=new RenderList(device); + + return(true); + } + + Sampler *InitSampler(VkFilter filter) + { + SamplerCreateInfo sampler_create_info; - sampler_create_info.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO; - sampler_create_info.pNext = nullptr; - sampler_create_info.flags = 0; sampler_create_info.magFilter = filter; sampler_create_info.minFilter = filter; sampler_create_info.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR; @@ -126,63 +124,86 @@ private: sampler_create_info.borderColor = VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK; sampler_create_info.unnormalizedCoordinates = false; - return device->CreateSampler(&sampler_create_info); + return db->CreateSampler(&sampler_create_info); } bool InitTexture() { - texture=vulkan::CreateTextureFromFile(device,OS_TEXT("res/image/heightmap.Tex2D")); + texture=db->LoadTexture2D(OS_TEXT("res/image/heightmap.Tex2D")); return texture; } - bool InitMaterial(struct MPD *mpd,vulkan::Sampler *sampler,const OSString &fragment_shader) + bool InitMaterial(MP *mp,const OSString &mtl_name) { - mpd->material=shader_manage->CreateMaterial(OS_TEXT("res/shader/Texture2D.vert"), - OS_TEXT("res/shader/")+fragment_shader+OS_TEXT(".frag")); - if(!mpd->material) - return(false); + mp->material=db->CreateMaterial(mtl_name); + if(!mp->material)return(false); - mpd->material_instance=mpd->material->CreateInstance(); + mp->pipeline=CreatePipeline(mp->material,pipeline_data); + if(!mp->pipeline)return(false); - mpd->material_instance->BindSampler("tex",texture,sampler); - mpd->material_instance->Update(); - - mpd->render_obj=mpd->material->CreateRenderable(VERTEX_COUNT); - mpd->render_obj->Set("Vertex",vertex_buffer); - mpd->render_obj->Set("TexCoord",tex_coord_buffer); - mpd->render_obj->Set(index_buffer); - - AutoDelete - pipeline_creater=new vulkan::PipelineCreater(device,mpd->material,sc_render_target); - pipeline_creater->CloseCullFace(); - pipeline_creater->Set(Prim::Triangles); - - mpd->pipeline=pipeline_creater->Create(); - - return mpd->pipeline; + return(true); } - bool Add(struct MPD *mpd,const Matrix4f &offset) + bool InitMaterial() { - RenderableInstance *ri=db->CreateRenderableInstance(mpd->pipeline,mpd->material_instance,mpd->render_obj); + pipeline_data=GetPipelineData(InlinePipeline::Solid2D); + if(!pipeline_data)return(false); - if(!ri)return(false); + if(!InitMaterial(&mp_normal,OS_TEXT("res/material/Texture2D")))return(false); + if(!InitMaterial(&mp_hq, OS_TEXT("res/material/Texture2DHQ")))return(false); - render_root.Add(ri,offset); + return(true); + } + + bool InitMIR(struct MIR *mir,Sampler *sampler,MP *mp) + { + mir->material_instance=db->CreateMaterialInstance(mp->material); + if(!mir->material_instance)return(false); + + { + MaterialParameters *mp_global=mir->material_instance->GetMP(DescriptorSetsType::Global); + + if(!mp_global) + return(false); + + if(!mp_global->BindUBO("g_camera",GetCameraInfoBuffer()))return(false); + + mp_global->Update(); + } + + { + MaterialParameters *mp_texture=mir->material_instance->GetMP(DescriptorSetsType::Value); + + if(!mp_texture) + return(false); + + if(!mp_texture->BindSampler("tex",texture,sampler))return(false); + + mp_texture->Update(); + } + + mir->renderable_instance=db->CreateRenderableInstance(render_obj,mir->material_instance,mp->pipeline); + + if(!mir->renderable_instance) + return(false); + + return(true); + } + + bool Add(struct MIR *mir,const Matrix4f &offset) + { + render_root.CreateSubNode(offset,mir->renderable_instance); return(true); } bool InitScene() { - Add(&nearest, translate(-1,-1,0)); - Add(&linear, translate( 0,-1,0)); - Add(&nearest_hq,translate(-1, 0,0)); - Add(&linear_hq, translate( 0, 0,0)); + Add(&mir_nearest, translate(-1,-1,0)); + Add(&mir_linear, translate( 0,-1,0)); + Add(&mir_nearest_hq,translate(-1, 0,0)); + Add(&mir_linear_hq, translate( 0, 0,0)); - render_root.RefreshMatrix(); - render_root.ExpendToList(&render_list); - BuildCommandBuffer(&render_list); return(true); } @@ -190,22 +211,28 @@ public: bool Init() { - if(!VulkanApplicationFramework::Init(SCREEN_WIDTH,SCREEN_HEIGHT)) + if(!CameraAppFramework::Init(SCREEN_SIZE,SCREEN_SIZE)) return(false); if(!InitVBO()) return(false); - sampler_nearest=InitSampler(VK_FILTER_NEAREST); - sampler_linear=InitSampler(VK_FILTER_LINEAR); + if(!InitRenderObject()) + return(false); if(!InitTexture()) return(false); - if(!InitMaterial(&nearest, sampler_nearest ,OS_TEXT("FlatTexture")))return(false); - if(!InitMaterial(&linear, sampler_linear ,OS_TEXT("FlatTexture")))return(false); - if(!InitMaterial(&nearest_hq, sampler_nearest ,OS_TEXT("hqfilter")))return(false); - if(!InitMaterial(&linear_hq, sampler_linear ,OS_TEXT("hqfilter")))return(false); + if(!InitMaterial()) + return(false); + + sampler_nearest=InitSampler(VK_FILTER_NEAREST); + sampler_linear=InitSampler(VK_FILTER_LINEAR); + + if(!InitMIR(&mir_nearest, sampler_nearest ,&mp_normal ))return(false); + if(!InitMIR(&mir_linear, sampler_linear ,&mp_normal ))return(false); + if(!InitMIR(&mir_nearest_hq, sampler_nearest ,&mp_hq ))return(false); + if(!InitMIR(&mir_linear_hq, sampler_linear ,&mp_hq ))return(false); if(!InitScene()) return(false); @@ -215,14 +242,22 @@ public: void Resize(int w,int h) override { - BuildCommandBuffer(&render_list); + VulkanApplicationFramework::BuildCommandBuffer(render_list); + } + + void BuildCommandBuffer(uint32_t index) override + { + render_root.RefreshMatrix(); + render_list->Expend(camera->info,&render_root); + + VulkanApplicationFramework::BuildCommandBuffer(index,render_list); } };//class TestApp:public VulkanApplicationFramework int main(int,char **) { #ifdef _DEBUG - if(!vulkan::CheckStrideBytesByFormat()) + if(!CheckStrideBytesByFormat()) return 0xff; #endif// diff --git a/example/Vulkan/InlineGeometryScene.cpp b/example/Vulkan/InlineGeometryScene.cpp index b2d7c80d..94fa31e7 100644 --- a/example/Vulkan/InlineGeometryScene.cpp +++ b/example/Vulkan/InlineGeometryScene.cpp @@ -4,8 +4,9 @@ #include"VulkanAppFramework.h" #include #include -#include -#include +#include +#include +#include #include using namespace hgl; @@ -14,84 +15,160 @@ using namespace hgl::graph; constexpr uint32_t SCREEN_WIDTH=1280; constexpr uint32_t SCREEN_HEIGHT=720; +struct PhongLight +{ + Vector4f color; + Vector4f position; +}; + +struct PhongMaterial +{ + Vector4f BaseColor; + Vector4f specular; + float ambient; +}; + +constexpr size_t v3flen=sizeof(PhongLight); + class TestApp:public CameraAppFramework { - Color4f color; + PhongLight light; + PhongMaterial phong; private: - SceneNode render_root; - RenderList render_list; + SceneNode render_root; + RenderList * render_list =nullptr; + + Material * material =nullptr; + MaterialInstance * material_instance =nullptr; - vulkan::Material * material =nullptr; - vulkan::MaterialInstance * material_instance =nullptr; - vulkan::Buffer * ubo_color =nullptr; + Material * axis_material =nullptr; + MaterialInstance * axis_mi =nullptr; - vulkan::Renderable *ro_plane_grid, - *ro_cube, - *ro_sphere, - *ro_dome, - *ro_torus, - *ro_cylinder, - *ro_cone; + Pipeline * axis_pipeline =nullptr; + Pipeline * pipeline_solid =nullptr; - vulkan::Pipeline *pipeline_line =nullptr, - *pipeline_solid =nullptr; + GPUBuffer * ubo_light =nullptr; + GPUBuffer * ubo_phong =nullptr; + + struct + { + Sampler * sampler =nullptr; + Texture2D * color =nullptr; + Texture2D * normal =nullptr; + }texture; + + Renderable *ro_axis, + *ro_cube, + *ro_sphere, + *ro_torus, + *ro_cylinder, + *ro_cone; private: bool InitMaterial() { - material=shader_manage->CreateMaterial(OS_TEXT("res/shader/OnlyPosition3D.vert"), - OS_TEXT("res/shader/FlatColor.frag")); - if(!material) - return(false); + light.color=Vector4f(1,1,1,1); + light.position=Vector4f(1000,1000,1000,1.0); - material_instance=material->CreateInstance(); + phong.BaseColor=Vector4f(1,1,1,1); + phong.ambient=0.5; + phong.specular=Vector4f(0.3,0.3,0.3,32); + + { + axis_material=db->CreateMaterial(OS_TEXT("res/material/VertexColor3D")); + if(!axis_material)return(false); + + axis_mi=db->CreateMaterialInstance(axis_material); + if(!axis_mi)return(false); + + axis_pipeline=CreatePipeline(axis_mi,InlinePipeline::Solid3D,Prim::Lines); + if(!axis_pipeline)return(false); + } + + { + texture.color =db->LoadTexture2D(OS_TEXT("res/image/Brickwall/Albedo.Tex2D"),true); + texture.normal =db->LoadTexture2D(OS_TEXT("res/image/Brickwall/Normal.Tex2D"),true); + + if(!texture.color + ||!texture.normal) + return(false); + + VkSamplerCreateInfo sampler_create_info= + { + VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, + nullptr, + 0, + VK_FILTER_LINEAR, + VK_FILTER_LINEAR, + VK_SAMPLER_MIPMAP_MODE_LINEAR, + VK_SAMPLER_ADDRESS_MODE_REPEAT, + VK_SAMPLER_ADDRESS_MODE_REPEAT, + VK_SAMPLER_ADDRESS_MODE_REPEAT, + 0.0f, + VK_TRUE, + device->GetPhysicalDevice()->GetMaxSamplerAnisotropy(), + false, + VK_COMPARE_OP_NEVER, + 0.0f, + static_cast(texture.color->GetMipLevel()), + VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK, + false + }; + + texture.sampler =db->CreateSampler(&sampler_create_info); + } + + { + material=db->CreateMaterial(OS_TEXT("res/material/TextureNormal")); + if(!material)return(false); + + material_instance=db->CreateMaterialInstance(material); + if(!material_instance)return(false); + + { + MaterialParameters *mp_texture=material_instance->GetMP(DescriptorSetsType::Value); + + if(!mp_texture) + return(false); + + mp_texture->BindSampler("TexColor" ,texture.color, texture.sampler); + mp_texture->BindSampler("TexNormal" ,texture.normal, texture.sampler); + } + } + + pipeline_solid=CreatePipeline(material_instance,InlinePipeline::Solid3D,Prim::Triangles); + if(!pipeline_solid)return(false); - db->Add(material); - db->Add(material_instance); return(true); } void CreateRenderObject() { { - struct PlaneGridCreateInfo pgci; + struct AxisCreateInfo aci; - pgci.coord[0].Set(-100,-100,0); - pgci.coord[1].Set( 100,-100,0); - pgci.coord[2].Set( 100, 100,0); - pgci.coord[3].Set(-100, 100,0); + aci.size=200; - pgci.step.u=20; - pgci.step.v=20; + ro_axis=CreateRenderableAxis(db,axis_mi->GetVAB(),&aci); + } - pgci.side_step.u=10; - pgci.side_step.v=10; - - pgci.color.Set(0.75,0,0,1); - pgci.side_color.Set(1,0,0,1); - - ro_plane_grid=CreateRenderablePlaneGrid(db,material,&pgci); + const VAB *vab=material_instance->GetVAB(); + + { + struct CubeCreateInfo cci; + cci.normal=true; + cci.tangent=true; + cci.tex_coord=true; + cci.color_type=CubeCreateInfo::ColorType::SameColor; + cci.color[0]=Vector4f(1,1,1,1); + ro_cube=CreateRenderableCube(db,vab,&cci); } { - struct CubeCreateInfo cci; - ro_cube=CreateRenderableCube(db,material,&cci); - } - - { - ro_sphere=CreateRenderableSphere(db,material,16); - } - - { - DomeCreateInfo dci; - - dci.radius=100; - dci.numberSlices=32; - - ro_dome=CreateRenderableDome(db,material,&dci); + ro_sphere=CreateRenderableSphere(db,vab,64); } { @@ -100,10 +177,13 @@ private: tci.innerRadius=50; tci.outerRadius=70; - tci.numberSlices=32; - tci.numberStacks=16; + tci.numberSlices=128; + tci.numberStacks=64; - ro_torus=CreateRenderableTorus(db,material,&tci); + tci.uv_scale.x=4; + tci.uv_scale.y=1; + + ro_torus=CreateRenderableTorus(db,vab,&tci); } { @@ -111,9 +191,9 @@ private: cci.halfExtend=10; cci.radius=10; - cci.numberSlices=16; + cci.numberSlices=32; - ro_cylinder=CreateRenderableCylinder(db,material,&cci); + ro_cylinder=CreateRenderableCylinder(db,vab,&cci); } { @@ -121,87 +201,86 @@ private: cci.halfExtend=10; cci.radius=10; - cci.numberSlices=16; - cci.numberStacks=1; + cci.numberSlices=128; + cci.numberStacks=32; - ro_cone=CreateRenderableCone(db,material,&cci); + ro_cone=CreateRenderableCone(db,vab,&cci); } } bool InitUBO() { - color.Set(1,1,1,1); + ubo_light=db->CreateUBO(sizeof(PhongLight),&light); + ubo_phong=db->CreateUBO(sizeof(PhongMaterial),&phong); - ubo_color=device->CreateUBO(sizeof(Vector4f),&color); + { + MaterialParameters *mp_value=material_instance->GetMP(DescriptorSetsType::Value); + + if(!mp_value) + return(false); - db->Add(ubo_color); + mp_value->BindUBO("light",ubo_light); + mp_value->BindUBO("phong",ubo_phong); - material_instance->BindUBO("color_material",ubo_color); + mp_value->Update(); + } - if(!material_instance->BindUBO("world",GetCameraMatrixBuffer())) - return(false); + BindCameraUBO(material_instance); - material_instance->Update(); return(true); } - - bool InitPipeline() + + void Add(Renderable *r,Pipeline *pl) { - AutoDelete - pipeline_creater=new vulkan::PipelineCreater(device,material,sc_render_target); - pipeline_creater->Set(Prim::Lines); + auto ri=db->CreateRenderableInstance(r,material_instance,pl); - pipeline_line=pipeline_creater->Create(); + render_root.CreateSubNode(ri); + } - if(!pipeline_line) - return(false); + void Add(Renderable *r,Pipeline *pl,const Matrix4f &mat) + { + auto ri=db->CreateRenderableInstance(r,material_instance,pl); - db->Add(pipeline_line); - - pipeline_creater->Set(Prim::Triangles); - pipeline_creater->SetPolygonMode(VK_POLYGON_MODE_FILL); - pipeline_solid=pipeline_creater->Create(); - - if(!pipeline_solid) - return(false); - - db->Add(pipeline_solid); - return(true); + render_root.CreateSubNode(mat,ri); } bool InitScene() { - render_root.Add(db->CreateRenderableInstance(pipeline_line,material_instance,ro_plane_grid)); - //render_root.Add(db->CreateRenderableInstance(pipeline_solid,material_instance,ro_dome)); - render_root.Add(db->CreateRenderableInstance(pipeline_solid,material_instance,ro_torus)); - render_root.Add(db->CreateRenderableInstance(pipeline_solid,material_instance,ro_cube ),translate(-10, 0, 5)*scale(10,10,10)); - render_root.Add(db->CreateRenderableInstance(pipeline_solid,material_instance,ro_sphere ),translate( 10, 0, 5)*scale(10,10,10)); - render_root.Add(db->CreateRenderableInstance(pipeline_solid,material_instance,ro_cylinder ),translate( 0, 16, 0)); - render_root.Add(db->CreateRenderableInstance(pipeline_solid,material_instance,ro_cone ),translate( 0,-16, 0)); + render_root.CreateSubNode(db->CreateRenderableInstance(ro_axis,axis_mi,axis_pipeline)); + + Add(ro_torus ,pipeline_solid); + Add(ro_cube ,pipeline_solid,translate(-10, 0, 5)*scale(10,10,10)); + Add(ro_sphere ,pipeline_solid,translate( 10, 0, 5)*scale(10,10,10)); + Add(ro_cylinder ,pipeline_solid,translate( 0, 16, 0)); + Add(ro_cone ,pipeline_solid,translate( 0,-16, 0)); render_root.RefreshMatrix(); - render_root.ExpendToList(&render_list); + render_list->Expend(GetCameraInfo(),&render_root); return(true); } public: + ~TestApp() + { + SAFE_CLEAR(render_list); + } + bool Init() { if(!CameraAppFramework::Init(SCREEN_WIDTH,SCREEN_HEIGHT)) return(false); - + + render_list=new RenderList(device); + if(!InitMaterial()) return(false); - CreateRenderObject(); - if(!InitUBO()) return(false); - if(!InitPipeline()) - return(false); + CreateRenderObject(); if(!InitScene()) return(false); @@ -212,10 +291,9 @@ public: void BuildCommandBuffer(uint32_t index) override { render_root.RefreshMatrix(); - render_list.Clear(); - render_root.ExpendToList(&render_list); + render_list->Expend(GetCameraInfo(),&render_root); - VulkanApplicationFramework::BuildCommandBuffer(index,&render_list); + VulkanApplicationFramework::BuildCommandBuffer(index,render_list); } };//class TestApp:public CameraAppFramework diff --git a/example/Vulkan/LoadStaticMesh.cpp b/example/Vulkan/LoadStaticMesh.cpp index 4cd50b44..2d18d8b3 100644 --- a/example/Vulkan/LoadStaticMesh.cpp +++ b/example/Vulkan/LoadStaticMesh.cpp @@ -36,7 +36,7 @@ vulkan::Renderable *CreateMeshRenderable(Database *db,vulkan::Material *mtl,cons if(vertex_binding==-1) return(nullptr); - vulkan::VAB *vbo=db->CreateVAB(FMT_RGB32F,mesh->vertex_count,mesh->position); + vulkan::VAB *vbo=db->CreateVAB(VAF_VEC3,mesh->vertex_count,mesh->position); render_obj=mtl->CreateRenderable(); render_obj->Set(vertex_binding,vbo); @@ -47,7 +47,7 @@ vulkan::Renderable *CreateMeshRenderable(Database *db,vulkan::Material *mtl,cons if(normal_binding!=-1) { - vulkan::VAB *vbo=db->CreateVAB(FMT_RGB32F,mesh->vertex_count,mesh->normal); + vulkan::VAB *vbo=db->CreateVAB(VAF_VEC3,mesh->vertex_count,mesh->normal); render_obj->Set(normal_binding,vbo); } @@ -56,7 +56,7 @@ vulkan::Renderable *CreateMeshRenderable(Database *db,vulkan::Material *mtl,cons if(tagent_binding!=-1) { - vulkan::VAB *vbo=db->CreateVAB(FMT_RGB32F,mesh->vertex_count,mesh->tangent); + vulkan::VAB *vbo=db->CreateVAB(VAF_VEC3,mesh->vertex_count,mesh->tangent); render_obj->Set(tagent_binding,vbo); } @@ -65,7 +65,7 @@ vulkan::Renderable *CreateMeshRenderable(Database *db,vulkan::Material *mtl,cons if(bitagent_binding!=-1) { - vulkan::VAB *vbo=db->CreateVAB(FMT_RGB32F,mesh->vertex_count,mesh->bitangent); + vulkan::VAB *vbo=db->CreateVAB(VAF_VEC3,mesh->vertex_count,mesh->bitangent); render_obj->Set(bitagent_binding,vbo); } diff --git a/example/Vulkan/OffscreenRender.cpp b/example/Vulkan/OffscreenRender.cpp new file mode 100644 index 00000000..d5a13ac7 --- /dev/null +++ b/example/Vulkan/OffscreenRender.cpp @@ -0,0 +1,210 @@ +#include +#include +#include"VulkanAppFramework.h" + +using namespace hgl; +using namespace hgl::graph; + +constexpr uint OFFSCREEN_SIZE =256; +constexpr uint SCREEN_WIDTH =1024; +constexpr uint SCREEN_HEIGHT =(SCREEN_WIDTH/16)*9; + +class TestApp:public CameraAppFramework +{ + struct RenderObject + { + Camera cam; + + MaterialInstance * material_instance =nullptr; + GPUBuffer * ubo_camera_info =nullptr; + }; + + struct:public RenderObject + { + RenderTarget * render_taget =nullptr; + RenderCmdBuffer * command_buffer =nullptr; + + Pipeline * pipeline =nullptr; + RenderableInstance *renderable_instance =nullptr; + + public: + + bool Submit() + { + if(!render_taget->Submit(command_buffer)) + return(false); + if(!render_taget->WaitQueue()) + return(false); + + return(true); + } + }os; + + struct:public RenderObject + { + Sampler * sampler =nullptr; + + Pipeline * pipeline =nullptr; + RenderableInstance *renderable_instance =nullptr; + + SceneNode scene_root; + RenderList * render_list =nullptr; + }cube; + +public: + + ~TestApp() + { + SAFE_CLEAR(cube.render_list); + SAFE_CLEAR(os.render_taget); + } + + bool InitUBO(RenderObject *ro,const VkExtent2D &extent) + { + ro->cam.width=extent.width; + ro->cam.height=extent.height; + + ro->cam.Refresh(); + + ro->ubo_camera_info=db->CreateUBO(sizeof(CameraInfo),&ro->cam.info); + + if(!ro->ubo_camera_info) + return(false); + + { + MaterialParameters *mp_global=ro->material_instance->GetMP(DescriptorSetsType::Global); + + if(!mp_global) + return(false); + + if(!mp_global->BindUBO("g_camera",ro->ubo_camera_info))return(false); + + mp_global->Update(); + } + + return(true); + } + + bool InitOffscreen() + { + FramebufferInfo fbi(UPF_RGBA8,OFFSCREEN_SIZE,OFFSCREEN_SIZE); + + os.render_taget=device->CreateRenderTarget(&fbi); + if(!os.render_taget)return(false); + + os.command_buffer=device->CreateRenderCommandBuffer(); + if(!os.command_buffer)return(false); + + os.material_instance=db->CreateMaterialInstance(OS_TEXT("res/material/VertexColor2D")); + if(!os.material_instance)return(false); + + os.pipeline=os.render_taget->GetRenderPass()->CreatePipeline(os.material_instance,InlinePipeline::Solid2D,Prim::Fan); + if(!os.pipeline)return(false); + + if(!InitUBO(&os,os.render_taget->GetExtent())) + return(false); + + { + CircleCreateInfo cci; + + cci.center=Vector2f(OFFSCREEN_SIZE*0.5,OFFSCREEN_SIZE*0.5); + cci.radius=Vector2f(OFFSCREEN_SIZE*0.45,OFFSCREEN_SIZE*0.45); + cci.field_count=32; + cci.has_color=true; + cci.center_color=Vector4f(1,1,1,1); + cci.border_color=Vector4f(1,1,1,0); + + Renderable *render_obj=CreateRenderableCircle(db,os.material_instance->GetVAB(),&cci); + if(!render_obj)return(false); + + os.renderable_instance=db->CreateRenderableInstance(render_obj,os.material_instance,os.pipeline); + + if(!os.renderable_instance)return(false); + } + + VulkanApplicationFramework::BuildCommandBuffer(os.command_buffer,os.render_taget,os.renderable_instance); + + os.Submit(); + + return(true); + } + + bool InitCube() + { + cube.render_list=new RenderList(device); + + cube.material_instance=db->CreateMaterialInstance(OS_TEXT("res/material/TextureMask3D")); + if(!cube.material_instance)return(false); + + cube.pipeline=CreatePipeline(cube.material_instance,InlinePipeline::Solid3D,Prim::Triangles); + if(!cube.pipeline)return(false); + + cube.sampler=db->CreateSampler(); + if(!cube.sampler)return(false); + + { + MaterialParameters *mp_texture=cube.material_instance->GetMP(DescriptorSetsType::Value); + + if(!mp_texture) + return(false); + + if(!mp_texture->BindSampler("tex",os.render_taget->GetColorTexture(),cube.sampler))return(false); + + mp_texture->Update(); + } + + { + CubeCreateInfo cci; + + Renderable *render_obj=CreateRenderableCube(db,cube.material_instance->GetVAB(),&cci); + if(!render_obj)return(false); + + cube.renderable_instance=db->CreateRenderableInstance(render_obj,cube.material_instance,cube.pipeline); + + cube.scene_root.CreateSubNode(cube.renderable_instance); + } + + camera->pos=Vector4f(5,5,5,1.0); + + cube.scene_root.RefreshMatrix(); + cube.render_list->Expend(GetCameraInfo(),&cube.scene_root); + + return(true); + } + + bool Init() + { + if(!CameraAppFramework::Init(SCREEN_WIDTH,SCREEN_HEIGHT)) + return(false); + + SetClearColor(COLOR::MozillaCharcoal); + + if(!InitOffscreen()) + return(false); + + if(!InitCube()) + return(false); + + return(true); + } + + void BuildCommandBuffer(uint32 index) + { + cube.scene_root.RefreshMatrix(); + cube.render_list->Expend(GetCameraInfo(),&cube.scene_root); + + VulkanApplicationFramework::BuildCommandBuffer(index,cube.render_list); + } +};//class TestApp:public CameraAppFramework + +int main(int,char **) +{ + TestApp app; + + if(!app.Init()) + return(-1); + + while(app.Run()); + + return 0; +} diff --git a/example/Vulkan/RayPicking.cpp b/example/Vulkan/RayPicking.cpp new file mode 100644 index 00000000..17391420 --- /dev/null +++ b/example/Vulkan/RayPicking.cpp @@ -0,0 +1,189 @@ +// 18.RayPicking + +#include"VulkanAppFramework.h" +#include +#include +#include +#include +#include +#include +#include + +using namespace hgl; +using namespace hgl::graph; + +constexpr uint32_t SCREEN_WIDTH=1280; +constexpr uint32_t SCREEN_HEIGHT=720; + +static float position_data[2][3]= +{ + {100,100,100}, + {0,0,0} +}; + +static float color_data[2][4]= +{ + {1,1,0,1}, + {1,1,0,1} +}; + +class TestApp:public CameraAppFramework +{ + Color4f color; + + GPUBuffer *ubo_color=nullptr; + +private: + + SceneNode render_root; + RenderList * render_list =nullptr; + + Material * material =nullptr; + MaterialInstance * material_instance =nullptr; + Pipeline * pipeline =nullptr; + + Renderable * ro_plane_grid =nullptr; + + Renderable * ro_line =nullptr; + + VBO * vbo_pos =nullptr; + + Ray ray; + +private: + + bool InitMDP() + { + material=db->CreateMaterial(OS_TEXT("res/material/VertexColor3D")); + if(!material)return(false); + + material_instance=db->CreateMaterialInstance(material); + if(!material_instance)return(false); + + pipeline=CreatePipeline(material_instance,InlinePipeline::Solid3D,Prim::Lines); + if(!pipeline) + return(false); + + return(true); + } + + RenderableInstance *Add(Renderable *r,const Matrix4f &mat) + { + RenderableInstance *ri=db->CreateRenderableInstance(r,material_instance,pipeline); + + render_root.CreateSubNode(mat,ri); + + return ri; + } + + bool CreateRenderObject() + { + { + struct PlaneGridCreateInfo pgci; + + pgci.coord[0]=Vector3f(-100,-100,0); + pgci.coord[1]=Vector3f( 100,-100,0); + pgci.coord[2]=Vector3f( 100, 100,0); + pgci.coord[3]=Vector3f(-100, 100,0); + + pgci.step.x=32; + pgci.step.y=32; + + pgci.side_step.x=8; + pgci.side_step.y=8; + + pgci.color.Set(0.25,0,0,1); + pgci.side_color.Set(1,0,0,1); + + const VAB *vab=material_instance->GetVAB(); + + ro_plane_grid=CreateRenderablePlaneGrid(db,vab,&pgci); + } + + { + ro_line=db->CreateRenderable(2); + if(!ro_line)return(false); + + if(!ro_line->Set(VAN::Position, vbo_pos=db->CreateVBO(VF_V3F,2,position_data)))return(false); + if(!ro_line->Set(VAN::Color, db->CreateVBO(VF_V4F,2,color_data)))return(false); + } + + return(true); + } + + bool InitScene() + { + Add(ro_plane_grid,Matrix4f(1.0f)); + Add(ro_line,Matrix4f(1.0f)); + + camera->pos=Vector3f(100,100,50); + camera_control->SetTarget(Vector3f(0,0,0)); + camera_control->Refresh(); + + render_root.RefreshMatrix(); + render_list->Expend(camera->info,&render_root); + + return(true); + } + +public: + + ~TestApp() + { + SAFE_CLEAR(render_list); + } + + bool Init() + { + if(!CameraAppFramework::Init(SCREEN_WIDTH,SCREEN_HEIGHT)) + return(false); + + render_list=new RenderList(device); + + if(!InitMDP()) + return(false); + + if(!CreateRenderObject()) + return(false); + + if(!InitScene()) + return(false); + + return(true); + } + + void BuildCommandBuffer(uint32 index) + { + const CameraInfo &ci=GetCameraInfo(); + + ray.Set(GetMouseCoord(),&ci); //设置射线查询的屏幕坐标点 + + const Vector3f pos=ray.ClosestPoint(Vector3f(0,0,0)); //求射线上与点(0,0,0)最近的点的坐标 + + vbo_pos->Write(&pos,3*sizeof(float)); //更新VBO上这个点的位置 + + render_root.RefreshMatrix(); + render_list->Expend(ci,&render_root); + + VulkanApplicationFramework::BuildCommandBuffer(index,render_list); + } + + void Resize(int w,int h)override + { + CameraAppFramework::Resize(w,h); + + VulkanApplicationFramework::BuildCommandBuffer(render_list); + } +};//class TestApp:public CameraAppFramework + +int main(int,char **) +{ + TestApp app; + + if(!app.Init()) + return(-1); + + while(app.Run()); + + return 0; +} diff --git a/example/Vulkan/RectanglePrimitive.cpp b/example/Vulkan/RectanglePrimitive.cpp index 4081a421..388ccd2e 100644 --- a/example/Vulkan/RectanglePrimitive.cpp +++ b/example/Vulkan/RectanglePrimitive.cpp @@ -2,15 +2,15 @@ // 该示例是texture_rect的进化,演示使用GeometryShader画矩形 #include"VulkanAppFramework.h" -#include -#include +#include +#include #include using namespace hgl; using namespace hgl::graph; VK_NAMESPACE_BEGIN -Texture2D *CreateTextureFromFile(Device *device,const OSString &filename); +Texture2D *CreateTexture2DFromFile(GPUDevice *device,const OSString &filename); VK_NAMESPACE_END constexpr uint32_t SCREEN_SIZE=512; @@ -36,40 +36,52 @@ class TestApp:public VulkanApplicationFramework private: - vulkan::Material * material =nullptr; - vulkan::Texture2D * texture =nullptr; - vulkan::Sampler * sampler =nullptr; - vulkan::MaterialInstance * material_instance =nullptr; - vulkan::Renderable * render_obj =nullptr; - vulkan::Buffer * ubo_world_matrix =nullptr; + Texture2D * texture =nullptr; + Sampler * sampler =nullptr; + MaterialInstance * material_instance =nullptr; + Renderable * render_obj =nullptr; + RenderableInstance *render_instance =nullptr; + GPUBuffer * ubo_camera_info =nullptr; - vulkan::Pipeline * pipeline =nullptr; - - vulkan::VAB *vertex_buffer =nullptr; - vulkan::VAB *tex_coord_buffer =nullptr; + Pipeline * pipeline =nullptr; private: bool InitMaterial() { - material=shader_manage->CreateMaterial( OS_TEXT("res/shader/DrawRect2D.vert"), - OS_TEXT("res/shader/DrawRect2D.geom"), - OS_TEXT("res/shader/FlatTexture.frag")); - if(!material) - return(false); + material_instance=db->CreateMaterialInstance(OS_TEXT("res/material/TextureRect2D")); + if(!material_instance)return(false); - render_obj=db->CreateRenderable(material,VERTEX_COUNT); - material_instance=db->CreateMaterialInstance(material); + pipeline=CreatePipeline(material_instance,InlinePipeline::Solid2D,Prim::SolidRectangles); + if(!pipeline)return(false); - texture=vulkan::CreateTextureFromFile(device,OS_TEXT("res/image/lena.Tex2D")); + texture=db->LoadTexture2D(OS_TEXT("res/image/lena.Tex2D")); + if(!texture)return(false); sampler=db->CreateSampler(); - material_instance->BindSampler("tex",texture,sampler); - material_instance->BindUBO("world",ubo_world_matrix); - material_instance->Update(); + { + MaterialParameters *mp_global=material_instance->GetMP(DescriptorSetsType::Global); + + if(!mp_global) + return(false); + + if(!mp_global->BindUBO("g_camera",ubo_camera_info))return(false); + + mp_global->Update(); + } + + { + MaterialParameters *mp_texture=material_instance->GetMP(DescriptorSetsType::Value); + + if(!mp_texture) + return(false); + + if(!mp_texture->BindSampler("tex",texture,sampler))return(false); + + mp_texture->Update(); + } - db->Add(material); db->Add(texture); return(true); } @@ -83,34 +95,26 @@ private: cam.Refresh(); - ubo_world_matrix=db->CreateUBO(sizeof(WorldMatrix),&cam.matrix); + ubo_camera_info=db->CreateUBO(sizeof(CameraInfo),&cam.info); - if(!ubo_world_matrix) + if(!ubo_camera_info) return(false); return(true); } - void InitVBO() - { - vertex_buffer =db->CreateVAB(FMT_RGBA32F,VERTEX_COUNT,vertex_data); - tex_coord_buffer=db->CreateVAB(FMT_RGBA32F,VERTEX_COUNT,tex_coord_data); + bool InitVBO() + { + render_obj=db->CreateRenderable(VERTEX_COUNT); - render_obj->Set("Vertex",vertex_buffer); - render_obj->Set("TexCoord",tex_coord_buffer); - } + if(!render_obj)return(false); - bool InitPipeline() - { - AutoDelete - pipeline_creater=new vulkan::PipelineCreater(device,material,sc_render_target); - pipeline_creater->CloseCullFace(); - pipeline_creater->Set(Prim::Rectangles); + render_obj->Set(VAN::Position,db->CreateVBO(VF_V4F,VERTEX_COUNT,vertex_data)); + render_obj->Set(VAN::TexCoord,db->CreateVBO(VF_V4F,VERTEX_COUNT,tex_coord_data)); + + render_instance=db->CreateRenderableInstance(render_obj,material_instance,pipeline); - pipeline=pipeline_creater->Create(); - - db->Add(pipeline); - return pipeline; + return(render_instance); } public: @@ -126,12 +130,10 @@ public: if(!InitMaterial()) return(false); - InitVBO(); - - if(!InitPipeline()) + if(!InitVBO()) return(false); - BuildCommandBuffer(pipeline,material_instance,render_obj); + BuildCommandBuffer(render_instance); return(true); } @@ -143,9 +145,9 @@ public: cam.Refresh(); - ubo_world_matrix->Write(&cam.matrix); - - BuildCommandBuffer(pipeline,material_instance,render_obj); + ubo_camera_info->Write(&cam.info); + + BuildCommandBuffer(render_instance); } };//class TestApp:public VulkanApplicationFramework diff --git a/example/Vulkan/TextureFormat.cpp b/example/Vulkan/TextureFormat.cpp index 4b5f4d19..c437c9de 100644 --- a/example/Vulkan/TextureFormat.cpp +++ b/example/Vulkan/TextureFormat.cpp @@ -1,7 +1,7 @@ #include -#include -#include -#include +#include +#include +#include using namespace hgl; using namespace hgl::graph; @@ -35,7 +35,7 @@ constexpr char *data_type_name[] "SRGB" };// -vulkan::Instance *InitVulkanInstance() +VulkanInstance *InitVulkanInstance() { #ifdef _DEBUG if(!CheckStrideBytesByFormat()) @@ -47,7 +47,7 @@ vulkan::Instance *InitVulkanInstance() InitNativeWindowSystem(); - InitVulkanProperties(); + //InitVulkanProperties(); CreateInstanceLayerInfo cili; @@ -56,15 +56,15 @@ vulkan::Instance *InitVulkanInstance() cili.lunarg.standard_validation=true; cili.khronos.validation=true; - return vulkan::CreateInstance("VulkanTest",nullptr,&cili); + return CreateInstance("VulkanTest",nullptr,&cili); } int main(int,char **) { - Window * win =nullptr; - vulkan::Instance * inst =nullptr; - vulkan::Device * device =nullptr; - const vulkan::PhysicalDevice *physical_device =nullptr; + Window * win =nullptr; + VulkanInstance * inst =nullptr; + GPUDevice * device =nullptr; + const GPUPhysicalDevice * physical_device =nullptr; inst=InitVulkanInstance(); diff --git a/example/Vulkan/VulkanAppFramework.h b/example/Vulkan/VulkanAppFramework.h deleted file mode 100644 index 8f5831e1..00000000 --- a/example/Vulkan/VulkanAppFramework.h +++ /dev/null @@ -1,384 +0,0 @@ -#pragma once -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -using namespace hgl; -using namespace hgl::graph; - -class VulkanApplicationFramework -{ -private: - - Window * win =nullptr; - vulkan::Instance * inst =nullptr; - - void OnKeyDown (KeyboardButton kb){key_status[kb]=true;} - void OnKeyUp (KeyboardButton kb){key_status[kb]=false;} - void OnKeyPress (KeyboardButton kb){KeyPress(kb);} - -protected: - - uint mouse_key=0; - Vector2f mouse_pos; - - void OnMouseDown(int,int,uint mk){mouse_key=mk;MouseDown(mk);} - void OnMouseUp (int,int,uint mk){mouse_key=0;MouseUp(mk);} - void OnMouseMove(int x,int y){mouse_pos.Set(x,y);MouseMove();} - void OnMouseWheel(int v,int h,uint mk){MouseWheel(v,h,mk);} - -protected: - - vulkan::Device * device =nullptr; - vulkan::SwapchainRenderTarget * sc_render_target =nullptr; - - vulkan::Semaphore * present_complete_semaphore =nullptr, - * render_complete_semaphore =nullptr; - - vulkan::ShaderModuleManage * shader_manage =nullptr; - -protected: - - int32_t swap_chain_count =0; - - vulkan::CommandBuffer ** cmd_buf =nullptr; - -protected: - - vulkan::Database * db =nullptr; - - bool key_status[kbRangeSize]; - -public: - - virtual ~VulkanApplicationFramework() - { - SAFE_CLEAR(present_complete_semaphore); - SAFE_CLEAR(render_complete_semaphore); - - SAFE_CLEAR(db); - SAFE_CLEAR_OBJECT_ARRAY(cmd_buf,swap_chain_count); - - SAFE_CLEAR(shader_manage); - SAFE_CLEAR(device); - SAFE_CLEAR(win); - SAFE_CLEAR(inst); - } - - virtual bool Init(int w,int h) - { - hgl_zero(key_status); - - #ifdef _DEBUG - if(!vulkan::CheckStrideBytesByFormat()) - return(false); - #endif// - - InitNativeWindowSystem(); - - VK_NAMESPACE::InitVulkanProperties(); - - win=CreateRenderWindow(OS_TEXT("VulkanTest")); - if(!win) - return(false); - - if(!win->Create(w,h)) - return(false); - - { - VK_NAMESPACE::CreateInstanceLayerInfo cili; - - memset(&cili, 0, sizeof(VK_NAMESPACE::CreateInstanceLayerInfo)); - - cili.lunarg.standard_validation = true; - cili.khronos.validation = true; - cili.RenderDoc.Capture = true; - - inst=vulkan::CreateInstance("VulkanTest",nullptr,&cili); - - if(!inst) - return(false); - } - - device=CreateRenderDevice(inst,win); - - if(!device) - return(false); - - present_complete_semaphore =device->CreateSem(); - render_complete_semaphore =device->CreateSem(); - - shader_manage=device->CreateShaderModuleManage(); - db=new vulkan::Database(device); - - InitCommandBuffer(); - - SetEventCall(win->OnResize, this,VulkanApplicationFramework,OnResize ); - SetEventCall(win->OnKeyDown, this,VulkanApplicationFramework,OnKeyDown ); - SetEventCall(win->OnKeyUp, this,VulkanApplicationFramework,OnKeyUp ); - SetEventCall(win->OnKeyPress, this,VulkanApplicationFramework,OnKeyPress ); - - SetEventCall(win->OnMouseDown, this,VulkanApplicationFramework,OnMouseDown ); - SetEventCall(win->OnMouseUp, this,VulkanApplicationFramework,OnMouseUp ); - SetEventCall(win->OnMouseMove, this,VulkanApplicationFramework,OnMouseMove ); - SetEventCall(win->OnMouseWheel, this,VulkanApplicationFramework,OnMouseWheel); - - return(true); - } - - virtual void Resize(int,int)=0; - virtual void KeyPress(KeyboardButton){} - virtual void MouseDown(uint){} - virtual void MouseUp(uint){} - virtual void MouseMove(){} - virtual void MouseWheel(int,int,uint){} - - void OnResize(int w,int h) - { - if(w>0&&h>0) - device->Resize(w,h); - - InitCommandBuffer(); - Resize(w,h); - } - - void InitCommandBuffer() - { - if(cmd_buf) - SAFE_CLEAR_OBJECT_ARRAY(cmd_buf,swap_chain_count); - - sc_render_target=device->GetSwapchainRT(); - - swap_chain_count=sc_render_target->GetImageCount(); - { - const VkExtent2D extent=sc_render_target->GetExtent(); - - cmd_buf=hgl_zero_new(swap_chain_count); - - for(int32_t i=0;iCreateCommandBuffer(extent,2); - } - } - - void BuildCommandBuffer(uint32_t index,vulkan::Pipeline *p,vulkan::MaterialInstance *mi,vulkan::Renderable *r) - { - if(!p||!mi||!r) - return; - - const vulkan::IndexBuffer *ib=r->GetIndexBuffer(); - - vulkan::CommandBuffer *cb=cmd_buf[index]; - - cb->Begin(); - cb->BeginRenderPass(sc_render_target->GetRenderPass(),sc_render_target->GetFramebuffer(index)); - cb->Bind(p); - cb->Bind(mi->GetDescriptorSets()); - cb->Bind(r); - - if (ib) - cb->DrawIndexed(ib->GetCount()); - else - cb->Draw(r->GetDrawCount()); - - cb->EndRenderPass(); - cb->End(); - } - - void BuildCommandBuffer(vulkan::Pipeline *p,vulkan::MaterialInstance *mi,vulkan::Renderable *r) - { - for(int32_t i=0;iGetCurrentFrameIndices(),p,mi,r); - } - - void BuildCommandBuffer(uint32_t index,RenderList *rl) - { - if(!rl)return; - - vulkan::CommandBuffer *cb=cmd_buf[index]; - - cb->Begin(); - cb->BeginRenderPass(sc_render_target->GetRenderPass(),sc_render_target->GetFramebuffer(index)); - rl->Render(cb); - cb->EndRenderPass(); - cb->End(); - } - - void BuildCommandBuffer(RenderList *rl) - { - for(int32_t i=0;iGetCurrentFrameIndices(),rl); - } - -public: - - int AcquireNextImage() - { - return sc_render_target->AcquireNextImage(present_complete_semaphore); - } - - virtual void SubmitDraw(int index) - { - VkCommandBuffer cb=*cmd_buf[index]; - - sc_render_target->Submit(cb,present_complete_semaphore,render_complete_semaphore); - sc_render_target->PresentBackbuffer(render_complete_semaphore); - sc_render_target->Wait(); - } - - virtual void Draw() - { - int index=AcquireNextImage(); - - if(index<0||index>=swap_chain_count)return; - - SubmitDraw(index); - } - - bool Run() - { - if(!win->Update())return(false); - - if(win->IsVisible()) - Draw(); - - return(true); - } -};//class VulkanApplicationFramework - -class CameraAppFramework:public VulkanApplicationFramework -{ -private: - - vulkan::Buffer * ubo_world_matrix =nullptr; - -protected: - - ControlCamera camera; - float move_speed=1; - - Vector2f mouse_last_pos; - -public: - - virtual ~CameraAppFramework()=default; - - virtual bool Init(int w,int h) - { - if(!VulkanApplicationFramework::Init(w,h)) - return(false); - - InitCamera(w,h); - return(true); - } - - virtual void InitCamera(int w,int h) - { - camera.type=CameraType::Perspective; - camera.width=w; - camera.height=h; - camera.vp_width=w; - camera.vp_height=h; - camera.center.Set(0,0,0,1); - camera.eye.Set(10,10,10,1); //xyz三个值不要一样,以方便调试 - - camera.Refresh(); //更新矩阵计算 - - ubo_world_matrix=db->CreateUBO(sizeof(WorldMatrix),&camera.matrix); - } - - void Resize(int w,int h)override - { - camera.width=w; - camera.height=h; - } - - vulkan::Buffer *GetCameraMatrixBuffer() - { - return ubo_world_matrix; - } - - virtual void BuildCommandBuffer(uint32_t index)=0; - - virtual void Draw()override - { - camera.Refresh(); //更新相机矩阵 - ubo_world_matrix->Write(&camera.matrix); //写入缓冲区 - - const uint32_t index=AcquireNextImage(); - - BuildCommandBuffer(index); - - SubmitDraw(index); - - if(key_status[kbW])camera.Forward (move_speed);else - if(key_status[kbS])camera.Backward (move_speed);else - if(key_status[kbA])camera.Left (move_speed);else - if(key_status[kbD])camera.Right (move_speed);else - if(key_status[kbR])camera.Up (move_speed);else - if(key_status[kbF])camera.Down (move_speed);else - - if(key_status[kbLeft ])camera.WrapHorzRotate( move_speed);else - if(key_status[kbRight ])camera.WrapHorzRotate(-move_speed);else - if(key_status[kbUp ])camera.WrapVertRotate( move_speed);else - if(key_status[kbDown ])camera.WrapVertRotate(-move_speed);else - return; - } - - virtual void KeyPress(KeyboardButton kb)override - { - if(kb==kbMinus)move_speed*=0.9f;else - if(kb==kbEquals)move_speed*=1.1f;else - return; - } - - virtual void MouseDown(uint) override - { - mouse_last_pos=mouse_pos; - } - - virtual void MouseMove() override - { - if(!(mouse_key&(mbLeft|mbRight)))return; - - Vector2f gap=mouse_pos-mouse_last_pos; - - bool update=false; - if(gap.x!=0){update=true;if(mouse_key&mbLeft)camera.HorzRotate(-gap.x/10.0f);else camera.WrapHorzRotate(gap.x);} - if(gap.y!=0){update=true;if(mouse_key&mbLeft)camera.VertRotate(-gap.y/10.0f);else camera.WrapVertRotate(gap.y);} - - mouse_last_pos=mouse_pos; - } - - virtual void MouseWheel(int v,int h,uint) - { - camera.Distance(1+(v/1000.0f)); - } -};//class CameraAppFramework diff --git a/example/Vulkan/auto_material.cpp b/example/Vulkan/auto_material.cpp deleted file mode 100644 index eefa9751..00000000 --- a/example/Vulkan/auto_material.cpp +++ /dev/null @@ -1,16 +0,0 @@ -#include - -using namespace hgl; -using namespace hgl::graph; -using namespace hgl::graph::shader; - -SHADER_NAMESPACE_BEGIN -bool CreateDefaultMaterial(); -SHADER_NAMESPACE_END - -int main() -{ - CreateDefaultMaterial(); - - return 0; -} diff --git a/example/Vulkan/first_triangle.cpp b/example/Vulkan/first_triangle.cpp index 5fccfe94..7479cc58 100644 --- a/example/Vulkan/first_triangle.cpp +++ b/example/Vulkan/first_triangle.cpp @@ -4,13 +4,11 @@ #include"VulkanAppFramework.h" #include #include +#include using namespace hgl; using namespace hgl::graph; -bool SaveToFile(const OSString &filename,VK_NAMESPACE::PipelineCreater *pc); -bool LoadFromFile(const OSString &filename,VK_NAMESPACE::PipelineCreater *pc); - constexpr uint32_t SCREEN_WIDTH=1280; constexpr uint32_t SCREEN_HEIGHT=720; @@ -23,10 +21,10 @@ constexpr float vertex_data[VERTEX_COUNT][2]= {SCREEN_WIDTH*0.25, SCREEN_HEIGHT*0.75} }; -constexpr float color_data[VERTEX_COUNT][3]= -{ {1,0,0}, - {0,1,0}, - {0,0,1} +constexpr float color_data[VERTEX_COUNT][4]= +{ {1,0,0,1}, + {0,1,0,1}, + {0,0,1,1} }; class TestApp:public VulkanApplicationFramework @@ -35,41 +33,25 @@ private: Camera cam; - vulkan::Material * material =nullptr; - vulkan::MaterialInstance * material_instance =nullptr; - vulkan::Renderable * render_obj =nullptr; - vulkan::Buffer * ubo_world_matrix =nullptr; + MaterialInstance * material_instance =nullptr; + RenderableInstance *render_instance =nullptr; + GPUBuffer * ubo_camera_info =nullptr; - vulkan::Pipeline * pipeline =nullptr; - - vulkan::VAB * vertex_buffer =nullptr; - vulkan::VAB * color_buffer =nullptr; - -public: - - ~TestApp() - { - SAFE_CLEAR(color_buffer); - SAFE_CLEAR(vertex_buffer); - SAFE_CLEAR(pipeline); - SAFE_CLEAR(ubo_world_matrix); - SAFE_CLEAR(render_obj); - SAFE_CLEAR(material_instance); - SAFE_CLEAR(material); - } + Pipeline * pipeline =nullptr; private: bool InitMaterial() { - material=shader_manage->CreateMaterial(OS_TEXT("res/shader/FlatColor.vert"), - OS_TEXT("res/shader/VertexColor.frag")); - if(!material) - return(false); + material_instance=db->CreateMaterialInstance(OS_TEXT("res/material/VertexColor2D")); - render_obj=material->CreateRenderable(VERTEX_COUNT); - material_instance=material->CreateInstance(); - return(true); + if(!material_instance) + return(false); + +// pipeline=db->CreatePipeline(material_instance,sc_render_target,OS_TEXT("res/pipeline/solid2d")); + pipeline=CreatePipeline(material_instance,InlinePipeline::Solid2D,Prim::Triangles); //等同上一行,为Framework重载,默认使用swapchain的render target + + return pipeline; } bool InitUBO() @@ -79,54 +61,37 @@ private: cam.width=extent.width; cam.height=extent.height; - cam.Refresh(); + cam.RefreshCameraInfo(); - ubo_world_matrix=device->CreateUBO(sizeof(WorldMatrix),&cam.matrix); + ubo_camera_info=db->CreateUBO(sizeof(CameraInfo),&cam.info); - if(!ubo_world_matrix) + if(!ubo_camera_info) return(false); - - material_instance->BindUBO("world",ubo_world_matrix); - material_instance->Update(); + + { + MaterialParameters *mp_global=material_instance->GetMP(DescriptorSetsType::Global); + + if(!mp_global) + return(false); + + mp_global->BindUBO("g_camera",ubo_camera_info); + mp_global->Update(); + } return(true); } bool InitVBO() { - vertex_buffer =device->CreateVAB(FMT_RG32F, VERTEX_COUNT,vertex_data); - color_buffer =device->CreateVAB(FMT_RGB32F, VERTEX_COUNT,color_data); - - if(!render_obj->Set("Vertex", vertex_buffer))return(false); - if(!render_obj->Set("Color", color_buffer))return(false); + Renderable *render_obj=db->CreateRenderable(VERTEX_COUNT); + if(!render_obj)return(false); + if(!render_obj->Set(VAN::Position, db->CreateVBO(VF_V2F,VERTEX_COUNT,vertex_data)))return(false); + if(!render_obj->Set(VAN::Color, db->CreateVBO(VF_V4F,VERTEX_COUNT,color_data)))return(false); + + render_instance=db->CreateRenderableInstance(render_obj,material_instance,pipeline); return(true); } - bool InitPipeline() - { - constexpr os_char PIPELINE_FILENAME[]=OS_TEXT("2DSolid.pipeline"); - - { - AutoDelete - pipeline_creater=new vulkan::PipelineCreater(device,material,sc_render_target); - pipeline_creater->CloseCullFace(); - pipeline_creater->Set(Prim::Triangles); - - SaveToFile(PIPELINE_FILENAME,pipeline_creater); - } - - { - void *data; - uint size=filesystem::LoadFileToMemory(PIPELINE_FILENAME,(void **)&data); - - AutoDelete pipeline_creater=new vulkan::PipelineCreater(device,material,sc_render_target,(uchar *)data,size); - - pipeline=pipeline_creater->Create(); - } - - return pipeline; - } - public: bool Init() @@ -143,11 +108,9 @@ public: if(!InitVBO()) return(false); - if(!InitPipeline()) + if(!BuildCommandBuffer(render_instance)) return(false); - BuildCommandBuffer(pipeline,material_instance,render_obj); - return(true); } @@ -156,11 +119,11 @@ public: cam.width=w; cam.height=h; - cam.Refresh(); + cam.RefreshCameraInfo(); - ubo_world_matrix->Write(&cam.matrix); + ubo_camera_info->Write(&cam.info); - BuildCommandBuffer(pipeline,material_instance,render_obj); + BuildCommandBuffer(render_instance); } };//class TestApp:public VulkanApplicationFramework diff --git a/example/Vulkan/indices_rect.cpp b/example/Vulkan/indices_rect.cpp index d9f267b9..a7ca4b92 100644 --- a/example/Vulkan/indices_rect.cpp +++ b/example/Vulkan/indices_rect.cpp @@ -7,22 +7,19 @@ using namespace hgl; using namespace hgl::graph; -constexpr uint32_t SCREEN_WIDTH=128; -constexpr uint32_t SCREEN_HEIGHT=128; +constexpr uint32_t SCREEN_WIDTH=256; +constexpr uint32_t SCREEN_HEIGHT=256; constexpr uint32_t VERTEX_COUNT=4; static Vector4f color(1,1,1,1); -constexpr float SSP=0.25; -constexpr float SSN=1-SSP; - constexpr float vertex_data[VERTEX_COUNT][2]= { - {SCREEN_WIDTH*SSP, SCREEN_HEIGHT*SSP}, - {SCREEN_WIDTH*SSN, SCREEN_HEIGHT*SSP}, - {SCREEN_WIDTH*SSP, SCREEN_HEIGHT*SSN}, - {SCREEN_WIDTH*SSN, SCREEN_HEIGHT*SSN} + {0,0}, + {SCREEN_WIDTH,0}, + {0,SCREEN_HEIGHT}, + {SCREEN_WIDTH,SCREEN_HEIGHT} }; constexpr uint32_t INDEX_COUNT=6; @@ -37,85 +34,65 @@ class TestApp:public VulkanApplicationFramework { private: - WorldMatrix wm; + Camera cam; - vulkan::Material * material =nullptr; - vulkan::MaterialInstance * material_instance =nullptr; - vulkan::Renderable * render_obj =nullptr; - vulkan::Buffer * ubo_world_matrix =nullptr; - vulkan::Buffer * ubo_color_material =nullptr; + MaterialInstance * material_instance =nullptr; + RenderableInstance *renderable_instance =nullptr; + GPUBuffer * ubo_camera_info =nullptr; - vulkan::Pipeline * pipeline =nullptr; - - vulkan::VAB *vertex_buffer =nullptr; - vulkan::IndexBuffer * index_buffer =nullptr; - -public: - - ~TestApp() - { - SAFE_CLEAR(index_buffer); - SAFE_CLEAR(vertex_buffer); - SAFE_CLEAR(pipeline); - SAFE_CLEAR(ubo_color_material); - SAFE_CLEAR(ubo_world_matrix); - SAFE_CLEAR(render_obj); - SAFE_CLEAR(material_instance); - SAFE_CLEAR(material); - } + Pipeline * pipeline =nullptr; private: bool InitMaterial() { - material=shader_manage->CreateMaterial(OS_TEXT("res/shader/OnlyPosition.vert"), - OS_TEXT("res/shader/HexGrid.frag")); - if(!material) - return(false); - - render_obj=material->CreateRenderable(VERTEX_COUNT); - material_instance=material->CreateInstance(); - return(true); + material_instance=db->CreateMaterialInstance(OS_TEXT("res/material/FragColor")); + if(!material_instance)return(false); + + // pipeline=db->CreatePipeline(material_instance,sc_render_target,OS_TEXT("res/pipeline/solid2d")); + pipeline=CreatePipeline(material_instance,InlinePipeline::Solid2D,Prim::Triangles); //等同上一行,为Framework重载,默认使用swapchain的render target + + return pipeline; } - + bool InitUBO() { const VkExtent2D extent=sc_render_target->GetExtent(); - wm.ortho=ortho(extent.width,extent.height); - wm.canvas_resolution.x=extent.width; - wm.canvas_resolution.y=extent.height; + cam.vp_width=cam.width=extent.width; + cam.vp_height=cam.height=extent.height; - ubo_world_matrix =device->CreateUBO(sizeof(WorldMatrix),&wm); - ubo_color_material =device->CreateUBO(sizeof(Vector4f),&color); + cam.Refresh(); - material_instance->BindUBO("world",ubo_world_matrix); - material_instance->BindUBO("fs_world",ubo_world_matrix); - material_instance->BindUBO("color_material",ubo_color_material); + ubo_camera_info=db->CreateUBO(sizeof(CameraInfo),&cam.info); + + if(!ubo_camera_info) + return(false); + + { + MaterialParameters *mp_global=material_instance->GetMP(DescriptorSetsType::Global); - material_instance->Update(); + if(!mp_global) + return(false); + + if(!mp_global->BindUBO("g_camera",ubo_camera_info))return(false); + + mp_global->Update(); + } return(true); } - void InitVBO() - { - vertex_buffer =device->CreateVAB(FMT_RG32F,VERTEX_COUNT,vertex_data); - index_buffer =device->CreateIBO16(INDEX_COUNT,index_data); + bool InitVBO() + { + auto render_obj=db->CreateRenderable(VERTEX_COUNT); + if(!render_obj)return(false); - render_obj->Set("Vertex",vertex_buffer); - render_obj->Set(index_buffer); - } + if(!render_obj->Set(VAN::Position,db->CreateVBO(VF_V2F,VERTEX_COUNT,vertex_data)))return(false); + if(!render_obj->Set(db->CreateIBO16(INDEX_COUNT,index_data)))return(false); - bool InitPipeline() - { - AutoDelete - pipeline_creater=new vulkan::PipelineCreater(device,material,sc_render_target); - pipeline_creater->CloseCullFace(); - pipeline_creater->Set(Prim::Triangles); + renderable_instance=db->CreateRenderableInstance(render_obj,material_instance,pipeline); - pipeline=pipeline_creater->Create(); - - return pipeline; + return(true); } public: @@ -131,26 +108,31 @@ public: if(!InitUBO()) return(false); - InitVBO(); - - if(!InitPipeline()) + if(!InitVBO()) return(false); - BuildCommandBuffer(pipeline,material_instance,render_obj); + BuildCommandBuffer(renderable_instance); return(true); } - void Resize(int,int)override + void Resize(int w,int h)override { - BuildCommandBuffer(pipeline,material_instance,render_obj); + cam.vp_width=w; + cam.vp_height=h; + + cam.Refresh(); + + ubo_camera_info->Write(&cam.info); + + BuildCommandBuffer(renderable_instance); } };//class TestApp:public VulkanApplicationFramework int main(int,char **) { #ifdef _DEBUG - if(!vulkan::CheckStrideBytesByFormat()) + if(!CheckStrideBytesByFormat()) return 0xff; #endif// diff --git a/example/Vulkan/texture_rect.cpp b/example/Vulkan/texture_rect.cpp index d4a8cf34..bc0067de 100644 --- a/example/Vulkan/texture_rect.cpp +++ b/example/Vulkan/texture_rect.cpp @@ -2,19 +2,20 @@ // 该示例是1.indices_rect的进化,演示在矩形上贴上贴图 #include"VulkanAppFramework.h" -#include -#include +#include +#include +#include #include using namespace hgl; using namespace hgl::graph; VK_NAMESPACE_BEGIN -Texture2D *CreateTextureFromFile(Device *device,const OSString &filename); +Texture2D *CreateTexture2DFromFile(GPUDevice *device,const OSString &filename); VK_NAMESPACE_END -constexpr uint32_t SCREEN_WIDTH=128; -constexpr uint32_t SCREEN_HEIGHT=128; +constexpr uint32_t SCREEN_WIDTH=256; +constexpr uint32_t SCREEN_HEIGHT=256; constexpr uint32_t VERTEX_COUNT=4; @@ -48,54 +49,41 @@ class TestApp:public VulkanApplicationFramework private: - vulkan::Material * material =nullptr; - vulkan::Texture2D * texture =nullptr; - vulkan::Sampler * sampler =nullptr; - vulkan::MaterialInstance * material_instance =nullptr; - vulkan::Renderable * render_obj =nullptr; - vulkan::Buffer * ubo_world_matrix =nullptr; - - vulkan::Pipeline * pipeline =nullptr; - - vulkan::VAB * vertex_buffer =nullptr; - vulkan::VAB * tex_coord_buffer =nullptr; - vulkan::IndexBuffer * index_buffer =nullptr; - -public: - - ~TestApp() - { - SAFE_CLEAR(index_buffer); - SAFE_CLEAR(tex_coord_buffer); - SAFE_CLEAR(vertex_buffer); - SAFE_CLEAR(pipeline); - SAFE_CLEAR(ubo_world_matrix); - SAFE_CLEAR(render_obj); - SAFE_CLEAR(material_instance); - SAFE_CLEAR(sampler); - SAFE_CLEAR(texture); - SAFE_CLEAR(material); - } + Texture2D * texture =nullptr; + Sampler * sampler =nullptr; + MaterialInstance * material_instance =nullptr; + RenderableInstance *renderable_instance =nullptr; + GPUBuffer * ubo_camera_info =nullptr; + Pipeline * pipeline =nullptr; private: bool InitMaterial() { - material=shader_manage->CreateMaterial(OS_TEXT("res/shader/FlatTexture.vert"), - OS_TEXT("res/shader/FlatTexture.frag")); - if(!material) + material_instance=db->CreateMaterialInstance(OS_TEXT("res/material/Texture2D")); + if(!material_instance)return(false); + +// pipeline=db->CreatePipeline(material_instance,sc_render_target,OS_TEXT("res/pipeline/solid2d")); + pipeline=CreatePipeline(material_instance,InlinePipeline::Solid2D,Prim::Triangles); //等同上一行,为Framework重载,默认使用swapchain的render target + + if(!pipeline) return(false); - render_obj=material->CreateRenderable(VERTEX_COUNT); - material_instance=material->CreateInstance(); + texture=db->LoadTexture2D(OS_TEXT("res/image/lena.Tex2D"),true); + if(!texture)return(false); - texture=vulkan::CreateTextureFromFile(device,OS_TEXT("res/image/lena.Tex2D")); + sampler=db->CreateSampler(); - sampler=device->CreateSampler(); + { + MaterialParameters *mp_texture=material_instance->GetMP(DescriptorSetsType::Value); + + if(!mp_texture) + return(false); + + if(!mp_texture->BindSampler("tex",texture,sampler))return(false); - material_instance->BindSampler("tex",texture,sampler); - material_instance->BindUBO("world",ubo_world_matrix); - material_instance->Update(); + mp_texture->Update(); + } return(true); } @@ -104,40 +92,42 @@ private: { const VkExtent2D extent=sc_render_target->GetExtent(); - cam.width=extent.width; - cam.height=extent.height; + cam.vp_width =cam.width =extent.width; + cam.vp_height=cam.height=extent.height; cam.Refresh(); - ubo_world_matrix=device->CreateUBO(sizeof(WorldMatrix),&cam.matrix); + ubo_camera_info=db->CreateUBO(sizeof(CameraInfo),&cam.info); - if(!ubo_world_matrix) + if(!ubo_camera_info) return(false); + + { + MaterialParameters *mp_global=material_instance->GetMP(DescriptorSetsType::Global); + + if(!mp_global) + return(false); + + if(!mp_global->BindUBO("g_camera",ubo_camera_info))return(false); + + mp_global->Update(); + } return(true); } - void InitVBO() + bool InitVBO() { - vertex_buffer =device->CreateVAB(FMT_RG32F,VERTEX_COUNT,vertex_data); - tex_coord_buffer=device->CreateVAB(FMT_RG32F,VERTEX_COUNT,tex_coord_data); - index_buffer =device->CreateIBO16(INDEX_COUNT,index_data); + auto render_obj=db->CreateRenderable(VERTEX_COUNT); + if(!render_obj)return(false); - render_obj->Set("Vertex",vertex_buffer); - render_obj->Set("TexCoord",tex_coord_buffer); - render_obj->Set(index_buffer); - } + if(!render_obj->Set(VAN::Position,db->CreateVBO(VF_V2F,VERTEX_COUNT,vertex_data)))return(false); + if(!render_obj->Set(VAN::TexCoord,db->CreateVBO(VF_V2F,VERTEX_COUNT,tex_coord_data)))return(false); + if(!render_obj->Set(db->CreateIBO16(INDEX_COUNT,index_data)))return(false); - bool InitPipeline() - { - AutoDelete - pipeline_creater=new vulkan::PipelineCreater(device,material,sc_render_target); - pipeline_creater->CloseCullFace(); - pipeline_creater->Set(Prim::Triangles); + renderable_instance=db->CreateRenderableInstance(render_obj,material_instance,pipeline); - pipeline=pipeline_creater->Create(); - - return pipeline; + return(true); } public: @@ -146,19 +136,17 @@ public: { if(!VulkanApplicationFramework::Init(SCREEN_WIDTH,SCREEN_HEIGHT)) return(false); + + if(!InitMaterial()) + return(false); if(!InitUBO()) return(false); - if(!InitMaterial()) - return(false); - - InitVBO(); - - if(!InitPipeline()) + if(!InitVBO()) return(false); - BuildCommandBuffer(pipeline,material_instance,render_obj); + BuildCommandBuffer(renderable_instance); return(true); } @@ -170,16 +158,16 @@ public: cam.Refresh(); - ubo_world_matrix->Write(&cam.matrix); - - BuildCommandBuffer(pipeline,material_instance,render_obj); + ubo_camera_info->Write(&cam.info); + + BuildCommandBuffer(renderable_instance); } };//class TestApp:public VulkanApplicationFramework int main(int,char **) { #ifdef _DEBUG - if(!vulkan::CheckStrideBytesByFormat()) + if(!CheckStrideBytesByFormat()) return 0xff; #endif// diff --git a/example/Vulkan/two_triangle.cpp b/example/Vulkan/two_triangle.cpp new file mode 100644 index 00000000..67e5b55f --- /dev/null +++ b/example/Vulkan/two_triangle.cpp @@ -0,0 +1,155 @@ +// 1.two_triangle +// 该范例主要演示使用CmdBindDescriptorSets偏移UBO绘图 + +#include"VulkanAppFramework.h" +#include +#include + +using namespace hgl; +using namespace hgl::graph; + +constexpr uint32_t SCREEN_WIDTH=1280; +constexpr uint32_t SCREEN_HEIGHT=720; + +constexpr uint32_t VERTEX_COUNT=3; + +constexpr float vertex_data[VERTEX_COUNT][2]= +{ + {SCREEN_WIDTH*0.5, SCREEN_HEIGHT*0.25}, + {SCREEN_WIDTH*0.75, SCREEN_HEIGHT*0.75}, + {SCREEN_WIDTH*0.25, SCREEN_HEIGHT*0.75} +}; + +constexpr float color_data[VERTEX_COUNT][4]= +{ {1,0,0,1}, + {0,1,0,1}, + {0,0,1,1} +}; + +class TestApp:public VulkanApplicationFramework +{ +private: + + Camera cam; + + SceneNode render_root; + RenderList * render_list =nullptr; + + MaterialInstance * material_instance =nullptr; + RenderableInstance *render_instance =nullptr; + GPUBuffer * ubo_camera_info =nullptr; + + Pipeline * pipeline =nullptr; + +private: + + bool InitMaterial() + { + material_instance=db->CreateMaterialInstance(OS_TEXT("res/material/VertexColor2D")); + + if(!material_instance) + return(false); + +// pipeline=db->CreatePipeline(material_instance,sc_render_target,OS_TEXT("res/pipeline/solid2d")); + pipeline=CreatePipeline(material_instance,InlinePipeline::Solid2D,Prim::Triangles); //等同上一行,为Framework重载,默认使用swapchain的render target + + return pipeline; + } + + bool InitUBO() + { + const VkExtent2D extent=sc_render_target->GetExtent(); + + cam.width=extent.width; + cam.height=extent.height; + + cam.Refresh(); + + ubo_camera_info=db->CreateUBO(sizeof(CameraInfo),&cam.info); + + if(!ubo_camera_info) + return(false); + + { + MaterialParameters *mp_global=material_instance->GetMP(DescriptorSetsType::Global); + + if(!mp_global) + return(false); + + mp_global->BindUBO("g_camera",ubo_camera_info); + mp_global->Update(); + } + return(true); + } + + bool InitVBO() + { + Renderable *render_obj=db->CreateRenderable(VERTEX_COUNT); + if(!render_obj)return(false); + + if(!render_obj->Set(VAN::Position, db->CreateVBO(VF_V2F,VERTEX_COUNT,vertex_data)))return(false); + if(!render_obj->Set(VAN::Color, db->CreateVBO(VF_V4F,VERTEX_COUNT,color_data)))return(false); + + render_instance=db->CreateRenderableInstance(render_obj,material_instance,pipeline); + + render_root.CreateSubNode(scale(0.5,0.5),render_instance); + + render_root.RefreshMatrix(); + + render_list->Expend(cam.info,&render_root); + + return(true); + } + +public: + + ~TestApp() + { + SAFE_CLEAR(render_list); + } + + bool Init() + { + if(!VulkanApplicationFramework::Init(SCREEN_WIDTH,SCREEN_HEIGHT)) + return(false); + + render_list=new RenderList(device); + + if(!InitMaterial()) + return(false); + + if(!InitUBO()) + return(false); + + if(!InitVBO()) + return(false); + + BuildCommandBuffer(render_list); + + return(true); + } + + void Resize(int w,int h)override + { + cam.width=w; + cam.height=h; + + cam.Refresh(); + + ubo_camera_info->Write(&cam.info); + + BuildCommandBuffer(render_list); + } +};//class TestApp:public VulkanApplicationFramework + +int main(int,char **) +{ + TestApp app; + + if(!app.Init()) + return(-1); + + while(app.Run()); + + return 0; +} diff --git a/example/Vulkan/ViewModelFramework.h b/example/common/ViewModelFramework.h similarity index 100% rename from example/Vulkan/ViewModelFramework.h rename to example/common/ViewModelFramework.h diff --git a/example/common/VulkanAppFramework.h b/example/common/VulkanAppFramework.h new file mode 100644 index 00000000..dc46a908 --- /dev/null +++ b/example/common/VulkanAppFramework.h @@ -0,0 +1,490 @@ +#pragma once +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//#include +#include + +#include +#include + +using namespace hgl; +using namespace hgl::io; +using namespace hgl::graph; + +class VulkanApplicationFramework:WindowEvent +{ +protected: + + Window * win =nullptr; + VulkanInstance * inst =nullptr; + +protected: + + GPUDevice * device =nullptr; + RenderPass * device_render_pass =nullptr; + SwapchainRenderTarget * sc_render_target =nullptr; + +protected: + + int32_t swap_chain_count =0; + + RenderCmdBuffer ** cmd_buf =nullptr; + + Color4f clear_color; + +protected: + + RenderResource * db =nullptr; + +public: + + virtual ~VulkanApplicationFramework() + { + win->Unjoin(this); + + SAFE_CLEAR(db); + SAFE_CLEAR_OBJECT_ARRAY(cmd_buf,swap_chain_count); + + SAFE_CLEAR(device); + SAFE_CLEAR(win); + SAFE_CLEAR(inst); + } + + virtual bool Init(int w,int h) + { + clear_color.Zero(); + + #ifdef _DEBUG + if(!CheckStrideBytesByFormat()) + return(false); + #endif// + + InitNativeWindowSystem(); + + InitVulkanInstanceProperties(); + + win=CreateRenderWindow(OS_TEXT("VulkanTest")); + if(!win) + return(false); + + if(!win->Create(w,h)) + return(false); + + { + CreateInstanceLayerInfo cili; + + hgl_zero(cili); + + cili.lunarg.standard_validation = true; + cili.khronos.validation = true; + cili.RenderDoc.Capture = true; + + inst=CreateInstance("VulkanTest",nullptr,&cili); + + if(!inst) + return(false); + } + + device=CreateRenderDevice(inst,win); + + if(!device) + return(false); + + device_render_pass=device->GetRenderPass(); + + db=new RenderResource(device); + + InitCommandBuffer(); + + win->Join(this); + + return(true); + } + + virtual void Resize(int,int)=0; + + void SetClearColor(COLOR cc) + { + clear_color.Use(cc,1.0); + } + + void OnResize(uint w,uint h) override + { + if(w>0&&h>0) + device->Resize(w,h); + + InitCommandBuffer(); + Resize(w,h); + } + + void InitCommandBuffer() + { + if(cmd_buf) + SAFE_CLEAR_OBJECT_ARRAY(cmd_buf,swap_chain_count); + + sc_render_target=device->GetSwapchainRT(); + + swap_chain_count=sc_render_target->GetImageCount(); + { + const VkExtent2D extent=sc_render_target->GetExtent(); + + cmd_buf=hgl_zero_new(swap_chain_count); + + for(int32_t i=0;iCreateRenderCommandBuffer(); + } + } + + bool BuildCommandBuffer(RenderCmdBuffer *cb,RenderPass *rp,Framebuffer *fb,RenderableInstance *ri) + { + if(!ri)return(false); + + const IndexBuffer *ib=ri->GetIndexBuffer(); + + cb->Begin(); + cb->BindFramebuffer(rp,fb); + cb->SetClearColor(0,clear_color.r,clear_color.g,clear_color.b); + cb->BeginRenderPass(); + cb->BindPipeline(ri->GetPipeline()); + cb->BindDescriptorSets(ri); + cb->BindVBO(ri); + + if (ib) + cb->DrawIndexed(ib->GetCount()); + else + cb->Draw(ri->GetDrawCount()); + + cb->EndRenderPass(); + cb->End(); + + return(true); + } + + void BuildCommandBuffer(RenderCmdBuffer *cb,RenderTarget *rt,RenderableInstance *ri) + { + if(!cb||!rt||!ri) + return; + + BuildCommandBuffer(cb,rt->GetRenderPass(),rt->GetFramebuffer(),ri); + } + + bool BuildCommandBuffer(uint32_t index,RenderableInstance *ri) + { + if(!ri)return(false); + + return BuildCommandBuffer(cmd_buf[index],sc_render_target->GetRenderPass(),sc_render_target->GetFramebuffer(index),ri); + } + + bool BuildCommandBuffer(RenderableInstance *ri) + { + if(!ri)return(false); + + for(int32_t i=0;iGetCurrentFrameIndices(),ri); + } + + void BuildCommandBuffer(uint32_t index,RenderList *rl) + { + if(!rl)return; + + RenderCmdBuffer *cb=cmd_buf[index]; + + cb->Begin(); + cb->BindFramebuffer(sc_render_target->GetRenderPass(),sc_render_target->GetFramebuffer(index)); + cb->SetClearColor(0,clear_color.r,clear_color.g,clear_color.b); + cb->BeginRenderPass(); + rl->Render(cb); + cb->EndRenderPass(); + cb->End(); + } + + void BuildCommandBuffer(RenderList *rl) + { + for(int32_t i=0;iGetCurrentFrameIndices(),rl); + } + + template + Pipeline *CreatePipeline(ARGS...args){return device_render_pass->CreatePipeline(args...);} + +public: + + int AcquireNextImage() + { + return sc_render_target->AcquireNextImage(); + } + + virtual void SubmitDraw(int index) + { + VkCommandBuffer cb=*cmd_buf[index]; + + sc_render_target->Submit(cb); + sc_render_target->PresentBackbuffer(); + sc_render_target->WaitQueue(); + sc_render_target->WaitFence(); + } + + virtual void Draw() + { + int index=AcquireNextImage(); + + if(index<0||index>=swap_chain_count)return; + + SubmitDraw(index); + } + + bool Run() + { + if(!win->Update())return(false); + + if(win->IsVisible()) + Draw(); + + return(true); + } +};//class VulkanApplicationFramework + +class CameraKeyboardControl:public KeyboardStateEvent +{ + FirstPersonCameraControl *camera; + float move_speed; + +public: + + CameraKeyboardControl(FirstPersonCameraControl *wc) + { + camera=wc; + move_speed=1.0f; + } + + bool OnPressed(const KeyboardButton &kb)override + { + if(!KeyboardStateEvent::OnPressed(kb)) + return(false); + + if(kb==KeyboardButton::Minus )move_speed*=0.9f;else + if(kb==KeyboardButton::Equals )move_speed*=1.1f; + + return(true); + } + + void Update() + { + if(HasPressed(KeyboardButton::W ))camera->Forward (move_speed);else + if(HasPressed(KeyboardButton::S ))camera->Backward (move_speed);else + if(HasPressed(KeyboardButton::A ))camera->Left (move_speed);else + if(HasPressed(KeyboardButton::D ))camera->Right (move_speed);else + //if(HasPressed(KeyboardButton::R ))camera->Up (move_speed);else + //if(HasPressed(KeyboardButton::F ))camera->Down (move_speed);else + + //if(HasPressed(KeyboardButton::Left ))camera->HoriRotate( move_speed);else + //if(HasPressed(KeyboardButton::Right ))camera->HoriRotate(-move_speed);else + //if(HasPressed(KeyboardButton::Up ))camera->VertRotate( move_speed);else + //if(HasPressed(KeyboardButton::Down ))camera->VertRotate(-move_speed);else + return; + } +}; + +class CameraMouseControl:public MouseEvent +{ + FirstPersonCameraControl *camera; + double cur_time; + double last_time; + + Vector2f mouse_pos; + Vector2f mouse_last_pos; + +protected: + + bool OnPressed(int x,int y,MouseButton) override + { + mouse_last_pos.x=x; + mouse_last_pos.y=y; + + last_time=cur_time; + + return(true); + } + + bool OnMove(int x,int y) override + { + mouse_pos.x=x; + mouse_pos.y=y; + + bool left=HasPressed(MouseButton::Left); + bool right=HasPressed(MouseButton::Right); + + if(left||right) + { + Vector2f pos(x,y); + Vector2f gap=pos-mouse_last_pos; + + camera->Rotate(gap/180.0f,(cur_time-last_time)*5); + + last_time=cur_time; + mouse_last_pos=Vector2f(x,y); + } + + return(true); + } + +public: + + CameraMouseControl(FirstPersonCameraControl *wc) + { + camera=wc; + cur_time=0; + } + + const Vector2f &GetMouseCoord()const{return mouse_pos;} + + void Update() + { + cur_time=GetDoubleTime(); + } +}; + +class CameraAppFramework:public VulkanApplicationFramework +{ +private: + + GPUBuffer *ubo_camera_info=nullptr; + +protected: + + Camera *camera=nullptr; + FirstPersonCameraControl *camera_control=nullptr; + + CameraKeyboardControl * ckc=nullptr; + CameraMouseControl * cmc=nullptr; + + const Vector2f &GetMouseCoord()const{return cmc->GetMouseCoord();} + +public: + + virtual ~CameraAppFramework() + { + SAFE_CLEAR(ckc); + SAFE_CLEAR(cmc); + SAFE_CLEAR(camera); + } + + virtual bool Init(int w,int h) + { + if(!VulkanApplicationFramework::Init(w,h)) + return(false); + + InitCamera(w,h); + return(true); + } + + virtual void InitCamera(int w,int h) + { + camera=new Camera; + + camera->width=w; + camera->height=h; + camera->vp_width=w; + camera->vp_height=h; + + camera->pos=Vector3f(10,10,10); + + camera_control=new FirstPersonCameraControl(camera); + + camera_control->Refresh(); //更新矩阵计算 + + ubo_camera_info=db->CreateUBO(sizeof(CameraInfo),&camera->info); + + ckc=new CameraKeyboardControl(camera_control); + cmc=new CameraMouseControl(camera_control); + + win->Join(ckc); + win->Join(cmc); + } + + void Resize(int w,int h)override + { + camera->width=w; + camera->height=h; + + camera_control->Refresh(); + + ubo_camera_info->Write(&camera->info); + } + + const CameraInfo &GetCameraInfo() + { + return camera->info; + } + + GPUBuffer *GetCameraInfoBuffer() + { + return ubo_camera_info; + } + + bool BindCameraUBO(MaterialInstance *mi) + { + MaterialParameters *mp_global=mi->GetMP(DescriptorSetsType::Global); + + if(!mp_global) + return(false); + + if(!mp_global->BindUBO("g_camera",ubo_camera_info))return(false); + + mp_global->Update(); + + return(true); + } + + virtual void BuildCommandBuffer(uint32_t index)=0; + + virtual void Draw()override + { + camera_control->Refresh(); //更新相机矩阵 + ubo_camera_info->Write(&camera->info); //写入缓冲区 + + const uint32_t index=AcquireNextImage(); + + BuildCommandBuffer(index); + + SubmitDraw(index); + + ckc->Update(); + cmc->Update(); + } +};//class CameraAppFramework \ No newline at end of file diff --git a/inc/hgl/graph/Bitmap2DLoader.h b/inc/hgl/graph/Bitmap2DLoader.h new file mode 100644 index 00000000..9b9bc61c --- /dev/null +++ b/inc/hgl/graph/Bitmap2DLoader.h @@ -0,0 +1,32 @@ +#ifndef HGL_GRAPH_BITMAP2D_LOADER_INCLUDE +#define HGL_GRAPH_BITMAP2D_LOADER_INCLUDE + +#include +namespace hgl +{ + namespace graph + { + /** + * 2Dλͼ + */ + class Bitmap2DLoader:public Texture2DLoader + { + protected: + + BitmapData *bmp=nullptr; + + public: + + Bitmap2DLoader():Texture2DLoader(){} + ~Bitmap2DLoader(); + + void *OnBegin(uint32 total_bytes) override; + void OnEnd() override {} + + BitmapData *GetBitmap(); + };//class Bitmap2DLoader + + BitmapData *LoadBitmapFromFile(const OSString &filename); + }//namespace graph +}//namespace hgl +#endif//HGL_GRAPH_BITMAP2D_LOADER_INCLUDE diff --git a/inc/hgl/graph/GPUDataArray.h b/inc/hgl/graph/GPUDataArray.h new file mode 100644 index 00000000..25d1de60 --- /dev/null +++ b/inc/hgl/graph/GPUDataArray.h @@ -0,0 +1,77 @@ +#ifndef HGL_GRAPH_GPU_DATA_ARRAY_INCLUDE +#define HGL_GRAPH_GPU_DATA_ARRAY_INCLUDE + +#include +namespace hgl +{ + namespace graph + { + /** + * GPU数据阵列 + **/ + class GPUDataArray + { + uint32_t alloc_count; + uint32_t count; + uint32_t item_size; + + GPUBuffer * buf_gpu; + uint8 * buf_cpu; + + uint32_t * offset; + + public: + + GPUDataArray(const uint32_t s=0) + { + alloc_count=0; + count=0; + item_size=s; + buf_gpu=nullptr; + buf_cpu=nullptr; + offset=nullptr; + } + + virtual ~GPUDataArray() + { + Clear(); + } + + virtual void Clear() + { + alloc_count=0; + count=0; + + if(buf_gpu) + { + buf_gpu->Unmap(); + delete buf_gpu; + buf_gpu=nullptr; + } + + SAFE_CLEAR_ARRAY(buf_cpu); + SAFE_CLEAR_ARRAY(offset); + } + + bool Init(const uint32_t c,const uint32_t s=0) + { + if(s + &&item_size<=0) + { + if(s>HGL_SIZE_1KB*64) + return(false); + + item_size=s; + } + + count=c; + + if(count*item_size<=0) + return(false); + + buf_cpu=new + } + };//class GPUDataArray + }//namespace graph +}//namespace hgl +#endif//HGL_GRAPH_GPU_DATA_ARRAY_INCLUDE diff --git a/inc/hgl/graph/InlineGeometry.h b/inc/hgl/graph/InlineGeometry.h index a8f8b469..14a0e929 100644 --- a/inc/hgl/graph/InlineGeometry.h +++ b/inc/hgl/graph/InlineGeometry.h @@ -1,10 +1,11 @@ #ifndef HGL_GRAPH_INLINE_GEOMETRY_INCLUDE #define HGL_GRAPH_INLINE_GEOMETRY_INCLUDE -#include +#include #include #include #include +#include namespace hgl { namespace graph @@ -17,12 +18,12 @@ namespace hgl RectScope2f scope; };//struct RectangleCreateInfo - vulkan::Renderable *CreateRenderableRectangle(vulkan::Database *db,vulkan::Material *mtl,const RectangleCreateInfo *rci); + Renderable *CreateRenderableRectangle(RenderResource *db,const VAB *vab,const RectangleCreateInfo *rci); /** * 创建延迟渲染用全屏平面 */ - vulkan::Renderable *CreateRenderableGBufferComposition(vulkan::Database *db,vulkan::Material *mtl); + Renderable *CreateRenderableGBufferComposition(RenderResource *db,const VAB *vab); /** * 圆角矩形创建信息(扇形/线圈) @@ -33,7 +34,7 @@ namespace hgl uint32_t round_per; ///<圆角精度 };//struct RoundRectangleCreateInfo:public RectangleCreateInfo - vulkan::Renderable *CreateRenderableRoundRectangle(vulkan::Database *db,vulkan::Material *mtl,const RoundRectangleCreateInfo *rci); + Renderable *CreateRenderableRoundRectangle(RenderResource *db,const VAB *vab,const RoundRectangleCreateInfo *rci); /** * 圆形创建信息 @@ -42,13 +43,18 @@ namespace hgl { Vector2f center; ///<圆心坐标 Vector2f radius; ///<半径 - uint field_count; ///<分段次数 + uint field_count=8; ///<分段次数 + + bool has_color =false; + + Vector4f center_color; ///<圆心颜色 + Vector4f border_color; ///<边缘颜色 };//struct CircleCreateInfo /** * 创建一个2D圆形(扇形/线圈) */ - vulkan::Renderable *CreateRenderableCircle(vulkan::Database *db,vulkan::Material *mtl,const CircleCreateInfo *rci); + Renderable *CreateRenderableCircle(RenderResource *db,const VAB *vab,const CircleCreateInfo *cci); /** * 平面网格创建信息 @@ -56,9 +62,9 @@ namespace hgl struct PlaneGridCreateInfo { Vector3f coord[4]; - vec2 step; + Vector2u step; - vec2 side_step; //到边界的步数 + Vector2u side_step; //到边界的步数 Color4f color; //一般线条颜色 Color4f side_color; //边界线条颜色 @@ -67,7 +73,7 @@ namespace hgl /** * 创建一个平面网格(线条) */ - vulkan::Renderable *CreateRenderablePlaneGrid(vulkan::Database *db,vulkan::Material *mtl,const PlaneGridCreateInfo *pgci); + Renderable *CreateRenderablePlaneGrid(RenderResource *db,const VAB *vab,const PlaneGridCreateInfo *pgci); struct PlaneCreateInfo { @@ -77,64 +83,87 @@ namespace hgl PlaneCreateInfo() { - tile.Set(1,1); + tile.x=1.0f; + tile.y=1.0f; } };//struct PlaneCreateInfo /** * 创建一个平面(三角形) */ - vulkan::Renderable *CreateRenderablePlane(vulkan::Database *db,vulkan::Material *mtl,const PlaneCreateInfo *pci); + Renderable *CreateRenderablePlane(RenderResource *db,const VAB *vab,const PlaneCreateInfo *pci); struct CubeCreateInfo { - Vector3f center; - Vector3f size; - Vector2f tile; + bool normal; + bool tangent; + bool tex_coord; - bool has_color; - Vector4f color; + enum class ColorType + { + NoColor=0, ///<没有颜色 + SameColor, ///<一个颜色 + FaceColor, ///<每个面一个颜色(请写入6个颜色值) + VertexColor, ///<每个顶点一个颜色(请写入24个颜色值) + + ENUM_CLASS_RANGE(NoColor,VertexColor) + }; + + ColorType color_type; + Vector4f color[24]; public: - - void Set(const AABB &box) - { - center=box.CenterPoint().xyz(); - size=box.Size().xyz(); - } CubeCreateInfo() { - center.Set(0,0,0); - size.Set(1,1,1); - tile.Set(1,1); + normal=false; + tangent=false; + tex_coord=false; - has_color=false; - } - - CubeCreateInfo(const AABB &box) - { - Set(box); - tile.Set(1,1); - - has_color=false; + color_type=ColorType::NoColor; } };//struct CubeCreateInfo /** * 创建一个立方体(三角形) */ - vulkan::Renderable *CreateRenderableCube(vulkan::Database *db,vulkan::Material *mtl,const CubeCreateInfo *cci); - + Renderable *CreateRenderableCube(RenderResource *db,const VAB *vab,const CubeCreateInfo *cci); + + struct BoundingBoxCreateInfo + { + bool normal; + + enum class ColorType + { + NoColor=0, ///<没有颜色 + SameColor, ///<一个颜色 + VertexColor, ///<每个顶点一个颜色(请写入8个颜色值) + + ENUM_CLASS_RANGE(NoColor,VertexColor) + }; + + ColorType color_type; + Vector4f color[8]; + + public: + + BoundingBoxCreateInfo() + { + normal=false; + + color_type=ColorType::NoColor; + } + };//struct BoundingBoxCreateInfo + /** * 创建一个绑定盒(线条) */ - vulkan::Renderable *CreateRenderableBoundingBox(vulkan::Database *db,vulkan::Material *mtl,const CubeCreateInfo *cci); - + Renderable *CreateRenderableBoundingBox(RenderResource *db,const VAB *vab,const BoundingBoxCreateInfo *cci); + /** * 创建一个球心坐标为0,0,0,半径为1的球体(三角形) */ - vulkan::Renderable *CreateRenderableSphere(vulkan::Database *db,vulkan::Material *mtl,const uint numberSlices); + Renderable *CreateRenderableSphere(RenderResource *db,const VAB *vab,const uint numberSlices); struct DomeCreateInfo { @@ -145,7 +174,7 @@ namespace hgl /** * 创建一个穹顶(三角形) */ - vulkan::Renderable *CreateRenderableDome(vulkan::Database *db,vulkan::Material *mtl, const DomeCreateInfo *); + Renderable *CreateRenderableDome(RenderResource *db,const VAB *vab, const DomeCreateInfo *); struct TorusCreateInfo { @@ -154,12 +183,14 @@ namespace hgl uint numberSlices, numberStacks; + + Vector2f uv_scale={1.0,1.0}; };//struct TorusCreateInfo - + /** * 创建一个圆环(三角形) */ - vulkan::Renderable *CreateRenderableTorus(vulkan::Database *db,vulkan::Material *mtl,const TorusCreateInfo *tci); + Renderable *CreateRenderableTorus(RenderResource *db,const VAB *vab,const TorusCreateInfo *tci); struct CylinderCreateInfo { @@ -171,7 +202,7 @@ namespace hgl /** * 创建一个圆柱(三角形) */ - vulkan::Renderable *CreateRenderableCylinder(vulkan::Database *db,vulkan::Material *mtl,const CylinderCreateInfo *cci); + Renderable *CreateRenderableCylinder(RenderResource *db,const VAB *vab,const CylinderCreateInfo *cci); struct ConeCreateInfo { @@ -184,47 +215,28 @@ namespace hgl /** * 创建一个圆锥(三角形) */ - vulkan::Renderable *CreateRenderableCone(vulkan::Database *db,vulkan::Material *mtl,const ConeCreateInfo *cci); - + Renderable *CreateRenderableCone(RenderResource *db,const VAB *vab,const ConeCreateInfo *cci); + struct AxisCreateInfo { - Vector3f root; - Vector3f size; + float size; Color4f color[3]; public: - void RestartColor() + AxisCreateInfo() { + size=1.0f; color[0].Set(1,0,0,1); color[1].Set(0,1,0,1); color[2].Set(0,0,1,1); } - - void Set(const AABB &box) - { - root=box.CenterPoint().xyz(); - size=box.HalfSize().xyz(); - } - - AxisCreateInfo() - { - root.Set(0,0,0); - size.Set(1,1,1); - RestartColor(); - } - - AxisCreateInfo(const AABB &box) - { - Set(box); - RestartColor(); - } };//struct AxisCreateInfo /** * 创建一个坐标线(线条) */ - vulkan::Renderable *CreateRenderableAxis(vulkan::Database *db,vulkan::Material *mtl,const AxisCreateInfo *aci); + Renderable *CreateRenderableAxis(RenderResource *db,const VAB *vab,const AxisCreateInfo *aci); }//namespace graph };//namespace hgl #endif//HGL_GRAPH_INLINE_GEOMETRY_INCLUDE diff --git a/inc/hgl/graph/RenderList.h b/inc/hgl/graph/RenderList.h index c574e7c6..c4f8f75b 100644 --- a/inc/hgl/graph/RenderList.h +++ b/inc/hgl/graph/RenderList.h @@ -1,50 +1,73 @@ #ifndef HGL_GRAPH_RENDER_LIST_INCLUDE #define HGL_GRAPH_RENDER_LIST_INCLUDE -#include +#include #include #include +#include +#include +#include #include +#include namespace hgl { namespace graph { - class RenderableInstance; + using MVPArrayBuffer=GPUArrayBuffer; + using MaterialSets=SortedSets; + /** + * 渲染对象列表
+ * 已经展开的渲染对象列表,产生mvp用UBO/SSBO等数据,最终创建RenderCommandBuffer + */ class RenderList { - vulkan::CommandBuffer *cmd_buf; + GPUDevice * device; + RenderCmdBuffer *cmd_buf; private: - List scene_node_list; + CameraInfo camera_info; + + RenderNodeList render_node_list; ///<场景节点列表 + MaterialSets material_sets; ///<材质合集 - vulkan::PushConstant * last_pc; - vulkan::Pipeline * last_pipeline; - vulkan::MaterialInstance * last_mat_inst; - vulkan::Renderable * last_renderable; + RenderNodeComparator render_node_comparator; - void Render(SceneNode *,RenderableInstance *); - void Render(SceneNode *,List &); + private: + + MVPArrayBuffer *mvp_array; + List ri_list; + + VkDescriptorSet ds_list[(size_t)DescriptorSetsType::RANGE_SIZE]; + DescriptorSets *renderable_desc_sets; + + uint32_t ubo_offset; + uint32_t ubo_align; + + protected: + + virtual bool Begin(); + virtual bool Expend(SceneNode *); + virtual void End(); + + private: + + Pipeline * last_pipeline; + MaterialParameters *last_mp[(size_t)DescriptorSetsType::RANGE_SIZE]; + uint32_t last_vbo; + + void Render(RenderableInstance *); public: - RenderList() - { - cmd_buf=nullptr; - last_pc=nullptr; - last_pipeline=nullptr; - last_mat_inst=nullptr; - last_renderable=nullptr; - } + RenderList(GPUDevice *); + virtual ~RenderList(); + + virtual bool Expend(const CameraInfo &,SceneNode *); - ~RenderList()=default; - - void Add (SceneNode *node) {if(node)scene_node_list.Add(node);} - void Clear () {scene_node_list.ClearData();} - - bool Render(vulkan::CommandBuffer *); - };//class RenderList + virtual bool Render(RenderCmdBuffer *); + };//class RenderList }//namespace graph }//namespace hgl #endif//HGL_GRAPH_RENDER_LIST_INCLUDE diff --git a/inc/hgl/graph/RenderNode.h b/inc/hgl/graph/RenderNode.h new file mode 100644 index 00000000..6f6965b2 --- /dev/null +++ b/inc/hgl/graph/RenderNode.h @@ -0,0 +1,39 @@ +#ifndef HGL_GRAPH_RENDER_NODE_INCLUDE +#define HGL_GRAPH_RENDER_NODE_INCLUDE + +#include +#include +#include +namespace hgl +{ + namespace graph + { + class RenderableInstance; + + struct RenderNode + { + MVPMatrix matrix; + + Vector3f WorldCenter; + + float distance_to_camera_square; +// float distance_to_camera; + + RenderableInstance *ri; + + public: + + /** + * 取得渲染对象ubo独占区大小 + */ + virtual const uint32 GetUBOBytes()const{return sizeof(MVPMatrix);} + };//struct RenderNode + + using RenderNodeList=List; + }//namespace graph +}//namespace hgl + +using RenderNodePointer=hgl::graph::RenderNode *; +using RenderNodeComparator=Comparator; + +#endif//HGL_GRAPH_RENDER_NODE_INCLUDE diff --git a/inc/hgl/graph/RenderableCreater.h b/inc/hgl/graph/RenderableCreater.h index 7464915a..8a7c5a3b 100644 --- a/inc/hgl/graph/RenderableCreater.h +++ b/inc/hgl/graph/RenderableCreater.h @@ -1,9 +1,9 @@ #ifndef HGL_GRAPH_RENDERABLE_CREATER_INCLUDE #define HGL_GRAPH_RENDERABLE_CREATER_INCLUDE -#include +#include #include -#include +#include namespace hgl { namespace graph @@ -13,7 +13,7 @@ namespace hgl AnsiString name; uint binding; VAD * data =nullptr; - vulkan::VAB * vab =nullptr; + VBO * vbo =nullptr; public: @@ -23,7 +23,7 @@ namespace hgl } };//struct ShaderStageBind - using VADMaps=MapObject; + using ShaderStageBindMap=MapObject; /** * 可渲染对象创建器 @@ -32,25 +32,21 @@ namespace hgl { protected: - vulkan::Database *db; - vulkan::Material *mtl; + RenderResource *db; + Material *mtl; - const vulkan::VertexShaderModule *vsm; + const VAB *vab; protected: - uint32 vertices_number; + uint32 vertices_number; - vulkan::IndexBuffer * ibo; - VADMaps vab_maps; - - protected: - - virtual VAD *CreateVAD(const AnsiString &name,const vulkan::ShaderStage *ss); ///<创建一个顶点属性缓冲区 + IndexBuffer * ibo; + ShaderStageBindMap ssb_map; public: - RenderableCreater(vulkan::Database *sdb,vulkan::Material *m); + RenderableCreater(RenderResource *sdb,const VAB *); virtual ~RenderableCreater()=default; virtual bool Init(const uint32 count); ///<初始化,参数为顶点数量 @@ -60,12 +56,9 @@ namespace hgl template T * CreateVADA(const AnsiString &name) ///<创建一个顶点属性缓冲区以及访问器 { - const vulkan::ShaderStage *ss=vsm->GetStageInput(name); + const VkFormat format=vab->GetFormat(name); - if(!ss) - return(nullptr); - - if(ss->format!=T::GetVulkanFormat()) + if(format!=T::GetVulkanFormat()) return(nullptr); VAD *vad=this->CreateVAD(name); @@ -85,7 +78,7 @@ namespace hgl uint16 * CreateIBO16(uint count,const uint16 *data=nullptr); ///<创建16位的索引缓冲区 uint32 * CreateIBO32(uint count,const uint32 *data=nullptr); ///<创建32位的索引缓冲区 - virtual vulkan::Renderable * Finish(); ///<结束并创建可渲染对象 + virtual Renderable * Finish(); ///<结束并创建可渲染对象 };//class RenderableCreater }//namespace graph }//namespace hgl diff --git a/inc/hgl/graph/RenderableInstance.h b/inc/hgl/graph/RenderableInstance.h deleted file mode 100644 index 9194be33..00000000 --- a/inc/hgl/graph/RenderableInstance.h +++ /dev/null @@ -1,76 +0,0 @@ -#ifndef HGL_GRAPH_RENDERABLE_INSTANCE_INCLUDE -#define HGL_GRAPH_RENDERABLE_INSTANCE_INCLUDE - -#include -#include -#include -namespace hgl -{ - namespace graph - { - /** - * 可渲染对象节点 - */ - class RenderableInstance - { - vulkan::Pipeline * pipeline; - vulkan::MaterialInstance *mat_inst; - vulkan::Renderable * render_obj; - - public: - - RenderableInstance(vulkan::Pipeline *p,vulkan::MaterialInstance *mi,vulkan::Renderable *r):pipeline(p),mat_inst(mi),render_obj(r){} - virtual ~RenderableInstance() - { - //需要在这里添加删除pipeline/desc_sets/render_obj引用计数的代码 - } - - vulkan::Pipeline * GetPipeline (){return pipeline;} - vulkan::MaterialInstance * GetMaterialInstance (){return mat_inst;} - vulkan::Renderable * GetRenderable (){return render_obj;} - const AABB & GetBoundingBox ()const{return render_obj->GetBoundingBox();} - - const int Comp(const RenderableInstance *ri)const - { - //绘制顺序: - - // ARM Mali GPU : 不透明、AlphaTest、半透明 - // Adreno/NV/AMD: AlphaTest、不透明、半透明 - // PowerVR: 同Adreno/NV/AMD,但不透明部分可以不排序 - - if(pipeline->IsAlphaBlend()) - { - if(!ri->pipeline->IsAlphaBlend()) - return 1; - } - else - { - if(ri->pipeline->IsAlphaBlend()) - return -1; - } - - if(pipeline->IsAlphaTest()) - { - if(!ri->pipeline->IsAlphaTest()) - return 1; - } - else - { - if(ri->pipeline->IsAlphaTest()) - return -1; - } - - if(pipeline!=ri->pipeline) - return pipeline-ri->pipeline; - - if(mat_inst!=ri->mat_inst) - return int64(mat_inst)-int64(ri->mat_inst); - - return render_obj-ri->render_obj; - } - - CompOperator(const RenderableInstance *,Comp) - };//class RenderableInstance - }//namespace graph -}//namespace hgl -#endif//HGL_GRAPH_RENDERABLE_INSTANCE_INCLUDE diff --git a/inc/hgl/graph/SceneInfo.h b/inc/hgl/graph/SceneInfo.h new file mode 100644 index 00000000..b23be4c2 --- /dev/null +++ b/inc/hgl/graph/SceneInfo.h @@ -0,0 +1,38 @@ +#ifndef HGL_GRAPH_SCENE_INFO_INCLUDE +#define HGL_GRAPH_SCENE_INFO_INCLUDE + +#include +#include +namespace hgl +{ + namespace graph + { + /** + * MVP矩阵 + */ + struct MVPMatrix + { + Matrix4f model; ///< model: Local to World + //Matrix4f normal; /// #include -#include +#include +#include namespace hgl { namespace graph { - class SceneNode; - struct Camera; - class RenderList; - class RenderableInstance; - - using RenderListCompFunc=float (*)(Camera *,SceneNode *,SceneNode *); ///<渲染列表排序比较函数 - - float CameraLengthComp(Camera *,SceneNode *,SceneNode *); ///<摄像机距离比较函数 - - using FilterSceneNodeFunc=bool (*)(const SceneNode *,void *); ///<场景节点过滤函数重定义 - - bool FrustumClipFilter(const SceneNode *,void *); ///<平截头截减过滤函数 - /** * 场景节点数据类
- * 从场景坐标变换(SceneOrient)类继承 + * 从场景坐标变换(SceneOrient)类继承, + * 每个场景节点中可能包括一个可渲染数据实例,或是完全不包含(用于坐标变换的父节点,或是灯光/摄像机之类)。 */ class SceneNode:public SceneOrient ///场景节点类 { @@ -33,28 +22,33 @@ namespace hgl AABB LocalBoundingBox; ///<本地坐标绑定盒 AABB WorldBoundingBox; ///<世界坐标绑定盒 - Vector3f Center; ///<中心点 - Vector3f LocalCenter; ///<本地坐标中心点 - Vector3f WorldCenter; ///<世界坐标中心点 + Vector4f Center; ///<中心点 + Vector4f LocalCenter; ///<本地坐标中心点 + Vector4f WorldCenter; ///<世界坐标中心点 + + RenderableInstance *render_obj=nullptr; ///<可渲染实例 public: ObjectList SubNode; ///<子节点 - List renderable_instances; ///<可渲染实例 - public: SceneNode()=default; - SceneNode(const Matrix4f &mat) + SceneNode( RenderableInstance *ri ) {render_obj=ri;} + SceneNode(const Matrix4f &mat ):SceneOrient(mat) {} + SceneNode(const Matrix4f &mat, RenderableInstance *ri ):SceneOrient(mat) {render_obj=ri;} + + virtual ~SceneNode()=default; + + void Clear() { - SetLocalMatrix(mat); + SubNode.ClearData(); + render_obj=nullptr; } - virtual ~SceneNode() - { - ClearSubNode(); - } + RenderableInstance *GetRI(){return render_obj;} + void SetRI(RenderableInstance *); SceneNode *CreateSubNode() { @@ -64,6 +58,14 @@ namespace hgl return sn; } + SceneNode *CreateSubNode(RenderableInstance *ri) + { + SceneNode *sn=new SceneNode(ri); + + SubNode.Add(sn); + return sn; + } + SceneNode *CreateSubNode(const Matrix4f &mat) { SceneNode *sn=new SceneNode(mat); @@ -72,21 +74,14 @@ namespace hgl return sn; } - void Add(SceneNode *n){if(n)SubNode.Add(n);} ///<增加一个子节点 - void ClearSubNode(){SubNode.ClearData();} ///<清除子节点 - - void Add(RenderableInstance *ri){if(ri)renderable_instances.Add(ri);} ///<增加渲染实例 - - void Add(RenderableInstance *ri,const Matrix4f &mat) + SceneNode *CreateSubNode(const Matrix4f &mat,RenderableInstance *ri) { - SceneNode *sn=new SceneNode(mat); + SceneNode *sn=new SceneNode(mat,ri); - sn->Add(ri); SubNode.Add(sn); + return sn; } - void ClearRenderableInstance(){renderable_instances.ClearData();} ///<清除渲染实例 - public: //坐标相关方法 virtual void SetBoundingBox (const AABB &bb){BoundingBox=bb;} ///<设置绑定盒 @@ -98,17 +93,9 @@ namespace hgl virtual const AABB & GetLocalBoundingBox ()const{return LocalBoundingBox;} ///<取得本地坐标绑定盒 virtual const AABB & GetWorldBoundingBox ()const{return WorldBoundingBox;} ///<取得世界坐标绑定盒 - virtual const Vector3f & GetCenter ()const{return Center;} ///<取得中心点 - virtual const Vector3f & GetLocalCenter ()const{return LocalCenter;} ///<取得本地坐标中心点 - virtual const Vector3f & GetWorldCenter ()const{return WorldCenter;} ///<取得世界坐标中心点 - - public: //渲染列表相关方法 - - virtual bool ExpendToList(RenderList *,FilterSceneNodeFunc func=nullptr,void *func_data=nullptr); ///<展开到渲染列表 - bool ExpendToList(RenderList *rl,Frustum *f) ///<展开到渲染列表(使用平截头裁剪) - {return ExpendToList(rl,FrustumClipFilter,f);} - - bool ExpendToList(RenderList *,Camera *,RenderListCompFunc=nullptr); ///<展开到渲染列表(使用摄像机平截头裁剪并排序) + virtual const Vector4f & GetCenter ()const{return Center;} ///<取得中心点 + virtual const Vector4f & GetLocalCenter ()const{return LocalCenter;} ///<取得本地坐标中心点 + virtual const Vector4f & GetWorldCenter ()const{return WorldCenter;} ///<取得世界坐标中心点 };//class SceneNode }//namespace graph }//namespace hgl diff --git a/inc/hgl/graph/SceneOrient.h b/inc/hgl/graph/SceneOrient.h index f961df45..eda68117 100644 --- a/inc/hgl/graph/SceneOrient.h +++ b/inc/hgl/graph/SceneOrient.h @@ -3,7 +3,7 @@ //#include #include -#include +#include //#include namespace hgl { @@ -24,15 +24,12 @@ namespace hgl Matrix4f InverseLocalMatrix; ///<反向当前矩阵 Matrix4f InverseLocalToWorldMatrix; ///<反向当前到世界矩阵 - vulkan::PushConstant pc; - public: SceneOrient(); + SceneOrient(const Matrix4f &mat); virtual ~SceneOrient()=default; - vulkan::PushConstant *GetPushConstant(){return &pc;} - Matrix4f & SetLocalMatrix (const Matrix4f &); ///<设定当前节点矩阵 Matrix4f & SetLocalToWorldMatrix (const Matrix4f &); ///<设定当前节点到世界矩阵 @@ -42,7 +39,9 @@ namespace hgl const Matrix4f & GetInverseLocalMatrix ()const {return InverseLocalMatrix;} const Matrix4f & GetInverseLocalToWorldMatrix()const {return InverseLocalToWorldMatrix;} - void RefreshLocalToWorldMatrix (const Matrix4f *); ///<刷新到世界空间矩阵 + public: + + virtual void RefreshLocalToWorldMatrix (const Matrix4f *); ///<刷新到世界空间矩阵 };//class SceneOrient }//namespace graph }//namespace hgl diff --git a/inc/hgl/graph/SceneRoot.h b/inc/hgl/graph/SceneRoot.h new file mode 100644 index 00000000..4f978353 --- /dev/null +++ b/inc/hgl/graph/SceneRoot.h @@ -0,0 +1,23 @@ +#ifndef HGL_GRAPH_SCENE_ROOT_INCLUDE +#define HGL_GRAPH_SCENE_ROOT_INCLUDE + +#include + +namespace hgl +{ + namespace graph + { + /** + * 场景根节点 + */ + class SceneRoot + { + Camera *camera; ///<根相机 + + public: + + + };//class SceneRoot + }//namespace graph +}//namespace hgl +#endif//HGL_GRAPH_SCENE_ROOT_INCLUDE diff --git a/inc/hgl/graph/TextureLoader.h b/inc/hgl/graph/TextureLoader.h index 2f8f50f9..db6681f7 100644 --- a/inc/hgl/graph/TextureLoader.h +++ b/inc/hgl/graph/TextureLoader.h @@ -4,55 +4,86 @@ #include #include #include +#include namespace hgl { namespace graph { #pragma pack(push,1) - struct Tex2DFileHeader - { - uint8 id[6]; ///>3;} - };//struct TexPixelFormat - #pragma pack(pop) - - /** - * 2D纹理加载器 - */ - class Texture2DLoader - { - protected: - - Tex2DFileHeader file_header; + uint8 channels; //0: compress 1/2/3/4:normal union { - TexPixelFormat pixel_format; - uint16 compress_format; + struct + { + char colors[4]; + uint8 bits[4]; + uint8 datatype; + }; + + struct + { + uint16 compress_format; + }; }; - uint32 total_bytes; + public: - protected: + const uint pixel_bits()const; + };//struct TexPixelFormat + + constexpr uint TexPixelFormatLength=sizeof(TexPixelFormat); + + struct alignas(8) TextureFileHeader + { + uint8 id_str[7]; /// #include #include -#include +#include VK_NAMESPACE_USING @@ -33,7 +33,7 @@ namespace hgl */ class TileData ///Tile纹理管理 { - Device *device; + GPUDevice *device; protected: @@ -48,9 +48,9 @@ namespace hgl protected: - vulkan::Buffer *tile_buffer; /// commit_list; + List commit_list; uint8 *commit_ptr; bool CommitTile(TileObject *,const void *,const uint,const int,const int); ///<提交一个Tile数据 @@ -67,7 +67,7 @@ namespace hgl public: - TileData(Device *,Texture2D *,const uint tw,const uint th); + TileData(GPUDevice *,Texture2D *,const uint tw,const uint th); virtual ~TileData(); void BeginCommit(); diff --git a/inc/hgl/graph/VK.h b/inc/hgl/graph/VK.h new file mode 100644 index 00000000..e4146684 --- /dev/null +++ b/inc/hgl/graph/VK.h @@ -0,0 +1,278 @@ +#ifndef HGL_GRAPH_VULKAN_INCLUDE +#define HGL_GRAPH_VULKAN_INCLUDE + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +VK_NAMESPACE_BEGIN + +#ifndef VK_DESCRIPTOR_TYPE_BEGIN_RANGE +constexpr size_t VK_DESCRIPTOR_TYPE_BEGIN_RANGE=VK_DESCRIPTOR_TYPE_SAMPLER; +#endif//VK_DESCRIPTOR_TYPE_BEGIN_RANGE + +#ifndef VK_DESCRIPTOR_TYPE_END_RANGE +constexpr size_t VK_DESCRIPTOR_TYPE_END_RANGE=VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT; +#endif//VK_DESCRIPTOR_TYPE_END_RANGE + +#ifndef VK_DESCRIPTOR_TYPE_RANGE_SIZE +constexpr size_t VK_DESCRIPTOR_TYPE_RANGE_SIZE=VK_DESCRIPTOR_TYPE_END_RANGE-VK_DESCRIPTOR_TYPE_BEGIN_RANGE+1; +#endif//VK_DESCRIPTOR_TYPE_RANGE_SIZE + +using CharPointerList=hgl::List; +using BindingMapping=Map; + +class VulkanInstance; +class GPUPhysicalDevice; +class GPUDevice; +struct GPUDeviceAttribute; +class GPUQueue; +class ImageView; +class Framebuffer; +struct Swapchain; +class RenderTarget; +class SwapchainRenderTarget; + +class Texture; +class Texture1D; +class Texture1DArray; +class Texture2D; +class Texture2DArray; +class Texture3D; +class TextureCube; +class TextureCubeArray; + +class Sampler; + +class GPUMemory; +class GPUBuffer; +struct GPUBufferData; + +class VertexAttribBuffer; +using VBO=VertexAttribBuffer; + +class IndexBuffer; + +class GPUCmdBuffer; +class RenderCmdBuffer; +class TextureCmdBuffer; + +class RenderPass; +class DeviceRenderPassManage; + +class GPUFence; +class GPUSemaphore; + +enum class DescriptorSetsType +{ + //设计使其对应shader中的set + + Global=0, ///<全局参数(如太阳光等) + Material, ///<材质中永远不变的参数 +// Texture, ///<材质中的纹理参数 + Value, ///<材质中的变量参数 + Renderable, ///<渲染实例参数(如Local2World matrix) + + ENUM_CLASS_RANGE(Global,Renderable) +};// + +const DescriptorSetsType CheckDescriptorSetsType(const char *str); + +constexpr char *DescriptSetsTypeName[]= +{ + "Global","Material","Value","Renderable" +}; + +inline const char *GetDescriptorSetsTypeName(const enum class DescriptorSetsType &type) +{ + ENUM_CLASS_RANGE_ERROR_RETURN_NULLPTR(type); + + return DescriptSetsTypeName[(size_t)type]; +} + +struct PipelineLayoutData; +class DescriptorSets; + +struct ShaderStage; + +class ShaderResource; +class ShaderModule; +class VertexShaderModule; +class ShaderModuleMap; +class MaterialDescriptorSets; + +class Material; +class MaterialParameters; +class MaterialInstance; +struct PipelineData; +enum class InlinePipeline; +class Pipeline; + +struct VAConfig +{ + VkFormat format=PF_UNDEFINED; + bool instance=false; + +public: + + CompOperatorMemcmp(const VAConfig &); +}; + +using VABConfigInfo=Map; + +class VertexAttributeBinding; +using VAB=VertexAttributeBinding; + +class Renderable; +class RenderableInstance; + +class RenderResource; + +enum class SharingMode +{ + Exclusive = 0, + Concurrent +};// + +enum class Filter +{ + Nearest=0, + Linear, +};// + +enum ImageTiling +{ + Optimal=0, + Linear +};// + +inline const uint32_t GetMipLevel(const VkExtent2D &ext) +{ + return hgl::GetMipLevel(ext.width,ext.height); +} + +inline const uint32_t GetMipLevel(const VkExtent3D &ext) +{ + return hgl::GetMipLevel(ext.width,ext.height,ext.depth); +} + +/** + * 索引类型,等同于VkIndexType + */ +enum IndexType +{ + U16=0, + U32 +}; + +enum class ShaderStageBit +{ + Vertex =VK_SHADER_STAGE_VERTEX_BIT, + TessControl =VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, + TessEval =VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, + Geometry =VK_SHADER_STAGE_GEOMETRY_BIT, + Fragment =VK_SHADER_STAGE_FRAGMENT_BIT, + Compute =VK_SHADER_STAGE_COMPUTE_BIT +};//enum class ShaderStageBit + +inline const uint GetShaderCountByBits(const uint32_t bits) +{ + uint comp=(uint)VK_SHADER_STAGE_VERTEX_BIT; + uint result=0; + + for(uint i=0;i<6;i++) + { + if(bits&comp) + ++result; + + comp<<=1; + } + + return result; +} + +/** + * max-lengths: + * + 256 bytes: nvidia,arm + 128 bytes: amd,intel,powervr,adreno + */ +struct PushConstant +{ + Matrix4f local_to_world; + Matrix4f normal; +}; + +constexpr uint32_t MAX_PUSH_CONSTANT_BYTES=sizeof(PushConstant); + +inline void copy(VkExtent3D &e3d,const VkExtent2D &e2d,const uint32 depth=1) +{ + e3d.width =e2d.width; + e3d.height =e2d.height; + e3d.depth =depth; +} + +inline void debug_out_vk_version(const uint32_t version) +{ + std::cout< +inline hgl::String VkUUID2String(const uint8_t *pipelineCacheUUID) +{ + T *hstr=new T[VK_UUID_SIZE*2+1]; + + DataToLowerHexStr(hstr,pipelineCacheUUID,VK_UUID_SIZE); + + return hgl::String::newOf(hstr,VK_UUID_SIZE*2); +} + +inline void debug_out(const char *front,const hgl::List &layer_properties) +{ + const int property_count=layer_properties.GetCount(); + + if(property_count<=0)return; + + const VkLayerProperties *lp=layer_properties.GetData(); + + for(int i=0;ilayerName<<" [spec: "; + debug_out_vk_version(lp->specVersion); + + std::cout<<", impl: "; + debug_out_vk_version(lp->implementationVersion); + + std::cout<<"] desc: "<description< &extension_properties) +{ + const int extension_count=extension_properties.GetCount(); + + if(extension_count<=0)return; + + VkExtensionProperties *ep=extension_properties.GetData(); + for(int i=0;iextensionName<<" ver: "; + + debug_out_vk_version(ep->specVersion); + + std::cout< +#include +#include +#include +namespace hgl +{ + namespace graph + { + /** + * GPU数据阵列缓冲区
+ * 它用于储存多份相同格式的数据,常用于多物件渲染,instance等 + */ + template class GPUArrayBuffer + { + protected: + + GPUDevice *device; + VkBufferUsageFlags buffer_usage_flags; + VKMemoryAllocator *vk_ma; + + uint32_t ubo_offset_alignment; + + Collection *coll; + + public: + + GPUArrayBuffer(GPUDevice *dev,VkBufferUsageFlags flags) + { + device=dev; + buffer_usage_flags=flags; + + { + ubo_offset_alignment=device->GetUBOAlign(); + + const uint32_t unit_size=hgl_align(sizeof(T),ubo_offset_alignment); + + vk_ma=new VKMemoryAllocator(device,buffer_usage_flags,unit_size); // construct function is going to set AllocUnitSize by minUniformOffsetAlignment + MemoryBlock *mb=new MemoryBlock(vk_ma); + + coll=new Collection(unit_size,mb); + } + } + + virtual ~GPUArrayBuffer() + { + delete coll; + } + + const uint32_t GetOffsetAlignment()const + { + return ubo_offset_alignment; + } + + const uint32_t GetUnitSize()const + { + return coll->GetUnitBytes(); + } + + GPUBuffer *GetBuffer() + { + return vk_ma->GetBuffer(); + } + + uint32 Alloc(const uint32 max_count) ///<预分配空间 + { + if(!coll->Alloc(max_count)) + return(0); + + return coll->GetAllocCount(); + } + + void Clear() + { + coll->Clear(); + } + + T *Map(const uint32 start,const uint32 count) + { + return (T *)(coll->Map(start,count)); + } + + void Flush(const uint32 count) + { + vk_ma->Flush(count*GetUnitSize()); + } + };//class GPUArrayBuffer + }//namespace graph +}//namespace hgl +#endif//HGL_GRAPH_VULKAN_ARRAY_BUFFER_INCLUDE diff --git a/inc/hgl/graph/VKAttachment.h b/inc/hgl/graph/VKAttachment.h new file mode 100644 index 00000000..1a6f40f7 --- /dev/null +++ b/inc/hgl/graph/VKAttachment.h @@ -0,0 +1,13 @@ +#ifndef HGL_VULKAN_ATTACHMENT_INCLUDE +#define HGL_VULKAN_ATTACHMENT_INCLUDE +#include +VK_NAMESPACE_BEGIN +struct Attachment +{ + VkFormat format =VK_FORMAT_UNDEFINED; + VkSampleCountFlagBits samples =VK_SAMPLE_COUNT_1_BIT; + VkImageUsageFlags usage =VK_IMAGE_USAGE_SAMPLED_BIT; + VkImageLayout initial_layout =VK_IMAGE_LAYOUT_UNDEFINED; +};//struct Attachment +VK_NAMESPACE_END +#endif//HGL_VULKAN_ATTACHMENT_INCLUDE diff --git a/inc/hgl/graph/VKBuffer.h b/inc/hgl/graph/VKBuffer.h new file mode 100644 index 00000000..7fe19a5d --- /dev/null +++ b/inc/hgl/graph/VKBuffer.h @@ -0,0 +1,52 @@ +#ifndef HGL_GRAPH_VULKAN_BUFFER_INCLUDE +#define HGL_GRAPH_VULKAN_BUFFER_INCLUDE + +#include +#include +VK_NAMESPACE_BEGIN +struct GPUBufferData +{ + VkBuffer buffer; + GPUMemory * memory=nullptr; + VkDescriptorBufferInfo info; +};//struct GPUBufferData + +class GPUBuffer +{ +protected: + + VkDevice device; + GPUBufferData buf; + +private: + + friend class GPUDevice; + friend class VertexAttribBuffer; + friend class IndexBuffer; + + GPUBuffer(VkDevice d,const GPUBufferData &b) + { + device=d; + buf=b; + } + +public: + + virtual ~GPUBuffer(); + + VkBuffer GetBuffer ()const{return buf.buffer;} + GPUMemory * GetMemory ()const{return buf.memory;} + const VkDescriptorBufferInfo * GetBufferInfo ()const{return &buf.info;} + + void * Map () {return buf.memory->Map();} + virtual void * Map (VkDeviceSize start,VkDeviceSize size) {return buf.memory->Map(start,size);} + void Unmap () {return buf.memory->Unmap();} + void Flush (VkDeviceSize start,VkDeviceSize size) {return buf.memory->Flush(start,size);} + void Flush (VkDeviceSize size) {return buf.memory->Flush(size);} + + bool Write (const void *ptr,uint32_t start,uint32_t size) {return buf.memory->Write(ptr,start,size);} + bool Write (const void *ptr,uint32_t size) {return buf.memory->Write(ptr,0,size);} + bool Write (const void *ptr) {return buf.memory->Write(ptr);} +};//class GPUBuffer +VK_NAMESPACE_END +#endif//HGL_GRAPH_VULKAN_BUFFER_INCLUDE diff --git a/inc/hgl/graph/vulkan/VKBufferData.h b/inc/hgl/graph/VKBufferData.h similarity index 100% rename from inc/hgl/graph/vulkan/VKBufferData.h rename to inc/hgl/graph/VKBufferData.h diff --git a/inc/hgl/graph/VKCommandBuffer.h b/inc/hgl/graph/VKCommandBuffer.h new file mode 100644 index 00000000..eaa797d9 --- /dev/null +++ b/inc/hgl/graph/VKCommandBuffer.h @@ -0,0 +1,229 @@ +#ifndef HGL_GRAPH_VULKAN_COMMAND_BUFFER_INCLUDE +#define HGL_GRAPH_VULKAN_COMMAND_BUFFER_INCLUDE + +#include +#include +#include +#include +VK_NAMESPACE_BEGIN +class GPUCmdBuffer +{ +protected: + + const GPUDeviceAttribute *dev_attr; + + VkCommandBuffer cmd_buf; + +public: + + GPUCmdBuffer(const GPUDeviceAttribute *attr,VkCommandBuffer cb); + virtual ~GPUCmdBuffer(); + + operator VkCommandBuffer(){return cmd_buf;} + operator const VkCommandBuffer()const{return cmd_buf;} + operator const VkCommandBuffer *()const{return &cmd_buf;} + + bool Begin(); + bool End(){return(vkEndCommandBuffer(cmd_buf)==VK_SUCCESS);} + +#ifdef _DEBUG + void SetDebugName(const char *); + void BeginRegion(const char *,const Color4f &); + void EndRegion(); +#else + void BeginRegion(const char *,const Color4f &){} + void EndRegion(){} +#endif//_DEBUG +};//class GPUCmdBuffer + +class RenderCmdBuffer:public GPUCmdBuffer +{ + uint32_t cv_count; + VkClearValue *clear_values; + VkRect2D render_area; + VkViewport viewport; + + float default_line_width; + + Framebuffer *fbo; + RenderPassBeginInfo rp_begin; + VkPipelineLayout pipeline_layout; + + void SetFBO(Framebuffer *); + +public: + + RenderCmdBuffer(const GPUDeviceAttribute *attr,VkCommandBuffer cb); + ~RenderCmdBuffer(); + + void SetRenderArea(const VkRect2D &ra){render_area=ra;} + void SetRenderArea(const VkExtent2D &); + void SetViewport(const VkViewport &vp){viewport=vp;} + + void SetClearColor(uint32_t index,float r,float g,float b,float a=1.0f) + { + if(index>=cv_count)return; + + VkClearValue *cv=clear_values+index; + + cv->color.float32[0]=r; + cv->color.float32[1]=g; + cv->color.float32[2]=b; + cv->color.float32[3]=a; + } + + void SetClearDepthStencil(uint32_t index,float d=1.0f,float s=0) + { + if(index>=cv_count)return; + + VkClearValue *cv=clear_values+index; + + cv->depthStencil.depth=d; + cv->depthStencil.stencil=s; + } + + //以上设定在Begin开始后即不可改变 + + bool BindFramebuffer(RenderPass *rp,Framebuffer *fb); + + bool BeginRenderPass(); + + bool BindPipeline(Pipeline *p) + { + if(!p)return(false); + + vkCmdBindPipeline(cmd_buf,VK_PIPELINE_BIND_POINT_GRAPHICS,*p); + return(true); + } + + bool BindDescriptorSets(DescriptorSets *dsl) + { + if(!dsl)return(false); + + pipeline_layout=dsl->GetPipelineLayout(); + + const VkDescriptorSet ds=dsl->GetDescriptorSet(); + + vkCmdBindDescriptorSets(cmd_buf,VK_PIPELINE_BIND_POINT_GRAPHICS,pipeline_layout,0,1,&ds,0,nullptr); + + return(true); + } + + bool BindDescriptorSets(DescriptorSets *dsl,const uint32_t offset) + { + if(!dsl)return(false); + + pipeline_layout=dsl->GetPipelineLayout(); + + const VkDescriptorSet ds=dsl->GetDescriptorSet(); + + vkCmdBindDescriptorSets(cmd_buf,VK_PIPELINE_BIND_POINT_GRAPHICS,pipeline_layout,0,1,&ds,1,&offset); + + return(true); + } + + bool BindDescriptorSets(VkPipelineLayout pipeline_layout,const uint32_t first_set,const VkDescriptorSet *ds_list,const uint32_t ds_count,const uint32_t *offset,const uint32_t offset_count) + { + if(!ds_list||ds_count<=0)return(false); + + vkCmdBindDescriptorSets(cmd_buf,VK_PIPELINE_BIND_POINT_GRAPHICS,pipeline_layout,first_set,ds_count,ds_list,offset_count,offset); + + return(true); + } + + bool BindDescriptorSets(RenderableInstance *ri); + + bool PushDescriptorSet(VkPipelineLayout pipeline_layout,uint32_t set,uint32_t count,const VkWriteDescriptorSet *write_desc_set) + { + vkCmdPushDescriptorSetKHR(cmd_buf,VK_PIPELINE_BIND_POINT_GRAPHICS,pipeline_layout,set,count,write_desc_set); + } + + void PushConstants(ShaderStageBit shader_stage_bit,uint32_t offset,uint32_t size,const void *pValues) + { + vkCmdPushConstants(cmd_buf,pipeline_layout,(VkShaderStageFlagBits)shader_stage_bit,offset,size,pValues); + } + + void PushConstants(const void *data,const uint32_t size) {vkCmdPushConstants(cmd_buf,pipeline_layout,VK_SHADER_STAGE_VERTEX_BIT,0, size,data);} + void PushConstants(const void *data,const uint32_t offset,const uint32_t size) {vkCmdPushConstants(cmd_buf,pipeline_layout,VK_SHADER_STAGE_VERTEX_BIT,offset, size,data);} + + bool BindVBO(RenderableInstance *); + + void SetViewport (uint32_t first,uint32_t count,const VkViewport *vp) {vkCmdSetViewport(cmd_buf,first,count,vp);} + void SetScissor (uint32_t first,uint32_t count,const VkRect2D *sci) {vkCmdSetScissor(cmd_buf,first,count,sci);} + + void SetLineWidth (float line_width) {vkCmdSetLineWidth(cmd_buf,line_width);} + + void SetDepthBias (float constant_factor,float clamp,float slope_factor) {vkCmdSetDepthBias(cmd_buf,constant_factor,clamp,slope_factor);} + void SetDepthBounds (float min_db,float max_db) {vkCmdSetDepthBounds(cmd_buf,min_db,max_db);} + void SetBlendConstants (const float constants[4]) {vkCmdSetBlendConstants(cmd_buf,constants);} + + void SetStencilCompareMask (VkStencilFaceFlags faceMask,uint32_t compareMask) {vkCmdSetStencilCompareMask(cmd_buf,faceMask,compareMask);} + void SetStencilWriteMask (VkStencilFaceFlags faceMask,uint32_t compareMask) {vkCmdSetStencilWriteMask(cmd_buf,faceMask,compareMask);} + void SetStencilReference (VkStencilFaceFlags faceMask,uint32_t compareMask) {vkCmdSetStencilReference(cmd_buf,faceMask,compareMask);} + +public: //draw + + void Draw (const uint32_t vertex_count) {vkCmdDraw(cmd_buf,vertex_count,1,0,0);} + void DrawIndexed (const uint32_t index_count ) {vkCmdDrawIndexed(cmd_buf,index_count,1,0,0,0);} + + template void Draw (ARGS...args) {vkCmdDraw(cmd_buf,args...);} + template void DrawIndexed (ARGS...args) {vkCmdDrawIndexed(cmd_buf,args...);} + + void DrawIndirect (VkBuffer,VkDeviceSize, uint32_t drawCount,uint32_t stride=sizeof(VkDrawIndirectCommand )); + void DrawIndexedIndirect(VkBuffer,VkDeviceSize, uint32_t drawCount,uint32_t stride=sizeof(VkDrawIndexedIndirectCommand )); + void DrawIndirect (VkBuffer buf, uint32_t drawCount,uint32_t stride=sizeof(VkDrawIndirectCommand )){return DrawIndirect( buf,0,drawCount,stride);} + void DrawIndexedIndirect(VkBuffer buf, uint32_t drawCount,uint32_t stride=sizeof(VkDrawIndexedIndirectCommand )){return DrawIndexedIndirect( buf,0,drawCount,stride);} + + void NextSubpass(){vkCmdNextSubpass(cmd_buf,VK_SUBPASS_CONTENTS_INLINE);} + + void EndRenderPass(){vkCmdEndRenderPass(cmd_buf);} + +public: //dynamic state +};//class RenderCmdBuffer:public GPUCmdBuffer + +class TextureCmdBuffer:public GPUCmdBuffer +{ + VkImageMemoryBarrier imageMemoryBarrier; + +public: + + TextureCmdBuffer(const GPUDeviceAttribute *attr,VkCommandBuffer cb):GPUCmdBuffer(attr,cb) + { + imageMemoryBarrier.sType=VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; + imageMemoryBarrier.pNext=nullptr; + imageMemoryBarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; + imageMemoryBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; + } + + template void PipelineBarrier (ARGS...args){vkCmdPipelineBarrier (cmd_buf,args...);} + template void CopyBufferToImage (ARGS...args){vkCmdCopyBufferToImage(cmd_buf,args...);} + template void CopyImageToBuffer (ARGS...args){vkCmdCopyImageToBuffer(cmd_buf,args...);} + template void BlitImage (ARGS...args){vkCmdBlitImage (cmd_buf,args...);} + + void ImageMemoryBarrier(VkImage image, + VkPipelineStageFlags srcStageMask, + VkPipelineStageFlags dstStageMask, + VkAccessFlags srcAccessMask, + VkAccessFlags dstAccessMask, + VkImageLayout oldImageLayout, + VkImageLayout newImageLayout, + VkImageSubresourceRange subresourceRange) + { + imageMemoryBarrier.srcAccessMask = srcAccessMask; + imageMemoryBarrier.dstAccessMask = dstAccessMask; + imageMemoryBarrier.oldLayout = oldImageLayout; + imageMemoryBarrier.newLayout = newImageLayout; + imageMemoryBarrier.image = image; + imageMemoryBarrier.subresourceRange = subresourceRange; + + vkCmdPipelineBarrier( cmd_buf, + srcStageMask, + dstStageMask, + 0, + 0, nullptr, + 0, nullptr, + 1, &imageMemoryBarrier); + } +};//class TextureCmdBuffer:public GPUCmdBuffer +VK_NAMESPACE_END +#endif//HGL_GRAPH_VULKAN_COMMAND_BUFFER_INCLUDE diff --git a/inc/hgl/graph/VKDebugMaker.h b/inc/hgl/graph/VKDebugMaker.h new file mode 100644 index 00000000..c5eaf6d8 --- /dev/null +++ b/inc/hgl/graph/VKDebugMaker.h @@ -0,0 +1,66 @@ +#ifndef HGL_GRAPH_VULKAN_DEBUG_MAKER_INCLUDE +#define HGL_GRAPH_VULKAN_DEBUG_MAKER_INCLUDE + +#include +#include + +VK_NAMESPACE_BEGIN +struct DebugMakerFunction +{ + PFN_vkDebugMarkerSetObjectTagEXT SetObjectTag; + PFN_vkDebugMarkerSetObjectNameEXT SetObjectName; + PFN_vkCmdDebugMarkerBeginEXT Begin; + PFN_vkCmdDebugMarkerEndEXT End; + PFN_vkCmdDebugMarkerInsertEXT Insert; +};//struct DebugMakerFunction + +class DebugMaker +{ + VkDevice device; + + DebugMakerFunction dmf; + +protected: + + void SetObjectName(uint64_t object, VkDebugReportObjectTypeEXT objectType, const char *name); + void SetObjectTag(uint64_t object, VkDebugReportObjectTypeEXT objectType, uint64_t name, size_t tagSize, const void* tag); + +private: + + friend DebugMaker *CreateDebugMaker(VkDevice device); + + DebugMaker(VkDevice dev,const DebugMakerFunction &f) + { + device=dev; + dmf=f; + } + +public: + + void Begin(VkCommandBuffer cmdbuffer, const char * pMarkerName, const Color4f &color); + void Insert(VkCommandBuffer cmdbuffer, const char *markerName, const Color4f &color); + void End(VkCommandBuffer cmdBuffer); + + #define DEBUG_MAKER_SET_FUNC(type,MNAME) void Set##type##Name(Vk##type obj,const char *name){SetObjectName((uint64_t)obj,VK_DEBUG_REPORT_OBJECT_TYPE_##MNAME##_EXT,name);} + + DEBUG_MAKER_SET_FUNC(CommandBuffer, COMMAND_BUFFER) + DEBUG_MAKER_SET_FUNC(Queue, QUEUE) + DEBUG_MAKER_SET_FUNC(Image, IMAGE) + DEBUG_MAKER_SET_FUNC(Sampler, SAMPLER) + DEBUG_MAKER_SET_FUNC(Buffer, BUFFER) + DEBUG_MAKER_SET_FUNC(DeviceMemory, DEVICE_MEMORY) + DEBUG_MAKER_SET_FUNC(ShaderModule, SHADER_MODULE) + DEBUG_MAKER_SET_FUNC(Pipeline, PIPELINE) + DEBUG_MAKER_SET_FUNC(PipelineLayout, PIPELINE_LAYOUT) + DEBUG_MAKER_SET_FUNC(RenderPass, RENDER_PASS) + DEBUG_MAKER_SET_FUNC(Framebuffer, FRAMEBUFFER) + DEBUG_MAKER_SET_FUNC(DescriptorSetLayout, DESCRIPTOR_SET_LAYOUT) + DEBUG_MAKER_SET_FUNC(DescriptorSet, DESCRIPTOR_SET) + DEBUG_MAKER_SET_FUNC(Semaphore, SEMAPHORE) + DEBUG_MAKER_SET_FUNC(Fence, FENCE) + DEBUG_MAKER_SET_FUNC(Event, EVENT) + + #undef DEBUG_MAKER_SET_FUNC +};//class DebugMaker +VK_NAMESPACE_END +#endif//HGL_GRAPH_VULKAN_DEBUG_MAKER_INCLUDE diff --git a/inc/hgl/graph/vulkan/VKDebugOut.h b/inc/hgl/graph/VKDebugOut.h similarity index 97% rename from inc/hgl/graph/vulkan/VKDebugOut.h rename to inc/hgl/graph/VKDebugOut.h index 280cac6e..2bc2394c 100644 --- a/inc/hgl/graph/vulkan/VKDebugOut.h +++ b/inc/hgl/graph/VKDebugOut.h @@ -1,7 +1,7 @@ #ifndef HGL_GRAPH_VULKAN_DEBUG_OUT_INCLUDE #define HGL_GRAPH_VULKAN_DEBUG_OUT_INCLUDE -#include +#include VK_NAMESPACE_BEGIN diff --git a/inc/hgl/graph/VKDescriptorSets.h b/inc/hgl/graph/VKDescriptorSets.h new file mode 100644 index 00000000..d3a39780 --- /dev/null +++ b/inc/hgl/graph/VKDescriptorSets.h @@ -0,0 +1,62 @@ +#ifndef HGL_GRAPH_VULKAN_DESCRIPTOR_SETS_LAYOUT_INCLUDE +#define HGL_GRAPH_VULKAN_DESCRIPTOR_SETS_LAYOUT_INCLUDE + +#include +#include +#include +VK_NAMESPACE_BEGIN +class GPUBuffer; + +class DescriptorSets +{ + VkDevice device; + int binding_count; + VkDescriptorSet desc_set; + + VkPipelineLayout pipeline_layout; + + ObjectList buffer_list; + ObjectList image_list; + List wds_list; + + SortedSets binded_sets; + + bool is_dirty; + +private: + + friend class GPUDevice; + + DescriptorSets(VkDevice dev,const int bc,VkPipelineLayout pl,VkDescriptorSet ds) + { + device =dev; + binding_count =bc; + desc_set =ds; + pipeline_layout =pl; + + is_dirty=true; + } + +public: + + ~DescriptorSets()=default; + + const uint32_t GetCount ()const{return binding_count;} + const VkDescriptorSet GetDescriptorSet ()const{return desc_set;} + const VkPipelineLayout GetPipelineLayout ()const{return pipeline_layout;} + + const bool IsReady ()const{return wds_list.GetCount()==binding_count;} + + void Clear(); + + bool BindUBO (const int binding,const GPUBuffer *buf,bool dynamic=false); + bool BindUBO (const int binding,const GPUBuffer *buf,const VkDeviceSize offset,const VkDeviceSize range,bool dynamic=false); + bool BindSSBO (const int binding,const GPUBuffer *buf,bool dynamic=false); + bool BindSSBO (const int binding,const GPUBuffer *buf,const VkDeviceSize offset,const VkDeviceSize range,bool dynamic=false); + + bool BindSampler(const int binding,Texture *,Sampler *); + bool BindInputAttachment(const int binding,Texture *); + void Update(); +};//class DescriptorSets +VK_NAMESPACE_END +#endif//HGL_GRAPH_VULKAN_DESCRIPTOR_SETS_LAYOUT_INCLUDE diff --git a/inc/hgl/graph/VKDevice.h b/inc/hgl/graph/VKDevice.h new file mode 100644 index 00000000..b74822fa --- /dev/null +++ b/inc/hgl/graph/VKDevice.h @@ -0,0 +1,267 @@ +#ifndef HGL_GRAPH_VULKAN_DEVICE_INCLUDE +#define HGL_GRAPH_VULKAN_DEVICE_INCLUDE + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace hgl +{ + namespace graph + { + class TileData; + class TileFont; + class FontSource; + }//namespace graph +}//namespace hgl + +VK_NAMESPACE_BEGIN +/* + * GPU设备创建信息 + */ +struct GPUDeviceCreateInfo +{ + VkPhysicalDeviceType device_type =VK_PHYSICAL_DEVICE_TYPE_MAX_ENUM; + + uint32_t swapchain_image_count =0; + VkSurfaceFormatKHR color_format ={PF_A2BGR10UN,VK_COLOR_SPACE_SRGB_NONLINEAR_KHR}; + VkFormat depth_format =VK_FORMAT_UNDEFINED; +};//struct GPUDeviceCreateInfo + +class GPUDevice +{ + GPUDeviceAttribute *attr; + + GPUQueue *texture_queue; + TextureCmdBuffer *texture_cmd_buf; + +private: + + DeviceRenderPassManage *render_pass_manage; + RenderPass *device_render_pass; + + SwapchainRenderTarget *swapchainRT; + + SwapchainRenderTarget *CreateSwapchainRenderTarget(); + + void InitRenderPassManage(); + void ClearRenderPassManage(); + +private: + + VkCommandBuffer CreateCommandBuffer(); + + bool CreateSwapchainFBO(Swapchain *); + + Swapchain *CreateSwapchain(const VkExtent2D &acquire_extent); + +private: + + friend GPUDevice *CreateRenderDevice(VulkanInstance *inst,const GPUPhysicalDevice *physical_device,VkSurfaceKHR surface,const VkExtent2D &extent); + + GPUDevice(GPUDeviceAttribute *da); + +public: + + virtual ~GPUDevice(); + + operator VkDevice () {return attr->device;} + GPUDeviceAttribute *GetDeviceAttribute () {return attr;} + + VkSurfaceKHR GetSurface () {return attr->surface;} + VkDevice GetDevice ()const {return attr->device;} + const GPUPhysicalDevice * GetPhysicalDevice ()const {return attr->physical_device;} + + VkDescriptorPool GetDescriptorPool () {return attr->desc_pool;} + VkPipelineCache GetPipelineCache () {return attr->pipeline_cache;} + + const VkFormat GetSurfaceFormat ()const {return attr->surface_format.format;} + const VkColorSpaceKHR GetColorSpace ()const {return attr->surface_format.colorSpace;} + VkQueue GetGraphicsQueue () {return attr->graphics_queue;} + + RenderPass * GetRenderPass () {return device_render_pass;} + + SwapchainRenderTarget * GetSwapchainRT () {return swapchainRT;} + + const VkExtent2D & GetSwapchainSize ()const {return swapchainRT->GetExtent();} + +public: + + bool Resize (const VkExtent2D &); + bool Resize (const uint32_t &w,const uint32_t &h) + { + VkExtent2D extent={w,h}; + + return Resize(extent); + } + +public: //内存相关 + + GPUMemory *CreateMemory(const VkMemoryRequirements &,const uint32_t properties); + GPUMemory *CreateMemory(VkImage,const uint32 flag=VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); + +private: //Buffer相关 + + bool CreateBuffer(GPUBufferData *buf,VkBufferUsageFlags buf_usage,VkDeviceSize range,VkDeviceSize size,const void *data,SharingMode sharing_mode); + bool CreateBuffer(GPUBufferData *buf,VkBufferUsageFlags buf_usage, VkDeviceSize size,const void *data,SharingMode sharing_mode){return CreateBuffer(buf,buf_usage,size,size,data,sharing_mode);} + +public: //Buffer相关 + + GPUBuffer * CreateBuffer(VkBufferUsageFlags buf_usage,VkDeviceSize range,VkDeviceSize size,const void *data, SharingMode sm=SharingMode::Exclusive); + GPUBuffer * CreateBuffer(VkBufferUsageFlags buf_usage,VkDeviceSize range,VkDeviceSize size, SharingMode sm=SharingMode::Exclusive){return CreateBuffer(buf_usage,range,size,nullptr,sm);} + + GPUBuffer * CreateBuffer(VkBufferUsageFlags buf_usage, VkDeviceSize size,const void *data, SharingMode sm=SharingMode::Exclusive){return CreateBuffer(buf_usage,size,size,data,sm);} + GPUBuffer * CreateBuffer(VkBufferUsageFlags buf_usage, VkDeviceSize size, SharingMode sm=SharingMode::Exclusive){return CreateBuffer(buf_usage,size,size,nullptr,sm);} + + VBO * CreateVBO (VkFormat format, uint32_t count,const void *data, SharingMode sm=SharingMode::Exclusive); + VBO * CreateVBO (VkFormat format, uint32_t count, SharingMode sm=SharingMode::Exclusive){return CreateVBO(format,count,nullptr,sm);} + VBO * CreateVBO (const VAD *vad, SharingMode sm=SharingMode::Exclusive){return CreateVBO(vad->GetVulkanFormat(),vad->GetCount(),vad->GetData(),sm);} + + IndexBuffer * CreateIBO (IndexType type, uint32_t count,const void * data, SharingMode sm=SharingMode::Exclusive); + IndexBuffer * CreateIBO16 ( uint32_t count,const uint16 *data, SharingMode sm=SharingMode::Exclusive){return CreateIBO(IndexType::U16, count,(void *)data,sm);} + IndexBuffer * CreateIBO32 ( uint32_t count,const uint32 *data, SharingMode sm=SharingMode::Exclusive){return CreateIBO(IndexType::U32, count,(void *)data,sm);} + + IndexBuffer * CreateIBO (IndexType type, uint32_t count, SharingMode sm=SharingMode::Exclusive){return CreateIBO(type, count,nullptr,sm);} + IndexBuffer * CreateIBO16 ( uint32_t count, SharingMode sm=SharingMode::Exclusive){return CreateIBO(IndexType::U16, count,nullptr,sm);} + IndexBuffer * CreateIBO32 ( uint32_t count, SharingMode sm=SharingMode::Exclusive){return CreateIBO(IndexType::U32, count,nullptr,sm);} + + const VkDeviceSize GetUBOAlign(); + +#define CREATE_BUFFER_OBJECT(LargeName,type) GPUBuffer *Create##LargeName( VkDeviceSize size,void *data, SharingMode sm=SharingMode::Exclusive) {return CreateBuffer(VK_BUFFER_USAGE_##type##_BUFFER_BIT,size ,size,data, sm);} \ + GPUBuffer *Create##LargeName( VkDeviceSize size, SharingMode sm=SharingMode::Exclusive) {return CreateBuffer(VK_BUFFER_USAGE_##type##_BUFFER_BIT,size ,size,nullptr, sm);} \ + GPUBuffer *Create##LargeName(VkDeviceSize range,VkDeviceSize size,void *data, SharingMode sm=SharingMode::Exclusive) {return CreateBuffer(VK_BUFFER_USAGE_##type##_BUFFER_BIT,range,size,data, sm);} \ + GPUBuffer *Create##LargeName(VkDeviceSize range,VkDeviceSize size, SharingMode sm=SharingMode::Exclusive) {return CreateBuffer(VK_BUFFER_USAGE_##type##_BUFFER_BIT,range,size,nullptr, sm);} + + CREATE_BUFFER_OBJECT(UBO,UNIFORM) + CREATE_BUFFER_OBJECT(SSBO,STORAGE) + CREATE_BUFFER_OBJECT(INBO,INDIRECT) + +#undef CREATE_BUFFER_OBJECT + +public: //Image + + VkImage CreateImage (VkImageCreateInfo *); + void DestroyImage (VkImage); + +private: //texture + + bool CommitTexture (Texture *,GPUBuffer *buf,const VkBufferImageCopy *,const int count,const uint32_t layer_count,VkPipelineStageFlags);//=VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT); + + bool CommitTexture2D (Texture2D *,GPUBuffer *buf,VkPipelineStageFlags stage); + bool CommitTexture2DMipmaps (Texture2D *,GPUBuffer *buf,const VkExtent3D &,uint32_t); + + bool CommitTextureCube (TextureCube *,GPUBuffer *buf,const uint32_t mipmaps_zero_bytes,VkPipelineStageFlags stage); + bool CommitTextureCubeMipmaps (TextureCube *,GPUBuffer *buf,const VkExtent3D &,uint32_t); + + bool SubmitTexture (const VkCommandBuffer *cmd_bufs,const uint32_t count=1); ///<提交纹理处理到队列 + +public: //Texture + + bool CheckFormatSupport(const VkFormat,const uint32_t bits,ImageTiling tiling=ImageTiling::Optimal)const; + + bool CheckTextureFormatSupport(const VkFormat fmt,ImageTiling tiling=ImageTiling::Optimal)const{return CheckFormatSupport(fmt,VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT,tiling);} + + Texture2D *CreateTexture2D(TextureData *); + Texture2D *CreateTexture2D(TextureCreateInfo *ci); + + TextureCube *CreateTextureCube(TextureData *); + TextureCube *CreateTextureCube(TextureCreateInfo *ci); + + void Clear(TextureCreateInfo *); + + bool ChangeTexture2D(Texture2D *,GPUBuffer *buf,const List &, VkPipelineStageFlags=VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT); + bool ChangeTexture2D(Texture2D *,GPUBuffer *buf,uint32_t left,uint32_t top,uint32_t width,uint32_t height, VkPipelineStageFlags=VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT); + bool ChangeTexture2D(Texture2D *,void *data, uint32_t left,uint32_t top,uint32_t width,uint32_t height,uint32_t size,VkPipelineStageFlags=VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT); + + template + bool ChangeTexture2D(Texture2D *tex,GPUBuffer *buf,const RectScope2 &rs) + { + return ChangeTexture2D( tex, + buf, + rs.GetLeft(), + rs.GetTop(), + rs.GetWidth(), + rs.GetHeight()); + } + + template + bool ChangeTexture2D(Texture2D *tex,void *data,const RectScope2 &rs,uint32_t size) + { + return ChangeTexture2D( tex, + data, + rs.GetLeft(), + rs.GetTop(), + rs.GetWidth(), + rs.GetHeight(), + size); + } + +public: // + + Sampler *CreateSampler(VkSamplerCreateInfo *sci=nullptr); + Sampler *CreateSampler(Texture *); + +public: //shader & material + + PipelineLayoutData *CreatePipelineLayoutData(const MaterialDescriptorSets *); + void Destroy(PipelineLayoutData *); + + DescriptorSets * CreateDescriptorSets(const PipelineLayoutData *,const DescriptorSetsType &type)const; + MaterialParameters *CreateMP(const MaterialDescriptorSets *,const PipelineLayoutData *,const DescriptorSetsType &); + MaterialParameters *CreateMP(Material *,const DescriptorSetsType &); + + ShaderModule *CreateShaderModule(ShaderResource *); + + Material *CreateMaterial(const UTF8String &mtl_name,ShaderModuleMap *shader_maps,MaterialDescriptorSets *); + Material *CreateMaterial(const UTF8String &mtl_name,const VertexShaderModule *vertex_shader_module,const ShaderModule *fragment_shader_module,MaterialDescriptorSets *); + Material *CreateMaterial(const UTF8String &mtl_name,const VertexShaderModule *vertex_shader_module,const ShaderModule *geometry_shader_module,const ShaderModule *fragment_shader_module,MaterialDescriptorSets *); + + MaterialInstance *CreateMI(Material *,const VABConfigInfo *vab_cfg=nullptr); + +public: //Command Buffer 相关 + + RenderCmdBuffer * CreateRenderCommandBuffer(); + TextureCmdBuffer *CreateTextureCommandBuffer(); + +public: + + RenderPass * AcquireRenderPass( const RenderbufferInfo *,const uint subpass_count=2); + + GPUFence * CreateFence(bool); + GPUSemaphore * CreateGPUSemaphore(); + + GPUQueue * CreateQueue(const uint32_t fence_count=1,const bool create_signaled=false); + +public: //FrameBuffer相关 + + Framebuffer *CreateFramebuffer(RenderPass *rp,ImageView **color_list,const uint color_count,ImageView *depth); +// Framebuffer *CreateFramebuffer(RenderPass *,List &color,ImageView *depth); + Framebuffer *CreateFramebuffer(RenderPass *,ImageView *color,ImageView *depth); + Framebuffer *CreateFramebuffer(RenderPass *,ImageView *); + +public: + + RenderTarget *CreateRenderTarget( const FramebufferInfo *fbi,RenderPass *,const uint32_t fence_count=1); + RenderTarget *CreateRenderTarget( const FramebufferInfo *fbi,const uint32_t fence_count=1); + +public: + + TileData *CreateTileData(const VkFormat video_format,const uint width,const uint height,const uint count); ///<创建一个Tile数据集 + + TileFont *CreateTileFont(FontSource *fs,int limit_count=-1); ///<创建一个Tile字体 +};//class GPUDevice + +GPUDevice *CreateRenderDevice(VulkanInstance *inst,Window *win,const GPUPhysicalDevice *physical_device=nullptr); +VK_NAMESPACE_END +#endif//HGL_GRAPH_VULKAN_DEVICE_INCLUDE diff --git a/inc/hgl/graph/vulkan/VKDeviceAttribute.h b/inc/hgl/graph/VKDeviceAttribute.h similarity index 52% rename from inc/hgl/graph/vulkan/VKDeviceAttribute.h rename to inc/hgl/graph/VKDeviceAttribute.h index e323c113..275fab31 100644 --- a/inc/hgl/graph/vulkan/VKDeviceAttribute.h +++ b/inc/hgl/graph/VKDeviceAttribute.h @@ -1,15 +1,22 @@ #pragma once -#include +#include +#include + +#ifdef _DEBUG +#include +#endif//_DEBUG VK_NAMESPACE_BEGIN constexpr uint32_t ERROR_FAMILY_INDEX=UINT32_MAX; -struct DeviceAttribute +struct GPUDeviceAttribute { - VkInstance instance =VK_NULL_HANDLE; - const PhysicalDevice * physical_device =nullptr; + VulkanInstance * instance =nullptr; + const GPUPhysicalDevice * physical_device =nullptr; + + VkPhysicalDeviceDriverPropertiesKHR driver_properties; VkSurfaceKHR surface =VK_NULL_HANDLE; VkSurfaceCapabilitiesKHR surface_caps; @@ -23,8 +30,8 @@ struct DeviceAttribute List family_properties; List supports_present; - List surface_formts; - VkFormat format; + List surface_formats_list; + VkSurfaceFormatKHR surface_format; List present_modes; VkSurfaceTransformFlagBitsKHR preTransform; @@ -36,14 +43,32 @@ struct DeviceAttribute VkDescriptorPool desc_pool =VK_NULL_HANDLE; VkPipelineCache pipeline_cache =VK_NULL_HANDLE; + +#ifdef _DEBUG + DebugMaker * debug_maker =nullptr; +#endif//_DEBUG public: - DeviceAttribute(VkInstance inst,const PhysicalDevice *pd,VkSurfaceKHR s); - ~DeviceAttribute(); + GPUDeviceAttribute(VulkanInstance *inst,const GPUPhysicalDevice *pd,VkSurfaceKHR s); + ~GPUDeviceAttribute(); - bool CheckMemoryType(uint32_t typeBits,VkMemoryPropertyFlags properties,uint32_t *typeIndex) const; + int GetMemoryType(uint32_t typeBits,VkMemoryPropertyFlags properties) const; - void Refresh(); -};//class DeviceAttribute + void RefreshSurfaceCaps(); + +private: + + void GetSurfaceFormatList(); + void GetSurfacePresentMode(); + void GetQueueFamily(); + +public: + + template + T *GetDeviceProc(const char *name) + { + return instance->GetDeviceProc(device,name); + } +};//class GPUDeviceAttribute VK_NAMESPACE_END diff --git a/inc/hgl/graph/VKDeviceRenderPassManage.h b/inc/hgl/graph/VKDeviceRenderPassManage.h new file mode 100644 index 00000000..11f3fbb6 --- /dev/null +++ b/inc/hgl/graph/VKDeviceRenderPassManage.h @@ -0,0 +1,37 @@ +#ifndef HGL_VULKAN_DEVICE_RENDERPASS_MANAGE_INCLUDE +#define HGL_VULKAN_DEVICE_RENDERPASS_MANAGE_INCLUDE + +#include +#include +#include + +VK_NAMESPACE_BEGIN +using RenderPassHASHCode=util::HashCodeSHA1LE; + +class DeviceRenderPassManage +{ + VkDevice device; + VkPipelineCache pipeline_cache; + + util::Hash *hash; + + Map RenderPassList; + +private: + + friend class GPUDevice; + + DeviceRenderPassManage(VkDevice,VkPipelineCache); + ~DeviceRenderPassManage(); + +private: + + RenderPass * CreateRenderPass( const List &desc_list, + const List &subpass, + const List &dependency, + const RenderbufferInfo *); + + RenderPass * AcquireRenderPass( const RenderbufferInfo *,const uint subpass_count=2); +};//class DeviceRenderPassManage +VK_NAMESPACE_END +#endif//HGL_VULKAN_DEVICE_RENDERPASS_MANAGE_INCLUDE diff --git a/inc/hgl/graph/vulkan/VKFence.h b/inc/hgl/graph/VKFence.h similarity index 68% rename from inc/hgl/graph/vulkan/VKFence.h rename to inc/hgl/graph/VKFence.h index a15165ea..088bf7ca 100644 --- a/inc/hgl/graph/vulkan/VKFence.h +++ b/inc/hgl/graph/VKFence.h @@ -1,18 +1,18 @@ #ifndef HGL_VULKAN_GRAPH_FENCE_INCLUDE #define HGL_VULKAN_GRAPH_FENCE_INCLUDE -#include +#include VK_NAMESPACE_BEGIN -class Fence +class GPUFence { VkDevice device; VkFence fence; private: - friend class Device; + friend class GPUDevice; - Fence(VkDevice d,VkFence f) + GPUFence(VkDevice d,VkFence f) { device=d; fence=f; @@ -20,9 +20,9 @@ private: public: - ~Fence(); + ~GPUFence(); operator VkFence(){return fence;} -};//class Fence +};//class GPUFence VK_NAMESPACE_END #endif//HGL_VULKAN_GRAPH_FENCE_INCLUDE diff --git a/inc/hgl/graph/VKFramebuffer.h b/inc/hgl/graph/VKFramebuffer.h new file mode 100644 index 00000000..2e2c2b8f --- /dev/null +++ b/inc/hgl/graph/VKFramebuffer.h @@ -0,0 +1,39 @@ +#ifndef HGL_GRAPH_VULKAN_FRAMEBUFFER_INCLUDE +#define HGL_GRAPH_VULKAN_FRAMEBUFFER_INCLUDE + +#include +VK_NAMESPACE_BEGIN +class Framebuffer +{ + VkDevice device; + VkFramebuffer frame_buffer; + VkRenderPass render_pass; + + VkExtent2D extent; + uint32_t attachment_count; + uint32_t color_count; + bool has_depth; + +private: + + friend class GPUDevice; + + Framebuffer(VkDevice,VkFramebuffer,const VkExtent2D &,VkRenderPass,uint32_t color_count,bool depth); + +public: + + ~Framebuffer(); + + operator VkFramebuffer(){return frame_buffer;} + + const VkFramebuffer GetFramebuffer ()const{return frame_buffer;} + const VkRenderPass GetRenderPass ()const{return render_pass;} + + const VkExtent2D & GetExtent ()const{return extent;} + + const uint32_t GetAttachmentCount ()const{return attachment_count;} ///<获取渲染目标成分数量 + const uint32_t GetColorCount ()const{return color_count;} ///<取得颜色成分数量 + const bool HasDepth ()const{return has_depth;} ///<是否包含深度成分 +};//class Framebuffer +VK_NAMESPACE_END +#endif//HGL_GRAPH_VULKAN_FRAMEBUFFER_INCLUDE diff --git a/inc/hgl/graph/VKImageView.h b/inc/hgl/graph/VKImageView.h new file mode 100644 index 00000000..55c11fdc --- /dev/null +++ b/inc/hgl/graph/VKImageView.h @@ -0,0 +1,65 @@ +#ifndef HGL_GRAPH_VULKAN_IMAGE_VIEW_INCLUDE +#define HGL_GRAPH_VULKAN_IMAGE_VIEW_INCLUDE + +#include +VK_NAMESPACE_BEGIN +class ImageView +{ +protected: + + VkDevice device; + VkImageView image_view; + ImageViewCreateInfo *ivci; + + VkExtent3D extent; + +private: + + friend ImageView *CreateImageView(VkDevice device,VkImageViewType type,VkFormat format,const VkExtent3D &ext,const uint32_t &miplevel,VkImageAspectFlags aspectMask,VkImage img); + + ImageView(VkDevice dev,VkImageView iv,ImageViewCreateInfo *ci,const VkExtent3D &ext) + { + device =dev; + image_view =iv; + ivci =ci; + extent =ext; + } + +public: + + virtual ~ImageView(); + + operator VkImageView(){return image_view;} + +public: + + const VkImageViewType GetViewType ()const{return ivci->viewType;} + const VkFormat GetFormat ()const{return ivci->format;} + const VkExtent3D & GetExtent ()const{return extent;} + const VkImageAspectFlags GetAspectFlags ()const{return ivci->subresourceRange.aspectMask;} + const uint32_t GetLayerCount ()const{return ivci->subresourceRange.layerCount;} + + const bool hasColor ()const{return ivci->subresourceRange.aspectMask&VK_IMAGE_ASPECT_COLOR_BIT;} + const bool hasDepth ()const{return ivci->subresourceRange.aspectMask&VK_IMAGE_ASPECT_DEPTH_BIT;} + const bool hasStencil ()const{return ivci->subresourceRange.aspectMask&VK_IMAGE_ASPECT_STENCIL_BIT;} + const bool hasDepthStencil ()const{return ivci->subresourceRange.aspectMask&(VK_IMAGE_ASPECT_DEPTH_BIT|VK_IMAGE_ASPECT_STENCIL_BIT);} +};//class ImageView + +ImageView *CreateImageView(VkDevice device,VkImageViewType type,VkFormat format,const VkExtent3D &ext,const uint32_t &miplevel,VkImageAspectFlags aspectMask,VkImage img); + +#define CREATE_IMAGE_VIEW(short_name,larget_name) \ + inline ImageView *CreateImageView##short_name(VkDevice device,VkFormat format,const VkExtent3D &ext,const uint32_t &miplevel,VkImageAspectFlags aspectMask,VkImage img=VK_NULL_HANDLE) \ + { \ + return CreateImageView(device,VK_IMAGE_VIEW_TYPE_##larget_name,format,ext,miplevel,aspectMask,img); \ + } + + CREATE_IMAGE_VIEW(1D,1D); + CREATE_IMAGE_VIEW(2D,2D); + CREATE_IMAGE_VIEW(3D,3D); + CREATE_IMAGE_VIEW(Cube,CUBE); + CREATE_IMAGE_VIEW(1DArray,1D_ARRAY); + CREATE_IMAGE_VIEW(2DArray,2D_ARRAY); + CREATE_IMAGE_VIEW(CubeArray,CUBE_ARRAY); +#undef CREATE_IMAGE_VIEW +VK_NAMESPACE_END +#endif//HGL_GRAPH_VULKAN_IMAGE_VIEW_INCLUDE diff --git a/inc/hgl/graph/VKIndexBuffer.h b/inc/hgl/graph/VKIndexBuffer.h new file mode 100644 index 00000000..9dc375a4 --- /dev/null +++ b/inc/hgl/graph/VKIndexBuffer.h @@ -0,0 +1,34 @@ +#ifndef HGL_GRAPH_VULKAN_INDEX_BUFFER_INCLUDE +#define HGL_GRAPH_VULKAN_INDEX_BUFFER_INCLUDE + +#include + +namespace hgl +{ + namespace graph + { + class IndexBuffer:public GPUBuffer + { + IndexType index_type; + uint32_t count; + + private: + + friend class GPUDevice; + + IndexBuffer(VkDevice d,const GPUBufferData &vb,IndexType it,uint32_t _count):GPUBuffer(d,vb) + { + index_type=it; + count=_count; + } + + public: + + ~IndexBuffer()=default; + + const IndexType GetType ()const{return index_type;} + const uint32 GetCount()const{return count;} + };//class IndexBuffer:public GPUBuffer + }//namespace graph +}//namespace hgl +#endif//HGL_GRAPH_VULKAN_INDEX_BUFFER_INCLUDE diff --git a/inc/hgl/graph/VKInstance.h b/inc/hgl/graph/VKInstance.h new file mode 100644 index 00000000..5187d71d --- /dev/null +++ b/inc/hgl/graph/VKInstance.h @@ -0,0 +1,105 @@ +#ifndef HGL_GRAPH_VULKAN_INSTANCE_INCLUDE +#define HGL_GRAPH_VULKAN_INSTANCE_INCLUDE + +#include +#include +#include +#include +#include + +VK_NAMESPACE_BEGIN + #define VK_BOOL1BIT(name) bool name:1; + struct CreateInstanceLayerInfo + { + struct + { + VK_BOOL1BIT(api_dump) + VK_BOOL1BIT(device_simulation) + VK_BOOL1BIT(monitor) + VK_BOOL1BIT(screenshot) + VK_BOOL1BIT(standard_validation) + VK_BOOL1BIT(vktrace) + }lunarg; + + struct + { + VK_BOOL1BIT(validation) + }khronos; + + struct + { + VK_BOOL1BIT(optimus) + }nv; + + struct + { + VK_BOOL1BIT(steam_overlay) + VK_BOOL1BIT(steam_fossilize) + }valve; + + struct + { + VK_BOOL1BIT(Capture) + }RenderDoc; + + struct + { + VK_BOOL1BIT(helper); + }bandicam; + }; + #undef VK_BOOL1BIT + + class VulkanInstance + { + VkInstance inst; + + VKDebugOut *debug_out; + + ObjectList physical_devices; + + private: + + PFN_vkGetDeviceProcAddr GetDeviceProcAddr; + + private: + + friend VulkanInstance *CreateInstance(const AnsiString &app_name,VKDebugOut *out=nullptr,CreateInstanceLayerInfo *cili=nullptr); + + VulkanInstance(VkInstance,VKDebugOut *); + + public: + + virtual ~VulkanInstance(); + + operator VkInstance (){return inst;} + + const ObjectList &GetDeviceList ()const {return physical_devices;} + const GPUPhysicalDevice * GetDevice (VkPhysicalDeviceType)const; + + template + T *GetInstanceProc(const char *name) + { + return reinterpret_cast(vkGetInstanceProcAddr(inst,name)); + } + + template + T *GetDeviceProc(const char *name) + { + if(!GetDeviceProcAddr)return(nullptr); + + return reinterpret_cast(GetDeviceProcAddr(name)); + } + + void DestroySurface(VkSurfaceKHR); + };//class VulkanInstance + + void InitVulkanInstanceProperties(); + const List & GetInstanceLayerProperties(); + const List & GetInstanceExtensionProperties(); + const bool CheckInstanceLayerSupport(const AnsiString &); + const bool GetInstanceLayerVersion(const AnsiString &,uint32_t &spec,uint32_t &impl); + const bool CheckInstanceExtensionSupport(const AnsiString &); + + VulkanInstance *CreateInstance(const AnsiString &,VKDebugOut *,CreateInstanceLayerInfo *); ///<创建一个Vulkan实例 +VK_NAMESPACE_END +#endif//HGL_GRAPH_VULKAN_INSTANCE_INCLUDE diff --git a/inc/hgl/graph/VKLoadStoreOpInfo.h b/inc/hgl/graph/VKLoadStoreOpInfo.h new file mode 100644 index 00000000..59c531e3 --- /dev/null +++ b/inc/hgl/graph/VKLoadStoreOpInfo.h @@ -0,0 +1,12 @@ +#ifndef HGL_VULKAN_LOAD_STORE_OP_INFO_INCLUDE +#define HGL_VULKAN_LOAD_STORE_OP_INFO_INCLUDE + +#include +VK_NAMESPACE_BEGIN +struct LoadStoreInfo +{ + VkAttachmentLoadOp load_op = VK_ATTACHMENT_LOAD_OP_CLEAR; + VkAttachmentStoreOp store_op = VK_ATTACHMENT_STORE_OP_STORE; +}; +VK_NAMESPACE_END +#endif//HGL_VULKAN_LOAD_STORE_OP_INFO_INCLUDE diff --git a/inc/hgl/graph/VKMaterial.h b/inc/hgl/graph/VKMaterial.h new file mode 100644 index 00000000..4d04e78e --- /dev/null +++ b/inc/hgl/graph/VKMaterial.h @@ -0,0 +1,76 @@ +#ifndef HGL_GRAPH_VULKAN_MATERIAL_INCLUDE +#define HGL_GRAPH_VULKAN_MATERIAL_INCLUDE + +#include +#include +#include +#include +VK_NAMESPACE_BEGIN +using ShaderStageCreateInfoList=List; + +struct MaterialData +{ + UTF8String name; + + ShaderModuleMap *shader_maps; + MaterialDescriptorSets *mds; + + VertexShaderModule *vertex_sm; + + ShaderStageCreateInfoList shader_stage_list; + + PipelineLayoutData *pipeline_layout_data; + + struct + { + MaterialParameters *m,*g,*r; + }mp; + +private: + + friend class Material; + + ~MaterialData(); +};//struct MaterialData + +/** + * 材质类
+ * 用于管理shader,提供DescriptorSetLayoutCreater + */ +class Material +{ + MaterialData *data; + +private: + + friend GPUDevice; + + MaterialData *GetMaterialData(){return data;} + +public: + + Material(MaterialData *md):data(md){} + ~Material(); + + const UTF8String & GetName ()const{return data->name;} + + VertexShaderModule * GetVertexShaderModule () {return data->vertex_sm;} + + const ShaderStageCreateInfoList & GetStageList ()const{return data->shader_stage_list;} + + const MaterialDescriptorSets * GetDescriptorSets ()const{return data->mds;} + const VkPipelineLayout GetPipelineLayout ()const; + const PipelineLayoutData * GetPipelineLayoutData ()const{return data->pipeline_layout_data;} + +public: + + MaterialParameters * GetMP (const DescriptorSetsType &type) + { + if(type==DescriptorSetsType::Material )return data->mp.m;else + if(type==DescriptorSetsType::Renderable )return data->mp.r;else + if(type==DescriptorSetsType::Global )return data->mp.g;else + return(nullptr); + } +};//class Material +VK_NAMESPACE_END +#endif//HGL_GRAPH_VULKAN_MATERIAL_INCLUDE diff --git a/inc/hgl/graph/VKMaterialDescriptorSets.h b/inc/hgl/graph/VKMaterialDescriptorSets.h new file mode 100644 index 00000000..67e3506d --- /dev/null +++ b/inc/hgl/graph/VKMaterialDescriptorSets.h @@ -0,0 +1,55 @@ +#ifndef HGL_GRAPH_VULKAN_MATERIAL_DESCRIPTOR_SETS_INCLUDE +#define HGL_GRAPH_VULKAN_MATERIAL_DESCRIPTOR_SETS_INCLUDE + +#include + +VK_NAMESPACE_BEGIN + +struct ShaderDescriptor +{ + char name[128]; + + VkDescriptorType desc_type; + DescriptorSetsType set_type; + uint32_t set; + uint32_t binding; + uint32_t stage_flag; +}; + +using ShaderDescriptorList=List; + +class MaterialDescriptorSets +{ + UTF8String mtl_name; + + ShaderDescriptor *sd_list; + uint sd_count; + + ShaderDescriptorList descriptor_list[VK_DESCRIPTOR_TYPE_RANGE_SIZE]; + + Map sd_by_name; + Map binding_map[VK_DESCRIPTOR_TYPE_RANGE_SIZE]; + + int *binding_list[VK_DESCRIPTOR_TYPE_RANGE_SIZE]; + +private: + + DescriptorSetLayoutCreateInfo sds[size_t(DescriptorSetsType::RANGE_SIZE)]; + +public: + + MaterialDescriptorSets(const UTF8String &,ShaderDescriptor *,const uint); + ~MaterialDescriptorSets(); + + const UTF8String &GetMaterialName()const{return mtl_name;} + + const int GetBinding(const VkDescriptorType &desc_type,const AnsiString &name)const; + + const int GetUBO (const AnsiString &name,bool dynamic)const{return GetBinding(dynamic?VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,name);} + const int GetSSBO (const AnsiString &name,bool dynamic)const{return GetBinding(dynamic?VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,name);} + const int GetSampler (const AnsiString &name )const{return GetBinding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, name);} + + const DescriptorSetLayoutCreateInfo *GetBinding(const DescriptorSetsType &type)const{return sds+size_t(type);} +};//class MaterialDescriptorSets +VK_NAMESPACE_END +#endif//HGL_GRAPH_VULKAN_MATERIAL_DESCRIPTOR_SETS_INCLUDE diff --git a/inc/hgl/graph/VKMaterialInstance.h b/inc/hgl/graph/VKMaterialInstance.h new file mode 100644 index 00000000..b9483658 --- /dev/null +++ b/inc/hgl/graph/VKMaterialInstance.h @@ -0,0 +1,33 @@ +#ifndef HGL_GRAPH_VULKAN_MATERIAL_INSTANCE_INCLUDE +#define HGL_GRAPH_VULKAN_MATERIAL_INSTANCE_INCLUDE + +#include + +VK_NAMESPACE_BEGIN +class MaterialInstance +{ + Material *material; + + VAB *vab; + + MaterialParameters *mp_value; + +private: + + friend class GPUDevice; + + MaterialInstance(Material *,VAB *,MaterialParameters *); + +public: + + virtual ~MaterialInstance(); + + Material *GetMaterial(){return material;} + + const VAB *GetVAB()const{return vab;} + MaterialParameters *GetMP(){return mp_value;} + MaterialParameters *GetMP(const DescriptorSetsType &type); +};//class MaterialInstance +VK_NAMESPACE_END +#endif//HGL_GRAPH_VULKAN_MATERIAL_INSTANCE_INCLUDE + \ No newline at end of file diff --git a/inc/hgl/graph/VKMaterialParameters.h b/inc/hgl/graph/VKMaterialParameters.h new file mode 100644 index 00000000..4893e5e2 --- /dev/null +++ b/inc/hgl/graph/VKMaterialParameters.h @@ -0,0 +1,52 @@ +#ifndef HGL_GRAPH_VULKAN_MATERIAL_PARAMETERS_INCLUDE +#define HGL_GRAPH_VULKAN_MATERIAL_PARAMETERS_INCLUDE + +#include +#include +#include +VK_NAMESPACE_BEGIN +class MaterialParameters +{ + const MaterialDescriptorSets *mds; + + DescriptorSetsType ds_type; + + DescriptorSets *descriptor_sets; + +private: + + friend class GPUDevice; + + MaterialParameters(const MaterialDescriptorSets *,const DescriptorSetsType &type,DescriptorSets *); + +public: + + const DescriptorSetsType GetType (){return ds_type;} + DescriptorSets * GetDescriptorSet (){return descriptor_sets;} + const VkDescriptorSet GetVkDescriptorSet ()const{return descriptor_sets->GetDescriptorSet();} + + const uint32_t GetCount ()const{return descriptor_sets->GetCount();} + const bool IsReady ()const{return descriptor_sets->IsReady();} + +public: + + #define MP_TYPE_IS(name) const bool is##name()const{return ds_type==DescriptorSetsType::name;} + MP_TYPE_IS(Material) +// MP_TYPE_IS(Texture) + MP_TYPE_IS(Value) + MP_TYPE_IS(Renderable) + MP_TYPE_IS(Global) + #undef MP_TYPE_IS + +public: + + virtual ~MaterialParameters(); + + bool BindUBO(const AnsiString &name,GPUBuffer *ubo,bool dynamic=false); + bool BindSSBO(const AnsiString &name,GPUBuffer *ubo,bool dynamic=false); + bool BindSampler(const AnsiString &name,Texture *tex,Sampler *sampler); + + void Update(); +};//class MaterialParameters +VK_NAMESPACE_END +#endif//HGL_GRAPH_VULKAN_MATERIAL_PARAMETERS_INCLUDE \ No newline at end of file diff --git a/inc/hgl/graph/vulkan/VKMemory.h b/inc/hgl/graph/VKMemory.h similarity index 74% rename from inc/hgl/graph/vulkan/VKMemory.h rename to inc/hgl/graph/VKMemory.h index e291e104..32399b91 100644 --- a/inc/hgl/graph/vulkan/VKMemory.h +++ b/inc/hgl/graph/VKMemory.h @@ -1,9 +1,9 @@ #ifndef HGL_GRAPH_VULKAN_MEMORY_INCLUDE #define HGL_GRAPH_VULKAN_MEMORY_INCLUDE -#include +#include VK_NAMESPACE_BEGIN -class Memory +class GPUMemory { VkDevice device; VkDeviceMemory memory; @@ -11,22 +11,17 @@ class Memory uint32_t index; uint32_t properties; + VkMappedMemoryRange memory_range; + private: - friend class Device; + friend class GPUDevice; - Memory(VkDevice dev,VkDeviceMemory dm,const VkMemoryRequirements &mr,const uint32 i,const uint32_t p) - { - device=dev; - memory=dm; - req=mr; - index=i; - properties=p; - } + GPUMemory(VkDevice dev,VkDeviceMemory dm,const VkMemoryRequirements &mr,const uint32 i,const uint32_t p); public: - virtual ~Memory(); + virtual ~GPUMemory(); operator VkDeviceMemory(){return memory;} @@ -34,7 +29,7 @@ public: const uint32_t GetType ()const{return req.memoryTypeBits;} const VkDeviceSize GetSize ()const{return req.size;} - const VkDeviceSize GetAligment ()const{return req.alignment;} + const VkDeviceSize GetAlignment ()const{return req.alignment;} const uint32_t GetTypeIndex ()const{return index;} const uint32_t GetProperties ()const{return properties;} @@ -48,6 +43,9 @@ public: bool BindBuffer (VkBuffer buffer); bool BindImage (VkImage image); -};//class Memory + + void Flush (VkDeviceSize,VkDeviceSize); + void Flush (VkDeviceSize size){Flush(0,size);} +};//class GPUMemory VK_NAMESPACE_END #endif//HGL_GRAPH_VULKAN_MEMORY_INCLUDE diff --git a/inc/hgl/graph/VKMemoryAllocator.h b/inc/hgl/graph/VKMemoryAllocator.h new file mode 100644 index 00000000..23918f48 --- /dev/null +++ b/inc/hgl/graph/VKMemoryAllocator.h @@ -0,0 +1,40 @@ +#ifndef HGL_GRAPH_VULKAN_MEMORY_ALLOCATOR_INCLUDE +#define HGL_GRAPH_VULKAN_MEMORY_ALLOCATOR_INCLUDE + +#include +#include + +VK_NAMESPACE_BEGIN +class VKMemoryAllocator:public AbstractMemoryAllocator +{ + GPUDevice *device; + + uint32_t buffer_usage_flag_bits; + + GPUBuffer *gpu_buffer; + + VkDeviceSize range; //ubo之类需要一个一次访问范围 + +protected: + + bool AllocMemory() override; + +public: + + const bool CanRealloc ()const override{return false;} + + const uint32_t GetBufferUsageFlagBits ()const{return buffer_usage_flag_bits;} + + GPUBuffer * GetBuffer (){return gpu_buffer;} + +public: + + VKMemoryAllocator(GPUDevice *,const uint32_t flags,const VkDeviceSize r); + ~VKMemoryAllocator(); + + void Free() override {/* DON'T RUN ANY OPERATION.*/} + + void Flush(const VkDeviceSize); +};//class VKMemoryAllocator:public AbstractMemoryAllocator +VK_NAMESPACE_END +#endif//HGL_GRAPH_VULKAN_MEMORY_ALLOCATOR_INCLUDE diff --git a/inc/hgl/graph/VKPhysicalDevice.h b/inc/hgl/graph/VKPhysicalDevice.h new file mode 100644 index 00000000..7b1c3206 --- /dev/null +++ b/inc/hgl/graph/VKPhysicalDevice.h @@ -0,0 +1,169 @@ +#pragma once + +#include +#include +#include + +VK_NAMESPACE_BEGIN +class GPUPhysicalDevice +{ + VkInstance instance=nullptr; + VkPhysicalDevice physical_device=nullptr; + + VkPhysicalDeviceFeatures features; + VkPhysicalDeviceVulkan11Features features11; + VkPhysicalDeviceVulkan12Features features12; + + VkPhysicalDeviceProperties properties; + VkPhysicalDeviceVulkan11Properties properties11; + VkPhysicalDeviceVulkan12Properties properties12; + + VkPhysicalDeviceMemoryProperties memory_properties; + List layer_properties; + List extension_properties; + List queue_family_properties; + +private: + + bool dynamic_state=false; + +public: + + GPUPhysicalDevice(VkInstance,VkPhysicalDevice); + ~GPUPhysicalDevice()=default; + + operator VkPhysicalDevice(){return physical_device;} + operator const VkPhysicalDevice()const{return physical_device;} + + const int GetMemoryType(uint32_t,VkMemoryPropertyFlags)const; + + VkPhysicalDeviceType GetDeviceType()const{return properties.deviceType;} + const char * GetDeviceName()const{return properties.deviceName;} + + const VkPhysicalDeviceFeatures & GetFeatures10 ()const{return features;} + const VkPhysicalDeviceVulkan11Features &GetFeatures11 ()const{return features11;} + const VkPhysicalDeviceVulkan12Features &GetFeatures12 ()const{return features12;} + + const VkPhysicalDeviceProperties & GetProperties ()const{return properties;} + const VkPhysicalDeviceMemoryProperties &GetMemoryProperties ()const{return memory_properties;} + const VkPhysicalDeviceLimits & GetLimits ()const{return properties.limits;} + + const bool GetLayerVersion(const AnsiString &,uint32_t &spec,uint32_t &impl)const; + const uint32_t GetExtensionVersion(const AnsiString &name)const; + const bool CheckExtensionSupport(const AnsiString &name)const; + +public: + + const uint32_t GetUBORange ()const{return properties.limits.maxUniformBufferRange;} + const VkDeviceSize GetUBOAlign ()const{return properties.limits.minUniformBufferOffsetAlignment;} + + const uint32_t GetSSBORange ()const{return properties.limits.maxStorageBufferRange;} + const VkDeviceSize GetSSBOAlign ()const{return properties.limits.minStorageBufferOffsetAlignment;} + + const uint32_t GetConstantSize ()const{return properties.limits.maxPushConstantsSize;} + +public: + + /** + * 获取该设备是否是显卡 + */ + const bool isGPU()const + { + if(properties.deviceType==VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU)return(true); + if(properties.deviceType==VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU)return(true); + if(properties.deviceType==VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU)return(true); + + return(false); + } + + const bool isDiscreteGPU ()const{return(properties.deviceType==VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU);} ///<是否是独立显卡 + const bool isIntegratedGPU ()const{return(properties.deviceType==VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU);} ///<是否是集成显卡 + const bool isVirtualGPU ()const{return(properties.deviceType==VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU);} ///<是否是虚拟显卡 + +public: + + VkFormatProperties GetFormatProperties(const VkFormat format)const + { + VkFormatProperties fp; + + hgl_zero(fp); + + vkGetPhysicalDeviceFormatProperties(physical_device,format,&fp); + + return fp; + } + + bool OptimalSupport (const VkFormat format,const VkFormatFeatureFlags flag)const{VkFormatProperties fp;vkGetPhysicalDeviceFormatProperties(physical_device,format,&fp);return fp.optimalTilingFeatures&flag;} + bool LinearSupport (const VkFormat format,const VkFormatFeatureFlags flag)const{VkFormatProperties fp;vkGetPhysicalDeviceFormatProperties(physical_device,format,&fp);return fp.linearTilingFeatures&flag;} + bool BufferSupport (const VkFormat format,const VkFormatFeatureFlags flag)const{VkFormatProperties fp;vkGetPhysicalDeviceFormatProperties(physical_device,format,&fp);return fp.bufferFeatures&flag;} + + bool IsColorAttachmentOptimal(const VkFormat format)const{return OptimalSupport(format,VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT);} + bool IsDepthAttachmentOptimal(const VkFormat format)const{return OptimalSupport(format,VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT);} + + bool IsColorAttachmentLinear(const VkFormat format)const{return LinearSupport(format,VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT);} + bool IsDepthAttachmentLinear(const VkFormat format)const{return LinearSupport(format,VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT);} + + bool IsColorAttachmentBuffer(const VkFormat format)const{return BufferSupport(format,VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT);} + bool IsDepthAttachmentBuffer(const VkFormat format)const{return BufferSupport(format,VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT);} + + VkFormat GetDepthFormat(bool lower_to_high=false)const; + VkFormat GetDepthStencilFormat(bool lower_to_high=false)const; + +public: + + const VkBool32 SupportGeometryShader ()const{return features.geometryShader;} + const VkBool32 SupportCubeMapArray ()const{return features.imageCubeArray;} + + + // support != open, so please don't direct use GetFeatures(). + // open any features in CreateDevice()&SetDeviceFeatures() functions. + const bool SupportMDI ()const + { + // I found a few device support MDI, but its MaxDrawIndirectCount is 1. + + return (features.multiDrawIndirect&&properties.limits.maxDrawIndirectCount>1); + } + + const uint32_t GetMaxMDICount ()const + { + return properties.limits.maxDrawIndirectCount; + } + + const uint32_t GetMaxImage1D ()const{return properties.limits.maxImageDimension1D;} + const uint32_t GetMaxImage2D ()const{return properties.limits.maxImageDimension2D;} + const uint32_t GetMaxImage3D ()const{return properties.limits.maxImageDimension3D;} + const uint32_t GetMaxImageCube ()const{return properties.limits.maxImageDimensionCube;} + const uint32_t GetMaxImageArrayLayers ()const{return properties.limits.maxImageArrayLayers;} + const uint32_t GetMaxUBORange ()const{return properties.limits.maxUniformBufferRange;} + const uint32_t GetMaxSSBORange ()const{return properties.limits.maxStorageBufferRange;} + const uint32_t GetMaxBoundDescriptorSets()const{return properties.limits.maxBoundDescriptorSets;} + + const uint32_t GetMaxVertexInputAttributes ()const{return properties.limits.maxVertexInputAttributes;} + const uint32_t GetMaxVertexInputBindings ()const{return properties.limits.maxVertexInputBindings;} + + const uint32_t GetMaxColorAttachments ()const{return properties.limits.maxColorAttachments;} + + const VkBool32 SupportSamplerAnisotropy ()const{return features.samplerAnisotropy;} + const float GetMaxSamplerAnisotropy ()const{return properties.limits.maxSamplerAnisotropy;} + const float GetMaxSamplerLodBias ()const{return properties.limits.maxSamplerLodBias;} + + const VkBool32 SupportYcbcrConversion ()const{return features11.samplerYcbcrConversion;} + const VkBool32 SupportClampMirrorToEdge ()const{return features12.samplerMirrorClampToEdge;} + + const void GetPointSize(float &granularity,float &min_size,float &max_size) const + { + granularity =properties.limits.pointSizeGranularity; + min_size =properties.limits.pointSizeRange[0]; + max_size =properties.limits.pointSizeRange[1]; + } + + const void GetLineWidth(float &granularity,float &min_width,float &max_width) const + { + granularity =properties.limits.lineWidthGranularity; + min_width =properties.limits.lineWidthRange[0]; + max_width =properties.limits.lineWidthRange[1]; + } + + const bool SupportDynamicState() const {return dynamic_state;} +};//class GPUPhysicalDevice +VK_NAMESPACE_END diff --git a/inc/hgl/graph/VKPipeline.h b/inc/hgl/graph/VKPipeline.h new file mode 100644 index 00000000..e852b6c7 --- /dev/null +++ b/inc/hgl/graph/VKPipeline.h @@ -0,0 +1,43 @@ +#ifndef HGL_GRAPH_VULKAN_PIPELINE_INCLUDE +#define HGL_GRAPH_VULKAN_PIPELINE_INCLUDE + +#include +#include +#include +#include +VK_NAMESPACE_BEGIN +class Pipeline +{ + VkDevice device; + VkPipeline pipeline; + PipelineData *data; + + bool alpha_test; + bool alpha_blend; + +private: + + friend class RenderPass; + + Pipeline(VkDevice dev,VkPipeline p,PipelineData *pd) + { + device=dev; + pipeline=p; + data=pd; + + alpha_test=false; + alpha_blend=false; + } + +public: + + virtual ~Pipeline(); + + operator VkPipeline(){return pipeline;} + + const bool IsAlphaTest()const{return data->alpha_test>0;} + const bool IsAlphaBlend()const{return data->alpha_blend;} +};//class GraphicsPipeline +VK_NAMESPACE_END +#endif//HGL_GRAPH_VULKAN_PIPELINE_INCLUDE + \ No newline at end of file diff --git a/inc/hgl/graph/VKQueue.h b/inc/hgl/graph/VKQueue.h new file mode 100644 index 00000000..c2f2238c --- /dev/null +++ b/inc/hgl/graph/VKQueue.h @@ -0,0 +1,38 @@ +#ifndef HGL_GRAPH_VULKAN_SUBMIT_QUEUE_INCLUDE +#define HGL_GRAPH_VULKAN_SUBMIT_QUEUE_INCLUDE + +#include +#include +VK_NAMESPACE_BEGIN +class GPUQueue +{ +protected: + + VkDevice device; + VkQueue queue; + + uint32_t current_fence; + GPUFence **fence_list; + uint32_t fence_count; + + SubmitInfo submit_info; + +private: + + friend class GPUDevice; + + GPUQueue(VkDevice dev,VkQueue q,GPUFence **,const uint32_t fc); + +public: + + virtual ~GPUQueue(); + + VkResult Present(const VkPresentInfoKHR *pi){return vkQueuePresentKHR(queue,pi);} + + bool WaitQueue(); + bool WaitFence(const bool wait_all=true,const uint64_t time_out=HGL_NANO_SEC_PER_SEC); + bool Submit(const VkCommandBuffer &cmd_buf,GPUSemaphore *wait_sem,GPUSemaphore *complete_sem); + bool Submit(const VkCommandBuffer *cmd_buf,const uint32_t count,GPUSemaphore *wait_sem,GPUSemaphore *complete_sem); +};//class SumbitQueue +VK_NAMESPACE_END +#endif//HGL_GRAPH_VULKAN_SUBMIT_QUEUE_INCLUDE diff --git a/inc/hgl/graph/VKRenderContext.h b/inc/hgl/graph/VKRenderContext.h new file mode 100644 index 00000000..d417d9f7 --- /dev/null +++ b/inc/hgl/graph/VKRenderContext.h @@ -0,0 +1,36 @@ +#ifndef HGL_VULKAN_RENDER_CONTEXT_INCLUDE +#define HGL_VULKAN_RENDER_CONTEXT_INCLUDE + +#include +#include +VK_NAMESPACE_BEGIN +/** + * Ⱦ + */ +class RenderContext +{ +protected: + + GPUDevice *device; + + VkExtent2D extent; + +public: + + RenderContext(GPUDevice *,const VkExtent2D &); + virtual ~RenderContext(); + + void Prepare( +};//class RenderContext + +class RenderContextSwapchain:public RenderContext +{ + Swapchain *swapchain; + +public: + + void RequestPresentMode(const VkPresentModeKHR present_mode); + void RequestImageFormat(const VkFormat format); +};//class RenderContextSwapchain:public RenderContext +VK_NAMESPACE_END +#endif//HGL_VULKAN_RENDER_CONTEXT_INCLUDE diff --git a/inc/hgl/graph/VKRenderPass.h b/inc/hgl/graph/VKRenderPass.h new file mode 100644 index 00000000..4bc48f4e --- /dev/null +++ b/inc/hgl/graph/VKRenderPass.h @@ -0,0 +1,67 @@ +#ifndef HGL_GRAPH_VULKAN_RENDER_PASS_INCLUDE +#define HGL_GRAPH_VULKAN_RENDER_PASS_INCLUDE + +#include +#include +#include +VK_NAMESPACE_BEGIN +/** + * RenderPass功能封装
+ * RenderPass在创建时,需要指定输入的color imageview与depth imageview象素格式, + * 在随后创建Framebuffer时,需要同时指定RenderPass与ColorImageView,DepthImageView,象素格式要一致。 + */ +class RenderPass +{ + VkDevice device; + VkPipelineCache pipeline_cache; + VkRenderPass render_pass; + + List color_formats; + VkFormat depth_format; + + VkExtent2D granularity; + +protected: + + ObjectList pipeline_list; + + Pipeline *CreatePipeline(Material *,PipelineData *,const VAB *); + +private: + + friend class DeviceRenderPassManage; + + RenderPass(VkDevice d,VkPipelineCache pc,VkRenderPass rp,const List &cf,VkFormat df); + +public: + + virtual ~RenderPass(); + + VkRenderPass GetVkRenderPass(){return render_pass;} + VkPipelineCache GetPipelineCache(){return pipeline_cache;} + + const uint GetColorCount()const{return color_formats.GetCount();} + const List & GetColorFormat()const{return color_formats;} + const VkFormat GetColorFormat(int index)const + { + if(index<0||index>=color_formats.GetCount())return VK_FORMAT_UNDEFINED; + + return color_formats.GetData()[index]; + } + const VkFormat GetDepthFormat()const{return depth_format;} + + const VkExtent2D & GetGranularity()const{return granularity;} + +public: + + Pipeline *CreatePipeline(MaterialInstance *, const PipelineData *); + Pipeline *CreatePipeline(MaterialInstance *, const InlinePipeline &); + +public: + + Pipeline *CreatePipeline(MaterialInstance *, const InlinePipeline &, const Prim &prim,const bool prim_restart=false); + Pipeline *CreatePipeline(MaterialInstance *, const PipelineData *, const Prim &prim,const bool prim_restart=false); + Pipeline *CreatePipeline(MaterialInstance *, const OSString &, const Prim &prim,const bool prim_restart=false); +};//class RenderPass +VK_NAMESPACE_END +#endif//HGL_GRAPH_VULKAN_RENDER_PASS_INCLUDE diff --git a/inc/hgl/graph/vulkan/VKDatabase.h b/inc/hgl/graph/VKRenderResource.h similarity index 56% rename from inc/hgl/graph/vulkan/VKDatabase.h rename to inc/hgl/graph/VKRenderResource.h index 4d04477d..4b702bfb 100644 --- a/inc/hgl/graph/vulkan/VKDatabase.h +++ b/inc/hgl/graph/VKRenderResource.h @@ -1,22 +1,22 @@ #ifndef HGL_GRAPH_VULKAN_DATABASE_INCLUDE #define HGL_GRAPH_VULKAN_DATABASE_INCLUDE -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include -#include +#include #include #include VK_NAMESPACE_BEGIN using MaterialID =int; using MaterialInstanceID =int; -using PipelineID =int; using BufferID =int; using DescriptorSetsID =int; using RenderableID =int; @@ -29,45 +29,47 @@ class VertexAttribData; /** * 资源管理,用于管理场景内所需的所有数据 */ -class Database +class RenderResource { - Device *device; - + GPUDevice *device; + + MapObject shader_module_by_name; + Map material_by_name; + Map texture_by_name; + IDResManage rm_material; ///<材质合集 IDResManage rm_material_instance; ///<材质实例合集 - IDResManage rm_pipeline; ///<管线合集 IDResManage rm_desc_sets; ///<描述符合集 IDResManage rm_renderables; ///<可渲染对象合集 - IDResManage rm_buffers; ///<顶点缓冲区合集 + IDResManage rm_buffers; ///<顶点缓冲区合集 IDResManage rm_samplers; ///<采样器合集 IDResManage rm_textures; ///<纹理合集 IDResManage rm_renderable_instances; ///<渲染实例集合集 public: - Database(Device *dev):device(dev){} - virtual ~Database()=default; + RenderResource(GPUDevice *dev):device(dev){} + virtual ~RenderResource()=default; public: //Add MaterialID Add(Material * mtl ){return rm_material.Add(mtl);} MaterialInstanceID Add(MaterialInstance * mi ){return rm_material_instance.Add(mi);} - PipelineID Add(Pipeline * p ){return rm_pipeline.Add(p);} DescriptorSetsID Add(DescriptorSets * ds ){return rm_desc_sets.Add(ds);} RenderableID Add(Renderable * r ){return rm_renderables.Add(r);} - BufferID Add(Buffer * buf ){return rm_buffers.Add(buf);} + BufferID Add(GPUBuffer * buf ){return rm_buffers.Add(buf);} SamplerID Add(Sampler * s ){return rm_samplers.Add(s);} TextureID Add(Texture * t ){return rm_textures.Add(t);} RenderableInstanceID Add(RenderableInstance *ri ){return rm_renderable_instances.Add(ri);} -public: //Create +public: // VBO/VAO - VAB *CreateVAB(VkFormat format,uint32_t count,const void *data,SharingMode sm=SharingMode::Exclusive); - VAB *CreateVAB(VkFormat format,uint32_t count,SharingMode sm=SharingMode::Exclusive){return CreateVAB(format,count,nullptr,sm);} - VAB *CreateVAB(const VAD *vad,SharingMode sm=SharingMode::Exclusive){return CreateVAB(vad->GetVulkanFormat(),vad->GetCount(),vad->GetData(),sm);} + VBO *CreateVBO(VkFormat format,uint32_t count,const void *data,SharingMode sm=SharingMode::Exclusive); + VBO *CreateVBO(VkFormat format,uint32_t count,SharingMode sm=SharingMode::Exclusive){return CreateVBO(format,count,nullptr,sm);} + VBO *CreateVBO(const VAD *vad,SharingMode sm=SharingMode::Exclusive){return CreateVBO(vad->GetVulkanFormat(),vad->GetCount(),vad->GetData(),sm);} - #define SCENE_DB_CREATE_FUNC(name) Buffer *Create##name(VkDeviceSize size,void *data,SharingMode sm=SharingMode::Exclusive); \ - Buffer *Create##name(VkDeviceSize size,SharingMode sm=SharingMode::Exclusive); + #define SCENE_DB_CREATE_FUNC(name) GPUBuffer *Create##name(VkDeviceSize size,void *data,SharingMode sm=SharingMode::Exclusive); \ + GPUBuffer *Create##name(VkDeviceSize size,SharingMode sm=SharingMode::Exclusive); SCENE_DB_CREATE_FUNC(UBO) SCENE_DB_CREATE_FUNC(SSBO) @@ -75,33 +77,45 @@ public: //Create #undef SCENE_DB_CREATE_FUNC - IndexBuffer *CreateIBO(IndexType index_type,uint32_t count,const void *data,SharingMode sm=SharingMode::Exclusive); - IndexBuffer *CreateIBO16(uint32_t count,const uint16 *data,SharingMode sm=SharingMode::Exclusive){return CreateIBO(IndexType::U16,count,(void *)data,sm);} - IndexBuffer *CreateIBO32(uint32_t count,const uint32 *data,SharingMode sm=SharingMode::Exclusive){return CreateIBO(IndexType::U32,count,(void *)data,sm);} + IndexBuffer *CreateIBO(IndexType index_type,uint32_t count,const void * data, SharingMode sm=SharingMode::Exclusive); + IndexBuffer *CreateIBO16( uint32_t count,const uint16 *data, SharingMode sm=SharingMode::Exclusive){return CreateIBO(IndexType::U16,count,(void *)data,sm);} + IndexBuffer *CreateIBO32( uint32_t count,const uint32 *data, SharingMode sm=SharingMode::Exclusive){return CreateIBO(IndexType::U32,count,(void *)data,sm);} IndexBuffer *CreateIBO(IndexType index_type,uint32_t count,SharingMode sm=SharingMode::Exclusive){return CreateIBO(index_type,count,nullptr,sm);} - IndexBuffer *CreateIBO16(uint32_t count,SharingMode sm=SharingMode::Exclusive){return CreateIBO(IndexType::U16,count,nullptr,sm);} - IndexBuffer *CreateIBO32(uint32_t count,SharingMode sm=SharingMode::Exclusive){return CreateIBO(IndexType::U32,count,nullptr,sm);} + IndexBuffer *CreateIBO16( uint32_t count,SharingMode sm=SharingMode::Exclusive){return CreateIBO(IndexType::U16,count,nullptr,sm);} + IndexBuffer *CreateIBO32( uint32_t count,SharingMode sm=SharingMode::Exclusive){return CreateIBO(IndexType::U32,count,nullptr,sm);} - MaterialInstance * CreateMaterialInstance(Material *); - Renderable * CreateRenderable(Material *,const uint32_t vertex_count=0); +public: //Material + + const ShaderModule *CreateShaderModule(const OSString &filename,ShaderResource *shader_resource); + + Material * CreateMaterial(const OSString &); + MaterialInstance * CreateMaterialInstance(Material *,const VABConfigInfo *vab_cfg=nullptr); + MaterialInstance * CreateMaterialInstance(const OSString &,const VABConfigInfo *vab_cfg=nullptr); + + Renderable * CreateRenderable(const uint32_t vertex_count=0); TextRenderable * CreateTextRenderable(Material *); - RenderableInstance *CreateRenderableInstance(Pipeline *p,MaterialInstance *mi,Renderable *r); + RenderableInstance *CreateRenderableInstance(Renderable *r,MaterialInstance *mi,Pipeline *p); Sampler * CreateSampler(VkSamplerCreateInfo *sci=nullptr); + Sampler * CreateSampler(Texture *); + +public: //texture + + Texture2D * LoadTexture2D(const OSString &,bool auto_mipmaps=false); + TextureCube * LoadTextureCube(const OSString &,bool auto_mipmaps=false); public: //Get Material * GetMaterial (const MaterialID &id){return rm_material.Get(id);} MaterialInstance * GetMaterialInstance (const MaterialInstanceID &id){return rm_material_instance.Get(id);} - Pipeline * GetPipeline (const PipelineID &id){return rm_pipeline.Get(id);} DescriptorSets * GetDescSets (const DescriptorSetsID &id){return rm_desc_sets.Get(id);} Renderable * GetRenderable (const RenderableID &id){return rm_renderables.Get(id);} - Buffer * GetBuffer (const BufferID &id){return rm_buffers.Get(id);} + GPUBuffer * GetBuffer (const BufferID &id){return rm_buffers.Get(id);} Sampler * GetSampler (const SamplerID &id){return rm_samplers.Get(id);} Texture * GetTexture (const TextureID &id){return rm_textures.Get(id);} RenderableInstance *GetRenderableInstance (const RenderableInstanceID &id){return rm_renderable_instances.Get(id);} -};//class Database +};//class RenderResource VK_NAMESPACE_END #endif//HGL_GRAPH_VULKAN_DATABASE_INCLUDE diff --git a/inc/hgl/graph/VKRenderTarget.h b/inc/hgl/graph/VKRenderTarget.h new file mode 100644 index 00000000..580e620a --- /dev/null +++ b/inc/hgl/graph/VKRenderTarget.h @@ -0,0 +1,114 @@ +#ifndef HGL_GRAPH_VULKAN_RENDER_TARGET_INCLUDE +#define HGL_GRAPH_VULKAN_RENDER_TARGET_INCLUDE + +#include +#include +#include +#include +#include +#include +VK_NAMESPACE_BEGIN +/** + * 渲染目标 + */ +class RenderTarget +{ +protected: + + GPUQueue *queue; + + RenderPass *render_pass; + Framebuffer *fbo; + + VkExtent2D extent; + + GPUSemaphore *render_complete_semaphore =nullptr; + +protected: + + uint32_t color_count; + Texture2D **color_textures; + Texture2D *depth_texture; + +protected: + + friend class GPUDevice; + + RenderTarget(GPUQueue *,GPUSemaphore *); + RenderTarget(GPUQueue *,GPUSemaphore *,RenderPass *_rp,Framebuffer *_fb,Texture2D **color_texture_list,const uint32_t color_count,Texture2D *depth_texture); + +public: + + virtual ~RenderTarget(); + + const VkExtent2D & GetExtent ()const {return extent;} + virtual RenderPass * GetRenderPass () {return render_pass;} + virtual const VkRenderPass GetVkRenderPass ()const {return render_pass->GetVkRenderPass();} + virtual const uint32_t GetColorCount ()const {return fbo->GetColorCount();} + virtual Framebuffer * GetFramebuffer () {return fbo;} + + virtual Texture2D * GetColorTexture (const int index=0){return color_textures[index];} + virtual Texture2D * GetDepthTexture (){return depth_texture;} + +public: // command buffer + + GPUSemaphore * GetRenderCompleteSemaphore (){return render_complete_semaphore;} + virtual bool Submit (RenderCmdBuffer *,GPUSemaphore *present_complete_semaphore=nullptr); + + bool WaitQueue(){return queue->WaitQueue();} + bool WaitFence(){return queue->WaitFence();} +};//class RenderTarget + +/** + * 交换链专用渲染目标 + */ +class SwapchainRenderTarget:public RenderTarget +{ + VkDevice device; + Swapchain *swapchain; + PresentInfo present_info; + + GPUSemaphore *present_complete_semaphore=nullptr; + + uint32_t current_frame; + +public: + + SwapchainRenderTarget(VkDevice dev,Swapchain *sc,GPUQueue *q,GPUSemaphore *rcs,GPUSemaphore *pcs,RenderPass *rp); + ~SwapchainRenderTarget(); + + Framebuffer * GetFramebuffer ()override {return swapchain->render_frame[current_frame];} + Framebuffer * GetFramebuffer (const uint32_t index) {return swapchain->render_frame[index];} + + const uint32_t GetColorCount ()const override {return 1;} + const uint32_t GetImageCount ()const {return swapchain->color_count;} + + virtual Texture2D * GetColorTexture (const int index=0) override{return swapchain->sc_color[index];} + virtual Texture2D * GetDepthTexture () override{return swapchain->sc_depth;} + +public: + + const uint32_t GetCurrentFrameIndices ()const {return current_frame;} + GPUSemaphore * GetPresentCompleteSemaphore () {return present_complete_semaphore;} + +public: + + /** + * 请求下一帧画面的索引 + * @param present_complete_semaphore 推送完成信号 + */ + int AcquireNextImage(); + + /** + * 推送后台画面到前台 + * @param render_complete_semaphore 渲染完成信号 + */ + bool PresentBackbuffer(VkSemaphore *wait_semaphores,const uint32_t wait_semaphore_count); + + bool PresentBackbuffer(); + + bool Submit(VkCommandBuffer); + bool Submit(VkCommandBuffer,GPUSemaphore *); +};//class SwapchainRenderTarget:public RenderTarget +VK_NAMESPACE_END +#endif//HGL_GRAPH_VULKAN_RENDER_TARGET_INCLUDE diff --git a/inc/hgl/graph/VKRenderable.h b/inc/hgl/graph/VKRenderable.h new file mode 100644 index 00000000..79740354 --- /dev/null +++ b/inc/hgl/graph/VKRenderable.h @@ -0,0 +1,89 @@ +#ifndef HGL_GRAPH_VULKAN_RENDERABLE_INCLUDE +#define HGL_GRAPH_VULKAN_RENDERABLE_INCLUDE + +#include +#include +#include +#include +#include +VK_NAMESPACE_BEGIN +/** + * 可渲染数据对象
+ * 本对象包含材质实例信息和Mesh信息,可渲染数据对象中包含供最终API使用的VBO数据,可能存在多个MESH数据的集合。

+ * 比如有多种形状的石头,它们使用了同一种材质,这种情况下多个mesh就可以合并到一个Renderable中,渲染时不再切换VBO。 + */ +class Renderable +{ + struct VBOData + { + VBO *buf; + VkDeviceSize offset; + + public: + + CompOperatorMemcmp(const VBOData &); + }; + + Map buffer_list; + +protected: + + uint32_t draw_count; + + IndexBuffer *indices_buffer=nullptr; + VkDeviceSize indices_offset=0; + +protected: + + AABB BoundingBox; + +protected: + + friend class RenderableNode; + + uint ref_count=0; + + uint RefInc(){return ++ref_count;} + uint RefDec(){return --ref_count;} + +public: + + Renderable(const uint32_t dc=0):draw_count(dc){} + virtual ~Renderable()=default; + + const uint GetRefCount()const{return ref_count;} + + void SetBoundingBox(const AABB &aabb){BoundingBox=aabb;} + const AABB &GetBoundingBox()const {return BoundingBox;} + + bool Set(const AnsiString &name,VBO *vb,VkDeviceSize offset=0); + + bool Set(IndexBuffer *ib,VkDeviceSize offset=0) + { + if(!ib)return(false); + + indices_buffer=ib; + indices_offset=offset; + return(true); + } + +public: + + void SetDrawCount(const uint32_t dc){draw_count=dc;} ///<设置当前对象绘制需要多少个顶点 + virtual const uint32_t GetDrawCount()const ///<取得当前对象绘制需要多少个顶点 + { + if(indices_buffer) + return indices_buffer->GetCount(); + + return draw_count; + } + + VBO * GetVBO (const AnsiString &,VkDeviceSize *); + VkBuffer GetBuffer (const AnsiString &,VkDeviceSize *); + const int GetBufferCount ()const {return buffer_list.GetCount();} + + IndexBuffer * GetIndexBuffer () {return indices_buffer;} + const VkDeviceSize GetIndexBufferOffset()const {return indices_offset;} +};//class Renderable +VK_NAMESPACE_END +#endif//HGL_GRAPH_VULKAN_RENDERABLE_INCLUDE diff --git a/inc/hgl/graph/VKRenderableInstance.h b/inc/hgl/graph/VKRenderableInstance.h new file mode 100644 index 00000000..bcc9ba6e --- /dev/null +++ b/inc/hgl/graph/VKRenderableInstance.h @@ -0,0 +1,60 @@ +#ifndef HGL_GRAPH_RENDERABLE_INSTANCE_INCLUDE +#define HGL_GRAPH_RENDERABLE_INSTANCE_INCLUDE + +#include +#include +#include +#include +#include +#include +VK_NAMESPACE_BEGIN +/** +* 可渲染对象实例
+* RenderList会统一管理Shader中的LocalToWorld数据,使用DynamicUBO/DynamicSSBO实现。 +*/ +class RenderableInstance ///可渲染对象实例 +{ + Pipeline * pipeline; + MaterialInstance * mat_inst; + Renderable * render_obj; + + uint32_t buffer_count; + VkBuffer * buffer_list; + VkDeviceSize * buffer_size; + + uint32_t buffer_hash; + +private: + + friend RenderableInstance *CreateRenderableInstance(Renderable *,MaterialInstance *,Pipeline *); + + RenderableInstance(Renderable *,MaterialInstance *,Pipeline *,const uint32_t,VkBuffer *,VkDeviceSize *); + +public: + + virtual ~RenderableInstance(); + + void UpdatePipeline (Pipeline *p){pipeline=p;} + + Pipeline * GetPipeline (){return pipeline;} + VkPipelineLayout GetPipelineLayout (){return mat_inst->GetMaterial()->GetPipelineLayout();} + Material * GetMaterial (){return mat_inst->GetMaterial();} + MaterialInstance * GetMaterialInstance (){return mat_inst;} + Renderable * GetRenderable (){return render_obj;} + const AABB & GetBoundingBox ()const{return render_obj->GetBoundingBox();} + + const uint32_t GetBufferCount ()const{return buffer_count;} + VkBuffer * GetBuffer ()const{return buffer_list;} + VkDeviceSize * GetBufferSize ()const{return buffer_size;} + IndexBuffer * GetIndexBuffer ()const{return render_obj->GetIndexBuffer();} + const uint32_t GetIndexBufferOffset()const{return render_obj->GetIndexBufferOffset();} + const uint32_t GetDrawCount ()const{return render_obj->GetDrawCount();} + + const uint32_t GetBufferHash ()const{return buffer_hash;} + + MaterialParameters *GetMP (const DescriptorSetsType &type){return mat_inst->GetMP(type);} +};//class RenderableInstance + +RenderableInstance *CreateRenderableInstance(Renderable *,MaterialInstance *,Pipeline *); +VK_NAMESPACE_END +#endif//HGL_GRAPH_RENDERABLE_INSTANCE_INCLUDE diff --git a/inc/hgl/graph/vulkan/VKSampler.h b/inc/hgl/graph/VKSampler.h similarity index 89% rename from inc/hgl/graph/vulkan/VKSampler.h rename to inc/hgl/graph/VKSampler.h index d29dfb06..c7175175 100644 --- a/inc/hgl/graph/vulkan/VKSampler.h +++ b/inc/hgl/graph/VKSampler.h @@ -1,7 +1,7 @@ #ifndef HGL_GRAPH_VULKAN_SAMPLER_INCLUDE #define HGL_GRAPH_VULKAN_SAMPLER_INCLUDE -#include +#include VK_NAMESPACE_BEGIN class Device; @@ -12,7 +12,7 @@ class Sampler protected: - friend class Device; + friend class GPUDevice; Sampler(VkDevice dev,VkSampler s) { diff --git a/inc/hgl/graph/vulkan/VKSemaphore.h b/inc/hgl/graph/VKSemaphore.h similarity index 70% rename from inc/hgl/graph/vulkan/VKSemaphore.h rename to inc/hgl/graph/VKSemaphore.h index 1c969608..f9f3d0b5 100644 --- a/inc/hgl/graph/vulkan/VKSemaphore.h +++ b/inc/hgl/graph/VKSemaphore.h @@ -1,18 +1,18 @@ #ifndef HGL_GRAPH_VULKAN_SEMAPHORE_INCLUDE #define HGL_GRAPH_VULKAN_SEMAPHORE_INCLUDE -#include +#include VK_NAMESPACE_BEGIN -class Semaphore +class GPUSemaphore { VkDevice device; VkSemaphore sem; private: - friend class Device; + friend class GPUDevice; - Semaphore(VkDevice d,VkSemaphore s) + GPUSemaphore(VkDevice d,VkSemaphore s) { device=d; sem=s; @@ -20,11 +20,11 @@ private: public: - ~Semaphore(); + ~GPUSemaphore(); operator VkSemaphore(){return sem;} operator const VkSemaphore *()const{return &sem;} -};//class Semaphore +};//class GPUSemaphore VK_NAMESPACE_END #endif//HGL_GRAPH_VULKAN_SEMAPHORE_INCLUDE diff --git a/inc/hgl/graph/vulkan/VKShaderModule.h b/inc/hgl/graph/VKShaderModule.h similarity index 65% rename from inc/hgl/graph/vulkan/VKShaderModule.h rename to inc/hgl/graph/VKShaderModule.h index 589c5062..f0dd8087 100644 --- a/inc/hgl/graph/vulkan/VKShaderModule.h +++ b/inc/hgl/graph/VKShaderModule.h @@ -1,8 +1,8 @@ #ifndef HGL_GRAPH_VULKAN_SHADER_MODULE_INCLUDE #define HGL_GRAPH_VULKAN_SHADER_MODULE_INCLUDE -#include -#include +#include +#include VK_NAMESPACE_BEGIN @@ -13,7 +13,6 @@ VK_NAMESPACE_BEGIN class ShaderModule { VkDevice device; - int shader_id; int ref_count; private: @@ -26,11 +25,9 @@ protected: public: - ShaderModule(VkDevice dev,int id,VkPipelineShaderStageCreateInfo *pssci,ShaderResource *); + ShaderModule(VkDevice dev,VkPipelineShaderStageCreateInfo *pssci,ShaderResource *); virtual ~ShaderModule(); - const int GetID()const{return shader_id;} - const int IncRef(){return ++ref_count;} const int DecRef(){return --ref_count;} @@ -48,17 +45,8 @@ public: const bool IsMesh ()const{return stage_create_info->stage==VK_SHADER_STAGE_MESH_BIT_NV;} const VkPipelineShaderStageCreateInfo * GetCreateInfo ()const{return stage_create_info;} - - const int GetBinding (VkDescriptorType desc_type,const AnsiString &name)const - { - return shader_resource->GetBinding(desc_type,name); - } - - const ShaderDescriptorList * GetDescriptorList()const{return shader_resource->GetDescriptorList();} };//class ShaderModule -class VertexAttributeBinding; - /** * 顶点Shader模块
* 由于顶点shader在最前方执行,所以它比其它shader多了VertexInput的数据 @@ -66,16 +54,17 @@ class VertexAttributeBinding; class VertexShaderModule:public ShaderModule { uint32_t attr_count; - VkVertexInputBindingDescription *binding_list; - VkVertexInputAttributeDescription *attribute_list; + VertexAttribType *type_list; + const AnsiString **name_list; + ShaderStage **ssi_list; private: - - Set vab_sets; + + SortedSets vab_sets; public: - VertexShaderModule(VkDevice dev,int id,VkPipelineShaderStageCreateInfo *pssci,ShaderResource *sr); + VertexShaderModule(VkDevice dev,VkPipelineShaderStageCreateInfo *pssci,ShaderResource *sr); virtual ~VertexShaderModule(); /** @@ -83,20 +72,21 @@ public: */ const int GetStageInputBinding(const AnsiString &name)const{return shader_resource->GetStageInputBinding(name);} const ShaderStage * GetStageInput (const AnsiString &name)const{return shader_resource->GetStageInput(name);} - const uint GetStageInputCount () const{return shader_resource->GetStageInputCount();} + const uint GetStageInputCount () const{return shader_resource->GetStageInputCount();} + const ShaderStageList & GetStageInputs () const{return shader_resource->GetStageInputs();} - const uint32_t GetAttrCount()const{return attr_count;} + //const uint32_t GetAttrCount()const{return attr_count;} - const VkVertexInputBindingDescription * GetDescList ()const{return binding_list;} - const VkVertexInputAttributeDescription * GetAttrList ()const{return attribute_list;} + //const VkVertexInputBindingDescription * GetDescList ()const{return binding_list;} + //const VkVertexInputAttributeDescription * GetAttrList ()const{return attribute_list;} - const VkVertexInputBindingDescription * GetDesc (const uint32_t index)const{return (index>=attr_count?nullptr:binding_list+index);} - const VkVertexInputAttributeDescription * GetAttr (const uint32_t index)const{return (index>=attr_count?nullptr:attribute_list+index);} + //const VkVertexInputBindingDescription * GetDesc (const uint32_t index)const{return (index>=attr_count?nullptr:binding_list+index);} + //const VkVertexInputAttributeDescription * GetAttr (const uint32_t index)const{return (index>=attr_count?nullptr:attribute_list+index);} public: - VertexAttributeBinding * CreateVertexAttributeBinding(); - bool Release(VertexAttributeBinding *); + VAB * CreateVAB(const VABConfigInfo *format_map=nullptr); + bool Release(VAB *); const uint32_t GetInstanceCount()const{return vab_sets.GetCount();} };//class VertexShaderModule:public ShaderModule VK_NAMESPACE_END diff --git a/inc/hgl/graph/vulkan/ShaderModuleMap.h b/inc/hgl/graph/VKShaderModuleMap.h similarity index 79% rename from inc/hgl/graph/vulkan/ShaderModuleMap.h rename to inc/hgl/graph/VKShaderModuleMap.h index dd7d8f8b..cbe059cb 100644 --- a/inc/hgl/graph/vulkan/ShaderModuleMap.h +++ b/inc/hgl/graph/VKShaderModuleMap.h @@ -1,15 +1,14 @@ -#ifndef HGL_GRAPH_VULKAN_SHADER_MODULE_MAP_INCLUDE +#ifndef HGL_GRAPH_VULKAN_SHADER_MODULE_MAP_INCLUDE #define HGL_GRAPH_VULKAN_SHADER_MODULE_MAP_INCLUDE #include -#include +#include +#include VK_NAMESPACE_BEGIN using namespace hgl; -class ShaderModule; - class ShaderModuleMap:public Map { public: diff --git a/inc/hgl/graph/VKShaderResource.h b/inc/hgl/graph/VKShaderResource.h new file mode 100644 index 00000000..8fc13342 --- /dev/null +++ b/inc/hgl/graph/VKShaderResource.h @@ -0,0 +1,68 @@ +#ifndef HGL_GRAPH_VULKAN_SHADER_RESOURCE_INCLUDE +#define HGL_GRAPH_VULKAN_SHADER_RESOURCE_INCLUDE + +#include +#include +#include +#include + +VK_NAMESPACE_BEGIN + +struct ShaderStage +{ + AnsiString name; + uint location; + + VertexAttribType type; ///<成份数量(如vec4中的4) + + bool global; ///<是否全局数据 + bool dynamic; ///<是否动态数量 +};//struct ShaderStage + +using ShaderStageList =ObjectList; + +class ShaderResource +{ + VkShaderStageFlagBits stage_flag; + + const void *spv_data; + uint32 spv_size; + + ShaderStageList stage_inputs; + ShaderStageList stage_outputs; + +public: + + ShaderResource(const VkShaderStageFlagBits &,const void *,const uint32); + virtual ~ShaderResource()=default; + + const VkShaderStageFlagBits GetStage ()const {return stage_flag;} + const os_char * GetStageName ()const; + + const uint32_t * GetCode ()const {return (uint32_t *)spv_data;} + const uint32_t GetCodeSize ()const {return spv_size;} + + ShaderStageList & GetStageInputs () {return stage_inputs;} + ShaderStageList & GetStageOutputs () {return stage_outputs;} + + const uint GetStageInputCount ()const {return stage_inputs.GetCount();} + const uint GetStageOutputCount ()const {return stage_outputs.GetCount();} + + const ShaderStage * GetStageInput (const AnsiString &)const; + const int GetStageInputBinding(const AnsiString &)const; +};//class ShaderResource + +ShaderResource *LoadShaderResource(const uint8 *origin_filedata,const int64 filesize); + +struct ShaderModuleCreateInfo:public vkstruct_flag +{ +public: + + ShaderModuleCreateInfo(ShaderResource *sr) + { + codeSize=sr->GetCodeSize(); + pCode =sr->GetCode(); + } +};//struct ShaderModuleCreateInfo +VK_NAMESPACE_END +#endif//HGL_GRAPH_VULKAN_SHADER_RESOURCE_INCLUDE \ No newline at end of file diff --git a/inc/hgl/graph/vulkan/VKSubpass.h b/inc/hgl/graph/VKSubpass.h similarity index 96% rename from inc/hgl/graph/vulkan/VKSubpass.h rename to inc/hgl/graph/VKSubpass.h index 1202a32a..7aa18714 100644 --- a/inc/hgl/graph/vulkan/VKSubpass.h +++ b/inc/hgl/graph/VKSubpass.h @@ -1,7 +1,7 @@ #ifndef HGL_GRAPH_VULKAN_SUBPASS_INCLUDE #define HGL_GRAPH_VULKAN_SUBPASS_INCLUDE -#include +#include VK_NAMESPACE_BEGIN /** * 渲染流程中一次具体的操作,即便整个Renderpass只有一次渲染,也需要创建subpass diff --git a/inc/hgl/graph/VKSubpassInfo.h b/inc/hgl/graph/VKSubpassInfo.h new file mode 100644 index 00000000..9ff904c9 --- /dev/null +++ b/inc/hgl/graph/VKSubpassInfo.h @@ -0,0 +1,25 @@ +#ifndef HGL_VULKAN_SUBPASS_INFO_INCLUDE +#define HGL_VULKAN_SUBPASS_INFO_INCLUDE + +#include +#include +VK_NAMESPACE_BEGIN +struct SubpassInfo +{ + List input_attachments; + List output_attachments; + + struct + { + List attachments; + }color; + + struct + { + bool enable; + uint32_t attachment; + VkResolveModeFlagBits mode; + }depth_stencil; +};//struct SubpassInfo +VK_NAMESPACE_END +#endif//HGL_VULKAN_SUBPASS_INFO_INCLUDE diff --git a/inc/hgl/graph/vulkan/VKSurfaceExtensionName.h b/inc/hgl/graph/VKSurfaceExtensionName.h similarity index 96% rename from inc/hgl/graph/vulkan/VKSurfaceExtensionName.h rename to inc/hgl/graph/VKSurfaceExtensionName.h index 5b9c1451..57ee55f1 100644 --- a/inc/hgl/graph/vulkan/VKSurfaceExtensionName.h +++ b/inc/hgl/graph/VKSurfaceExtensionName.h @@ -1,6 +1,6 @@ #pragma once -#include +#include #ifdef __ANDROID__ #include diff --git a/inc/hgl/graph/VKSwapchain.h b/inc/hgl/graph/VKSwapchain.h new file mode 100644 index 00000000..11b08af6 --- /dev/null +++ b/inc/hgl/graph/VKSwapchain.h @@ -0,0 +1,30 @@ +#ifndef HGL_GRAPH_VULKAN_SWAP_CHAIN_INCLUDE +#define HGL_GRAPH_VULKAN_SWAP_CHAIN_INCLUDE + +#include +#include +#include +VK_NAMESPACE_BEGIN +struct Swapchain +{ +public: + + VkDevice device =VK_NULL_HANDLE; + + VkExtent2D extent; + + VkSwapchainKHR swap_chain =VK_NULL_HANDLE; + + uint32_t color_count=0; + + Texture2D ** sc_color =nullptr; + Texture2D * sc_depth =nullptr; + + Framebuffer ** render_frame =nullptr; + +public: + + virtual ~Swapchain(); +};//struct Swapchain +VK_NAMESPACE_END +#endif//HGL_GRAPH_VULKAN_SWAP_CHAIN_INCLUDE diff --git a/inc/hgl/graph/vulkan/VKTexture.h b/inc/hgl/graph/VKTexture.h similarity index 74% rename from inc/hgl/graph/vulkan/VKTexture.h rename to inc/hgl/graph/VKTexture.h index 07af932b..af0f95e7 100644 --- a/inc/hgl/graph/vulkan/VKTexture.h +++ b/inc/hgl/graph/VKTexture.h @@ -1,25 +1,16 @@ #ifndef HGL_GRAPH_VULKAN_TEXTURE_INCLUDE #define HGL_GRAPH_VULKAN_TEXTURE_INCLUDE -#include -#include -#include +#include +#include +#include #include #include +#include VK_NAMESPACE_BEGIN BitmapData *LoadBitmapFromFile(const OSString &filename); -struct TextureData -{ - Memory * memory =nullptr; - VkImage image =VK_NULL_HANDLE; - VkImageLayout image_layout=VK_IMAGE_LAYOUT_UNDEFINED; - ImageView * image_view =nullptr; - uint32 mip_levels =0; - VkImageTiling tiling =VK_IMAGE_TILING_OPTIMAL; -};//struct TextureData - class Texture { protected: @@ -36,10 +27,10 @@ public: VkImageLayout GetImageLayout () {return data?data->image_layout:VK_IMAGE_LAYOUT_UNDEFINED;} VkImageView GetVulkanImageView () {return data?data->image_view->operator VkImageView():VK_NULL_HANDLE;} - Memory * GetMemory () {return data?data->memory:nullptr;} + GPUMemory * GetMemory () {return data?data->memory:nullptr;} ImageView * GetImageView () {return data?data->image_view:nullptr;} - const uint32 GetMipLevels ()const {return data?data->mip_levels:0;} + const uint32 GetMipLevel ()const {return data?data->miplevel:0;} const bool IsOptimal ()const {return data?data->tiling==VK_IMAGE_TILING_OPTIMAL:false;} const bool IsLinear ()const {return data?data->tiling==VK_IMAGE_TILING_LINEAR:false;} @@ -75,6 +66,8 @@ public: Texture2D(VkDevice dev,TextureData *td):Texture(dev,td){} ~Texture2D()=default; + static VkImageViewType GetImageViewType(){return VK_IMAGE_VIEW_TYPE_2D;} + const uint32_t GetWidth ()const{return data?data->image_view->GetExtent().width:0;} const uint32_t GetHeight()const{return data?data->image_view->GetExtent().height:0;} };//class Texture2D:public Texture @@ -89,15 +82,23 @@ public: // uint32_t width,height,depth; //};//class Texture3D:public Texture -//class TextureCubemap:public Texture -//{ -// uint32_t width,height; -//};//class TextureCubemap:public Texture +class TextureCube:public Texture +{ +public: -//class TextureCubemapArray:public Texture + TextureCube(VkDevice dev,TextureData *td):Texture(dev,td){} + ~TextureCube()=default; + + static VkImageViewType GetImageViewType(){return VK_IMAGE_VIEW_TYPE_CUBE;} + + const uint32_t GetWidth ()const{return data?data->image_view->GetExtent().width:0;} + const uint32_t GetHeight()const{return data?data->image_view->GetExtent().height:0;} +};//class TextureCube:public Texture + +//class TextureCubeArray:public Texture //{ // uint32_t width,height,count; -//};//class TextureCubemapArray:public Texture +//};//class TextureCubeArray:public Texture VK_NAMESPACE_END #endif//HGL_GRAPH_VULKAN_TEXTURE_INCLUDE diff --git a/inc/hgl/graph/VKTextureCreateInfo.h b/inc/hgl/graph/VKTextureCreateInfo.h new file mode 100644 index 00000000..d3d88dd6 --- /dev/null +++ b/inc/hgl/graph/VKTextureCreateInfo.h @@ -0,0 +1,324 @@ +#ifndef HGL_GRAPH_VULKAN_TEXTURE_CREATE_INFO_INCLUDE +#define HGL_GRAPH_VULKAN_TEXTURE_CREATE_INFO_INCLUDE + +#include +VK_NAMESPACE_BEGIN +struct TextureCreateInfo +{ + VkImageViewType type; + + VkExtent3D extent; //如为arrays,depth等同于layers + + VkFormat format; + uint32_t usage; + uint32_t mipmap_zero_total_bytes; + uint32_t origin_mipmaps; //原始mipmaps,0/1 + uint32_t target_mipmaps; //目标mipmaps,如果和origin_mipmaps不相等,则证明希望自动生成mipmaps + VkImageAspectFlags aspect; + ImageTiling tiling; + + VkImageLayout image_layout; + + VkImage image; //如果没有IMAGE,则创建。(交换链等会直接提供image,所以存在外部传入现像) + GPUMemory * memory; //同时需分配内存并绑定 + + ImageView * image_view; //如果没有imageview,则创建 + + void * pixels; //如果没有buffer但有pixels,则根据pixels和以上条件创建buffer + VkDeviceSize total_bytes; + GPUBuffer * buffer; //如果pixels也没有,则代表不会立即写入图像数据 + +public: + + TextureCreateInfo() + { + hgl_zero(*this); + } + + TextureCreateInfo(const uint32_t aspect_bit,const VkExtent2D &ext,const VkFormat &fmt,VkImage img):TextureCreateInfo() + { + aspect=aspect_bit; + + extent.width=ext.width; + extent.height=ext.height; + extent.depth=1; + + format=fmt; + image=img; + } + + TextureCreateInfo(const uint32_t aspect_bit,const uint32_t u,const ImageTiling it,const VkImageLayout il):TextureCreateInfo() + { + aspect=aspect_bit; + + usage=u; + tiling=it; + image_layout=il; + } + + TextureCreateInfo(const uint32_t aspect_bit,const VkFormat &fmt,const uint32_t u,const ImageTiling it,const VkImageLayout il):TextureCreateInfo() + { + aspect=aspect_bit; + + format=fmt; + usage=u; + tiling=it; + image_layout=il; + } + + TextureCreateInfo(const uint32_t aspect_bit,const uint32_t u,const ImageTiling it) + :TextureCreateInfo(aspect_bit,u,it, + (tiling==ImageTiling::Optimal? + VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL: + VK_IMAGE_LAYOUT_GENERAL)){} + + TextureCreateInfo(const uint32_t aspect_bit,const VkExtent2D &ext,const uint32_t u,const ImageTiling it) + :TextureCreateInfo(aspect_bit,u,it) + { + extent.width=ext.width; + extent.height=ext.height; + extent.depth=1; + } + + TextureCreateInfo(const uint32_t aspect_bit,const VkFormat &fmt,const VkExtent2D &ext,const uint32_t u,const ImageTiling it,const VkImageLayout il) + :TextureCreateInfo(aspect_bit,u,it,il) + { + format=fmt; + extent.width=ext.width; + extent.height=ext.height; + extent.depth=1; + } + + TextureCreateInfo(const uint32_t aspect_bit,const uint32_t u) + :TextureCreateInfo(aspect_bit,u,ImageTiling::Optimal,VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL){} + + TextureCreateInfo(const uint32_t aspect_bit) + :TextureCreateInfo( aspect_bit, + VK_IMAGE_USAGE_TRANSFER_DST_BIT|VK_IMAGE_USAGE_SAMPLED_BIT, + ImageTiling::Optimal, + VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL){} + + TextureCreateInfo(const VkFormat fmt):TextureCreateInfo() + { + if(IsDepthStencilFormat(fmt)) + aspect=VK_IMAGE_ASPECT_DEPTH_BIT|VK_IMAGE_ASPECT_STENCIL_BIT; + else + if(IsDepthFormat(fmt)) + aspect=VK_IMAGE_ASPECT_DEPTH_BIT; + else + if(CheckVulkanFormat(fmt)) + { + aspect=VK_IMAGE_ASPECT_COLOR_BIT; + } + else + { + aspect=0; + } + + format=fmt; + usage=VK_IMAGE_USAGE_TRANSFER_DST_BIT|VK_IMAGE_USAGE_SAMPLED_BIT; + } + + TextureCreateInfo(const uint32_t aspect_bits,const VkFormat fmt,const VkExtent2D &ext):TextureCreateInfo(fmt) + { + aspect=aspect; + + extent.width=ext.width; + extent.height=ext.height; + extent.depth=1; + } + + bool SetFormat(const VkFormat fmt) + { + if(!CheckVulkanFormat(fmt))return(false); + + if(aspect&VK_IMAGE_ASPECT_DEPTH_BIT) + { + if(aspect&VK_IMAGE_ASPECT_STENCIL_BIT) + { + if(!IsDepthStencilFormat(fmt))return(false); + } + else + { + if(!IsDepthFormat(fmt))return(false); + } + } + else + { + if(aspect&VK_IMAGE_ASPECT_STENCIL_BIT) + if(!IsStencilFormat(fmt))return(false); + } + + return(true); + } + + bool SetData(GPUBuffer *buf,const VkExtent3D &ext) + { + if(!buf)return(false); + if(ext.width<=0||ext.height<=0||ext.depth<=0)return(false); + + buffer=buf; + + extent=ext; + + return(true); + } + + void SetAutoMipmaps() + { + target_mipmaps=hgl::GetMipLevel(extent.width,extent.height,extent.depth); + } +};//struct TextureCreateInfo + +struct ColorTextureCreateInfo:public TextureCreateInfo +{ + ColorTextureCreateInfo():TextureCreateInfo(VK_IMAGE_ASPECT_COLOR_BIT){} + ColorTextureCreateInfo(const VkFormat format,const VkExtent2D &ext):TextureCreateInfo(VK_IMAGE_ASPECT_COLOR_BIT,format,ext){} +};//struct ColorTextureCreateInfo:public TextureCreateInfo + +struct DepthTextureCreateInfo:public TextureCreateInfo +{ + DepthTextureCreateInfo():TextureCreateInfo(VK_IMAGE_ASPECT_DEPTH_BIT){} + DepthTextureCreateInfo(const VkFormat format,const VkExtent2D &ext):TextureCreateInfo(VK_IMAGE_ASPECT_COLOR_BIT,format,ext){} +};//struct DepthTextureCreateInfo:public TextureCreateInfo + +struct DepthStencilTextureCreateInfo:public TextureCreateInfo +{ + DepthStencilTextureCreateInfo():TextureCreateInfo(VK_IMAGE_ASPECT_DEPTH_BIT|VK_IMAGE_ASPECT_STENCIL_BIT){} +};//struct DepthStencilTextureCreateInfo:public TextureCreateInfo + +struct AttachmentTextureCreateInfo:public TextureCreateInfo +{ + AttachmentTextureCreateInfo(const uint32_t aspect_bit,const uint32_t u,const VkImageLayout il):TextureCreateInfo(aspect_bit,u,ImageTiling::Optimal,il){} +};//struct AttachmentTextureCreateInfo:public TextureCreateInfo + +struct ColorAttachmentTextureCreateInfo:public AttachmentTextureCreateInfo +{ + ColorAttachmentTextureCreateInfo() + :AttachmentTextureCreateInfo( VK_IMAGE_ASPECT_COLOR_BIT, + + VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT + |VK_IMAGE_USAGE_TRANSFER_SRC_BIT + |VK_IMAGE_USAGE_TRANSFER_DST_BIT + |VK_IMAGE_USAGE_SAMPLED_BIT, + + VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL){} + + ColorAttachmentTextureCreateInfo(const VkFormat fmt,const VkExtent3D &ext):ColorAttachmentTextureCreateInfo() + { + format=fmt; + extent=ext; + } + + ColorAttachmentTextureCreateInfo(const VkFormat fmt,const VkExtent2D &ext):ColorAttachmentTextureCreateInfo() + { + format=fmt; + extent.width=ext.width; + extent.height=ext.height; + extent.depth=1; + } +}; + +struct DepthAttachmentTextureCreateInfo:public AttachmentTextureCreateInfo +{ + DepthAttachmentTextureCreateInfo() + :AttachmentTextureCreateInfo( VK_IMAGE_ASPECT_DEPTH_BIT, + + VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT + |VK_IMAGE_USAGE_TRANSFER_SRC_BIT + |VK_IMAGE_USAGE_TRANSFER_DST_BIT + |VK_IMAGE_USAGE_SAMPLED_BIT, + + VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL){} + + DepthAttachmentTextureCreateInfo(const VkFormat fmt,const VkExtent3D &ext):DepthAttachmentTextureCreateInfo() + { + format=fmt; + extent=ext; + } + + DepthAttachmentTextureCreateInfo(const VkFormat fmt,const VkExtent2D &ext):DepthAttachmentTextureCreateInfo() + { + format=fmt; + extent.width=ext.width; + extent.height=ext.height; + extent.depth=1; + } +}; + +struct DepthStencilAttachmentTextureCreateInfo:public AttachmentTextureCreateInfo +{ + DepthStencilAttachmentTextureCreateInfo() + :AttachmentTextureCreateInfo( VK_IMAGE_ASPECT_DEPTH_BIT|VK_IMAGE_ASPECT_STENCIL_BIT, + + VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT + |VK_IMAGE_USAGE_TRANSFER_SRC_BIT + |VK_IMAGE_USAGE_TRANSFER_DST_BIT + |VK_IMAGE_USAGE_SAMPLED_BIT, + + VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL){} + + DepthStencilAttachmentTextureCreateInfo(const VkFormat fmt,const VkExtent3D &ext):DepthStencilAttachmentTextureCreateInfo() + { + format=fmt; + extent=ext; + } + + DepthStencilAttachmentTextureCreateInfo(const VkFormat fmt,const VkExtent2D &ext):DepthStencilAttachmentTextureCreateInfo() + { + format=fmt; + extent.width=ext.width; + extent.height=ext.height; + extent.depth=1; + } +}; + +struct SwapchainColorTextureCreateInfo:public TextureCreateInfo +{ + SwapchainColorTextureCreateInfo(const VkFormat fmt,const VkExtent2D &ext,VkImage img) + :TextureCreateInfo(VK_IMAGE_ASPECT_COLOR_BIT,ext,fmt,img){} +};//struct SwapchainColorTextureCreateInfo:public TextureCreateInfo + +struct SwapchainDepthTextureCreateInfo:public TextureCreateInfo +{ + SwapchainDepthTextureCreateInfo(const VkFormat fmt,const VkExtent2D &ext) + :TextureCreateInfo( VK_IMAGE_ASPECT_DEPTH_BIT, + fmt, + ext, + VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, + ImageTiling::Optimal, + VK_IMAGE_LAYOUT_UNDEFINED){} +};//struct SwapchainColorTextureCreateInfo:public TextureCreateInfo + +struct TextureData +{ + GPUMemory * memory; + VkImage image; + VkImageLayout image_layout; + ImageView * image_view; + uint32 miplevel; + VkImageTiling tiling; + +public: + + TextureData() + { + hgl_zero(*this); + } + + TextureData(const TextureCreateInfo *tci) + { + memory =tci->memory; + image =tci->image; + image_view =tci->image_view; + miplevel =tci->target_mipmaps; + tiling =VkImageTiling(tci->tiling); + + if(!tci->buffer&&!tci->pixels&&tci->image_layout==VK_IMAGE_LAYOUT_UNDEFINED) + image_layout=VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; + else + image_layout=tci->image_layout; + } +};//struct TextureData +VK_NAMESPACE_END +#endif//HGL_GRAPH_VULKAN_TEXTURE_CREATE_INFO_INCLUDE \ No newline at end of file diff --git a/inc/hgl/graph/VKTextureLoader.h b/inc/hgl/graph/VKTextureLoader.h new file mode 100644 index 00000000..6bf40b8a --- /dev/null +++ b/inc/hgl/graph/VKTextureLoader.h @@ -0,0 +1,97 @@ +#ifndef HGL_GRAPH_VULKAN_TEXTURE_LOADER_INCLUDE +#define HGL_GRAPH_VULKAN_TEXTURE_LOADER_INCLUDE + +#include + +VK_NAMESPACE_BEGIN +template +class VkTextureLoader:public L +{ +protected: + + GPUDevice *device; + GPUBuffer *buf; + + T *tex; + + bool auto_mipmaps; + +public: + + VkTextureLoader(GPUDevice *dev,const bool am) + { + device =dev; + buf =nullptr; + tex =nullptr; + auto_mipmaps=am; + } + + virtual ~VkTextureLoader() + { + SAFE_CLEAR(buf); + SAFE_CLEAR(tex); + } + + T *GetTexture() + { + T *result=tex; + tex=nullptr; + return result; + } + + void *OnBegin(uint32 total_bytes) override + { + SAFE_CLEAR(buf); + SAFE_CLEAR(tex); + + if(!CheckVulkanFormat(format)) + return(nullptr); + + buf=device->CreateBuffer(VK_BUFFER_USAGE_TRANSFER_SRC_BIT,total_bytes); + + if(!buf) + return(nullptr); + + return buf->Map(); + } + + void OnEnd() override + { + buf->Unmap(); + + TextureCreateInfo *tci=new TextureCreateInfo(format); + + tci->type=type; + + VkExtent3D extent; + + extent.width =file_header.width; + extent.height =file_header.height; + extent.depth =file_header.depth; + + tci->SetData(buf,extent); + + if(auto_mipmaps&&file_header.mipmaps<=1) + { + if(device->CheckFormatSupport(format,VK_FORMAT_FEATURE_BLIT_DST_BIT)) + { + tci->usage|=VK_IMAGE_USAGE_TRANSFER_SRC_BIT; + tci->SetAutoMipmaps(); + } + } + else + { + tci->origin_mipmaps= + tci->target_mipmaps=file_header.mipmaps; + } + + tci->mipmap_zero_total_bytes=mipmap_zero_total_bytes; + + tex=device->CreateTexture2D(tci); + + if(tex) + buf=nullptr; + } +};//class VkTextureLoader:public L +VK_NAMESPACE_END +#endif//HGL_GRAPH_VULKAN_TEXTURE_LOADER_INCLUDE diff --git a/inc/hgl/graph/VKVertexAttribBuffer.h b/inc/hgl/graph/VKVertexAttribBuffer.h new file mode 100644 index 00000000..24b9b807 --- /dev/null +++ b/inc/hgl/graph/VKVertexAttribBuffer.h @@ -0,0 +1,39 @@ +#ifndef HGL_GRAPH_VULKAN_VERTEX_ATTRIB_BUFFER_INCLUDE +#define HGL_GRAPH_VULKAN_VERTEX_ATTRIB_BUFFER_INCLUDE + +#include + +namespace hgl +{ + namespace graph + { + class VertexAttribBuffer:public GPUBuffer + { + VkFormat format; ///<ݸʽ + uint32_t stride; ///<ֽ + uint32_t count; ///< + + private: + + friend class GPUDevice; + + VertexAttribBuffer(VkDevice d,const GPUBufferData &vb,VkFormat fmt,uint32_t _stride,uint32_t _count):GPUBuffer(d,vb) + { + format=fmt; + stride=_stride; + count=_count; + } + + public: + + ~VertexAttribBuffer()=default; + + const VkFormat GetFormat()const { return format; } + const uint32_t GetStride()const { return stride; } + const uint32_t GetCount ()const { return count; } + };//class VertexAttribBuffer:public GPUBuffer + + using VBO=VertexAttribBuffer; + }//namespace graph +}//namespace hgl +#endif//HGL_GRAPH_VULKAN_VERTEX_ATTRIB_BUFFER_INCLUDE diff --git a/inc/hgl/graph/VertexAttribData.h b/inc/hgl/graph/VertexAttribData.h index 46f913c8..64aee685 100644 --- a/inc/hgl/graph/VertexAttribData.h +++ b/inc/hgl/graph/VertexAttribData.h @@ -1,7 +1,7 @@ #ifndef HGL_GRAPH_VERTEX_ATTRIB_DATA_INCLUDE #define HGL_GRAPH_VERTEX_ATTRIB_DATA_INCLUDE -#include +#include namespace hgl { namespace graph @@ -69,11 +69,12 @@ namespace hgl /** * 根据格式要求,创建对应的顶点属性数据区(VAD) - * @param base_type 基础格式 - * @param vecsize vec数量 - * @param vertex_count 顶点数量 + * @param vertex_count 顶点数量 + * @param fmt Vulkan格式 + * @param vec_size vec数量 + * @param stride 单个数据字节数 */ - VAD *CreateVertexAttribData(const VertexAttribType *,const uint32_t vertex_count); + VAD *CreateVertexAttribData(const uint32_t vertex_count,const VkFormat fmt,const int vec_size,const uint stride); //这个函数比较重要,就不搞成CreateVAD的简写了 }//namespace graph }//namespace hgl diff --git a/inc/hgl/graph/VertexAttribDataAccess.h b/inc/hgl/graph/VertexAttribDataAccess.h index ea493a0e..c011f3cd 100644 --- a/inc/hgl/graph/VertexAttribDataAccess.h +++ b/inc/hgl/graph/VertexAttribDataAccess.h @@ -44,7 +44,7 @@ namespace hgl virtual ~VertexAttribDataAccess()=default; - void BufferData(const T *ptr) + void Write(const T *ptr) { if(!ptr)return; @@ -60,7 +60,7 @@ namespace hgl { if(!data||offset>=count) { - LOG_HINT(OS_TEXT("VertexAttribBuffer::Get() out,offset:")+OSString::valueOf(offset)); + LOG_HINT(OS_TEXT("VertexAttribDataAccess::Get() out,offset:")+OSString::valueOf(offset)); return(nullptr); } @@ -76,7 +76,7 @@ namespace hgl { if(access) { - LOG_HINT(OS_TEXT("VertexAttribBuffer::Begin() access!=0,offset:")+OSString::valueOf(offset)); + LOG_HINT(OS_TEXT("VertexAttribDataAccess::Begin() access!=0,offset:")+OSString::valueOf(offset)); return(nullptr); } @@ -106,7 +106,7 @@ namespace hgl { if(!this->access||this->access+C*number>this->data_end) { - LOG_HINT(OS_TEXT("VertexAttribBuffer::Write(const T *,number) out,number:")+OSString::valueOf(number)); + LOG_HINT(OS_TEXT("VertexAttribDataAccess::Write(const T *,number) out,number:")+OSString::valueOf(number)); return(false); } @@ -116,7 +116,7 @@ namespace hgl return(true); } - };//class VertexAttribBuffer + };//class VertexAttribDataAccess /** * 一元数据缓冲区 @@ -324,7 +324,7 @@ namespace hgl * @param count 写入数量 */ template - bool Fill(const V2 &v,const uint32_t count) + bool RepeatWrite(const V2 &v,const uint32_t count) { if(!this->access||this->access+(count<<1)>this->data_end) { @@ -629,7 +629,7 @@ namespace hgl * @param count 写入数量 */ template - bool Fill(const V3 &v,const uint32_t count) + bool RepeatWrite(const V3 &v,const uint32_t count) { if(!this->access||this->access+(count*3)>this->data_end) { @@ -917,7 +917,7 @@ namespace hgl return(true); } - bool Fill(const Color4f &v,const uint32_t count) + bool RepeatWrite(const Color4f &v,const uint32_t count) { if(count<=0)return(false); @@ -944,7 +944,7 @@ namespace hgl * @param count 写入数量 */ template - bool Fill(const V4 &v,const uint32_t count) + bool RepeatWrite(const V4 &v,const uint32_t count) { if(!this->access||this->access+(count<<2)>this->data_end) { @@ -1140,41 +1140,41 @@ namespace hgl };//class VertexAttribDataAccess4 //缓冲区具体数据类型定义 - typedef VertexAttribDataAccess1 VB1i8 ,VB1b; - typedef VertexAttribDataAccess1 VB1i16 ,VB1s; - typedef VertexAttribDataAccess1 VB1i32 ,VB1i; - typedef VertexAttribDataAccess1 VB1u8 ,VB1ub; - typedef VertexAttribDataAccess1 VB1u16 ,VB1us; - typedef VertexAttribDataAccess1 VB1u32 ,VB1ui; - typedef VertexAttribDataAccess1 VB1f; - typedef VertexAttribDataAccess1 VB1d; + typedef VertexAttribDataAccess1 VB1i8 ,VB1b; + typedef VertexAttribDataAccess1 VB1i16 ,VB1s; + typedef VertexAttribDataAccess1 VB1i32 ,VB1i; + typedef VertexAttribDataAccess1 VB1u8 ,VB1ub; + typedef VertexAttribDataAccess1 VB1u16 ,VB1us; + typedef VertexAttribDataAccess1 VB1u32 ,VB1ui; + typedef VertexAttribDataAccess1 VB1f; + typedef VertexAttribDataAccess1 VB1d; - typedef VertexAttribDataAccess2 VB2i8 ,VB2b; - typedef VertexAttribDataAccess2 VB2i16 ,VB2s; - typedef VertexAttribDataAccess2 VB2i32 ,VB2i; - typedef VertexAttribDataAccess2 VB2u8 ,VB2ub; - typedef VertexAttribDataAccess2 VB2u16 ,VB2us; - typedef VertexAttribDataAccess2 VB2u32 ,VB2ui; - typedef VertexAttribDataAccess2 VB2f; - typedef VertexAttribDataAccess2 VB2d; + typedef VertexAttribDataAccess2 VB2i8 ,VB2b; + typedef VertexAttribDataAccess2 VB2i16 ,VB2s; + typedef VertexAttribDataAccess2 VB2i32 ,VB2i; + typedef VertexAttribDataAccess2 VB2u8 ,VB2ub; + typedef VertexAttribDataAccess2 VB2u16 ,VB2us; + typedef VertexAttribDataAccess2 VB2u32 ,VB2ui; + typedef VertexAttribDataAccess2 VB2f; + typedef VertexAttribDataAccess2 VB2d; -// typedef VertexAttribDataAccess3 VB3i8 ,VB3b; -// typedef VertexAttribDataAccess3 VB3i16 ,VB3s; - typedef VertexAttribDataAccess3 VB3i32 ,VB3i; -// typedef VertexAttribDataAccess3 VB3u8 ,VB3ub; -// typedef VertexAttribDataAccess3 VB3u16 ,VB3us; - typedef VertexAttribDataAccess3 VB3u32 ,VB3ui; - typedef VertexAttribDataAccess3 VB3f; - typedef VertexAttribDataAccess3 VB3d; +// typedef VertexAttribDataAccess3 VB3i8 ,VB3b; +// typedef VertexAttribDataAccess3 VB3i16 ,VB3s; + typedef VertexAttribDataAccess3 VB3i32 ,VB3i; +// typedef VertexAttribDataAccess3 VB3u8 ,VB3ub; +// typedef VertexAttribDataAccess3 VB3u16 ,VB3us; + typedef VertexAttribDataAccess3 VB3u32 ,VB3ui; + typedef VertexAttribDataAccess3 VB3f; + typedef VertexAttribDataAccess3 VB3d; - typedef VertexAttribDataAccess4 VB4i8 ,VB4b; - typedef VertexAttribDataAccess4 VB4i16 ,VB4s; - typedef VertexAttribDataAccess4 VB4i32 ,VB4i; - typedef VertexAttribDataAccess4 VB4u8 ,VB4ub; - typedef VertexAttribDataAccess4 VB4u16 ,VB4us; - typedef VertexAttribDataAccess4 VB4u32 ,VB4ui; - typedef VertexAttribDataAccess4 VB4f; - typedef VertexAttribDataAccess4 VB4d; + typedef VertexAttribDataAccess4 VB4i8 ,VB4b; + typedef VertexAttribDataAccess4 VB4i16 ,VB4s; + typedef VertexAttribDataAccess4 VB4i32 ,VB4i; + typedef VertexAttribDataAccess4 VB4u8 ,VB4ub; + typedef VertexAttribDataAccess4 VB4u16 ,VB4us; + typedef VertexAttribDataAccess4 VB4u32 ,VB4ui; + typedef VertexAttribDataAccess4 VB4f; + typedef VertexAttribDataAccess4 VB4d; }//namespace graph }//namespace hgl #endif//HGL_GRAPH_VERTEX_ATTRIB_DATA_ACCESS_INCLUDE diff --git a/inc/hgl/graph/font/FontSource.h b/inc/hgl/graph/font/FontSource.h index b19d5d4f..771e7f36 100644 --- a/inc/hgl/graph/font/FontSource.h +++ b/inc/hgl/graph/font/FontSource.h @@ -3,7 +3,7 @@ #include #include -#include +#include #include #include @@ -70,7 +70,7 @@ namespace hgl { protected: - Set ref_object; + SortedSets ref_object; MapObject cla_cache; diff --git a/inc/hgl/graph/font/TextLayout.h b/inc/hgl/graph/font/TextLayout.h index c1d40d2a..a56f4995 100644 --- a/inc/hgl/graph/font/TextLayout.h +++ b/inc/hgl/graph/font/TextLayout.h @@ -99,7 +99,7 @@ namespace hgl int draw_chars_count; ///<要绘制字符列表 - Set alone_chars; ///<不重复字符统计缓冲区 + SortedSets alone_chars; ///<不重复字符统计缓冲区 TileUVFloatMap alone_chars_uv; ///<所有要绘制字符的uv struct CharDrawAttr @@ -141,7 +141,7 @@ namespace hgl protected: TextRenderable *text_render_obj; - MemBlock vertex; + MemBlock vertex; MemBlock tex_coord; public: diff --git a/inc/hgl/graph/font/TextRenderable.h b/inc/hgl/graph/font/TextRenderable.h index 79ad2af0..68aa9410 100644 --- a/inc/hgl/graph/font/TextRenderable.h +++ b/inc/hgl/graph/font/TextRenderable.h @@ -1,7 +1,7 @@ #ifndef HGL_GRAPH_TEXT_RENDERABLE_INCLUDE #define HGL_GRAPH_TEXT_RENDERABLE_INCLUDE -#include +#include namespace hgl { namespace graph @@ -9,28 +9,28 @@ namespace hgl /** * 文本可渲染对象 */ - class TextRenderable:public vulkan::Renderable + class TextRenderable:public Renderable { - vulkan::Device * device; - vulkan::Material * mtl; + GPUDevice * device; + Material * mtl; - uint max_count; ///<缓冲区最大容量 + uint max_count; ///<缓冲区最大容量 - vulkan::VAB * vab_position; - vulkan::VAB * vab_tex_coord; + VBO * vbo_position; + VBO * vbo_tex_coord; public: - TextRenderable(vulkan::Device *,vulkan::Material *,uint mc=1024); + TextRenderable(GPUDevice *,Material *,uint mc=1024); virtual ~TextRenderable(); public: void SetCharCount (const uint); - bool WriteVertex (const float *fp); + bool WriteVertex (const int16 *fp); bool WriteTexCoord (const float *fp); - };//class TextRenderable:public vulkan::Renderable + };//class TextRenderable:public Renderable }//namespace graph }//namespace hgl #endif//HGL_GRAPH_TEXT_RENDERABLE_INCLUDE diff --git a/inc/hgl/graph/material/Material.h b/inc/hgl/graph/material/Material.h deleted file mode 100644 index 5c0cf66b..00000000 --- a/inc/hgl/graph/material/Material.h +++ /dev/null @@ -1,68 +0,0 @@ -#ifndef HGL_GRAPH_MATERIAL_INCLUDE -#define HGL_GRAPH_MATERIAL_INCLUDE - -#include -#include - -MATERIAL_NAMESPACE_BEGIN - enum class BlendMode - { - Opaque=0, - Mask, - Alpha, - Additive, - Subtractive, - Modulate, - PreMultiAlpha, // 预计算好一半的Alpha - - BEGIN_RANGE =Opaque, - END_RANGE =PreMultiAlpha, - RANGE_SIZE =END_RANGE-BEGIN_RANGE+1 - };//enum class BlendMode - - /** - * 延迟渲染阶段流程 - */ - enum class DeferredRenderPass - { - Opaque, ///<不透明部分 - Mask, ///<遮罩部分 - - Composition, /// -MATERIAL_NAMESPACE_BEGIN -/** - * 标准PBR材质
- * BaseColor/Normal/Metallic/Roughness四个属性必须都有。如未提供,则会使用const方式提供一个数值 - */ -class PBRMaterial:public Material -{ -public: - - PBRMaterial(const UTF8String & n, - const BlendMode & bm =BlendMode::Opaque, - const bool ts =false, - const bool wf =false): - Material(n,MCC_CNMR,bm,ts,wf){} - - virtual ~PBRMaterial()=default; -};//class PBRMaterial:public Material -MATERIAL_NAMESPACE_END -#endif//HGL_GRAPH_MATERIAL_PBR_INCLUDE diff --git a/inc/hgl/graph/material/StandardMaterial.h b/inc/hgl/graph/material/StandardMaterial.h deleted file mode 100644 index dbe81d95..00000000 --- a/inc/hgl/graph/material/StandardMaterial.h +++ /dev/null @@ -1,40 +0,0 @@ -#ifndef HGL_GRAPH_MATERIAL_STANDARD_INCLUDE -#define HGL_GRAPH_MATERIAL_STANDARD_INCLUDE - -#include -MATERIAL_NAMESPACE_BEGIN -/** - * 传统标准材质 - */ -class StandardMaterial:public Material -{ -public: - - enum class DataSource - { - Const, - Param, - Texture, - Position, - };// - - struct - { - Component comp; ///<成份 - DataSource source; ///<来源 - DataFormat format; ///<数据格式 - }; - -public: - - StandardMaterial( const UTF8String & n, - const ComponentBitsConfig & cbf, - const BlendMode & bm =BlendMode::Opaque, - const bool ts =false, - const bool wf =false): - Material(n,cbf,bm,ts,wf){} - - virtual ~StandardMaterial()=default; -};//class StandardMaterial:public Material -MATERIAL_NAMESPACE_END -#endif//HGL_GRAPH_MATERIAL_STANDARD_INCLUDE diff --git a/inc/hgl/graph/shader/ShaderResource.h b/inc/hgl/graph/shader/ShaderResource.h deleted file mode 100644 index 1a39091e..00000000 --- a/inc/hgl/graph/shader/ShaderResource.h +++ /dev/null @@ -1,98 +0,0 @@ -#pragma once -#include -#include -#include -#include - -VK_NAMESPACE_BEGIN -struct ShaderStage -{ - AnsiString name; - uint location; - - VertexAttribType type; ///<成份数量(如vec4中的4) - VkFormat format; ///<对应的Vulkan格式(如vec4对应的FMT_RGBA32F) - - uint binding; -};//struct ShaderStage - -using ShaderStageList =ObjectList; -using DescriptorSetList =List; -using DescriptorBindingList =List; - -struct ShaderDescriptorList -{ - AnsiStringList name_list; - DescriptorSetList set_list; - DescriptorBindingList binding_list; -}; - -#ifndef VK_DESCRIPTOR_TYPE_BEGIN_RANGE -constexpr size_t VK_DESCRIPTOR_TYPE_BEGIN_RANGE=VK_DESCRIPTOR_TYPE_SAMPLER; -#endif//VK_DESCRIPTOR_TYPE_BEGIN_RANGE - -#ifndef VK_DESCRIPTOR_TYPE_END_RANGE -constexpr size_t VK_DESCRIPTOR_TYPE_END_RANGE=VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT; -#endif//VK_DESCRIPTOR_TYPE_END_RANGE - -#ifndef VK_DESCRIPTOR_TYPE_RANGE_SIZE -constexpr size_t VK_DESCRIPTOR_TYPE_RANGE_SIZE=VK_DESCRIPTOR_TYPE_END_RANGE-VK_DESCRIPTOR_TYPE_BEGIN_RANGE+1; -#endif//VK_DESCRIPTOR_TYPE_RANGE_SIZE - -class ShaderResource -{ - VkShaderStageFlagBits stage_flag; - - const void *spv_data; - uint32 spv_size; - - ShaderStageList stage_inputs; - ShaderStageList stage_outputs; - - ShaderDescriptorList descriptor_list[VK_DESCRIPTOR_TYPE_RANGE_SIZE]; - -public: - - ShaderResource(const VkShaderStageFlagBits &,const void *,const uint32); - virtual ~ShaderResource()=default; - - const VkShaderStageFlagBits GetStage ()const {return stage_flag;} - - const uint32_t * GetCode ()const {return (uint32_t *)spv_data;} - const uint32_t GetCodeSize ()const {return spv_size;} - - ShaderStageList & GetStageInputs () {return stage_inputs;} - ShaderStageList & GetStageOutputs () {return stage_outputs;} - - const uint GetStageInputCount ()const {return stage_inputs.GetCount();} - const uint GetStageOutputCount ()const {return stage_outputs.GetCount();} - - const ShaderStage * GetStageInput (const AnsiString &)const; - const int GetStageInputBinding(const AnsiString &)const; - - const ShaderDescriptorList * GetDescriptorList ()const {return descriptor_list;} - ShaderDescriptorList * GetDescriptorList (VkDescriptorType desc_type) - { - if(desc_typeVK_DESCRIPTOR_TYPE_END_RANGE)return nullptr; - - return descriptor_list+desc_type; - } - - ShaderDescriptorList &GetUBO (){return descriptor_list[VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER];} - ShaderDescriptorList &GetSSBO (){return descriptor_list[VK_DESCRIPTOR_TYPE_STORAGE_BUFFER];} - ShaderDescriptorList &GetSampler(){return descriptor_list[VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER];} - - const int GetBinding (VkDescriptorType desc_type,const AnsiString &name)const; - const DescriptorBindingList * GetBindingList (VkDescriptorType desc_type)const - { - if(desc_typeVK_DESCRIPTOR_TYPE_END_RANGE)return nullptr; - - return &(descriptor_list[desc_type].binding_list); - } -};//class ShaderResource - -ShaderResource *LoadShaderResource(const uint8 *origin_filedata,const int64 filesize,bool include_file_header); -ShaderResource *LoadShaderResoruce(const OSString &filename); -VK_NAMESPACE_END \ No newline at end of file diff --git a/inc/hgl/graph/vulkan/VK.h b/inc/hgl/graph/vulkan/VK.h deleted file mode 100644 index b8326eff..00000000 --- a/inc/hgl/graph/vulkan/VK.h +++ /dev/null @@ -1,160 +0,0 @@ -#ifndef HGL_GRAPH_VULKAN_INCLUDE -#define HGL_GRAPH_VULKAN_INCLUDE - -#include -#include -#include -#include -#include -#include - -VK_NAMESPACE_BEGIN - -using CharPointerList=hgl::List; - -class Instance; -class PhysicalDevice; -class Device; -struct DeviceAttribute; -class ImageView; -class Framebuffer; -struct Swapchain; -class RenderTarget; -class SwapchainRenderTarget; - -class Texture; -class Texture1D; -class Texture1DArray; -class Texture2D; -class Texture2DArray; -class Texture3D; -class TextureCubemap; -class TextureCubemapArray; - -class Sampler; - -class Memory; -class Buffer; -struct BufferData; - -class VertexAttribBuffer; -using VAB=VertexAttribBuffer; - -class IndexBuffer; - -class CommandBuffer; -class RenderPass; -class Fence; -class Semaphore; - -struct ShaderStage; - -class ShaderModuleMap; -class ShaderModule; -class ShaderModuleManage; -class VertexShaderModule; -class Material; -class MaterialInstance; -class PipelineLayout; -class Pipeline; -class DescriptorSets; -class VertexAttributeBinding; - -class Renderable; - -class Database; - -enum class SharingMode -{ - Exclusive = 0, - Concurrent -};// - -enum ImageTiling -{ - Optimal=0, - Linear -};// - -enum IndexType -{ - U16=0, - U32 -}; - -enum class ShaderStageBit -{ - Vertex =VK_SHADER_STAGE_VERTEX_BIT, - TessControl =VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, - TessEval =VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, - Geometry =VK_SHADER_STAGE_GEOMETRY_BIT, - Fragment =VK_SHADER_STAGE_FRAGMENT_BIT, - Compute =VK_SHADER_STAGE_COMPUTE_BIT -};//enum class ShaderStageBit - -inline const uint GetShaderCountByBits(const uint32_t bits) -{ - uint comp=(uint)VK_SHADER_STAGE_VERTEX_BIT; - uint result=0; - - for(uint i=0;i<6;i++) - { - if(bits&comp) - ++result; - - comp<<=1; - } - - return result; -} - -/** - * max-lengths: - * - 256 bytes: nvidia,arm - 128 bytes: amd,intel,powervr,adreno - */ -struct PushConstant -{ - Matrix4f local_to_world; -}; - -constexpr uint32_t MAX_PUSH_CONSTANT_BYTES=sizeof(PushConstant); - -inline void copy(VkExtent3D &e3d,const VkExtent2D &e2d,const uint32 depth=1) -{ - e3d.width =e2d.width; - e3d.height =e2d.height; - e3d.depth =depth; -} - -inline void debug_out(const hgl::List &layer_properties) -{ - const int property_count=layer_properties.GetCount(); - - if(property_count<=0)return; - - const VkLayerProperties *lp=layer_properties.GetData(); - - for(int i=0;ilayerName<<" desc: "<description< &extension_properties) -{ - const int extension_count=extension_properties.GetCount(); - - if(extension_count<=0)return; - - VkExtensionProperties *ep=extension_properties.GetData(); - for(int i=0;iextensionName<<" ver: "<specVersion< -#include -VK_NAMESPACE_BEGIN -struct BufferData -{ - VkBuffer buffer; - Memory * memory=nullptr; - VkDescriptorBufferInfo info; -};//struct BufferData - -class Buffer -{ -protected: - - VkDevice device; - BufferData buf; - -private: - - friend class Device; - friend class VertexAttribBuffer; - friend class IndexBuffer; - - Buffer(VkDevice d,const BufferData &b) - { - device=d; - buf=b; - } - -public: - - virtual ~Buffer(); - - VkBuffer GetBuffer (){return buf.buffer;} - Memory * GetMemory (){return buf.memory;} - const VkDescriptorBufferInfo * GetBufferInfo()const{return &buf.info;} - - void * Map () {return buf.memory->Map();} - virtual void * Map (VkDeviceSize start,VkDeviceSize size) {return buf.memory->Map(start,size);} - void Unmap () {return buf.memory->Unmap();} - - bool Write (const void *ptr,uint32_t start,uint32_t size) {return buf.memory->Write(ptr,start,size);} - bool Write (const void *ptr,uint32_t size) {return buf.memory->Write(ptr,0,size);} - bool Write (const void *ptr) {return buf.memory->Write(ptr);} -};//class Buffer - -class VertexAttribBuffer:public Buffer -{ - VkFormat format; ///<数据格式 - uint32_t stride; ///<单个数据字节数 - uint32_t count; ///<数据数量 - -private: - - friend class Device; - - VertexAttribBuffer(VkDevice d,const BufferData &vb,VkFormat fmt,uint32_t _stride,uint32_t _count):Buffer(d,vb) - { - format=fmt; - stride=_stride; - count=_count; - } - -public: - - ~VertexAttribBuffer()=default; - - const VkFormat GetFormat()const { return format; } - const uint32_t GetStride()const { return stride; } - const uint32_t GetCount ()const { return count; } - - void *Map(VkDeviceSize start=0,VkDeviceSize size=0) override - { - return Buffer::Map(start*stride,size*stride); - } -};//class VertexAttribBuffer:public Buffer - -using VAB=VertexAttribBuffer; - -class IndexBuffer:public Buffer -{ - IndexType index_type; - uint32_t count; - -private: - - friend class Device; - - IndexBuffer(VkDevice d,const BufferData &vb,IndexType it,uint32_t _count):Buffer(d,vb) - { - index_type=it; - count=_count; - } - -public: - - ~IndexBuffer()=default; - - const IndexType GetType ()const{return index_type;} - const uint32 GetCount()const{return count;} -};//class IndexBuffer:public Buffer -VK_NAMESPACE_END -#endif//HGL_GRAPH_VULKAN_BUFFER_INCLUDE diff --git a/inc/hgl/graph/vulkan/VKCommandBuffer.h b/inc/hgl/graph/vulkan/VKCommandBuffer.h deleted file mode 100644 index 1a64efb2..00000000 --- a/inc/hgl/graph/vulkan/VKCommandBuffer.h +++ /dev/null @@ -1,161 +0,0 @@ -#ifndef HGL_GRAPH_VULKAN_COMMAND_BUFFER_INCLUDE -#define HGL_GRAPH_VULKAN_COMMAND_BUFFER_INCLUDE - -#include -#include -#include -VK_NAMESPACE_BEGIN -//push constant 一般只有128/256字节,仅能存在矩阵。 -//所以我们将每个对象的独立变换矩阵存在push constant中 -class CommandBuffer -{ - VkDevice device; - VkCommandPool pool; - VkCommandBuffer cmd_buf; - - uint32_t cv_count; - VkClearValue *clear_values; - VkRect2D render_area; - VkViewport viewport; - - float default_line_width; - - VkPipelineLayout pipeline_layout; - -public: - - CommandBuffer(VkDevice dev,const VkExtent2D &extent,const uint32_t att_count,VkCommandPool cp,VkCommandBuffer cb); - ~CommandBuffer(); - - operator VkCommandBuffer(){return cmd_buf;} - operator const VkCommandBuffer()const{return cmd_buf;} - operator const VkCommandBuffer *()const{return &cmd_buf;} - - void SetRenderArea(const VkRect2D &ra){render_area=ra;} - void SetRenderArea(const VkExtent2D &); - void SetViewport(const VkViewport &vp){viewport=vp;} - - void SetClearColor(uint32_t index,float r,float g,float b,float a=1.0f) - { - if(index>=cv_count)return; - - VkClearValue *cv=clear_values+index; - - cv->color.float32[0]=r; - cv->color.float32[1]=g; - cv->color.float32[2]=b; - cv->color.float32[3]=a; - } - - void SetClearDepthStencil(uint32_t index,float d=1.0f,float s=0) - { - if(index>=cv_count)return; - - VkClearValue *cv=clear_values+index; - - cv->depthStencil.depth=d; - cv->depthStencil.stencil=s; - } - - //以上设定在Begin开始后即不可改变 - - bool Begin(); - - void PipelineBarrier( - VkPipelineStageFlags srcStageMask, - VkPipelineStageFlags dstStageMask, - VkDependencyFlags dependencyFlags, - uint32_t memoryBarrierCount, - const VkMemoryBarrier * pMemoryBarriers, - uint32_t bufferMemoryBarrierCount, - const VkBufferMemoryBarrier * pBufferMemoryBarriers, - uint32_t imageMemoryBarrierCount, - const VkImageMemoryBarrier * pImageMemoryBarriers) - { - vkCmdPipelineBarrier(cmd_buf,srcStageMask,dstStageMask,dependencyFlags,memoryBarrierCount,pMemoryBarriers,bufferMemoryBarrierCount,pBufferMemoryBarriers,imageMemoryBarrierCount,pImageMemoryBarriers); - } - - void CopyBufferToImage( - VkBuffer srcBuffer, - VkImage dstImage, - VkImageLayout dstImageLayout, - uint32_t regionCount, - const VkBufferImageCopy * pRegions) - { - vkCmdCopyBufferToImage(cmd_buf,srcBuffer,dstImage,dstImageLayout,regionCount,pRegions); - } - - void CopyImageToBuffer( - VkImage srcImage, - VkImageLayout srcImageLayout, - VkBuffer dstBuffer, - uint32_t regionCount, - const VkBufferImageCopy * pRegions) - { - vkCmdCopyImageToBuffer(cmd_buf,srcImage,srcImageLayout,dstBuffer,regionCount,pRegions); - } - - bool BeginRenderPass(VkRenderPass rp,VkFramebuffer fb); - bool BeginRenderPass(RenderTarget *rt); - - bool Bind(Pipeline *p) - { - if(!p)return(false); - - vkCmdBindPipeline(cmd_buf,VK_PIPELINE_BIND_POINT_GRAPHICS,*p); - return(true); - } - - bool Bind(DescriptorSets *dsl) - { - if(!dsl)return(false); - - pipeline_layout=dsl->GetPipelineLayout(); - - vkCmdBindDescriptorSets(cmd_buf,VK_PIPELINE_BIND_POINT_GRAPHICS,pipeline_layout,0,1,dsl->GetDescriptorSets(),0,nullptr); - - return(true); - } - - void PushConstants(ShaderStageBit shader_stage_bit,uint32_t offset,uint32_t size,const void *pValues) - { - vkCmdPushConstants(cmd_buf,pipeline_layout,(VkShaderStageFlagBits)shader_stage_bit,offset,size,pValues); - } - - void PushConstants(const void *data,const uint32_t size){vkCmdPushConstants(cmd_buf,pipeline_layout,VK_SHADER_STAGE_VERTEX_BIT,0,size,data);} - - bool Bind(Renderable *); - - void SetViewport (uint32_t first,uint32_t count,const VkViewport *vp) {vkCmdSetViewport(cmd_buf,first,count,vp);} - void SetScissor (uint32_t first,uint32_t count,const VkRect2D *sci) {vkCmdSetScissor(cmd_buf,first,count,sci);} - - void SetLineWidth (float line_width) {vkCmdSetLineWidth(cmd_buf,line_width);} - - void SetDepthBias (float constant_factor,float clamp,float slope_factor) {vkCmdSetDepthBias(cmd_buf,constant_factor,clamp,slope_factor);} - void SetDepthBounds (float min_db,float max_db) {vkCmdSetDepthBounds(cmd_buf,min_db,max_db);} - void SetBlendConstants (const float constants[4]) {vkCmdSetBlendConstants(cmd_buf,constants);} - - void SetStencilCompareMask (VkStencilFaceFlags faceMask,uint32_t compareMask) {vkCmdSetStencilCompareMask(cmd_buf,faceMask,compareMask);} - void SetStencilWriteMask (VkStencilFaceFlags faceMask,uint32_t compareMask) {vkCmdSetStencilWriteMask(cmd_buf,faceMask,compareMask);} - void SetStencilReference (VkStencilFaceFlags faceMask,uint32_t compareMask) {vkCmdSetStencilReference(cmd_buf,faceMask,compareMask);} - - void Draw (const uint32_t vertex_count){vkCmdDraw(cmd_buf,vertex_count,1,0,0);} - void DrawIndexed(const uint32_t index_count ){vkCmdDrawIndexed(cmd_buf,index_count,1,0,0,0);} - - void Draw (const uint32_t vertex_count, const uint32_t instance_count,const uint32_t first_vertex, const uint32_t first_instance) - { - vkCmdDraw(cmd_buf,vertex_count,instance_count,first_vertex,first_instance); - } - - void DrawIndexed(const uint32_t index_count, const uint32_t instance_count,const uint32_t first_index, const uint32_t vertex_offset,const uint32_t first_instance) - { - vkCmdDrawIndexed(cmd_buf,index_count,instance_count,first_index,vertex_offset,first_instance); - } - - void NextSubpass(){vkCmdNextSubpass(cmd_buf,VK_SUBPASS_CONTENTS_INLINE);} - - void EndRenderPass(){vkCmdEndRenderPass(cmd_buf);} - bool End(){return(vkEndCommandBuffer(cmd_buf)==VK_SUCCESS);} -};//class CommandBuffer -VK_NAMESPACE_END -#endif//HGL_GRAPH_VULKAN_COMMAND_BUFFER_INCLUDE diff --git a/inc/hgl/graph/vulkan/VKDescriptorSets.h b/inc/hgl/graph/vulkan/VKDescriptorSets.h deleted file mode 100644 index 09907cf8..00000000 --- a/inc/hgl/graph/vulkan/VKDescriptorSets.h +++ /dev/null @@ -1,49 +0,0 @@ -#ifndef HGL_GRAPH_VULKAN_DESCRIPTOR_SETS_LAYOUT_INCLUDE -#define HGL_GRAPH_VULKAN_DESCRIPTOR_SETS_LAYOUT_INCLUDE - -#include -#include -VK_NAMESPACE_BEGIN -class Device; -class Buffer; - -class DescriptorSets -{ - Device *device; - int count; - VkDescriptorSet desc_set; - const Map *index_by_binding; - - VkPipelineLayout pipeline_layout; - - ObjectList desc_image_info; - List wds_list; - -private: - - friend class DescriptorSetLayoutCreater; - - DescriptorSets(Device *dev,const int c,VkPipelineLayout pl,VkDescriptorSet ds,const Map *bi):index_by_binding(bi) - { - device=dev; - count=c; - desc_set=ds; - pipeline_layout=pl; - } - -public: - - ~DescriptorSets()=default; - - const uint32_t GetCount ()const{return count;} - const VkDescriptorSet * GetDescriptorSets ()const{return &desc_set;} - const VkPipelineLayout GetPipelineLayout ()const{return pipeline_layout;} - - void Clear(); - bool BindUBO(const int binding,const Buffer *); - bool BindUBODynamic(const int binding,const Buffer *); - bool BindSampler(const int binding,Texture *,Sampler *); - void Update(); -};//class DescriptorSets -VK_NAMESPACE_END -#endif//HGL_GRAPH_VULKAN_DESCRIPTOR_SETS_LAYOUT_INCLUDE diff --git a/inc/hgl/graph/vulkan/VKDevice.h b/inc/hgl/graph/vulkan/VKDevice.h deleted file mode 100644 index 44168ded..00000000 --- a/inc/hgl/graph/vulkan/VKDevice.h +++ /dev/null @@ -1,274 +0,0 @@ -#ifndef HGL_GRAPH_RENDER_SURFACE_INCLUDE -#define HGL_GRAPH_RENDER_SURFACE_INCLUDE - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace hgl -{ - namespace graph - { - class TileData; - class TileFont; - class FontSource; - }//namespace graph -}//namespace hgl - -VK_NAMESPACE_BEGIN -class Device -{ - DeviceAttribute *attr; - - SubmitQueue *textureSQ; - CommandBuffer *texture_cmd_buf; - - Swapchain *swapchain; - SwapchainRenderTarget *swapchainRT; - - bool CreateSwapchainColorTexture(); - bool CreateSwapchainDepthTexture(); - - bool CreateSwapchain(const VkExtent2D &acquire_extent); - -private: - - friend Device *CreateRenderDevice(VkInstance inst,const PhysicalDevice *physical_device,VkSurfaceKHR surface,const VkExtent2D &extent); - - Device(DeviceAttribute *da); - -public: - - virtual ~Device(); - - operator VkDevice () {return attr->device;} - DeviceAttribute * GetDeviceAttribute () {return attr;} - - VkSurfaceKHR GetSurface () {return attr->surface;} - VkDevice GetDevice () {return attr->device;} - const PhysicalDevice * GetPhysicalDevice ()const {return attr->physical_device;} - - VkDescriptorPool GetDescriptorPool () {return attr->desc_pool;} - VkPipelineCache GetPipelineCache () {return attr->pipeline_cache;} - - const VkFormat GetSurfaceFormat ()const {return attr->format;} - VkQueue GetGraphicsQueue () {return attr->graphics_queue;} - - Swapchain * GetSwapchain () {return swapchain;} - - SwapchainRenderTarget * GetSwapchainRT () {return swapchainRT;} - -public: - - const VkExtent2D & GetSwapchainSize ()const {return swapchain->extent;} - - bool Resize (const VkExtent2D &); - bool Resize (const uint32_t &w,const uint32_t &h) - { - VkExtent2D extent={w,h}; - - return Resize(extent); - } - -public: //内存相关 - - Memory *CreateMemory(const VkMemoryRequirements &,const uint32_t properties); - Memory *CreateMemory(VkImage,const uint32 flag=VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); - -private: //Buffer相关 - - bool CreateBuffer(BufferData *buf,VkBufferUsageFlags buf_usage,VkDeviceSize size,const void *data,SharingMode sharing_mode); - -public: //Buffer相关 - - Buffer * CreateBuffer(VkBufferUsageFlags buf_usage,VkDeviceSize size,const void *data, SharingMode sharing_mode=SharingMode::Exclusive); - Buffer * CreateBuffer(VkBufferUsageFlags buf_usage,VkDeviceSize size, SharingMode sharing_mode=SharingMode::Exclusive){return CreateBuffer(buf_usage,size,nullptr,sharing_mode);} - - VAB * CreateVAB (VkFormat format,uint32_t count,const void *data, SharingMode sharing_mode=SharingMode::Exclusive); - VAB * CreateVAB (VkFormat format,uint32_t count, SharingMode sharing_mode=SharingMode::Exclusive){return CreateVAB(format,count,nullptr,sharing_mode);} - VAB * CreateVAB (const VAD *vad, SharingMode sharing_mode=SharingMode::Exclusive){return CreateVAB(vad->GetVulkanFormat(),vad->GetCount(),vad->GetData(),sharing_mode);} - - IndexBuffer * CreateIBO (IndexType index_type,uint32_t count,const void * data,SharingMode sharing_mode=SharingMode::Exclusive); - IndexBuffer * CreateIBO16 ( uint32_t count,const uint16 *data,SharingMode sharing_mode=SharingMode::Exclusive){return CreateIBO(IndexType::U16,count,(void *)data,sharing_mode);} - IndexBuffer * CreateIBO32 ( uint32_t count,const uint32 *data,SharingMode sharing_mode=SharingMode::Exclusive){return CreateIBO(IndexType::U32,count,(void *)data,sharing_mode);} - - IndexBuffer * CreateIBO (IndexType index_type,uint32_t count,SharingMode sharing_mode=SharingMode::Exclusive){return CreateIBO(index_type,count,nullptr,sharing_mode);} - IndexBuffer * CreateIBO16 ( uint32_t count,SharingMode sharing_mode=SharingMode::Exclusive){return CreateIBO(IndexType::U16,count,nullptr,sharing_mode);} - IndexBuffer * CreateIBO32 ( uint32_t count,SharingMode sharing_mode=SharingMode::Exclusive){return CreateIBO(IndexType::U32,count,nullptr,sharing_mode);} - -#define CREATE_BUFFER_OBJECT(LargeName,type) Buffer *Create##LargeName(VkDeviceSize size,void *data,SharingMode sharing_mode=SharingMode::Exclusive){return CreateBuffer(VK_BUFFER_USAGE_##type##_BUFFER_BIT,size,data,sharing_mode);} \ - Buffer *Create##LargeName(VkDeviceSize size,SharingMode sharing_mode=SharingMode::Exclusive){return CreateBuffer(VK_BUFFER_USAGE_##type##_BUFFER_BIT,size,nullptr,sharing_mode);} - - CREATE_BUFFER_OBJECT(UBO,UNIFORM) - CREATE_BUFFER_OBJECT(SSBO,STORAGE) - CREATE_BUFFER_OBJECT(INBO,INDIRECT) - -#undef CREATE_BUFFER_OBJECT - -public: //Image - - VkImage CreateImage1D (const VkFormat format,const uint32_t width, const uint usage,const ImageTiling tiling); - VkImage CreateImage1DArray (const VkFormat format,const uint32_t width,const uint32_t layer, const uint usage,const ImageTiling tiling); - VkImage CreateImage2D (const VkFormat format,const uint32_t width,const uint32_t height, const uint usage,const ImageTiling tiling); - VkImage CreateImage2DArray (const VkFormat format,const uint32_t width,const uint32_t height,const uint32_t layer, const uint usage,const ImageTiling tiling); - VkImage CreateImage3D (const VkFormat format,const uint32_t width,const uint32_t height,const uint32_t depth, const uint usage,const ImageTiling tiling); - VkImage CreateCubemap (const VkFormat format,const uint32_t width,const uint32_t height, const uint usage,const ImageTiling tiling); -// VkImage CreateCubemapArray (const VkFormat format,const uint32_t width,const uint32_t height,const uint32_t count, const uint usage,const ImageTiling tiling); - - void DestoryImage (VkImage); - -public: //Texture - - Texture2D *CreateTexture2D(Memory *mem,VkImage image,ImageView *image_view,VkImageLayout image_layout,ImageTiling tiling); - Texture2D *CreateTexture2D(VkFormat format,uint32_t width,uint32_t height,VkImageAspectFlagBits aspectMask,VkImage image,VkImageLayout image_layout,ImageTiling tiling=ImageTiling::Optimal); - - Texture2D *CreateTexture2D(const VkFormat format,uint32_t width,uint32_t height,const VkImageAspectFlags aspectMask,const uint usage,const VkImageLayout image_layout,ImageTiling tiling=ImageTiling::Optimal); - - Texture2D *CreateTexture2DColor(const VkFormat video_format,uint32_t width,uint32_t height,const ImageTiling tiling=ImageTiling::Optimal) - { - return CreateTexture2D(video_format,width,height, - VK_IMAGE_ASPECT_COLOR_BIT, - VK_IMAGE_USAGE_TRANSFER_DST_BIT|VK_IMAGE_USAGE_SAMPLED_BIT, - (tiling==ImageTiling::Optimal?VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL:VK_IMAGE_LAYOUT_GENERAL), - tiling); - } - - Texture2D *CreateTexture2DDepth(const VkFormat video_format,uint32_t width,uint32_t height,const ImageTiling tiling=ImageTiling::Optimal) - { - return CreateTexture2D(video_format,width,height, - VK_IMAGE_ASPECT_DEPTH_BIT, - VK_IMAGE_USAGE_TRANSFER_DST_BIT|VK_IMAGE_USAGE_SAMPLED_BIT, - (tiling==ImageTiling::Optimal?VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL:VK_IMAGE_LAYOUT_GENERAL), - tiling); - } - - Texture2D *CreateAttachmentTexture(const VkFormat video_format,uint32_t width,uint32_t height,const VkImageAspectFlags aspectMask,const uint usage,const VkImageLayout image_layout) - { - return CreateTexture2D(video_format,width,height,aspectMask,usage|VK_IMAGE_USAGE_SAMPLED_BIT,image_layout); - } - - Texture2D *CreateAttachmentTextureColor(const VkFormat video_format,uint32_t width,uint32_t height) - { - return CreateAttachmentTexture( video_format,width,height, - VK_IMAGE_ASPECT_COLOR_BIT, - VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, - VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); - } - - Texture2D *CreateAttachmentTextureDepth(const VkFormat video_format,uint32_t width,uint32_t height) - { - return CreateAttachmentTexture( video_format,width,height, - VK_IMAGE_ASPECT_DEPTH_BIT,//|VK_IMAGE_ASPECT_STENCIL_BIT, - VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT|VK_IMAGE_USAGE_TRANSFER_SRC_BIT|VK_IMAGE_USAGE_TRANSFER_DST_BIT, - VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL); - } - - Texture2D *CreateTexture2D( const VkFormat video_format,Buffer *buf,uint32_t width,uint32_t height, - const VkImageAspectFlags aspectMask =VK_IMAGE_ASPECT_COLOR_BIT, - const uint usage =VK_IMAGE_USAGE_TRANSFER_DST_BIT|VK_IMAGE_USAGE_SAMPLED_BIT, - const VkImageLayout image_layout=VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, - const ImageTiling tiling =ImageTiling::Optimal); - - Texture2D *CreateTexture2D( const VkFormat video_format,void *data,uint32_t width,uint32_t height,uint32_t size, - const VkImageAspectFlags aspectMask =VK_IMAGE_ASPECT_COLOR_BIT, - const uint usage =VK_IMAGE_USAGE_TRANSFER_DST_BIT|VK_IMAGE_USAGE_SAMPLED_BIT, - const VkImageLayout image_layout=VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, - const ImageTiling tiling =ImageTiling::Optimal); - - bool ChangeTexture2D(Texture2D *,Buffer *buf,const VkBufferImageCopy *,const int count); - bool ChangeTexture2D(Texture2D *,Buffer *buf,const List &); - - bool ChangeTexture2D(Texture2D *,Buffer *buf,uint32_t left,uint32_t top,uint32_t width,uint32_t height); - bool ChangeTexture2D(Texture2D *,void *data,uint32_t left,uint32_t top,uint32_t width,uint32_t height,uint32_t size); - - template - bool ChangeTexture2D(Texture2D *tex,Buffer *buf,const RectScope2 &rs) - { - return ChangeTexture2D( tex, - buf, - rs.GetLeft(), - rs.GetTop(), - rs.GetWidth(), - rs.GetHeight()); - } - - template - bool ChangeTexture2D(Texture2D *tex,void *data,const RectScope2 &rs,uint32_t size) - { - return ChangeTexture2D( tex, - data, - rs.GetLeft(), - rs.GetTop(), - rs.GetWidth(), - rs.GetHeight(), - size); - } - -public: // - - Sampler *CreateSampler(VkSamplerCreateInfo *sci=nullptr); - - ShaderModuleManage *CreateShaderModuleManage(); - -public: //Command Buffer 相关 - - CommandBuffer * CreateCommandBuffer(const VkExtent2D &extent,const uint32_t atta_count); - - void CreateAttachmentReference(VkAttachmentReference *ref_list,uint start,uint count,VkImageLayout layout)const; - - void CreateColorAttachmentReference(List &ref_list, uint start,uint count )const{ref_list.SetCount(count); CreateAttachmentReference(ref_list.GetData(), start,count,VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);} - void CreateDepthAttachmentReference( VkAttachmentReference *depth_ref, uint index )const{ CreateAttachmentReference(depth_ref, index,1 ,VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);} - void CreateInputAttachment( List &ref_list, uint start,uint count )const{ref_list.SetCount(count); CreateAttachmentReference(ref_list.GetData(), start,count,VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);} - - bool CreateAttachment( List &color_output_desc_list, - const List &color_format, - const VkFormat depth_format, - const VkImageLayout color_final_layout=VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, - const VkImageLayout depth_final_layout=VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)const; - - bool CreateColorAttachment( List &ref_list,List &desc_list,const List &color_format,const VkImageLayout color_final_layout=VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL)const; - bool CreateDepthAttachment( List &ref_list,List &desc_list,const VkFormat &depth_format,const VkImageLayout depth_final_layout=VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)const; - - void CreateSubpassDependency(VkSubpassDependency *); - void CreateSubpassDependency(List &dependency,const uint32_t count)const; - void CreateSubpassDescription(VkSubpassDescription &,const List &color_ref_list,VkAttachmentReference *depth_ref=nullptr)const; - - RenderPass * CreateRenderPass( const List &desc_list, - const List &subpass, - const List &dependency, - const List &color_format, - const VkFormat depth_format, - const VkImageLayout color_final_layout=VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, - const VkImageLayout depth_final_layout=VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)const; - - RenderPass * CreateRenderPass( const VkFormat color_format, - const VkFormat depth_format, - const VkImageLayout color_final_layout=VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, - const VkImageLayout depth_final_layout=VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)const; - - Fence * CreateFence(bool); - vulkan::Semaphore * CreateSem(); - -public: - - bool SubmitTexture (const VkCommandBuffer *cmd_bufs,const uint32_t count=1); ///<提交纹理处理到队列 - - RenderTarget *CreateRenderTarget(Framebuffer *); - - TileData *CreateTileData(const VkFormat video_format,const uint width,const uint height,const uint count); ///<创建一个Tile数据集 - - TileFont *CreateTileFont(FontSource *fs,int limit_count=-1); ///<创建一个Tile字体 -};//class Device - -Device *CreateRenderDevice(Instance *inst,Window *win,const PhysicalDevice *physical_device=nullptr); -VK_NAMESPACE_END -#endif//HGL_GRAPH_RENDER_SURFACE_INCLUDE diff --git a/inc/hgl/graph/vulkan/VKFramebuffer.h b/inc/hgl/graph/vulkan/VKFramebuffer.h deleted file mode 100644 index dacf25d4..00000000 --- a/inc/hgl/graph/vulkan/VKFramebuffer.h +++ /dev/null @@ -1,55 +0,0 @@ -#ifndef HGL_GRAPH_VULKAN_FRAMEBUFFER_INCLUDE -#define HGL_GRAPH_VULKAN_FRAMEBUFFER_INCLUDE - -#include -VK_NAMESPACE_BEGIN -class Framebuffer -{ - VkDevice device; - VkFramebuffer frame_buffer; - VkFramebufferCreateInfo *fb_info; - - VkExtent2D extent; - uint32_t color_count; - bool has_depth; - -private: - - friend Framebuffer *CreateFramebuffer(Device *dev,RenderPass *rp,ImageView **color_list,const uint color_count,ImageView *depth); - - Framebuffer(VkDevice dev,VkFramebuffer fb,VkFramebufferCreateInfo *fb_create_info,bool depth) - { - device=dev; - frame_buffer=fb; - fb_info=fb_create_info; - - extent.width=fb_info->width; - extent.height=fb_info->height; - - has_depth=depth; - if(has_depth) - color_count=fb_info->attachmentCount-1; - else - color_count=fb_info->attachmentCount; - } - -public: - - ~Framebuffer(); - - const VkFramebuffer GetFramebuffer ()const{return frame_buffer;} - const VkRenderPass GetRenderPass ()const{return fb_info->renderPass;} - - const VkExtent2D & GetExtent ()const{return extent;} - - const uint32_t GetAttachmentCount ()const{return fb_info->attachmentCount;} ///<获取渲染目标成分数量 - const uint32_t GetColorCount ()const{return color_count;} ///<取得颜色成分数量 - const bool HasDepth ()const{return has_depth;} ///<是否包含深度成分 -};//class Framebuffer - -Framebuffer *CreateFramebuffer(Device *,RenderPass *,List &color,ImageView *depth); -Framebuffer *CreateFramebuffer(Device *,RenderPass *,List &image_view_list); -Framebuffer *CreateFramebuffer(Device *,RenderPass *,ImageView *color,ImageView *depth=nullptr); -Framebuffer *CreateFramebuffer(Device *,RenderPass *,ImageView *depth); -VK_NAMESPACE_END -#endif//HGL_GRAPH_VULKAN_FRAMEBUFFER_INCLUDE diff --git a/inc/hgl/graph/vulkan/VKImageView.h b/inc/hgl/graph/vulkan/VKImageView.h deleted file mode 100644 index ac8061b8..00000000 --- a/inc/hgl/graph/vulkan/VKImageView.h +++ /dev/null @@ -1,64 +0,0 @@ -#ifndef HGL_GRAPH_VULKAN_IMAGE_VIEW_INCLUDE -#define HGL_GRAPH_VULKAN_IMAGE_VIEW_INCLUDE - -#include -VK_NAMESPACE_BEGIN -class ImageView -{ -protected: - - VkDevice device; - VkImageView image_view; - - VkImageViewType view_type; - VkFormat format; - VkImageAspectFlags aspect_mask; - - VkExtent3D extent; - -private: - - friend ImageView *CreateImageView(VkDevice device,VkImageViewType type,VkFormat format,const VkExtent3D &ext,VkImageAspectFlags aspectMask,VkImage img); - - ImageView(VkDevice dev,VkImageView iv,const VkImageViewType vt,const VkFormat fmt,const VkExtent3D &ext,const VkImageAspectFlags am) - { - device =dev; - image_view =iv; - view_type =vt; - format =fmt; - aspect_mask =am; - extent =ext; - } - -public: - - virtual ~ImageView(); - - operator VkImageView(){return image_view;} - -public: - - const VkImageViewType GetViewType ()const{return view_type;} - const VkFormat GetFormat ()const{return format;} - const VkExtent3D & GetExtent ()const{return extent;} - const VkImageAspectFlags GetAspectFlags ()const{return aspect_mask;} -};//class ImageView - -ImageView *CreateImageView(VkDevice device,VkImageViewType type,VkFormat format,const VkExtent3D &ext,VkImageAspectFlags aspectMask,VkImage img); - -#define CREATE_IMAGE_VIEW(short_name,larget_name) \ - inline ImageView *CreateImageView##short_name(VkDevice device,VkFormat format,const VkExtent3D &ext,VkImageAspectFlags aspectMask,VkImage img=VK_NULL_HANDLE) \ - { \ - return CreateImageView(device,VK_IMAGE_VIEW_TYPE_##larget_name,format,ext,aspectMask,img); \ - } - - CREATE_IMAGE_VIEW(1D,1D); - CREATE_IMAGE_VIEW(2D,2D); - CREATE_IMAGE_VIEW(3D,3D); - CREATE_IMAGE_VIEW(Cube,CUBE); - CREATE_IMAGE_VIEW(1DArray,1D_ARRAY); - CREATE_IMAGE_VIEW(2DArray,2D_ARRAY); - CREATE_IMAGE_VIEW(CubeArray,CUBE_ARRAY); -#undef CREATE_IMAGE_VIEW -VK_NAMESPACE_END -#endif//HGL_GRAPH_VULKAN_IMAGE_VIEW_INCLUDE diff --git a/inc/hgl/graph/vulkan/VKInstance.h b/inc/hgl/graph/vulkan/VKInstance.h deleted file mode 100644 index dcb612a9..00000000 --- a/inc/hgl/graph/vulkan/VKInstance.h +++ /dev/null @@ -1,83 +0,0 @@ -#ifndef HGL_GRAPH_VULKAN_INSTANCE_INCLUDE -#define HGL_GRAPH_VULKAN_INSTANCE_INCLUDE - -#include -#include -#include -#include -#include - -VK_NAMESPACE_BEGIN - #define VK_BOOL1BIT(name) bool name:1; - struct CreateInstanceLayerInfo - { - struct - { - VK_BOOL1BIT(api_dump) - VK_BOOL1BIT(device_simulation) - VK_BOOL1BIT(monitor) - VK_BOOL1BIT(screenshot) - VK_BOOL1BIT(standard_validation) - VK_BOOL1BIT(vktrace) - }lunarg; - - struct - { - VK_BOOL1BIT(validation) - }khronos; - - struct - { - VK_BOOL1BIT(optimus) - }nv; - - struct - { - VK_BOOL1BIT(steam_overlay) - VK_BOOL1BIT(steam_fossilize) - }valve; - - struct - { - VK_BOOL1BIT(Capture) - }RenderDoc; - - struct - { - VK_BOOL1BIT(helper); - }bandicam; - }; - #undef VK_BOOL1BIT - - class Instance - { - VkInstance inst; - - VKDebugOut *debug_out; - - ObjectList physical_devices; - - private: - - friend Instance *CreateInstance(const AnsiString &app_name,VKDebugOut *out=nullptr,CreateInstanceLayerInfo *cili=nullptr); - - Instance(VkInstance,VKDebugOut *); - - public: - - virtual ~Instance(); - - operator VkInstance (){return inst;} - - const ObjectList &GetDeviceList ()const {return physical_devices;} - const PhysicalDevice * GetDevice (VkPhysicalDeviceType)const; - };//class Instance - - void InitVulkanProperties(); - const List & GetLayerProperties(); - const List & GetExtensionProperties(); - const bool CheckLayerSupport(const char *); - - Instance *CreateInstance(const AnsiString &,VKDebugOut *,CreateInstanceLayerInfo *); ///<创建一个Vulkan实例 -VK_NAMESPACE_END -#endif//HGL_GRAPH_VULKAN_INSTANCE_INCLUDE diff --git a/inc/hgl/graph/vulkan/VKMaterial.h b/inc/hgl/graph/vulkan/VKMaterial.h deleted file mode 100644 index 5c7c300e..00000000 --- a/inc/hgl/graph/vulkan/VKMaterial.h +++ /dev/null @@ -1,63 +0,0 @@ -#ifndef HGL_GRAPH_VULKAN_MATERIAL_INCLUDE -#define HGL_GRAPH_VULKAN_MATERIAL_INCLUDE - -#include -#include -#include -VK_NAMESPACE_BEGIN -class DescriptorSetLayoutCreater; - -/** - * 材质类
- * 用于管理shader,提供DescriptorSetLayoutCreater - */ -class Material -{ - Device *device; - ShaderModuleMap *shader_maps; - VertexShaderModule *vertex_sm; - List *shader_stage_list; - - DescriptorSetLayoutCreater *dsl_creater; - - VertexAttributeBinding *vab; - -public: - - Material(Device *dev,ShaderModuleMap *smm,List *,DescriptorSetLayoutCreater *dslc); - ~Material(); - - const VertexShaderModule *GetVertexShaderModule()const{return vertex_sm;} - - const int GetBinding(VkDescriptorType,const AnsiString &)const; - -#define GET_BO_BINDING(name,vk_name) const int Get##name(const AnsiString &obj_name)const{return GetBinding(VK_DESCRIPTOR_TYPE_##vk_name,obj_name);} -// GET_BO_BINDING(Sampler, SAMPLER) - - GET_BO_BINDING(Sampler, COMBINED_IMAGE_SAMPLER) -// GET_BO_BINDING(SampledImage, SAMPLED_IMAGE) - GET_BO_BINDING(StorageImage, STORAGE_IMAGE) - - GET_BO_BINDING(UTBO, UNIFORM_TEXEL_BUFFER) - GET_BO_BINDING(SSTBO, STORAGE_TEXEL_BUFFER) - GET_BO_BINDING(UBO, UNIFORM_BUFFER) - GET_BO_BINDING(SSBO, STORAGE_BUFFER) - GET_BO_BINDING(UBODynamic, UNIFORM_BUFFER_DYNAMIC) - GET_BO_BINDING(SSBODynamic, STORAGE_BUFFER_DYNAMIC) - - GET_BO_BINDING(InputAttachment, INPUT_ATTACHMENT) - #undef GET_BO_BINDING - - const uint32_t GetStageCount ()const{return shader_stage_list->GetCount();} - const VkPipelineShaderStageCreateInfo * GetStages ()const{return shader_stage_list->GetData();} - - const VkPipelineLayout GetPipelineLayout ()const; - DescriptorSets * CreateDescriptorSets()const; - - void Write(VkPipelineVertexInputStateCreateInfo &vis)const; - - Renderable *CreateRenderable(const uint32_t draw_count=0); - MaterialInstance *CreateInstance(); -};//class Material -VK_NAMESPACE_END -#endif//HGL_GRAPH_VULKAN_MATERIAL_INCLUDE diff --git a/inc/hgl/graph/vulkan/VKMaterialInstance.h b/inc/hgl/graph/vulkan/VKMaterialInstance.h deleted file mode 100644 index 85613c0f..00000000 --- a/inc/hgl/graph/vulkan/VKMaterialInstance.h +++ /dev/null @@ -1,34 +0,0 @@ -#ifndef HGL_GRAPH_VULKAN_MATERIAL_INSTANCE_INCLUDE -#define HGL_GRAPH_VULKAN_MATERIAL_INSTANCE_INCLUDE - -#include -#include -VK_NAMESPACE_BEGIN -class MaterialInstance -{ - Material *material; - - DescriptorSets *descriptor_sets; - -private: - - friend class Material; - - MaterialInstance(Material *,DescriptorSets *); - -public: - - Material * GetMaterial (){return material;} - DescriptorSets *GetDescriptorSets (){return descriptor_sets;} - -public: - - ~MaterialInstance(); - - bool BindUBO(const AnsiString &name,vulkan::Buffer *ubo); - bool BindSampler(const AnsiString &name,Texture *tex,Sampler *sampler); - - void Update(); -};//class MaterialInstance -VK_NAMESPACE_END -#endif//HGL_GRAPH_VULKAN_MATERIAL_INSTANCE_INCLUDE \ No newline at end of file diff --git a/inc/hgl/graph/vulkan/VKPhysicalDevice.h b/inc/hgl/graph/vulkan/VKPhysicalDevice.h deleted file mode 100644 index 77e3b080..00000000 --- a/inc/hgl/graph/vulkan/VKPhysicalDevice.h +++ /dev/null @@ -1,121 +0,0 @@ -#pragma once - -#include -#include -#include - -VK_NAMESPACE_BEGIN -class PhysicalDevice -{ - VkInstance instance=nullptr; - VkPhysicalDevice physical_device=nullptr; - VkPhysicalDeviceFeatures features; - VkPhysicalDeviceProperties properties; - VkPhysicalDeviceDriverPropertiesKHR driver_properties; - VkPhysicalDeviceMemoryProperties memory_properties; - List layer_properties; - List extension_properties; - -public: - - PhysicalDevice(VkInstance,VkPhysicalDevice); - ~PhysicalDevice()=default; - - operator VkPhysicalDevice(){return physical_device;} - operator const VkPhysicalDevice()const{return physical_device;} - - const bool CheckMemoryType(uint32_t,VkMemoryPropertyFlags,uint32_t *)const; - - VkPhysicalDeviceType GetDeviceType()const{return properties.deviceType;} - const char * GetDeviceName()const{return properties.deviceName;} - - const VkPhysicalDeviceFeatures & GetFeatures ()const{return features;} - const VkPhysicalDeviceProperties & GetProperties ()const{return properties;} - const VkPhysicalDeviceMemoryProperties &GetMemoryProperties ()const{return memory_properties;} - - const uint32_t GetExtensionSpecVersion(const AnsiString &name)const; - - const VkDriverIdKHR GetDriverId ()const{return driver_properties.driverID;} - const char * GetDriverName ()const{return driver_properties.driverName;} - const char * GetDriverInfo ()const{return driver_properties.driverInfo;} - -public: - - const uint32_t GetConstantSize()const{return properties.limits.maxPushConstantsSize;} - -public: - - /** - * 获取该设备是否是显卡 - */ - const bool isGPU()const - { - if(properties.deviceType==VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU)return(true); - if(properties.deviceType==VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU)return(true); - if(properties.deviceType==VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU)return(true); - - return(false); - } - - const bool isDiscreteGPU ()const{return(properties.deviceType==VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU);} ///<是否是独立显卡 - const bool isIntegratedGPU ()const{return(properties.deviceType==VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU);} ///<是否是集成显卡 - const bool isVirtualGPU ()const{return(properties.deviceType==VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU);} ///<是否是虚拟显卡 - -public: - - VkFormatProperties GetFormatProperties(const VkFormat format)const - { - VkFormatProperties fp; - - vkGetPhysicalDeviceFormatProperties(physical_device,format,&fp); - - return fp; - } - - bool OptimalSupport (const VkFormat format,const VkFormatFeatureFlags flag)const{VkFormatProperties fp;vkGetPhysicalDeviceFormatProperties(physical_device,format,&fp);return fp.optimalTilingFeatures&flag;} - bool LinearSupport (const VkFormat format,const VkFormatFeatureFlags flag)const{VkFormatProperties fp;vkGetPhysicalDeviceFormatProperties(physical_device,format,&fp);return fp.linearTilingFeatures&flag;} - bool BufferSupport (const VkFormat format,const VkFormatFeatureFlags flag)const{VkFormatProperties fp;vkGetPhysicalDeviceFormatProperties(physical_device,format,&fp);return fp.bufferFeatures&flag;} - - bool IsColorAttachmentOptimal(const VkFormat format)const{return OptimalSupport(format,VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT);} - bool IsDepthAttachmentOptimal(const VkFormat format)const{return OptimalSupport(format,VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT);} - - bool IsColorAttachmentLinear(const VkFormat format)const{return LinearSupport(format,VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT);} - bool IsDepthAttachmentLinear(const VkFormat format)const{return LinearSupport(format,VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT);} - - bool IsColorAttachmentBuffer(const VkFormat format)const{return BufferSupport(format,VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT);} - bool IsDepthAttachmentBuffer(const VkFormat format)const{return BufferSupport(format,VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT);} - - VkFormat GetDepthFormat(bool lower_to_high=true)const; - VkFormat GetDepthStencilFormat(bool lower_to_high=true)const; - -public: - - const uint32_t GetMaxImage1D ()const{return properties.limits.maxImageDimension1D;} - const uint32_t GetMaxImage2D ()const{return properties.limits.maxImageDimension2D;} - const uint32_t GetMaxImage3D ()const{return properties.limits.maxImageDimension3D;} - const uint32_t GetMaxImageCube ()const{return properties.limits.maxImageDimensionCube;} - const uint32_t GetMaxImageArrayLayers ()const{return properties.limits.maxImageArrayLayers;} - const uint32_t GetMaxUBORange ()const{return properties.limits.maxUniformBufferRange;} - const uint32_t GetMaxSSBORange ()const{return properties.limits.maxStorageBufferRange;} - const uint32_t GetMaxBoundDescriptorSets()const{return properties.limits.maxBoundDescriptorSets;} - - const uint32_t GetMaxVertexInputAttributes ()const{return properties.limits.maxVertexInputAttributes;} - const uint32_t GetMaxVertexInputBindings ()const{return properties.limits.maxVertexInputBindings;} - - const uint32_t GetMaxColorAttachments ()const{return properties.limits.maxColorAttachments;} - - const void GetPointSize(float &granularity,float &min_size,float &max_size) - { - granularity =properties.limits.pointSizeGranularity; - min_size =properties.limits.pointSizeRange[0]; - max_size =properties.limits.pointSizeRange[1]; - } - - const void GetLineWidth(float &granularity,float &min_width,float &max_width) - { - granularity =properties.limits.lineWidthGranularity; - min_width =properties.limits.lineWidthRange[0]; - max_width =properties.limits.lineWidthRange[1]; - } -};//class PhysicalDevice -VK_NAMESPACE_END diff --git a/inc/hgl/graph/vulkan/VKPipeline.h b/inc/hgl/graph/vulkan/VKPipeline.h deleted file mode 100644 index 23aada8f..00000000 --- a/inc/hgl/graph/vulkan/VKPipeline.h +++ /dev/null @@ -1,199 +0,0 @@ -#ifndef HGL_GRAPH_VULKAN_PIPELINE_INCLUDE -#define HGL_GRAPH_VULKAN_PIPELINE_INCLUDE - -#include -#include -VK_NAMESPACE_BEGIN -class Pipeline -{ - VkDevice device; - VkPipeline pipeline; - - bool alpha_test; - bool alpha_blend; - -public: - - Pipeline(VkDevice dev,VkPipeline p,bool at,bool ab):device(dev),pipeline(p),alpha_test(at),alpha_blend(ab){} - virtual ~Pipeline(); - - operator VkPipeline(){return pipeline;} - - const bool IsAlphaTest()const{return alpha_test;} - const bool IsAlphaBlend()const{return alpha_blend;} -};//class GraphicsPipeline - -constexpr size_t MAX_SAMPLE_MASK_COUNT=(VK_SAMPLE_COUNT_64_BIT+31)/32; - -#ifndef VK_DYNAMIC_STATE_BEGIN_RANGE -constexpr size_t VK_DYNAMIC_STATE_BEGIN_RANGE=VK_DYNAMIC_STATE_VIEWPORT; -#endif//VK_DYNAMIC_STATE_BEGIN_RANGE - -#ifndef VK_DYNAMIC_STATE_END_RANGE -constexpr size_t VK_DYNAMIC_STATE_END_RANGE=VK_DYNAMIC_STATE_STENCIL_REFERENCE; -#endif//VK_DYNAMIC_STATE_END_RANGE - -#ifndef VK_DYNAMIC_STATE_RANGE_SIZE -constexpr size_t VK_DYNAMIC_STATE_RANGE_SIZE=VK_DYNAMIC_STATE_END_RANGE-VK_DYNAMIC_STATE_BEGIN_RANGE+1; -#endif//VK_DYNAMIC_STATE_RANGE_SIZE - -class PipelineCreater -{ - VkDevice device; - VkExtent2D extent; - VkPipelineCache cache; - VkGraphicsPipelineCreateInfo pipelineInfo; - - VkPipelineVertexInputStateCreateInfo vis_create_info; - - void InitVertexInputState(const Material *); - - VkPipelineInputAssemblyStateCreateInfo inputAssembly; - VkPipelineTessellationStateCreateInfo tessellation; - - VkViewport viewport; - VkRect2D scissor; - VkPipelineViewportStateCreateInfo viewportState; - - void InitViewportState(); - - VkPipelineRasterizationStateCreateInfo rasterizer; - - VkPipelineMultisampleStateCreateInfo multisampling; - VkSampleMask sample_mask[MAX_SAMPLE_MASK_COUNT]; - - VkPipelineDepthStencilStateCreateInfo depthStencilState; - - VkPipelineColorBlendStateCreateInfo colorBlending; - List colorBlendAttachments; - - VkDynamicState dynamicStateEnables[VK_DYNAMIC_STATE_RANGE_SIZE]; - VkPipelineDynamicStateCreateInfo dynamicState; - - void InitDynamicState(); - - float alpha_test=0; - bool alpha_blend=false; - -public: - - PipelineCreater(Device *dev,const Material *,const RenderTarget *); - PipelineCreater(Device *dev,const Material *,const RenderTarget *,uchar *data,uint size); - ~PipelineCreater()=default; - - bool Set(const Prim prim,bool=false); - - void SetViewport( float x,float y,float w,float h){viewport.x=x;viewport.y=y;viewport.width=w;viewport.height=h;} - void SetDepthRange( float min_depth,float max_depth){viewport.minDepth=min_depth;viewport.maxDepth=max_depth;} - void SetScissor( float l,float t,float w,float h){scissor.offset.x=l;scissor.offset.y=t;scissor.extent.width=w;scissor.extent.height=h;} - - void SetAlphaTest( const float at) {alpha_test=at;} - - void SetDepthTest( bool dt) {depthStencilState.depthTestEnable=dt;} - void SetDepthWrite( bool dw) {depthStencilState.depthWriteEnable=dw;} - void SetDepthCompareOp( VkCompareOp op) {depthStencilState.depthCompareOp=op;} - void SetDepthBoundsTest(bool dbt) {depthStencilState.depthBoundsTestEnable=dbt;} - void SetDepthBounds( float min_depth, - float max_depth) {depthStencilState.depthBoundsTestEnable=VK_TRUE; - depthStencilState.minDepthBounds=min_depth; - depthStencilState.maxDepthBounds=max_depth;} - void SetStencilTest( bool st) {depthStencilState.stencilTestEnable=st;} - - void SetDepthClamp( bool dc) {rasterizer.depthClampEnable=dc;} - void SetDiscard( bool discard) {rasterizer.rasterizerDiscardEnable=discard;} - void SetPolygonMode( VkPolygonMode pm) {rasterizer.polygonMode =pm;} - void SetCullMode( VkCullModeFlagBits cm) {rasterizer.cullMode =cm;} - void CloseCullFace() {rasterizer.cullMode =VK_CULL_MODE_NONE;} - void SetFrontFace( VkFrontFace ff) {rasterizer.frontFace =ff;} - void SetDepthBias( float ConstantFactor, - float Clamp, - float SlopeFactor) - { - rasterizer.depthBiasEnable =VK_TRUE; - rasterizer.depthBiasConstantFactor =ConstantFactor; - rasterizer.depthBiasClamp =Clamp; - rasterizer.depthBiasSlopeFactor =SlopeFactor; - } - void DisableDepthBias() {rasterizer.depthBiasEnable=VK_FALSE;} - void SetLineWidth( float line_width) {rasterizer.lineWidth =line_width;} - - void SetSamleCount( VkSampleCountFlagBits sc) - { - multisampling.sampleShadingEnable=(sc==VK_SAMPLE_COUNT_1_BIT?VK_FALSE:VK_TRUE); - multisampling.rasterizationSamples=sc; - } - - bool SetColorWriteMask(uint index,bool r,bool g,bool b,bool a) - { - VkPipelineColorBlendAttachmentState *cba=colorBlendAttachments.GetPointer(index); - - if(!cba)return(false); - - cba->colorWriteMask=0; - - if(r)cba->colorWriteMask|=VK_COLOR_COMPONENT_R_BIT; - if(r)cba->colorWriteMask|=VK_COLOR_COMPONENT_G_BIT; - if(g)cba->colorWriteMask|=VK_COLOR_COMPONENT_B_BIT; - if(a)cba->colorWriteMask|=VK_COLOR_COMPONENT_A_BIT; - - return(true); - } - - void AddColorBlendAttachment(const VkPipelineColorBlendAttachmentState *cba) - { - if(!cba)return; - - colorBlendAttachments.Add(*cba); - colorBlending.attachmentCount=colorBlendAttachments.GetCount(); - - if(cba->blendEnable) - alpha_blend=true; - } - - bool SetBlend(uint index,bool blend) - { - VkPipelineColorBlendAttachmentState *cba=colorBlendAttachments.GetPointer(index); - - if(!cba)return(false); - - cba->blendEnable=blend; - - if(blend) - alpha_blend=true; - else - { - cba=colorBlendAttachments.GetData(); - - for(int i=0;iblendEnable) - { - alpha_blend=true; - return(true); - } - - alpha_blend=false; - } - - return(true); - } - - void SetLogicOp(VkLogicOp logic_op) {colorBlending.logicOpEnable=VK_TRUE;colorBlending.logicOp=logic_op;} - void DisableLogicOp() {colorBlending.logicOpEnable=VK_FALSE;} - - void SetBlendConstans(float r,float g,float b,float a) - { - colorBlending.blendConstants[0] = r; - colorBlending.blendConstants[1] = g; - colorBlending.blendConstants[2] = b; - colorBlending.blendConstants[3] = a; - } - - void SetBlendConstans(float *blend_constans) {hgl_typecpy(colorBlending.blendConstants,blend_constans,4);} - - bool SaveToStream(io::DataOutputStream *dos); - bool LoadFromMemory(uchar *,uint); - - Pipeline *Create(); -};//class PipelineCreater -VK_NAMESPACE_END -#endif//HGL_GRAPH_VULKAN_PIPELINE_INCLUDE diff --git a/inc/hgl/graph/vulkan/VKPrimivate.h b/inc/hgl/graph/vulkan/VKPrimivate.h deleted file mode 100644 index 36056f33..00000000 --- a/inc/hgl/graph/vulkan/VKPrimivate.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef HGL_GRAPH_VULKAN_PRIMITIVE_INCLUDE -#define HGL_GRAPH_VULKAN_PRIMITIVE_INCLUDE - -#include - -/** - * 图元类型枚举 - */ -enum class Prim -{ - Points=0, ///<点 - Lines, ///<线 - LineStrip, ///<连续线 - Triangles, ///<三角形 - TriangleStrip, ///<三角形条 - Fan, ///<扇形 - LinesAdj, ///<代表一个有四个顶点的Primitive,其中第二个点与第三个点会形成线段,而第一个点与第四个点则用来提供2,3邻近点的信息. - LineStripAdj, ///<与LINES_ADJACENCY类似,第一个点跟最后一个点提供信息,剩下的点则跟Line Strip一样形成线段. - TrianglesAdj, ///<代表一个有六个顶点的Primitive,其中第1,3,5个顶点代表一个Triangle,而地2,4,6个点提供邻近信息.(由1起算) - TriangleStripAdj, ///<4+2N个Vertices代表N个Primitive,其中1,3,5,7,9...代表原本的Triangle strip形成Triangle,而2,4,6,8,10...代表邻近提供信息的点.(由1起算) - Patchs, - - Rectangles=0x100, ///<矩形(并非原生支持。以画点形式在每个点的Position中传递Left,Top,Width,Height。在Geometry Shader中转换为2个三角形。用于2D游戏或UI) - - ENUM_CLASS_RANGE(Points,Patchs) -};// - -#endif//HGL_GRAPH_VULKAN_PRIMITIVE_INCLUDE diff --git a/inc/hgl/graph/vulkan/VKRenderPass.h b/inc/hgl/graph/vulkan/VKRenderPass.h deleted file mode 100644 index acc123cd..00000000 --- a/inc/hgl/graph/vulkan/VKRenderPass.h +++ /dev/null @@ -1,68 +0,0 @@ -#ifndef HGL_GRAPH_VULKAN_RENDER_PASS_INCLUDE -#define HGL_GRAPH_VULKAN_RENDER_PASS_INCLUDE - -#include -VK_NAMESPACE_BEGIN -/** - * RenderPass功能封装
- * RenderPass在创建时,需要指定输入的color imageview与depth imageview象素格式, - * 在随后创建Framebuffer时,需要同时指定RenderPass与ColorImageView,DepthImageView,象素格式要一致。 - */ -class RenderPass -{ - VkDevice device; - VkRenderPass render_pass; - - List color_formats; - VkFormat depth_format; - -private: - - friend class Device; - - RenderPass(VkDevice d,VkRenderPass rp,const List &cf,VkFormat df) - { - device=d; - render_pass=rp; - color_formats=cf; - depth_format=df; - } - - RenderPass(VkDevice d,VkRenderPass rp,VkFormat cf,VkFormat df) - { - device=d; - render_pass=rp; - color_formats.Add(cf); - depth_format=df; - } - -public: - - virtual ~RenderPass(); - - operator VkRenderPass(){return render_pass;} - - const uint GetColorCount()const{return color_formats.GetCount();} - const List & GetColorFormat()const{return color_formats;} - const VkFormat GetDepthFormat()const{return depth_format;} -};//class RenderPass - -class RenderpassCreater -{ - Device *device; - - List atta_desc_list; - -public: - - RenderpassCreater(Device *d) - { - device=d; - } - - ~RenderpassCreater()=default; - - int AddSwapchainImage(); -};//class RenderpassCreater -VK_NAMESPACE_END -#endif//HGL_GRAPH_VULKAN_RENDER_PASS_INCLUDE diff --git a/inc/hgl/graph/vulkan/VKRenderTarget.h b/inc/hgl/graph/vulkan/VKRenderTarget.h deleted file mode 100644 index a6450fe2..00000000 --- a/inc/hgl/graph/vulkan/VKRenderTarget.h +++ /dev/null @@ -1,104 +0,0 @@ -#ifndef HGL_GRAPH_VULKAN_RENDER_TARGET_INCLUDE -#define HGL_GRAPH_VULKAN_RENDER_TARGET_INCLUDE - -#include -#include -#include -#include -#include -VK_NAMESPACE_BEGIN -class SubmitQueue -{ -protected: - - Device *device; - VkQueue queue; - - uint32_t current_fence; - ObjectList fence_list; - - VkSubmitInfo submit_info; - -public: - - SubmitQueue(Device *dev,VkQueue q,const uint32_t fence_count=1); - virtual ~SubmitQueue(); - - bool Wait(const bool wait_wall=true,const uint64_t time_out=HGL_NANO_SEC_PER_SEC); - bool Submit(const VkCommandBuffer &cmd_buf,vulkan::Semaphore *wait_sem,vulkan::Semaphore *complete_sem); - bool Submit(const VkCommandBuffer *cmd_buf,const uint32_t count,vulkan::Semaphore *wait_sem,vulkan::Semaphore *complete_sem); -};//class SumbitQueue - -/** - * 渲染目标 - */ -class RenderTarget:public SubmitQueue -{ -protected: - - Framebuffer *fb; - - VkExtent2D extent; - -protected: - - friend class Device; - - RenderTarget(Device *dev,Framebuffer *_fb,const uint32_t fence_count=1); - -public: - - virtual ~RenderTarget()=default; - - const VkExtent2D & GetExtent()const{return extent;} - virtual const VkRenderPass GetRenderPass()const{return fb->GetRenderPass();} - virtual const uint32_t GetColorCount()const{return fb->GetColorCount();} - virtual const VkFramebuffer GetFramebuffer()const{return fb->GetFramebuffer();} -};//class RenderTarget - -/** - * 交换链专用渲染目标 - */ -class SwapchainRenderTarget:public RenderTarget -{ - Swapchain *swapchain; - VkSwapchainKHR vk_swapchain; - VkPresentInfoKHR present_info; - - RenderPass *main_rp=nullptr; - - uint32_t swap_chain_count; - - uint32_t current_frame; - ObjectList render_frame; - -public: - - SwapchainRenderTarget(Device *dev,Swapchain *sc); - ~SwapchainRenderTarget(); - - const VkRenderPass GetRenderPass()const override{return *main_rp;} - const VkFramebuffer GetFramebuffer()const override{return render_frame[current_frame]->GetFramebuffer();} - VkFramebuffer GetFramebuffer(const uint32_t index){return render_frame[index]->GetFramebuffer();} - - const uint32_t GetColorCount()const override{return 1;} - const uint32_t GetImageCount()const{return swap_chain_count;} - - const uint32_t GetCurrentFrameIndices()const{return current_frame;} - -public: - - /** - * 请求下一帧画面的索引 - * @param present_complete_semaphore 推送完成信号 - */ - int AcquireNextImage(vulkan::Semaphore *present_complete_semaphore); - - /** - * 推送后台画面到前台 - * @param render_complete_semaphore 渲染完成信号 - */ - bool PresentBackbuffer(vulkan::Semaphore *render_complete_semaphore); -};//class SwapchainRenderTarget:public RenderTarget -VK_NAMESPACE_END -#endif//HGL_GRAPH_VULKAN_RENDER_TARGET_INCLUDE diff --git a/inc/hgl/graph/vulkan/VKRenderable.h b/inc/hgl/graph/vulkan/VKRenderable.h deleted file mode 100644 index e343c266..00000000 --- a/inc/hgl/graph/vulkan/VKRenderable.h +++ /dev/null @@ -1,83 +0,0 @@ -#ifndef HGL_GRAPH_VULKAN_RENDERABLE_INCLUDE -#define HGL_GRAPH_VULKAN_RENDERABLE_INCLUDE - -#include -#include -#include -#include -VK_NAMESPACE_BEGIN -/** - * 可渲染数据对象
- * 本对象包含材质实例信息和Mesh信息,可渲染数据对象中包含供最终API使用的VBO数据,可能存在多个MESH数据的集合。

- * 比如有多种形状的石头,它们使用了同一种材质,这种情况下多个mesh就可以合并到一个Renderable中,渲染时不再切换VBO。 - */ -class Renderable -{ - const VertexShaderModule *vertex_sm; - - int buf_count; - VkBuffer *buf_list=nullptr; - VkDeviceSize *buf_offset=nullptr; - -protected: - - uint32_t draw_count; - - IndexBuffer *indices_buffer=nullptr; - VkDeviceSize indices_offset=0; - -protected: - - AABB BoundingBox; - -protected: - - friend class RenderableNode; - - uint ref_count=0; - - uint RefInc(){return ++ref_count;} - uint RefDec(){return --ref_count;} - -public: - - Renderable(const VertexShaderModule *,const uint32_t dc=0); - virtual ~Renderable(); - - const uint GetRefCount()const{return ref_count;} - - void SetBoundingBox(const AABB &aabb){BoundingBox=aabb;} - const AABB &GetBoundingBox()const {return BoundingBox;} - - bool Set(const int stage_input_binding, VAB *vb,VkDeviceSize offset=0); - bool Set(const AnsiString &name, VAB *vb,VkDeviceSize offset=0); - - bool Set(IndexBuffer *ib,VkDeviceSize offset=0) - { - if(!ib)return(false); - - indices_buffer=ib; - indices_offset=offset; - return(true); - } - -public: - - void SetDrawCount(const uint32_t dc){draw_count=dc;} ///<设置当前对象绘制需要多少个顶点 - virtual const uint32_t GetDrawCount()const ///<取得当前对象绘制需要多少个顶点 - { - if(indices_buffer) - return indices_buffer->GetCount(); - - return draw_count; - } - - const int GetBufferCount ()const{return buf_count;} - const VkBuffer * GetBuffer ()const{return buf_list;} - const VkDeviceSize * GetOffset ()const{return buf_offset;} - - IndexBuffer * GetIndexBuffer() {return indices_buffer;} - const VkDeviceSize GetIndexOffset()const{return indices_offset;} -};//class Renderable -VK_NAMESPACE_END -#endif//HGL_GRAPH_VULKAN_RENDERABLE_INCLUDE diff --git a/inc/hgl/graph/vulkan/VKShaderModuleManage.h b/inc/hgl/graph/vulkan/VKShaderModuleManage.h deleted file mode 100644 index 6f465a69..00000000 --- a/inc/hgl/graph/vulkan/VKShaderModuleManage.h +++ /dev/null @@ -1,73 +0,0 @@ -#ifndef HGL_GRAPH_VULKAN_SHADER_MODULE_MANAGE_INCLUDE -#define HGL_GRAPH_VULKAN_SHADER_MODULE_MANAGE_INCLUDE - -#include -#include -#include -VK_NAMESPACE_BEGIN - -class ShaderResource; - -/** - * Shader模块管理器
- * 所有的shader模块均由它创建和释放 - * 该管理器在一个设备下仅有一个,它负责管理所有的shader(仅vs/fs/gs等单个,非组合体) - */ -class ShaderModuleManage -{ - Device *device; - - int shader_count; - Map shader_list; - -protected: - - void Free(ShaderModuleMap *); - Material *CreateMaterial(ShaderModuleMap *); - -public: - - ShaderModuleManage(Device *dev) - { - device=dev; - shader_count=0; - } - - ~ShaderModuleManage(); - - const ShaderModule *CreateShader(ShaderResource *); - const ShaderModule *CreateShader(const VkShaderStageFlagBits shader_stage_bit,const OSString &filename); -/* -#define ADD_SHADER_FUNC(sn,vk_name) const ShaderModule *Create##sn##Shader(const void *spv_data,const uint32_t spv_size){return CreateShader(VK_SHADER_STAGE_##vk_name##_BIT,spv_data,spv_size);} - ADD_SHADER_FUNC(Vertex, VERTEX) - ADD_SHADER_FUNC(Fragment, FRAGMENT) - ADD_SHADER_FUNC(Geometry, GEOMETRY) - ADD_SHADER_FUNC(TessCtrl, TESSELLATION_CONTROL) - ADD_SHADER_FUNC(TessEval, TESSELLATION_EVALUATION) - ADD_SHADER_FUNC(Compute, COMPUTE) -#undef ADD_SHADER_FUNC - -#define ADD_NV_SHADER_FUNC(sn,vk_name) const ShaderModule *Create##sn##Shader(const void *spv_data,const uint32_t spv_size){return CreateShader(VK_SHADER_STAGE_##vk_name##_BIT_NV,spv_data,spv_size);} - ADD_NV_SHADER_FUNC(Raygen, RAYGEN); - ADD_NV_SHADER_FUNC(AnyHit, ANY_HIT); - ADD_NV_SHADER_FUNC(ClosestHit, CLOSEST_HIT); - ADD_NV_SHADER_FUNC(MissBit, MISS); - ADD_NV_SHADER_FUNC(Intersection,INTERSECTION); - ADD_NV_SHADER_FUNC(Callable, CALLABLE); - ADD_NV_SHADER_FUNC(Task, TASK); - ADD_NV_SHADER_FUNC(Mesh, MESH); -#undef ADD_NV_SHADER_FUNC -*/ - const ShaderModule *GetShader (int); - bool ReleaseShader (const ShaderModule *); - - Material *CreateMaterial(const VertexShaderModule *vertex_shader_module,const ShaderModule *fragment_shader_module); - Material *CreateMaterial(const VertexShaderModule *vertex_shader_module,const ShaderModule *geometry_shader_module,const ShaderModule *fragment_shader_module); - - Material *CreateMaterial(const OSString &vertex_shader_filename,const OSString &fragment_shader_filename); - Material *CreateMaterial(const OSString &vertex_shader_filename,const OSString &geometry_shader_filename,const OSString &fragment_shader_filename); - - Material *CreateMaterial(const OSString &filename); -};//class ShaderModuleManage -VK_NAMESPACE_END -#endif//HGL_GRAPH_VULKAN_SHADER_MODULE_MANAGE_INCLUDE diff --git a/inc/hgl/graph/vulkan/VKSwapchain.h b/inc/hgl/graph/vulkan/VKSwapchain.h deleted file mode 100644 index 6c0b2afe..00000000 --- a/inc/hgl/graph/vulkan/VKSwapchain.h +++ /dev/null @@ -1,39 +0,0 @@ -#ifndef HGL_GRAPH_VULKAN_SWAP_CHAIN_INCLUDE -#define HGL_GRAPH_VULKAN_SWAP_CHAIN_INCLUDE - -#include -#include -#include -VK_NAMESPACE_BEGIN -struct Swapchain -{ -public: - - VkDevice device =VK_NULL_HANDLE; - - VkExtent2D extent; - - VkQueue graphics_queue =VK_NULL_HANDLE; - VkSwapchainKHR swap_chain =VK_NULL_HANDLE; - - uint32_t swap_chain_count=0; - - ObjectList sc_color; - Texture2D * sc_depth =nullptr; - -public: - - VkSwapchainKHR GetSwapchain () {return swap_chain;} - const VkExtent2D & GetExtent ()const {return extent;} - const uint32_t GetImageCount ()const {return sc_color.GetCount();} - - Texture2D ** GetColorTextures () {return sc_color.GetData();} - Texture2D * GetColorTexture (int index) {return sc_color[index];} - Texture2D * GetDepthTexture () {return sc_depth;} - -public: - - virtual ~Swapchain(); -};//struct Swapchain -VK_NAMESPACE_END -#endif//HGL_GRAPH_VULKAN_SWAP_CHAIN_INCLUDE diff --git a/inc/hgl/graph/vulkan/VKVertexAttributeBinding.h b/inc/hgl/graph/vulkan/VKVertexAttributeBinding.h deleted file mode 100644 index b38e42b6..00000000 --- a/inc/hgl/graph/vulkan/VKVertexAttributeBinding.h +++ /dev/null @@ -1,35 +0,0 @@ -#ifndef HGL_GRAPH_VULKAN_VERTEX_ATTRIBUTE_BINDING_INCLUDE -#define HGL_GRAPH_VULKAN_VERTEX_ATTRIBUTE_BINDING_INCLUDE - -#include -#include -VK_NAMESPACE_BEGIN -/** -* 顶点输入状态实例
-* 本对象用于传递给Material,用于已经确定好顶点格式的情况下,依然可修改部分设定(如instance)。 -*/ -class VertexAttributeBinding -{ - uint32_t attr_count; - VkVertexInputBindingDescription *binding_list; - VkVertexInputAttributeDescription *attribute_list; - -private: - - friend class VertexShaderModule; - - VertexAttributeBinding(const uint32_t,const VkVertexInputBindingDescription *,const VkVertexInputAttributeDescription *); - -public: - - ~VertexAttributeBinding(); - - bool SetInstance(const uint binding,bool instance); - bool SetStride (const uint binding,const uint32_t & stride); - bool SetFormat (const uint binding,const VkFormat & format); - bool SetOffset (const uint binding,const uint32_t offset); - - void Write(VkPipelineVertexInputStateCreateInfo &vis)const; -};//class VertexAttributeBinding -VK_NAMESPACE_END -#endif//HGL_GRAPH_VULKAN_VERTEX_ATTRIBUTE_BINDING_INCLUDE diff --git a/inc/hgl/gui/Form.h b/inc/hgl/gui/Form.h new file mode 100644 index 00000000..5e5c6e39 --- /dev/null +++ b/inc/hgl/gui/Form.h @@ -0,0 +1,28 @@ +#ifndef HGL_GUI_FORM_INCLUDE +#define HGL_GUI_FORM_INCLUDE + +#include +#include +namespace hgl +{ + namespace gui + { + using namespace hgl::graph; + + /** + * 窗体组件,窗体是承载所有GUI控件的基本装置 + */ + class Form:public Widget + { + protected: + + public: + + Form(ThemeEngine *te=nullptr):Widget(nullptr,te){} + virtual ~Form()=default; + + + };//class Form + }//namespace gui +}//namespace hgl +#endif//HGL_GUI_FORM_INCLUDE diff --git a/inc/hgl/gui/Layout.h b/inc/hgl/gui/Layout.h new file mode 100644 index 00000000..57e3deeb --- /dev/null +++ b/inc/hgl/gui/Layout.h @@ -0,0 +1,58 @@ +#ifndef HGL_GUI_LAYOUT_INCLUDE +#define HGL_GUI_LAYOUT_INCLUDE + +#include +#include +namespace hgl +{ + namespace gui + { + /** + * 布局器基础 + */ + class LayoutBase + { + protected: + + SortedSets widgets_set; + + public: + + virtual bool AddWidget(Widget *); + virtual bool RemoveWidget(Widget *); + };//class LayoutBase + + /** + * 布局器 + */ + class Layout:public LayoutBase + { + public: + };//class Layout:public LayoutBase + + /** + * 垂直分布布局器 + */ + class VBoxLayout:public LayoutBase + { + public: + };//class VBoxLayout:public LayoutBase + + /** + * 水平分布布局器 + */ + class HBoxLayout:public LayoutBase + { + public: + };//class HBoxLayout:public LayoutBase + + /** + * 网格分布布局器 + */ + class GridLayout:public LayoutBase + { + public: + };//class GridLayout:public LayoutBase + }//namespace gui +}//namespace hgl +#endif//HGL_GUI_LAYOUT_INCLUDE diff --git a/inc/hgl/gui/Panel.h b/inc/hgl/gui/Panel.h new file mode 100644 index 00000000..db279d06 --- /dev/null +++ b/inc/hgl/gui/Panel.h @@ -0,0 +1,21 @@ +#ifndef HGL_GUI_PANEL_INCLUDE +#define HGL_GUI_PANEL_INCLUDE + +#include +namespace hgl +{ + namespace gui + { + class Panel:public Widget + { + public: + + Panel(Widget *p):Widget(p){} + + virtual ~Panel()=default; + + void Draw() override; + };//class Panel:public Widget + }//namespace gui +}//namespace hgl +#endif//HGL_GUI_PANEL_INCLUDE diff --git a/inc/hgl/gui/ThemeEngine.h b/inc/hgl/gui/ThemeEngine.h new file mode 100644 index 00000000..8a0c0cae --- /dev/null +++ b/inc/hgl/gui/ThemeEngine.h @@ -0,0 +1,52 @@ +#ifndef HGL_GUI_THEME_ENGINE_INCLUDE +#define HGL_GUI_THEME_ENGINE_INCLUDE + +#include +#include +#include +namespace hgl +{ + namespace gui + { + namespace vulkan + { + class GPUDevice; + }//namespace vulkan + + constexpr VkFormat DefaultRenderTargetFormat=UPF_ABGR8; ///<缺省窗体绘图表面格式 + + class ThemeEngine + { + protected: + + GPUDevice *device; + + MapObject
form_list; + + RenderTarget *CreateRenderTarget(const uint32_t,const uint32_t,const VkFormat); + + protected: + + virtual ThemeForm *CreateForm(Form *,RenderTarget *,RenderCmdBuffer *)=0; + + virtual bool Render(ThemeForm *); + + public: + + ThemeEngine(GPUDevice *dev){device=dev;} + virtual ~ThemeEngine()=default; + + virtual bool Init()=0; + virtual void Clear()=0; + + virtual bool Registry(Form *,const VkFormat format=DefaultRenderTargetFormat); + virtual void Unregistry(Form *); + virtual bool Resize(Form *,const uint32_t,const uint32_t,const VkFormat format=DefaultRenderTargetFormat); + virtual bool Render(Form *); + };//class ThemeEngine + +// ThemeEngine *CreateThemeEngine(); + ThemeEngine *GetDefaultThemeEngine(); ///<获取缺省主题引擎 + }//namespace gui +}//namespace hgl +#endif//HGL_GUI_THEME_ENGINE_INCLUDE \ No newline at end of file diff --git a/inc/hgl/gui/ThemeForm.h b/inc/hgl/gui/ThemeForm.h new file mode 100644 index 00000000..438d3a0b --- /dev/null +++ b/inc/hgl/gui/ThemeForm.h @@ -0,0 +1,38 @@ +#ifndef HGL_GUI_THEME_FORM_INCLUDE +#define HGL_GUI_THEME_FORM_INCLUDE + +#include +#include + +namespace hgl +{ + namespace gui + { + using namespace hgl::graph; + + class ThemeForm + { + protected: + + Form *form; + + RenderTarget *render_target; + RenderCmdBuffer *cmd_buf; + + public: + + ThemeForm(Form *,RenderTarget *,RenderCmdBuffer *); + virtual ~ThemeForm(); + + RenderTarget * GetRenderTarget(){return render_target;} + bool SetRenderTarget(RenderTarget *); + + void Resize(uint w,uint h); + + bool BeginRender(); + virtual bool Render()=0; + bool EndRender(); + };//class ThemeForm + }//namespace gui +}//namespace hgl +#endif//HGL_GUI_THEME_FORM_INCLUDE diff --git a/inc/hgl/gui/Widget.h b/inc/hgl/gui/Widget.h new file mode 100644 index 00000000..56110e6e --- /dev/null +++ b/inc/hgl/gui/Widget.h @@ -0,0 +1,71 @@ +#ifndef HGL_GUI_WIDGET_INCLUDE +#define HGL_GUI_WIDGET_INCLUDE + +#include +#include +namespace hgl +{ + namespace gui + { + class ThemeEngine; + + enum Alignment + { + None =0x00, + Left =0x01, + Top =0x02, + Right =0x04, + Bottom =0x08, + Center =0x10, + HCenter =0x20, + VCenter =0x40 + };//enum Alignment + + /** + * 装置类,是所有GUI组件的基类 + */ + class Widget + { + private: + + Widget *parent_widget; + ThemeEngine *theme_engine; + + bool visible; ///<控件是否可看见 + bool recv_event; ///<控件是否接收事件 + uint8 align_bits; ///<对齐位属性(注:不可见依然影响排版) + + RectScope2f position; ///<所在位置 + + public: + + Widget * GetParent (){return parent_widget;} + ThemeEngine * GetThemeEngine (){return theme_engine;} + + public: + + const bool IsVisible ()const{return visible;} + const bool IsRecvEvent ()const{return recv_event;} + const uint8 GetAlign ()const{return align_bits;} + const RectScope2f & GetPosition ()const{return position;} + const Vector2f GetOffset ()const{return position.GetLeftTop();} + const Vector2f GetSize ()const{return position.GetSize();} + + void SetVisible (const bool); + void SetRecvEvent(const bool); + void SetAlign (const uint8); + void SetPosition (const RectScope2i &); + void SetSize (const Vector2f &); + + public: //事件 + + virtual void OnResize(uint,uint); + + public: + + Widget(Widget *parent=nullptr,ThemeEngine *te=nullptr); + virtual ~Widget()=default; + };//class Widget + }//namespace gui +}//namespace hgl +#endif//HGL_GUI_WIDGET_INCLUDE diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 92567e2a..43d3903f 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,4 +1,4 @@ add_subdirectory(Util) -add_subdirectory(RenderDevice) add_subdirectory(SceneGraph) #add_subdirectory(Tools) +add_subdirectory(GUI) diff --git a/src/GUI/CMakeLists.txt b/src/GUI/CMakeLists.txt new file mode 100644 index 00000000..d9eb11ea --- /dev/null +++ b/src/GUI/CMakeLists.txt @@ -0,0 +1,27 @@ +SET(GUI_INCLUDE_PATH ${ROOT_INCLUDE_PATH}/hgl/gui) + +SET(THEME_SOURCE ${GUI_INCLUDE_PATH}/ThemeForm.h + ${GUI_INCLUDE_PATH}/ThemeEngine.h + ThemeEngine.cpp + ThemeForm.cpp) + +SET(DEFAULT_THEME_SOURCE DefaultThemeEngine.h + DefaultThemeEngine.cpp + DefaultThemeForm.h + DefaultThemeForm.cpp) + +set(WIDGET_SOURCE ${GUI_INCLUDE_PATH}/Widget.h + ${GUI_INCLUDE_PATH}/Layout.h + ${GUI_INCLUDE_PATH}/Form.h + ${GUI_INCLUDE_PATH}/Panel.h + Widget.cpp + Form.cpp + Panel.cpp) + +SOURCE_GROUP("Widget" FILES ${WIDGET_SOURCE}) +SOURCE_GROUP("Theme" FILES ${THEME_SOURCE}) +SOURCE_GROUP("Theme\\Default" FILES ${DEFAULT_THEME_SOURCE}) + +add_cm_library(ULRE.GUI "ULRE" ${THEME_SOURCE} + ${DEFAULT_THEME_SOURCE} + ${WIDGET_SOURCE}) diff --git a/src/GUI/DefaultThemeEngine.cpp b/src/GUI/DefaultThemeEngine.cpp new file mode 100644 index 00000000..defe85e4 --- /dev/null +++ b/src/GUI/DefaultThemeEngine.cpp @@ -0,0 +1,33 @@ +#include"DefaultThemeEngine.h" + +namespace hgl +{ + namespace gui + { + ThemeEngine *CreateDefaultThemeEngine(GPUDevice *dev) + { + return(new DefaultThemeEngine(dev)); + } + + bool DefaultThemeEngine::Init() + { + return(true); + } + + void DefaultThemeEngine::Clear() + { + } + + ThemeForm *DefaultThemeEngine::CreateForm(Form *f,RenderTarget *rt,RenderCmdBuffer *rc) + { + return(new DefaultThemeForm(f,rt,rc)); + } + + void DefaultThemeEngine::DrawPanel(RenderCmdBuffer *rc,const RectScope2f &rs) + { + if(!rc)return; + + + } + }//namespace gui +}//namespace hgl diff --git a/src/GUI/DefaultThemeEngine.h b/src/GUI/DefaultThemeEngine.h new file mode 100644 index 00000000..ca240d0b --- /dev/null +++ b/src/GUI/DefaultThemeEngine.h @@ -0,0 +1,42 @@ +#pragma once + +#include +#include +#include +#include"DefaultThemeForm.h" + +namespace hgl +{ + namespace gui + { + using namespace hgl::graph; + + class Form; ///<窗体 + + /** + * 缺省GUI主题引擎 + */ + class DefaultThemeEngine:public ThemeEngine + { + struct + { + Material *material; + Pipeline *pieline; + }panel; + + public: + + using ThemeEngine::ThemeEngine; + virtual ~DefaultThemeEngine() override; + + bool Init() override; + void Clear() override; + + ThemeForm *CreateForm(Form *,RenderTarget *,RenderCmdBuffer *) override; + + public: + + void DrawPanel(RenderCmdBuffer *,const RectScope2f &); + };//class DefaultThemeEngine:public ThemeEngine + }//namespace gui +}//namespace hgl diff --git a/src/GUI/DefaultThemeForm.cpp b/src/GUI/DefaultThemeForm.cpp new file mode 100644 index 00000000..adeefb49 --- /dev/null +++ b/src/GUI/DefaultThemeForm.cpp @@ -0,0 +1,20 @@ +#include"DefaultThemeForm.h" +#include +#include + +namespace hgl +{ + namespace gui + { + bool DefaultThemeForm::Render() + { + if(!cmd_buf->BeginRenderPass()) + return(false); + + + + cmd_buf->EndRenderPass(); + return(true); + } + }//namespace gui +}//namespace hgl diff --git a/src/GUI/DefaultThemeForm.h b/src/GUI/DefaultThemeForm.h new file mode 100644 index 00000000..a5d7e6b6 --- /dev/null +++ b/src/GUI/DefaultThemeForm.h @@ -0,0 +1,27 @@ +#ifndef HGL_GUI_DEFAULT_THEME_FORM_INCLUDE +#define HGL_GUI_DEFAULT_THEME_FORM_INCLUDE + +#include +#include + +namespace hgl +{ + namespace gui + { + using namespace hgl::graph; + + class Form; + + class DefaultThemeForm:public ThemeForm + { + + public: + + using ThemeForm::ThemeForm; + ~DefaultThemeForm()=default; + + bool Render() override; + };//class DefaultThemeForm + }//namespace gui +}//namespace hgl +#endif//HGL_GUI_DEFAULT_THEME_FORM_INCLUDE diff --git a/src/GUI/Form.cpp b/src/GUI/Form.cpp new file mode 100644 index 00000000..e69de29b diff --git a/src/GUI/Panel.cpp b/src/GUI/Panel.cpp new file mode 100644 index 00000000..f8c7f9fc --- /dev/null +++ b/src/GUI/Panel.cpp @@ -0,0 +1,12 @@ +#include +#include + +namespace hgl +{ + namespace gui + { + void Panel::Draw() + { + } + }//namespace gui +}//namespace hgl \ No newline at end of file diff --git a/src/GUI/ThemeEngine.cpp b/src/GUI/ThemeEngine.cpp new file mode 100644 index 00000000..6e6d2f9f --- /dev/null +++ b/src/GUI/ThemeEngine.cpp @@ -0,0 +1,134 @@ +#include +#include +#include +#include + +namespace hgl +{ + namespace gui + { + namespace + { + ThemeEngine *default_theme_engine=nullptr; + }//namespace + + ThemeEngine *CreateDefaultThemeEngine(GPUDevice *dev); + + ThemeEngine *GetDefaultThemeEngine(GPUDevice *dev) + { + if(!default_theme_engine) + default_theme_engine=CreateDefaultThemeEngine(dev); + + return default_theme_engine; + } + + ThemeEngine *CreateThemeEngine(GPUDevice *dev) + { + return GetDefaultThemeEngine(); + } + + RenderTarget *ThemeEngine::CreateRenderTarget(const uint32_t w,const uint32_t h,const VkFormat format) + { + const uint width=power_to_2(w); + const uint height=power_to_2(h); + + FramebufferInfo fbi(format,w,h); + + return device->CreateRenderTarget(&fbi); + } + + bool ThemeEngine::Registry(Form *f,const VkFormat format) + { + if(!f)return(false); + + if(form_list.KeyExist(f)) + return(false); + + Vector2f size=f->GetSize(); + + RenderTarget *rt=CreateRenderTarget(size.x,size.y,format); + + if(!rt)return(false); + + ThemeForm *tf=CreateForm(f,rt); + + form_list.Add(f,tf); + + return(true); + } + + void ThemeEngine::Unregistry(Form *f) + { + if(!f)return; + + ThemeForm *tf; + + if(!form_list.Get(f,tf)) + return; + + delete tf; + } + + bool ThemeEngine::Resize(Form *f,const uint32_t w,const uint32_t h,const VkFormat format) + { + if(!f)return(false); + + ThemeForm *tf; + + if(!form_list.Get(f,tf))return(false); + + if(w<=0||h<=0) + { + tf->SetRenderTarget(nullptr); + return(true); + } + + RenderTarget *old_rt=tf->GetRenderTarget(); + + if(!old_rt) + { + const VkExtent2D old_size=old_rt->GetExtent(); + + if(old_size.width>=w + &&old_size.height>=h) + { + tf->Resize(w,h); + return(true); + } + } + + graph::RenderTarget *rt=CreateRenderTarget(w,h,format); + + if(!rt)return(false); + + tf->SetRenderTarget(rt); + tf->Resize(w,h); + return(true); + } + + bool ThemeEngine::Render(ThemeForm *tf) + { + tf->BeginRender(); + + tf->Render(); + + tf->EndRender(); + } + + bool ThemeEngine::Render(Form *f) + { + if(!f)return(false); + + const Vector2f &size=f->GetSize(); + + if(size.x==0&&size.y==0)return(false); + + ThemeForm *tf; + + if(!form_list.Get(f,tf)) + return(false); + + return Render(tf); + } + }//namespace gui +}//namespace hgl \ No newline at end of file diff --git a/src/GUI/ThemeForm.cpp b/src/GUI/ThemeForm.cpp new file mode 100644 index 00000000..ca8f9f92 --- /dev/null +++ b/src/GUI/ThemeForm.cpp @@ -0,0 +1,57 @@ +#include +#include + +namespace hgl +{ + namespace gui + { + ThemeForm::ThemeForm(Form *f,RenderTarget *rt,RenderCmdBuffer *rc) + { + form=f; + render_target=rt; + cmd_buf=rc; + } + + ThemeForm::~ThemeForm() + { + delete cmd_buf; + delete render_target; + } + + bool ThemeForm::SetRenderTarget(RenderTarget *rt) + { + SAFE_CLEAR(render_target); + + if(!rt) + return(true); + + render_target=rt; + return(true); + } + + void ThemeForm::Resize(uint w,uint h) + { + form->OnResize(w,h); + } + + bool ThemeForm::BeginRender() + { + if(!cmd_buf->Begin())return(false); + if(!cmd_buf->BindFramebuffer(render_target->GetRenderPass(),render_target->GetFramebuffer()))return(false); + + cmd_buf->SetClearColor(0,0,0,0,1.0f); + + return(true); + } + + bool ThemeForm::EndRender() + { + if(!cmd_buf->End())return(false); + + if(!render_target->Submit(cmd_buf))return(false); + if(!render_target->WaitQueue())return(false); + + return(true); + } + }//namespace gui +}//namespace hgl diff --git a/src/GUI/Widget.cpp b/src/GUI/Widget.cpp new file mode 100644 index 00000000..39d8423d --- /dev/null +++ b/src/GUI/Widget.cpp @@ -0,0 +1,28 @@ +#include +#include + +namespace hgl +{ + namespace gui + { + Widget::Widget(Widget *parent,ThemeEngine *te) + { + parent_widget=parent; + + if(te) + theme_engine=te; + else + theme_engine=GetDefaultThemeEngine(); + + //默认值 + visible=false; //不显示 + recv_event=false; //不接收事件 + align_bits=0; //不对齐 + position.Clear(); + } + + void Widget::OnResize(const uint,const uint) + { + } + }//namespace gui +}//namespace hgl \ No newline at end of file diff --git a/src/RenderDevice/CMakeLists.txt b/src/RenderDevice/CMakeLists.txt deleted file mode 100644 index 96f5da34..00000000 --- a/src/RenderDevice/CMakeLists.txt +++ /dev/null @@ -1 +0,0 @@ -add_subdirectory(Vulkan) diff --git a/src/RenderDevice/Vulkan/CMakeLists.txt b/src/RenderDevice/Vulkan/CMakeLists.txt deleted file mode 100644 index e98e2daf..00000000 --- a/src/RenderDevice/Vulkan/CMakeLists.txt +++ /dev/null @@ -1,120 +0,0 @@ -set(RD_INCLUDE_PATH ${ROOT_INCLUDE_PATH}/hgl/graph/vulkan) - -SET(VK_DB_SOURCE ${RD_INCLUDE_PATH}/VKDatabase.h - VKDatabase.cpp) - -SOURCE_GROUP("Database" FILES ${VK_DB_SOURCE}) - -SET(VK_INST_SOURCE ${RD_INCLUDE_PATH}/VKInstance.h - VKInstance.cpp) - -SET(VK_DEBUG_SOURCE ${RD_INCLUDE_PATH}/VKDebugOut.h - VKDebugOut.cpp) - -SET(VK_MEMORY_SOURCE ${RD_INCLUDE_PATH}/VKMemory.h - ${RD_INCLUDE_PATH}/VKBuffer.h - VKMemory.cpp - VKBuffer.cpp) - -SET(VK_DEVICE_SOURCE ${RD_INCLUDE_PATH}/VKDevice.h - ${RD_INCLUDE_PATH}/VKDeviceAttribute.h - VKDeviceAttribute.cpp - VKDeviceCreater.cpp - VKDevice.cpp - VKDeviceBuffer.cpp - VKDeviceImage.cpp - VKDeviceTexture.cpp - VKDeviceSwapchain.cpp - VKDeviceRenderPass.cpp) - -SET(VK_PHYSICAL_DEVICE_SOURCE ${RD_INCLUDE_PATH}/VKPhysicalDevice.h - VKPhysicalDevice.cpp - VKProperties.cpp) - -SOURCE_GROUP("Device" FILES ${VK_DEVICE_SOURCE}) -SOURCE_GROUP("Device\\Debug" FILES ${VK_DEBUG_SOURCE}) -SOURCE_GROUP("Device\\Instance" FILES ${VK_INST_SOURCE}) -SOURCE_GROUP("Device\\Physical Device" FILES ${VK_PHYSICAL_DEVICE_SOURCE}) -SOURCE_GROUP("Device\\Memory" FILES ${VK_MEMORY_SOURCE}) - -SET(VK_DESCRIPTOR_SETS_SOURCE ${RD_INCLUDE_PATH}/VKDescriptorSets.h - VKDescriptorSets.cpp - VKDescriptorSetLayoutCreater.cpp - VKDescriptorSetLayoutCreater.h) - -SOURCE_GROUP("Descriptor Sets" FILES ${VK_DESCRIPTOR_SETS_SOURCE}) - -SET(VK_SHADER_SOURCE ${RD_INCLUDE_PATH}/VKShaderModule.h - ${RD_INCLUDE_PATH}/VKShaderModuleManage.h - VKShaderModule.cpp - VKShaderModuleManage.cpp) - -SET(VK_TEXTURE_SOURCE ${RD_INCLUDE_PATH}/VKImageView.h - ${RD_INCLUDE_PATH}/VKTexture.h - ${RD_INCLUDE_PATH}/VKSampler.h - VKSampler.cpp - VKImageView.cpp - VKTexture.cpp - POD/VKTextureLoader.cpp) - -SET(VK_MATERIAL_SOURCE ${RD_INCLUDE_PATH}/VKMaterial.h - ${RD_INCLUDE_PATH}/VKMaterialInstance.h - ${RD_INCLUDE_PATH}/ShaderModuleMap.h - ShaderModuleMap.cpp - VKMaterial.cpp - VKMaterialInstance.cpp) - -SOURCE_GROUP("Material" FILES ${VK_MATERIAL_SOURCE}) -SOURCE_GROUP("Material\\Texture" FILES ${VK_TEXTURE_SOURCE}) -SOURCE_GROUP("Material\\Shader" FILES ${VK_SHADER_SOURCE}) - -SET(VK_RENDER_PASS_SOURCE ${RD_INCLUDE_PATH}/VKFramebuffer.h - ${RD_INCLUDE_PATH}/VKPipeline.h - ${RD_INCLUDE_PATH}/VKRenderPass.h - ${RD_INCLUDE_PATH}/VKRenderTarget.h - ${RD_INCLUDE_PATH}/VKSwapchain.h - ${RD_INCLUDE_PATH}/VKCommandBuffer.h - ${RD_INCLUDE_PATH}/VKSemaphore.h - ${RD_INCLUDE_PATH}/VKFence.h - VKSemaphore.cpp - VKFence.cpp - VKFramebuffer.cpp - VKPipeline.cpp - VKRenderPass.cpp - VKRenderTarget.cpp - VKSwapchain.cpp - VKCommandBuffer.cpp - POD/VKPipelineCreateInfo.POD.cpp) - -SOURCE_GROUP("Render Pass" FILES ${VK_RENDER_PASS_SOURCE}) - -SET(VK_RENDERABLE_SOURCE ${RD_INCLUDE_PATH}/VKVertexAttributeBinding.h - ${RD_INCLUDE_PATH}/VKRenderable.h - VKVertexAttributeBinding.cpp - VKRenderable.cpp - VKTileData.cpp - VKTileFont.cpp) - -SOURCE_GROUP("Renderable" FILES ${VK_RENDERABLE_SOURCE}) - -IF(WIN32) - OPTION(FORCE_DISCETE_GPU "Force Discrete GPU" OFF) - - IF(FORCE_DISCETE_GPU) - SET(RENDER_DEVICE_SOURCE ForceDiscreteGPU.c) - ENDIF() -ENDIF(WIN32) - -add_cm_library(ULRE.RenderDevice.Vulkan "ULRE" ${VK_DB_SOURCE} - ${VK_INST_SOURCE} - ${VK_DEBUG_SOURCE} - ${VK_MEMORY_SOURCE} - ${VK_DEVICE_SOURCE} - ${VK_PHYSICAL_DEVICE_SOURCE} - ${VK_DESCRIPTOR_SETS_SOURCE} - ${VK_SHADER_SOURCE} - ${VK_TEXTURE_SOURCE} - ${VK_MATERIAL_SOURCE} - ${VK_RENDER_PASS_SOURCE} - ${VK_RENDERABLE_SOURCE} - ${VK_RENDER_DEVICE_SOURCE}) diff --git a/src/RenderDevice/Vulkan/POD/VKPipelineCreateInfo.POD.cpp b/src/RenderDevice/Vulkan/POD/VKPipelineCreateInfo.POD.cpp deleted file mode 100644 index 73437def..00000000 --- a/src/RenderDevice/Vulkan/POD/VKPipelineCreateInfo.POD.cpp +++ /dev/null @@ -1,150 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include - -using namespace hgl; - -VK_NAMESPACE_BEGIN - -#define WRITE_AND_CHECK_SIZE(ptr,type) if(dos->Write(ptr,sizeof(type))!=sizeof(type))return(false); - -bool PipelineCreater::SaveToStream(io::DataOutputStream *dos) -{ - if(!dos)return(false); - - if(!dos->WriteUint16(1))return(false); //file ver - - WRITE_AND_CHECK_SIZE(&pipelineInfo,VkGraphicsPipelineCreateInfo); - WRITE_AND_CHECK_SIZE(pipelineInfo.pInputAssemblyState, VkPipelineInputAssemblyStateCreateInfo ); - WRITE_AND_CHECK_SIZE(pipelineInfo.pTessellationState, VkPipelineTessellationStateCreateInfo ); - WRITE_AND_CHECK_SIZE(pipelineInfo.pRasterizationState, VkPipelineRasterizationStateCreateInfo ); - - WRITE_AND_CHECK_SIZE(pipelineInfo.pMultisampleState, VkPipelineMultisampleStateCreateInfo ); - if(pipelineInfo.pMultisampleState->pSampleMask) - { - const uint count=(pipelineInfo.pMultisampleState->rasterizationSamples+31)/32; - if(!dos->WriteUint8(count))return(false); - if(dos->WriteUint32(pipelineInfo.pMultisampleState->pSampleMask,count)!=count)return(false); - } - else - { - if(!dos->WriteUint8(0))return(false); - } - - WRITE_AND_CHECK_SIZE(pipelineInfo.pDepthStencilState, VkPipelineDepthStencilStateCreateInfo); - - WRITE_AND_CHECK_SIZE(pipelineInfo.pColorBlendState, VkPipelineColorBlendStateCreateInfo); - for(uint32_t i=0;iattachmentCount;i++) - WRITE_AND_CHECK_SIZE(pipelineInfo.pColorBlendState->pAttachments+i,VkPipelineColorBlendAttachmentState); - - if(!dos->WriteFloat(alpha_test))return(false); - - return(true); -} - -#define CHECK_SIZE_AND_COPY(ptr,type) if(size0) - { - memcpy(sample_mask,data,count); - multisampling.pSampleMask=sample_mask; - data+=count; - size=count; - } - else - { - multisampling.pSampleMask=nullptr; - } - - CHECK_SIZE_AND_COPY(depthStencilState,VkPipelineDepthStencilStateCreateInfo); - CHECK_SIZE_AND_COPY(colorBlending,VkPipelineColorBlendStateCreateInfo); - - if(colorBlending.attachmentCount>0) - { - if(sizeblendEnable) - alpha_blend=true; - - ++cba; - } - } - else - { - colorBlending.pAttachments=nullptr; - alpha_blend=false; - } - - CHECK_SIZE_AND_COPY(alpha_test,float); - - return(true); -} -VK_NAMESPACE_END - -bool SaveToFile(const OSString &filename,VK_NAMESPACE::PipelineCreater *pc) -{ - if(filename.IsEmpty()||!pc) - return(false); - - io::MemoryOutputStream mos; - io::DataOutputStream *dos=new io::LEDataOutputStream(&mos); - - pc->SaveToStream(dos); - - delete dos; - - filesystem::SaveMemoryToFile(filename,mos.GetData(),mos.Tell()); - - return(true); -} - -bool LoadFromFile(const OSString &filename,VK_NAMESPACE::PipelineCreater *pc) -{ - if(filename.IsEmpty()||!pc) - return(false); - - char *data; - uint size=filesystem::LoadFileToMemory(filename,(void **)&data); - - bool result=pc->LoadFromMemory((uchar *)data,size); - - delete[] data; - return result; -} diff --git a/src/RenderDevice/Vulkan/POD/VKTextureLoader.cpp b/src/RenderDevice/Vulkan/POD/VKTextureLoader.cpp deleted file mode 100644 index 7abebc01..00000000 --- a/src/RenderDevice/Vulkan/POD/VKTextureLoader.cpp +++ /dev/null @@ -1,174 +0,0 @@ -#include -#include -#include -#include -#include -#include - -VK_NAMESPACE_BEGIN -namespace -{ - struct PixelFormat - { - VkFormat format; - - uint8 channels; //颜色通道数 - char colors[4]; - uint8 bits[4]; - VulkanDataType type; - - public: - - const uint GetPixelBytes()const{return (bits[0]+bits[1]+bits[2]+bits[3])>>3;} ///<获取单个象素所需字节数 - };// - - constexpr PixelFormat pf_list[]= - { - {UFMT_BGRA4, 4,{'B','G','R','A'},{ 4, 4, 4, 4},VulkanDataType::UNORM}, - {UFMT_RGB565, 3,{'R','G','B', 0 },{ 5, 6, 5, 0},VulkanDataType::UNORM}, - {UFMT_A1RGB5, 4,{'A','R','G','B'},{ 1, 5, 5, 5},VulkanDataType::UNORM}, - {UFMT_R8, 1,{'R', 0 , 0 , 0 },{ 8, 0, 0, 0},VulkanDataType::UNORM}, - {UFMT_RG8, 2,{'R','G', 0 , 0 },{ 8, 8, 0, 0},VulkanDataType::UNORM}, - {UFMT_RGBA8, 4,{'R','G','B','A'},{ 8, 8, 8, 8},VulkanDataType::UNORM}, - {UFMT_A2BGR10, 4,{'A','B','G','R'},{ 2,10,10,10},VulkanDataType::UNORM}, - {UFMT_R16, 1,{'R', 0 , 0 , 0 },{16, 0, 0, 0},VulkanDataType::UNORM}, - {UFMT_R16F, 1,{'R', 0 , 0 , 0 },{16, 0, 0, 0},VulkanDataType::SFLOAT}, - {UFMT_RG16, 2,{'R','G', 0 , 0 },{16,16, 0, 0},VulkanDataType::UNORM}, - {UFMT_RG16F, 2,{'R','G', 0 , 0 },{16,16, 0, 0},VulkanDataType::SFLOAT}, - {UFMT_RGBA16, 4,{'R','G','B','A'},{16,16,16,16},VulkanDataType::UNORM}, - {UFMT_RGBA16F, 4,{'R','G','B','A'},{16,16,16,16},VulkanDataType::SFLOAT}, - {UFMT_R32U, 1,{'R', 0 , 0 , 0 },{32, 0, 0, 0},VulkanDataType::UINT}, - {UFMT_R32I, 1,{'R', 0 , 0 , 0 },{32, 0, 0, 0},VulkanDataType::SINT}, - {UFMT_R32F, 1,{'R', 0 , 0 , 0 },{32, 0, 0, 0},VulkanDataType::SFLOAT}, - {UFMT_RG32U, 2,{'R','G', 0 , 0 },{32,32, 0, 0},VulkanDataType::UINT}, - {UFMT_RG32I, 2,{'R','G', 0 , 0 },{32,32, 0, 0},VulkanDataType::SINT}, - {UFMT_RG32F, 2,{'R','G', 0 , 0 },{32,32, 0, 0},VulkanDataType::SFLOAT}, - {UFMT_RGB32U, 3,{'R','G','B', 0 },{32,32,32, 0},VulkanDataType::UINT}, - {UFMT_RGB32I, 3,{'R','G','B', 0 },{32,32,32, 0},VulkanDataType::SINT}, - {UFMT_RGB32F, 3,{'R','G','B', 0 },{32,32,32, 0},VulkanDataType::SFLOAT}, - {UFMT_RGBA32U, 4,{'R','G','B','A'},{32,32,32,32},VulkanDataType::UINT}, - {UFMT_RGBA32I, 4,{'R','G','B','A'},{32,32,32,32},VulkanDataType::SINT}, - {UFMT_RGBA32F, 4,{'R','G','B','A'},{32,32,32,32},VulkanDataType::SFLOAT}, - {UFMT_B10GR11UF, 3,{'B','G','R', 0 },{10,11,11, 0},VulkanDataType::UFLOAT} - }; - - constexpr uint PixelFormatCount=sizeof(pf_list)/sizeof(PixelFormat); - - const VkFormat GetVulkanFormat(const int channels,const TexPixelFormat &tpf) - { - const PixelFormat *pf=pf_list; - - for(uint i=0;ichannels)continue; - if(tpf.datatype!=(uint8)pf->type)continue; - - if(tpf.colors[0]!=pf->colors[0])continue; - if(tpf.colors[1]!=pf->colors[1])continue; - if(tpf.colors[2]!=pf->colors[2])continue; - if(tpf.colors[3]!=pf->colors[3])continue; - - if(tpf.bits[0]!=pf->bits[0])continue; - if(tpf.bits[1]!=pf->bits[1])continue; - if(tpf.bits[2]!=pf->bits[2])continue; - if(tpf.bits[3]!=pf->bits[3])continue; - - return pf->format; - } - - return VK_FORMAT_UNDEFINED; - } - - class VkTexture2DLoader:public Texture2DLoader - { - protected: - - Device *device; - - VkFormat format; - vulkan::Buffer *buf; - - Texture2D *tex; - - public: - - VkTexture2DLoader(Device *dev):device(dev) - { - buf=nullptr; - format=VK_FORMAT_UNDEFINED; - tex=nullptr; - } - - virtual ~VkTexture2DLoader() - { - SAFE_CLEAR(buf); - SAFE_CLEAR(tex); - } - - void *OnBegin(uint32 total_bytes) override - { - constexpr VkFormat CompressFormatList[]= - { - FMT_BC1_RGBUN, - FMT_BC1_RGBAUN, - FMT_BC2UN, - FMT_BC3UN, - FMT_BC4UN, - FMT_BC5UN, - FMT_BC6UF, - FMT_BC6SF, - FMT_BC7UN - }; - - constexpr size_t CompressFormatCount=sizeof(CompressFormatList)/sizeof(VkFormat); - - SAFE_CLEAR(buf); - SAFE_CLEAR(tex); - - if(file_header.channels==0) - { - if(compress_format<0||compress_format>=CompressFormatCount) - return(nullptr); - - format=CompressFormatList[compress_format]; - } - else - format=GetVulkanFormat(file_header.channels,pixel_format); - - if(!CheckVulkanFormat(format)) - return(nullptr); - - buf=device->CreateBuffer(VK_BUFFER_USAGE_TRANSFER_SRC_BIT,total_bytes); - - if(!buf) - return(nullptr); - - return buf->Map(); - } - - void OnEnd() override - { - buf->Unmap(); - - tex=device->CreateTexture2D(format,buf,file_header.width,file_header.height); - } - - Texture2D *GetTexture() - { - Texture2D *result=tex; - tex=nullptr; - return result; - } - };//class VkTexture2DLoader -}//namespace - -Texture2D *CreateTextureFromFile(Device *device,const OSString &filename) -{ - VkTexture2DLoader loader(device); - - if(!loader.Load(filename)) - return(nullptr); - - return loader.GetTexture(); -} -VK_NAMESPACE_END diff --git a/src/RenderDevice/Vulkan/VKCommandBuffer.cpp b/src/RenderDevice/Vulkan/VKCommandBuffer.cpp deleted file mode 100644 index 1ea208ca..00000000 --- a/src/RenderDevice/Vulkan/VKCommandBuffer.cpp +++ /dev/null @@ -1,124 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -VK_NAMESPACE_BEGIN -CommandBuffer::CommandBuffer(VkDevice dev,const VkExtent2D &extent,const uint32_t atta_count,VkCommandPool cp,VkCommandBuffer cb) -{ - device=dev; - pool=cp; - cmd_buf=cb; - - cv_count=atta_count; - - if(cv_count>0) - { - clear_values=hgl_zero_new(cv_count); - - clear_values[cv_count-1].depthStencil.depth = 1.0f; - clear_values[cv_count-1].depthStencil.stencil = 0; - } - else - { - clear_values=nullptr; - } - - render_area.offset.x=0; - render_area.offset.y=0; - render_area.extent=extent; - - default_line_width=1.0; - - pipeline_layout=VK_NULL_HANDLE; -} - -CommandBuffer::~CommandBuffer() -{ - delete[] clear_values; - - vkFreeCommandBuffers(device,pool,1,&cmd_buf); -} - -void CommandBuffer::SetRenderArea(const VkExtent2D &ext2d) -{ - render_area.offset.x=0; - render_area.offset.y=0; - render_area.extent=ext2d; -} - -bool CommandBuffer::Begin() -{ - VkCommandBufferBeginInfo cmd_buf_info; - - cmd_buf_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; - cmd_buf_info.pNext = nullptr; - cmd_buf_info.flags = 0; - cmd_buf_info.pInheritanceInfo = nullptr; - - if(vkBeginCommandBuffer(cmd_buf, &cmd_buf_info)!=VK_SUCCESS) - return(false); - - return(true); -} - -bool CommandBuffer::BeginRenderPass(VkRenderPass rp,VkFramebuffer fb) -{ - VkRenderPassBeginInfo rp_begin; - - rp_begin.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; - rp_begin.pNext = nullptr; - rp_begin.renderPass = rp; - rp_begin.framebuffer = fb; - rp_begin.renderArea = render_area; - rp_begin.clearValueCount = cv_count; - rp_begin.pClearValues = clear_values; - - vkCmdBeginRenderPass(cmd_buf, &rp_begin, VK_SUBPASS_CONTENTS_INLINE); - - viewport.x = 0; - viewport.y = 0; - viewport.minDepth = 0.0f; - viewport.maxDepth = 1.0f; - viewport.width = render_area.extent.width; - viewport.height = render_area.extent.height; - - vkCmdSetViewport(cmd_buf,0,1,&viewport); - vkCmdSetScissor(cmd_buf,0,1,&render_area); - vkCmdSetLineWidth(cmd_buf,default_line_width); - - pipeline_layout=VK_NULL_HANDLE; - - return(true); -} - -bool CommandBuffer::BeginRenderPass(RenderTarget *rt) -{ - return BeginRenderPass(rt->GetRenderPass(),rt->GetFramebuffer()); -} - -bool CommandBuffer::Bind(Renderable *render_obj) -{ - if(!render_obj) - return(false); - - const uint count=render_obj->GetBufferCount(); - - if(count<=0) - return(false); - - vkCmdBindVertexBuffers(cmd_buf,0,count,render_obj->GetBuffer(),render_obj->GetOffset()); - - IndexBuffer *indices_buffer=render_obj->GetIndexBuffer(); - - if(indices_buffer) - vkCmdBindIndexBuffer(cmd_buf,indices_buffer->GetBuffer(),render_obj->GetIndexOffset(),VkIndexType(indices_buffer->GetType())); - - return(true); -} -VK_NAMESPACE_END diff --git a/src/RenderDevice/Vulkan/VKDatabase.cpp b/src/RenderDevice/Vulkan/VKDatabase.cpp deleted file mode 100644 index 8aff6c71..00000000 --- a/src/RenderDevice/Vulkan/VKDatabase.cpp +++ /dev/null @@ -1,109 +0,0 @@ -#include -#include -#include - -VK_NAMESPACE_BEGIN -VAB *Database::CreateVAB(VkFormat format,uint32_t count,const void *data,SharingMode sharing_mode) -{ - VAB *vb=device->CreateVAB(format,count,data,sharing_mode); - - if(!vb) - return(nullptr); - - rm_buffers.Add(vb); - - return vb; -} - -#define SCENE_DB_CREATE_BUFFER(name) Buffer *Database::Create##name(VkDeviceSize size,void *data,SharingMode sharing_mode) \ - { \ - Buffer *buf=device->Create##name(size,data,sharing_mode); \ - \ - if(!buf)return(nullptr); \ - rm_buffers.Add(buf); \ - return(buf); \ - } \ - \ - Buffer *Database::Create##name(VkDeviceSize size,SharingMode sharing_mode) \ - { \ - Buffer *buf=device->Create##name(size,sharing_mode); \ - \ - if(!buf)return(nullptr); \ - rm_buffers.Add(buf); \ - return(buf); \ - } - - SCENE_DB_CREATE_BUFFER(UBO) - SCENE_DB_CREATE_BUFFER(SSBO) - SCENE_DB_CREATE_BUFFER(INBO) - -#undef SCENE_DB_CREATE_BUFFER - -IndexBuffer *Database::CreateIBO(IndexType index_type,uint32_t count,const void *data,SharingMode sharing_mode) -{ - IndexBuffer *buf=device->CreateIBO(index_type,count,data,sharing_mode); - - if(!buf)return(nullptr); - rm_buffers.Add(buf); - return(buf); -} - -MaterialInstance *Database::CreateMaterialInstance(Material *mtl) -{ - if(!mtl)return(nullptr); - - MaterialInstance *mi=mtl->CreateInstance(); - - if(mi) - Add(mi); - - return mi; -} - -Renderable *Database::CreateRenderable(Material *mtl,const uint32_t vertex_count) -{ - if(!mtl)return(nullptr); - - Renderable *ro=mtl->CreateRenderable(vertex_count); - - if(ro) - Add(ro); - - return ro; -} - -TextRenderable *Database::CreateTextRenderable(Material *mtl) -{ - if(!mtl)return(nullptr); - - TextRenderable *tr=new TextRenderable(device,mtl); - - if(tr) - Add(tr); - - return tr; -} - -RenderableInstance *Database::CreateRenderableInstance(Pipeline *p,MaterialInstance *mi,Renderable *r) -{ - if(!p||!mi||!r) - return(nullptr); - - RenderableInstance *ri=new RenderableInstance(p,mi,r); - - if(ri) - Add(ri); - - return ri; -} - -Sampler *Database::CreateSampler(VkSamplerCreateInfo *sci) -{ - Sampler *s=device->CreateSampler(sci); - - if(s) - Add(s); - - return s; -} -VK_NAMESPACE_END diff --git a/src/RenderDevice/Vulkan/VKDescriptorSetLayoutCreater.cpp b/src/RenderDevice/Vulkan/VKDescriptorSetLayoutCreater.cpp deleted file mode 100644 index 6ba4359b..00000000 --- a/src/RenderDevice/Vulkan/VKDescriptorSetLayoutCreater.cpp +++ /dev/null @@ -1,136 +0,0 @@ -#include"VKDescriptorSetLayoutCreater.h" -#include -#include - -VK_NAMESPACE_BEGIN -DescriptorSetLayoutCreater::~DescriptorSetLayoutCreater() -{ - if(pipeline_layout) - vkDestroyPipelineLayout(*device,pipeline_layout,nullptr); - - if(dsl) - vkDestroyDescriptorSetLayout(*device,dsl,nullptr); -} - -void DescriptorSetLayoutCreater::Bind(const uint32_t binding,VkDescriptorType desc_type,VkShaderStageFlagBits stageFlags) -{ - if(index_by_binding.KeyExist(binding)) - { - //重复的绑定点,有可能存在的,比如WorldMatrix在vs/fs中同时存在 - return; - } - - VkDescriptorSetLayoutBinding layout_binding; - - layout_binding.binding = binding; - layout_binding.descriptorType = desc_type; - layout_binding.descriptorCount = 1; - layout_binding.stageFlags = stageFlags; - layout_binding.pImmutableSamplers = nullptr; - - const int index=layout_binding_list.Add(layout_binding); - - index_by_binding.Add(binding,index); -} - -void DescriptorSetLayoutCreater::Bind(const uint32_t *binding,const uint32_t count,VkDescriptorType desc_type,VkShaderStageFlagBits stageFlags) -{ - if(!binding||count<=0)return; - - const uint old_count=layout_binding_list.GetCount(); - - layout_binding_list.PreMalloc(old_count+count); - - VkDescriptorSetLayoutBinding *p=layout_binding_list.GetData()+old_count; - - uint fin_count=0; - - for(uint i=old_count;ibinding = *binding; - p->descriptorType = desc_type; - p->descriptorCount = 1; - p->stageFlags = stageFlags; - p->pImmutableSamplers = nullptr; - - index_by_binding.Add(*binding,i); - - ++p; - ++fin_count; - } - - ++binding; - } - - layout_binding_list.SetCount(old_count+fin_count); -} - -bool DescriptorSetLayoutCreater::CreatePipelineLayout() -{ - const int count=layout_binding_list.GetCount(); - - if(count<=0) - return(false); - - VkDescriptorSetLayoutCreateInfo descriptor_layout; - - descriptor_layout.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; - descriptor_layout.pNext = nullptr; - descriptor_layout.flags = 0; - descriptor_layout.bindingCount = count; - descriptor_layout.pBindings = layout_binding_list.GetData(); - - if(dsl) - vkDestroyDescriptorSetLayout(*device,dsl,nullptr); - - if(vkCreateDescriptorSetLayout(*device,&descriptor_layout,nullptr,&dsl)!=VK_SUCCESS) - return(false); - - VkPushConstantRange push_constant_range; - - push_constant_range.stageFlags = VK_SHADER_STAGE_VERTEX_BIT; - push_constant_range.size = MAX_PUSH_CONSTANT_BYTES; - push_constant_range.offset = 0; - - VkPipelineLayoutCreateInfo pPipelineLayoutCreateInfo; - pPipelineLayoutCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; - pPipelineLayoutCreateInfo.pNext = nullptr; - pPipelineLayoutCreateInfo.flags = 0; - pPipelineLayoutCreateInfo.setLayoutCount = 1; - pPipelineLayoutCreateInfo.pSetLayouts = &dsl; - pPipelineLayoutCreateInfo.pushConstantRangeCount = 1; - pPipelineLayoutCreateInfo.pPushConstantRanges = &push_constant_range; - - if(vkCreatePipelineLayout(*device,&pPipelineLayoutCreateInfo,nullptr,&pipeline_layout)!=VK_SUCCESS) - return(false); - - return(true); -} - -DescriptorSets *DescriptorSetLayoutCreater::Create() -{ - if(!pipeline_layout||!dsl) - return(nullptr); - - const int count=layout_binding_list.GetCount(); - - if(count<=0) - return(nullptr); - - VkDescriptorSetAllocateInfo alloc_info; - alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; - alloc_info.pNext = nullptr; - alloc_info.descriptorPool = device->GetDescriptorPool(); - alloc_info.descriptorSetCount = 1; - alloc_info.pSetLayouts = &dsl; - - VkDescriptorSet desc_set; - - if(vkAllocateDescriptorSets(*device,&alloc_info,&desc_set)!=VK_SUCCESS) - return(nullptr); - - return(new DescriptorSets(device,count,pipeline_layout,desc_set,&index_by_binding)); -} -VK_NAMESPACE_END \ No newline at end of file diff --git a/src/RenderDevice/Vulkan/VKDescriptorSetLayoutCreater.h b/src/RenderDevice/Vulkan/VKDescriptorSetLayoutCreater.h deleted file mode 100644 index af65f88d..00000000 --- a/src/RenderDevice/Vulkan/VKDescriptorSetLayoutCreater.h +++ /dev/null @@ -1,74 +0,0 @@ -#pragma once - -#include -#include -VK_NAMESPACE_BEGIN -class Device; -class DescriptorSets; - -/** -* 描述符合集创造器 -*/ -class DescriptorSetLayoutCreater -{ - Device *device; - - List layout_binding_list; - VkDescriptorSetLayout dsl=VK_NULL_HANDLE; - Map index_by_binding; - - VkPipelineLayout pipeline_layout=VK_NULL_HANDLE; - -public: - - DescriptorSetLayoutCreater(Device *dev):device(dev){} - ~DescriptorSetLayoutCreater(); - - void Bind(const uint32_t binding,VkDescriptorType,VkShaderStageFlagBits); - void Bind(const uint32_t *binding,const uint32_t count,VkDescriptorType type,VkShaderStageFlagBits stage); - void Bind(const DescriptorBindingList &dbl,VkDescriptorType type,VkShaderStageFlagBits stage) - { - if(dbl.GetCount()>0) - Bind(dbl.GetData(),dbl.GetCount(),type,stage); - } - - void Bind(const ShaderDescriptorList *sdl,VkShaderStageFlagBits stage) - { - for(uint32_t i=VK_DESCRIPTOR_TYPE_BEGIN_RANGE;i<=VK_DESCRIPTOR_TYPE_END_RANGE;i++) - { - if(sdl->binding_list.GetCount()>0) - Bind(sdl->binding_list.GetData(),sdl->binding_list.GetCount(),(VkDescriptorType)i,stage); - - ++sdl; - } - } - -//以下代码不再需要,使用一个void Bind(const ShaderResource &sr,VkShaderStageFlagBits stage)即可全部替代,而且更方便,但以此为提示 -// -//#define DESC_SET_BIND_FUNC(name,vkname) void Bind##name(const uint32_t binding,VkShaderStageFlagBits stage_flag){Bind(binding,VK_DESCRIPTOR_TYPE_##vkname,stage_flag);} \ -// void Bind##name(const uint32_t *binding,const uint32_t count,VkShaderStageFlagBits stage_flag){Bind(binding,count,VK_DESCRIPTOR_TYPE_##vkname,stage_flag);} -// -// DESC_SET_BIND_FUNC(Sampler, SAMPLER); -// -// DESC_SET_BIND_FUNC(CombinedImageSampler, COMBINED_IMAGE_SAMPLER); -// DESC_SET_BIND_FUNC(SampledImage, SAMPLED_IMAGE); -// DESC_SET_BIND_FUNC(StorageImage, STORAGE_IMAGE); -// -// DESC_SET_BIND_FUNC(UTBO, UNIFORM_TEXEL_BUFFER); -// DESC_SET_BIND_FUNC(SSTBO, STORAGE_TEXEL_BUFFER); -// DESC_SET_BIND_FUNC(UBO, UNIFORM_BUFFER); -// DESC_SET_BIND_FUNC(SSBO, STORAGE_BUFFER); -// DESC_SET_BIND_FUNC(UBODynamic, UNIFORM_BUFFER_DYNAMIC); -// DESC_SET_BIND_FUNC(SSBODynamic, STORAGE_BUFFER_DYNAMIC); -// -// DESC_SET_BIND_FUNC(InputAttachment, INPUT_ATTACHMENT); -// -//#undef DESC_SET_BIND_FUNC - - bool CreatePipelineLayout(); - - const VkPipelineLayout GetPipelineLayout()const{return pipeline_layout;} - - DescriptorSets *Create(); -};//class DescriptorSetLayoutCreater -VK_NAMESPACE_END \ No newline at end of file diff --git a/src/RenderDevice/Vulkan/VKDescriptorSets.cpp b/src/RenderDevice/Vulkan/VKDescriptorSets.cpp deleted file mode 100644 index 61f10754..00000000 --- a/src/RenderDevice/Vulkan/VKDescriptorSets.cpp +++ /dev/null @@ -1,92 +0,0 @@ -#include -#include -#include -#include -#include - -VK_NAMESPACE_BEGIN -void DescriptorSets::Clear() -{ - wds_list.ClearData(); - desc_image_info.ClearData(); -} - -bool DescriptorSets::BindUBO(const int binding,const Buffer *buf) -{ - if(binding<0||!buf) - return(false); - - VkWriteDescriptorSet wds; - - wds.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; - wds.pNext = nullptr; - wds.dstSet = desc_set; - wds.dstBinding = binding; - wds.dstArrayElement = 0; - wds.descriptorCount = 1; - wds.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; - wds.pImageInfo = nullptr; - wds.pBufferInfo = buf->GetBufferInfo(); - wds.pTexelBufferView = nullptr; - - wds_list.Add(wds); - return(true); -} - -bool DescriptorSets::BindUBODynamic(const int binding,const Buffer *buf) -{ - if(binding<0||!buf) - return(false); - - VkWriteDescriptorSet wds; - - wds.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; - wds.pNext = nullptr; - wds.dstSet = desc_set; - wds.dstBinding = binding; - wds.dstArrayElement = 0; - wds.descriptorCount = 1; - wds.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC; - wds.pImageInfo = nullptr; - wds.pBufferInfo = buf->GetBufferInfo(); - wds.pTexelBufferView = nullptr; - - wds_list.Add(wds); - return(true); -} - -bool DescriptorSets::BindSampler(const int binding,Texture *tex,Sampler *sampler) -{ - if(binding<0||!tex||!sampler) - return(false); - - VkDescriptorImageInfo *image_info=new VkDescriptorImageInfo; - image_info->imageView =tex->GetVulkanImageView(); - //image_info->imageLayout =tex->GetImageLayout(); - image_info->imageLayout =VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; - image_info->sampler =*sampler; - - desc_image_info.Add(image_info); - - VkWriteDescriptorSet wds; - - wds.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; - wds.pNext = nullptr; - wds.dstSet = desc_set; - wds.dstBinding = binding; - wds.dstArrayElement = 0; - wds.descriptorCount = 1; - wds.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; - wds.pImageInfo = image_info; - wds.pBufferInfo = nullptr; - wds.pTexelBufferView = nullptr; - - wds_list.Add(wds); - return(true); -} - -void DescriptorSets::Update() -{ - vkUpdateDescriptorSets(*device,wds_list.GetCount(),wds_list.GetData(),0,nullptr); -} -VK_NAMESPACE_END diff --git a/src/RenderDevice/Vulkan/VKDevice.cpp b/src/RenderDevice/Vulkan/VKDevice.cpp deleted file mode 100644 index 03f57376..00000000 --- a/src/RenderDevice/Vulkan/VKDevice.cpp +++ /dev/null @@ -1,122 +0,0 @@ -#include -#include -#include -#include -#include -#include -//#include -#include -#include -#include -#include - -VK_NAMESPACE_BEGIN -Device::Device(DeviceAttribute *da) -{ - attr=da; - - textureSQ=nullptr; - texture_cmd_buf=nullptr; - - swapchain=nullptr; - swapchainRT=nullptr; - Resize(attr->surface_caps.currentExtent); -} - -Device::~Device() -{ - SAFE_CLEAR(swapchainRT); - SAFE_CLEAR(swapchain); - - SAFE_CLEAR(textureSQ); - SAFE_CLEAR(texture_cmd_buf); - - delete attr; -} - -bool Device::Resize(const VkExtent2D &extent) -{ - SAFE_CLEAR(swapchainRT); - SAFE_CLEAR(swapchain); - - SAFE_CLEAR(textureSQ); - SAFE_CLEAR(texture_cmd_buf); - - attr->Refresh(); - - if(!CreateSwapchain(extent)) - return(false); - - texture_cmd_buf=CreateCommandBuffer(extent,0); - textureSQ=new SubmitQueue(this,attr->graphics_queue,1); - - swapchainRT=new SwapchainRenderTarget(this,swapchain); - - return(true); -} - -CommandBuffer *Device::CreateCommandBuffer(const VkExtent2D &extent,const uint32_t atta_count) -{ - if(!attr->cmd_pool) - return(nullptr); - - VkCommandBufferAllocateInfo cmd; - cmd.sType =VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; - cmd.pNext =nullptr; - cmd.commandPool =attr->cmd_pool; - cmd.level =VK_COMMAND_BUFFER_LEVEL_PRIMARY; - cmd.commandBufferCount =1; - - VkCommandBuffer cmd_buf; - - VkResult res=vkAllocateCommandBuffers(attr->device,&cmd,&cmd_buf); - - if(res!=VK_SUCCESS) - return(nullptr); - - return(new CommandBuffer(attr->device,extent,atta_count,attr->cmd_pool,cmd_buf)); -} - -/** - * 创建栅栏 - * @param create_signaled 是否创建初始信号 - */ -Fence *Device::CreateFence(bool create_signaled) -{ - VkFenceCreateInfo fenceInfo; - fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; - fenceInfo.pNext = nullptr; - fenceInfo.flags = create_signaled?VK_FENCE_CREATE_SIGNALED_BIT:0; - - VkFence fence; - - if(vkCreateFence(attr->device, &fenceInfo, nullptr, &fence)!=VK_SUCCESS) - return(nullptr); - - return(new Fence(attr->device,fence)); -} - -vulkan::Semaphore *Device::CreateSem() -{ - VkSemaphoreCreateInfo SemaphoreCreateInfo; - SemaphoreCreateInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; - SemaphoreCreateInfo.pNext = nullptr; - SemaphoreCreateInfo.flags = 0; - - VkSemaphore sem; - if(vkCreateSemaphore(attr->device, &SemaphoreCreateInfo, nullptr, &sem)!=VK_SUCCESS) - return(nullptr); - - return(new vulkan::Semaphore(attr->device,sem)); -} - -ShaderModuleManage *Device::CreateShaderModuleManage() -{ - return(new ShaderModuleManage(this)); -} - -RenderTarget *Device::CreateRenderTarget(Framebuffer *fb) -{ - return(new RenderTarget(this,fb)); -} -VK_NAMESPACE_END diff --git a/src/RenderDevice/Vulkan/VKDeviceAttribute.cpp b/src/RenderDevice/Vulkan/VKDeviceAttribute.cpp deleted file mode 100644 index 1a69446a..00000000 --- a/src/RenderDevice/Vulkan/VKDeviceAttribute.cpp +++ /dev/null @@ -1,160 +0,0 @@ -#include -#include -#include -#include -#include - -VK_NAMESPACE_BEGIN -DeviceAttribute::DeviceAttribute(VkInstance inst,const PhysicalDevice *pd,VkSurfaceKHR s) -{ - instance=inst; - physical_device=pd; - surface=s; - - Refresh(); -} - -DeviceAttribute::~DeviceAttribute() -{ - if(pipeline_cache) - vkDestroyPipelineCache(device,pipeline_cache,nullptr); - - if(desc_pool) - vkDestroyDescriptorPool(device,desc_pool,nullptr); - - if(cmd_pool) - vkDestroyCommandPool(device,cmd_pool,nullptr); - - if(device) - vkDestroyDevice(device,nullptr); - - if(surface) - vkDestroySurfaceKHR(instance,surface,nullptr); -} - -bool DeviceAttribute::CheckMemoryType(uint32_t typeBits,VkMemoryPropertyFlags properties,uint32_t *typeIndex) const -{ - return physical_device->CheckMemoryType(typeBits,properties,typeIndex); -} - -void DeviceAttribute::Refresh() -{ - VkPhysicalDevice pdevice = *physical_device; - - vkGetPhysicalDeviceSurfaceCapabilitiesKHR(pdevice, surface, &surface_caps); - - { - if (surface_caps.supportedTransforms & VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR) - { - preTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR; - } - else - { - preTransform = surface_caps.currentTransform; - } - } - - { - constexpr VkCompositeAlphaFlagBitsKHR compositeAlphaFlags[4]={VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR, - VK_COMPOSITE_ALPHA_PRE_MULTIPLIED_BIT_KHR, - VK_COMPOSITE_ALPHA_POST_MULTIPLIED_BIT_KHR, - VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR }; - - for (uint32_t i = 0; i < sizeof(compositeAlphaFlags); i++) - { - if (surface_caps.supportedCompositeAlpha & compositeAlphaFlags[i]) - { - compositeAlpha = compositeAlphaFlags[i]; - break; - } - } - } - - { - uint32_t format_count; - if (vkGetPhysicalDeviceSurfaceFormatsKHR(pdevice, surface, &format_count, nullptr) == VK_SUCCESS) - { - surface_formts.SetCount(format_count); - - if (vkGetPhysicalDeviceSurfaceFormatsKHR(pdevice, surface, &format_count, surface_formts.GetData()) != VK_SUCCESS) - { - surface_formts.Clear(); - format = VK_FORMAT_B8G8R8A8_UNORM; - } - else - { - VkSurfaceFormatKHR *sf = surface_formts.GetData(); - - if (format_count == 1 && sf->format == VK_FORMAT_UNDEFINED) - format = VK_FORMAT_B8G8R8A8_UNORM; - else - format = sf->format; - } - } - } - - { - uint32_t mode_count; - if (vkGetPhysicalDeviceSurfacePresentModesKHR(pdevice, surface, &mode_count, nullptr) == VK_SUCCESS) - { - present_modes.SetCount(mode_count); - if (vkGetPhysicalDeviceSurfacePresentModesKHR(pdevice, surface, &mode_count, present_modes.GetData()) != VK_SUCCESS) - present_modes.Clear(); - } - } - - { - uint32_t family_count; - vkGetPhysicalDeviceQueueFamilyProperties(pdevice, &family_count, nullptr); - family_properties.SetCount(family_count); - vkGetPhysicalDeviceQueueFamilyProperties(pdevice, &family_count, family_properties.GetData()); - - { - supports_present.SetCount(family_count); - VkBool32 *sp = supports_present.GetData(); - for (uint32_t i = 0; i < family_count; i++) - { - vkGetPhysicalDeviceSurfaceSupportKHR(pdevice, i, surface, sp); - ++sp; - } - } - - { - VkQueueFamilyProperties *fp = family_properties.GetData(); - VkBool32 *sp = supports_present.GetData(); - for (uint32_t i = 0; i < family_count; i++) - { - if (fp->queueFlags & VK_QUEUE_GRAPHICS_BIT) - { - if (graphics_family == ERROR_FAMILY_INDEX) - graphics_family = i; - - if (*sp) - { - graphics_family = i; - present_family = i; - break; - } - } - - ++fp; - ++sp; - } - } - - if (present_family == ERROR_FAMILY_INDEX) - { - VkBool32 *sp = supports_present.GetData(); - for (uint32_t i = 0; i < family_count; i++) - { - if (*sp) - { - present_family = i; - break; - } - ++sp; - } - } - } -} -VK_NAMESPACE_END diff --git a/src/RenderDevice/Vulkan/VKDeviceImage.cpp b/src/RenderDevice/Vulkan/VKDeviceImage.cpp deleted file mode 100644 index 90381bf5..00000000 --- a/src/RenderDevice/Vulkan/VKDeviceImage.cpp +++ /dev/null @@ -1,234 +0,0 @@ -#include - -VK_NAMESPACE_BEGIN -namespace -{ - void InitImageCreateInfo(VkImageCreateInfo &imageCreateInfo) - { - imageCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; - imageCreateInfo.pNext = nullptr; - imageCreateInfo.flags = 0; - imageCreateInfo.mipLevels = 1; - imageCreateInfo.arrayLayers = 1; - imageCreateInfo.samples = VK_SAMPLE_COUNT_1_BIT; - imageCreateInfo.sharingMode = VkSharingMode(SharingMode::Exclusive); - imageCreateInfo.queueFamilyIndexCount = 0; - imageCreateInfo.pQueueFamilyIndices = nullptr; - imageCreateInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; - } -}//namespace - -VkImage Device::CreateImage1D(const VkFormat format,const uint32_t length,const uint usage,const ImageTiling tiling) -{ - if(!CheckVulkanFormat(format))return(nullptr); - if(length<1)return(nullptr); - - VkImageCreateInfo imageCreateInfo; - - imageCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; - imageCreateInfo.pNext = nullptr; - imageCreateInfo.flags = 0; - imageCreateInfo.imageType = VK_IMAGE_TYPE_2D; - imageCreateInfo.format = format; - imageCreateInfo.extent.width = length; - imageCreateInfo.extent.height = 1; - imageCreateInfo.extent.depth = 1; - imageCreateInfo.mipLevels = 1; - imageCreateInfo.arrayLayers = 1; - imageCreateInfo.samples = VK_SAMPLE_COUNT_1_BIT; - imageCreateInfo.usage = usage; - imageCreateInfo.sharingMode = VkSharingMode(SharingMode::Exclusive); - imageCreateInfo.queueFamilyIndexCount = 0; - imageCreateInfo.pQueueFamilyIndices = nullptr; - imageCreateInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; - imageCreateInfo.tiling = VkImageTiling(tiling); - - VkImage image; - - if(vkCreateImage(attr->device,&imageCreateInfo, nullptr, &image)!=VK_SUCCESS) - return(nullptr); - - return image; -} - -VkImage Device::CreateImage1DArray(const VkFormat format,const uint32_t length,const uint32_t layer,const uint usage,const ImageTiling tiling) -{ - if(!CheckVulkanFormat(format))return(nullptr); - if(length<1||layer<1)return(nullptr); - - VkImageCreateInfo imageCreateInfo; - - imageCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; - imageCreateInfo.pNext = nullptr; - imageCreateInfo.flags = 0; - imageCreateInfo.imageType = VK_IMAGE_TYPE_1D; - imageCreateInfo.format = format; - imageCreateInfo.extent.width = length; - imageCreateInfo.extent.height = 1; - imageCreateInfo.extent.depth = 1; - imageCreateInfo.mipLevels = 1; - imageCreateInfo.arrayLayers = layer; - imageCreateInfo.samples = VK_SAMPLE_COUNT_1_BIT; - imageCreateInfo.usage = usage; - imageCreateInfo.sharingMode = VkSharingMode(SharingMode::Exclusive); - imageCreateInfo.queueFamilyIndexCount = 0; - imageCreateInfo.pQueueFamilyIndices = nullptr; - imageCreateInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; - imageCreateInfo.tiling = VkImageTiling(tiling); - - VkImage image; - - if(vkCreateImage(attr->device,&imageCreateInfo, nullptr, &image)!=VK_SUCCESS) - return(nullptr); - - return image; -} - -VkImage Device::CreateImage2D(const VkFormat format,const uint32_t width,const uint32_t height,const uint usage,const ImageTiling tiling) -{ - if(!CheckVulkanFormat(format))return(nullptr); - if(width<1||height<1)return(nullptr); - - VkImageCreateInfo imageCreateInfo; - - imageCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; - imageCreateInfo.pNext = nullptr; - imageCreateInfo.flags = 0; - imageCreateInfo.imageType = VK_IMAGE_TYPE_2D; - imageCreateInfo.format = format; - imageCreateInfo.extent.width = width; - imageCreateInfo.extent.height = height; - imageCreateInfo.extent.depth = 1; - imageCreateInfo.mipLevels = 1; - imageCreateInfo.arrayLayers = 1; - imageCreateInfo.samples = VK_SAMPLE_COUNT_1_BIT; - imageCreateInfo.usage = usage; - imageCreateInfo.sharingMode = VkSharingMode(SharingMode::Exclusive); - imageCreateInfo.queueFamilyIndexCount = 0; - imageCreateInfo.pQueueFamilyIndices = nullptr; - imageCreateInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; - imageCreateInfo.tiling = VkImageTiling(tiling); - - VkImage image; - - if(vkCreateImage(attr->device,&imageCreateInfo, nullptr, &image)!=VK_SUCCESS) - return(nullptr); - - return image; -} - -VkImage Device::CreateImage2DArray(const VkFormat format,const uint32_t width,const uint32_t height,const uint32_t layer,const uint usage,const ImageTiling tiling) -{ - if(!CheckVulkanFormat(format))return(nullptr); - if(width<1||height<1)return(nullptr); - - VkImageCreateInfo imageCreateInfo; - - imageCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; - imageCreateInfo.pNext = nullptr; - imageCreateInfo.flags = 0; - imageCreateInfo.imageType = VK_IMAGE_TYPE_2D; - imageCreateInfo.format = format; - imageCreateInfo.extent.width = width; - imageCreateInfo.extent.height = height; - imageCreateInfo.extent.depth = 1; - imageCreateInfo.mipLevels = 1; - imageCreateInfo.arrayLayers = layer; - imageCreateInfo.samples = VK_SAMPLE_COUNT_1_BIT; - imageCreateInfo.usage = usage; - imageCreateInfo.sharingMode = VkSharingMode(SharingMode::Exclusive); - imageCreateInfo.queueFamilyIndexCount = 0; - imageCreateInfo.pQueueFamilyIndices = nullptr; - imageCreateInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; - imageCreateInfo.tiling = VkImageTiling(tiling); - - VkImage image; - - if(vkCreateImage(attr->device,&imageCreateInfo, nullptr, &image)!=VK_SUCCESS) - return(nullptr); - - return image; -} - -VkImage Device::CreateImage3D(const VkFormat format,const uint32_t width,const uint32_t height,const uint32_t depth,const uint usage,const ImageTiling tiling) -{ - if(!CheckVulkanFormat(format))return(nullptr); - if(width<1||height<1)return(nullptr); - - VkImageCreateInfo imageCreateInfo; - - imageCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; - imageCreateInfo.pNext = nullptr; - imageCreateInfo.flags = 0; - imageCreateInfo.imageType = VK_IMAGE_TYPE_3D; - imageCreateInfo.format = format; - imageCreateInfo.extent.width = width; - imageCreateInfo.extent.height = height; - imageCreateInfo.extent.depth = depth; - imageCreateInfo.mipLevels = 1; - imageCreateInfo.arrayLayers = 1; - imageCreateInfo.samples = VK_SAMPLE_COUNT_1_BIT; - imageCreateInfo.usage = usage; - imageCreateInfo.sharingMode = VkSharingMode(SharingMode::Exclusive); - imageCreateInfo.queueFamilyIndexCount = 0; - imageCreateInfo.pQueueFamilyIndices = nullptr; - imageCreateInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; - imageCreateInfo.tiling = VkImageTiling(tiling); - - VkImage image; - - if(vkCreateImage(attr->device,&imageCreateInfo, nullptr, &image)!=VK_SUCCESS) - return(nullptr); - - return image; -} - -VkImage Device::CreateCubemap(const VkFormat format,const uint32_t width,const uint32_t height,const uint usage,const ImageTiling tiling) -{ - if(!CheckVulkanFormat(format))return(nullptr); - if(width<1||height<1)return(nullptr); - - VkImageCreateInfo imageCreateInfo; - - imageCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; - imageCreateInfo.pNext = nullptr; - imageCreateInfo.flags = VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT; - imageCreateInfo.imageType = VK_IMAGE_TYPE_2D; - imageCreateInfo.format = format; - imageCreateInfo.extent.width = width; - imageCreateInfo.extent.height = height; - imageCreateInfo.extent.depth = 1; - imageCreateInfo.mipLevels = 1; - imageCreateInfo.arrayLayers = 6; - imageCreateInfo.samples = VK_SAMPLE_COUNT_1_BIT; - imageCreateInfo.usage = usage; - imageCreateInfo.sharingMode = VkSharingMode(SharingMode::Exclusive); - imageCreateInfo.queueFamilyIndexCount = 0; - imageCreateInfo.pQueueFamilyIndices = nullptr; - imageCreateInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; - imageCreateInfo.tiling = VkImageTiling(tiling); - - VkImage image; - - if(vkCreateImage(attr->device,&imageCreateInfo, nullptr, &image)!=VK_SUCCESS) - return(nullptr); - - return image; -} - -void Device::DestoryImage(VkImage img) -{ - if(img==VK_NULL_HANDLE)return; - - vkDestroyImage(attr->device,img,nullptr); -} - -Memory *Device::CreateMemory(VkImage image,const uint32_t flag) -{ - VkMemoryRequirements memReqs; - - vkGetImageMemoryRequirements(attr->device,image,&memReqs); - - return CreateMemory(memReqs,flag); -} -VK_NAMESPACE_END diff --git a/src/RenderDevice/Vulkan/VKDeviceRenderPass.cpp b/src/RenderDevice/Vulkan/VKDeviceRenderPass.cpp deleted file mode 100644 index c5afa911..00000000 --- a/src/RenderDevice/Vulkan/VKDeviceRenderPass.cpp +++ /dev/null @@ -1,294 +0,0 @@ -#include -#include -#include - -VK_NAMESPACE_BEGIN -void Device::CreateSubpassDependency(VkSubpassDependency *dependency) -{ - dependency->srcSubpass = VK_SUBPASS_EXTERNAL; - dependency->dstSubpass = 0; - dependency->srcStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT; - dependency->srcAccessMask = VK_ACCESS_MEMORY_READ_BIT; - dependency->dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT; - dependency->dstStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT; - dependency->dstAccessMask = VK_ACCESS_MEMORY_READ_BIT; -} - -void Device::CreateSubpassDependency(List &subpass_dependency_list,const uint32_t count) const -{ - if(count<=0)return; - - subpass_dependency_list.SetCount(count); - - VkSubpassDependency *dependency=subpass_dependency_list.GetData(); - - dependency->srcSubpass = VK_SUBPASS_EXTERNAL; - dependency->dstSubpass = 0; - dependency->srcStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT; - dependency->srcAccessMask = VK_ACCESS_MEMORY_READ_BIT; - dependency->dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT; - - if(count==1) - { - dependency->dstStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT; - dependency->dstAccessMask = VK_ACCESS_MEMORY_READ_BIT; - } - else - { - dependency->dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; - dependency->dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; - - ++dependency; - - for(uint32_t i=1;isrcSubpass = i-1; - dependency->srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; - - if(i==count-1) - { - dependency->dstSubpass = VK_SUBPASS_EXTERNAL; - dependency->dstStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT; - dependency->srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; - dependency->dstAccessMask = VK_ACCESS_MEMORY_READ_BIT; - } - else - { - dependency->dstSubpass = i; - dependency->dstStageMask = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT; - dependency->srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; - dependency->dstAccessMask = VK_ACCESS_SHADER_READ_BIT; - } - - dependency->dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT; - - ++dependency; - } - } -} - -void Device::CreateAttachmentReference(VkAttachmentReference *ref_list,uint start,uint count,VkImageLayout layout) const -{ - VkAttachmentReference *ref=ref_list; - - for(uint i=start;iattachment =i; - ref->layout =layout; - - ++ref; - } -} - -bool Device::CreateAttachment(List &desc_list,const List &color_format,const VkFormat depth_format,VkImageLayout color_final_layout,VkImageLayout depth_final_layout) const -{ - const uint color_count=color_format.GetCount(); - - desc_list.SetCount(color_count+1); - VkAttachmentDescription *desc=desc_list.GetData(); - - for(uint i=0;iflags = 0; - desc->samples = VK_SAMPLE_COUNT_1_BIT; - desc->loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; //LOAD_OP_CLEAR代表LOAD时清空内容 - desc->storeOp = VK_ATTACHMENT_STORE_OP_STORE; //STORE_OP_STROE代表SOTRE时储存内容 - desc->stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; //DONT CARE表示不在意 - desc->stencilStoreOp= VK_ATTACHMENT_STORE_OP_DONT_CARE; - desc->initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; //代表不关心初始布局 - - ++desc; - } - - desc=desc_list.GetData(); - const VkFormat *cf=color_format.GetData(); - for(uint i=0;ifinalLayout = color_final_layout; - desc->format = *cf; - - ++desc; - ++cf; - } - - desc->finalLayout = depth_final_layout; - desc->format = depth_format; - desc->storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; //深度缓冲区不用于显示也不用于下一帧,所以结束后不用保存 - - return(true); -} - -bool Device::CreateColorAttachment( List &ref_list,List &desc_list,const List &color_format,const VkImageLayout color_final_layout) const -{ - const VkFormat *cf=color_format.GetData(); - - for(int i=0;iphysical_device->IsColorAttachmentOptimal(*cf)) - return(false); - - ++cf; - } - - ref_list.SetCount(color_format.GetCount()); - VkAttachmentReference *ref=ref_list.GetData(); - - desc_list.SetCount(color_format.GetCount()); - VkAttachmentDescription *desc=desc_list.GetData(); - - for(int i=0;iflags = 0; - desc->samples = VK_SAMPLE_COUNT_1_BIT; - desc->loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; //LOAD_OP_CLEAR代表LOAD时清空内容 - desc->storeOp = VK_ATTACHMENT_STORE_OP_STORE; //STORE_OP_STROE代表SOTRE时储存内容 - desc->stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; //DONT CARE表示不在意 - desc->stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; - desc->initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; //代表不关心初始布局 - desc->finalLayout = color_final_layout; - ++desc; - - ref->attachment = i; - ref->layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; - ++ref; - } - - return(true); -} - -bool Device::CreateDepthAttachment( List &ref_list,List &desc_list,const VkFormat &depth_format,const VkImageLayout depth_final_layout) const -{ - if(!attr->physical_device->IsDepthAttachmentOptimal(depth_format)) - return(false); - - { - ref_list.SetCount(1); - VkAttachmentReference *ref=ref_list.GetData(); - - ref->attachment=0; - ref->layout=VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; - } - - { - desc_list.SetCount(1); - VkAttachmentDescription *desc=desc_list.GetData(); - - desc->flags = 0; - desc->samples = VK_SAMPLE_COUNT_1_BIT; - desc->loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; //LOAD_OP_CLEAR代表LOAD时清空内容 - desc->storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; //DONT CARE表示不在意 - desc->stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; - desc->stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; - desc->initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; //代表不关心初始布局 - desc->finalLayout = depth_final_layout; - } - - return(true); -} - -void Device::CreateSubpassDescription(VkSubpassDescription &sd,const List &color_ref_list,VkAttachmentReference *depth_ref) const -{ - sd.flags =0; - sd.pipelineBindPoint =VK_PIPELINE_BIND_POINT_GRAPHICS; - sd.inputAttachmentCount =0; - sd.pInputAttachments =nullptr; - - sd.pColorAttachments =color_ref_list.GetData(); - sd.colorAttachmentCount =color_ref_list.GetCount(); - - sd.pDepthStencilAttachment =depth_ref; - - sd.pResolveAttachments =nullptr; - sd.preserveAttachmentCount =0; - sd.pPreserveAttachments =nullptr; -} - -RenderPass *Device::CreateRenderPass( const List &desc_list, - const List &subpass, - const List &dependency, - const List &color_format, - const VkFormat depth_format, - const VkImageLayout color_final_layout, - const VkImageLayout depth_final_layout) const -{ - { - const VkFormat *cf=color_format.GetData(); - - for(int i=0;iphysical_device->IsColorAttachmentOptimal(*cf) - &&!attr->physical_device->IsColorAttachmentLinear(*cf)) - return(nullptr); - - ++cf; - } - } - - if(!attr->physical_device->IsDepthAttachmentOptimal(depth_format) - &&!attr->physical_device->IsDepthAttachmentLinear(depth_format)) - return(nullptr); - - VkRenderPassCreateInfo rp_info; - rp_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; - rp_info.pNext = nullptr; - rp_info.flags = 0; - rp_info.attachmentCount = desc_list.GetCount(); - rp_info.pAttachments = desc_list.GetData(); - rp_info.subpassCount = subpass.GetCount(); - rp_info.pSubpasses = subpass.GetData(); - rp_info.dependencyCount = dependency.GetCount(); - rp_info.pDependencies = dependency.GetData(); - - VkRenderPass render_pass; - - if(vkCreateRenderPass(attr->device,&rp_info,nullptr,&render_pass)!=VK_SUCCESS) - return(nullptr); - - return(new RenderPass(attr->device,render_pass,color_format,depth_format)); -} - -RenderPass *Device::CreateRenderPass(VkFormat color_format,VkFormat depth_format,VkImageLayout color_final_layout,VkImageLayout depth_final_layout) const -{ - if(!attr->physical_device->IsColorAttachmentOptimal(color_format)) - return(nullptr); - - if(!attr->physical_device->IsDepthAttachmentOptimal(depth_format)) - return(nullptr); - - List color_ref; - VkAttachmentReference depth_ref; - List desc_list; - - List color_format_list; - - color_format_list.Add(color_format); - - CreateColorAttachmentReference(color_ref,0,1); - CreateDepthAttachmentReference(&depth_ref,1); - - CreateAttachment(desc_list,color_format_list,depth_format,color_final_layout,depth_final_layout); - - List subpass_desc_list; - - VkSubpassDescription subpass; - - subpass.flags = 0; - subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; - subpass.inputAttachmentCount = 0; - subpass.pInputAttachments = nullptr; - subpass.colorAttachmentCount = 1; - subpass.pColorAttachments = color_ref.GetData(); - subpass.pResolveAttachments = nullptr; - subpass.pDepthStencilAttachment = &depth_ref; - subpass.preserveAttachmentCount = 0; - subpass.pPreserveAttachments = nullptr; - - subpass_desc_list.Add(subpass); - - List subpass_dependency_list; - - CreateSubpassDependency(subpass_dependency_list,1); - - return CreateRenderPass(desc_list,subpass_desc_list,subpass_dependency_list,color_format_list,depth_format,color_final_layout,depth_final_layout); -} -VK_NAMESPACE_END diff --git a/src/RenderDevice/Vulkan/VKDeviceTexture.cpp b/src/RenderDevice/Vulkan/VKDeviceTexture.cpp deleted file mode 100644 index dc877127..00000000 --- a/src/RenderDevice/Vulkan/VKDeviceTexture.cpp +++ /dev/null @@ -1,311 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -VK_NAMESPACE_BEGIN -namespace -{ - uint32_t GetMipLevels(uint32_t size) - { - uint32_t level=1; - - while(size>>=1) - ++level; - - return level; - } -}//namespace - -Texture2D *Device::CreateTexture2D(Memory *mem,VkImage image,ImageView *image_view,VkImageLayout image_layout,ImageTiling tiling) -{ - TextureData *tex_data=new TextureData; - - tex_data->memory = mem; - tex_data->image_layout = image_layout; - tex_data->image = image; - tex_data->image_view = image_view; - - tex_data->mip_levels = 0; - tex_data->tiling = VkImageTiling(tiling); - - return(new Texture2D(attr->device,tex_data)); -} - -Texture2D *Device::CreateTexture2D(VkFormat format,uint32_t width,uint32_t height,VkImageAspectFlagBits aspectMask,VkImage image,VkImageLayout image_layout,ImageTiling tiling) -{ - VkExtent3D extent={width,height,1}; - - ImageView *iv=CreateImageView(attr->device,VK_IMAGE_VIEW_TYPE_2D,format,extent,aspectMask,image); - - return this->CreateTexture2D(nullptr,image,iv,image_layout,tiling); -} - -Texture2D *Device::CreateTexture2D(const VkFormat format,uint32_t width,uint32_t height,const VkImageAspectFlags aspectMask,const uint usage,const VkImageLayout image_layout,ImageTiling tiling) -{ - const VkFormatProperties fp=attr->physical_device->GetFormatProperties(format); - - if(tiling==ImageTiling::Optimal) - { - if(fp.optimalTilingFeatures&VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) - tiling=ImageTiling::Optimal; - else - tiling=ImageTiling::Linear; - } - - if(tiling==ImageTiling::Linear) - { - if(fp.linearTilingFeatures&VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) - tiling=ImageTiling::Linear; - else - return(nullptr); - } - - VkImage img=CreateImage2D(format,width,height,usage,tiling); - - if(!img)return(nullptr); - - Memory *mem=CreateMemory(img); - - if(!mem->BindImage(img)) - { - delete mem; - DestoryImage(img); - return(nullptr); - } - - const VkExtent3D ext={width,height,1}; - - ImageView *iv=CreateImageView2D(attr->device,format,ext,aspectMask,img); - - return CreateTexture2D(mem,img,iv,image_layout,tiling); -} - -Texture2D *Device::CreateTexture2D(const VkFormat format,Buffer *buf,uint32_t width,uint32_t height,const VkImageAspectFlags aspectMask,const uint usage,const VkImageLayout image_layout,const ImageTiling tiling) -{ - if(!buf)return(nullptr); - - Texture2D *tex=CreateTexture2D(format,width,height,aspectMask,usage,image_layout,tiling); - - if(!tex)return(nullptr); - - ChangeTexture2D(tex,buf,0,0,width,height); - - return(tex); -} - -Texture2D *Device::CreateTexture2D(const VkFormat format,void *data,uint32_t width,uint32_t height,uint32_t size,const VkImageAspectFlags aspectMask,const uint usage,const VkImageLayout image_layout,const ImageTiling tiling) -{ - Buffer *buf=CreateBuffer(VK_BUFFER_USAGE_TRANSFER_SRC_BIT,size,data); - - if(!buf)return(nullptr); - - Texture2D *tex=CreateTexture2D(format,buf,width,height,aspectMask,image_layout,tiling); - - delete buf; - return(tex); -} - -bool Device::ChangeTexture2D(Texture2D *tex,Buffer *buf,const VkBufferImageCopy *buffer_image_copy,const int count) -{ - if(!tex||!buf) - return(false); - - VkImageSubresourceRange subresourceRange; - subresourceRange.aspectMask = tex->GetAspect(); - subresourceRange.baseMipLevel = 0; - subresourceRange.levelCount = 1; - subresourceRange.baseArrayLayer = 0; - subresourceRange.layerCount = 1; - - VkImageMemoryBarrier imageMemoryBarrier; - imageMemoryBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; - imageMemoryBarrier.pNext = nullptr; - imageMemoryBarrier.srcAccessMask = 0; - imageMemoryBarrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; - imageMemoryBarrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED; - imageMemoryBarrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; - imageMemoryBarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; - imageMemoryBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; - imageMemoryBarrier.image = tex->GetImage(); - imageMemoryBarrier.subresourceRange = subresourceRange; - - texture_cmd_buf->Begin(); - texture_cmd_buf->PipelineBarrier( - VK_PIPELINE_STAGE_HOST_BIT, - VK_PIPELINE_STAGE_TRANSFER_BIT, - 0, - 0, nullptr, - 0, nullptr, - 1, &imageMemoryBarrier); - - texture_cmd_buf->CopyBufferToImage( - buf->GetBuffer(), - tex->GetImage(), - VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, - count, - buffer_image_copy); - - imageMemoryBarrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; - imageMemoryBarrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT; - imageMemoryBarrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; - imageMemoryBarrier.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; - - texture_cmd_buf->PipelineBarrier( - VK_PIPELINE_STAGE_TRANSFER_BIT, - VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, - 0, - 0, nullptr, - 0, nullptr, - 1, &imageMemoryBarrier); - - texture_cmd_buf->End(); - - SubmitTexture(*texture_cmd_buf); - return(true); -} - -bool Device::ChangeTexture2D(Texture2D *tex,Buffer *buf,const List &ir_list) -{ - if(!tex||!buf||ir_list.GetCount()<=0) - return(false); - - const int ir_count=ir_list.GetCount(); - int count=0; - - AutoDeleteArray buffer_image_copy=new VkBufferImageCopy[ir_count]; - VkBufferImageCopy *tp=buffer_image_copy; - const ImageRegion *sp=ir_list.GetData(); - - VkDeviceSize offset=0; - - for(int i=0;ibufferOffset = offset; - tp->bufferRowLength = 0; - tp->bufferImageHeight = 0; - tp->imageSubresource.aspectMask = tex->GetAspect(); - tp->imageSubresource.mipLevel = 0; - tp->imageSubresource.baseArrayLayer = 0; - tp->imageSubresource.layerCount = 1; - tp->imageOffset.x = sp->left; - tp->imageOffset.y = sp->top; - tp->imageOffset.z = 0; - tp->imageExtent.width = sp->width; - tp->imageExtent.height= sp->height; - tp->imageExtent.depth = 1; - - offset+=sp->bytes; - ++sp; - ++tp; - } - - return ChangeTexture2D(tex,buf,buffer_image_copy,ir_count); -} - -bool Device::ChangeTexture2D(Texture2D *tex,Buffer *buf,uint32_t left,uint32_t top,uint32_t width,uint32_t height) -{ - if(!tex||!buf - ||left<0||left+width>tex->GetWidth() - ||top<0||top+height>tex->GetHeight() - ||width<=0||height<=0) - return(false); - - VkBufferImageCopy buffer_image_copy; - buffer_image_copy.bufferOffset = 0; - buffer_image_copy.bufferRowLength = 0; - buffer_image_copy.bufferImageHeight = 0; - buffer_image_copy.imageSubresource.aspectMask = tex->GetAspect(); - buffer_image_copy.imageSubresource.mipLevel = 0; - buffer_image_copy.imageSubresource.baseArrayLayer = 0; - buffer_image_copy.imageSubresource.layerCount = 1; - buffer_image_copy.imageOffset.x = left; - buffer_image_copy.imageOffset.y = top; - buffer_image_copy.imageOffset.z = 0; - buffer_image_copy.imageExtent.width = width; - buffer_image_copy.imageExtent.height= height; - buffer_image_copy.imageExtent.depth = 1; - - return ChangeTexture2D(tex,buf,&buffer_image_copy,1); -} - -bool Device::ChangeTexture2D(Texture2D *tex,void *data,uint32_t left,uint32_t top,uint32_t width,uint32_t height,uint32_t size) -{ - if(!tex||!data - ||left<0||left+width>tex->GetWidth() - ||top<0||top+height>tex->GetHeight() - ||width<=0||height<=0 - ||size<=0) - return(false); - - Buffer *buf=CreateBuffer(VK_BUFFER_USAGE_TRANSFER_SRC_BIT,size,data); - - bool result=ChangeTexture2D(tex,buf,left,top,width,height); - - delete buf; - - return(result); -} - -bool Device::SubmitTexture(const VkCommandBuffer *cmd_bufs,const uint32_t count) -{ - if(!cmd_bufs||count<=0) - return(false); - - textureSQ->Submit(cmd_bufs,count,nullptr,nullptr); - textureSQ->Wait(); - - return(true); -} - -Sampler *Device::CreateSampler(VkSamplerCreateInfo *sci) -{ - static VkSamplerCreateInfo default_sampler_create_info= - { - VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, - nullptr, - 0, - VK_FILTER_LINEAR, - VK_FILTER_LINEAR, - VK_SAMPLER_MIPMAP_MODE_LINEAR, - VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, - VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, - VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, - 0.0f, - false, - 0, - false, - VK_COMPARE_OP_NEVER, - 0.0f, - 1.0f, - VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK, - false - }; - - if(!sci) - sci=&default_sampler_create_info; - - VkSampler sampler; - - sci->sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO; - - //if(attr->physical_device->features.samplerAnisotropy) //不知道为什么不准,先全部禁用吧 - //{ - // sci->maxAnisotropy = attr->physical_device->properties.limits.maxSamplerAnisotropy; - // sci->anisotropyEnable = VK_TRUE; - //} - //else - { - sci->maxAnisotropy = 1.0; - sci->anisotropyEnable = VK_FALSE; - } - - if(vkCreateSampler(attr->device,sci,nullptr,&sampler)!=VK_SUCCESS) - return(nullptr); - - return(new Sampler(attr->device,sampler)); -} -VK_NAMESPACE_END diff --git a/src/RenderDevice/Vulkan/VKFramebuffer.cpp b/src/RenderDevice/Vulkan/VKFramebuffer.cpp deleted file mode 100644 index 15ea88ca..00000000 --- a/src/RenderDevice/Vulkan/VKFramebuffer.cpp +++ /dev/null @@ -1,112 +0,0 @@ -#include -#include -#include -#include -#include - -VK_NAMESPACE_BEGIN -Framebuffer::~Framebuffer() -{ - vkDestroyFramebuffer(device,frame_buffer,nullptr); -} - -Framebuffer *CreateFramebuffer(Device *dev,RenderPass *rp,ImageView **color_list,const uint color_count,ImageView *depth) -{ - uint att_count=color_count; - - if(depth)++att_count; - - VkImageView *attachments=new VkImageView[att_count]; - - if(color_count) - { - const List &cf_list=rp->GetColorFormat(); - - const VkFormat *cf=cf_list.GetData(); - ImageView **iv=color_list; - for(uint i=0;iGetFormat()) - return(nullptr); - - attachments[i]=**iv; - - ++cf; - ++iv; - } - } - - if(depth) - { - if(rp->GetDepthFormat()!=depth->GetFormat()) - { - delete[] attachments; - return(nullptr); - } - - attachments[color_count]=*depth; - } - - const VkExtent3D extent=depth->GetExtent(); - - VkFramebufferCreateInfo *fb_info=new VkFramebufferCreateInfo; - fb_info->sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO; - fb_info->pNext = nullptr; - fb_info->flags = 0; - fb_info->renderPass = *rp; - fb_info->attachmentCount = att_count; - fb_info->pAttachments = attachments; - fb_info->width = extent.width; - fb_info->height = extent.height; - fb_info->layers = 1; - - VkFramebuffer fb; - - if(vkCreateFramebuffer(dev->GetDevice(),fb_info,nullptr,&fb)!=VK_SUCCESS) - return(nullptr); - - return(new Framebuffer(dev->GetDevice(),fb,fb_info,depth)); -} - -Framebuffer *CreateFramebuffer(Device *dev,RenderPass *rp,List &color,ImageView *depth) -{ - if(!dev)return(nullptr); - if(!rp)return(nullptr); - - if(rp->GetColorFormat().GetCount()!=color.GetCount())return(nullptr); - - if(color.GetCount()==0&&!depth)return(nullptr); - - return CreateFramebuffer(dev,rp,color.GetData(),color.GetCount(),depth); -} - -Framebuffer *CreateFramebuffer(Device *dev,RenderPass *rp,List &image_view_list) -{ - const int count=image_view_list.GetCount(); - - ImageView *last_iv=*(image_view_list.GetData()+count-1); - - if(last_iv->GetAspectFlags()&VK_IMAGE_ASPECT_DEPTH_BIT) - return CreateFramebuffer(dev,rp,image_view_list.GetData(),count-1,last_iv); - else - return CreateFramebuffer(dev,rp,image_view_list.GetData(),count,nullptr); -} - -Framebuffer *CreateFramebuffer(Device *dev,RenderPass *rp,ImageView *color,ImageView *depth) -{ - if(!dev)return(nullptr); - if(!rp)return(nullptr); - if(!color&&!depth)return(nullptr); - - return CreateFramebuffer(dev,rp,&color,1,depth); -} - -Framebuffer *CreateFramebuffer(Device *dev,RenderPass *rp,ImageView *depth) -{ - if(!dev)return(nullptr); - if(!rp)return(nullptr); - if(!depth)return(nullptr); - - return CreateFramebuffer(dev,rp,nullptr,0,depth); -} -VK_NAMESPACE_END diff --git a/src/RenderDevice/Vulkan/VKImageView.cpp b/src/RenderDevice/Vulkan/VKImageView.cpp deleted file mode 100644 index 48e89c99..00000000 --- a/src/RenderDevice/Vulkan/VKImageView.cpp +++ /dev/null @@ -1,50 +0,0 @@ -#include - -VK_NAMESPACE_BEGIN -ImageView::~ImageView() -{ - vkDestroyImageView(device,image_view,nullptr); -} - -ImageView *CreateImageView(VkDevice device,VkImageViewType type,VkFormat format,const VkExtent3D &ext,VkImageAspectFlags aspectMask,VkImage img) -{ - VkImageViewCreateInfo iv_createinfo={}; - - iv_createinfo.sType =VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; - iv_createinfo.pNext =nullptr; - iv_createinfo.flags =0; - iv_createinfo.image =img; - iv_createinfo.format =format; - iv_createinfo.viewType =type; - iv_createinfo.subresourceRange.aspectMask =aspectMask; - iv_createinfo.subresourceRange.baseMipLevel =0; - iv_createinfo.subresourceRange.levelCount =ext.depth; - iv_createinfo.subresourceRange.baseArrayLayer =0; - iv_createinfo.subresourceRange.layerCount =ext.depth; - - if(aspectMask&VK_IMAGE_ASPECT_DEPTH_BIT) - { - if(format>=VK_FORMAT_D16_UNORM_S8_UINT) - iv_createinfo.subresourceRange.aspectMask|=VK_IMAGE_ASPECT_STENCIL_BIT; - - iv_createinfo.components.r=VK_COMPONENT_SWIZZLE_IDENTITY; - iv_createinfo.components.g=VK_COMPONENT_SWIZZLE_IDENTITY; - iv_createinfo.components.b=VK_COMPONENT_SWIZZLE_IDENTITY; - iv_createinfo.components.a=VK_COMPONENT_SWIZZLE_IDENTITY; - } - else - { - iv_createinfo.components.r=VK_COMPONENT_SWIZZLE_R; - iv_createinfo.components.g=VK_COMPONENT_SWIZZLE_G; - iv_createinfo.components.b=VK_COMPONENT_SWIZZLE_B; - iv_createinfo.components.a=VK_COMPONENT_SWIZZLE_A; - } - - VkImageView img_view; - - if(vkCreateImageView(device,&iv_createinfo,nullptr,&img_view)!=VK_SUCCESS) - return(nullptr); - - return(new ImageView(device,img_view,type,format,ext,aspectMask)); -} -VK_NAMESPACE_END diff --git a/src/RenderDevice/Vulkan/VKInstance.cpp b/src/RenderDevice/Vulkan/VKInstance.cpp deleted file mode 100644 index 5b9c6b5a..00000000 --- a/src/RenderDevice/Vulkan/VKInstance.cpp +++ /dev/null @@ -1,108 +0,0 @@ -#include -#include -#include -#include -#include - -VK_NAMESPACE_BEGIN -Device *CreateRenderDevice(VkInstance,const PhysicalDevice *,Window *); - -void CheckInstanceLayer(CharPointerList &layer_list,CreateInstanceLayerInfo *layer_info); - -Instance *CreateInstance(const AnsiString &app_name,VKDebugOut *out,CreateInstanceLayerInfo *layer_info) -{ - VkApplicationInfo app_info; - VkInstanceCreateInfo inst_info; - CharPointerList ext_list; - CharPointerList layer_list; - - app_info.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO; - app_info.pNext = nullptr; - app_info.pApplicationName = app_name.c_str(); - app_info.applicationVersion = 1; - app_info.pEngineName = "CMGameEngine/ULRE"; - app_info.engineVersion = 1; - app_info.apiVersion = VK_API_VERSION_1_0; - - ext_list.Add(VK_KHR_SURFACE_EXTENSION_NAME); - ext_list.Add(HGL_VK_SURFACE_EXTENSION_NAME); //此宏在VKSurfaceExtensionName.h中定义 - -#ifdef _DEBUG - ext_list.Add(VK_EXT_DEBUG_REPORT_EXTENSION_NAME); - ext_list.Add(VK_EXT_DEBUG_UTILS_EXTENSION_NAME); -#endif//_DEBUG - - if(layer_info) - CheckInstanceLayer(layer_list,layer_info); - - inst_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; - inst_info.pNext = nullptr; - inst_info.flags = 0; - inst_info.pApplicationInfo = &app_info; - inst_info.enabledExtensionCount = ext_list.GetCount(); - inst_info.ppEnabledExtensionNames = ext_list.GetData(); - inst_info.enabledLayerCount = layer_list.GetCount(); - inst_info.ppEnabledLayerNames = layer_list.GetData(); - - VkInstance inst; - - if(vkCreateInstance(&inst_info,nullptr,&inst)==VK_SUCCESS) - { -#ifdef _DEBUG - if(!out) - out=new VKDebugOut; -#endif//_DEBUG - - if(out) - out->Init(inst); - - return(new Instance(inst,out)); - } - - return(nullptr); -} - -Instance::Instance(VkInstance i,VKDebugOut *out) -{ - inst=i; - - debug_out=out; - - uint32_t gpu_count = 1; - - if(vkEnumeratePhysicalDevices(inst, &gpu_count, nullptr)==VK_SUCCESS) - { - VkPhysicalDevice *pd_list=new VkPhysicalDevice[gpu_count]; - vkEnumeratePhysicalDevices(inst, &gpu_count,pd_list); - - for(uint32_t i=0;iGetDeviceType()==type) - return(*pd); - - ++pd; - } - - return(nullptr); -} -VK_NAMESPACE_END diff --git a/src/RenderDevice/Vulkan/VKMaterial.cpp b/src/RenderDevice/Vulkan/VKMaterial.cpp deleted file mode 100644 index 075762a8..00000000 --- a/src/RenderDevice/Vulkan/VKMaterial.cpp +++ /dev/null @@ -1,132 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include"VKDescriptorSetLayoutCreater.h" -VK_NAMESPACE_BEGIN -Material *CreateMaterial(Device *dev,ShaderModuleMap *shader_maps) -{ - const int shader_count=shader_maps->GetCount(); - - if(shader_count<2) - return(nullptr); - - const ShaderModule *sm; - - if(!shader_maps->Get(VK_SHADER_STAGE_VERTEX_BIT,sm)) - return(nullptr); - - DescriptorSetLayoutCreater *dsl_creater=new DescriptorSetLayoutCreater(dev); - List *shader_stage_list=new List; - - shader_stage_list->SetCount(shader_count); - - VkPipelineShaderStageCreateInfo *p=shader_stage_list->GetData(); - - auto **itp=shader_maps->GetDataList(); - for(int i=0;iright; - memcpy(p,sm->GetCreateInfo(),sizeof(VkPipelineShaderStageCreateInfo)); - - dsl_creater->Bind(sm->GetDescriptorList(),sm->GetStage()); - - ++p; - ++itp; - } - - if(!dsl_creater->CreatePipelineLayout()) - { - delete shader_stage_list; - delete dsl_creater; - delete shader_maps; - return(nullptr); - } - - return(new Material(dev,shader_maps,shader_stage_list,dsl_creater)); -} - -Material::Material(Device *dev,ShaderModuleMap *smm,List *psci_list,DescriptorSetLayoutCreater *dslc) -{ - device=dev; - shader_maps=smm; - shader_stage_list=psci_list; - dsl_creater=dslc; - - const ShaderModule *sm; - if(smm->Get(VK_SHADER_STAGE_VERTEX_BIT,sm)) - { - vertex_sm=(VertexShaderModule *)sm; - vab=vertex_sm->CreateVertexAttributeBinding(); - } - else - { - //理论上不可能到达这里,前面CreateMaterial已经检测过了 - vertex_sm=nullptr; - vab=nullptr; - } -} - -Material::~Material() -{ - delete dsl_creater; - - if(vab) - { - vertex_sm->Release(vab); - delete vab; - } - - delete shader_stage_list; - delete shader_maps; -} - -const int Material::GetBinding(VkDescriptorType desc_type,const AnsiString &name)const -{ - if(desc_typeVK_DESCRIPTOR_TYPE_END_RANGE - ||name.IsEmpty()) - return(-1); - - int binding; - const int shader_count=shader_maps->GetCount(); - - const ShaderModule *sm; - auto **itp=shader_maps->GetDataList(); - for(int i=0;iright; - binding=sm->GetBinding(desc_type,name); - if(binding!=-1) - return binding; - - ++itp; - } - - return(-1); -} - -const VkPipelineLayout Material::GetPipelineLayout()const -{ - return dsl_creater->GetPipelineLayout(); -} - -DescriptorSets *Material::CreateDescriptorSets()const -{ - return dsl_creater->Create(); -} - -void Material::Write(VkPipelineVertexInputStateCreateInfo &vis)const -{ - return vab->Write(vis); -} - -Renderable *Material::CreateRenderable(const uint32_t draw_count) -{ - return(new Renderable(vertex_sm,draw_count)); -} -VK_NAMESPACE_END diff --git a/src/RenderDevice/Vulkan/VKMaterialInstance.cpp b/src/RenderDevice/Vulkan/VKMaterialInstance.cpp deleted file mode 100644 index 71971c2d..00000000 --- a/src/RenderDevice/Vulkan/VKMaterialInstance.cpp +++ /dev/null @@ -1,63 +0,0 @@ -#include - -#include -#include - -VK_NAMESPACE_BEGIN -MaterialInstance::MaterialInstance(Material *m,DescriptorSets *ds) -{ - material=m; - descriptor_sets=ds; -} - -MaterialInstance::~MaterialInstance() -{ - delete descriptor_sets; -} - -bool MaterialInstance::BindUBO(const AnsiString &name,vulkan::Buffer *ubo) -{ - if(name.IsEmpty()||!ubo) - return(false); - - const int index=material->GetUBO(name); - - if(index<0) - return(false); - - if(!descriptor_sets->BindUBO(index,ubo)) - return(false); - - return(true); -} - -bool MaterialInstance::BindSampler(const AnsiString &name,Texture *tex,Sampler *sampler) -{ - if(name.IsEmpty()||!tex||!sampler) - return(false); - - const int index=material->GetSampler(name); - - if(index<0) - return(false); - - if(!descriptor_sets->BindSampler(index,tex,sampler)) - return(false); - - return(true); -} - -void MaterialInstance::Update() -{ - descriptor_sets->Update(); -} - -MaterialInstance *Material::CreateInstance() -{ - DescriptorSets *ds=CreateDescriptorSets(); - - if(!ds)return(nullptr); - - return(new MaterialInstance(this,ds)); -} -VK_NAMESPACE_END \ No newline at end of file diff --git a/src/RenderDevice/Vulkan/VKMemory.cpp b/src/RenderDevice/Vulkan/VKMemory.cpp deleted file mode 100644 index eca608ae..00000000 --- a/src/RenderDevice/Vulkan/VKMemory.cpp +++ /dev/null @@ -1,87 +0,0 @@ -#include -#include -#include -VK_NAMESPACE_BEGIN -Memory *Device::CreateMemory(const VkMemoryRequirements &req,uint32_t properties) -{ - uint32_t index; - - if(!attr->physical_device->CheckMemoryType(req.memoryTypeBits,properties,&index)) - return(nullptr); - - VkMemoryAllocateInfo alloc_info; - - alloc_info.sType =VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; - alloc_info.pNext =nullptr; - alloc_info.memoryTypeIndex =index; - alloc_info.allocationSize =req.size; - - VkDeviceMemory memory; - - if(vkAllocateMemory(attr->device,&alloc_info,nullptr,&memory)!=VK_SUCCESS) - return(nullptr); - - return(new Memory(attr->device,memory,req,index,properties)); -} - -Memory::~Memory() -{ - vkFreeMemory(device,memory,nullptr); -} - -void *Memory::Map() -{ - void *result; - - if(vkMapMemory(device,memory,0,req.size,0,&result)==VK_SUCCESS) - return result; - - return(nullptr); -} - -void *Memory::Map(const VkDeviceSize offset,const VkDeviceSize size) -{ - if(offset<0||offset+size>=req.size) - return(nullptr); - - void *result; - - if(vkMapMemory(device,memory,0,size,0,&result)==VK_SUCCESS) - return result; - - return(nullptr); -} - -void Memory::Unmap() -{ - vkUnmapMemory(device,memory); -} - -bool Memory::Write(const void *ptr,VkDeviceSize start,VkDeviceSize size) -{ - if(!ptr)return(false); - - void *dst; - - if(vkMapMemory(device,memory,start,size,0,&dst)!=VK_SUCCESS) - return(false); - - memcpy(dst,ptr,size); - vkUnmapMemory(device,memory); - return(true); -} - -bool Memory::BindBuffer(VkBuffer buffer) -{ - if(!buffer)return(false); - - return(vkBindBufferMemory(device,buffer,memory,0)==VK_SUCCESS); -} - -bool Memory::BindImage(VkImage image) -{ - if(!image)return(false); - - return(vkBindImageMemory(device,image,memory,0)==VK_SUCCESS); -} -VK_NAMESPACE_END diff --git a/src/RenderDevice/Vulkan/VKPhysicalDevice.cpp b/src/RenderDevice/Vulkan/VKPhysicalDevice.cpp deleted file mode 100644 index d4c84752..00000000 --- a/src/RenderDevice/Vulkan/VKPhysicalDevice.cpp +++ /dev/null @@ -1,147 +0,0 @@ -#include - -VK_NAMESPACE_BEGIN -PhysicalDevice::PhysicalDevice(VkInstance inst,VkPhysicalDevice pd) -{ - instance=inst; - physical_device=pd; - - { - uint32_t property_count; - - vkEnumerateDeviceLayerProperties(physical_device,&property_count,nullptr); - - layer_properties.SetCount(property_count); - vkEnumerateDeviceLayerProperties(physical_device,&property_count,layer_properties.GetData()); - - debug_out(layer_properties); - } - - { - uint32_t exten_count; - - vkEnumerateDeviceExtensionProperties(physical_device,nullptr,&exten_count,nullptr); - - extension_properties.SetCount(exten_count); - vkEnumerateDeviceExtensionProperties(physical_device,nullptr,&exten_count,extension_properties.GetData()); - - debug_out(extension_properties); - } - - vkGetPhysicalDeviceFeatures(physical_device,&features); - vkGetPhysicalDeviceMemoryProperties(physical_device,&memory_properties); - - PFN_vkGetPhysicalDeviceProperties2 GetPhysicalDeviceProperties2=nullptr; - - if(GetExtensionSpecVersion(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) - GetPhysicalDeviceProperties2=(PFN_vkGetPhysicalDeviceProperties2KHR)vkGetInstanceProcAddr(instance,"vkGetPhysicalDeviceProperties2KHR"); - - if(!GetPhysicalDeviceProperties2) - if(GetExtensionSpecVersion(VK_KHR_DRIVER_PROPERTIES_EXTENSION_NAME)) - GetPhysicalDeviceProperties2=(PFN_vkGetPhysicalDeviceProperties2)vkGetInstanceProcAddr(instance,"vkGetPhysicalDeviceProperties2"); - - if(GetPhysicalDeviceProperties2) - { - VkPhysicalDeviceProperties2KHR properties2; - GetPhysicalDeviceProperties2(physical_device,&properties2); - - hgl_cpy(properties,properties2.properties); - - if(properties2.pNext) - memcpy(&driver_properties,properties2.pNext,sizeof(VkPhysicalDeviceDriverPropertiesKHR)); - } - else - { - vkGetPhysicalDeviceProperties(physical_device,&properties); - - hgl_zero(driver_properties); - } -} - -const uint32_t PhysicalDevice::GetExtensionSpecVersion(const AnsiString &name)const -{ - const uint count=extension_properties.GetCount(); - const VkExtensionProperties *ep=extension_properties.GetData(); - - for(uint i=0;iextensionName)==0) - return ep->specVersion; - } - - return 0; -} - -const bool PhysicalDevice::CheckMemoryType(uint32_t typeBits,VkMemoryPropertyFlags properties,uint32_t *typeIndex)const -{ - // Search memtypes to find first index with those properties - for(uint32_t i=0; i>=1; - } - // No memory types matched, return failure - return false; -} - -VkFormat PhysicalDevice::GetDepthFormat(bool lower_to_high)const -{ - constexpr VkFormat depthFormats[] = - { - FMT_D16UN, - FMT_X8_D24UN, - FMT_D16UN_S8U, - FMT_D24UN_S8U, - FMT_D32F, - FMT_D32F_S8U - }; - - VkFormat result=VK_FORMAT_UNDEFINED; - - for (auto& format : depthFormats) - { - if(IsDepthAttachmentOptimal(format)) - { - if(lower_to_high) - return format; - else - result=format; - } - } - - return result; -} - -VkFormat PhysicalDevice::GetDepthStencilFormat(bool lower_to_high)const -{ - constexpr VkFormat depthStencilFormats[] = - { - FMT_D16UN_S8U, - FMT_D24UN_S8U, - FMT_D32F_S8U - }; - - VkFormat result=VK_FORMAT_UNDEFINED; - - for (auto& format : depthStencilFormats) - { - if(IsDepthAttachmentOptimal(format)) - { - if(lower_to_high) - return format; - else - result=format; - } - } - - return result; -} -VK_NAMESPACE_END \ No newline at end of file diff --git a/src/RenderDevice/Vulkan/VKPipeline.cpp b/src/RenderDevice/Vulkan/VKPipeline.cpp deleted file mode 100644 index 54e1de5c..00000000 --- a/src/RenderDevice/Vulkan/VKPipeline.cpp +++ /dev/null @@ -1,244 +0,0 @@ -#include -#include -#include -#include -#include -#include - -VK_NAMESPACE_BEGIN -Pipeline::~Pipeline() -{ - vkDestroyPipeline(device,pipeline,nullptr); -} - -void PipelineCreater::InitVertexInputState(const Material *material) -{ - pipelineInfo.stageCount = material->GetStageCount(); - pipelineInfo.pStages = material->GetStages(); - - { - vis_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; - vis_create_info.pNext = nullptr; - vis_create_info.flags = 0; - - material->Write(vis_create_info); - - pipelineInfo.pVertexInputState=&vis_create_info; - } -} - -void PipelineCreater::InitViewportState() -{ - viewport.x = 0.0f; - viewport.y = 0.0f; - viewport.width = extent.width; - viewport.height = extent.height; - viewport.minDepth = 0.0f; - viewport.maxDepth = 1.0f; - - scissor.offset = {0, 0}; - scissor.extent = extent; - - viewportState.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO; - viewportState.pNext = nullptr; - viewportState.flags = 0; - viewportState.viewportCount = 1; - viewportState.pViewports = &viewport; - viewportState.scissorCount = 1; - viewportState.pScissors = &scissor; - - pipelineInfo.pViewportState = &viewportState; -} - -void PipelineCreater::InitDynamicState() -{ - memset(dynamicStateEnables, 0, sizeof dynamicStateEnables); - - dynamicState.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO; - dynamicState.pNext = nullptr; - dynamicState.flags = 0; - dynamicState.pDynamicStates = dynamicStateEnables; - dynamicState.dynamicStateCount = 0; - dynamicStateEnables[dynamicState.dynamicStateCount++] = VK_DYNAMIC_STATE_VIEWPORT; - dynamicStateEnables[dynamicState.dynamicStateCount++] = VK_DYNAMIC_STATE_SCISSOR; - dynamicStateEnables[dynamicState.dynamicStateCount++] = VK_DYNAMIC_STATE_LINE_WIDTH; - - //如果窗口大小不变,可以不设置这两个。能不能提升效能未知 - - pipelineInfo.pDynamicState=&dynamicState; -} - -//为什么一定要把ext放在这里,因为如果不放在这里,总是会让人遗忘它的重要性 - -PipelineCreater::PipelineCreater(Device *dev,const Material *material,const RenderTarget *rt) -{ - device=dev->GetDevice(); - extent=rt->GetExtent(); - cache=dev->GetPipelineCache(); - - //未来这里需要增加是否有vs/fs的检测 - - hgl_zero(pipelineInfo); - pipelineInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; - InitVertexInputState(material); - - tessellation.sType=VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO; - tessellation.pNext=nullptr; - tessellation.flags=0; - tessellation.patchControlPoints=0; - - pipelineInfo.pTessellationState=&tessellation; - - InitViewportState(); - - rasterizer.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO; - rasterizer.pNext = nullptr; - rasterizer.flags = 0; - rasterizer.depthClampEnable = VK_FALSE; - rasterizer.rasterizerDiscardEnable = VK_FALSE; - rasterizer.polygonMode = VK_POLYGON_MODE_FILL; - rasterizer.cullMode = VK_CULL_MODE_BACK_BIT; - rasterizer.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE; //逆时针,和opengl一样 - rasterizer.depthBiasEnable = VK_FALSE; - rasterizer.depthBiasConstantFactor = 0; - rasterizer.depthBiasClamp = 0; - rasterizer.depthBiasSlopeFactor = 0; - rasterizer.lineWidth = 1.0f; - - pipelineInfo.pRasterizationState = &rasterizer; - - multisampling.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO; - multisampling.pNext = nullptr; - multisampling.flags = 0; - multisampling.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT; - multisampling.sampleShadingEnable = VK_FALSE; - multisampling.minSampleShading = 0.0; - multisampling.pSampleMask = nullptr; - multisampling.alphaToCoverageEnable = VK_FALSE; - multisampling.alphaToOneEnable = VK_FALSE; - - pipelineInfo.pMultisampleState = &multisampling; - - depthStencilState.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO; - depthStencilState.pNext = nullptr; - depthStencilState.flags = 0; - depthStencilState.depthTestEnable = VK_TRUE; - depthStencilState.depthWriteEnable = VK_TRUE; - depthStencilState.depthCompareOp = VK_COMPARE_OP_LESS_OR_EQUAL; - depthStencilState.depthBoundsTestEnable = VK_FALSE; - depthStencilState.minDepthBounds = 0; - depthStencilState.maxDepthBounds = 0; - depthStencilState.stencilTestEnable = VK_FALSE; - depthStencilState.back.failOp = VK_STENCIL_OP_KEEP; - depthStencilState.back.passOp = VK_STENCIL_OP_KEEP; - depthStencilState.back.compareOp = VK_COMPARE_OP_ALWAYS; - depthStencilState.back.compareMask = 0; - depthStencilState.back.reference = 0; - depthStencilState.back.depthFailOp = VK_STENCIL_OP_KEEP; - depthStencilState.back.writeMask = 0; - depthStencilState.front = depthStencilState.back; - depthStencilState.front.compareOp=VK_COMPARE_OP_NEVER; - - pipelineInfo.pDepthStencilState=&depthStencilState; - - VkPipelineColorBlendAttachmentState cba; - cba.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT; - cba.blendEnable = VK_FALSE; - cba.alphaBlendOp = VK_BLEND_OP_ADD; - cba.colorBlendOp = VK_BLEND_OP_ADD; - cba.srcColorBlendFactor = VK_BLEND_FACTOR_ZERO; - cba.dstColorBlendFactor = VK_BLEND_FACTOR_ZERO; - cba.srcAlphaBlendFactor = VK_BLEND_FACTOR_ZERO; - cba.dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO; - - colorBlendAttachments.Add(cba,rt->GetColorCount()); //这个需要和subpass中的color attachment数量相等,所以添加多份 - - alpha_blend=false; - - colorBlending.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO; - colorBlending.pNext = nullptr; - colorBlending.flags = 0; - colorBlending.logicOpEnable = VK_FALSE; - colorBlending.logicOp = VK_LOGIC_OP_CLEAR; - colorBlending.attachmentCount = colorBlendAttachments.GetCount(); - colorBlending.pAttachments = colorBlendAttachments.GetData(); - colorBlending.blendConstants[0] = 0.0f; - colorBlending.blendConstants[1] = 0.0f; - colorBlending.blendConstants[2] = 0.0f; - colorBlending.blendConstants[3] = 0.0f; - - pipelineInfo.pColorBlendState = &colorBlending; - - InitDynamicState(); - - pipelineInfo.layout = material->GetPipelineLayout(); - { - pipelineInfo.renderPass = rt->GetRenderPass(); - pipelineInfo.subpass = 0; //subpass由于还不知道有什么用,所以暂时写0,待知道功用后,需改进 - } - - { - pipelineInfo.basePipelineHandle = VK_NULL_HANDLE; - pipelineInfo.basePipelineIndex = -1; - } -} - -PipelineCreater::PipelineCreater(Device *dev,const Material *material,const RenderTarget *rt,uchar *data,uint size) -{ - LoadFromMemory(data,size); - - device=dev->GetDevice(); - extent=rt->GetExtent(); - cache=dev->GetPipelineCache(); - - InitVertexInputState(material); - - pipelineInfo.pInputAssemblyState=&inputAssembly; - pipelineInfo.pTessellationState =&tessellation; - - InitViewportState(); - - pipelineInfo.pRasterizationState=&rasterizer; - pipelineInfo.pMultisampleState =&multisampling; - pipelineInfo.pDepthStencilState =&depthStencilState; - pipelineInfo.pColorBlendState =&colorBlending; - - InitDynamicState(); - - pipelineInfo.layout = material->GetPipelineLayout(); - { - pipelineInfo.renderPass = rt->GetRenderPass(); - pipelineInfo.subpass = 0; //subpass由于还不知道有什么用,所以暂时写0,待知道功用后,需改进 - } - - { - pipelineInfo.basePipelineHandle = VK_NULL_HANDLE; - pipelineInfo.basePipelineIndex = -1; - } -} - -bool PipelineCreater::Set(const Prim topology,bool restart) -{ - if(topologyPrim::END_RANGE) - if(topology!=Prim::Rectangles)return(false); - - inputAssembly.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO; - inputAssembly.pNext = nullptr; - inputAssembly.flags = 0; - inputAssembly.topology = VkPrimitiveTopology(topology==Prim::Rectangles?Prim::Points:topology); - inputAssembly.primitiveRestartEnable = restart; - - pipelineInfo.pInputAssemblyState = &inputAssembly; - return(true); -} - -Pipeline *PipelineCreater::Create() -{ - VkPipeline graphicsPipeline; - - if (vkCreateGraphicsPipelines(device, cache, 1, &pipelineInfo, nullptr, &graphicsPipeline) != VK_SUCCESS) - return(nullptr); - - return(new Pipeline(device,graphicsPipeline,alpha_test>0,alpha_blend)); -} -VK_NAMESPACE_END diff --git a/src/RenderDevice/Vulkan/VKRenderPass.cpp b/src/RenderDevice/Vulkan/VKRenderPass.cpp deleted file mode 100644 index 618bad21..00000000 --- a/src/RenderDevice/Vulkan/VKRenderPass.cpp +++ /dev/null @@ -1,24 +0,0 @@ -#include -#include -VK_NAMESPACE_BEGIN -RenderPass::~RenderPass() -{ - vkDestroyRenderPass(device,render_pass,nullptr); -} - -int RenderpassCreater::AddSwapchainImage() -{ - VkAttachmentDescription desc; - - desc.format = device->GetSurfaceFormat(); - desc.samples = VK_SAMPLE_COUNT_1_BIT; - desc.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; - desc.storeOp = VK_ATTACHMENT_STORE_OP_STORE; - desc.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; - desc.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; - desc.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; - desc.finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR; - - return atta_desc_list.Add(desc); -} -VK_NAMESPACE_END diff --git a/src/RenderDevice/Vulkan/VKRenderTarget.cpp b/src/RenderDevice/Vulkan/VKRenderTarget.cpp deleted file mode 100644 index 38a7dc8d..00000000 --- a/src/RenderDevice/Vulkan/VKRenderTarget.cpp +++ /dev/null @@ -1,174 +0,0 @@ -#include -#include -#include -#include - -VK_NAMESPACE_BEGIN -namespace -{ - const VkPipelineStageFlags pipe_stage_flags=VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; -}//namespace - -SubmitQueue::SubmitQueue(Device *dev,VkQueue q,const uint32_t fence_count) -{ - device=dev; - queue=q; - - for(uint32_t i=0;iCreateFence(false)); - - current_fence=0; - - submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; - submit_info.pNext = nullptr; - submit_info.pWaitDstStageMask = &pipe_stage_flags; -} - -SubmitQueue::~SubmitQueue() -{ - fence_list.Clear(); -} - -bool SubmitQueue::Wait(const bool wait_all,uint64_t time_out) -{ - VkFence fence=*fence_list[current_fence]; - - VkResult result; - - result=vkWaitForFences(device->GetDevice(),1,&fence,wait_all,time_out); - result=vkResetFences(device->GetDevice(),1,&fence); - - if(++current_fence==fence_list.GetCount()) - current_fence=0; - - return(true); -} - -bool SubmitQueue::Submit(const VkCommandBuffer *cmd_buf,const uint32_t cb_count,vulkan::Semaphore *wait_sem,vulkan::Semaphore *complete_sem) -{ - VkSemaphore ws; - VkSemaphore cs; - - if(wait_sem) - { - ws=*wait_sem; - - submit_info.waitSemaphoreCount =1; - submit_info.pWaitSemaphores =&ws; - } - else - { - submit_info.waitSemaphoreCount =0; - submit_info.pWaitSemaphores =nullptr; - } - - if(complete_sem) - { - cs=*complete_sem; - - submit_info.signalSemaphoreCount=1; - submit_info.pSignalSemaphores =&cs; - } - else - { - submit_info.signalSemaphoreCount=0; - submit_info.pSignalSemaphores =nullptr; - } - - submit_info.commandBufferCount =cb_count; - submit_info.pCommandBuffers =cmd_buf; - - VkFence fence=*fence_list[current_fence]; - - VkResult result=vkQueueSubmit(queue,1,&submit_info,fence); - - //不在这里立即等待fence完成,是因为有可能queue submit需要久一点工作时间,我们这个时间可以去干别的。等在AcquireNextImage时再去等待fence,而且是另一帧的fence。这样有利于异步处理 - - return(result==VK_SUCCESS); -} - -bool SubmitQueue::Submit(const VkCommandBuffer &cmd_buf,vulkan::Semaphore *wait_sem,vulkan::Semaphore *complete_sem) -{ - return Submit(&cmd_buf,1,wait_sem,complete_sem); -} - -RenderTarget::RenderTarget(Device *dev,Framebuffer *_fb,const uint32_t fence_count):SubmitQueue(dev,dev->GetGraphicsQueue(),fence_count) -{ - fb=_fb; -} - -SwapchainRenderTarget::SwapchainRenderTarget(Device *dev,Swapchain *sc):RenderTarget(dev,nullptr,sc->GetImageCount()) -{ - swapchain=sc; - vk_swapchain=swapchain->GetSwapchain(); - - present_info.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR; - present_info.pNext = nullptr; - present_info.waitSemaphoreCount = 0; - present_info.pWaitSemaphores = nullptr; - present_info.swapchainCount = 1; - present_info.pResults = nullptr; - present_info.pSwapchains = &vk_swapchain; - - Texture2D **sc_color=swapchain->GetColorTextures(); - Texture2D *sc_depth=swapchain->GetDepthTexture(); - - main_rp=device->CreateRenderPass((*sc_color)->GetFormat(),sc_depth->GetFormat()); - - swap_chain_count=swapchain->GetImageCount(); - - extent=swapchain->GetExtent(); - - for(uint i=0;iGetImageView(),sc_depth->GetImageView())); - ++sc_color; - } - - current_frame=0; -} - -SwapchainRenderTarget::~SwapchainRenderTarget() -{ - render_frame.Clear(); - - delete main_rp; -} - -int SwapchainRenderTarget::AcquireNextImage(vulkan::Semaphore *present_complete_semaphore) -{ - VkSemaphore sem=*present_complete_semaphore; - - if(vkAcquireNextImageKHR(device->GetDevice(),vk_swapchain,UINT64_MAX,sem,VK_NULL_HANDLE,¤t_frame)==VK_SUCCESS) - return current_frame; - - return -1; -} - -bool SwapchainRenderTarget::PresentBackbuffer(vulkan::Semaphore *render_complete_semaphore) -{ - VkSemaphore sem=*render_complete_semaphore; - - present_info.waitSemaphoreCount =1; - present_info.pWaitSemaphores =&sem; - present_info.pImageIndices =¤t_frame; - - VkResult result=vkQueuePresentKHR(queue,&present_info); - - if (!((result == VK_SUCCESS) || (result == VK_SUBOPTIMAL_KHR))) - { - if (result == VK_ERROR_OUT_OF_DATE_KHR) { - // Swap chain is no longer compatible with the surface and needs to be recreated - - return false; - } - } - - result=vkQueueWaitIdle(queue); - - if(result!=VK_SUCCESS) - return(false); - - return(true); -} -VK_NAMESPACE_END diff --git a/src/RenderDevice/Vulkan/VKRenderable.cpp b/src/RenderDevice/Vulkan/VKRenderable.cpp deleted file mode 100644 index 7aebc97f..00000000 --- a/src/RenderDevice/Vulkan/VKRenderable.cpp +++ /dev/null @@ -1,45 +0,0 @@ -#include -#include -#include - -VK_NAMESPACE_BEGIN -Renderable::Renderable(const VertexShaderModule *vsm,const uint32_t dc) -{ - vertex_sm=vsm; - draw_count=dc; - - buf_count=vertex_sm->GetAttrCount(); - - buf_list=hgl_zero_new(buf_count); - buf_offset=hgl_zero_new(buf_count); -} - -Renderable::~Renderable() -{ - delete[] buf_offset; - delete[] buf_list; -} - -bool Renderable::Set(const int stage_input_binding,VAB *vab,VkDeviceSize offset) -{ - if(stage_input_binding<0||stage_input_binding>=buf_count||!vab)return(false); - - const VkVertexInputBindingDescription *desc=vertex_sm->GetDesc(stage_input_binding); - const VkVertexInputAttributeDescription *attr=vertex_sm->GetAttr(stage_input_binding); - - if(vab->GetFormat()!=attr->format)return(false); - if(vab->GetStride()!=desc->stride)return(false); - - //format信息来自于shader,实际中可以不一样。但那样需要为每一个格式产生一个同样shader的material instance,不同的格式又需要不同的pipeline,我们不支持这种行为 - - buf_list[stage_input_binding]=vab->GetBuffer(); - buf_offset[stage_input_binding]=offset; - - return(true); -} - -bool Renderable::Set(const AnsiString &name,VAB *vab,VkDeviceSize offset) -{ - return Set(vertex_sm->GetStageInputBinding(name),vab,offset); -} -VK_NAMESPACE_END diff --git a/src/RenderDevice/Vulkan/VKShaderModule.cpp b/src/RenderDevice/Vulkan/VKShaderModule.cpp deleted file mode 100644 index c96191e3..00000000 --- a/src/RenderDevice/Vulkan/VKShaderModule.cpp +++ /dev/null @@ -1,83 +0,0 @@ -#include -#include - -VK_NAMESPACE_BEGIN -ShaderModule::ShaderModule(VkDevice dev,int id,VkPipelineShaderStageCreateInfo *sci,ShaderResource *sr) -{ - device=dev; - shader_id=id; - ref_count=0; - - stage_create_info=sci; - - shader_resource=sr; -} - -ShaderModule::~ShaderModule() -{ - vkDestroyShaderModule(device,stage_create_info->module,nullptr); - delete stage_create_info; -} - -VertexShaderModule::VertexShaderModule(VkDevice dev,int id,VkPipelineShaderStageCreateInfo *pssci,ShaderResource *sr):ShaderModule(dev,id,pssci,sr) -{ - const ShaderStageList &stage_inputs=sr->GetStageInputs(); - - attr_count=stage_inputs.GetCount(); - binding_list=new VkVertexInputBindingDescription[attr_count]; - attribute_list=new VkVertexInputAttributeDescription[attr_count]; - - VkVertexInputBindingDescription *bind=binding_list; - VkVertexInputAttributeDescription *attr=attribute_list; - - ShaderStage **si=stage_inputs.GetData(); - - for(uint i=0;ibinding =i; //binding对应在vkCmdBindVertexBuffer中设置的缓冲区的序列号,所以这个数字必须从0开始,而且紧密排列。 - //在VertexInput类中,buf_list需要严格按照本此binding为序列号排列 - bind->stride =GetStrideByFormat((*si)->format); - bind->inputRate =VK_VERTEX_INPUT_RATE_VERTEX; - - //binding对应的是第几个数据输入流 - //实际使用一个binding可以绑定多个attrib - //比如在一个流中传递{pos,color}这样两个数据,就需要两个attrib - //但在我们的设计中,仅支持一个流传递一个attrib - - attr->binding =i; - attr->location =(*si)->location; //此值对应shader中的layout(location= - attr->format =(*si)->format; - attr->offset =0; - - ++attr; - ++bind; - - ++si; - } -} - -VertexShaderModule::~VertexShaderModule() -{ - if(vab_sets.GetCount()>0) - { - //还有在用的,这是个错误 - } - - SAFE_CLEAR_ARRAY(binding_list); - SAFE_CLEAR_ARRAY(attribute_list); -} - -VertexAttributeBinding *VertexShaderModule::CreateVertexAttributeBinding() -{ - VertexAttributeBinding *vab=new VertexAttributeBinding(attr_count,binding_list,attribute_list); - - vab_sets.Add(vab); - - return(vab); -} - -bool VertexShaderModule::Release(VertexAttributeBinding *vab) -{ - return vab_sets.Delete(vab); -} -VK_NAMESPACE_END diff --git a/src/RenderDevice/Vulkan/VKShaderModuleManage.cpp b/src/RenderDevice/Vulkan/VKShaderModuleManage.cpp deleted file mode 100644 index 03fe60a7..00000000 --- a/src/RenderDevice/Vulkan/VKShaderModuleManage.cpp +++ /dev/null @@ -1,278 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include - -VK_NAMESPACE_BEGIN -Material *CreateMaterial(Device *dev,ShaderModuleMap *shader_maps); - -ShaderModuleManage::~ShaderModuleManage() -{ - const int count=shader_list.GetCount(); - - if(count>0) - { - auto **p=shader_list.GetDataList(); - - for(int i=0;iright; - - ++p; - } - } -} - -const ShaderModule *ShaderModuleManage::CreateShader(ShaderResource *sr) -{ - if(!sr) - return(nullptr); - - VkPipelineShaderStageCreateInfo *shader_stage=new VkPipelineShaderStageCreateInfo; - shader_stage->sType =VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; - shader_stage->pNext =nullptr; - shader_stage->pSpecializationInfo =nullptr; - shader_stage->flags =0; - shader_stage->stage =sr->GetStage(); - shader_stage->pName ="main"; - - VkShaderModuleCreateInfo moduleCreateInfo; - moduleCreateInfo.sType =VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; - moduleCreateInfo.pNext =nullptr; - moduleCreateInfo.flags =0; - moduleCreateInfo.codeSize =sr->GetCodeSize(); - moduleCreateInfo.pCode =sr->GetCode(); - - if(vkCreateShaderModule(*device,&moduleCreateInfo,nullptr,&(shader_stage->module))!=VK_SUCCESS) - return(nullptr); - - ShaderModule *sm; - - if(sr->GetStage()==VK_SHADER_STAGE_VERTEX_BIT) - sm=new VertexShaderModule(*device,shader_count,shader_stage,sr); - else - sm=new ShaderModule(*device,shader_count,shader_stage,sr); - - shader_list.Add(shader_count,sm); - - ++shader_count; - - return sm; -} - -const ShaderModule *ShaderModuleManage::CreateShader(const VkShaderStageFlagBits shader_stage_bit,const OSString &filename) -{ - ShaderResource *shader_resource=LoadShaderResoruce(filename); - - if(!shader_resource)return(nullptr); - - return CreateShader(shader_resource); -} - -const ShaderModule *ShaderModuleManage::GetShader(int id) -{ - ShaderModule *sm; - - if(!shader_list.Get(id,sm)) - return nullptr; - - sm->IncRef(); - return sm; -} - -bool ShaderModuleManage::ReleaseShader(const ShaderModule *const_sm) -{ - if(!const_sm) - return(false); - - ShaderModule *sm; - - if(!shader_list.Get(const_sm->GetID(),sm)) - return(false); - - if(sm!=const_sm) - return(false); - - sm->DecRef(); - return(true); -} - -void ShaderModuleManage::Free(ShaderModuleMap *smm) -{ - const int count=smm->GetCount(); - - auto **it=smm->GetDataList(); - - for(int i=0;iright); - - ++it; - } - - delete smm; -} - -Material *ShaderModuleManage::CreateMaterial(ShaderModuleMap *smm) -{ - Material *mtl=VK_NAMESPACE::CreateMaterial(device,smm); - - if(mtl)return(mtl); - - Free(smm); - return(nullptr); -} - -Material *ShaderModuleManage::CreateMaterial(const VertexShaderModule *vertex_shader_module,const ShaderModule *fragment_shader_module) -{ - if(!vertex_shader_module||!fragment_shader_module) - return(nullptr); - - if(!vertex_shader_module->IsVertex())return(nullptr); - if(!fragment_shader_module->IsFragment())return(nullptr); - - ShaderModuleMap *smm=new ShaderModuleMap; - - smm->Add(vertex_shader_module); - smm->Add(fragment_shader_module); - - return CreateMaterial(smm); -} - -Material *ShaderModuleManage::CreateMaterial(const VertexShaderModule *vertex_shader_module,const ShaderModule *geometry_shader_module,const ShaderModule *fragment_shader_module) -{ - if(!vertex_shader_module - ||!geometry_shader_module - ||!fragment_shader_module) - return(nullptr); - - if(!vertex_shader_module->IsVertex())return(nullptr); - if(!geometry_shader_module->IsGeometry())return(nullptr); - if(!fragment_shader_module->IsFragment())return(nullptr); - - ShaderModuleMap *smm=new ShaderModuleMap; - - smm->Add(vertex_shader_module); - smm->Add(geometry_shader_module); - smm->Add(fragment_shader_module); - - return CreateMaterial(smm); -} - -Material *ShaderModuleManage::CreateMaterial(const OSString &vertex_shader_filename,const OSString &fragment_shader_filename) -{ - const ShaderModule *vs=CreateShader(VK_SHADER_STAGE_VERTEX_BIT,vertex_shader_filename); - - if(!vs) - return(nullptr); - - const ShaderModule *fs=CreateShader(VK_SHADER_STAGE_FRAGMENT_BIT,fragment_shader_filename); - - if(!fs) - { - ReleaseShader(vs); - return(nullptr); - } - - return(CreateMaterial((VertexShaderModule *)vs,fs)); -} - -Material *ShaderModuleManage::CreateMaterial(const OSString &vertex_shader_filename,const OSString &geometry_shader_filename,const OSString &fragment_shader_filename) -{ - const ShaderModule *vs=CreateShader(VK_SHADER_STAGE_VERTEX_BIT,vertex_shader_filename); - - if(!vs) - return(nullptr); - - const ShaderModule *gs=CreateShader(VK_SHADER_STAGE_GEOMETRY_BIT,geometry_shader_filename); - - if(!gs) - { - ReleaseShader(vs); - return(nullptr); - } - - const ShaderModule *fs=CreateShader(VK_SHADER_STAGE_FRAGMENT_BIT,fragment_shader_filename); - - if(!fs) - { - ReleaseShader(gs); - ReleaseShader(vs); - return(nullptr); - } - - return(CreateMaterial((VertexShaderModule *)vs,gs,fs)); -} - -Material *ShaderModuleManage::CreateMaterial(const OSString &filename) -{ - constexpr char MaterialFileHeader[]=u8"Material\x1A"; - constexpr uint MaterialFileHeaderLength=sizeof(MaterialFileHeader)-1; - - int64 filesize; - AutoDeleteArray origin_filedata=(uint8 *)filesystem::LoadFileToMemory(filename+OS_TEXT(".material"),filesize); - - if(filesizeAdd(sm)) - continue; - } - } - - result=false; - break; - } - - if(result) - return CreateMaterial(smm); - - Free(smm); - return(nullptr); -} -VK_NAMESPACE_END diff --git a/src/RenderDevice/Vulkan/VKVertexAttributeBinding.cpp b/src/RenderDevice/Vulkan/VKVertexAttributeBinding.cpp deleted file mode 100644 index e76e4c6d..00000000 --- a/src/RenderDevice/Vulkan/VKVertexAttributeBinding.cpp +++ /dev/null @@ -1,70 +0,0 @@ -#include -#include - -VK_NAMESPACE_BEGIN -VertexAttributeBinding::VertexAttributeBinding(const uint32_t count,const VkVertexInputBindingDescription *bind_list,const VkVertexInputAttributeDescription *attr_list) -{ - attr_count=count; - - if(attr_count<=0) - { - binding_list=nullptr; - attribute_list=nullptr; - return; - } - - binding_list=hgl_copy_new(attr_count,bind_list); - attribute_list=hgl_copy_new(attr_count,attr_list); -} - -VertexAttributeBinding::~VertexAttributeBinding() -{ - delete[] attribute_list; - delete[] binding_list; -} - -bool VertexAttributeBinding::SetInstance(const uint index,bool instance) -{ - if(index>=attr_count)return(false); - - binding_list[index].inputRate=instance?VK_VERTEX_INPUT_RATE_INSTANCE:VK_VERTEX_INPUT_RATE_VERTEX; - - return(true); -} - -bool VertexAttributeBinding::SetStride(const uint index,const uint32_t &stride) -{ - if(index>=attr_count)return(false); - - binding_list[index].stride=stride; - - return(true); -} - -bool VertexAttributeBinding::SetFormat(const uint index,const VkFormat &format) -{ - if(index>=attr_count)return(false); - - attribute_list[index].format=format; - - return(true); -} - -bool VertexAttributeBinding::SetOffset(const uint index,const uint32_t offset) -{ - if(index>=attr_count)return(false); - - attribute_list[index].offset=offset; - - return(true); -} - -void VertexAttributeBinding::Write(VkPipelineVertexInputStateCreateInfo &vis_create_info) const -{ - vis_create_info.vertexBindingDescriptionCount = attr_count; - vis_create_info.pVertexBindingDescriptions = binding_list; - - vis_create_info.vertexAttributeDescriptionCount = attr_count; - vis_create_info.pVertexAttributeDescriptions = attribute_list; -} -VK_NAMESPACE_END diff --git a/src/SceneGraph/Bitmap2DLoader.cpp b/src/SceneGraph/Bitmap2DLoader.cpp new file mode 100644 index 00000000..d4f1046d --- /dev/null +++ b/src/SceneGraph/Bitmap2DLoader.cpp @@ -0,0 +1,44 @@ +#include + +namespace hgl +{ + namespace graph + { + Bitmap2DLoader::~Bitmap2DLoader() + { + SAFE_CLEAR(bmp); + } + + void *Bitmap2DLoader::OnBegin(uint32 total_bytes) + { + SAFE_CLEAR(bmp); + + bmp=new BitmapData; + + bmp->width =file_header.width; + bmp->height =file_header.height; + bmp->total_bytes=total_bytes; + + bmp->data=new char[total_bytes]; + + return bmp->data; + } + + BitmapData *Bitmap2DLoader::GetBitmap() + { + BitmapData *result=bmp; + bmp=nullptr; + return result; + } + + BitmapData *LoadBitmapFromFile(const OSString &filename) + { + Bitmap2DLoader loader; + + if(!loader.Load(filename)) + return(nullptr); + + return loader.GetBitmap(); + } + }//namespace graph +}//namespace hgl diff --git a/src/SceneGraph/CMakeLists.txt b/src/SceneGraph/CMakeLists.txt index 7cd4babf..598aadcd 100644 --- a/src/SceneGraph/CMakeLists.txt +++ b/src/SceneGraph/CMakeLists.txt @@ -1,40 +1,33 @@ -SET(SHADER_RESOURCE_FILES ${ROOT_INCLUDE_PATH}/hgl/graph/shader/ShaderResource.h - shader/ShaderResource.cpp) +set(SG_INCLUDE_PATH ${ROOT_INCLUDE_PATH}/hgl/graph) -file(GLOB SG_MATERIAL_HEADER ${ROOT_INCLUDE_PATH}/hgl/graph/material/*.*) +SET(SG_TEXTURE_SOURCE ${SG_INCLUDE_PATH}/TextureLoader.h + ${SG_INCLUDE_PATH}/Bitmap2DLoader.h + TextureLoader.cpp + Bitmap2DLoader.cpp) -file(GLOB SG_MATERIAL_SOURCE material/*.*) +SOURCE_GROUP("Texture" FILES ${SG_TEXTURE_SOURCE}) -SOURCE_GROUP("Material" FILES ${SG_MATERIAL_HEADER} - ${SG_MATERIAL_SOURCE}) - -SOURCE_GROUP("Material\\Shader" FILES ${SHADER_RESOURCE_FILES}) - -SET(SG_TEXTURE_SOURCE ${ROOT_INCLUDE_PATH}/hgl/graph/TextureLoader.h - Texture2DLoader.cpp) - -SOURCE_GROUP("Material\\Texture" FILES ${SG_TEXTURE_SOURCE}) - -SET(SG_VAD_SOURCE ${ROOT_INCLUDE_PATH}/hgl/graph/VertexAttribData.h - ${ROOT_INCLUDE_PATH}/hgl/graph/VertexAttribDataAccess.h +SET(SG_VAD_SOURCE ${SG_INCLUDE_PATH}/VertexAttribData.h + ${SG_INCLUDE_PATH}/VertexAttribDataAccess.h VertexAttribData.cpp) SOURCE_GROUP("VertexAttribData" FILES ${SG_VAD_SOURCE}) -SET(TILE_SOURCE ${ROOT_INCLUDE_PATH}/hgl/graph/TileData.h +SET(TILE_SOURCE ${SG_INCLUDE_PATH}/TileData.h TileData.cpp) SOURCE_GROUP("Tile" FILES ${TILE_SOURCE}) -SET(SCENE_GRAPH_HEADER ${ROOT_INCLUDE_PATH}/hgl/graph/Light.h - ${ROOT_INCLUDE_PATH}/hgl/graph/SceneNode.h - ${ROOT_INCLUDE_PATH}/hgl/graph/SceneOrient.h - ${ROOT_INCLUDE_PATH}/hgl/graph/RenderableInstance.h - ${ROOT_INCLUDE_PATH}/hgl/graph/RenderList.h - ${ROOT_INCLUDE_PATH}/hgl/graph/InlineGeometry.h - #${ROOT_INCLUDE_PATH}/hgl/graph/Mesh.h - #${ROOT_INCLUDE_PATH}/hgl/graph/Material.h - #${ROOT_INCLUDE_PATH}/hgl/graph/Spline.h +SET(SCENE_GRAPH_HEADER ${SG_INCLUDE_PATH}/Light.h + ${SG_INCLUDE_PATH}/SceneInfo.h + ${SG_INCLUDE_PATH}/SceneNode.h + ${SG_INCLUDE_PATH}/RenderNode.h + ${SG_INCLUDE_PATH}/SceneOrient.h + ${SG_INCLUDE_PATH}/RenderList.h + ${SG_INCLUDE_PATH}/InlineGeometry.h + #${SG_INCLUDE_PATH}/Mesh.h + #${SG_INCLUDE_PATH}/Material.h + #${SG_INCLUDE_PATH}/Spline.h ) SET(SCENE_GRAPH_SOURCE RenderList.cpp @@ -47,28 +40,28 @@ SET(SCENE_GRAPH_SOURCE RenderList.cpp #SceneFile.cpp ) -SET(RENDERABLE_FILES ${ROOT_INCLUDE_PATH}/hgl/graph/RenderableCreater.h +SET(RENDERABLE_FILES ${SG_INCLUDE_PATH}/RenderableCreater.h RenderableCreater.cpp) SOURCE_GROUP("Renderable" FILES ${RENDERABLE_FILES}) -SET(FONT_MANAGE_SOURCE ${ROOT_INCLUDE_PATH}/hgl/graph/font/Font.h - ${ROOT_INCLUDE_PATH}/hgl/graph/font/FontManage.h +SET(FONT_MANAGE_SOURCE ${SG_INCLUDE_PATH}/font/Font.h + ${SG_INCLUDE_PATH}/font/FontManage.h font/Font.cpp) -SET(FONT_SOURCE ${ROOT_INCLUDE_PATH}/hgl/graph/font/FontSource.h +SET(FONT_SOURCE ${SG_INCLUDE_PATH}/font/FontSource.h font/FontSource.cpp font/FontSourceSingle.cpp font/FontSourceMulti.cpp font/FontSourceManage.cpp) -SET(TILE_FONT_SOURCE ${ROOT_INCLUDE_PATH}/hgl/graph/font/TileFont.h +SET(TILE_FONT_SOURCE ${SG_INCLUDE_PATH}/font/TileFont.h font/TileFont.cpp) -SET(FONT_LAYOUT_SOURCE ${ROOT_INCLUDE_PATH}/hgl/graph/font/TextLayout.h +SET(FONT_LAYOUT_SOURCE ${SG_INCLUDE_PATH}/font/TextLayout.h font/TextLayout.cpp) -SET(TEXT_RENDERABLE_SOURCE ${ROOT_INCLUDE_PATH}/hgl/graph/font/TextRenderable.h +SET(TEXT_RENDERABLE_SOURCE ${SG_INCLUDE_PATH}/font/TextRenderable.h font/TextRenderable.cpp) SOURCE_GROUP("Font" FILES ${FONT_MANAGE_SOURCE}) @@ -86,14 +79,185 @@ ENDIF(WIN32) SOURCE_GROUP("Header Files" FILES ${SCENE_GRAPH_HEADER}) SOURCE_GROUP("Source Files" FILES ${SCENE_GRAPH_SOURCE}) +SET(VK_RR_SOURCE ${SG_INCLUDE_PATH}/VKRenderResource.h + Vulkan/VKRenderResource.cpp + Vulkan/VKRenderResourceMaterial.cpp) + +SOURCE_GROUP("Vulkan\\RenderResource" FILES ${VK_RR_SOURCE}) + +SET(VK_RR_SHADER_FILES ${SG_INCLUDE_PATH}/VKShaderResource.h + Vulkan/VKShaderResource.cpp) + +SOURCE_GROUP("Vulkan\\RenderResource\\Shader" FILES ${VK_RR_SHADER_FILES}) + +SET(VK_RR_MATERIAL_FILES ${SG_INCLUDE_PATH}/VKMaterialDescriptorSets.h + Vulkan/VKMaterialDescriptorSets.cpp) + +SOURCE_GROUP("Vulkan\\RenderResource\\Material" FILES ${VK_RR_MATERIAL_FILES}) + +SET(VK_INST_SOURCE ${SG_INCLUDE_PATH}/VKInstance.h + Vulkan/VKInstance.cpp) + +SET(VK_DEBUG_SOURCE ${SG_INCLUDE_PATH}/VKDebugOut.h + ${SG_INCLUDE_PATH}/VKDebugMaker.h + Vulkan/VKDebugOut.cpp + Vulkan/VKDebugMaker.cpp) + +SET(VK_MEMORY_SOURCE ${SG_INCLUDE_PATH}/VKMemory.h + ${SG_INCLUDE_PATH}/VKMemoryAllocator.h + ${SG_INCLUDE_PATH}/VKBuffer.h + ${SG_INCLUDE_PATH}/VKIndexBuffer.h + ${SG_INCLUDE_PATH}/VKArrayBuffer.h + Vulkan/VKMemory.cpp + Vulkan/VKMemoryAllocator.cpp + Vulkan/VKBuffer.cpp + ) + +SET(VK_DEVICE_TEXTURE_SOURCE Vulkan/Texture/BufferImageCopy2D.h + Vulkan/Texture/GenMipmaps.cpp + Vulkan/Texture/VKDeviceTexture.cpp + Vulkan/Texture/VKDeviceTexture2D.cpp + Vulkan/Texture/VKDeviceTextureCube.cpp) + +SET(VK_TEXTURE_LOADER_SOURCE ${SG_INCLUDE_PATH}/VKTextureCreateInfo.h + Vulkan/Texture/VKTextureLoader.h + Vulkan/Texture/VKTexture2DLoader.cpp + Vulkan/Texture/VKTextureCubeLoader.cpp) + +SET(VK_DEVICE_SOURCE ${SG_INCLUDE_PATH}/VKDevice.h + ${SG_INCLUDE_PATH}/VKDeviceAttribute.h + Vulkan/VKDeviceAttribute.cpp + Vulkan/VKDeviceCreater.cpp + Vulkan/VKDevice.cpp + Vulkan/VKDeviceMemory.cpp + Vulkan/VKDeviceBuffer.cpp + Vulkan/VKDeviceImage.cpp + Vulkan/VKDeviceSampler.cpp + Vulkan/VKDeviceMaterial.cpp + Vulkan/VKDeviceFramebuffer.cpp + Vulkan/VKDeviceSwapchain.cpp + Vulkan/VKDeviceRenderPass.cpp + Vulkan/VKDeviceRenderPassManage.cpp + Vulkan/VKDeviceRenderTarget.cpp) + +SET(VK_PHYSICAL_DEVICE_SOURCE ${SG_INCLUDE_PATH}/VKPhysicalDevice.h + Vulkan/VKPhysicalDevice.cpp + Vulkan/VKProperties.cpp) + +SOURCE_GROUP("Vulkan\\Device" FILES ${VK_DEVICE_SOURCE}) +SOURCE_GROUP("Vulkan\\Device\\Debug" FILES ${VK_DEBUG_SOURCE}) +SOURCE_GROUP("Vulkan\\Device\\Instance" FILES ${VK_INST_SOURCE}) +SOURCE_GROUP("Vulkan\\Device\\Physical Device" FILES ${VK_PHYSICAL_DEVICE_SOURCE}) +SOURCE_GROUP("Vulkan\\Device\\Memory" FILES ${VK_MEMORY_SOURCE}) +SOURCE_GROUP("Vulkan\\Device\\Texture" FILES ${VK_DEVICE_TEXTURE_SOURCE}) +SOURCE_GROUP("Vulkan\\Device\\Texture\\Loader" FILES ${VK_TEXTURE_LOADER_SOURCE}) + +SET(VK_DESCRIPTOR_SETS_SOURCE ${SG_INCLUDE_PATH}/VKDescriptorSets.h + Vulkan/VKDescriptorSets.cpp + Vulkan/VKPipelineLayoutData.h + Vulkan/VKPipelineLayoutData.cpp) + +SOURCE_GROUP("Vulkan\\Descriptor Sets" FILES ${VK_DESCRIPTOR_SETS_SOURCE}) + +SET(VK_SHADER_SOURCE ${SG_INCLUDE_PATH}/VKShaderModule.h + ${SG_INCLUDE_PATH}/VKShaderModuleMap.h + Vulkan/VKShaderModuleMap.cpp + Vulkan/VKShaderModule.cpp) + +SET(VK_TEXTURE_SOURCE ${SG_INCLUDE_PATH}/VKImageView.h + ${SG_INCLUDE_PATH}/VKTexture.h + ${SG_INCLUDE_PATH}/VKSampler.h + Vulkan/VKSampler.cpp + Vulkan/VKImageView.cpp + Vulkan/VKTexture.cpp) + +SET(VK_MATERIAL_SOURCE ${SG_INCLUDE_PATH}/VKMaterial.h + ${SG_INCLUDE_PATH}/VKMaterialParameters.h + ${SG_INCLUDE_PATH}/VKMaterialInstance.h + Vulkan/VKMaterial.cpp + Vulkan/VKMaterialParameters.cpp + Vulkan/VKMaterialInstance.cpp) + +SOURCE_GROUP("Vulkan\\Material" FILES ${VK_MATERIAL_SOURCE}) +SOURCE_GROUP("Vulkan\\Material\\Texture" FILES ${VK_TEXTURE_SOURCE}) +SOURCE_GROUP("Vulkan\\Material\\Shader" FILES ${VK_SHADER_SOURCE}) + +SET(VK_RENDER_CONTEXT_SOURCE ${SG_INCLUDE_PATH}/VKRenderContext.h + ${SG_INCLUDE_PATH}/VKSubpass.h + Vulkan/VKSubpass.cpp + Vulkan/VKRenderContext.cpp) + +SET(VK_RENDER_PASS_SOURCE ${SG_INCLUDE_PATH}/VKFramebuffer.h + ${SG_INCLUDE_PATH}/VKPipeline.h + ${SG_INCLUDE_PATH}/VKRenderPass.h + ${SG_INCLUDE_PATH}/VKRenderTarget.h + ${SG_INCLUDE_PATH}/VKSwapchain.h + ${SG_INCLUDE_PATH}/VKSemaphore.h + ${SG_INCLUDE_PATH}/VKFence.h + Vulkan/VKQueue.cpp + Vulkan/VKSemaphore.cpp + Vulkan/VKFence.cpp + Vulkan/VKFramebuffer.cpp + Vulkan/VKPipeline.cpp + Vulkan/VKPipelineCache.cpp + #Vulkan/VKSubpass.cpp + Vulkan/VKRenderPass.cpp + Vulkan/VKRenderTarget.cpp + Vulkan/VKSwapchainRenderTarget.cpp + Vulkan/VKSwapchain.cpp + ) + +SOURCE_GROUP("Vulkan\\Render Pass" FILES ${VK_RENDER_PASS_SOURCE}) + +SOURCE_GROUP("Vulkan\\Render Context" FILES ${VK_RENDER_CONTEXT_SOURCE}) + +SET(VK_CMD_BUFFER_SOURCE ${SG_INCLUDE_PATH}/VKCommandBuffer.h + Vulkan/VKCommandBuffer.cpp + Vulkan/VKCommandBufferRender.cpp) + +SOURCE_GROUP("Vulkan\\Command Buffer" FILES ${VK_CMD_BUFFER_SOURCE}) + +SET(VK_RENDERABLE_SOURCE ${SG_INCLUDE_PATH}/VKRenderable.h + ${SG_INCLUDE_PATH}/VKRenderableInstance.h + Vulkan/VKRenderable.cpp + Vulkan/VKRenderableInstance.cpp + Vulkan/VKTileData.cpp + Vulkan/VKTileFont.cpp) + +SOURCE_GROUP("Vulkan\\Renderable" FILES ${VK_RENDERABLE_SOURCE}) + +IF(WIN32) + OPTION(FORCE_DISCETE_GPU "Force Discrete GPU" OFF) + + IF(FORCE_DISCETE_GPU) + SET(RENDER_DEVICE_SOURCE ForceDiscreteGPU.c) + ENDIF() +ENDIF(WIN32) + +SET(VULKAN_RENDER_SOURCE ${VK_RR_SOURCE} + ${VK_RR_SHADER_FILES} + ${VK_RR_MATERIAL_FILES} + ${VK_INST_SOURCE} + ${VK_DEBUG_SOURCE} + ${VK_MEMORY_SOURCE} + ${VK_DEVICE_SOURCE} + ${VK_DEVICE_TEXTURE_SOURCE} + ${VK_TEXTURE_LOADER_SOURCE} + ${VK_PHYSICAL_DEVICE_SOURCE} + ${VK_DESCRIPTOR_SETS_SOURCE} + ${VK_SHADER_SOURCE} + ${VK_TEXTURE_SOURCE} + ${VK_MATERIAL_SOURCE} + ${VK_RENDER_PASS_SOURCE} + #${VK_RENDER_CONTEXT_SOURCE} + ${VK_CMD_BUFFER_SOURCE} + ${VK_RENDERABLE_SOURCE} + ${VK_RENDER_DEVICE_SOURCE}) + add_cm_library(ULRE.SceneGraph "ULRE" ${SCENE_GRAPH_HEADER} ${SCENE_GRAPH_SOURCE} - ${SHADER_RESOURCE_FILES} - ${SG_TEXTURE_SOURCE} - ${SG_MATERIAL_HEADER} - ${SG_MATERIAL_SOURCE} ${TILE_SOURCE} ${SG_VAD_SOURCE} @@ -104,4 +268,6 @@ add_cm_library(ULRE.SceneGraph "ULRE" ${SCENE_GRAPH_HEADER} ${FONT_SOURCE_OS} ${TILE_FONT_SOURCE} ${FONT_LAYOUT_SOURCE} - ${TEXT_RENDERABLE_SOURCE}) + ${TEXT_RENDERABLE_SOURCE} + + ${VULKAN_RENDER_SOURCE}) diff --git a/src/SceneGraph/InlineGeometry.cpp b/src/SceneGraph/InlineGeometry.cpp index 3265047d..79d936a2 100644 --- a/src/SceneGraph/InlineGeometry.cpp +++ b/src/SceneGraph/InlineGeometry.cpp @@ -3,18 +3,18 @@ #include #include -#include -#include -#include +#include +#include +#include #include namespace hgl { namespace graph { - vulkan::Renderable *CreateRenderableRectangle(vulkan::Database *db,vulkan::Material *mtl,const RectangleCreateInfo *rci) + Renderable *CreateRenderableRectangle(RenderResource *db,const VAB *vab,const RectangleCreateInfo *rci) { - RenderableCreater rc(db,mtl); + RenderableCreater rc(db,vab); if(!rc.Init(4)) return(nullptr); @@ -29,18 +29,18 @@ namespace hgl return rc.Finish(); } - vulkan::Renderable *CreateRenderableGBufferComposition(vulkan::Database *db,vulkan::Material *mtl) + Renderable *CreateRenderableGBufferComposition(RenderResource *db,const VAB *vab) { RectangleCreateInfo rci; rci.scope.Set(-1,-1,2,2); - return CreateRenderableRectangle(db,mtl,&rci); + return CreateRenderableRectangle(db,vab,&rci); } - vulkan::Renderable *CreateRenderableRoundRectangle(vulkan::Database *db,vulkan::Material *mtl,const RoundRectangleCreateInfo *rci) + Renderable *CreateRenderableRoundRectangle(RenderResource *db,const VAB *vab,const RoundRectangleCreateInfo *rci) { - RenderableCreater rc(db,mtl); + RenderableCreater rc(db,vab); if(rci->radius==0||rci->round_per<=1) //这是要画矩形 { @@ -63,7 +63,7 @@ namespace hgl AutoDelete vertex=rc.CreateVADA(VAN::Position); - vec2 *coord=new vec2[rci->round_per]; + Vector2f *coord=new Vector2f[rci->round_per]; float l=rci->scope.GetLeft(), r=rci->scope.GetRight(), @@ -74,8 +74,8 @@ namespace hgl { float ang=float(i)/float(rci->round_per-1)*90.0f; - float x=sin(hgl_ang2rad(ang))*radius; - float y=cos(hgl_ang2rad(ang))*radius; + float x=sin(deg2rad(ang))*radius; + float y=cos(deg2rad(ang))*radius; coord[i].x=x; coord[i].y=y; @@ -112,50 +112,73 @@ namespace hgl return rc.Finish(); } - vulkan::Renderable *CreateRenderableCircle(vulkan::Database *db,vulkan::Material *mtl,const CircleCreateInfo *cci) + Renderable *CreateRenderableCircle(RenderResource *db,const VAB *vab,const CircleCreateInfo *cci) { - RenderableCreater rc(db,mtl); + RenderableCreater rc(db,vab); - if(!rc.Init(cci->field_count)) - return(nullptr); + uint edge; + + if(cci->has_color) + { + edge=cci->field_count+1; + if(!rc.Init(cci->field_count+2))return(nullptr); + } + else + { + edge=cci->field_count; + if(!rc.Init(cci->field_count))return(nullptr); + } AutoDelete vertex=rc.CreateVADA(VAN::Position); + AutoDelete color=rc.CreateVADA(VAN::Color); if(!vertex) return(nullptr); - for(uint i=0;ifield_count;i++) + if(cci->has_color) + { + if(!color) + return(nullptr); + + vertex->Write(cci->center); + color->Write(cci->center_color); + } + + for(uint i=0;ifield_count)*360.0f; - float x=cci->center.x+sin(hgl_ang2rad(ang))*cci->radius.x; - float y=cci->center.y+cos(hgl_ang2rad(ang))*cci->radius.y; + float x=cci->center.x+sin(deg2rad(ang))*cci->radius.x; + float y=cci->center.y+cos(deg2rad(ang))*cci->radius.y; vertex->Write(x,y); + + if(cci->has_color) + color->Write(cci->border_color); } return rc.Finish(); } - vulkan::Renderable *CreateRenderablePlaneGrid(vulkan::Database *db,vulkan::Material *mtl,const PlaneGridCreateInfo *pgci) + Renderable *CreateRenderablePlaneGrid(RenderResource *db,const VAB *vab,const PlaneGridCreateInfo *pgci) { - RenderableCreater rc(db,mtl); + RenderableCreater rc(db,vab); - if(!rc.Init(((pgci->step.u+1)+(pgci->step.v+1))*2)) + if(!rc.Init(((pgci->step.x+1)+(pgci->step.y+1))*2)) return(nullptr); AutoDelete vertex=rc.CreateVADA(VAN::Position); - for(uint row=0;row<=pgci->step.u;row++) + for(uint row=0;row<=pgci->step.x;row++) { - float pos=float(row)/float(pgci->step.u); + float pos=float(row)/float(pgci->step.x); vertex->WriteLine( to(pgci->coord[0],pgci->coord[1],pos), to(pgci->coord[3],pgci->coord[2],pos)); } - for(uint col=0;col<=pgci->step.v;col++) + for(uint col=0;col<=pgci->step.y;col++) { - float pos=float(col)/float(pgci->step.v); + float pos=float(col)/float(pgci->step.y); vertex->WriteLine(to(pgci->coord[1],pgci->coord[2],pos), to(pgci->coord[0],pgci->coord[3],pos)); @@ -164,34 +187,34 @@ namespace hgl AutoDelete color=rc.CreateVADA(VAN::Color); if(color) { - for(uint row=0;row<=pgci->step.u;row++) + for(uint row=0;row<=pgci->step.x;row++) { - if((row%pgci->side_step.u)==0) - color->Fill(pgci->side_color,2); + if((row%pgci->side_step.x)==0) + color->RepeatWrite(pgci->side_color,2); else - color->Fill(pgci->color,2); + color->RepeatWrite(pgci->color,2); } - for(uint col=0;col<=pgci->step.v;col++) + for(uint col=0;col<=pgci->step.y;col++) { - if((col%pgci->side_step.v)==0) - color->Fill(pgci->side_color,2); + if((col%pgci->side_step.y)==0) + color->RepeatWrite(pgci->side_color,2); else - color->Fill(pgci->color,2); + color->RepeatWrite(pgci->color,2); } } return rc.Finish(); } - vulkan::Renderable *CreateRenderablePlane(vulkan::Database *db,vulkan::Material *mtl,const PlaneCreateInfo *pci) + Renderable *CreateRenderablePlane(RenderResource *db,const VAB *vab,const PlaneCreateInfo *pci) { const float xy_vertices [] = { -0.5f,-0.5f,0.0f, +0.5f,-0.5f,0.0f, +0.5f,+0.5f,0.0f, -0.5f,+0.5f,0.0f }; float xy_tex_coord[] = { 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f }; const Vector3f xy_normal(0.0f,0.0f,1.0f); const Vector3f xy_tangent(1.0f,0.0f,0.0f); - RenderableCreater rc(db,mtl); + RenderableCreater rc(db,vab); if(!rc.Init(4)) return(nullptr); @@ -201,13 +224,13 @@ namespace hgl { AutoDelete normal=rc.CreateVADA(VAN::Normal); - if(normal)normal->Fill(xy_normal,4); + if(normal)normal->RepeatWrite(xy_normal,4); } { AutoDelete tangent=rc.CreateVADA(VAN::Tangent); - tangent->Fill(xy_tangent,4); + tangent->RepeatWrite(xy_tangent,4); } { @@ -218,82 +241,103 @@ namespace hgl xy_tex_coord[2]=xy_tex_coord[4]=pci->tile.x; xy_tex_coord[5]=xy_tex_coord[7]=pci->tile.y; - tex_coord->BufferData(xy_tex_coord); + tex_coord->Write(xy_tex_coord); } } return rc.Finish(); } - vulkan::Renderable *CreateRenderableCube(vulkan::Database *db,vulkan::Material *mtl,const CubeCreateInfo *cci) - { // Points of a cube. - /* 4 5 */ const float points[]={ -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, +0.5f, +0.5f, -0.5f, +0.5f, +0.5f, -0.5f, -0.5f, -0.5f, +0.5f, -0.5f, -0.5f, +0.5f, +0.5f, - /* *------------* */ +0.5f, +0.5f, +0.5f, +0.5f, +0.5f, -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, +0.5f, -0.5f, +0.5f, +0.5f, -0.5f, +0.5f, -0.5f, -0.5f, - /* /| /| */ -0.5f, -0.5f, +0.5f, -0.5f, +0.5f, +0.5f, +0.5f, +0.5f, +0.5f, +0.5f, -0.5f, +0.5f, -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, +0.5f, - /* 0/ | 1/ | */ -0.5f, +0.5f, +0.5f, -0.5f, +0.5f, -0.5f, +0.5f, -0.5f, -0.5f, +0.5f, -0.5f, +0.5f, +0.5f, +0.5f, +0.5f, +0.5f, +0.5f, -0.5f }; - /* *--+---------* | */ // Normals of a cube. - /* | | | | */ const float normals[]={ +0.0f, -1.0f, +0.0f, +0.0f, -1.0f, +0.0f, +0.0f, -1.0f, +0.0f, +0.0f, -1.0f, +0.0f, +0.0f, +1.0f, +0.0f, +0.0f, +1.0f, +0.0f, - /* | 7| | 6| */ +0.0f, +1.0f, +0.0f, +0.0f, +1.0f, +0.0f, +0.0f, +0.0f, -1.0f, +0.0f, +0.0f, -1.0f, +0.0f, +0.0f, -1.0f, +0.0f, +0.0f, -1.0f, - /* | *---------+--* */ +0.0f, +0.0f, +1.0f, +0.0f, +0.0f, +1.0f, +0.0f, +0.0f, +1.0f, +0.0f, +0.0f, +1.0f, -1.0f, +0.0f, +0.0f, -1.0f, +0.0f, +0.0f, - /* | / | / */ -1.0f, +0.0f, +0.0f, -1.0f, +0.0f, +0.0f, +1.0f, +0.0f, +0.0f, +1.0f, +0.0f, +0.0f, +1.0f, +0.0f, +0.0f, +1.0f, +0.0f, +0.0f }; - /* |/ 2|/ */ // The associated indices. - /* 3*------------* */ const uint16 indices[]={ 0, 2, 1, 0, 3, 2, 4, 5, 6, 4, 6, 7, 8, 9, 10, 8, 10, 11, 12, 15, 14, 12, 14, 13, 16, 17, 18, 16, 18, 19, 20, 23, 22, 20, 22, 21 }; + Renderable *CreateRenderableCube(RenderResource *db,const VAB *vab,const CubeCreateInfo *cci) + { + /** + * 4 5 + * *------------* Z Y + * /| /| | Y | Z + * 0/ | 1/ | | / | / + * *--+---------* | | / | / + * | | | | | / | / + * | 7| | 6| |/ |/ + * | *---------+--* *-----------X *-----------X + * | / | / + * |/ 2|/ my Cubemap + * 3*------------* + * + * 注:cubemap纹理坐标系依然遵循OpenGL时代定下的坐标系,所以这里的position虽然使用vulkan坐标系,但在shader中当做cubemap纹理坐标使用时,需要在shader中转换为opengl坐标系(交换yz即可) + */ - const float tangents[] = { +1.0f, 0.0f, 0.0f, +1.0f, 0.0f, 0.0f, +1.0f, 0.0f, 0.0f, +1.0f, 0.0f, 0.0f, +1.0f, 0.0f, 0.0f, +1.0f, 0.0f, 0.0f, - +1.0f, 0.0f, 0.0f, +1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, - +1.0f, 0.0f, 0.0f, +1.0f, 0.0f, 0.0f, +1.0f, 0.0f, 0.0f, +1.0f, 0.0f, 0.0f, 0.0f, 0.0f,+1.0f, 0.0f, 0.0f,+1.0f, - 0.0f, 0.0f,+1.0f, 0.0f, 0.0f,+1.0f, 0.0f, 0.0f,-1.0f, 0.0f, 0.0f,-1.0f, 0.0f, 0.0f,-1.0f, 0.0f, 0.0f,-1.0f }; + constexpr float positions[]={ -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, +0.5f, +0.5f, -0.5f, +0.5f, +0.5f, -0.5f, -0.5f, + -0.5f, +0.5f, -0.5f, -0.5f, +0.5f, +0.5f, +0.5f, +0.5f, +0.5f, +0.5f, +0.5f, -0.5f, + -0.5f, -0.5f, -0.5f, -0.5f, +0.5f, -0.5f, +0.5f, +0.5f, -0.5f, +0.5f, -0.5f, -0.5f, + -0.5f, -0.5f, +0.5f, -0.5f, +0.5f, +0.5f, +0.5f, +0.5f, +0.5f, +0.5f, -0.5f, +0.5f, + -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, +0.5f, -0.5f, +0.5f, +0.5f, -0.5f, +0.5f, -0.5f, + +0.5f, -0.5f, -0.5f, +0.5f, -0.5f, +0.5f, +0.5f, +0.5f, +0.5f, +0.5f, +0.5f, -0.5f}; - const float tex_coords[] ={ 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, - 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, - 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f }; + constexpr float normals[]={ +0.0f, +1.0f, +0.0f, +0.0f, +1.0f, +0.0f, +0.0f, +1.0f, +0.0f, +0.0f, +1.0f, +0.0f, + +0.0f, -1.0f, +0.0f, +0.0f, -1.0f, +0.0f, +0.0f, -1.0f, +0.0f, +0.0f, -1.0f, +0.0f, + +0.0f, -0.0f, -1.0f, +0.0f, -0.0f, -1.0f, +0.0f, -0.0f, -1.0f, +0.0f, -0.0f, -1.0f, + +0.0f, -0.0f, +1.0f, +0.0f, -0.0f, +1.0f, +0.0f, -0.0f, +1.0f, +0.0f, -0.0f, +1.0f, + -1.0f, -0.0f, +0.0f, -1.0f, -0.0f, +0.0f, -1.0f, -0.0f, +0.0f, -1.0f, -0.0f, +0.0f, + +1.0f, -0.0f, +0.0f, +1.0f, -0.0f, +0.0f, +1.0f, -0.0f, +0.0f, +1.0f, -0.0f, +0.0f}; - RenderableCreater rc(db,mtl); + constexpr float tangents[] = { +1.0f, 0.0f, 0.0f, +1.0f, 0.0f, 0.0f, +1.0f, 0.0f, 0.0f, +1.0f, 0.0f, 0.0f, + +1.0f, 0.0f, 0.0f, +1.0f, 0.0f, 0.0f, +1.0f, 0.0f, 0.0f, +1.0f, 0.0f, 0.0f, + -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, + +1.0f, 0.0f, 0.0f, +1.0f, 0.0f, 0.0f, +1.0f, 0.0f, 0.0f, +1.0f, 0.0f, 0.0f, + 0.0f, 0.0f,+1.0f, 0.0f, 0.0f,+1.0f, 0.0f, 0.0f,+1.0f, 0.0f, 0.0f,+1.0f, + 0.0f, 0.0f,-1.0f, 0.0f, 0.0f,-1.0f, 0.0f, 0.0f,-1.0f, 0.0f, 0.0f,-1.0f}; + + constexpr float tex_coords[] ={ 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, + 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, + 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, + 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, + 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f}; + // The associated indices. + constexpr uint16 indices[]={ 0, 2, 1, 0, 3, 2, + 4, 5, 6, 4, 6, 7, + 8, 9, 10, 8, 10, 11, + 12, 15, 14, 12, 14, 13, + 16, 17, 18, 16, 18, 19, + 20, 23, 22, 20, 22, 21}; + + RenderableCreater rc(db,vab); if(!rc.Init(24)) return(nullptr); - if(cci->center ==Vector3f(0,0,0) - &&cci->size ==Vector3f(1,1,1)) - { - rc.WriteVAD(VAN::Position,points,sizeof(points)); - } - else - { - const float *sp=points; - AutoDelete vertex=rc.CreateVADA(VAN::Position); - float *vp=vertex->Get(); - - for(uint i=0;i<24;i++) - { - *vp=cci->center.x+(*sp)*cci->size.x; ++vp;++sp; - *vp=cci->center.y+(*sp)*cci->size.y; ++vp;++sp; - *vp=cci->center.z+(*sp)*cci->size.z; ++vp;++sp; - } - } + rc.WriteVAD(VAN::Position,positions,sizeof(positions)); + if(cci->normal) rc.WriteVAD(VAN::Normal,normals,sizeof(normals)); + + if(cci->tangent) rc.WriteVAD(VAN::Tangent,tangents,sizeof(tangents)); - if(cci->tile.x==1&&cci->tile.y==1) - { - rc.WriteVAD(VAN::TexCoord,tex_coords,sizeof(tex_coords)); - } - else - { - AutoDelete tex_coord=rc.CreateVADA(VAN::TexCoord); + if(cci->tex_coord) + rc.WriteVAD(VAN::TexCoord,tex_coords,sizeof(tex_coords)); - if(tex_coord) + if(cci->color_type!=CubeCreateInfo::ColorType::NoColor) + { + ENUM_CLASS_RANGE_ERROR_RETURN_NULLPTR(cci->color_type); + + AutoDelete color=rc.CreateVADA(VAN::Color); + + if(color) { - float *tcp=tex_coord->Get(); - - const float *tcs=tex_coords; - - for(uint i=0;i<24;i++) + if(cci->color_type==CubeCreateInfo::ColorType::SameColor) + color->RepeatWrite(cci->color[0],24); + else + if(cci->color_type==CubeCreateInfo::ColorType::FaceColor) { - *tcp=(*tcs)*cci->tile.x;++tcs;++tcp; - *tcp=(*tcs)*cci->tile.y;++tcs;++tcp; + for(uint face=0;face<6;face++) + color->RepeatWrite(cci->color[face],4); } + else + if(cci->color_type==CubeCreateInfo::ColorType::VertexColor) + color->Write(cci->color,24); + else + return(nullptr); } } @@ -327,7 +371,7 @@ namespace hgl void glusQuaternionRotateRyf(float quaternion[4], const float angle) { - float halfAngleRadian = hgl_ang2rad(angle) * 0.5f; + float halfAngleRadian = deg2rad(angle) * 0.5f; quaternion[0] = 0.0f; quaternion[1] = sin(halfAngleRadian); @@ -337,7 +381,7 @@ namespace hgl void glusQuaternionRotateRzf(float quaternion[4], const float angle) { - float halfAngleRadian = hgl_ang2rad(angle) * 0.5f; + float halfAngleRadian = deg2rad(angle) * 0.5f; quaternion[0] = 0.0f; quaternion[1] = 0.0f; @@ -396,9 +440,9 @@ namespace hgl * @param numberSlices 切片数 * @return 可渲染数据 */ - vulkan::Renderable *CreateRenderableSphere(vulkan::Database *db,vulkan::Material *mtl,const uint numberSlices) + Renderable *CreateRenderableSphere(RenderResource *db,const VAB *vab,const uint numberSlices) { - RenderableCreater rc(db,mtl); + RenderableCreater rc(db,vab); uint numberParallels = (numberSlices+1) / 2; uint numberVertices = (numberParallels + 1) * (numberSlices + 1); @@ -439,9 +483,9 @@ namespace hgl if(np) { - *np=x;++np; - *np=y;++np; - *np=z;++np; + *np=+x;++np; + *np=-y;++np; + *np=+z;++np; } if(tcp) @@ -472,9 +516,9 @@ namespace hgl return rc.Finish(); } - vulkan::Renderable *CreateRenderableDome(vulkan::Database *db,vulkan::Material *mtl,const DomeCreateInfo *dci) + Renderable *CreateRenderableDome(RenderResource *db,const VAB *vab,const DomeCreateInfo *dci) { - RenderableCreater rc(db,mtl); + RenderableCreater rc(db,vab); uint i, j; @@ -591,9 +635,9 @@ namespace hgl } }//namespace - vulkan::Renderable *CreateRenderableTorus(vulkan::Database *db,vulkan::Material *mtl,const TorusCreateInfo *tci) + Renderable *CreateRenderableTorus(RenderResource *db,const VAB *vab,const TorusCreateInfo *tci) { - RenderableCreater rc(db,mtl); + RenderableCreater rc(db,vab); // s, t = parametric values of the equations, in the range [0,1] float s = 0; @@ -665,16 +709,16 @@ namespace hgl // generate normal and stores it in the right position // NOTE: cos (2PIx) = cos (x) and sin (2PIx) = sin (x) so, we can use this formula // normal = {cos(2PIs)cos(2PIt) , sin(2PIs)cos(2PIt) ,sin(2PIt)} - *np = cos2PIs * cos2PIt; ++np; - *np = sin2PIt; ++np; - *np = sin2PIs * cos2PIt; ++np; + *np = +cos2PIs * cos2PIt; ++np; + *np = -sin2PIt; ++np; + *np = +sin2PIs * cos2PIt; ++np; } if(tcp) { // generate texture coordinates and stores it in the right position - *tcp = s; ++tcp; - *tcp = t; ++tcp; + *tcp = s*tci->uv_scale.x; ++tcp; + *tcp = t*tci->uv_scale.y; ++tcp; } if(tp) @@ -709,7 +753,7 @@ namespace hgl for (i = 0; i < numberSlices; i++) { - *tp = centerIndex; ++tp; + *tp = centerIndex; ++tp; *tp = indexCounter; ++tp; *tp = indexCounter + 1; ++tp; @@ -723,7 +767,7 @@ namespace hgl for (i = 0; i < numberSlices; i++) { - *tp = centerIndex; ++tp; + *tp = centerIndex; ++tp; *tp = indexCounter + 1; ++tp; *tp = indexCounter; ++tp; @@ -734,11 +778,11 @@ namespace hgl // Sides for (i = 0; i < numberSlices; i++) { - *tp = indexCounter; ++tp; + *tp = indexCounter; ++tp; *tp = indexCounter + 1; ++tp; *tp = indexCounter + 2; ++tp; - *tp = indexCounter + 2; ++tp; + *tp = indexCounter + 2; ++tp; *tp = indexCounter + 1; ++tp; *tp = indexCounter + 3; ++tp; @@ -747,14 +791,14 @@ namespace hgl } }//namespace - vulkan::Renderable *CreateRenderableCylinder(vulkan::Database *db,vulkan::Material *mtl,const CylinderCreateInfo *cci) + Renderable *CreateRenderableCylinder(RenderResource *db,const VAB *vab,const CylinderCreateInfo *cci) { uint numberIndices = cci->numberSlices * 3 * 2 + cci->numberSlices * 6; if(numberIndices<=0) return(nullptr); - RenderableCreater rc(db,mtl); + RenderableCreater rc(db,vab); uint numberVertices = (cci->numberSlices + 2) * 2 + (cci->numberSlices + 1) * 2; @@ -802,11 +846,11 @@ namespace hgl for(uint i = 0; i < cci->numberSlices + 1; i++) { - float currentAngle = angleStep * (float)i; + float currentAngle = angleStep * (float)i; - *vp = cos(currentAngle) * cci->radius; ++vp; - *vp = -sin(currentAngle) * cci->radius; ++vp; - *vp = -cci->halfExtend; ++vp; + *vp = cos(currentAngle) * cci->radius; ++vp; + *vp = -sin(currentAngle) * cci->radius; ++vp; + *vp = -cci->halfExtend; ++vp; if(np) { @@ -855,11 +899,11 @@ namespace hgl for(uint i = 0; i < cci->numberSlices + 1; i++) { - float currentAngle = angleStep * (float)i; + float currentAngle = angleStep * (float)i; - *vp = cos(currentAngle) * cci->radius; ++vp; - *vp = -sin(currentAngle) * cci->radius; ++vp; - *vp = cci->halfExtend; ++vp; + *vp = cos(currentAngle) * cci->radius; ++vp; + *vp = -sin(currentAngle) * cci->radius; ++vp; + *vp = cci->halfExtend; ++vp; if(np) { @@ -884,37 +928,37 @@ namespace hgl for(uint i = 0; i < cci->numberSlices + 1; i++) { - float currentAngle = angleStep * (float)i; + float currentAngle = angleStep * (float)i; - float sign = -1.0f; + float sign = -1.0f; - for (uint j = 0; j < 2; j++) + for (uint j = 0; j < 2; j++) { - *vp = cos(currentAngle) * cci->radius; ++vp; - *vp = -sin(currentAngle) * cci->radius; ++vp; - *vp = cci->halfExtend * sign; ++vp; + *vp = cos(currentAngle) * cci->radius; ++vp; + *vp = -sin(currentAngle) * cci->radius; ++vp; + *vp = cci->halfExtend * sign; ++vp; if(np) { - *np = cos(currentAngle); ++np; - *np = -sin(currentAngle); ++np; - *np = 0.0f; ++np; + *np = cos(currentAngle); ++np; + *np = sin(currentAngle); ++np; + *np = 0.0f; ++np; } if(tp) { - *tp = -sin(currentAngle); ++tp; - *tp = -cos(currentAngle); ++tp; - *tp = 0.0f; ++tp; + *tp = -sin(currentAngle); ++tp; + *tp = -cos(currentAngle); ++tp; + *tp = 0.0f; ++tp; } if(tcp) { - *tcp = (float)i / (float)cci->numberSlices; ++tcp; - *tcp = (sign + 1.0f) / 2.0f; ++tcp; + *tcp = (float)i / (float)cci->numberSlices; ++tcp; + *tcp = (sign + 1.0f) / 2.0f; ++tcp; } - sign = 1.0f; + sign = 1.0f; } } @@ -938,7 +982,7 @@ namespace hgl for (i = 0; i < numberSlices; i++) { - *tp = centerIndex; ++tp; + *tp = centerIndex; ++tp; *tp = indexCounter; ++tp; *tp = indexCounter + 1; ++tp; @@ -947,28 +991,28 @@ namespace hgl indexCounter++; // Sides - for (j = 0; j < numberStacks; j++) - { - for (i = 0; i < numberSlices; i++) - { - *tp = indexCounter; ++tp; - *tp = indexCounter + numberSlices + 1; ++tp; - *tp = indexCounter + 1; ++tp; + for (j = 0; j < numberStacks; j++) + { + for (i = 0; i < numberSlices; i++) + { + *tp = indexCounter; ++tp; + *tp = indexCounter + numberSlices + 1; ++tp; + *tp = indexCounter + 1; ++tp; - *tp = indexCounter + 1; ++tp; - *tp = indexCounter + numberSlices + 1; ++tp; - *tp = indexCounter + numberSlices + 2; ++tp; + *tp = indexCounter + 1; ++tp; + *tp = indexCounter + numberSlices + 1; ++tp; + *tp = indexCounter + numberSlices + 2; ++tp; - indexCounter++; - } - indexCounter++; + indexCounter++; + } + indexCounter++; } } }//namespace - vulkan::Renderable *CreateRenderableCone(vulkan::Database *db,vulkan::Material *mtl,const ConeCreateInfo *cci) + Renderable *CreateRenderableCone(RenderResource *db,const VAB *vab,const ConeCreateInfo *cci) { - RenderableCreater rc(db,mtl); + RenderableCreater rc(db,vab); uint i, j; @@ -1024,63 +1068,63 @@ namespace hgl for (i = 0; i < cci->numberSlices + 1; i++) { - float currentAngle = angleStep * (float)i; + float currentAngle = angleStep * (float)i; - *vp = cos(currentAngle) * cci->radius; ++vp; - *vp = -sin(currentAngle) * cci->radius; ++vp; - *vp = -cci->halfExtend; ++vp; + *vp = cos(currentAngle) * cci->radius; ++vp; + *vp = -sin(currentAngle) * cci->radius; ++vp; + *vp = -cci->halfExtend; ++vp; if(np) { - *np = 0.0f;++np; - *np = 0.0f;++np; - *np =-1.0f;++np; + *np = 0.0f;++np; + *np = 0.0f;++np; + *np =-1.0f;++np; } if(tp) { - *tp = sin(currentAngle); ++tp; - *tp = cos(currentAngle); ++tp; - *tp = 0.0f; ++tp; + *tp = sin(currentAngle); ++tp; + *tp = cos(currentAngle); ++tp; + *tp = 0.0f; ++tp; } if(tcp) { - *tcp = 0.0f; ++tcp; - *tcp = 0.0f; ++tcp; + *tcp = 0.0f; ++tcp; + *tcp = 0.0f; ++tcp; } } - for (j = 0; j < cci->numberStacks + 1; j++) + for (j = 0; j < cci->numberStacks + 1; j++) { - float level = (float)j / (float)cci->numberStacks; + float level = (float)j / (float)cci->numberStacks; - for (i = 0; i < cci->numberSlices + 1; i++) - { - float currentAngle = angleStep * (float)i; + for (i = 0; i < cci->numberSlices + 1; i++) + { + float currentAngle = angleStep * (float)i; - *vp = cos(currentAngle) * cci->radius * (1.0f - level); ++vp; - *vp = -sin(currentAngle) * cci->radius * (1.0f - level); ++vp; - *vp = -cci->halfExtend + 2.0f * cci->halfExtend * level; ++vp; + *vp = cos(currentAngle) * cci->radius * (1.0f - level); ++vp; + *vp = -sin(currentAngle) * cci->radius * (1.0f - level); ++vp; + *vp = -cci->halfExtend + 2.0f * cci->halfExtend * level; ++vp; if(np) { - *np = h / l * cos(currentAngle); ++np; - *np = h / l * -sin(currentAngle); ++np; - *np = r / l; ++np; + *np = h / l * cos(currentAngle); ++np; + *np = h / l * sin(currentAngle); ++np; + *np = r / l; ++np; } if(tp) { - *tp = -sin(currentAngle); ++tp; - *tp = -cos(currentAngle); ++tp; - *tp = 0.0f; ++tp; + *tp = -sin(currentAngle); ++tp; + *tp = -cos(currentAngle); ++tp; + *tp = 0.0f; ++tp; } if(tcp) { - *tcp = (float)i / (float)cci->numberSlices; ++tcp; - *tcp = level; ++tcp; + *tcp = (float)i / (float)cci->numberSlices; ++tcp; + *tcp = level; ++tcp; } } } @@ -1093,9 +1137,11 @@ namespace hgl return rc.Finish(); } - vulkan::Renderable *CreateRenderableAxis(vulkan::Database *db,vulkan::Material *mtl,const AxisCreateInfo *aci) + Renderable *CreateRenderableAxis(RenderResource *db,const VAB *vab,const AxisCreateInfo *aci) { - RenderableCreater rc(db,mtl); + if(!db||!vab||!aci)return(nullptr); + + RenderableCreater rc(db,vab); if(!rc.Init(6)) return(nullptr); @@ -1106,19 +1152,19 @@ namespace hgl if(!vertex||!color) return(nullptr); - vertex->Write(aci->root);color->Write(aci->color[0]); - vertex->Write(aci->root.x+aci->size[0],aci->root.y,aci->root.z);color->Write(aci->color[0]); + const float s=aci->size; - vertex->Write(aci->root);color->Write(aci->color[1]); - vertex->Write(aci->root.x,aci->root.y+aci->size[1],aci->root.z);color->Write(aci->color[1]); - - vertex->Write(aci->root);color->Write(aci->color[2]); - vertex->Write(aci->root.x,aci->root.y,aci->root.z+aci->size[2]);color->Write(aci->color[2]); + vertex->Write(0,0,0);color->Write(aci->color[0]); + vertex->Write(s,0,0);color->Write(aci->color[0]); + vertex->Write(0,0,0);color->Write(aci->color[1]); + vertex->Write(0,s,0);color->Write(aci->color[1]); + vertex->Write(0,0,0);color->Write(aci->color[2]); + vertex->Write(0,0,s);color->Write(aci->color[2]); return rc.Finish(); } - vulkan::Renderable *CreateRenderableBoundingBox(vulkan::Database *db,vulkan::Material *mtl,const CubeCreateInfo *cci) + Renderable *CreateRenderableBoundingBox(RenderResource *db,const VAB *vab,const BoundingBoxCreateInfo *cci) { // Points of a cube. /* 4 5 */ const float points[]={ -0.5,-0.5, 0.5, 0.5,-0.5,0.5, 0.5,-0.5,-0.5, -0.5,-0.5,-0.5, @@ -1140,7 +1186,7 @@ namespace hgl 0,4, 1,5, 2,6, 3,7 }; - RenderableCreater rc(db,mtl); + RenderableCreater rc(db,vab); if(!rc.Init(8)) return(nullptr); @@ -1149,36 +1195,21 @@ namespace hgl if(!vertex)return(nullptr); - if(cci->center ==Vector3f(0,0,0) - &&cci->size ==Vector3f(1,1,1)) - { - rc.WriteVAD(VAN::Position,points,sizeof(points)); - } - else - { - const float *sp=points; - float *vp=vertex->Get(); + rc.WriteVAD(VAN::Position,points,sizeof(points)); - for(uint i=0;i<8;i++) - { - *vp=cci->center.x+(*sp)*cci->size.x; ++vp;++sp; - *vp=cci->center.y+(*sp)*cci->size.y; ++vp;++sp; - *vp=cci->center.z+(*sp)*cci->size.z; ++vp;++sp; - } - } - - if(cci->has_color) + if(cci->color_type!=BoundingBoxCreateInfo::ColorType::NoColor) { + ENUM_CLASS_RANGE_ERROR_RETURN_NULLPTR(cci->color_type); + AutoDelete color=rc.CreateVADA(VAN::Color); - float *color_pointer=color->Get(); - if(color_pointer) + if(color) { - for(uint i=0;i<8;i++) - { - memcpy(color_pointer,&(cci->color),4*sizeof(float)); - color_pointer+=4; - } + if(cci->color_type==BoundingBoxCreateInfo::ColorType::SameColor) + color->RepeatWrite(cci->color[0],8); + else + if(cci->color_type==BoundingBoxCreateInfo::ColorType::VertexColor) + color->Write(cci->color,8); } } diff --git a/src/SceneGraph/RenderList.cpp b/src/SceneGraph/RenderList.cpp index c510b90e..d6acfb3f 100644 --- a/src/SceneGraph/RenderList.cpp +++ b/src/SceneGraph/RenderList.cpp @@ -1,69 +1,273 @@ #include #include #include -#include -#include +#include +#include +#include #include -#include -#include +#include +#include +#include + +/** +* 理论上讲,我们需要按以下顺序排序 +* +* for(pipeline) +* for(material_instance) +* for(vbo) +* for(distance) +*/ + +template<> +int Comparator::compare(const RenderNodePointer &obj_one,const RenderNodePointer &obj_two) const +{ + int off; + + hgl::graph::RenderableInstance *ri_one=obj_one->ri; + hgl::graph::RenderableInstance *ri_two=obj_two->ri; + + //比较管线 + { + off=ri_one->GetPipeline() + -ri_two->GetPipeline(); + + if(off) + return off; + } + + //比较材质实例 + { + for(int i =(int)hgl::graph::DescriptorSetsType::BEGIN_RANGE; + i<=(int)hgl::graph::DescriptorSetsType::END_RANGE; + i++) + { + off=ri_one->GetMP((hgl::graph::DescriptorSetsType)i) + -ri_two->GetMP((hgl::graph::DescriptorSetsType)i); + + if(off) + return off; + } + } + + //比较vbo+ebo + { + off=ri_one->GetBufferHash() + -ri_two->GetBufferHash(); + + if(off) + return off; + } + + //比较距离 + { + const double dist=obj_one->distance_to_camera_square- + obj_two->distance_to_camera_square; + + //由于距离差距可能会小于1,但又返回int,所以需要做如此处理 + + if(dist>0)return 1;else + if(dist<0)return -1; + } + + return 0; +} namespace hgl { namespace graph { - float CameraLengthComp(Camera *cam,SceneNode *obj_one,SceneNode *obj_two) + RenderList::RenderList(GPUDevice *dev) { - if(!cam||!obj_one||!obj_two) - return(0); + device =dev; + cmd_buf =nullptr; + + hgl_zero(camera_info); - return( length_squared(obj_one->GetCenter(),cam->eye)- - length_squared(obj_two->GetCenter(),cam->eye)); + mvp_array =new MVPArrayBuffer(device,VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT); + + ubo_offset =0; + ubo_align =0; + + last_pipeline =nullptr; + hgl_zero(last_mp); + last_vbo =0; } - //bool FrustumClipFilter(const SceneNode *node,void *fc) - //{ - // if(!node||!fc)return(false); + RenderList::~RenderList() + { + delete mvp_array; + } - // return (((Frustum *)fc)->BoxIn(node->GetWorldBoundingBox())!=Frustum::OUTSIDE); - //} + bool RenderList::Begin() + { + render_node_list.ClearData(); + mvp_array->Clear(); + ri_list.ClearData(); - void RenderList::Render(SceneNode *node,RenderableInstance *ri) + material_sets.ClearData(); + + return(true); + } + + void RenderList::End() + { + if(render_node_list.GetCount()<=0)return; + + //排序 + Sort(render_node_list,&render_node_comparator); + + //产生MVP矩阵UBO数据 + { + const uint32_t count=render_node_list.GetCount(); + + { + //按当前总节点数量分配UBO + mvp_array->Alloc(count); + mvp_array->Clear(); + + ri_list.ClearData(); + ri_list.SetCount(count); + } + + { + ubo_align=mvp_array->GetUnitSize(); + + char *mp=(char *)(mvp_array->Map(0,count)); + RenderableInstance **ri=ri_list.GetData(); + + for(RenderNode *node:render_node_list) //未来可能要在Expend处考虑做去重 + { + memcpy(mp,&(node->matrix),MVPMatrixBytes); + mp+=ubo_align; + + (*ri)=node->ri; + ++ri; + } + + mvp_array->Flush(count); + } + } + + //为所有的材质绑定 + for(Material *mtl:material_sets) + { + MaterialParameters *mp=mtl->GetMP(DescriptorSetsType::Renderable); + + if(mp) + { + if(mp->BindUBO("r_scene_info",mvp_array->GetBuffer(),true)) + mp->Update(); + } + } + } + + bool RenderList::Expend(SceneNode *sn) + { + if(!sn)return(false); + + RenderableInstance *ri=sn->GetRI(); + + if(ri) + { + RenderNode *rn=new RenderNode; + + rn->matrix.Set(sn->GetLocalToWorldMatrix(),camera_info.vp,camera_info.view); + + rn->WorldCenter=sn->GetWorldCenter(); + + rn->distance_to_camera_square=length_squared(rn->WorldCenter,camera_info.pos); +// rn->distance_to_camera=sqrtf(rn->distance_to_camera_square); + + rn->ri=ri; + + render_node_list.Add(rn); + + material_sets.Add(ri->GetMaterial()); + } + + for(SceneNode *sub:sn->SubNode) + Expend(sub); + + return(true); + } + + bool RenderList::Expend(const CameraInfo &ci,SceneNode *sn) + { + if(!device|!sn)return(false); + + camera_info=ci; + + Begin(); + Expend(sn); + End(); + + return(true); + } + + void RenderList::Render(RenderableInstance *ri) { if(last_pipeline!=ri->GetPipeline()) { last_pipeline=ri->GetPipeline(); - cmd_buf->Bind(last_pipeline); - - last_mat_inst=nullptr; + cmd_buf->BindPipeline(last_pipeline); } - if(last_mat_inst!=ri->GetMaterialInstance()) { - last_mat_inst=ri->GetMaterialInstance(); + uint32_t ds_count=0; + uint32_t first_set=0; + MaterialParameters *mp; - cmd_buf->Bind(last_mat_inst->GetDescriptorSets()); + for(int i=(int)DescriptorSetsType::BEGIN_RANGE; + i<(int)DescriptorSetsType::Renderable; + i++) + { + mp=ri->GetMP((DescriptorSetsType)i); + + if(last_mp[i]!=mp) + { + last_mp[i]=mp; + + if(mp) + { + ds_list[ds_count]=mp->GetVkDescriptorSet(); + ++ds_count; + } + } + else + { + if(mp) + ++first_set; + } + } + + { + mp=ri->GetMP(DescriptorSetsType::Renderable); + + if(mp) + { + ds_list[ds_count]=mp->GetVkDescriptorSet(); + ++ds_count; + + cmd_buf->BindDescriptorSets(ri->GetPipelineLayout(),first_set,ds_list,ds_count,&ubo_offset,1); + } + else + { + cmd_buf->BindDescriptorSets(ri->GetPipelineLayout(),first_set,ds_list,ds_count,nullptr,0); + } + + ubo_offset+=ubo_align; + } } - if(last_pc!=node->GetPushConstant()) + if(last_vbo!=ri->GetBufferHash()) { - last_pc=node->GetPushConstant(); - - cmd_buf->PushConstants(last_pc,sizeof(vulkan::PushConstant)); + last_vbo=ri->GetBufferHash(); + + cmd_buf->BindVBO(ri); } - //更新fin_mvp - - vulkan::Renderable *obj=ri->GetRenderable(); - - if(obj!=last_renderable) - { - cmd_buf->Bind(obj); - - last_renderable=obj; - } - - const vulkan::IndexBuffer *ib=obj->GetIndexBuffer(); + const IndexBuffer *ib=ri->GetIndexBuffer(); if(ib) { @@ -71,42 +275,27 @@ namespace hgl } else { - cmd_buf->Draw(obj->GetDrawCount()); + cmd_buf->Draw(ri->GetDrawCount()); } } - void RenderList::Render(SceneNode *node,List &ri_list) - { - const int count=ri_list.GetCount(); - RenderableInstance **ri=ri_list.GetData(); - - for(int i=0;irenderable_instances); - ++node; - } + for(RenderableInstance *ri:ri_list) + Render(ri); return(true); } diff --git a/src/SceneGraph/RenderableCreater.cpp b/src/SceneGraph/RenderableCreater.cpp index a9056eb4..36ac8ebc 100644 --- a/src/SceneGraph/RenderableCreater.cpp +++ b/src/SceneGraph/RenderableCreater.cpp @@ -1,15 +1,14 @@ #include -#include +#include namespace hgl { namespace graph { - RenderableCreater::RenderableCreater(vulkan::Database *sdb,vulkan::Material *m) + RenderableCreater::RenderableCreater(RenderResource *sdb,const VAB *v) { db =sdb; - mtl =m; - vsm =mtl->GetVertexShaderModule(); + vab =v; vertices_number =0; ibo =nullptr; @@ -24,70 +23,68 @@ namespace hgl return(true); } - VAD *RenderableCreater::CreateVAD(const AnsiString &name,const vulkan::ShaderStage *ss) + VAD *RenderableCreater::CreateVAD(const AnsiString &name) { - if(!ss)return(nullptr); + if(!vab)return(nullptr); + if(name.IsEmpty())return(nullptr); + + const auto *va=vab->GetVertexAttribute(name); + + if(!va) + return(nullptr); ShaderStageBind *ssb; - if(vab_maps.Get(name,ssb)) + if(ssb_map.Get(name,ssb)) return ssb->data; + VAD *vad=hgl::graph::CreateVertexAttribData(vertices_number,va->format,va->vec_size,va->stride); + + if(!vad) + return(nullptr); + ssb=new ShaderStageBind; - ssb->data =hgl::graph::CreateVertexAttribData(&(ss->type),vertices_number); + ssb->data =vad; ssb->name =name; - ssb->binding=ss->binding; + ssb->binding=va->binding; - ssb->vab =nullptr; + ssb->vbo =nullptr; - vab_maps.Add(name,ssb); + ssb_map.Add(name,ssb); return ssb->data; } - VAD *RenderableCreater::CreateVAD(const AnsiString &name) - { - if(!vsm)return(nullptr); - if(name.IsEmpty())return(nullptr); - - const vulkan::ShaderStage *ss=vsm->GetStageInput(name); - - if(!ss) - return(nullptr); - - return this->CreateVAD(name,ss); - } - bool RenderableCreater::WriteVAD(const AnsiString &name,const void *data,const uint32_t bytes) { - if(!vsm)return(false); + if(!vab)return(false); if(name.IsEmpty())return(false); if(!data)return(false); if(!bytes)return(false); ShaderStageBind *ssb; - if(vab_maps.Get(name,ssb)) + if(ssb_map.Get(name,ssb)) return false; - const vulkan::ShaderStage *ss=vsm->GetStageInput(name); + const auto *va=vab->GetVertexAttribute(name); - if(!ss) + if(!va) return(false); - if(ss->type.GetStride()*vertices_number!=bytes) + if(va->stride*vertices_number!=bytes) return(false); ssb=new ShaderStageBind; ssb->data =nullptr; ssb->name =name; - ssb->binding=ss->binding; + ssb->binding=va->binding; - ssb->vab =db->CreateVAB(ss->format,vertices_number,data); + ssb->vbo =db->CreateVBO(va->format,vertices_number,data); - vab_maps.Add(name,ssb); + ssb_map.Add(name,ssb); return true; } @@ -108,22 +105,22 @@ namespace hgl return (uint32 *)ibo->Map(); } - vulkan::Renderable *RenderableCreater::Finish() + Renderable *RenderableCreater::Finish() { - const uint si_count=vsm->GetStageInputCount(); + const uint si_count=vab->GetVertexAttrCount(); - if(vab_maps.GetCount()!=si_count) + if(ssb_map.GetCount()!=si_count) return(nullptr); - vulkan::Renderable *render_obj=mtl->CreateRenderable(vertices_number); + Renderable *render_obj=db->CreateRenderable(vertices_number); - const auto *sp=vab_maps.GetDataList(); + const auto *sp=ssb_map.GetDataList(); for(uint i=0;iright->vab) - render_obj->Set((*sp)->right->binding,(*sp)->right->vab); + if((*sp)->right->vbo) + render_obj->Set((*sp)->left,(*sp)->right->vbo); else - render_obj->Set((*sp)->right->binding,db->CreateVAB((*sp)->right->data)); + render_obj->Set((*sp)->left,db->CreateVBO((*sp)->right->data)); ++sp; } diff --git a/src/SceneGraph/SceneNode.cpp b/src/SceneGraph/SceneNode.cpp index 700cbda7..e1352362 100644 --- a/src/SceneGraph/SceneNode.cpp +++ b/src/SceneGraph/SceneNode.cpp @@ -1,9 +1,27 @@ #include #include +#include namespace hgl { namespace graph { + void SceneNode::SetRI(RenderableInstance *ri) + { + render_obj=ri; + + if(render_obj) + { + SetBoundingBox(render_obj->GetBoundingBox()); + } + else + { + BoundingBox.minPoint=Vector3f(0,0,0); + BoundingBox.maxPoint=Vector3f(0,0,0); + + WorldBoundingBox=LocalBoundingBox=BoundingBox; + } + } + /** * 刷新矩阵 * @param root_matrix 根矩阵 @@ -51,64 +69,63 @@ namespace hgl } LocalBoundingBox=local; - } - /** - * 从当前节点展开输出到一个渲染列表 - * @param rl 渲染列表 - * @param func 过滤函数 - * @param func_data 过滤函数用辅助数据 - * @return 成功与否 - */ - bool SceneNode::ExpendToList(RenderList *rl,FilterSceneNodeFunc func,void *func_data) - { - if(!rl)return(false); + ///** + //* 从当前节点展开输出到一个渲染列表 + //* @param rl 渲染列表 + //* @param func 过滤函数 + //* @param func_data 过滤函数用辅助数据 + //* @return 成功与否 + //*/ + //bool SceneNode::ExpendToList(RenderList *rl,FilterSceneNodeFunc func,void *func_data) + //{ + // if(!rl)return(false); - if(func) - if(!func(this,func_data)) - return(false); + // if(func) + // if(!func(this,func_data)) + // return(false); - { - int count=renderable_instances.GetCount(); + // { + // int count=renderable_instances.GetCount(); - if(count>0) - rl->Add(this); - } + // if(count>0) + // rl->Add(this); + // } - { - int count=SubNode.GetCount(); - SceneNode **sub=SubNode.GetData(); + // { + // int count=SubNode.GetCount(); + // SceneNode **sub=SubNode.GetData(); - for(int i=0;iExpendToList(rl,func,func_data); //展开子节点 + // for(int i=0;iExpendToList(rl,func,func_data); //展开子节点 - ++sub; - } - } + // ++sub; + // } + // } - return(true); - } + // return(true); + //} - /** - * 从当前节点展开输出到一个渲染列表 - * @param rl 渲染列表 - * @param cam 摄像机 - * @param comp_func 渲染列表远近比较函数 - */ - bool SceneNode::ExpendToList(RenderList *rl,Camera *cam,RenderListCompFunc comp_func) - { - if(!rl||!cam)return(false); + ///** + //* 从当前节点展开输出到一个渲染列表 + //* @param rl 渲染列表 + //* @param cam 摄像机 + //* @param comp_func 渲染列表远近比较函数 + //*/ + //bool SceneNode::ExpendToList(RenderList *rl,Camera *cam,RenderListCompFunc comp_func) + //{ + // if(!rl||!cam)return(false); - if(!ExpendToList(rl)) - return(false); + // if(!ExpendToList(rl)) + // return(false); - if(comp_func) - { - } + // if(comp_func) + // { + // } - return(true); - } + // return(true); + //} }//namespace graph }//namespace hgl diff --git a/src/SceneGraph/SceneOrient.cpp b/src/SceneGraph/SceneOrient.cpp index 80ea9230..8e061f10 100644 --- a/src/SceneGraph/SceneOrient.cpp +++ b/src/SceneGraph/SceneOrient.cpp @@ -3,15 +3,20 @@ namespace hgl { namespace graph { - Matrix4f Ortho2DMatrix; ///<全局2D视图矩阵 - SceneOrient::SceneOrient() { - pc.local_to_world =Matrix4f::identity; - LocalMatrix =Matrix4f::identity; - LocalToWorldMatrix =Matrix4f::identity; - InverseLocalMatrix =Matrix4f::identity; - InverseLocalToWorldMatrix =Matrix4f::identity; + LocalMatrix =Matrix4f(1.0f); + LocalToWorldMatrix =Matrix4f(1.0f); + InverseLocalMatrix =Matrix4f(1.0f); + InverseLocalToWorldMatrix =Matrix4f(1.0f); + } + + SceneOrient::SceneOrient(const Matrix4f &mat) + { + SetLocalMatrix(mat); + + LocalToWorldMatrix =Matrix4f(1.0f); + InverseLocalToWorldMatrix =Matrix4f(1.0f); } Matrix4f &SceneOrient::SetLocalMatrix(const Matrix4f &m) @@ -29,10 +34,6 @@ namespace hgl InverseLocalToWorldMatrix=inverse(LocalToWorldMatrix); - pc.local_to_world =LocalToWorldMatrix; -// pc.object_position =; -// pc.object_size =; - return LocalToWorldMatrix; } diff --git a/src/SceneGraph/Texture2DLoader.cpp b/src/SceneGraph/Texture2DLoader.cpp deleted file mode 100644 index bf83b962..00000000 --- a/src/SceneGraph/Texture2DLoader.cpp +++ /dev/null @@ -1,106 +0,0 @@ -#include -#include -#include -#include - -namespace hgl -{ - namespace graph - { - bool Texture2DLoader::Load(io::InputStream *is) - { - if(!is)return(false); - - if(is->Read(&file_header,sizeof(Tex2DFileHeader))!=sizeof(Tex2DFileHeader)) - return(false); - - if(file_header.version!=2) - return(false); - - total_bytes=0; - - if(file_header.channels==0) //压缩格式 - { - if(is->Read(&compress_format,sizeof(uint16))!=sizeof(uint16)) - return(false); - - if(is->Read(&total_bytes,sizeof(uint32))!=sizeof(uint32)) - return(false); - } - else - { - if(is->Read(&pixel_format,sizeof(TexPixelFormat))!=sizeof(TexPixelFormat)) - return(false); - - total_bytes=file_header.pixel_count()*pixel_format.pixel_bytes(); - } - - if(is->Available()Read(ptr,total_bytes)!=total_bytes) - OnError(); - - OnEnd(); - - return(true); - } - - bool Texture2DLoader::Load(const OSString &filename) - { - io::OpenFileInputStream fis(filename); - - if(!fis) - { - LOG_ERROR(OS_TEXT("[ERROR] open texture file<")+filename+OS_TEXT("> failed.")); - return(false); - } - - return this->Load(&fis); - } - }//namespace graph - - namespace graph - { - Bitmap2DLoader::~Bitmap2DLoader() - { - SAFE_CLEAR(bmp); - } - - void *Bitmap2DLoader::OnBegin(uint32 total_bytes) - { - SAFE_CLEAR(bmp); - - bmp=new BitmapData; - - bmp->width =file_header.width; - bmp->height =file_header.height; - bmp->total_bytes=total_bytes; - - bmp->data=new char[total_bytes]; - - return bmp->data; - } - - BitmapData *Bitmap2DLoader::GetBitmap() - { - BitmapData *result=bmp; - bmp=nullptr; - return result; - } - - BitmapData *LoadBitmapFromFile(const OSString &filename) - { - Bitmap2DLoader loader; - - if(!loader.Load(filename)) - return(nullptr); - - return loader.GetBitmap(); - } - }//namespace graph -}//namespace hgl diff --git a/src/SceneGraph/TextureLoader.cpp b/src/SceneGraph/TextureLoader.cpp new file mode 100644 index 00000000..174c724b --- /dev/null +++ b/src/SceneGraph/TextureLoader.cpp @@ -0,0 +1,242 @@ +#include +#include +#include + +namespace hgl +{ + namespace graph + { + namespace + { + constexpr VkFormat CompressFormatList[]= + { + PF_BC1_RGBUN, + PF_BC1_RGBAUN, + PF_BC2UN, + PF_BC3UN, + PF_BC4UN, + PF_BC5UN, + PF_BC6UF, + PF_BC6SF, + PF_BC7UN + }; + + constexpr uint32 CompressFormatBits[]={4,4,8,8,4,8,8,8,8}; + + constexpr uint32 CompressFormatCount=sizeof(CompressFormatList)/sizeof(VkFormat); + } + + const uint TexPixelFormat::pixel_bits()const + { + return channels ?bits[0]+bits[1]+bits[2]+bits[3] + :CompressFormatBits[compress_format]; + } + + const uint32 ComputeMipmapBytes(uint32 length,uint32 bytes) + { + uint32 total=0; + + while(length>=1) + { + if(bytes<8) + total+=8; + else + total+=bytes; + + if(length==1)break; + + if(length>1){length>>=1;bytes>>=1;} + } + + return total; + } + + const uint32 ComputeMipmapBytes(uint32 width,uint32 height,uint32 bytes) + { + uint32 total=0; + + while(width>=1&&height>=1) + { + if(bytes<8) + total+=8; + else + total+=bytes; + + if(width==1&&height==1)break; + + if(width >1){width >>=1;bytes>>=1;} + if(height>1){height>>=1;bytes>>=1;} + } + + return total; + } + + const uint32 ComputeMipmapBytes(uint32 width,uint32 height,uint32 depth,uint32 bytes) + { + uint32 total=0; + + while(width>=1&&height>=1&&depth>=1) + { + if(bytes<8) + total+=8; + else + total+=bytes; + + if(width==1&&height==1&&depth==1)break; + + if(depth >1){depth >>=1;bytes>>=1;} + if(width >1){width >>=1;bytes>>=1;} + if(height>1){height>>=1;bytes>>=1;} + } + + return total; + } + + struct VulkanTexturePixelFormat + { + VkFormat format; + + uint8 channels; //ɫͨ + char colors[4]; + uint8 bits[4]; + VulkanDataType type; + };// + + constexpr VulkanTexturePixelFormat pf_list[]= + { + { PF_RGBA4, 4,{'R','G','B','A'},{ 4, 4, 4, 4},VulkanDataType::UNORM}, //Android ֲ֧ + { PF_BGRA4, 4,{'B','G','R','A'},{ 4, 4, 4, 4},VulkanDataType::UNORM}, //ios֧ + {UPF_RGB565, 3,{'R','G','B', 0 },{ 5, 6, 5, 0},VulkanDataType::UNORM}, + {UPF_A1RGB5, 4,{'A','R','G','B'},{ 1, 5, 5, 5},VulkanDataType::UNORM}, + {UPF_R8, 1,{'R', 0 , 0 , 0 },{ 8, 0, 0, 0},VulkanDataType::UNORM}, + {UPF_RG8, 2,{'R','G', 0 , 0 },{ 8, 8, 0, 0},VulkanDataType::UNORM}, + {UPF_RGBA8, 4,{'R','G','B','A'},{ 8, 8, 8, 8},VulkanDataType::UNORM}, + {UPF_RGBA8S, 4,{'R','G','B','A'},{ 8, 8, 8, 8},VulkanDataType::SNORM}, + {UPF_RGBA8U, 4,{'R','G','B','A'},{ 8, 8, 8, 8},VulkanDataType::UINT}, + {UPF_RGBA8I, 4,{'R','G','B','A'},{ 8, 8, 8, 8},VulkanDataType::SINT}, + {UPF_ABGR8, 4,{'A','B','G','R'},{ 8, 8, 8, 8},VulkanDataType::UNORM}, + {UPF_A2BGR10, 4,{'A','B','G','R'},{ 2,10,10,10},VulkanDataType::UNORM}, + {UPF_R16, 1,{'R', 0 , 0 , 0 },{16, 0, 0, 0},VulkanDataType::UNORM}, + {UPF_R16U, 1,{'R', 0 , 0 , 0 },{16, 0, 0, 0},VulkanDataType::UINT}, + {UPF_R16I, 1,{'R', 0 , 0 , 0 },{16, 0, 0, 0},VulkanDataType::SINT}, + {UPF_R16F, 1,{'R', 0 , 0 , 0 },{16, 0, 0, 0},VulkanDataType::SFLOAT}, + {UPF_RG16, 2,{'R','G', 0 , 0 },{16,16, 0, 0},VulkanDataType::UNORM}, + {UPF_RG16U, 2,{'R','G', 0 , 0 },{16,16, 0, 0},VulkanDataType::UINT}, + {UPF_RG16I, 2,{'R','G', 0 , 0 },{16,16, 0, 0},VulkanDataType::SINT}, + {UPF_RG16F, 2,{'R','G', 0 , 0 },{16,16, 0, 0},VulkanDataType::SFLOAT}, + { PF_RGBA16UN, 4,{'R','G','B','A'},{16,16,16,16},VulkanDataType::UNORM}, + { PF_RGBA16SN, 4,{'R','G','B','A'},{16,16,16,16},VulkanDataType::SNORM}, + {UPF_RGBA16U, 4,{'R','G','B','A'},{16,16,16,16},VulkanDataType::UINT}, + {UPF_RGBA16I, 4,{'R','G','B','A'},{16,16,16,16},VulkanDataType::SINT}, + {UPF_RGBA16F, 4,{'R','G','B','A'},{16,16,16,16},VulkanDataType::SFLOAT}, + {UPF_R32U, 1,{'R', 0 , 0 , 0 },{32, 0, 0, 0},VulkanDataType::UINT}, + {UPF_R32I, 1,{'R', 0 , 0 , 0 },{32, 0, 0, 0},VulkanDataType::SINT}, + {UPF_R32F, 1,{'R', 0 , 0 , 0 },{32, 0, 0, 0},VulkanDataType::SFLOAT}, + {UPF_RG32U, 2,{'R','G', 0 , 0 },{32,32, 0, 0},VulkanDataType::UINT}, + {UPF_RG32I, 2,{'R','G', 0 , 0 },{32,32, 0, 0},VulkanDataType::SINT}, + {UPF_RG32F, 2,{'R','G', 0 , 0 },{32,32, 0, 0},VulkanDataType::SFLOAT}, + { PF_RGB32U, 3,{'R','G','B', 0 },{32,32,32, 0},VulkanDataType::UINT}, + { PF_RGB32I, 3,{'R','G','B', 0 },{32,32,32, 0},VulkanDataType::SINT}, + { PF_RGB32F, 3,{'R','G','B', 0 },{32,32,32, 0},VulkanDataType::SFLOAT}, + {UPF_RGBA32U, 4,{'R','G','B','A'},{32,32,32,32},VulkanDataType::UINT}, + {UPF_RGBA32I, 4,{'R','G','B','A'},{32,32,32,32},VulkanDataType::SINT}, + {UPF_RGBA32F, 4,{'R','G','B','A'},{32,32,32,32},VulkanDataType::SFLOAT}, + {UPF_B10GR11UF, 3,{'B','G','R', 0 },{10,11,11, 0},VulkanDataType::UFLOAT} + }; + + constexpr uint VulkanTexturePixelFormatCount=sizeof(pf_list)/sizeof(VulkanTexturePixelFormat); + + const VkFormat GetVulkanFormat(const TexPixelFormat &tpf) + { + const VulkanTexturePixelFormat *pf=pf_list; + + for(uint i=0;ichannels)continue; + if(tpf.datatype!=(uint8)pf->type)continue; + + if(tpf.colors[0]!=pf->colors[0])continue; + if(tpf.colors[1]!=pf->colors[1])continue; + if(tpf.colors[2]!=pf->colors[2])continue; + if(tpf.colors[3]!=pf->colors[3])continue; + + if(tpf.bits[0]!=pf->bits[0])continue; + if(tpf.bits[1]!=pf->bits[1])continue; + if(tpf.bits[2]!=pf->bits[2])continue; + if(tpf.bits[3]!=pf->bits[3])continue; + + return pf->format; + } + + return VK_FORMAT_UNDEFINED; + } + + bool TextureLoader::Load(io::InputStream *is) + { + if(!is)return(false); + + if(is->Read(&file_header,sizeof(TextureFileHeader))!=sizeof(TextureFileHeader)) + return(false); + + constexpr char TEXTURE_FILE_HEADER[]="Texture"; + constexpr uint TEXTURE_FILE_HEADER_LENGTH=sizeof(TEXTURE_FILE_HEADER)-1; + + if(memcmp(&file_header.id_str,TEXTURE_FILE_HEADER,TEXTURE_FILE_HEADER_LENGTH)) + return(false); + + if(file_header.version!=0) + return(false); + +// if(file_header.type!=type) +// return(false); + + if(file_header.pixel_format.channels==0) + { + if(file_header.pixel_format.compress_format<0 + ||file_header.pixel_format.compress_format>=CompressFormatCount) + return(nullptr); + + format=CompressFormatList[file_header.pixel_format.compress_format]; + } + else + { + format=GetVulkanFormat(file_header.pixel_format); + } + + //0mipmapͼֽ + mipmap_zero_total_bytes=(GetPixelsCount()*file_header.pixel_format.pixel_bits())>>3; + + total_bytes=GetTotalBytes(); + + const uint32 file_left_bytes=is->Available(); + + if(file_left_bytesRead(ptr,total_bytes)!=total_bytes) + OnError(); + + OnEnd(); + + return(true); + } + + bool TextureLoader::Load(const OSString &filename) + { + io::OpenFileInputStream fis(filename); + + if(!fis) + { + LOG_ERROR(OS_TEXT("[ERROR] open texture file<")+filename+OS_TEXT("> failed.")); + return(false); + } + + return this->Load(&fis); + } + }//namespace graph +}//namespace hgl diff --git a/src/SceneGraph/TileData.cpp b/src/SceneGraph/TileData.cpp index 86faf184..bb582ccb 100644 --- a/src/SceneGraph/TileData.cpp +++ b/src/SceneGraph/TileData.cpp @@ -1,13 +1,13 @@ #include #include -#include -#include +#include +#include namespace hgl { namespace graph { - TileData::TileData(Device *dev,Texture2D *tt,const uint tw,const uint th) + TileData::TileData(GPUDevice *dev,Texture2D *tt,const uint tw,const uint th) { device=dev; @@ -108,7 +108,7 @@ namespace hgl memcpy(commit_ptr,data,bytes); commit_ptr+=bytes; - ImageRegion ir; + Image2DRegion ir; ir.left =obj->uv_pixel.GetLeft(); ir.top =obj->uv_pixel.GetTop(); diff --git a/src/SceneGraph/VertexAttribData.cpp b/src/SceneGraph/VertexAttribData.cpp index 3d4fc79d..b8c0122c 100644 --- a/src/SceneGraph/VertexAttribData.cpp +++ b/src/SceneGraph/VertexAttribData.cpp @@ -4,14 +4,15 @@ namespace hgl { namespace graph { - VAD *CreateVertexAttribData(const VertexAttribType *type,const uint32_t vertex_count) + VAD *CreateVertexAttribData(const uint32_t vertex_count,const VkFormat fmt,const int vec_size,const uint stride) { - if(!type||!type->Check()) + if(vertex_count<=0 + ||vec_size<1||vec_size>4 + ||stride<1||stride>8*4 + ||!CheckVulkanFormat(fmt)) return(nullptr); - VkFormat fmt=vulkan::GetVulkanFormat(type); - - return(new VertexAttribData(vertex_count,type->vec_size,type->GetStride(),fmt)); + return(new VertexAttribData(vertex_count,vec_size,stride,fmt)); } }//namespace graph }//namespace hgl diff --git a/src/RenderDevice/Vulkan/ForceDiscreteGPU.c b/src/SceneGraph/Vulkan/ForceDiscreteGPU.c similarity index 100% rename from src/RenderDevice/Vulkan/ForceDiscreteGPU.c rename to src/SceneGraph/Vulkan/ForceDiscreteGPU.c diff --git a/src/SceneGraph/Vulkan/Texture/BufferImageCopy2D.h b/src/SceneGraph/Vulkan/Texture/BufferImageCopy2D.h new file mode 100644 index 00000000..17ab2d5f --- /dev/null +++ b/src/SceneGraph/Vulkan/Texture/BufferImageCopy2D.h @@ -0,0 +1,56 @@ +#pragma once +#include +VK_NAMESPACE_BEGIN +struct BufferImageCopy:public VkBufferImageCopy +{ +public: + + BufferImageCopy() + { + hgl_zero(*this); + imageSubresource.layerCount=1; + } + + BufferImageCopy(const VkImageAspectFlags aspect_mask):BufferImageCopy() + { + imageSubresource.aspectMask=aspect_mask; + } + + BufferImageCopy(const Texture2D *tex):BufferImageCopy() + { + imageSubresource.aspectMask=tex->GetAspect(); + SetRectScope(0,0,tex->GetWidth(),tex->GetHeight()); + } + + BufferImageCopy(const TextureCube *tex):BufferImageCopy() + { + imageSubresource.aspectMask=tex->GetAspect(); + imageSubresource.layerCount=6; + SetRectScope(0,0,tex->GetWidth(),tex->GetHeight()); + } + + void Set(const VkImageAspectFlags aspect_mask,const uint32_t layer_count) + { + imageSubresource.aspectMask=aspect_mask; + imageSubresource.layerCount=layer_count; + } + + void Set(Image2DRegion *ir) + { + imageOffset.x=ir->left; + imageOffset.y=ir->top; + imageExtent.width=ir->width; + imageExtent.height=ir->height; + imageExtent.depth=1; + } + + void SetRectScope(int32_t left,int32_t top,uint32_t width,uint32_t height) + { + imageOffset.x=left; + imageOffset.y=top; + imageExtent.width=width; + imageExtent.height=height; + imageExtent.depth=1; + } +};// +VK_NAMESPACE_END diff --git a/src/SceneGraph/Vulkan/Texture/GenMipmaps.cpp b/src/SceneGraph/Vulkan/Texture/GenMipmaps.cpp new file mode 100644 index 00000000..0b352502 --- /dev/null +++ b/src/SceneGraph/Vulkan/Texture/GenMipmaps.cpp @@ -0,0 +1,70 @@ +#include + +VK_NAMESPACE_BEGIN +void GenerateMipmaps(TextureCmdBuffer *texture_cmd_buf,VkImage image,VkImageAspectFlags aspect_mask,VkExtent3D extent,const uint32_t mipLevels,const uint32 layer_count) +{ + ImageSubresourceRange subresourceRange(aspect_mask,1,layer_count); + + VkImageBlit blit; + + blit.srcOffsets[0] = {0, 0, 0}; + blit.srcSubresource.aspectMask = aspect_mask; + blit.srcSubresource.baseArrayLayer = 0; + blit.srcSubresource.layerCount = layer_count; + + blit.dstOffsets[0] = {0, 0, 0}; + blit.dstSubresource=blit.srcSubresource; + + int32_t width =extent.width; + int32_t height =extent.height; + + for (uint32_t i = 1; i < mipLevels; i++) + { + subresourceRange.baseMipLevel = i - 1; + + blit.srcOffsets[1] = {width,height,1}; + blit.srcSubresource.mipLevel = i - 1; + + if(width >1)width >>=1; + if(height>1)height>>=1; + + blit.dstOffsets[1] = {width,height,1}; + blit.dstSubresource.mipLevel = i; + + texture_cmd_buf->ImageMemoryBarrier(image, + VK_PIPELINE_STAGE_TRANSFER_BIT, + VK_PIPELINE_STAGE_TRANSFER_BIT, + VK_ACCESS_TRANSFER_WRITE_BIT, + VK_ACCESS_TRANSFER_READ_BIT, + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, + subresourceRange); + + texture_cmd_buf->BlitImage( + image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, + image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + 1, &blit, + VK_FILTER_LINEAR); + + texture_cmd_buf->ImageMemoryBarrier(image, + VK_PIPELINE_STAGE_TRANSFER_BIT, + VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, + VK_ACCESS_TRANSFER_READ_BIT, + VK_ACCESS_SHADER_READ_BIT, + VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, + VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, + subresourceRange); + } + + subresourceRange.baseMipLevel = mipLevels - 1; + + texture_cmd_buf->ImageMemoryBarrier(image, + VK_PIPELINE_STAGE_TRANSFER_BIT, + VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, + VK_ACCESS_TRANSFER_WRITE_BIT, + VK_ACCESS_SHADER_READ_BIT, + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, + subresourceRange); +} +VK_NAMESPACE_END \ No newline at end of file diff --git a/src/SceneGraph/Vulkan/Texture/VKDeviceTexture.cpp b/src/SceneGraph/Vulkan/Texture/VKDeviceTexture.cpp new file mode 100644 index 00000000..09e0c5c2 --- /dev/null +++ b/src/SceneGraph/Vulkan/Texture/VKDeviceTexture.cpp @@ -0,0 +1,86 @@ +#include +#include + +VK_NAMESPACE_BEGIN +bool GPUDevice::CheckFormatSupport(const VkFormat format,const uint32_t bits,ImageTiling tiling) const +{ + const VkFormatProperties fp=attr->physical_device->GetFormatProperties(format); + + if(tiling==ImageTiling::Optimal) + return(fp.optimalTilingFeatures&bits); + else + return(fp.linearTilingFeatures&bits); +} + +void GPUDevice::Clear(TextureCreateInfo *tci) +{ + if(!tci)return; + + if(tci->image)DestroyImage(tci->image); + if(tci->image_view)delete tci->image_view; + if(tci->memory)delete tci->memory; + + delete tci; +} + +bool GPUDevice::CommitTexture(Texture *tex,GPUBuffer *buf,const VkBufferImageCopy *buffer_image_copy,const int count,const uint32_t layer_count,VkPipelineStageFlags destinationStage) +{ + if(!tex||!buf) + return(false); + + ImageSubresourceRange subresourceRange(tex->GetAspect(),tex->GetMipLevel(),layer_count); + + texture_cmd_buf->ImageMemoryBarrier(tex->GetImage(), + VK_PIPELINE_STAGE_HOST_BIT, + VK_PIPELINE_STAGE_TRANSFER_BIT, + 0, + VK_ACCESS_TRANSFER_WRITE_BIT, + VK_IMAGE_LAYOUT_UNDEFINED, + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + subresourceRange); + + texture_cmd_buf->CopyBufferToImage( + buf->GetBuffer(), + tex->GetImage(), + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + count, + buffer_image_copy); + + if(destinationStage==VK_PIPELINE_STAGE_TRANSFER_BIT) //接下来还有,一般是给自动生成mipmaps + { + //texture_cmd_buf->ImageMemoryBarrier(tex->GetImage(), + // VK_PIPELINE_STAGE_TRANSFER_BIT, + // VK_PIPELINE_STAGE_TRANSFER_BIT, + // VK_ACCESS_TRANSFER_WRITE_BIT, + // VK_ACCESS_TRANSFER_READ_BIT, + // VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + // VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, + // subresourceRange); + } + else// if(destinationStage==VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT) //接下来就给fragment shader用了,证明是最后一步 + { + texture_cmd_buf->ImageMemoryBarrier(tex->GetImage(), + VK_PIPELINE_STAGE_TRANSFER_BIT, + VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, + VK_ACCESS_TRANSFER_WRITE_BIT, + VK_ACCESS_SHADER_READ_BIT, + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, + subresourceRange); + } + + return(true); +} + +bool GPUDevice::SubmitTexture(const VkCommandBuffer *cmd_bufs,const uint32_t count) +{ + if(!cmd_bufs||count<=0) + return(false); + + texture_queue->Submit(cmd_bufs,count,nullptr,nullptr); +// texture_queue->WaitQueue(); + texture_queue->WaitFence(); + + return(true); +} +VK_NAMESPACE_END diff --git a/src/SceneGraph/Vulkan/Texture/VKDeviceTexture2D.cpp b/src/SceneGraph/Vulkan/Texture/VKDeviceTexture2D.cpp new file mode 100644 index 00000000..b8c107f0 --- /dev/null +++ b/src/SceneGraph/Vulkan/Texture/VKDeviceTexture2D.cpp @@ -0,0 +1,218 @@ +#include +#include +#include +#include"BufferImageCopy2D.h" +VK_NAMESPACE_BEGIN +void GenerateMipmaps(TextureCmdBuffer *texture_cmd_buf,VkImage image,VkImageAspectFlags aspect_mask,VkExtent3D extent,const uint32_t mipLevels,const uint32_t layer_count); + +Texture2D *GPUDevice::CreateTexture2D(TextureData *tex_data) +{ + if(!tex_data) + return(nullptr); + + return(new Texture2D(attr->device,tex_data)); +} + +Texture2D *GPUDevice::CreateTexture2D(TextureCreateInfo *tci) +{ + if(!tci)return(nullptr); + + if(tci->extent.width*tci->extent.height<=0) + { + Clear(tci); + return(nullptr); + } + + if(tci->target_mipmaps==0) + tci->target_mipmaps=(tci->origin_mipmaps>1?tci->origin_mipmaps:1); + + if(!tci->image) + { + Image2DCreateInfo ici(tci->usage,tci->tiling,tci->format,tci->extent,tci->target_mipmaps); + tci->image=CreateImage(&ici); + + if(!tci->image) + { + Clear(tci); + return(nullptr); + } + + tci->memory=CreateMemory(tci->image); + } + + if(!tci->image_view) + tci->image_view=CreateImageView2D(attr->device,tci->format,tci->extent,tci->target_mipmaps,tci->aspect,tci->image); + + TextureData *tex_data=new TextureData(tci); + + Texture2D *tex=CreateTexture2D(tex_data); + + if(!tex) + { + Clear(tci); + return(nullptr); + } + + if((!tci->buffer)&&tci->pixels&&tci->total_bytes>0) + tci->buffer=CreateBuffer(VK_BUFFER_USAGE_TRANSFER_SRC_BIT,tci->total_bytes,tci->pixels); + + if(tci->buffer) + { + texture_cmd_buf->Begin(); + if(tci->target_mipmaps==tci->origin_mipmaps) + { + if(tci->target_mipmaps<=1) //本身不含mipmaps,但也不要mipmaps + { + CommitTexture2D(tex,tci->buffer,VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT); + } + else //本身有mipmaps数据 + { + CommitTexture2DMipmaps(tex,tci->buffer,tci->extent,tci->mipmap_zero_total_bytes); + } + } + else + if(tci->origin_mipmaps<=1) //本身不含mipmaps数据,又想要mipmaps + { + CommitTexture2D(tex,tci->buffer,VK_PIPELINE_STAGE_TRANSFER_BIT); + GenerateMipmaps(texture_cmd_buf,tex->GetImage(),tex->GetAspect(),tci->extent,tex_data->miplevel,1); + } + texture_cmd_buf->End(); + + SubmitTexture(*texture_cmd_buf); + + delete tci->buffer; + } + + delete tci; //"delete tci" is correct,please don't use "Clear(tci)" + return tex; +} + +bool GPUDevice::CommitTexture2D(Texture2D *tex,GPUBuffer *buf,VkPipelineStageFlags destinationStage) +{ + if(!tex||!buf)return(false); + + BufferImageCopy buffer_image_copy(tex); + + return CommitTexture(tex,buf,&buffer_image_copy,1,1,destinationStage); +} + +bool GPUDevice::CommitTexture2DMipmaps(Texture2D *tex,GPUBuffer *buf,const VkExtent3D &extent,uint32_t total_bytes) +{ + if(!tex||!buf + ||extent.width*extent.height<=0) + return(false); + + const uint32_t miplevel=tex->GetMipLevel(); + + AutoDeleteArray buffer_image_copy(miplevel); + + VkDeviceSize offset=0; + uint32_t level=0; + + uint32_t width=extent.width; + uint32_t height=extent.height; + + buffer_image_copy.zero(); + + for(VkBufferImageCopy &bic:buffer_image_copy) + { + bic.bufferOffset = offset; + bic.bufferRowLength = 0; + bic.bufferImageHeight = 0; + bic.imageSubresource.aspectMask = tex->GetAspect(); + bic.imageSubresource.mipLevel = level++; + bic.imageSubresource.baseArrayLayer = 0; + bic.imageSubresource.layerCount = 1; + bic.imageOffset.x = 0; + bic.imageOffset.y = 0; + bic.imageOffset.z = 0; + bic.imageExtent.width = width; + bic.imageExtent.height= height; + bic.imageExtent.depth = 1; + + if(total_bytes<8) + offset+=8; + else + offset+=total_bytes; + + if(width>1){width>>=1;total_bytes>>=1;} + if(height>1){height>>=1;total_bytes>>=1;} + } + + return CommitTexture(tex,buf,buffer_image_copy,miplevel,1,VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT); +} + +bool GPUDevice::ChangeTexture2D(Texture2D *tex,GPUBuffer *buf,const List &ir_list,VkPipelineStageFlags destinationStage) +{ + if(!tex||!buf||ir_list.GetCount()<=0) + return(false); + + const int ir_count=ir_list.GetCount(); + int count=0; + + AutoDeleteArray buffer_image_copy(ir_count); + VkBufferImageCopy *tp=buffer_image_copy; + + VkDeviceSize offset=0; + + for(const Image2DRegion &sp:ir_list) + { + tp->bufferOffset = offset; + tp->bufferRowLength = 0; + tp->bufferImageHeight = 0; + tp->imageSubresource.aspectMask = tex->GetAspect(); + tp->imageSubresource.mipLevel = 0; + tp->imageSubresource.baseArrayLayer = 0; + tp->imageSubresource.layerCount = 1; + tp->imageOffset.x = sp.left; + tp->imageOffset.y = sp.top; + tp->imageOffset.z = 0; + tp->imageExtent.width = sp.width; + tp->imageExtent.height= sp.height; + tp->imageExtent.depth = 1; + + offset+=sp.bytes; + ++tp; + } + + texture_cmd_buf->Begin(); + bool result=CommitTexture(tex,buf,buffer_image_copy,ir_count,1,destinationStage); + texture_cmd_buf->End(); + SubmitTexture(*texture_cmd_buf); + return result; +} + +bool GPUDevice::ChangeTexture2D(Texture2D *tex,GPUBuffer *buf,uint32_t left,uint32_t top,uint32_t width,uint32_t height,VkPipelineStageFlags destinationStage) +{ + if(!tex||!buf + ||left<0||left+width>tex->GetWidth() + ||top<0||top+height>tex->GetHeight() + ||width<=0||height<=0) + return(false); + + BufferImageCopy buffer_image_copy(tex); + + texture_cmd_buf->Begin(); + bool result=CommitTexture(tex,buf,&buffer_image_copy,1,1,destinationStage); + texture_cmd_buf->End(); + SubmitTexture(*texture_cmd_buf); + return result; +} + +bool GPUDevice::ChangeTexture2D(Texture2D *tex,void *data,uint32_t left,uint32_t top,uint32_t width,uint32_t height,uint32_t size,VkPipelineStageFlags destinationStage) +{ + if(!tex||!data + ||left<0||left+width>tex->GetWidth() + ||top<0||top+height>tex->GetHeight() + ||width<=0||height<=0 + ||size<=0) + return(false); + + GPUBuffer *buf=CreateBuffer(VK_BUFFER_USAGE_TRANSFER_SRC_BIT,size,data); + + bool result=ChangeTexture2D(tex,buf,left,top,width,height,destinationStage); + + delete buf; + return(result); +} +VK_NAMESPACE_END \ No newline at end of file diff --git a/src/SceneGraph/Vulkan/Texture/VKDeviceTextureCube.cpp b/src/SceneGraph/Vulkan/Texture/VKDeviceTextureCube.cpp new file mode 100644 index 00000000..3e705184 --- /dev/null +++ b/src/SceneGraph/Vulkan/Texture/VKDeviceTextureCube.cpp @@ -0,0 +1,218 @@ +#include +#include +#include +#include"BufferImageCopy2D.h" +VK_NAMESPACE_BEGIN +void GenerateMipmaps(TextureCmdBuffer *texture_cmd_buf,VkImage image,VkImageAspectFlags aspect_mask,VkExtent3D extent,const uint32_t mipLevels,const uint32_t layer_count); + +TextureCube *GPUDevice::CreateTextureCube(TextureData *tex_data) +{ + if(!tex_data) + return(nullptr); + + return(new TextureCube(attr->device,tex_data)); +} + +TextureCube *GPUDevice::CreateTextureCube(TextureCreateInfo *tci) +{ + if(!tci)return(nullptr); + + if(tci->extent.width*tci->extent.height<=0)return(nullptr); + + if(tci->target_mipmaps==0) + tci->target_mipmaps=(tci->origin_mipmaps>1?tci->origin_mipmaps:1); + + if(!tci->image) + { + ImageCubeCreateInfo ici(tci->usage,tci->tiling,tci->format,tci->extent,tci->target_mipmaps); + tci->image=CreateImage(&ici); + + if(!tci->image) + { + Clear(tci); + return(nullptr); + } + + tci->memory=CreateMemory(tci->image); + } + + if(!tci->image_view) + tci->image_view=CreateImageViewCube(attr->device,tci->format,tci->extent,tci->target_mipmaps,tci->aspect,tci->image); + + TextureData *tex_data=new TextureData(tci); + + TextureCube *tex=CreateTextureCube(tex_data); + + if(!tex) + { + Clear(tci); + return(nullptr); + } + + if((!tci->buffer)&&tci->pixels&&tci->total_bytes>0) + tci->buffer=CreateBuffer(VK_BUFFER_USAGE_TRANSFER_SRC_BIT,tci->total_bytes,tci->pixels); + + if(tci->buffer) + { + texture_cmd_buf->Begin(); + if(tci->target_mipmaps==tci->origin_mipmaps) + { + if(tci->target_mipmaps<=1) //mipmapsҲҪmipmaps + { + CommitTextureCube(tex,tci->buffer,tci->mipmap_zero_total_bytes,VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT); + } + else //mipmaps + { + CommitTextureCubeMipmaps(tex,tci->buffer,tci->extent,tci->mipmap_zero_total_bytes); + } + } + else + if(tci->origin_mipmaps<=1) //mipmaps,Ҫmipmaps + { + CommitTextureCube(tex,tci->buffer,tci->mipmap_zero_total_bytes,VK_PIPELINE_STAGE_TRANSFER_BIT); + GenerateMipmaps(texture_cmd_buf,tex->GetImage(),tex->GetAspect(),tci->extent,tex_data->miplevel,6); + } + texture_cmd_buf->End(); + + SubmitTexture(*texture_cmd_buf); + + delete tci->buffer; + } + + delete tci; //"delete tci" is correct,please don't use "Clear(tci)" + return tex; +} + +bool GPUDevice::CommitTextureCube(TextureCube *tex,GPUBuffer *buf,const uint32_t mipmaps_zero_bytes,VkPipelineStageFlags destinationStage) +{ + if(!tex||!buf||!mipmaps_zero_bytes)return(false); + + BufferImageCopy buffer_image_copy(tex); + + return CommitTexture(tex,buf,&buffer_image_copy,1,6,destinationStage); +} + +bool GPUDevice::CommitTextureCubeMipmaps(TextureCube *tex,GPUBuffer *buf,const VkExtent3D &extent,uint32_t total_bytes) +{ + if(!tex||!buf + ||extent.width*extent.height<=0) + return(false); + + const uint32_t miplevel=tex->GetMipLevel(); + + AutoDeleteArray buffer_image_copy(miplevel); + + VkDeviceSize offset=0; + + uint32_t face=0; + uint32_t level=0; + + uint32_t width=extent.width; + uint32_t height=extent.height; + + buffer_image_copy.zero(); + + for(VkBufferImageCopy &bic:buffer_image_copy) + { + bic.bufferOffset = offset; + bic.bufferRowLength = 0; + bic.bufferImageHeight = 0; + bic.imageSubresource.aspectMask = tex->GetAspect(); + bic.imageSubresource.mipLevel = level; + bic.imageSubresource.baseArrayLayer = 0; + bic.imageSubresource.layerCount = 6; + bic.imageOffset.x = 0; + bic.imageOffset.y = 0; + bic.imageOffset.z = 0; + bic.imageExtent.width = width; + bic.imageExtent.height= height; + bic.imageExtent.depth = 1; + + if(total_bytes<8) + offset+=8; + else + offset+=total_bytes; + + ++level; + + if(width>1){width>>=1;total_bytes>>=1;} + if(height>1){height>>=1;total_bytes>>=1;} + } + + return CommitTexture(tex,buf,buffer_image_copy,miplevel,6,VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT); +} + +//bool GPUDevice::ChangeTexture2D(Texture2D *tex,GPUBuffer *buf,const List &ir_list,VkPipelineStageFlags destinationStage) +//{ +// if(!tex||!buf||ir_list.GetCount()<=0) +// return(false); +// +// const int ir_count=ir_list.GetCount(); +// int count=0; +// +// AutoDeleteArray buffer_image_copy(ir_count); +// VkBufferImageCopy *tp=buffer_image_copy; +// +// VkDeviceSize offset=0; +// +// for(const Image2DRegion &sp:ir_list) +// { +// tp->bufferOffset = offset; +// tp->bufferRowLength = 0; +// tp->bufferImageHeight = 0; +// tp->imageSubresource.aspectMask = tex->GetAspect(); +// tp->imageSubresource.mipLevel = 0; +// tp->imageSubresource.baseArrayLayer = 0; +// tp->imageSubresource.layerCount = 1; +// tp->imageOffset.x = sp.left; +// tp->imageOffset.y = sp.top; +// tp->imageOffset.z = 0; +// tp->imageExtent.width = sp.width; +// tp->imageExtent.height= sp.height; +// tp->imageExtent.depth = 1; +// +// offset+=sp.bytes; +// ++tp; +// } +// +// texture_cmd_buf->Begin(); +// bool result=CommitTexture2D(tex,buf,buffer_image_copy,ir_count,destinationStage); +// texture_cmd_buf->End(); +// SubmitTexture(*texture_cmd_buf); +// return result; +//} +// +//bool GPUDevice::ChangeTexture2D(Texture2D *tex,GPUBuffer *buf,uint32_t left,uint32_t top,uint32_t width,uint32_t height,VkPipelineStageFlags destinationStage) +//{ +// if(!tex||!buf +// ||left<0||left+width>tex->GetWidth() +// ||top<0||top+height>tex->GetHeight() +// ||width<=0||height<=0) +// return(false); +// +// BufferImageCopy buffer_image_copy(tex); +// +// texture_cmd_buf->Begin(); +// bool result=CommitTexture2D(tex,buf,&buffer_image_copy,1,destinationStage); +// texture_cmd_buf->End(); +// SubmitTexture(*texture_cmd_buf); +// return result; +//} +// +//bool GPUDevice::ChangeTexture2D(Texture2D *tex,void *data,uint32_t left,uint32_t top,uint32_t width,uint32_t height,uint32_t size,VkPipelineStageFlags destinationStage) +//{ +// if(!tex||!data +// ||left<0||left+width>tex->GetWidth() +// ||top<0||top+height>tex->GetHeight() +// ||width<=0||height<=0 +// ||size<=0) +// return(false); +// +// GPUBuffer *buf=CreateBuffer(VK_BUFFER_USAGE_TRANSFER_SRC_BIT,size,data); +// +// bool result=ChangeTexture2D(tex,buf,left,top,width,height,destinationStage); +// +// delete buf; +// return(result); +//} +VK_NAMESPACE_END \ No newline at end of file diff --git a/src/SceneGraph/Vulkan/Texture/VKTexture2DLoader.cpp b/src/SceneGraph/Vulkan/Texture/VKTexture2DLoader.cpp new file mode 100644 index 00000000..e8e9ece2 --- /dev/null +++ b/src/SceneGraph/Vulkan/Texture/VKTexture2DLoader.cpp @@ -0,0 +1,27 @@ +#include"VKTextureLoader.h" +#include +#include + +VK_NAMESPACE_BEGIN +template<> void VkTextureLoader::OnExtent(VkExtent3D &extent) +{ + extent.width =file_header.width; + extent.height =file_header.height; + extent.depth =1; +} + +template<> Texture2D *VkTextureLoader::OnCreateTexture(TextureCreateInfo *tci) +{ + return device->CreateTexture2D(tci); +} + +Texture2D *CreateTexture2DFromFile(GPUDevice *device,const OSString &filename,bool auto_mipmaps) +{ + VkTextureLoader loader(device,auto_mipmaps); + + if(!loader.Load(filename)) + return(nullptr); + + return loader.GetTexture(); +} +VK_NAMESPACE_END diff --git a/src/SceneGraph/Vulkan/Texture/VKTextureCubeLoader.cpp b/src/SceneGraph/Vulkan/Texture/VKTextureCubeLoader.cpp new file mode 100644 index 00000000..7d7322d5 --- /dev/null +++ b/src/SceneGraph/Vulkan/Texture/VKTextureCubeLoader.cpp @@ -0,0 +1,27 @@ +#include"VKTextureLoader.h" +#include +#include + +VK_NAMESPACE_BEGIN +template<> void VkTextureLoader::OnExtent(VkExtent3D &extent) +{ + extent.width =file_header.width; + extent.height =file_header.height; + extent.depth =1; +} + +template<> TextureCube *VkTextureLoader::OnCreateTexture(TextureCreateInfo *tci) +{ + return device->CreateTextureCube(tci); +} + +TextureCube *CreateTextureCubeFromFile(GPUDevice *device,const OSString &filename,bool auto_mipmaps) +{ + VkTextureLoader loader(device,auto_mipmaps); + + if(!loader.Load(filename)) + return(nullptr); + + return loader.GetTexture(); +} +VK_NAMESPACE_END diff --git a/src/SceneGraph/Vulkan/Texture/VKTextureLoader.h b/src/SceneGraph/Vulkan/Texture/VKTextureLoader.h new file mode 100644 index 00000000..cb0c8fee --- /dev/null +++ b/src/SceneGraph/Vulkan/Texture/VKTextureLoader.h @@ -0,0 +1,96 @@ +#pragma once +#include +#include +#include +#include +#include + +VK_NAMESPACE_BEGIN +template class VkTextureLoader:public TL +{ +protected: + + GPUDevice *device; + GPUBuffer *buf; + T *tex; + + bool auto_mipmaps; + +public: + + VkTextureLoader(GPUDevice *dev,const bool am) + { + device=dev; + buf=nullptr; + tex=nullptr; + auto_mipmaps=am; + } + + virtual ~VkTextureLoader() + { + SAFE_CLEAR(tex); + SAFE_CLEAR(buf); + } + + void *OnBegin(uint32 total_bytes) override + { + SAFE_CLEAR(buf); + + if(!CheckVulkanFormat(format)) + return(nullptr); + + buf=device->CreateBuffer(VK_BUFFER_USAGE_TRANSFER_SRC_BIT,total_bytes); + + if(!buf) + return(nullptr); + + return buf->Map(); + } + + void OnExtent(VkExtent3D &extent); + T *OnCreateTexture(TextureCreateInfo *); + + void OnEnd() override + { + buf->Unmap(); + + TextureCreateInfo *tci=new TextureCreateInfo(format); + + VkExtent3D extent; + + OnExtent(extent); + + tci->SetData(buf,extent); + + tci->origin_mipmaps=file_header.mipmaps; + + if(auto_mipmaps&&file_header.mipmaps<=1) + { + if(device->CheckFormatSupport(format,VK_FORMAT_FEATURE_BLIT_DST_BIT)) + { + tci->usage|=VK_IMAGE_USAGE_TRANSFER_SRC_BIT; + tci->SetAutoMipmaps(); + } + } + else + { + tci->target_mipmaps=file_header.mipmaps; + } + + tci->mipmap_zero_total_bytes=mipmap_zero_total_bytes; + + SAFE_CLEAR(tex); + tex=OnCreateTexture(tci); + + if(tex) + buf=nullptr; + } + + T *GetTexture() + { + T *result=tex; + tex=nullptr; + return result; + } +};//class VkTextureLoader +VK_NAMESPACE_END \ No newline at end of file diff --git a/src/SceneGraph/Vulkan/VKArrayBuffer.cpp b/src/SceneGraph/Vulkan/VKArrayBuffer.cpp new file mode 100644 index 00000000..fa286e73 --- /dev/null +++ b/src/SceneGraph/Vulkan/VKArrayBuffer.cpp @@ -0,0 +1,60 @@ +#include + +namespace hgl +{ + namespace graph + { + /** + * 本类构造函数 + * @param d 设备指针 + * @param s 单个数据长度 + * @param c 数据个数 + */ + GPUArrayBuffer::GPUArrayBuffer(GPUDevice *d,const uint32_t s,const uint32_t c) + { + device=d; + + item_size=s; + count=c; + alloc_count=power_to_2(c); + + buf_gpu=nullptr; + buf_cpu=nullptr; + offset=nullptr; + } + + GPUArrayBuffer::~GPUArrayBuffer() + { + SAFE_CLEAR_ARRAY(offset); + SAFE_CLEAR(buf_gpu); + } + + void GPUArrayBuffer::Clear() + { + count=0; + } + + bool GPUArrayBuffer::Init(const uint32_t c) + { + if(c<=0)return(false); + + if(!buf_gpu) + { + count=c; + alloc_count=power_to_2(count); + + total_bytes=item_size*alloc_count; + + if(total_bytes<=0)return(false); + + buf_gpu=device->CreateUBO(total_bytes); + buf_cpu=(uint8 *)(buf_gpu->Map()); + + offset=new uint32_t[alloc_count]; + } + else + { + } + } + }//namespace graph +}//namespace hgl diff --git a/src/RenderDevice/Vulkan/VKBuffer.cpp b/src/SceneGraph/Vulkan/VKBuffer.cpp similarity index 68% rename from src/RenderDevice/Vulkan/VKBuffer.cpp rename to src/SceneGraph/Vulkan/VKBuffer.cpp index f1e1aa3d..355b9758 100644 --- a/src/RenderDevice/Vulkan/VKBuffer.cpp +++ b/src/SceneGraph/Vulkan/VKBuffer.cpp @@ -1,7 +1,7 @@ -#include +#include VK_NAMESPACE_BEGIN -Buffer::~Buffer() +GPUBuffer::~GPUBuffer() { if(buf.memory)delete buf.memory; vkDestroyBuffer(device,buf.buffer,nullptr); diff --git a/src/SceneGraph/Vulkan/VKCommandBuffer.cpp b/src/SceneGraph/Vulkan/VKCommandBuffer.cpp new file mode 100644 index 00000000..1977c10c --- /dev/null +++ b/src/SceneGraph/Vulkan/VKCommandBuffer.cpp @@ -0,0 +1,47 @@ +#include +#include + +VK_NAMESPACE_BEGIN +GPUCmdBuffer::GPUCmdBuffer(const GPUDeviceAttribute *attr,VkCommandBuffer cb) +{ + dev_attr=attr; + cmd_buf=cb; +} + +GPUCmdBuffer::~GPUCmdBuffer() +{ + vkFreeCommandBuffers(dev_attr->device,dev_attr->cmd_pool,1,&cmd_buf); +} + +bool GPUCmdBuffer::Begin() +{ + CommandBufferBeginInfo cmd_buf_info; + + cmd_buf_info.pInheritanceInfo = nullptr; + + if(vkBeginCommandBuffer(cmd_buf, &cmd_buf_info)!=VK_SUCCESS) + return(false); + + return(true); +} + +#ifdef _DEBUG +void GPUCmdBuffer::SetDebugName(const char *object_name) +{ + if(dev_attr->debug_maker) + dev_attr->debug_maker->SetCommandBufferName(cmd_buf,object_name); +} + +void GPUCmdBuffer::BeginRegion(const char *region_name,const Color4f &color) +{ + if(dev_attr->debug_maker) + dev_attr->debug_maker->Begin(cmd_buf,region_name,color); +} + +void GPUCmdBuffer::EndRegion() +{ + if(dev_attr->debug_maker) + dev_attr->debug_maker->End(cmd_buf); +} +#endif +VK_NAMESPACE_END diff --git a/src/SceneGraph/Vulkan/VKCommandBufferRender.cpp b/src/SceneGraph/Vulkan/VKCommandBufferRender.cpp new file mode 100644 index 00000000..e26e2350 --- /dev/null +++ b/src/SceneGraph/Vulkan/VKCommandBufferRender.cpp @@ -0,0 +1,191 @@ +#include +#include +#include +#include +#include +#include + +VK_NAMESPACE_BEGIN +RenderCmdBuffer::RenderCmdBuffer(const GPUDeviceAttribute *attr,VkCommandBuffer cb):GPUCmdBuffer(attr,cb) +{ + cv_count=0; + clear_values=nullptr; + + hgl_zero(render_area); + hgl_zero(viewport); + + default_line_width=1.0; + + fbo=nullptr; + pipeline_layout=VK_NULL_HANDLE; +} + +RenderCmdBuffer::~RenderCmdBuffer() +{ + if(clear_values) + hgl_free(clear_values); +} + +void RenderCmdBuffer::SetFBO(Framebuffer *fb) +{ + if(fbo==fb)return; + + fbo=fb; + cv_count=fbo->GetAttachmentCount(); + + if(cv_count>0) + { + clear_values=hgl_align_realloc(clear_values,cv_count); + + clear_values[cv_count-1].depthStencil.depth = 1.0f; + clear_values[cv_count-1].depthStencil.stencil = 0; + } + else + { + if(clear_values) + { + hgl_free(clear_values); + clear_values=nullptr; + } + } + + render_area.offset.x=0; + render_area.offset.y=0; + render_area.extent.width=0; + render_area.extent.height=0; +} + +void RenderCmdBuffer::SetRenderArea(const VkExtent2D &ext2d) +{ + render_area.offset.x=0; + render_area.offset.y=0; + render_area.extent=ext2d; +} + +bool RenderCmdBuffer::BindFramebuffer(RenderPass *rp,Framebuffer *fb) +{ + if(!rp||!fb)return(false); + + SetFBO(fb); + + render_area.offset.x=0; + render_area.offset.y=0; + render_area.extent=fb->GetExtent(); + + rp_begin.renderPass = rp->GetVkRenderPass(); + rp_begin.framebuffer = *fb; + rp_begin.renderArea = render_area; + rp_begin.clearValueCount = cv_count; + rp_begin.pClearValues = clear_values; + + viewport.x = 0; + viewport.y = 0; + viewport.minDepth = 0.0f; + viewport.maxDepth = 1.0f; + viewport.width = render_area.extent.width; + viewport.height = render_area.extent.height; + + return(true); +}; + +bool RenderCmdBuffer::BeginRenderPass() +{ + vkCmdBeginRenderPass(cmd_buf, &rp_begin, VK_SUBPASS_CONTENTS_INLINE); + + vkCmdSetViewport(cmd_buf,0,1,&viewport); + vkCmdSetScissor(cmd_buf,0,1,&render_area); + vkCmdSetLineWidth(cmd_buf,default_line_width); + + pipeline_layout=VK_NULL_HANDLE; + + return(true); +} + +bool RenderCmdBuffer::BindDescriptorSets(RenderableInstance *ri) +{ + if(!ri)return(false); + + uint32_t *dynamic_offset=nullptr; + uint32_t dynamic_count=0; + + { + uint32_t count=0; + + MaterialParameters *mp; + VkDescriptorSet ds[(size_t)DescriptorSetsType::RANGE_SIZE]; + + ENUM_CLASS_FOR(DescriptorSetsType,int,i) + { + mp=ri->GetMP((DescriptorSetsType)i); + + if(mp) + { + ds[count]=mp->GetVkDescriptorSet(); + ++count; + + if((DescriptorSetsType)i==DescriptorSetsType::Renderable) + { + dynamic_count=mp->GetCount(); + + dynamic_offset=hgl_zero_new(dynamic_count); + } + } + } + + if(count>0) + { + pipeline_layout=ri->GetPipelineLayout(); + + vkCmdBindDescriptorSets(cmd_buf,VK_PIPELINE_BIND_POINT_GRAPHICS,pipeline_layout,0,count,ds,dynamic_count,dynamic_offset); + + SAFE_CLEAR_ARRAY(dynamic_offset); + } + } + + return(true); +} + +bool RenderCmdBuffer::BindVBO(RenderableInstance *ri) +{ + if(!ri) + return(false); + + const uint count=ri->GetBufferCount(); + + if(count<=0) + return(false); + + vkCmdBindVertexBuffers(cmd_buf,0,count,ri->GetBuffer(),ri->GetBufferSize()); + + IndexBuffer *indices_buffer=ri->GetIndexBuffer(); + + if(indices_buffer) + vkCmdBindIndexBuffer(cmd_buf,indices_buffer->GetBuffer(),ri->GetIndexBufferOffset(),VkIndexType(indices_buffer->GetType())); + + return(true); +} + +void RenderCmdBuffer::DrawIndirect( VkBuffer buffer, + VkDeviceSize offset, + uint32_t drawCount, + uint32_t stride) +{ + if(this->dev_attr->physical_device->SupportMDI()) + vkCmdDrawIndirect(cmd_buf,buffer,offset,drawCount,stride); + else + for(uint32_t i=0;idev_attr->physical_device->SupportMDI()) + vkCmdDrawIndexedIndirect(cmd_buf,buffer,offset,drawCount,stride); + else + for(uint32_t i=0;i + +VK_NAMESPACE_BEGIN +void DebugMaker::SetObjectName(uint64_t object, VkDebugReportObjectTypeEXT objectType, const char *name) +{ + // Check for valid function pointer (may not be present if not running in a debugging application) + if(!dmf.SetObjectName)return; + + VkDebugMarkerObjectNameInfoEXT nameInfo = {}; + nameInfo.sType = VK_STRUCTURE_TYPE_DEBUG_MARKER_OBJECT_NAME_INFO_EXT; + nameInfo.objectType = objectType; + nameInfo.object = object; + nameInfo.pObjectName = name; + + dmf.SetObjectName(device, &nameInfo); +} + +void DebugMaker::SetObjectTag(uint64_t object, VkDebugReportObjectTypeEXT objectType, uint64_t name, size_t tagSize, const void* tag) +{ + // Check for valid function pointer (may not be present if not running in a debugging application) + if(!dmf.SetObjectTag)return; + + VkDebugMarkerObjectTagInfoEXT tagInfo = {}; + tagInfo.sType = VK_STRUCTURE_TYPE_DEBUG_MARKER_OBJECT_TAG_INFO_EXT; + tagInfo.objectType = objectType; + tagInfo.object = object; + tagInfo.tagName = name; + tagInfo.tagSize = tagSize; + tagInfo.pTag = tag; + + dmf.SetObjectTag(device, &tagInfo); +} + +void DebugMaker::Begin(VkCommandBuffer cmdbuffer, const char * pMarkerName, const Color4f &color) +{ + //Check for valid function pointer (may not be present if not running in a debugging application) + if(!dmf.Begin)return; + + VkDebugMarkerMarkerInfoEXT markerInfo = {}; + markerInfo.sType = VK_STRUCTURE_TYPE_DEBUG_MARKER_MARKER_INFO_EXT; + memcpy(markerInfo.color, &color, sizeof(float) * 4); + markerInfo.pMarkerName = pMarkerName; + + dmf.Begin(cmdbuffer, &markerInfo); +} + +void DebugMaker::Insert(VkCommandBuffer cmdbuffer, const char *markerName, const Color4f &color) +{ + // Check for valid function pointer (may not be present if not running in a debugging application) + if(!dmf.Insert)return; + + VkDebugMarkerMarkerInfoEXT markerInfo = {}; + markerInfo.sType = VK_STRUCTURE_TYPE_DEBUG_MARKER_MARKER_INFO_EXT; + memcpy(markerInfo.color, &color, sizeof(float) * 4); + markerInfo.pMarkerName = markerName; + + dmf.Insert(cmdbuffer, &markerInfo); +} + +void DebugMaker::End(VkCommandBuffer cmdBuffer) +{ + // Check for valid function (may not be present if not running in a debugging application) + if(!dmf.End)return; + + dmf.End(cmdBuffer); +} + +DebugMaker *CreateDebugMaker(VkDevice device) +{ + DebugMakerFunction dmf; + + dmf.SetObjectTag = reinterpret_cast(vkGetDeviceProcAddr(device, "vkDebugMarkerSetObjectTagEXT")); + dmf.SetObjectName = reinterpret_cast(vkGetDeviceProcAddr(device, "vkDebugMarkerSetObjectNameEXT")); + dmf.Begin = reinterpret_cast(vkGetDeviceProcAddr(device, "vkCmdDebugMarkerBeginEXT")); + dmf.End = reinterpret_cast(vkGetDeviceProcAddr(device, "vkCmdDebugMarkerEndEXT")); + dmf.Insert = reinterpret_cast(vkGetDeviceProcAddr(device, "vkCmdDebugMarkerInsertEXT")); + + if(!dmf.SetObjectTag )return(nullptr); + if(!dmf.SetObjectName )return(nullptr); + if(!dmf.Begin )return(nullptr); + if(!dmf.End )return(nullptr); + if(!dmf.Insert )return(nullptr); + + return(new DebugMaker(device,dmf)); +} +VK_NAMESPACE_END \ No newline at end of file diff --git a/src/RenderDevice/Vulkan/VKDebugOut.cpp b/src/SceneGraph/Vulkan/VKDebugOut.cpp similarity index 95% rename from src/RenderDevice/Vulkan/VKDebugOut.cpp rename to src/SceneGraph/Vulkan/VKDebugOut.cpp index f7e3a358..86b43b90 100644 --- a/src/RenderDevice/Vulkan/VKDebugOut.cpp +++ b/src/SceneGraph/Vulkan/VKDebugOut.cpp @@ -1,4 +1,4 @@ -#include +#include #include VK_NAMESPACE_BEGIN @@ -85,8 +85,10 @@ namespace VkDebugUtilsMessageTypeFlagsEXT messageType, const VkDebugUtilsMessengerCallbackDataEXT *pCallbackData) { - if(messageSeverity&VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT) std::cerr<<"[ERROR] "; else - if(messageSeverity&VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT) std::cerr<<"[WARNING] "; else + if(messageSeverity&VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT) + std::cerr<<"[ERROR] "; else + if(messageSeverity&VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT) + std::cerr<<"[WARNING] "; else if(messageSeverity&VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT) std::cerr<<"[INFO] "; else if(messageSeverity&VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT) std::cerr<<"[VERBOSE] "; else std::cerr<<"[Validation layer] "; @@ -145,13 +147,15 @@ namespace { const char *obj_type_name=GetVkDebugReportObjectTypename(objType); - if(msgFlags&VK_DEBUG_REPORT_ERROR_BIT_EXT) std::cerr<<"[ERROR:"; else - if(msgFlags&VK_DEBUG_REPORT_WARNING_BIT_EXT) std::cerr<<"[WARNING:"; else + if(msgFlags&VK_DEBUG_REPORT_ERROR_BIT_EXT) + std::cerr<<"[ERROR:"; else + if(msgFlags&VK_DEBUG_REPORT_WARNING_BIT_EXT) + std::cerr<<"[WARNING:"; else if(msgFlags&VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT)std::cerr<<"[PERFORMANCE WARNING:"; else if(msgFlags&VK_DEBUG_REPORT_INFORMATION_BIT_EXT) std::cerr<<"[INFO:"; else if(msgFlags&VK_DEBUG_REPORT_DEBUG_BIT_EXT) std::cerr<<"[DEBUG:"; - std::cerr< +#include +#include +#include +#include + +VK_NAMESPACE_BEGIN +namespace +{ + struct WriteDescriptorSet:public vkstruct + { + public: + + WriteDescriptorSet(VkDescriptorSet desc_set,const uint32_t binding,const VkDescriptorType desc_type) + { + dstSet = desc_set; + dstBinding = binding; + dstArrayElement = 0; + descriptorCount = 1; + descriptorType = desc_type; + } + + WriteDescriptorSet(VkDescriptorSet desc_set,const uint32_t binding,const VkDescriptorBufferInfo *buf_info,const VkDescriptorType desc_type):WriteDescriptorSet(desc_set,binding,desc_type) + { + pImageInfo = nullptr; + pBufferInfo = buf_info; + pTexelBufferView = nullptr; + } + + WriteDescriptorSet(VkDescriptorSet desc_set,const uint32_t binding,const VkDescriptorImageInfo *img_info,const VkDescriptorType desc_type=VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER):WriteDescriptorSet(desc_set,binding,desc_type) + { + pImageInfo = img_info; + pBufferInfo = nullptr; + pTexelBufferView= nullptr; + } + };//struct WriteDescriptorSet + + struct DescriptorBufferInfo:public VkDescriptorBufferInfo + { + public: + + DescriptorBufferInfo(const GPUBuffer *buf,const VkDeviceSize off,const VkDeviceSize rng) + { + buffer=buf->GetBuffer(); + offset=off; + range=rng; + } + };//struct DescriptorBufferInfo:public VkDescriptorBufferInfo + + struct DescriptorImageInfo:public VkDescriptorImageInfo + { + public: + + DescriptorImageInfo(Texture *tex,Sampler *sam) + { + sampler=*sam; + imageView=tex->GetVulkanImageView(); + imageLayout=VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; + } + };//struct DescriptorImageInfo:public VkDescriptorImageInfo +}//namespace + +void DescriptorSets::Clear() +{ + buffer_list.ClearData(); + image_list.ClearData(); + wds_list.ClearData(); + binded_sets.ClearData(); + is_dirty=true; +} + +bool DescriptorSets::BindUBO(const int binding,const GPUBuffer *buf,bool dynamic) +{ + if(binding<0||!buf) + return(false); + + if(binded_sets.IsMember(binding))return(false); + + const VkDescriptorType desc_type=dynamic?VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; + + wds_list.Add(WriteDescriptorSet(desc_set,binding,buf->GetBufferInfo(),desc_type)); + + binded_sets.Add(binding); + is_dirty=true; + return(true); +} + +bool DescriptorSets::BindUBO(const int binding,const GPUBuffer *buf,const VkDeviceSize offset,const VkDeviceSize range,bool dynamic) +{ + if(binding<0||!buf) + return(false); + + if(binded_sets.IsMember(binding))return(false); + + DescriptorBufferInfo *buf_info=new DescriptorBufferInfo(buf,offset,range); + + buffer_list.Add(buf_info); + + const VkDescriptorType desc_type=dynamic?VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; + + wds_list.Add(WriteDescriptorSet(desc_set,binding,buf_info,desc_type)); + + binded_sets.Add(binding); + is_dirty=true; + return(true); +} + +bool DescriptorSets::BindSSBO(const int binding,const GPUBuffer *buf,bool dynamic) +{ + if(binding<0||!buf) + return(false); + + if(binded_sets.IsMember(binding))return(false); + + const VkDescriptorType desc_type=dynamic?VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:VK_DESCRIPTOR_TYPE_STORAGE_BUFFER; + + wds_list.Add(WriteDescriptorSet(desc_set,binding,buf->GetBufferInfo(),desc_type)); + + binded_sets.Add(binding); + is_dirty=true; + return(true); +} + +bool DescriptorSets::BindSSBO(const int binding,const GPUBuffer *buf,const VkDeviceSize offset,const VkDeviceSize range,bool dynamic) +{ + if(binding<0||!buf) + return(false); + + if(binded_sets.IsMember(binding))return(false); + + DescriptorBufferInfo *buf_info=new DescriptorBufferInfo(buf,offset,range); + + buffer_list.Add(buf_info); + + const VkDescriptorType desc_type=dynamic?VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:VK_DESCRIPTOR_TYPE_STORAGE_BUFFER; + + wds_list.Add(WriteDescriptorSet(desc_set,binding,buf_info,desc_type)); + + binded_sets.Add(binding); + is_dirty=true; + return(true); +} + +bool DescriptorSets::BindSampler(const int binding,Texture *tex,Sampler *sampler) +{ + if(binding<0||!tex||!sampler) + return(false); + + if(binded_sets.IsMember(binding))return(false); + + DescriptorImageInfo *image_info=new DescriptorImageInfo(tex,sampler); + + image_list.Add(image_info); + + wds_list.Add(WriteDescriptorSet(desc_set,binding,image_info)); + + binded_sets.Add(binding); + is_dirty=true; + return(true); +} + +bool DescriptorSets::BindInputAttachment(const int binding,Texture *tex) +{ + if(binding<0||!tex) + return(false); + + if(binded_sets.IsMember(binding))return(false); + + DescriptorImageInfo *image_info=new DescriptorImageInfo(tex,nullptr); + + image_list.Add(image_info); + + wds_list.Add(WriteDescriptorSet(desc_set,binding,image_info,VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT)); + + binded_sets.Add(binding); + is_dirty=true; + return(true); +} + +void DescriptorSets::Update() +{ + if(!is_dirty)return; + + vkUpdateDescriptorSets(device,wds_list.GetCount(),wds_list.GetData(),0,nullptr); + is_dirty=false; +} +VK_NAMESPACE_END diff --git a/src/SceneGraph/Vulkan/VKDevice.cpp b/src/SceneGraph/Vulkan/VKDevice.cpp new file mode 100644 index 00000000..997a8449 --- /dev/null +++ b/src/SceneGraph/Vulkan/VKDevice.cpp @@ -0,0 +1,154 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +VK_NAMESPACE_BEGIN +void LogSurfaceFormat(const List &surface_format_list) +{ + const uint32_t format_count=surface_format_list.GetCount(); + const VkSurfaceFormatKHR *sf=surface_format_list.GetData(); + + LOG_INFO(OS_TEXT("Current physics device support ")+OSString::valueOf(format_count)+OS_TEXT(" surface format")); + + const VulkanFormat *vf; + const VulkanColorSpace *cs; + + for(uint32_t i=0;iformat); + cs=GetVulkanColorSpace(sf->colorSpace); + + LOG_INFO(" "+AnsiString::valueOf(i)+": "+AnsiString(vf->name)+", "+AnsiString(cs->name)); + + ++sf; + } +} + +GPUDevice::GPUDevice(GPUDeviceAttribute *da) +{ + attr=da; + + texture_queue=nullptr; + texture_cmd_buf=nullptr; + + InitRenderPassManage(); + + swapchainRT=nullptr; + Resize(attr->surface_caps.currentExtent); + + texture_cmd_buf=CreateTextureCommandBuffer(); + texture_queue=CreateQueue(); + + LogSurfaceFormat(attr->surface_formats_list); +} + +GPUDevice::~GPUDevice() +{ + ClearRenderPassManage(); + + SAFE_CLEAR(swapchainRT); + + SAFE_CLEAR(texture_queue); + SAFE_CLEAR(texture_cmd_buf); + + delete attr; +} + +bool GPUDevice::Resize(const VkExtent2D &extent) +{ + SAFE_CLEAR(swapchainRT); + + attr->RefreshSurfaceCaps(); + + swapchainRT=CreateSwapchainRenderTarget(); + + return(true); +} + +VkCommandBuffer GPUDevice::CreateCommandBuffer() +{ + if(!attr->cmd_pool) + return(VK_NULL_HANDLE); + + CommandBufferAllocateInfo cmd; + + cmd.commandPool =attr->cmd_pool; + cmd.level =VK_COMMAND_BUFFER_LEVEL_PRIMARY; + cmd.commandBufferCount =1; + + VkCommandBuffer cmd_buf; + + VkResult res=vkAllocateCommandBuffers(attr->device,&cmd,&cmd_buf); + + if(res!=VK_SUCCESS) + return(VK_NULL_HANDLE); + + return cmd_buf; +} + +RenderCmdBuffer *GPUDevice::CreateRenderCommandBuffer() +{ + VkCommandBuffer cb=CreateCommandBuffer(); + + if(cb==VK_NULL_HANDLE)return(nullptr); + + return(new RenderCmdBuffer(attr,cb)); +} + +TextureCmdBuffer *GPUDevice::CreateTextureCommandBuffer() +{ + VkCommandBuffer cb=CreateCommandBuffer(); + + if(cb==VK_NULL_HANDLE)return(nullptr); + + return(new TextureCmdBuffer(attr,cb)); +} + +/** + * 创建栅栏 + * @param create_signaled 是否创建初始信号 + */ +GPUFence *GPUDevice::CreateFence(bool create_signaled) +{ + FenceCreateInfo fenceInfo(create_signaled?VK_FENCE_CREATE_SIGNALED_BIT:0); + + VkFence fence; + + if(vkCreateFence(attr->device, &fenceInfo, nullptr, &fence)!=VK_SUCCESS) + return(nullptr); + + return(new GPUFence(attr->device,fence)); +} + +GPUSemaphore *GPUDevice::CreateGPUSemaphore() +{ + SemaphoreCreateInfo SemaphoreCreateInfo; + + VkSemaphore sem; + + if(vkCreateSemaphore(attr->device, &SemaphoreCreateInfo, nullptr, &sem)!=VK_SUCCESS) + return(nullptr); + + return(new GPUSemaphore(attr->device,sem)); +} + +GPUQueue *GPUDevice::CreateQueue(const uint32_t fence_count,const bool create_signaled) +{ + if(fence_count<=0)return(nullptr); + + GPUFence **fence_list=new GPUFence *[fence_count]; + + for(uint32_t i=0;idevice,attr->graphics_queue,fence_list,fence_count)); +} +VK_NAMESPACE_END diff --git a/src/SceneGraph/Vulkan/VKDeviceAttribute.cpp b/src/SceneGraph/Vulkan/VKDeviceAttribute.cpp new file mode 100644 index 00000000..45a27aeb --- /dev/null +++ b/src/SceneGraph/Vulkan/VKDeviceAttribute.cpp @@ -0,0 +1,193 @@ +#include +#include +#include +#include +#include + +VK_NAMESPACE_BEGIN +void SavePipelineCacheData(VkDevice device,VkPipelineCache cache,const VkPhysicalDeviceProperties &pdp); + +GPUDeviceAttribute::GPUDeviceAttribute(VulkanInstance *inst,const GPUPhysicalDevice *pd,VkSurfaceKHR s) +{ + instance=inst; + physical_device=pd; + surface=s; + + RefreshSurfaceCaps(); + GetSurfaceFormatList(); + GetSurfacePresentMode(); + GetQueueFamily(); +} + +GPUDeviceAttribute::~GPUDeviceAttribute() +{ + if(pipeline_cache) + { + SavePipelineCacheData(device,pipeline_cache,physical_device->GetProperties()); + vkDestroyPipelineCache(device,pipeline_cache,nullptr); + } + + if(desc_pool) + vkDestroyDescriptorPool(device,desc_pool,nullptr); + + if(cmd_pool) + vkDestroyCommandPool(device,cmd_pool,nullptr); + + if(device) + vkDestroyDevice(device,nullptr); + + if(surface) + instance->DestroySurface(surface); +} + +int GPUDeviceAttribute::GetMemoryType(uint32_t typeBits,VkMemoryPropertyFlags properties) const +{ + return physical_device->GetMemoryType(typeBits,properties); +} + +void GPUDeviceAttribute::RefreshSurfaceCaps() +{ + VkPhysicalDevice pdevice = *physical_device; + + vkGetPhysicalDeviceSurfaceCapabilitiesKHR(pdevice, surface, &surface_caps); + + { + if (surface_caps.supportedTransforms & VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR) + preTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR; + else + preTransform = surface_caps.currentTransform; + } + + { + constexpr VkCompositeAlphaFlagBitsKHR compositeAlphaFlags[4]= + { + VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR, + VK_COMPOSITE_ALPHA_PRE_MULTIPLIED_BIT_KHR, + VK_COMPOSITE_ALPHA_POST_MULTIPLIED_BIT_KHR, + VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR + }; + + for(auto flags:compositeAlphaFlags) + if (surface_caps.supportedCompositeAlpha & flags) + { + compositeAlpha = flags; + break; + } + } +} + +void GPUDeviceAttribute::GetSurfaceFormatList() +{ + VkPhysicalDevice pdevice = *physical_device; + + { + uint32_t format_count; + + surface_format.format = PF_A2BGR10UN; + surface_format.colorSpace = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR; + + if (vkGetPhysicalDeviceSurfaceFormatsKHR(pdevice, surface, &format_count, nullptr) == VK_SUCCESS) + { + surface_formats_list.SetCount(format_count); + + if (vkGetPhysicalDeviceSurfaceFormatsKHR(pdevice, surface, &format_count, surface_formats_list.GetData()) != VK_SUCCESS) + { + surface_formats_list.Clear(); + } + //else + //{ + // VkSurfaceFormatKHR *sf = surface_formats_list.GetData(); + + // if (format_count == 1 && sf->format == VK_FORMAT_UNDEFINED) + // { + // } + // else + // { + // surface_format.format=VK_FORMAT_UNDEFINED; + + // for(uint32_t i=0;iformat>surface_format.format + // &&sf->colorSpace==VK_COLOR_SPACE_SRGB_NONLINEAR_KHR) + // surface_format=*sf; + + // ++sf; + // } + // } + //} + } + } +} + +void GPUDeviceAttribute::GetSurfacePresentMode() +{ + uint32_t mode_count; + + VkPhysicalDevice pdevice = *physical_device; + + if (!vkGetPhysicalDeviceSurfacePresentModesKHR(pdevice, surface, &mode_count, nullptr) == VK_SUCCESS) + return; + + present_modes.SetCount(mode_count); + + if (vkGetPhysicalDeviceSurfacePresentModesKHR(pdevice, surface, &mode_count, present_modes.GetData()) != VK_SUCCESS) + present_modes.Clear(); +} + +void GPUDeviceAttribute::GetQueueFamily() +{ + VkPhysicalDevice pdevice = *physical_device; + + uint32_t family_count; + vkGetPhysicalDeviceQueueFamilyProperties(pdevice, &family_count, nullptr); + family_properties.SetCount(family_count); + vkGetPhysicalDeviceQueueFamilyProperties(pdevice, &family_count, family_properties.GetData()); + + { + supports_present.SetCount(family_count); + VkBool32 *sp = supports_present.GetData(); + for (uint32_t i = 0; i < family_count; i++) + { + vkGetPhysicalDeviceSurfaceSupportKHR(pdevice, i, surface, sp); + ++sp; + } + } + + { + VkQueueFamilyProperties *fp = family_properties.GetData(); + VkBool32 *sp = supports_present.GetData(); + for (uint32_t i = 0; i < family_count; i++) + { + if (fp->queueFlags & VK_QUEUE_GRAPHICS_BIT) + { + if (graphics_family == ERROR_FAMILY_INDEX) + graphics_family = i; + + if (*sp) + { + graphics_family = i; + present_family = i; + break; + } + } + + ++fp; + ++sp; + } + } + + if (present_family == ERROR_FAMILY_INDEX) + { + VkBool32 *sp = supports_present.GetData(); + for (uint32_t i = 0; i < family_count; i++) + { + if (*sp) + { + present_family = i; + break; + } + ++sp; + } + } +} +VK_NAMESPACE_END diff --git a/src/RenderDevice/Vulkan/VKDeviceBuffer.cpp b/src/SceneGraph/Vulkan/VKDeviceBuffer.cpp similarity index 56% rename from src/RenderDevice/Vulkan/VKDeviceBuffer.cpp rename to src/SceneGraph/Vulkan/VKDeviceBuffer.cpp index bf6e76ad..aa90ee62 100644 --- a/src/RenderDevice/Vulkan/VKDeviceBuffer.cpp +++ b/src/SceneGraph/Vulkan/VKDeviceBuffer.cpp @@ -1,18 +1,23 @@ -#include -#include +#include +#include +#include +#include VK_NAMESPACE_BEGIN -bool Device::CreateBuffer(BufferData *buf,VkBufferUsageFlags buf_usage,VkDeviceSize size,const void *data,SharingMode sharing_mode) +const VkDeviceSize GPUDevice::GetUBOAlign() { - VkBufferCreateInfo buf_info={}; - buf_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; - buf_info.pNext = nullptr; + return attr->physical_device->GetUBOAlign(); +} + +bool GPUDevice::CreateBuffer(GPUBufferData *buf,VkBufferUsageFlags buf_usage,VkDeviceSize range,VkDeviceSize size,const void *data,SharingMode sharing_mode) +{ + BufferCreateInfo buf_info; + buf_info.usage = buf_usage; buf_info.size = size; buf_info.queueFamilyIndexCount = 0; buf_info.pQueueFamilyIndices = nullptr; buf_info.sharingMode = VkSharingMode(sharing_mode); - buf_info.flags = 0; if(vkCreateBuffer(attr->device,&buf_info,nullptr,&buf->buffer)!=VK_SUCCESS) return(false); @@ -21,19 +26,19 @@ bool Device::CreateBuffer(BufferData *buf,VkBufferUsageFlags buf_usage,VkDeviceS vkGetBufferMemoryRequirements(attr->device,buf->buffer,&mem_reqs); - Memory *dm=CreateMemory(mem_reqs,VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT|VK_MEMORY_PROPERTY_HOST_COHERENT_BIT); + GPUMemory *dm=CreateMemory(mem_reqs,VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT|VK_MEMORY_PROPERTY_HOST_COHERENT_BIT); if(dm&&dm->BindBuffer(buf->buffer)) { buf->info.buffer =buf->buffer; buf->info.offset =0; - buf->info.range =size; + buf->info.range =range; buf->memory =dm; if(!data) return(true); - + dm->Write(data,0,size); return(true); } @@ -44,27 +49,27 @@ bool Device::CreateBuffer(BufferData *buf,VkBufferUsageFlags buf_usage,VkDeviceS return(false); } -VAB *Device::CreateVAB(VkFormat format,uint32_t count,const void *data,SharingMode sharing_mode) +VBO *GPUDevice::CreateVBO(VkFormat format,uint32_t count,const void *data,SharingMode sharing_mode) { const uint32_t stride=GetStrideByFormat(format); if(stride==0) { - std::cerr<<"format["<device,buf,format,stride,count)); } -IndexBuffer *Device::CreateIBO(IndexType index_type,uint32_t count,const void *data,SharingMode sharing_mode) +IndexBuffer *GPUDevice::CreateIBO(IndexType index_type,uint32_t count,const void *data,SharingMode sharing_mode) { uint32_t stride; @@ -74,7 +79,7 @@ IndexBuffer *Device::CreateIBO(IndexType index_type,uint32_t count,const void *d const VkDeviceSize size=stride*count; - BufferData buf; + GPUBufferData buf; if(!CreateBuffer(&buf,VK_BUFFER_USAGE_INDEX_BUFFER_BIT,size,data,sharing_mode)) return(nullptr); @@ -82,13 +87,13 @@ IndexBuffer *Device::CreateIBO(IndexType index_type,uint32_t count,const void *d return(new IndexBuffer(attr->device,buf,index_type,count)); } -Buffer *Device::CreateBuffer(VkBufferUsageFlags buf_usage,VkDeviceSize size,const void *data,SharingMode sharing_mode) +GPUBuffer *GPUDevice::CreateBuffer(VkBufferUsageFlags buf_usage,VkDeviceSize range,VkDeviceSize size,const void *data,SharingMode sharing_mode) { - BufferData buf; + GPUBufferData buf; - if(!CreateBuffer(&buf,buf_usage,size,data,sharing_mode)) + if(!CreateBuffer(&buf,buf_usage,range,size,data,sharing_mode)) return(nullptr); - return(new Buffer(attr->device,buf)); + return(new GPUBuffer(attr->device,buf)); } VK_NAMESPACE_END diff --git a/src/RenderDevice/Vulkan/VKDeviceCreater.cpp b/src/SceneGraph/Vulkan/VKDeviceCreater.cpp similarity index 64% rename from src/RenderDevice/Vulkan/VKDeviceCreater.cpp rename to src/SceneGraph/Vulkan/VKDeviceCreater.cpp index 9d822530..a78308ba 100644 --- a/src/RenderDevice/Vulkan/VKDeviceCreater.cpp +++ b/src/SceneGraph/Vulkan/VKDeviceCreater.cpp @@ -1,57 +1,104 @@ #include #include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include #include #include VK_NAMESPACE_BEGIN -Swapchain *CreateSwapchain(const DeviceAttribute *attr,const VkExtent2D &acquire_extent); +VkPipelineCache CreatePipelineCache(VkDevice device,const VkPhysicalDeviceProperties &); +Swapchain *CreateSwapchain(const GPUDeviceAttribute *attr,const VkExtent2D &acquire_extent); + +#ifdef _DEBUG +DebugMaker *CreateDebugMaker(VkDevice); +#endif//_DEBUG namespace { - VkDevice CreateDevice(VkInstance instance,VkPhysicalDevice physical_device,uint32_t graphics_family) + void SetDeviceExtension(CharPointerList *ext_list,const GPUPhysicalDevice *physical_device) + { + ext_list->Add(VK_KHR_SWAPCHAIN_EXTENSION_NAME); + + constexpr char *require_ext_list[]= + { + #ifdef _DEBUG + VK_EXT_DEBUG_MARKER_EXTENSION_NAME, + #endif//_DEBUG + VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME, +// VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME, +// VK_EXT_HDR_METADATA_EXTENSION_NAME, +// VK_EXT_FULL_SCREEN_EXCLUSIVE_EXTENSION_NAME, +// VK_AMD_DISPLAY_NATIVE_HDR_EXTENSION_NAME, + +// VK_EXT_SAMPLER_FILTER_MINMAX_EXTENSION_NAME, + }; + + for(const char *ext_name:require_ext_list) + if(physical_device->CheckExtensionSupport(ext_name)) + ext_list->Add(ext_name); + } + + void SetDeviceFeatures(VkPhysicalDeviceFeatures *features,const VkPhysicalDeviceFeatures &pdf) + { + #define FEATURE_COPY(name) features->name=pdf.name; + + FEATURE_COPY(geometryShader); + FEATURE_COPY(multiDrawIndirect); + FEATURE_COPY(samplerAnisotropy); + +// FEATURE_COPY(imageCubeArray); +// FEATURE_COPY(fullDrawIndexUint32); +// FEATURE_COPY(wideLines) +// FEATURE_COPY(largePoints) + + #undef FEATURE_COPY + } + + VkDevice CreateDevice(VkInstance instance,const GPUPhysicalDevice *physical_device,uint32_t graphics_family) { float queue_priorities[1]={0.0}; VkDeviceQueueCreateInfo queue_info; - queue_info.sType=VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; - queue_info.pNext=nullptr; - queue_info.queueFamilyIndex=graphics_family; - queue_info.queueCount=1; - queue_info.pQueuePriorities=queue_priorities; - queue_info.flags=0; //如果这里写VK_DEVICE_QUEUE_CREATE_PROTECTED_BIT,会导致vkGetDeviceQueue调用崩溃 - - VkDeviceCreateInfo create_info={}; - const char *ext_list[1]={VK_KHR_SWAPCHAIN_EXTENSION_NAME}; + queue_info.sType =VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; + queue_info.pNext =nullptr; + queue_info.queueFamilyIndex =graphics_family; + queue_info.queueCount =1; + queue_info.pQueuePriorities =queue_priorities; + queue_info.flags =0; //如果这里写VK_DEVICE_QUEUE_CREATE_PROTECTED_BIT,会导致vkGetDeviceQueue调用崩溃 + VkDeviceCreateInfo create_info; + CharPointerList ext_list; VkPhysicalDeviceFeatures features={}; - features.geometryShader=true; - create_info.sType=VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO; - create_info.pNext=nullptr; - create_info.queueCreateInfoCount=1; - create_info.pQueueCreateInfos=&queue_info; - create_info.enabledExtensionCount=1; - create_info.ppEnabledExtensionNames=ext_list; - create_info.enabledLayerCount=0; - create_info.ppEnabledLayerNames=nullptr; - create_info.pEnabledFeatures=&features; + SetDeviceExtension(&ext_list,physical_device); + SetDeviceFeatures(&features,physical_device->GetFeatures10()); + + create_info.sType =VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO; + create_info.pNext =nullptr; + create_info.flags =0; + create_info.queueCreateInfoCount =1; + create_info.pQueueCreateInfos =&queue_info; + create_info.enabledExtensionCount =ext_list.GetCount(); + create_info.ppEnabledExtensionNames =ext_list.GetData(); + create_info.enabledLayerCount =0; + create_info.ppEnabledLayerNames =nullptr; + create_info.pEnabledFeatures =&features; VkDevice device; - if(vkCreateDevice(physical_device,&create_info,nullptr,&device)==VK_SUCCESS) + if(vkCreateDevice(*physical_device,&create_info,nullptr,&device)==VK_SUCCESS) return device; return nullptr; } - void GetDeviceQueue(DeviceAttribute *attr) + void GetDeviceQueue(GPUDeviceAttribute *attr) { vkGetDeviceQueue(attr->device,attr->graphics_family,0,&attr->graphics_queue); @@ -65,10 +112,10 @@ namespace { VkCommandPoolCreateInfo cmd_pool_info={}; - cmd_pool_info.sType=VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; - cmd_pool_info.pNext=nullptr; - cmd_pool_info.queueFamilyIndex=graphics_family; - cmd_pool_info.flags=VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT; //允许COMMAND被重复begin,如果没有此标记也可以正常用,但是会频繁报错 + cmd_pool_info.sType =VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; + cmd_pool_info.pNext =nullptr; + cmd_pool_info.queueFamilyIndex =graphics_family; + cmd_pool_info.flags =VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT; VkCommandPool cmd_pool; @@ -78,21 +125,21 @@ namespace return(VK_NULL_HANDLE); } - ImageView *Create2DImageView(VkDevice device,VkFormat format,const VkExtent2D &ext,VkImage img=VK_NULL_HANDLE) + ImageView *Create2DImageView(VkDevice device,VkFormat format,const VkExtent2D &ext,const uint32_t miplevel,VkImage img=VK_NULL_HANDLE) { VkExtent3D extent; copy(extent,ext); - return CreateImageView(device,VK_IMAGE_VIEW_TYPE_2D,format,extent,VK_IMAGE_ASPECT_COLOR_BIT,img); + return CreateImageView(device,VK_IMAGE_VIEW_TYPE_2D,format,extent,miplevel,VK_IMAGE_ASPECT_COLOR_BIT,img); } - ImageView *CreateDepthImageView(VkDevice device,VkFormat format,const VkExtent2D &ext,VkImage img=VK_NULL_HANDLE) + ImageView *CreateDepthImageView(VkDevice device,VkFormat format,const VkExtent2D &ext,const uint32_t miplevel,VkImage img=VK_NULL_HANDLE) { VkExtent3D extent; copy(extent,ext,1); - return CreateImageView(device,VK_IMAGE_VIEW_TYPE_2D,format,extent,VK_IMAGE_ASPECT_DEPTH_BIT,img); + return CreateImageView(device,VK_IMAGE_VIEW_TYPE_2D,format,extent,miplevel,VK_IMAGE_ASPECT_DEPTH_BIT,img); } VkDescriptorPool CreateDescriptorPool(VkDevice device,uint32_t sets_count) @@ -121,26 +168,11 @@ namespace return desc_pool; } - VkPipelineCache CreatePipelineCache(VkDevice device) - { - VkPipelineCacheCreateInfo pipelineCache; - pipelineCache.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO; - pipelineCache.pNext = nullptr; - pipelineCache.flags = 0; - pipelineCache.initialDataSize = 0; - pipelineCache.pInitialData = nullptr; - - VkPipelineCache cache; - - if(vkCreatePipelineCache(device, &pipelineCache, nullptr, &cache)!=VK_SUCCESS) - return(VK_NULL_HANDLE); - - return cache; - } - void DebugOut(const VkPhysicalDeviceFeatures &features) { - #define OUTPUT_PHYSICAL_DEVICE_FEATURE(name) std::cout<(pdp.vendorID).c_str()<(pdp.deviceID).c_str()<(pdp.pipelineCacheUUID); + if(memcmp(pdp.pipelineCacheUUID,"rdoc",4)==0) + { + std::cout<<"pipelineCahceUUID: "<<(char *)pdp.pipelineCacheUUID<(pdp.pipelineCacheUUID); - std::cout<<"pipelineCahceUUID: "<GetDriverId(); - - if(driver_id>=VK_DRIVER_ID_BEGIN_RANGE - &&driver_id<=VK_DRIVER_ID_END_RANGE) - { - std::cout<<"DriverID: "<GetDriverId()<GetDriverName()<GetDriverInfo()<GetProperties()); - DebugOut(physical_device->GetFeatures()); + DebugOut(physical_device->GetFeatures10()); + DebugOut(physical_device->GetFeatures11()); + DebugOut(physical_device->GetFeatures12()); } #endif//_DEBUG - DeviceAttribute *device_attr=new DeviceAttribute(inst,physical_device,surface); + GPUDeviceAttribute *device_attr=new GPUDeviceAttribute(inst,physical_device,surface); - AutoDelete auto_delete(device_attr); + AutoDelete auto_delete(device_attr); if(device_attr->graphics_family==ERROR_FAMILY_INDEX) return(nullptr); - device_attr->device=CreateDevice(inst,*physical_device,device_attr->graphics_family); + device_attr->device=CreateDevice(*inst,physical_device,device_attr->graphics_family); if(!device_attr->device) return(nullptr); +#ifdef _DEBUG + device_attr->debug_maker=CreateDebugMaker(device_attr->device); +#endif//_DEBUG + GetDeviceQueue(device_attr); device_attr->cmd_pool=CreateCommandPool(device_attr->device,device_attr->graphics_family); @@ -421,17 +527,17 @@ Device *CreateRenderDevice(VkInstance inst,const PhysicalDevice *physical_device if(!device_attr->desc_pool) return(nullptr); - device_attr->pipeline_cache=CreatePipelineCache(device_attr->device); + device_attr->pipeline_cache=CreatePipelineCache(device_attr->device,physical_device->GetProperties()); if(!device_attr->pipeline_cache) return(nullptr); auto_delete.Discard(); - return(new Device(device_attr)); + return(new GPUDevice(device_attr)); } -Device *CreateRenderDevice(vulkan::Instance *inst,Window *win,const vulkan::PhysicalDevice *pd) +GPUDevice *CreateRenderDevice(VulkanInstance *inst,Window *win,const GPUPhysicalDevice *pd) { if(!inst) return(nullptr); @@ -453,7 +559,7 @@ Device *CreateRenderDevice(vulkan::Instance *inst,Window *win,const vulkan::Phys extent.width=win->GetWidth(); extent.height=win->GetHeight(); - Device *device=CreateRenderDevice(*inst,pd,surface,extent); + GPUDevice *device=CreateRenderDevice(inst,pd,surface,extent); if(!device) { diff --git a/src/SceneGraph/Vulkan/VKDeviceFramebuffer.cpp b/src/SceneGraph/Vulkan/VKDeviceFramebuffer.cpp new file mode 100644 index 00000000..57a4b472 --- /dev/null +++ b/src/SceneGraph/Vulkan/VKDeviceFramebuffer.cpp @@ -0,0 +1,113 @@ +#include + +VK_NAMESPACE_BEGIN +VkFramebuffer CreateVulkanFramebuffer(VkDevice device,RenderPass *rp,const VkExtent2D &extent,VkImageView *attachments,const uint attachmentCount) +{ + FramebufferCreateInfo fb_info; + + fb_info.renderPass = rp->GetVkRenderPass(); + fb_info.attachmentCount = attachmentCount; + fb_info.pAttachments = attachments; + fb_info.width = extent.width; + fb_info.height = extent.height; + fb_info.layers = 1; + + VkFramebuffer fb; + + if(vkCreateFramebuffer(device,&fb_info,nullptr,&fb)!=VK_SUCCESS) + return(nullptr); + + return fb; +} + +Framebuffer *GPUDevice::CreateFramebuffer(RenderPass *rp,ImageView **color_list,const uint color_count,ImageView *depth) +{ + uint att_count=color_count; + + if(depth)++att_count; + + AutoDeleteArray attachments(att_count); + VkImageView *ap=attachments; + + if(color_count) + { + const List &cf_list=rp->GetColorFormat(); + + const VkFormat *cf=cf_list.GetData(); + ImageView **iv=color_list; + + for(uint i=0;iGetFormat()) + return(nullptr); + + *ap=**iv; + + ++ap; + ++cf; + ++iv; + } + } + + VkExtent2D extent; + + if(depth) + { + if(rp->GetDepthFormat()!=depth->GetFormat()) + { + delete[] attachments; + return(nullptr); + } + + attachments[color_count]=*depth; + + extent.width=depth->GetExtent().width; + extent.height=depth->GetExtent().height; + } + else + { + extent.width=color_list[0]->GetExtent().width; + extent.height=color_list[0]->GetExtent().height; + } + + VkFramebuffer fbo=CreateVulkanFramebuffer(GetDevice(),rp,extent,attachments,att_count); + + if(!fbo) + return(nullptr); + + return(new Framebuffer(GetDevice(),fbo,extent,rp->GetVkRenderPass(),color_count,depth)); +} +// +//Framebuffer *GPUDevice::CreateFramebuffer(RenderPass *rp,List &color,ImageView *depth) +//{ +// if(!rp)return(nullptr); +// +// if(rp->GetColorFormat().GetCount()!=color.GetCount())return(nullptr); +// +// if(color.GetCount()==0&&!depth)return(nullptr); +// +// return CreateFramebuffer(rp,color.GetData(),color.GetCount(),depth); +//} + +Framebuffer *GPUDevice::CreateFramebuffer(RenderPass *rp,ImageView *color,ImageView *depth) +{ + if(!rp)return(nullptr); + if(!color&&!depth)return(nullptr); + + return CreateFramebuffer(rp,&color,1,depth); +} + +Framebuffer *GPUDevice::CreateFramebuffer(RenderPass *rp,ImageView *iv) +{ + if(!rp)return(nullptr); + if(!iv)return(nullptr); + + if(iv->hasColor()) + return CreateFramebuffer(rp,&iv,1,nullptr); + else + if(iv->hasDepth()) + return CreateFramebuffer(rp,nullptr,0,iv); + else + return nullptr; +} +VK_NAMESPACE_END \ No newline at end of file diff --git a/src/SceneGraph/Vulkan/VKDeviceImage.cpp b/src/SceneGraph/Vulkan/VKDeviceImage.cpp new file mode 100644 index 00000000..fda808d7 --- /dev/null +++ b/src/SceneGraph/Vulkan/VKDeviceImage.cpp @@ -0,0 +1,25 @@ +#include +#include + +VK_NAMESPACE_BEGIN +VkImage GPUDevice::CreateImage(VkImageCreateInfo *ici) +{ + if(!ici)return(VK_NULL_HANDLE); + if(!CheckVulkanFormat(ici->format))return(VK_NULL_HANDLE); + if(ici->extent.width*ici->extent.height*ici->extent.depth*ici->arrayLayers<=0)return(VK_NULL_HANDLE); + + VkImage image; + + if(vkCreateImage(attr->device,ici, nullptr, &image)!=VK_SUCCESS) + return(nullptr); + + return image; +} + +void GPUDevice::DestroyImage(VkImage img) +{ + if(img==VK_NULL_HANDLE)return; + + vkDestroyImage(attr->device,img,nullptr); +} +VK_NAMESPACE_END diff --git a/src/SceneGraph/Vulkan/VKDeviceMaterial.cpp b/src/SceneGraph/Vulkan/VKDeviceMaterial.cpp new file mode 100644 index 00000000..2ac6c18e --- /dev/null +++ b/src/SceneGraph/Vulkan/VKDeviceMaterial.cpp @@ -0,0 +1,153 @@ +#include +#include +#include +#include +#include +#include +#include +#include"VKPipelineLayoutData.h" + +VK_NAMESPACE_BEGIN +DescriptorSets *GPUDevice::CreateDescriptorSets(const PipelineLayoutData *pld,const DescriptorSetsType &type)const +{ + ENUM_CLASS_RANGE_ERROR_RETURN_NULLPTR(type); + + const uint32_t binding_count=pld->binding_count[size_t(type)]; + + if(!binding_count) + return(nullptr); + + DescriptorSetAllocateInfo alloc_info; + + alloc_info.descriptorPool = attr->desc_pool; + alloc_info.descriptorSetCount = 1; + alloc_info.pSetLayouts = pld->layouts+size_t(type); + + VkDescriptorSet desc_set; + + if(vkAllocateDescriptorSets(attr->device,&alloc_info,&desc_set)!=VK_SUCCESS) + return(nullptr); + + return(new DescriptorSets(attr->device,binding_count,pld->pipeline_layout,desc_set)); +} + +MaterialParameters *GPUDevice::CreateMP(const MaterialDescriptorSets *mds,const PipelineLayoutData *pld,const DescriptorSetsType &desc_set_type) +{ + if(!mds||!pld)return(nullptr); + if(!RangeCheck(desc_set_type)) + return(nullptr); + + DescriptorSets *ds=CreateDescriptorSets(pld,desc_set_type); + + if(!ds)return(nullptr); + +#ifdef _DEBUG + const UTF8String addr_string=HexToString((uint64_t)(ds->GetDescriptorSet())); + + LOG_INFO(U8_TEXT("Create [DescriptSets:")+addr_string+("] OK! Material Name: \"")+mds->GetMaterialName()+U8_TEXT("\" Type: ")+GetDescriptorSetsTypeName(desc_set_type)); +#endif//_DEBUG + + return(new MaterialParameters(mds,desc_set_type,ds)); +} + +MaterialParameters *GPUDevice::CreateMP(Material *mtl,const DescriptorSetsType &desc_set_type) +{ + if(!mtl)return(nullptr); + + return CreateMP(mtl->GetDescriptorSets(),mtl->GetPipelineLayoutData(),desc_set_type); +} + +void CreateShaderStageList(List &shader_stage_list,ShaderModuleMap *shader_maps) +{ + const ShaderModule *sm; + + const int shader_count=shader_maps->GetCount(); + shader_stage_list.SetCount(shader_count); + + VkPipelineShaderStageCreateInfo *p=shader_stage_list.GetData(); + + auto **itp=shader_maps->GetDataList(); + for(int i=0;iright; + hgl_cpy(p,sm->GetCreateInfo()); + + ++p; + ++itp; + } +} + +Material *GPUDevice::CreateMaterial(const UTF8String &mtl_name,ShaderModuleMap *shader_maps,MaterialDescriptorSets *mds) +{ + const int shader_count=shader_maps->GetCount(); + + if(shader_count<2) + return(nullptr); + + const ShaderModule *vsm; + + if(!shader_maps->Get(VK_SHADER_STAGE_VERTEX_BIT,vsm)) + return(nullptr); + + PipelineLayoutData *pld=CreatePipelineLayoutData(mds); + + if(!pld) + { + delete shader_maps; + SAFE_CLEAR(mds); + return(nullptr); + } + + MaterialData *data=new MaterialData; + + data->name =mtl_name; + data->shader_maps =shader_maps; + data->mds =mds; + data->vertex_sm =(VertexShaderModule *)vsm; + + CreateShaderStageList(data->shader_stage_list,shader_maps); + + data->pipeline_layout_data=pld; + data->mp.m=CreateMP(mds,pld,DescriptorSetsType::Material ); + data->mp.r=CreateMP(mds,pld,DescriptorSetsType::Renderable ); + data->mp.g=CreateMP(mds,pld,DescriptorSetsType::Global ); + + return(new Material(data)); +} + +Material *GPUDevice::CreateMaterial(const UTF8String &mtl_name,const VertexShaderModule *vertex_shader_module,const ShaderModule *fragment_shader_module,MaterialDescriptorSets *mds) +{ + if(!vertex_shader_module||!fragment_shader_module) + return(nullptr); + + if(!vertex_shader_module->IsVertex())return(nullptr); + if(!fragment_shader_module->IsFragment())return(nullptr); + + ShaderModuleMap *smm=new ShaderModuleMap; + + smm->Add(vertex_shader_module); + smm->Add(fragment_shader_module); + + return CreateMaterial(mtl_name,smm,mds); +} + +Material *GPUDevice::CreateMaterial(const UTF8String &mtl_name,const VertexShaderModule *vertex_shader_module,const ShaderModule *geometry_shader_module,const ShaderModule *fragment_shader_module,MaterialDescriptorSets *mds) +{ + if(!vertex_shader_module + ||!geometry_shader_module + ||!fragment_shader_module) + return(nullptr); + + if(!vertex_shader_module->IsVertex())return(nullptr); + if(!geometry_shader_module->IsGeometry())return(nullptr); + if(!fragment_shader_module->IsFragment())return(nullptr); + + ShaderModuleMap *smm=new ShaderModuleMap; + + smm->Add(vertex_shader_module); + smm->Add(geometry_shader_module); + smm->Add(fragment_shader_module); + + return CreateMaterial(mtl_name,smm,mds); +} +VK_NAMESPACE_END diff --git a/src/SceneGraph/Vulkan/VKDeviceMemory.cpp b/src/SceneGraph/Vulkan/VKDeviceMemory.cpp new file mode 100644 index 00000000..c8fa1fd7 --- /dev/null +++ b/src/SceneGraph/Vulkan/VKDeviceMemory.cpp @@ -0,0 +1,22 @@ +#include + +VK_NAMESPACE_BEGIN +GPUMemory *GPUDevice::CreateMemory(VkImage image,const uint32_t flag) +{ + VkMemoryRequirements memReqs; + + vkGetImageMemoryRequirements(attr->device,image,&memReqs); + + GPUMemory *mem=CreateMemory(memReqs,flag); + + if(!mem)return(nullptr); + + if(!mem->BindImage(image)) + { + delete mem; + return(nullptr); + } + + return(mem); +} +VK_NAMESPACE_END diff --git a/src/SceneGraph/Vulkan/VKDeviceRenderPass.cpp b/src/SceneGraph/Vulkan/VKDeviceRenderPass.cpp new file mode 100644 index 00000000..7df6b7e1 --- /dev/null +++ b/src/SceneGraph/Vulkan/VKDeviceRenderPass.cpp @@ -0,0 +1,33 @@ +#include +#include +#include +#include + +VK_NAMESPACE_BEGIN +void GPUDevice::InitRenderPassManage() +{ + render_pass_manage=new DeviceRenderPassManage(attr->device,attr->pipeline_cache); + + SwapchainRenderbufferInfo rbi(attr->surface_format.format,attr->physical_device->GetDepthFormat()); + + device_render_pass=render_pass_manage->AcquireRenderPass(&rbi); +} + +void GPUDevice::ClearRenderPassManage() +{ + SAFE_CLEAR(render_pass_manage); +} + +RenderPass *GPUDevice::AcquireRenderPass(const RenderbufferInfo *rbi,const uint subpass_count) +{ + for(const VkFormat &fmt:rbi->GetColorFormatList()) + if(!attr->physical_device->IsColorAttachmentOptimal(fmt)) + return(nullptr); + + if(rbi->HasDepthOrStencil()) + if(!attr->physical_device->IsDepthAttachmentOptimal(rbi->GetDepthFormat())) + return(nullptr); + + return render_pass_manage->AcquireRenderPass(rbi,subpass_count); +} +VK_NAMESPACE_END diff --git a/src/SceneGraph/Vulkan/VKDeviceRenderPassManage.cpp b/src/SceneGraph/Vulkan/VKDeviceRenderPassManage.cpp new file mode 100644 index 00000000..976768ff --- /dev/null +++ b/src/SceneGraph/Vulkan/VKDeviceRenderPassManage.cpp @@ -0,0 +1,333 @@ +#include +#include + +VK_NAMESPACE_BEGIN +void CreateSubpassDependency(List &subpass_dependency_list,const uint32_t count) +{ + if(count<=0)return; + + subpass_dependency_list.SetCount(count); + + VkSubpassDependency *dependency=subpass_dependency_list.GetData(); + + dependency->srcSubpass = VK_SUBPASS_EXTERNAL; + dependency->dstSubpass = 0; + dependency->srcStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT; + dependency->srcAccessMask = VK_ACCESS_MEMORY_READ_BIT; + dependency->dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT; + + if(count==1) + { + dependency->dstStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT; + dependency->dstAccessMask = VK_ACCESS_MEMORY_READ_BIT; + } + else + { + dependency->dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; + dependency->dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; + + ++dependency; + + for(uint32_t i=1;isrcSubpass = i-1; + dependency->srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; + + if(i==count-1) + { + dependency->dstSubpass = VK_SUBPASS_EXTERNAL; + dependency->dstStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT; + dependency->srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; + dependency->dstAccessMask = VK_ACCESS_MEMORY_READ_BIT; + } + else + { + dependency->dstSubpass = i; + dependency->dstStageMask = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT; + dependency->srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; + dependency->dstAccessMask = VK_ACCESS_SHADER_READ_BIT; + } + + dependency->dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT; + + ++dependency; + } + } +} + +void CreateAttachmentReference(VkAttachmentReference *ref_list,uint start,uint count,VkImageLayout layout) +{ + VkAttachmentReference *ref=ref_list; + + for(uint i=start;iattachment =i; + ref->layout =layout; + + ++ref; + } +} + +inline void CreateColorAttachmentReference(VkAttachmentReference *ref_list, uint start,uint count) {CreateAttachmentReference(ref_list, start,count,VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);} +inline void CreateDepthAttachmentReference(VkAttachmentReference *depth_ref,uint index) {CreateAttachmentReference(depth_ref, index,1 ,VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);} +inline void CreateInputAttachmentReference(VkAttachmentReference *ref_list, uint start,uint count) {CreateAttachmentReference(ref_list, start,count,VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);} + +bool CreateAttachmentDescription(List &desc_list,const RenderbufferInfo *rbi) +{ + const uint color_count=rbi->GetColorCount(); + + const uint count=(rbi->HasDepthOrStencil())?color_count+1:color_count; + + desc_list.SetCount(count); + + VkAttachmentDescription *desc=desc_list.GetData(); + + for(uint i=0;iflags = 0; + desc->samples = VK_SAMPLE_COUNT_1_BIT; + desc->loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; //LOAD_OP_CLEARLOADʱ + desc->storeOp = VK_ATTACHMENT_STORE_OP_STORE; //STORE_OP_STROESOTREʱ + desc->stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; //DONT CAREʾ + desc->stencilStoreOp= VK_ATTACHMENT_STORE_OP_DONT_CARE; + desc->initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; //ijʼ + + ++desc; + } + + desc=desc_list.GetData(); + const VkFormat *cf=rbi->GetColorFormat(); + for(uint i=0;ifinalLayout = rbi->GetColorLayout(); + desc->format = *cf; + + ++desc; + ++cf; + } + + if(rbi->GetDepthFormat()!=PF_UNDEFINED) + { + desc->finalLayout = rbi->GetDepthLayout(); + desc->format = rbi->GetDepthFormat(); + desc->storeOp = rbi->IsSwapchain()?VK_ATTACHMENT_STORE_OP_DONT_CARE:VK_ATTACHMENT_STORE_OP_STORE; + } + + return(true); +} + +bool CreateColorAttachment( List &ref_list,List &desc_list,const List &color_format,const VkImageLayout color_final_layout=VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) +{ + //const VkFormat *cf=color_format_list.GetData(); + + //for(int i=0;iphysical_device->IsColorAttachmentOptimal(*cf)) + // return(false); + + // ++cf; + //} + + ref_list.SetCount(color_format.GetCount()); + VkAttachmentReference *ref=ref_list.GetData(); + + desc_list.SetCount(color_format.GetCount()); + VkAttachmentDescription *desc=desc_list.GetData(); + + for(int i=0;iflags = 0; + desc->samples = VK_SAMPLE_COUNT_1_BIT; + desc->loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; //LOAD_OP_CLEARLOADʱ + desc->storeOp = VK_ATTACHMENT_STORE_OP_STORE; //STORE_OP_STROESOTREʱ + desc->stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; //DONT CAREʾ + desc->stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; + desc->initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; //ijʼ + desc->finalLayout = color_final_layout; + ++desc; + + ref->attachment = i; + ref->layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + ++ref; + } + + return(true); +} + +bool CreateDepthAttachment( List &ref_list,List &desc_list,const VkFormat &depth_format,const VkImageLayout depth_final_layout=VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL) +{ + //if(!attr->physical_device->IsDepthAttachmentOptimal(depth_format)) + // return(false); + + { + ref_list.SetCount(1); + VkAttachmentReference *ref=ref_list.GetData(); + + ref->attachment=0; + ref->layout=VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; + } + + { + desc_list.SetCount(1); + VkAttachmentDescription *desc=desc_list.GetData(); + + desc->flags = 0; + desc->samples = VK_SAMPLE_COUNT_1_BIT; + desc->loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; //LOAD_OP_CLEARLOADʱ + desc->storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; //DONT CAREʾ + desc->stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; + desc->stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; + desc->initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; //ijʼ + desc->finalLayout = depth_final_layout; + } + + return(true); +} + +DeviceRenderPassManage::DeviceRenderPassManage(VkDevice dev,VkPipelineCache pc) +{ + device=dev; + pipeline_cache=pc; + + hash=util::CreateSHA1LEHash(); +} + +DeviceRenderPassManage::~DeviceRenderPassManage() +{ + SAFE_CLEAR(hash); + + const int count=RenderPassList.GetCount(); + + auto *obj=RenderPassList.GetDataList(); + + for(int i=0;iright; + + ++obj; + } + + RenderPassList.Clear(); +} + +namespace +{ +// void HashRenderPass(RenderPassHASHCode *code,const VkRenderPassCreateInfo &rpci) +// { +// util::Hash *hash=util::CreateSHA1LEHash(); +// +// hash->Init(); +// +//// hash->Write(rpci.attachmentCount); +// hash->Write(rpci.pAttachments,rpci.attachmentCount); +//// hash->Write(rpci.subpassCount); +// { +// const VkSubpassDescription *sd=rpci.pSubpasses; +// +// for(uint32_t i=0;iWrite(sd->pipelineBindPoint); +// hash->Write(sd->pInputAttachments,sd->inputAttachmentCount); +// hash->Write(sd->pColorAttachments,sd->colorAttachmentCount); +// +// if(sd->pResolveAttachments) +// hash->Write(*sd->pResolveAttachments); +// +// if(sd->pDepthStencilAttachment) +// hash->Write(*sd->pDepthStencilAttachment); +// +// hash->Write(sd->pPreserveAttachments,sd->preserveAttachmentCount); +// +// ++sd; +// } +// } +// +// hash->Write(rpci.pDependencies,rpci.dependencyCount); +// +// hash->Final(code); +// +// delete hash; +// } + + void HashRenderPass(RenderPassHASHCode *code,const RenderbufferInfo *rbi,const uint8 subpass_count) + { + util::Hash *hash=util::CreateSHA1LEHash(); + + hash->Init(); + + hash->Write(subpass_count); + + for(const VkFormat &fmt:rbi->GetColorFormatList()) + hash->Write(fmt); + + hash->Final(code); + delete hash; + } +} + +RenderPass *DeviceRenderPassManage::CreateRenderPass( const List &desc_list, + const List &subpass, + const List &dependency, + const RenderbufferInfo *rbi) +{ + const VkFormat depth_format=rbi->GetDepthFormat(); + + VkRenderPassCreateInfo rp_info; + rp_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; + rp_info.pNext = nullptr; + rp_info.flags = 0; + rp_info.attachmentCount = desc_list.GetCount(); + rp_info.pAttachments = desc_list.GetData(); + rp_info.subpassCount = subpass.GetCount(); + rp_info.pSubpasses = subpass.GetData(); + rp_info.dependencyCount = dependency.GetCount(); + rp_info.pDependencies = dependency.GetData(); + + VkRenderPass render_pass; + + if(vkCreateRenderPass(device,&rp_info,nullptr,&render_pass)!=VK_SUCCESS) + return(nullptr); + + return(new RenderPass(device,pipeline_cache,render_pass,rbi->GetColorFormatList(),depth_format)); +} + +RenderPass *DeviceRenderPassManage::AcquireRenderPass(const RenderbufferInfo *rbi,const uint subpass_count) +{ + RenderPassHASHCode hash; + RenderPass *rp=nullptr; + + HashRenderPass(&hash,rbi,subpass_count); + + if(RenderPassList.Get(hash,rp)) + return rp; + + List color_ref_list; + VkAttachmentReference depth_ref; + List atta_desc_list; + List subpass_desc_list; + List subpass_dependency_list; + + color_ref_list.SetCount(rbi->GetColorCount()); + CreateColorAttachmentReference(color_ref_list.GetData(),0,rbi->GetColorCount()); + + CreateAttachmentDescription(atta_desc_list,rbi); + + if(rbi->HasDepthOrStencil()) + { + CreateDepthAttachmentReference(&depth_ref,rbi->GetColorCount()); + subpass_desc_list.Add(SubpassDescription(color_ref_list.GetData(),color_ref_list.GetCount(),&depth_ref)); + } + else + { + subpass_desc_list.Add(SubpassDescription(color_ref_list.GetData(),color_ref_list.GetCount())); + } + + CreateSubpassDependency(subpass_dependency_list,subpass_count); + + rp=CreateRenderPass(atta_desc_list,subpass_desc_list,subpass_dependency_list,rbi); + + RenderPassList.Add(hash,rp); + + return rp; +} +VK_NAMESPACE_END diff --git a/src/SceneGraph/Vulkan/VKDeviceRenderTarget.cpp b/src/SceneGraph/Vulkan/VKDeviceRenderTarget.cpp new file mode 100644 index 00000000..82853f72 --- /dev/null +++ b/src/SceneGraph/Vulkan/VKDeviceRenderTarget.cpp @@ -0,0 +1,81 @@ +#include + +VK_NAMESPACE_BEGIN +RenderTarget *GPUDevice::CreateRenderTarget(const FramebufferInfo *fbi,RenderPass *rp,const uint32_t fence_count) +{ + if(!fbi)return(nullptr); + if(!rp)return(nullptr); + + const uint32_t color_count=fbi->GetColorCount(); + const VkExtent2D extent=fbi->GetExtent(); + const VkFormat depth_format=fbi->GetDepthFormat(); + + AutoDeleteObjectArray color_texture_list(color_count); + AutoDeleteArray color_iv_list(color_count); //iv只是从Texture2D中取出来的,无需一个个delete + + Texture2D **tp=color_texture_list; + ImageView **iv=color_iv_list; + + for(const VkFormat &fmt:fbi->GetColorFormatList()) + { + Texture2D *color_texture=CreateTexture2D(new ColorAttachmentTextureCreateInfo(fmt,extent)); + + if(!color_texture) + return(nullptr); + + *tp++=color_texture; + *iv++=color_texture->GetImageView(); + } + + Texture2D *depth_texture=(depth_format!=PF_UNDEFINED)?CreateTexture2D(new DepthAttachmentTextureCreateInfo(depth_format,extent)):nullptr; + + Framebuffer *fb=CreateFramebuffer(rp,color_iv_list,color_count,depth_texture?depth_texture->GetImageView():nullptr); + + if(fb) + { + GPUQueue *q=CreateQueue(fence_count,false); + GPUSemaphore *render_complete_semaphore=CreateGPUSemaphore(); + + RenderTarget *rt=new RenderTarget(q,render_complete_semaphore,rp,fb,color_texture_list,color_count,depth_texture); + + color_texture_list.DiscardObject(); + return rt; + } + + SAFE_CLEAR(depth_texture); + return nullptr; +} + +RenderTarget *GPUDevice::CreateRenderTarget(const FramebufferInfo *fbi,const uint32_t fence_count) +{ + if(!fbi)return(nullptr); + + RenderPass *rp=AcquireRenderPass(fbi); + + if(!rp)return(nullptr); + + return CreateRenderTarget(fbi,rp,fence_count); +} + +SwapchainRenderTarget *GPUDevice::CreateSwapchainRenderTarget() +{ + Swapchain *sc=CreateSwapchain(attr->surface_caps.currentExtent); + + if(!sc) + return(false); + + GPUQueue *q=CreateQueue(sc->color_count,false); + GPUSemaphore *render_complete_semaphore=CreateGPUSemaphore(); + GPUSemaphore *present_complete_semaphore=CreateGPUSemaphore(); + + SwapchainRenderTarget *srt=new SwapchainRenderTarget( attr->device, + sc, + q, + render_complete_semaphore, + present_complete_semaphore, + device_render_pass + ); + + return srt; +} +VK_NAMESPACE_END \ No newline at end of file diff --git a/src/SceneGraph/Vulkan/VKDeviceSampler.cpp b/src/SceneGraph/Vulkan/VKDeviceSampler.cpp new file mode 100644 index 00000000..e305ddf1 --- /dev/null +++ b/src/SceneGraph/Vulkan/VKDeviceSampler.cpp @@ -0,0 +1,80 @@ +#include +#include +VK_NAMESPACE_BEGIN +Sampler *GPUDevice::CreateSampler(VkSamplerCreateInfo *sci) +{ + static VkSamplerCreateInfo default_sampler_create_info= + { + VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, + nullptr, + 0, + VK_FILTER_LINEAR, + VK_FILTER_LINEAR, + VK_SAMPLER_MIPMAP_MODE_LINEAR, + VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, + VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, + VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, + 0.0f, + false, + 1.0f, + false, + VK_COMPARE_OP_NEVER, + 0.0f, + 0.0f, + VK_BORDER_COLOR_INT_OPAQUE_BLACK,//VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK, + false + }; + + if(!sci) + sci=&default_sampler_create_info; + + VkSampler sampler; + + sci->sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO; + + if(vkCreateSampler(attr->device,sci,nullptr,&sampler)!=VK_SUCCESS) + return(nullptr); + + return(new Sampler(attr->device,sampler)); +} + +Sampler *GPUDevice::CreateSampler(Texture *tex) +{ + VkSamplerCreateInfo sci= + { + VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, + nullptr, + 0, + VK_FILTER_LINEAR, + VK_FILTER_LINEAR, + VK_SAMPLER_MIPMAP_MODE_LINEAR, + VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, + VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, + VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, + 0.0f, + false, + 1.0f, + false, + VK_COMPARE_OP_NEVER, + 0.0f, + 0.0f, + VK_BORDER_COLOR_INT_OPAQUE_BLACK,//VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK, + false + }; + + VkSampler sampler; + + sci.anisotropyEnable = attr->physical_device->SupportSamplerAnisotropy(); + + if(sci.anisotropyEnable) + sci.maxAnisotropy = attr->physical_device->GetMaxSamplerAnisotropy(); + + if(tex) + sci.maxLod=tex->GetMipLevel(); + + if(vkCreateSampler(attr->device,&sci,nullptr,&sampler)!=VK_SUCCESS) + return(nullptr); + + return(new Sampler(attr->device,sampler)); +} +VK_NAMESPACE_END diff --git a/src/RenderDevice/Vulkan/VKDeviceSwapchain.cpp b/src/SceneGraph/Vulkan/VKDeviceSwapchain.cpp similarity index 52% rename from src/RenderDevice/Vulkan/VKDeviceSwapchain.cpp rename to src/SceneGraph/Vulkan/VKDeviceSwapchain.cpp index f088d0e6..b72e995c 100644 --- a/src/RenderDevice/Vulkan/VKDeviceSwapchain.cpp +++ b/src/SceneGraph/Vulkan/VKDeviceSwapchain.cpp @@ -1,21 +1,21 @@ -#include -#include -#include +#include +#include +#include VK_NAMESPACE_BEGIN namespace { - VkExtent2D SwapchainExtentClamp(const VkSurfaceCapabilitiesKHR &surface_caps,const VkExtent2D &acquire_extent) - { - VkExtent2D swapchain_extent; + //VkExtent2D SwapchainExtentClamp(const VkSurfaceCapabilitiesKHR &surface_caps,const VkExtent2D &acquire_extent) + //{ + // VkExtent2D swapchain_extent; - swapchain_extent.width =hgl_clamp(acquire_extent.width, surface_caps.minImageExtent.width, surface_caps.maxImageExtent.width ); - swapchain_extent.height =hgl_clamp(acquire_extent.height, surface_caps.minImageExtent.height, surface_caps.maxImageExtent.height ); + // swapchain_extent.width =hgl_clamp(acquire_extent.width, surface_caps.minImageExtent.width, surface_caps.maxImageExtent.width ); + // swapchain_extent.height =hgl_clamp(acquire_extent.height, surface_caps.minImageExtent.height, surface_caps.maxImageExtent.height ); - return swapchain_extent; - } + // return swapchain_extent; + //} - VkSwapchainKHR CreateSwapChain(const DeviceAttribute *dev_attr,const VkExtent2D &extent) + VkSwapchainKHR CreateSwapChain(const GPUDeviceAttribute *dev_attr,const VkExtent2D &extent) { VkSwapchainCreateInfoKHR swapchain_ci; @@ -24,8 +24,8 @@ namespace swapchain_ci.flags =0; swapchain_ci.surface =dev_attr->surface; swapchain_ci.minImageCount =3;//rsa->surface_caps.minImageCount; - swapchain_ci.imageFormat =dev_attr->format; - swapchain_ci.imageColorSpace =VK_COLOR_SPACE_SRGB_NONLINEAR_KHR; + swapchain_ci.imageFormat =dev_attr->surface_format.format; + swapchain_ci.imageColorSpace =dev_attr->surface_format.colorSpace; swapchain_ci.imageExtent =extent; swapchain_ci.imageArrayLayers =1; swapchain_ci.imageUsage =VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; @@ -68,70 +68,55 @@ namespace } }//namespace -bool Device::CreateSwapchainColorTexture() +bool GPUDevice::CreateSwapchainFBO(Swapchain *swapchain) { - if(vkGetSwapchainImagesKHR(attr->device,swapchain->swap_chain,&(swapchain->swap_chain_count),nullptr)!=VK_SUCCESS) + if(vkGetSwapchainImagesKHR(attr->device,swapchain->swap_chain,&(swapchain->color_count),nullptr)!=VK_SUCCESS) return(false); - AutoDeleteArray sc_images=new VkImage[swapchain->swap_chain_count]; + AutoDeleteArray sc_images(swapchain->color_count); - if(vkGetSwapchainImagesKHR(attr->device,swapchain->swap_chain,&(swapchain->swap_chain_count),sc_images)!=VK_SUCCESS) + if(vkGetSwapchainImagesKHR(attr->device,swapchain->swap_chain,&(swapchain->color_count),sc_images)!=VK_SUCCESS) return(false); - VkImage *ip=sc_images; - Texture2D *tex; + swapchain->sc_depth =CreateTexture2D(new SwapchainDepthTextureCreateInfo(attr->physical_device->GetDepthFormat(),swapchain->extent)); - for(uint32_t i=0; iswap_chain_count; i++) + if(!swapchain->sc_depth) + return(false); + + swapchain->sc_color =hgl_zero_new(swapchain->color_count); + swapchain->render_frame =hgl_zero_new(swapchain->color_count); + + for(uint32_t i=0;icolor_count;i++) { - tex=CreateTexture2D(attr->format, - swapchain->extent.width, - swapchain->extent.height, - VK_IMAGE_ASPECT_COLOR_BIT, - *ip, - VK_IMAGE_LAYOUT_UNDEFINED); + swapchain->sc_color[i]=CreateTexture2D(new SwapchainColorTextureCreateInfo(attr->surface_format.format,swapchain->extent,sc_images[i])); - swapchain->sc_color.Add(tex); + if(!swapchain->sc_color[i]) + return(false); - ++ip; + swapchain->render_frame[i]=CreateFramebuffer( device_render_pass, + swapchain->sc_color[i]->GetImageView(), + swapchain->sc_depth->GetImageView()); } return(true); } -bool Device::CreateSwapchainDepthTexture() +Swapchain *GPUDevice::CreateSwapchain(const VkExtent2D &acquire_extent) { - const VkFormat depth_format=attr->physical_device->GetDepthFormat(); - - const VkFormatProperties props=attr->physical_device->GetFormatProperties(depth_format); - - swapchain->sc_depth=CreateTexture2D(depth_format, - swapchain->extent.width, - swapchain->extent.height, - VK_IMAGE_ASPECT_DEPTH_BIT, - VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, - VK_IMAGE_LAYOUT_UNDEFINED, - (props.optimalTilingFeatures&VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT)?ImageTiling::Optimal:ImageTiling::Linear); - - return swapchain->sc_depth; -} - -bool Device::CreateSwapchain(const VkExtent2D &acquire_extent) -{ - swapchain=new Swapchain; + Swapchain *swapchain=new Swapchain; swapchain->device =attr->device; - swapchain->extent =SwapchainExtentClamp(attr->surface_caps,acquire_extent); - swapchain->graphics_queue =attr->graphics_queue; - swapchain->swap_chain =CreateSwapChain(attr,swapchain->extent); + swapchain->extent =acquire_extent; + + swapchain->swap_chain =CreateSwapChain(attr,acquire_extent); if(swapchain->swap_chain) - if(CreateSwapchainColorTexture()) - if(CreateSwapchainDepthTexture()) - return(true); + if(CreateSwapchainFBO(swapchain)) + return(swapchain); delete swapchain; swapchain=nullptr; - return(false); + return(nullptr); } VK_NAMESPACE_END diff --git a/src/RenderDevice/Vulkan/VKFence.cpp b/src/SceneGraph/Vulkan/VKFence.cpp similarity index 59% rename from src/RenderDevice/Vulkan/VKFence.cpp rename to src/SceneGraph/Vulkan/VKFence.cpp index 382d61e4..7eb3f66c 100644 --- a/src/RenderDevice/Vulkan/VKFence.cpp +++ b/src/SceneGraph/Vulkan/VKFence.cpp @@ -1,6 +1,6 @@ -#include +#include VK_NAMESPACE_BEGIN -Fence::~Fence() +GPUFence::~GPUFence() { vkDestroyFence(device,fence,nullptr); } diff --git a/src/SceneGraph/Vulkan/VKFramebuffer.cpp b/src/SceneGraph/Vulkan/VKFramebuffer.cpp new file mode 100644 index 00000000..eb2d086a --- /dev/null +++ b/src/SceneGraph/Vulkan/VKFramebuffer.cpp @@ -0,0 +1,30 @@ +#include +#include +#include +#include +#include +#include + +VK_NAMESPACE_BEGIN + +Framebuffer::Framebuffer(VkDevice dev,VkFramebuffer fb,const VkExtent2D &ext,VkRenderPass rp,uint32_t cc,bool depth) +{ + device=dev; + frame_buffer=fb; + render_pass=rp; + + extent=ext; + color_count=cc; + has_depth=depth; + + attachment_count=color_count; + + if(has_depth) + ++attachment_count; +} + +Framebuffer::~Framebuffer() +{ + vkDestroyFramebuffer(device,frame_buffer,nullptr); +} +VK_NAMESPACE_END diff --git a/src/SceneGraph/Vulkan/VKImageView.cpp b/src/SceneGraph/Vulkan/VKImageView.cpp new file mode 100644 index 00000000..4fb8d8ad --- /dev/null +++ b/src/SceneGraph/Vulkan/VKImageView.cpp @@ -0,0 +1,58 @@ +#include + +VK_NAMESPACE_BEGIN +ImageView::~ImageView() +{ + delete ivci; + vkDestroyImageView(device,image_view,nullptr); +} + +ImageView *CreateImageView(VkDevice device,VkImageViewType type,VkFormat format,const VkExtent3D &ext,const uint32_t &miplevel,VkImageAspectFlags aspectMask,VkImage img) +{ + ImageViewCreateInfo *iv_createinfo=new ImageViewCreateInfo; + + iv_createinfo->image =img; + iv_createinfo->format =format; + iv_createinfo->viewType =type; + iv_createinfo->subresourceRange.aspectMask =aspectMask; + iv_createinfo->subresourceRange.baseMipLevel =0; + iv_createinfo->subresourceRange.levelCount =miplevel; + iv_createinfo->subresourceRange.baseArrayLayer =0; + + if(type==VK_IMAGE_VIEW_TYPE_CUBE) + iv_createinfo->subresourceRange.layerCount =6; + else + if(type==VK_IMAGE_VIEW_TYPE_CUBE_ARRAY) + iv_createinfo->subresourceRange.layerCount =6*ext.depth; + else + iv_createinfo->subresourceRange.layerCount =ext.depth; + + if(aspectMask&VK_IMAGE_ASPECT_DEPTH_BIT) + { + if(format>=VK_FORMAT_D16_UNORM_S8_UINT) + iv_createinfo->subresourceRange.aspectMask|=VK_IMAGE_ASPECT_STENCIL_BIT; + + iv_createinfo->components.r=VK_COMPONENT_SWIZZLE_IDENTITY; + iv_createinfo->components.g=VK_COMPONENT_SWIZZLE_IDENTITY; + iv_createinfo->components.b=VK_COMPONENT_SWIZZLE_IDENTITY; + iv_createinfo->components.a=VK_COMPONENT_SWIZZLE_IDENTITY; + } + else + { + iv_createinfo->components.r=VK_COMPONENT_SWIZZLE_R; + iv_createinfo->components.g=VK_COMPONENT_SWIZZLE_G; + iv_createinfo->components.b=VK_COMPONENT_SWIZZLE_B; + iv_createinfo->components.a=VK_COMPONENT_SWIZZLE_A; + } + + VkImageView img_view; + + if(vkCreateImageView(device,iv_createinfo,nullptr,&img_view)!=VK_SUCCESS) + { + delete iv_createinfo; + return(nullptr); + } + + return(new ImageView(device,img_view,iv_createinfo,ext)); +} +VK_NAMESPACE_END diff --git a/src/SceneGraph/Vulkan/VKInstance.cpp b/src/SceneGraph/Vulkan/VKInstance.cpp new file mode 100644 index 00000000..7427202c --- /dev/null +++ b/src/SceneGraph/Vulkan/VKInstance.cpp @@ -0,0 +1,112 @@ +#include +#include +#include +#include +#include + +VK_NAMESPACE_BEGIN +GPUDevice *CreateRenderDevice(VkInstance,const GPUPhysicalDevice *,Window *); + +void CheckInstanceLayer(CharPointerList &layer_list,CreateInstanceLayerInfo *layer_info); + +VulkanInstance *CreateInstance(const AnsiString &app_name,VKDebugOut *out,CreateInstanceLayerInfo *layer_info) +{ + ApplicationInfo app_info; + InstanceCreateInfo inst_info(&app_info); + CharPointerList ext_list; + CharPointerList layer_list; + + app_info.pApplicationName = app_name.c_str(); + app_info.applicationVersion = 1; + app_info.pEngineName = "CMGameEngine/ULRE"; + app_info.engineVersion = 1; + app_info.apiVersion = VK_API_VERSION_1_0; + + ext_list.Add(VK_KHR_SURFACE_EXTENSION_NAME); + ext_list.Add(HGL_VK_SURFACE_EXTENSION_NAME); //此宏在VKSurfaceExtensionName.h中定义 + + constexpr char *require_ext_list[]= + { +#ifdef _DEBUG + VK_EXT_DEBUG_REPORT_EXTENSION_NAME, + VK_EXT_DEBUG_UTILS_EXTENSION_NAME, +#endif//_DEBUG + VK_EXT_SWAPCHAIN_COLOR_SPACE_EXTENSION_NAME, + VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, + VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME, + }; + + for(const char *ext_name:require_ext_list) + if(CheckInstanceExtensionSupport(ext_name)) + ext_list.Add(ext_name); + + if(layer_info) + { + CheckInstanceLayer(layer_list,layer_info); + } + + inst_info.enabledExtensionCount = ext_list.GetCount(); + inst_info.ppEnabledExtensionNames = ext_list.GetData(); + inst_info.enabledLayerCount = layer_list.GetCount(); + inst_info.ppEnabledLayerNames = layer_list.GetData(); + + VkInstance inst; + + if(vkCreateInstance(&inst_info,nullptr,&inst)!=VK_SUCCESS) + return(nullptr); + +#ifdef _DEBUG + if(!out) + out=new VKDebugOut; +#endif//_DEBUG + + if(out) + out->Init(inst); + + return(new VulkanInstance(inst,out)); +} + +VulkanInstance::VulkanInstance(VkInstance i,VKDebugOut *out) +{ + inst=i; + + debug_out=out; + + uint32_t gpu_count = 1; + + if(vkEnumeratePhysicalDevices(inst, &gpu_count, nullptr)==VK_SUCCESS) + { + VkPhysicalDevice *pd_list=new VkPhysicalDevice[gpu_count]; + vkEnumeratePhysicalDevices(inst, &gpu_count,pd_list); + + for(uint32_t i=0;iGetDeviceType()==type) + return(pd); + + return(nullptr); +} + +void VulkanInstance::DestroySurface(VkSurfaceKHR surface) +{ + vkDestroySurfaceKHR(inst,surface,nullptr); +} +VK_NAMESPACE_END diff --git a/src/SceneGraph/Vulkan/VKMaterial.cpp b/src/SceneGraph/Vulkan/VKMaterial.cpp new file mode 100644 index 00000000..033cb0a5 --- /dev/null +++ b/src/SceneGraph/Vulkan/VKMaterial.cpp @@ -0,0 +1,26 @@ +#include +#include +#include +#include"VKPipelineLayoutData.h" +VK_NAMESPACE_BEGIN +MaterialData::~MaterialData() +{ + SAFE_CLEAR(mp.m); + SAFE_CLEAR(mp.r); + SAFE_CLEAR(mp.g); + + delete shader_maps; + SAFE_CLEAR(mds); +} + +Material::~Material() +{ + delete data->pipeline_layout_data; + delete data; +} + +const VkPipelineLayout Material::GetPipelineLayout()const +{ + return data->pipeline_layout_data->pipeline_layout; +} +VK_NAMESPACE_END diff --git a/src/SceneGraph/Vulkan/VKMaterialDescriptorSets.cpp b/src/SceneGraph/Vulkan/VKMaterialDescriptorSets.cpp new file mode 100644 index 00000000..91bb74e9 --- /dev/null +++ b/src/SceneGraph/Vulkan/VKMaterialDescriptorSets.cpp @@ -0,0 +1,115 @@ +#include +#include + +VK_NAMESPACE_BEGIN +void WriteDescriptorSetLayoutBinding(VkDescriptorSetLayoutBinding *dslb,ShaderDescriptor *sd) +{ + dslb->binding =sd->binding; + dslb->descriptorType =sd->desc_type; + dslb->descriptorCount =1; + dslb->stageFlags =sd->stage_flag; + dslb->pImmutableSamplers=nullptr; +} + +MaterialDescriptorSets::MaterialDescriptorSets(const UTF8String &name,ShaderDescriptor *sd,const uint count) +{ + mtl_name=name; + + sd_list=sd; + sd_count=count; + + if(sd_count<=0)return; + + { + ENUM_CLASS_FOR(DescriptorSetsType,int,i) + { + sds[i].bindingCount=0; + sds[i].pBindings=nullptr; + } + + { + ShaderDescriptor *sp=sd_list; + + for(uint i=0;idesc_type>=VK_DESCRIPTOR_TYPE_BEGIN_RANGE + &&sp->desc_type<=VK_DESCRIPTOR_TYPE_END_RANGE) + descriptor_list[(size_t)sp->desc_type].Add(sp); + + sd_by_name.Add(sp->name,sp); + binding_map[size_t(sp->desc_type)].Add(sp->name,sp->binding); + + ++sds[size_t(sp->set_type)].bindingCount; + + ++sp; + } + } + + VkDescriptorSetLayoutBinding *sds_ptr[size_t(DescriptorSetsType::RANGE_SIZE)]; + + { + ENUM_CLASS_FOR(DescriptorSetsType,int,i) + if(sds[i].bindingCount>0) + { + sds[i].pBindings=new VkDescriptorSetLayoutBinding[sds[i].bindingCount]; + sds_ptr[i]=(VkDescriptorSetLayoutBinding *)sds[i].pBindings; + } + } + + { + ShaderDescriptorList *sdl=descriptor_list; + ShaderDescriptor **sdp; + + for(uint i=VK_DESCRIPTOR_TYPE_BEGIN_RANGE; + i<=VK_DESCRIPTOR_TYPE_END_RANGE;i++) + { + if(sdl->GetCount()>0) + { + binding_list[i]=new int[sdl->GetCount()]; + + sdp=sdl->GetData(); + for(int j=0;jGetCount();j++) + { + binding_list[i][j]=(*sdp)->binding; + + WriteDescriptorSetLayoutBinding(sds_ptr[size_t((*sdp)->set_type)], + *sdp); + + ++sds_ptr[size_t((*sdp)->set_type)]; + + ++sdp; + } + } + else + { + binding_list[i]=nullptr; + } + + ++sdl; + } + } + } +} + +MaterialDescriptorSets::~MaterialDescriptorSets() +{ + ENUM_CLASS_FOR(DescriptorSetsType,int,i) + if(sds[i].bindingCount) + delete[] sds[i].pBindings; + + delete[] sd_list; //"delete[] nullptr" isn't bug. +} + +const int MaterialDescriptorSets::GetBinding(const VkDescriptorType &desc_type,const AnsiString &name)const +{ + if(desc_typeVK_DESCRIPTOR_TYPE_END_RANGE) + return -1; + + if(name.IsEmpty())return -1; + + int result; + + return(binding_map[size_t(desc_type)].Get(name,result)?result:-1); +} +VK_NAMESPACE_END \ No newline at end of file diff --git a/src/SceneGraph/Vulkan/VKMaterialInstance.cpp b/src/SceneGraph/Vulkan/VKMaterialInstance.cpp new file mode 100644 index 00000000..9cee676b --- /dev/null +++ b/src/SceneGraph/Vulkan/VKMaterialInstance.cpp @@ -0,0 +1,47 @@ +#include +#include +#include +#include +#include + +VK_NAMESPACE_BEGIN +MaterialInstance *GPUDevice::CreateMI(Material *mtl,const VABConfigInfo *vab_cfg) +{ + if(!mtl)return(nullptr); + + VertexShaderModule *vsm=mtl->GetVertexShaderModule(); + + VAB *vab=vsm->CreateVAB(vab_cfg); + + if(!vab)return(nullptr); + + MaterialParameters *mp=CreateMP(mtl,DescriptorSetsType::Value); + + return(new MaterialInstance(mtl,vab,mp)); +} + +MaterialInstance::MaterialInstance(Material *mtl,VAB *v,MaterialParameters *p) +{ + material=mtl; + + vab=v; + + mp_value=p; +} + +MaterialInstance::~MaterialInstance() +{ + SAFE_CLEAR(mp_value); +} + +MaterialParameters *MaterialInstance::GetMP(const DescriptorSetsType &type) +{ + //if(type==DescriptorSetsType::Texture + // return mp_texture; + + if(type==DescriptorSetsType::Value) + return mp_value; + + return material->GetMP(type); +} +VK_NAMESPACE_END diff --git a/src/SceneGraph/Vulkan/VKMaterialParameters.cpp b/src/SceneGraph/Vulkan/VKMaterialParameters.cpp new file mode 100644 index 00000000..c33a4bb1 --- /dev/null +++ b/src/SceneGraph/Vulkan/VKMaterialParameters.cpp @@ -0,0 +1,71 @@ +#include +#include +#include +#include + +VK_NAMESPACE_BEGIN +MaterialParameters::MaterialParameters(const MaterialDescriptorSets *_mds,const DescriptorSetsType &type,DescriptorSets *ds) +{ + mds=_mds; + ds_type=type; + descriptor_sets=ds; +} + +MaterialParameters::~MaterialParameters() +{ + delete descriptor_sets; +} + +bool MaterialParameters::BindUBO(const AnsiString &name,GPUBuffer *ubo,bool dynamic) +{ + if(name.IsEmpty()||!ubo) + return(false); + + const int index=mds->GetUBO(name,dynamic); + + if(index<0) + return(false); + + if(!descriptor_sets->BindUBO(index,ubo,dynamic)) + return(false); + + return(true); +} + +bool MaterialParameters::BindSSBO(const AnsiString &name,GPUBuffer *ssbo,bool dynamic) +{ + if(name.IsEmpty()||!ssbo) + return(false); + + const int index=mds->GetSSBO(name,dynamic); + + if(index<0) + return(false); + + if(!descriptor_sets->BindSSBO(index,ssbo,dynamic)) + return(false); + + return(true); +} + +bool MaterialParameters::BindSampler(const AnsiString &name,Texture *tex,Sampler *sampler) +{ + if(name.IsEmpty()||!tex||!sampler) + return(false); + + const int index=mds->GetSampler(name); + + if(index<0) + return(false); + + if(!descriptor_sets->BindSampler(index,tex,sampler)) + return(false); + + return(true); +} + +void MaterialParameters::Update() +{ + descriptor_sets->Update(); +} +VK_NAMESPACE_END \ No newline at end of file diff --git a/src/SceneGraph/Vulkan/VKMemory.cpp b/src/SceneGraph/Vulkan/VKMemory.cpp new file mode 100644 index 00000000..0d7aee34 --- /dev/null +++ b/src/SceneGraph/Vulkan/VKMemory.cpp @@ -0,0 +1,103 @@ +#include +#include +#include +VK_NAMESPACE_BEGIN +GPUMemory *GPUDevice::CreateMemory(const VkMemoryRequirements &req,uint32_t properties) +{ + const int index=attr->physical_device->GetMemoryType(req.memoryTypeBits,properties); + + if(index<0) + return(nullptr); + + MemoryAllocateInfo alloc_info(index,req.size); + + VkDeviceMemory memory; + + if(vkAllocateMemory(attr->device,&alloc_info,nullptr,&memory)!=VK_SUCCESS) + return(nullptr); + + return(new GPUMemory(attr->device,memory,req,index,properties)); +} + +GPUMemory::GPUMemory(VkDevice dev,VkDeviceMemory dm,const VkMemoryRequirements &mr,const uint32 i,const uint32_t p) +{ + device=dev; + memory=dm; + req=mr; + index=i; + properties=p; + + memory_range.sType =VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE; + memory_range.pNext =nullptr; + memory_range.memory =memory; +} + +GPUMemory::~GPUMemory() +{ + vkFreeMemory(device,memory,nullptr); +} + +void *GPUMemory::Map() +{ + void *result; + + if(vkMapMemory(device,memory,0,req.size,0,&result)==VK_SUCCESS) + return result; + + return(nullptr); +} + +void *GPUMemory::Map(const VkDeviceSize offset,const VkDeviceSize size) +{ + if(offset<0||offset+size>=req.size) + return(nullptr); + + void *result; + + if(vkMapMemory(device,memory,offset,size,0,&result)==VK_SUCCESS) + return result; + + return(nullptr); +} + +void GPUMemory::Unmap() +{ + vkUnmapMemory(device,memory); +} + +void GPUMemory::Flush(VkDeviceSize offset,VkDeviceSize size) +{ + memory_range.offset =offset; + memory_range.size =size; + + vkFlushMappedMemoryRanges(device,1,&memory_range); +} + +bool GPUMemory::Write(const void *ptr,VkDeviceSize start,VkDeviceSize size) +{ + if(!ptr)return(false); + + void *dst; + + if(vkMapMemory(device,memory,start,size,0,&dst)!=VK_SUCCESS) + return(false); + + memcpy(dst,ptr,size); + vkUnmapMemory(device,memory); + return(true); +} + +bool GPUMemory::BindBuffer(VkBuffer buffer) +{ + if(!buffer)return(false); + + return(vkBindBufferMemory(device,buffer,memory,0)==VK_SUCCESS); +} + +bool GPUMemory::BindImage(VkImage image) +{ + if(!image)return(false); + + return(vkBindImageMemory(device,image,memory,0)==VK_SUCCESS); +} +VK_NAMESPACE_END diff --git a/src/SceneGraph/Vulkan/VKMemoryAllocator.cpp b/src/SceneGraph/Vulkan/VKMemoryAllocator.cpp new file mode 100644 index 00000000..e160d38e --- /dev/null +++ b/src/SceneGraph/Vulkan/VKMemoryAllocator.cpp @@ -0,0 +1,48 @@ +#include +#include +#include +#include + +VK_NAMESPACE_BEGIN +VKMemoryAllocator::VKMemoryAllocator(GPUDevice *d,const uint32_t flags,const VkDeviceSize r) +{ + device=d; + buffer_usage_flag_bits=flags; + gpu_buffer=nullptr; + range=r; + + SetAllocUnitSize(range); +} + +VKMemoryAllocator::~VKMemoryAllocator() +{ + if(gpu_buffer) + { + gpu_buffer->Unmap(); + delete gpu_buffer; + } +} + +bool VKMemoryAllocator::AllocMemory() +{ + if(gpu_buffer) + delete gpu_buffer; + + gpu_buffer=device->CreateBuffer(buffer_usage_flag_bits,range,alloc_size); + + if(!gpu_buffer) + { + memory_block=nullptr; + return(false); + } + + memory_block=gpu_buffer->Map(); + + return(true); +} + +void VKMemoryAllocator::Flush(const VkDeviceSize size) +{ + gpu_buffer->Flush(size); +} +VK_NAMESPACE_END diff --git a/src/SceneGraph/Vulkan/VKPhysicalDevice.cpp b/src/SceneGraph/Vulkan/VKPhysicalDevice.cpp new file mode 100644 index 00000000..c39c3d99 --- /dev/null +++ b/src/SceneGraph/Vulkan/VKPhysicalDevice.cpp @@ -0,0 +1,266 @@ +#include +#include + +VK_NAMESPACE_BEGIN +namespace +{ + void debug_queue_family_properties_out(const char *front,const List &qfp_list) + { + constexpr char *queue_bit_name[]= + { + "Graphics", + "Compute", + "Transfer", + "SparseBinding", + "Protected", + "VideoDecode", + "VideoEncode" + }; + + const int count=qfp_list.GetCount(); + + if(count<=0)return; + + const VkQueueFamilyProperties *p=qfp_list.GetData(); + + for(int i=0;iqueueCount + <<", timestampValidBits: "<timestampValidBits + <<", minImageTransferGranularity [" <minImageTransferGranularity.width<<"," + <minImageTransferGranularity.height<<"," + <minImageTransferGranularity.depth<<"], queueFlags["; + + uint32_t bits=p->queueFlags; + + for(uint i=0;i<7;i++) + { + if(bits&1) + { + std::cout<>=1; + if(bits>0)std::cout<<","; + } + else + { + bits>>=1; + } + } + + std::cout<<"]"<>=1; + } + + // No memory types matched, return failure + return -1; +} + +VkFormat GPUPhysicalDevice::GetDepthFormat(bool lower_to_high)const +{ + constexpr VkFormat depthFormats[] = + { + PF_D16UN, + PF_X8_D24UN, + PF_D16UN_S8U, + PF_D24UN_S8U, + PF_D32F, + PF_D32F_S8U + }; + + VkFormat result=VK_FORMAT_UNDEFINED; + + for (auto& format : depthFormats) + { + if(IsDepthAttachmentOptimal(format)) + { + if(lower_to_high) + return format; + else + result=format; + } + } + + return result; +} + +VkFormat GPUPhysicalDevice::GetDepthStencilFormat(bool lower_to_high)const +{ + constexpr VkFormat depthStencilFormats[] = + { + PF_D16UN_S8U, + PF_D24UN_S8U, + PF_D32F_S8U + }; + + VkFormat result=VK_FORMAT_UNDEFINED; + + for (auto& format : depthStencilFormats) + { + if(IsDepthAttachmentOptimal(format)) + { + if(lower_to_high) + return format; + else + result=format; + } + } + + return result; +} +VK_NAMESPACE_END \ No newline at end of file diff --git a/src/SceneGraph/Vulkan/VKPipeline.cpp b/src/SceneGraph/Vulkan/VKPipeline.cpp new file mode 100644 index 00000000..5a60a5b1 --- /dev/null +++ b/src/SceneGraph/Vulkan/VKPipeline.cpp @@ -0,0 +1,9 @@ +#include + +VK_NAMESPACE_BEGIN +Pipeline::~Pipeline() +{ + delete data; + vkDestroyPipeline(device,pipeline,nullptr); +} +VK_NAMESPACE_END diff --git a/src/SceneGraph/Vulkan/VKPipelineCache.cpp b/src/SceneGraph/Vulkan/VKPipelineCache.cpp new file mode 100644 index 00000000..f1ae611f --- /dev/null +++ b/src/SceneGraph/Vulkan/VKPipelineCache.cpp @@ -0,0 +1,104 @@ +#include +#include +#include +#include + +VK_NAMESPACE_BEGIN +namespace +{ + using namespace hgl::filesystem; + + const OSString GetUUIDCachePath(const VkPhysicalDeviceProperties &pdp) + { + OSString app_data; + + if(!GetLocalAppdataPath(app_data))return OS_TEXT(""); + + OSStringList sl; + + sl.Add(app_data); + sl.Add(OS_TEXT("VkPipelineCache.com")); + sl.Add(OSString::valueOf(VK_PIPELINE_CACHE_HEADER_VERSION_ONE)); + sl.Add(OSString::valueOf(pdp.vendorID)); + sl.Add(OSString::valueOf(pdp.deviceID)); + + return ComboFilename(sl); + } + + void LoadPipelineCacheFile(VkPipelineCacheCreateInfo *pcci,const VkPhysicalDeviceProperties &pdp) + { + if(!pcci)return; + + const OSString pathname=GetUUIDCachePath(pdp); + const OSString filename=VkUUID2String(pdp.pipelineCacheUUID); + const OSString fullname=MergeFilename(pathname,filename); + + if(!FileExist(fullname)) + { + pcci->initialDataSize=0; + pcci->pInitialData=nullptr; + + if(!IsDirectory(pathname)) + { + MakePath(pathname); + return; + } + } + else + { + int64 size; + pcci->pInitialData=LoadFileToMemory(fullname,size); + pcci->initialDataSize=size; + } + } +}//namespace + +VkPipelineCache CreatePipelineCache(VkDevice device,const VkPhysicalDeviceProperties &pdp) +{ + VkPipelineCacheCreateInfo pipelineCache; + + pipelineCache.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO; + pipelineCache.pNext = nullptr; + pipelineCache.flags = 0; + pipelineCache.initialDataSize = 0; + pipelineCache.pInitialData = nullptr; + + LoadPipelineCacheFile(&pipelineCache,pdp); + + VkPipelineCache cache; + + VkResult result=vkCreatePipelineCache(device, &pipelineCache, nullptr, &cache); + + if(pipelineCache.pInitialData) + delete[] (char *)pipelineCache.pInitialData; + + if(result==VK_SUCCESS) + return cache; + else + return(VK_NULL_HANDLE); +} + +void SavePipelineCacheData(VkDevice device,VkPipelineCache cache,const VkPhysicalDeviceProperties &pdp) +{ + size_t size = 0; + AutoDeleteArray data; + + if(vkGetPipelineCacheData(device, cache, &size, nullptr)!=VK_SUCCESS) + return; + + data.alloc(size); + + if(!vkGetPipelineCacheData(device, cache, &size, data)==VK_SUCCESS) + return; + + const OSString pathname=GetUUIDCachePath(pdp); + const OSString filename=VkUUID2String(pdp.pipelineCacheUUID); + const OSString fullname=MergeFilename(pathname,filename); + + if(!IsDirectory(pathname)) + if(!MakePath(pathname)) + return; + + SaveMemoryToFile(fullname,data,size); +} +VK_NAMESPACE_END diff --git a/src/SceneGraph/Vulkan/VKPipelineLayoutData.cpp b/src/SceneGraph/Vulkan/VKPipelineLayoutData.cpp new file mode 100644 index 00000000..09086047 --- /dev/null +++ b/src/SceneGraph/Vulkan/VKPipelineLayoutData.cpp @@ -0,0 +1,72 @@ +#include"VKPipelineLayoutData.h" +#include +#include +#include + +VK_NAMESPACE_BEGIN +PipelineLayoutData *GPUDevice::CreatePipelineLayoutData(const MaterialDescriptorSets *mds) +{ + PipelineLayoutData *pld=hgl_zero_new(); + + ENUM_CLASS_FOR(DescriptorSetsType,int,i) + { + const DescriptorSetLayoutCreateInfo *dslci=mds->GetBinding((DescriptorSetsType)i); + + if(!dslci||dslci->bindingCount<=0) + continue; + + if(pld->layouts[i]) + vkDestroyDescriptorSetLayout(attr->device,pld->layouts[i],nullptr); + + if(vkCreateDescriptorSetLayout(attr->device,dslci,nullptr,pld->layouts+i)!=VK_SUCCESS) + { + delete pld; + return(nullptr); + } + + pld->binding_count[i]=dslci->bindingCount; + + pld->fin_dsl[pld->fin_dsl_count]=pld->layouts[i]; + ++pld->fin_dsl_count; + } + + if(pld->fin_dsl_count<=0) + { + delete pld; + return(nullptr); + } + + //VkPushConstantRange push_constant_range; + + //push_constant_range.stageFlags = VK_SHADER_STAGE_VERTEX_BIT; + //push_constant_range.size = MAX_PUSH_CONSTANT_BYTES; + //push_constant_range.offset = 0; + + PipelineLayoutCreateInfo pPipelineLayoutCreateInfo; + + pPipelineLayoutCreateInfo.setLayoutCount = pld->fin_dsl_count; + pPipelineLayoutCreateInfo.pSetLayouts = pld->fin_dsl; + pPipelineLayoutCreateInfo.pushConstantRangeCount = 0;//1; + pPipelineLayoutCreateInfo.pPushConstantRanges = nullptr;//&push_constant_range; + + pld->device=attr->device; + + if(vkCreatePipelineLayout(attr->device,&pPipelineLayoutCreateInfo,nullptr,&(pld->pipeline_layout))!=VK_SUCCESS) + { + delete pld; + return(nullptr); + } + + return(pld); +} + +PipelineLayoutData::~PipelineLayoutData() +{ + vkDestroyPipelineLayout(device,pipeline_layout,nullptr); + + ENUM_CLASS_FOR(DescriptorSetsType,int,i) + if(layouts[i]) + vkDestroyDescriptorSetLayout(device,layouts[i],nullptr); +} +VK_NAMESPACE_END + diff --git a/src/SceneGraph/Vulkan/VKPipelineLayoutData.h b/src/SceneGraph/Vulkan/VKPipelineLayoutData.h new file mode 100644 index 00000000..957ca441 --- /dev/null +++ b/src/SceneGraph/Vulkan/VKPipelineLayoutData.h @@ -0,0 +1,24 @@ +#pragma once + +#include +#include +#include +#include +VK_NAMESPACE_BEGIN +struct PipelineLayoutData +{ + VkDevice device; + + int binding_count[size_t(DescriptorSetsType::RANGE_SIZE)]; + VkDescriptorSetLayout layouts[size_t(DescriptorSetsType::RANGE_SIZE)]; + + VkDescriptorSetLayout fin_dsl[size_t(DescriptorSetsType::RANGE_SIZE)]; + uint32_t fin_dsl_count; + + VkPipelineLayout pipeline_layout; + +public: + + ~PipelineLayoutData(); +};//class PipelineLayoutData +VK_NAMESPACE_END \ No newline at end of file diff --git a/src/RenderDevice/Vulkan/VKProperties.cpp b/src/SceneGraph/Vulkan/VKProperties.cpp similarity index 69% rename from src/RenderDevice/Vulkan/VKProperties.cpp rename to src/SceneGraph/Vulkan/VKProperties.cpp index 4c8f067a..fd5baaf0 100644 --- a/src/RenderDevice/Vulkan/VKProperties.cpp +++ b/src/SceneGraph/Vulkan/VKProperties.cpp @@ -1,5 +1,5 @@ -#include -#include +#include +#include VK_NAMESPACE_BEGIN @@ -12,7 +12,7 @@ namespace const List &GetLayerProperties(){return layer_properties;} const List &GetExtensionProperties(){return extension_properties;} -void InitVulkanProperties() +void InitVulkanInstanceProperties() { layer_properties.Clear(); extension_properties.Clear(); @@ -24,7 +24,7 @@ void InitVulkanProperties() layer_properties.SetCount(layer_count); vkEnumerateInstanceLayerProperties(&layer_count,layer_properties.GetData()); - debug_out(layer_properties); + debug_out("Instance",layer_properties); } { @@ -34,24 +34,33 @@ void InitVulkanProperties() extension_properties.SetCount(prop_count); vkEnumerateInstanceExtensionProperties(nullptr,&prop_count,extension_properties.GetData()); - debug_out(extension_properties); + debug_out("Instance",extension_properties); } } -const bool CheckLayerSupport(const char *layer_name) +const bool CheckInstanceLayerSupport(const AnsiString &layer_name) { if(!layer_name||!*layer_name) return(false); - const uint32_t count=layer_properties.GetCount(); - VkLayerProperties *lp=layer_properties.GetData(); - - for(uint32_t i=0;ilayerName)==0) + for(const VkLayerProperties &lp:layer_properties) + if(layer_name.Comp(lp.layerName)==0) return(true); - ++lp; + return(false); +} + +const bool GetInstanceLayerVersion(const AnsiString &name,uint32_t &spec,uint32_t &impl) +{ + for(const VkLayerProperties &lp:layer_properties) + { + if(name.Comp(lp.layerName)==0) + { + spec=lp.specVersion; + impl=lp.implementationVersion; + + return(true); + } } return(false); @@ -61,7 +70,7 @@ void CheckInstanceLayer(CharPointerList &layer_list,CreateInstanceLayerInfo *lay { #define VK_LAYER_CHECK(sname,lname,name) if(layer_info->sname.name) \ { \ - if(CheckLayerSupport("VK_LAYER_" lname "_" #name)) \ + if(CheckInstanceLayerSupport("VK_LAYER_" lname "_" #name)) \ layer_list.Add("VK_LAYER_" lname "_" #name); \ } @@ -95,4 +104,15 @@ void CheckInstanceLayer(CharPointerList &layer_list,CreateInstanceLayerInfo *lay VK_LAYER_BANDICAM_ADD(helper) } + +const bool CheckInstanceExtensionSupport(const AnsiString &name) +{ + for(const VkExtensionProperties &ep:extension_properties) + { + if(name.Comp(ep.extensionName)==0) + return true; + } + + return(false); +} VK_NAMESPACE_END diff --git a/src/SceneGraph/Vulkan/VKQueue.cpp b/src/SceneGraph/Vulkan/VKQueue.cpp new file mode 100644 index 00000000..19501573 --- /dev/null +++ b/src/SceneGraph/Vulkan/VKQueue.cpp @@ -0,0 +1,98 @@ +#include +#include + +VK_NAMESPACE_BEGIN +namespace +{ + const VkPipelineStageFlags pipe_stage_flags=VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; +}//namespace + +GPUQueue::GPUQueue(VkDevice dev,VkQueue q,GPUFence **fl,const uint32_t fc) +{ + device=dev; + queue=q; + + current_fence=0; + fence_list=fl; + fence_count=fc; + + submit_info.pWaitDstStageMask = &pipe_stage_flags; +} + +GPUQueue::~GPUQueue() +{ + SAFE_CLEAR_OBJECT_ARRAY(fence_list,fence_count) +} + +bool GPUQueue::WaitQueue() +{ + VkResult result=vkQueueWaitIdle(queue); + + if(result!=VK_SUCCESS) + return(false); + + return(true); +} + +bool GPUQueue::WaitFence(const bool wait_all,uint64_t time_out) +{ + VkResult result; + VkFence fence=*fence_list[current_fence]; + + result=vkWaitForFences(device,1,&fence,wait_all,time_out); + result=vkResetFences(device,1,&fence); + + if(++current_fence==fence_count) + current_fence=0; + + return(true); +} + +bool GPUQueue::Submit(const VkCommandBuffer *cmd_buf,const uint32_t cb_count,GPUSemaphore *wait_sem,GPUSemaphore *complete_sem) +{ + VkSemaphore ws; + VkSemaphore cs; + + if(wait_sem) + { + ws=*wait_sem; + + submit_info.waitSemaphoreCount =1; + submit_info.pWaitSemaphores =&ws; + } + else + { + submit_info.waitSemaphoreCount =0; + submit_info.pWaitSemaphores =nullptr; + } + + if(complete_sem) + { + cs=*complete_sem; + + submit_info.signalSemaphoreCount=1; + submit_info.pSignalSemaphores =&cs; + } + else + { + submit_info.signalSemaphoreCount=0; + submit_info.pSignalSemaphores =nullptr; + } + + submit_info.commandBufferCount =cb_count; + submit_info.pCommandBuffers =cmd_buf; + + VkFence fence=*fence_list[current_fence]; + + VkResult result=vkQueueSubmit(queue,1,&submit_info,fence); + + //不在这里立即等待fence完成,是因为有可能queue submit需要久一点工作时间,我们这个时间可以去干别的。等在AcquireNextImage时再去等待fence,而且是另一帧的fence。这样有利于异步处理 + + return(result==VK_SUCCESS); +} + +bool GPUQueue::Submit(const VkCommandBuffer &cmd_buf,GPUSemaphore *wait_sem,GPUSemaphore *complete_sem) +{ + return Submit(&cmd_buf,1,wait_sem,complete_sem); +} +VK_NAMESPACE_END diff --git a/src/SceneGraph/Vulkan/VKRenderContext.cpp b/src/SceneGraph/Vulkan/VKRenderContext.cpp new file mode 100644 index 00000000..e69de29b diff --git a/src/SceneGraph/Vulkan/VKRenderPass.cpp b/src/SceneGraph/Vulkan/VKRenderPass.cpp new file mode 100644 index 00000000..f0e7895c --- /dev/null +++ b/src/SceneGraph/Vulkan/VKRenderPass.cpp @@ -0,0 +1,113 @@ +#include +#include +#include +#include +#include +#include +VK_NAMESPACE_BEGIN +RenderPass::RenderPass(VkDevice d,VkPipelineCache pc,VkRenderPass rp,const List &cf,VkFormat df) +{ + device=d; + pipeline_cache=pc; + render_pass=rp; + color_formats=cf; + depth_format=df; + + vkGetRenderAreaGranularity(device,render_pass,&granularity); +} + +RenderPass::~RenderPass() +{ + pipeline_list.Clear(); + + vkDestroyRenderPass(device,render_pass,nullptr); +} + +Pipeline *RenderPass::CreatePipeline(Material *mtl,PipelineData *pd,const VAB *vab) +{ + VkPipeline graphicsPipeline; + + pd->InitShaderStage(mtl->GetStageList()); + pd->InitVertexInputState(vab); + + pd->SetColorAttachments(color_formats.GetCount()); + + pd->pipeline_info.layout = mtl->GetPipelineLayout(); + + { + pd->pipeline_info.renderPass = render_pass; + pd->pipeline_info.subpass = 0; //subpass由于还不知道有什么用,所以暂时写0,待知道功用后,需改进 + } + + if (vkCreateGraphicsPipelines( device, + pipeline_cache, + 1,&pd->pipeline_info, + nullptr, + &graphicsPipeline) != VK_SUCCESS) + { + delete pd; + return(nullptr); + } + + return(new Pipeline(device,graphicsPipeline,pd)); +} + +Pipeline *RenderPass::CreatePipeline(MaterialInstance *mi,const PipelineData *data) +{ + Material *mtl=mi->GetMaterial(); + + PipelineData *pd=new PipelineData(data); + + return CreatePipeline(mtl,pd,mi->GetVAB()); +} + +Pipeline *RenderPass::CreatePipeline(MaterialInstance *mi,const InlinePipeline &ip) +{ + const PipelineData *pd=GetPipelineData(ip); + + if(!pd)return(nullptr); + + return CreatePipeline(mi,pd); +} + +Pipeline *RenderPass::CreatePipeline(MaterialInstance *mi,const InlinePipeline &ip,const Prim &prim,const bool prim_restart) +{ + if(!mi)return(nullptr); + + const PipelineData *cpd=GetPipelineData(ip); + + PipelineData *pd=new PipelineData(cpd); + + pd->Set(prim,prim_restart); + + Pipeline *p=CreatePipeline(mi->GetMaterial(),pd,mi->GetVAB()); + + if(p) + pipeline_list.Add(p); + + return p; +} + +Pipeline *RenderPass::CreatePipeline(MaterialInstance *mi,const PipelineData *cpd,const Prim &prim,const bool prim_restart) +{ + PipelineData *pd=new PipelineData(cpd); + + pd->Set(prim,prim_restart); + + Pipeline *p=CreatePipeline(mi->GetMaterial(),pd,mi->GetVAB()); + + if(p) + pipeline_list.Add(p); + + return(p); +} + +Pipeline *RenderPass::CreatePipeline(MaterialInstance *mi,const OSString &pipeline_filename,const Prim &prim,const bool prim_restart) +{ + const PipelineData *pd=GetPipelineData(pipeline_filename); + + if(!pd)return(nullptr); + + return CreatePipeline(mi,pd,prim,prim_restart); +} +VK_NAMESPACE_END diff --git a/src/SceneGraph/Vulkan/VKRenderResource.cpp b/src/SceneGraph/Vulkan/VKRenderResource.cpp new file mode 100644 index 00000000..ab2653cd --- /dev/null +++ b/src/SceneGraph/Vulkan/VKRenderResource.cpp @@ -0,0 +1,171 @@ +#include +#include +#include +#include +#include + +VK_NAMESPACE_BEGIN +VBO *RenderResource::CreateVBO(VkFormat format,uint32_t count,const void *data,SharingMode sharing_mode) +{ + VBO *vb=device->CreateVBO(format,count,data,sharing_mode); + + if(!vb) + return(nullptr); + + rm_buffers.Add(vb); + + return vb; +} + +#define SCENE_DB_CREATE_BUFFER(name) GPUBuffer *RenderResource::Create##name(VkDeviceSize size,void *data,SharingMode sharing_mode) \ + { \ + GPUBuffer *buf=device->Create##name(size,data,sharing_mode); \ + \ + if(!buf)return(nullptr); \ + rm_buffers.Add(buf); \ + return(buf); \ + } \ + \ + GPUBuffer *RenderResource::Create##name(VkDeviceSize size,SharingMode sharing_mode) \ + { \ + GPUBuffer *buf=device->Create##name(size,sharing_mode); \ + \ + if(!buf)return(nullptr); \ + rm_buffers.Add(buf); \ + return(buf); \ + } + + SCENE_DB_CREATE_BUFFER(UBO) + SCENE_DB_CREATE_BUFFER(SSBO) + SCENE_DB_CREATE_BUFFER(INBO) + +#undef SCENE_DB_CREATE_BUFFER + +IndexBuffer *RenderResource::CreateIBO(IndexType index_type,uint32_t count,const void *data,SharingMode sharing_mode) +{ + IndexBuffer *buf=device->CreateIBO(index_type,count,data,sharing_mode); + + if(!buf)return(nullptr); + rm_buffers.Add(buf); + return(buf); +} + +MaterialInstance *RenderResource::CreateMaterialInstance(Material *mtl,const VABConfigInfo *vab_cfg) +{ + if(!mtl)return(nullptr); + + MaterialInstance *mi=device->CreateMI(mtl,vab_cfg); + + if(mi) + Add(mi); + + return mi; +} + +MaterialInstance *RenderResource::CreateMaterialInstance(const OSString &mtl_filename,const VABConfigInfo *vab_cfg) +{ + Material *mtl=this->CreateMaterial(mtl_filename); + + if(!mtl) + return(nullptr); + + return CreateMaterialInstance(mtl,vab_cfg); +} + +Renderable *RenderResource::CreateRenderable(const uint32_t vertex_count) +{ + if(!vertex_count)return(nullptr); + + Renderable *ro=new Renderable(vertex_count); + + if(ro) + Add(ro); + + return ro; +} + +TextRenderable *RenderResource::CreateTextRenderable(Material *mtl) +{ + if(!mtl)return(nullptr); + + TextRenderable *tr=new TextRenderable(device,mtl); + + if(tr) + Add(tr); + + return tr; +} + +RenderableInstance *RenderResource::CreateRenderableInstance(Renderable *r,MaterialInstance *mi,Pipeline *p) +{ + if(!p||!mi||!r) + return(nullptr); + + RenderableInstance *ri=VK_NAMESPACE::CreateRenderableInstance(r,mi,p); + + if(ri) + Add(ri); + + return ri; +} + +Sampler *RenderResource::CreateSampler(VkSamplerCreateInfo *sci) +{ + Sampler *s=device->CreateSampler(sci); + + if(s) + Add(s); + + return s; +} + +Sampler *RenderResource::CreateSampler(Texture *tex) +{ + Sampler *s=device->CreateSampler(tex); + + if(s) + Add(s); + + return s; +} + +Texture2D *CreateTexture2DFromFile(GPUDevice *device,const OSString &filename,bool auto_mipmaps); + +Texture2D *RenderResource::LoadTexture2D(const OSString &filename,bool auto_mipmaps) +{ + Texture2D *tex; + + if(texture_by_name.Get(filename,(Texture *&)tex)) + return tex; + + tex=CreateTexture2DFromFile(device,filename,auto_mipmaps); + + if(tex) + { + texture_by_name.Add(filename,tex); + Add(tex); + } + + return tex; +} + +TextureCube *CreateTextureCubeFromFile(GPUDevice *device,const OSString &filename,bool auto_mipmaps); + +TextureCube *RenderResource::LoadTextureCube(const OSString &filename,bool auto_mipmaps) +{ + TextureCube *tex; + + if(texture_by_name.Get(filename,(Texture *&)tex)) + return tex; + + tex=CreateTextureCubeFromFile(device,filename,auto_mipmaps); + + if(tex) + { + texture_by_name.Add(filename,tex); + Add(tex); + } + + return tex; +} +VK_NAMESPACE_END diff --git a/src/SceneGraph/Vulkan/VKRenderResourceMaterial.cpp b/src/SceneGraph/Vulkan/VKRenderResourceMaterial.cpp new file mode 100644 index 00000000..2e6207c7 --- /dev/null +++ b/src/SceneGraph/Vulkan/VKRenderResourceMaterial.cpp @@ -0,0 +1,171 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +VK_NAMESPACE_BEGIN + +const ShaderModule *RenderResource::CreateShaderModule(const OSString &filename,ShaderResource *shader_resource) +{ + if(!device)return(nullptr); + if(filename.IsEmpty())return(nullptr); + if(!shader_resource)return(nullptr); + + ShaderModule *sm; + + if(shader_module_by_name.Get(filename,sm)) + return sm; + + sm=device->CreateShaderModule(shader_resource); + + shader_module_by_name.Add(filename,sm); + + return sm; +} + +void LoadShaderDescriptor(const uint8 *data,ShaderDescriptor *sd_list,const uint count) +{ + ShaderDescriptor *sd=sd_list; + uint str_len; + + for(uint i=0;idesc_type=VkDescriptorType(*data++); + + { + str_len=*data++; + memcpy(sd->name,(char *)data,str_len); + data+=str_len; + } + + sd->set =*data++; + sd->binding =*data++; + sd->stage_flag =*(uint32 *)data; + data+=sizeof(uint32); + + sd->set_type=CheckDescriptorSetsType(sd->name); + + if(sd->set_type==DescriptorSetsType::Renderable) + { + if(sd->desc_type==VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER)sd->desc_type=VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;else + if(sd->desc_type==VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)sd->desc_type=VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC; + } + + ++sd; + } +} + +Material *RenderResource::CreateMaterial(const OSString &filename) +{ + Material *mtl; + + if(material_by_name.Get(filename,mtl)) + return mtl; + + constexpr char MaterialFileHeader[]=u8"Material\x1A"; + constexpr uint MaterialFileHeaderLength=sizeof(MaterialFileHeader)-1; + + int64 filesize; + uint8 *filedata=(uint8 *)filesystem::LoadFileToMemory(filename+OS_TEXT(".material"),filesize); + + if(!filedata) + { + material_by_name.Add(filename,nullptr); + return(nullptr); + } + + AutoDeleteArray origin_filedata(filedata,filesize); + + if(filesizeGetStageName()); + + sm=CreateShaderModule(shader_name,sr); + + if(sm) + { + if(smm->Add(sm)) + continue; + } + } + + result=false; + break; + } + + const UTF8String mtl_name=ToUTF8String(filename); + + MaterialDescriptorSets *mds=nullptr; + { + const uint8 count=*sp; + ++sp; + + if(count>0) + { + ShaderDescriptor *sd_list=hgl_zero_new(count); + + LoadShaderDescriptor(sp,sd_list,count); + + mds=new MaterialDescriptorSets(mtl_name,sd_list,count); + } + } + + if(result) + { + mtl=device->CreateMaterial(mtl_name,smm,mds); + Add(mtl); + } + else + { + SAFE_CLEAR(mds); + delete smm; + mtl=nullptr; + } + + material_by_name.Add(filename,mtl); + return(mtl); +} +VK_NAMESPACE_END diff --git a/src/SceneGraph/Vulkan/VKRenderTarget.cpp b/src/SceneGraph/Vulkan/VKRenderTarget.cpp new file mode 100644 index 00000000..2e61bc50 --- /dev/null +++ b/src/SceneGraph/Vulkan/VKRenderTarget.cpp @@ -0,0 +1,66 @@ +#include +#include +#include +#include +#include +#include + +VK_NAMESPACE_BEGIN +RenderTarget::RenderTarget(GPUQueue *q,GPUSemaphore *s) +{ + queue=q; + render_pass=nullptr; + fbo=nullptr; + + color_count=0; + color_textures=nullptr; + depth_texture=nullptr; + render_complete_semaphore=s; +} + +RenderTarget::RenderTarget(GPUQueue *q,GPUSemaphore *s,RenderPass *_rp,Framebuffer *_fb,Texture2D **ctl,const uint32_t cc,Texture2D *dt) +{ + queue=q; + render_pass=_rp; + fbo=_fb; + + depth_texture=dt; + + color_count=cc; + if(color_count>0) + { + color_textures=new Texture2D *[color_count]; + hgl_cpy(color_textures,ctl,color_count); + + extent.width=color_textures[0]->GetWidth(); + extent.height=color_textures[0]->GetHeight(); + } + else + { + color_textures=nullptr; + + if(depth_texture) + { + extent.width=depth_texture->GetWidth(); + extent.height=depth_texture->GetHeight(); + } + } + + render_complete_semaphore=s; +} + +RenderTarget::~RenderTarget() +{ + SAFE_CLEAR(queue); + SAFE_CLEAR(depth_texture); + SAFE_CLEAR_OBJECT_ARRAY(color_textures,color_count); + + SAFE_CLEAR(render_complete_semaphore); + SAFE_CLEAR(fbo); +} + +bool RenderTarget::Submit(RenderCmdBuffer *command_buffer,GPUSemaphore *present_complete_semaphore) +{ + return queue->Submit(*command_buffer,present_complete_semaphore,render_complete_semaphore); +} +VK_NAMESPACE_END \ No newline at end of file diff --git a/src/SceneGraph/Vulkan/VKRenderable.cpp b/src/SceneGraph/Vulkan/VKRenderable.cpp new file mode 100644 index 00000000..3f7bb9b6 --- /dev/null +++ b/src/SceneGraph/Vulkan/VKRenderable.cpp @@ -0,0 +1,63 @@ +#include +#include +#include +#include + +VK_NAMESPACE_BEGIN +//bool Renderable::Set(const int stage_input_binding,VAB *vab,VkDeviceSize offset) +//{ +// if(stage_input_binding<0||stage_input_binding>=buf_count||!vab)return(false); +// +// const VkVertexInputBindingDescription *desc=vertex_sm->GetDesc(stage_input_binding); +// const VkVertexInputAttributeDescription *attr=vertex_sm->GetAttr(stage_input_binding); +// +// if(vab->GetFormat()!=attr->format)return(false); +// if(vab->GetStride()!=desc->stride)return(false); +// +// //format信息来自于shader,实际中可以不一样。但那样需要为每一个格式产生一个同样shader的material instance,不同的格式又需要不同的pipeline,我们不支持这种行为 +// +// buf_list[stage_input_binding]=vab->GetBuffer(); +// buf_offset[stage_input_binding]=offset; +// +// return(true); +//} + +bool Renderable::Set(const AnsiString &name,VBO *vbo,VkDeviceSize offset) +{ + if(!vbo)return(false); + if(buffer_list.KeyExist(name))return(false); + + VBOData bd; + + bd.buf=vbo; + bd.offset=offset; + + buffer_list.Add(name,bd); + return(true); +} + +VBO *Renderable::GetVBO(const AnsiString &name,VkDeviceSize *offset) +{ + if(!offset)return(nullptr); + if(name.IsEmpty())return(nullptr); + + VBOData bd; + + if(buffer_list.Get(name,bd)) + { + *offset=bd.offset; + return bd.buf; + } + + return(nullptr); +} + +VkBuffer Renderable::GetBuffer(const AnsiString &name,VkDeviceSize *offset) +{ + VBO *vbo=GetVBO(name,offset); + + if(vbo)return vbo->GetBuffer(); + + return(VK_NULL_HANDLE); +} +VK_NAMESPACE_END diff --git a/src/SceneGraph/Vulkan/VKRenderableInstance.cpp b/src/SceneGraph/Vulkan/VKRenderableInstance.cpp new file mode 100644 index 00000000..7a3e1da6 --- /dev/null +++ b/src/SceneGraph/Vulkan/VKRenderableInstance.cpp @@ -0,0 +1,100 @@ +#include +#include +#include +#include +#include +#include + +VK_NAMESPACE_BEGIN +using namespace util; + +RenderableInstance::RenderableInstance(Renderable *r,MaterialInstance *mi,Pipeline *p,const uint32_t count,VkBuffer *bl,VkDeviceSize *bs) +{ + render_obj=r; + pipeline=p; + mat_inst=mi; + + buffer_count=count; + buffer_list=bl; + buffer_size=bs; + + if(buffer_count>0) + CountHash(buffer_list,buffer_count*sizeof(VkBuffer),(void *)&buffer_hash); + else + buffer_hash=0; +} + +RenderableInstance::~RenderableInstance() +{ + //需要在这里添加删除pipeline/desc_sets/render_obj引用计数的代码 + + delete[] buffer_list; + delete[] buffer_size; +} + +RenderableInstance *CreateRenderableInstance(Renderable *r,MaterialInstance *mi,Pipeline *p) +{ + if(!r||!mi||!p)return(nullptr); + + const VAB *vab=mi->GetVAB(); + const int input_count=vab->GetVertexAttrCount(); + const UTF8String &mtl_name=mi->GetMaterial()->GetName(); + + if(r->GetBufferCount() buffer_list(input_count); + AutoDeleteArray buffer_size(input_count); + + VBO *vbo; + const AnsiString ** name_list=vab->GetVertexNameList(); + const VkVertexInputBindingDescription * bind_list=vab->GetVertexBindingList(); + const VkVertexInputAttributeDescription * attr_list=vab->GetVertexAttributeList(); + + for(int i=0;iGetVBO(**name_list,buffer_size+i); + + if(!vbo) + { + LOG_ERROR("[FATAL ERROR] can't find VBO \""+**name_list+"\" in Material: "+mtl_name); + return(nullptr); + } + + if(vbo->GetFormat()!=attr_list->format) + { + LOG_ERROR( "[FATAL ERROR] VBO \""+**name_list+ + UTF8String("\" format can't match Renderable, Material(")+mtl_name+ + UTF8String(") Format(")+GetVulkanFormatName(attr_list->format)+ + UTF8String("), VBO Format(")+GetVulkanFormatName(vbo->GetFormat())+ + ")"); + return(nullptr); + } + + if(vbo->GetStride()!=bind_list->stride) + { + LOG_ERROR( "[FATAL ERROR] VBO \""+**name_list+ + UTF8String("\" stride can't match Renderable, Material(")+mtl_name+ + UTF8String(") stride(")+UTF8String::valueOf(bind_list->stride)+ + UTF8String("), VBO stride(")+UTF8String::valueOf(vbo->GetStride())+ + ")"); + return(nullptr); + } + + buffer_list[i]=vbo->GetBuffer(); + + ++name_list; + ++bind_list; + ++attr_list; + } + + RenderableInstance *ri=new RenderableInstance(r,mi,p,input_count,buffer_list,buffer_size); + buffer_list.Discard(); + buffer_size.Discard(); + return ri; +} +VK_NAMESPACE_END diff --git a/src/RenderDevice/Vulkan/VKSampler.cpp b/src/SceneGraph/Vulkan/VKSampler.cpp similarity index 71% rename from src/RenderDevice/Vulkan/VKSampler.cpp rename to src/SceneGraph/Vulkan/VKSampler.cpp index 513e118c..8aa8d935 100644 --- a/src/RenderDevice/Vulkan/VKSampler.cpp +++ b/src/SceneGraph/Vulkan/VKSampler.cpp @@ -1,4 +1,4 @@ -#include +#include VK_NAMESPACE_BEGIN Sampler::~Sampler() { diff --git a/src/RenderDevice/Vulkan/VKSemaphore.cpp b/src/SceneGraph/Vulkan/VKSemaphore.cpp similarity index 55% rename from src/RenderDevice/Vulkan/VKSemaphore.cpp rename to src/SceneGraph/Vulkan/VKSemaphore.cpp index 6e7ef4e2..81eaa6ac 100644 --- a/src/RenderDevice/Vulkan/VKSemaphore.cpp +++ b/src/SceneGraph/Vulkan/VKSemaphore.cpp @@ -1,6 +1,6 @@ -#include +#include VK_NAMESPACE_BEGIN -Semaphore::~Semaphore() +GPUSemaphore::~GPUSemaphore() { vkDestroySemaphore(device,sem,nullptr); } diff --git a/src/SceneGraph/Vulkan/VKShaderModule.cpp b/src/SceneGraph/Vulkan/VKShaderModule.cpp new file mode 100644 index 00000000..eb9f923c --- /dev/null +++ b/src/SceneGraph/Vulkan/VKShaderModule.cpp @@ -0,0 +1,128 @@ +#include +#include +#include + +VK_NAMESPACE_BEGIN +ShaderModule *GPUDevice::CreateShaderModule(ShaderResource *sr) +{ + if(!sr)return(nullptr); + + PipelineShaderStageCreateInfo *shader_stage=new PipelineShaderStageCreateInfo(sr->GetStage()); + + ShaderModuleCreateInfo moduleCreateInfo(sr); + + if(vkCreateShaderModule(attr->device,&moduleCreateInfo,nullptr,&(shader_stage->module))!=VK_SUCCESS) + return(nullptr); + + ShaderModule *sm; + + if(sr->GetStage()==VK_SHADER_STAGE_VERTEX_BIT) + sm=new VertexShaderModule(attr->device,shader_stage,sr); + else + sm=new ShaderModule(attr->device,shader_stage,sr); + + return sm; +} + +ShaderModule::ShaderModule(VkDevice dev,VkPipelineShaderStageCreateInfo *sci,ShaderResource *sr) +{ + device=dev; + ref_count=0; + + stage_create_info=sci; + + shader_resource=sr; +} + +ShaderModule::~ShaderModule() +{ + vkDestroyShaderModule(device,stage_create_info->module,nullptr); + //这里不用删除stage_create_info,材质中会删除的 + + SAFE_CLEAR(shader_resource); +} + +VertexShaderModule::VertexShaderModule(VkDevice dev,VkPipelineShaderStageCreateInfo *pssci,ShaderResource *sr):ShaderModule(dev,pssci,sr) +{ + const ShaderStageList &stage_input_list=sr->GetStageInputs(); + + attr_count=stage_input_list.GetCount(); + ssi_list=stage_input_list.GetData(); + name_list=new const AnsiString *[attr_count]; + type_list=new VertexAttribType[attr_count]; + + for(uint i=0;iname); + type_list[i]= ssi_list[i]->type; + } +} + +VertexShaderModule::~VertexShaderModule() +{ + if(vab_sets.GetCount()>0) + { + //还有在用的,这是个错误 + } + + delete[] type_list; + delete[] name_list; +} + +VAB *VertexShaderModule::CreateVAB(const VABConfigInfo *cfg) +{ + VkVertexInputBindingDescription *binding_list=new VkVertexInputBindingDescription[attr_count]; + VkVertexInputAttributeDescription *attribute_list=new VkVertexInputAttributeDescription[attr_count]; + + VkVertexInputBindingDescription *bind=binding_list; + VkVertexInputAttributeDescription *attr=attribute_list; + + ShaderStage **si=ssi_list; + VAConfig vac; + + for(uint i=0;ibinding =i; + attr->location =(*si)->location; //此值对应shader中的layout(location= + + attr->offset =0; + + bind->binding =i; //binding对应在vkCmdBindVertexBuffer中设置的缓冲区的序列号,所以这个数字必须从0开始,而且紧密排列。 + //在RenderableInstance类中,buffer_list必需严格按照本此binding为序列号排列 + + if(!cfg||!cfg->Get((*si)->name,vac)) + { + attr->format =VK_NAMESPACE::GetVulkanFormat(&((*si)->type)); + bind->inputRate =VK_VERTEX_INPUT_RATE_VERTEX; + } + else + { + attr->format =vac.format; + bind->inputRate =vac.instance?VK_VERTEX_INPUT_RATE_INSTANCE:VK_VERTEX_INPUT_RATE_VERTEX; + } + + bind->stride =GetStrideByFormat(attr->format); + + ++attr; + ++bind; + + ++si; + } + + VAB *vab=new VAB(attr_count,name_list,type_list,binding_list,attribute_list); + + vab_sets.Add(vab); + + return(vab); +} + +bool VertexShaderModule::Release(VAB *vab) +{ + return vab_sets.Delete(vab); +} +VK_NAMESPACE_END diff --git a/src/RenderDevice/Vulkan/ShaderModuleMap.cpp b/src/SceneGraph/Vulkan/VKShaderModuleMap.cpp similarity index 74% rename from src/RenderDevice/Vulkan/ShaderModuleMap.cpp rename to src/SceneGraph/Vulkan/VKShaderModuleMap.cpp index 208aa002..605eaa06 100644 --- a/src/RenderDevice/Vulkan/ShaderModuleMap.cpp +++ b/src/SceneGraph/Vulkan/VKShaderModuleMap.cpp @@ -1,5 +1,5 @@ -#include -#include +#include +#include VK_NAMESPACE_BEGIN bool ShaderModuleMap::Add(const ShaderModule *sm) diff --git a/src/SceneGraph/Vulkan/VKShaderResource.cpp b/src/SceneGraph/Vulkan/VKShaderResource.cpp new file mode 100644 index 00000000..3dbb0dc5 --- /dev/null +++ b/src/SceneGraph/Vulkan/VKShaderResource.cpp @@ -0,0 +1,145 @@ +#include +#include +#include +#include + +VK_NAMESPACE_BEGIN + + const DescriptorSetsType CheckDescriptorSetsType(const char *str) + { + if(str[1]=='_') + { + if(str[0]=='m')return DescriptorSetsType::Material; + if(str[0]=='g')return DescriptorSetsType::Global; + if(str[0]=='r')return DescriptorSetsType::Renderable; + } + + return DescriptorSetsType::Value; + } + + #define AccessByPointer(data,type) *(type *)data;data+=sizeof(type); + + namespace + { + MapObject shader_resource_by_filename; + + const uint8 *LoadShaderStages(ShaderStageList &ss_list,const uint8 *data) + { + const uint count=*data++; + + if(count<=0) + return(data); + + int str_len; + + ShaderStage *ss; + + for(uint i=0;ilocation =*data++; + ss->type.basetype =(VertexAttribBaseType)*data++; + ss->type.vec_size =*data++; + + str_len=*data++; + ss->name.SetString((char *)data,str_len); + data+=str_len; + + ss_list.Add(ss); + } + + return data; + } + }//namespcae + + ShaderResource::ShaderResource(const VkShaderStageFlagBits &flag,const void *sd,const uint32 size) + { + stage_flag=flag; + spv_data=sd; + spv_size=size; + } + + const os_char *ShaderStageName[]= + { + OS_TEXT("vert"), + OS_TEXT("tesc"), + OS_TEXT("tese"), + OS_TEXT("geom"), + OS_TEXT("frag"), + OS_TEXT("comp"), + OS_TEXT("task"), + OS_TEXT("mesh") + }; + + const os_char *ShaderResource::GetStageName() const + { + switch(stage_flag) + { + case VK_SHADER_STAGE_VERTEX_BIT: return ShaderStageName[0]; + case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT: return ShaderStageName[1]; + case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT: return ShaderStageName[2]; + case VK_SHADER_STAGE_GEOMETRY_BIT: return ShaderStageName[3]; + case VK_SHADER_STAGE_FRAGMENT_BIT: return ShaderStageName[4]; + case VK_SHADER_STAGE_COMPUTE_BIT: return ShaderStageName[5]; + case VK_SHADER_STAGE_TASK_BIT_NV: return ShaderStageName[6]; + case VK_SHADER_STAGE_MESH_BIT_NV: return ShaderStageName[7]; + default: return nullptr; + } + } + + const ShaderStage *ShaderResource::GetStageInput(const AnsiString &name) const + { + const int count=stage_inputs.GetCount(); + ShaderStage **ss=stage_inputs.GetData(); + + for(int i=0;iname) + return *ss; + + ++ss; + } + + return nullptr; + } + + const int ShaderResource::GetStageInputBinding(const AnsiString &name) const + { + const int count=stage_inputs.GetCount(); + ShaderStage **ss=stage_inputs.GetData(); + + for(int i=0;iname) + return i; + + ++ss; + } + + return -1; + } + + ShaderResource *LoadShaderResource(const uint8 *origin_filedata,const int64 filesize) + { + if(!origin_filedata)return(nullptr); + + const uint8 *filedata=origin_filedata; + const uint8 *file_end=filedata+filesize; + + VkShaderStageFlagBits flag; + uint32 spv_size; + + flag =(const VkShaderStageFlagBits)AccessByPointer(filedata,uint32); + spv_size=AccessByPointer(filedata,uint32); + + ShaderResource *sr=new ShaderResource(flag,filedata,spv_size); + + filedata+=spv_size; + + filedata=LoadShaderStages(sr->GetStageInputs(),filedata); + filedata=LoadShaderStages(sr->GetStageOutputs(),filedata); + + return sr; + } +VK_NAMESPACE_END diff --git a/src/SceneGraph/Vulkan/VKSubpass.cpp b/src/SceneGraph/Vulkan/VKSubpass.cpp new file mode 100644 index 00000000..e69de29b diff --git a/src/RenderDevice/Vulkan/VKSwapchain.cpp b/src/SceneGraph/Vulkan/VKSwapchain.cpp similarity index 53% rename from src/RenderDevice/Vulkan/VKSwapchain.cpp rename to src/SceneGraph/Vulkan/VKSwapchain.cpp index 66a6c816..1e6a5edb 100644 --- a/src/RenderDevice/Vulkan/VKSwapchain.cpp +++ b/src/SceneGraph/Vulkan/VKSwapchain.cpp @@ -1,10 +1,12 @@ -#include +#include +#include VK_NAMESPACE_BEGIN Swapchain::~Swapchain() { + SAFE_CLEAR_OBJECT_ARRAY(render_frame,color_count); SAFE_CLEAR(sc_depth); - sc_color.Clear(); + SAFE_CLEAR_OBJECT_ARRAY(sc_color,color_count) if(swap_chain) { @@ -12,6 +14,6 @@ Swapchain::~Swapchain() swap_chain=VK_NULL_HANDLE; } - swap_chain_count=0; + color_count=0; } VK_NAMESPACE_END diff --git a/src/SceneGraph/Vulkan/VKSwapchainRenderTarget.cpp b/src/SceneGraph/Vulkan/VKSwapchainRenderTarget.cpp new file mode 100644 index 00000000..2b185b35 --- /dev/null +++ b/src/SceneGraph/Vulkan/VKSwapchainRenderTarget.cpp @@ -0,0 +1,77 @@ +#include +#include +#include + +VK_NAMESPACE_BEGIN +SwapchainRenderTarget::SwapchainRenderTarget(VkDevice dev,Swapchain *sc,GPUQueue *q,GPUSemaphore *rcs,GPUSemaphore *pcs,RenderPass *rp):RenderTarget(q,rcs) +{ + device=dev; + + swapchain=sc; + + present_info.waitSemaphoreCount = 0; + present_info.pWaitSemaphores = nullptr; + present_info.swapchainCount = 1; + present_info.pResults = nullptr; + present_info.pSwapchains = &(swapchain->swap_chain); + + render_pass=rp; + + extent=swapchain->extent; + + current_frame=0; + + present_complete_semaphore=pcs; +} + +SwapchainRenderTarget::~SwapchainRenderTarget() +{ + delete present_complete_semaphore; + delete swapchain; +} + +int SwapchainRenderTarget::AcquireNextImage() +{ + if(vkAcquireNextImageKHR(device,swapchain->swap_chain,UINT64_MAX,*(this->present_complete_semaphore),VK_NULL_HANDLE,¤t_frame)==VK_SUCCESS) + return current_frame; + + return -1; +} + +bool SwapchainRenderTarget::PresentBackbuffer(VkSemaphore *wait_semaphores,const uint32_t count) +{ + present_info.waitSemaphoreCount =count; + present_info.pWaitSemaphores =wait_semaphores; + present_info.pImageIndices =¤t_frame; + + VkResult result=queue->Present(&present_info); + + if (!((result == VK_SUCCESS) || (result == VK_SUBOPTIMAL_KHR))) + { + if (result == VK_ERROR_OUT_OF_DATE_KHR) { + // Swap chain is no longer compatible with the surface and needs to be recreated + + return false; + } + } + + return(true); +} + +bool SwapchainRenderTarget::PresentBackbuffer() +{ + VkSemaphore sem=*render_complete_semaphore; + + return this->PresentBackbuffer(&sem,1); +} + +bool SwapchainRenderTarget::Submit(VkCommandBuffer cb) +{ + return queue->Submit(cb,present_complete_semaphore,render_complete_semaphore); +} + +bool SwapchainRenderTarget::Submit(VkCommandBuffer cb,GPUSemaphore *pce) +{ + return queue->Submit(cb,pce,render_complete_semaphore); +} +VK_NAMESPACE_END diff --git a/src/RenderDevice/Vulkan/VKTexture.cpp b/src/SceneGraph/Vulkan/VKTexture.cpp similarity index 75% rename from src/RenderDevice/Vulkan/VKTexture.cpp rename to src/SceneGraph/Vulkan/VKTexture.cpp index 1e6ef7ab..b8cbe216 100644 --- a/src/RenderDevice/Vulkan/VKTexture.cpp +++ b/src/SceneGraph/Vulkan/VKTexture.cpp @@ -1,6 +1,6 @@ -#include -#include -#include +#include +#include +#include VK_NAMESPACE_BEGIN Texture::~Texture() { diff --git a/src/RenderDevice/Vulkan/VKTileData.cpp b/src/SceneGraph/Vulkan/VKTileData.cpp similarity index 84% rename from src/RenderDevice/Vulkan/VKTileData.cpp rename to src/SceneGraph/Vulkan/VKTileData.cpp index 7b09119e..df0ae137 100644 --- a/src/RenderDevice/Vulkan/VKTileData.cpp +++ b/src/SceneGraph/Vulkan/VKTileData.cpp @@ -1,5 +1,5 @@ -#include -#include +#include +#include #include namespace @@ -61,7 +61,7 @@ namespace }//namespace VK_NAMESPACE_BEGIN -TileData *Device::CreateTileData(const VkFormat format,const uint width,const uint height,const uint count) +TileData *GPUDevice::CreateTileData(const VkFormat format,const uint width,const uint height,const uint count) { if(!CheckVulkanFormat(format)) return(nullptr); @@ -80,17 +80,18 @@ TileData *Device::CreateTileData(const VkFormat format,const uint width,const ui if(!vf)return(nullptr); Texture2D *tex=nullptr; + VkExtent2D extent={tex_width,tex_height}; if(vf->color>VulkanDataType::NONE &&vf->colordepth>VulkanDataType::NONE &&vf->depth -#include +#include VK_NAMESPACE_BEGIN /** @@ -7,7 +7,7 @@ VK_NAMESPACE_BEGIN * @param f 字体需求信息 * @param limit_count 缓冲字符数量上限 */ -TileFont *Device::CreateTileFont(FontSource *fs,int limit_count) +TileFont *GPUDevice::CreateTileFont(FontSource *fs,int limit_count) { if(!fs)return(nullptr); @@ -23,7 +23,7 @@ TileFont *Device::CreateTileFont(FontSource *fs,int limit_count) if(!fs) return(nullptr); - TileData *td=CreateTileData(UFMT_R8,height,height,limit_count); + TileData *td=CreateTileData(UPF_R8,height,height,limit_count); if(!td) return nullptr; diff --git a/src/SceneGraph/font/TextLayout.cpp b/src/SceneGraph/font/TextLayout.cpp index 73ab927b..908b0ed4 100644 --- a/src/SceneGraph/font/TextLayout.cpp +++ b/src/SceneGraph/font/TextLayout.cpp @@ -173,7 +173,7 @@ namespace hgl int cur_size=0; int left=0,top=0; - float *tp=vertex; + int16 *tp=vertex; float *tcp=tex_coord; for(int i=0;i -#include -#include +#include +#include +#include namespace hgl { namespace graph { - TextRenderable::TextRenderable(vulkan::Device *dev,vulkan::Material *m,uint mc):vulkan::Renderable(m->GetVertexShaderModule(),mc) + TextRenderable::TextRenderable(GPUDevice *dev,Material *m,uint mc):Renderable(mc) { device=dev; mtl=m; max_count=0; - vab_position=nullptr; - vab_tex_coord=nullptr; + vbo_position=nullptr; + vbo_tex_coord=nullptr; } TextRenderable::~TextRenderable() { - SAFE_CLEAR(vab_tex_coord); - SAFE_CLEAR(vab_position); + SAFE_CLEAR(vbo_tex_coord); + SAFE_CLEAR(vbo_position); } void TextRenderable::SetCharCount(const uint cc) @@ -31,23 +32,23 @@ namespace hgl max_count=power_to_2(cc); { - if(vab_position) - delete vab_position; + if(vbo_position) + delete vbo_position; - vab_position =device->CreateVAB(VAF_VEC4,max_count); - Set(VAN::Position,vab_position); + vbo_position =device->CreateVBO(VF_V4I16,max_count); + Set(VAN::Position,vbo_position); } { - if(vab_tex_coord) - delete vab_tex_coord; + if(vbo_tex_coord) + delete vbo_tex_coord; - vab_tex_coord =device->CreateVAB(VAF_VEC4,max_count); - Set(VAN::TexCoord,vab_tex_coord); + vbo_tex_coord =device->CreateVBO(VF_V4F,max_count); + Set(VAN::TexCoord,vbo_tex_coord); } } - bool TextRenderable::WriteVertex (const float *fp){if(!fp)return(false);if(!vab_position )return(false);return vab_position ->Write(fp,draw_count*4*sizeof(float));} - bool TextRenderable::WriteTexCoord (const float *fp){if(!fp)return(false);if(!vab_tex_coord)return(false);return vab_tex_coord ->Write(fp,draw_count*4*sizeof(float));} + bool TextRenderable::WriteVertex (const int16 *fp){if(!fp)return(false);if(!vbo_position )return(false);return vbo_position ->Write(fp,draw_count*4*sizeof(int16));} + bool TextRenderable::WriteTexCoord (const float *fp){if(!fp)return(false);if(!vbo_tex_coord)return(false);return vbo_tex_coord ->Write(fp,draw_count*4*sizeof(float));} }//namespace graph }//namespace hgl diff --git a/src/SceneGraph/font/TileFont.cpp b/src/SceneGraph/font/TileFont.cpp index bf8d0e90..aefa2cb4 100644 --- a/src/SceneGraph/font/TileFont.cpp +++ b/src/SceneGraph/font/TileFont.cpp @@ -1,6 +1,6 @@ #include -#include -#include +#include +#include namespace hgl { diff --git a/src/SceneGraph/shader/ShaderResource.cpp b/src/SceneGraph/shader/ShaderResource.cpp deleted file mode 100644 index 015836f4..00000000 --- a/src/SceneGraph/shader/ShaderResource.cpp +++ /dev/null @@ -1,192 +0,0 @@ -#include -#include -#include - -VK_NAMESPACE_BEGIN - - #define AccessByPointer(data,type) *(type *)data;data+=sizeof(type); - - namespace - { - constexpr char SHADER_FILE_HEADER[] ="Shader\x1A"; - constexpr uint SHADER_FILE_HEADER_BYTES=sizeof(SHADER_FILE_HEADER)-1; - - constexpr uint32 SHADER_FILE_MIN_SIZE =SHADER_FILE_HEADER_BYTES - +1 //version - +sizeof(uint32) //shader flag - +sizeof(uint32) //spv_size - +1 //input states count - +1; //output states count - - const uint8 *LoadShaderStages(ShaderStageList &ss_list,const uint8 *data) - { - const uint count=*data++; - - if(count<=0) - return(data); - - const uint32 total_bytes=AccessByPointer(data,uint32); - - int str_len; - - ShaderStage *ss; - - for(uint i=0;ilocation=*data++; - ss->type.basetype=(VertexAttribBaseType)*data++; - ss->type.vec_size=*data++; - - ss->format=VK_NAMESPACE::GetVulkanFormat(&(ss->type)); - - str_len=*data++; - ss->name.SetString((char *)data,str_len); - data+=str_len; - - ss->binding=i; - - ss_list.Add(ss); - } - - return data; - } - - const uint8 *LoadShaderDescriptor(const uint8_t version,ShaderDescriptorList *sd_list,const uint8 *data) - { - const uint32 total_bytes=AccessByPointer(data,uint32); - - const uint count=*data++; - - uint str_len; - - sd_list->binding_list.PreMalloc(count); - sd_list->set_list.PreMalloc(count); - - for(uint i=0;i=1) - sd_list->set_list.Add(*data++); - else - sd_list->set_list.Add(0); - - sd_list->binding_list.Add(*data++); - str_len=*data++; - sd_list->name_list.Add(AnsiString((char *)data,str_len)); - data+=str_len; - } - - return data; - } - }//namespcae - - ShaderResource::ShaderResource(const VkShaderStageFlagBits &flag,const void *sd,const uint32 size) - { - stage_flag=flag; - spv_data=sd; - spv_size=size; - } - - const ShaderStage *ShaderResource::GetStageInput(const AnsiString &name) const - { - const int count=stage_inputs.GetCount(); - ShaderStage **ss=stage_inputs.GetData(); - - for(int i=0;iname) - return *ss; - - ++ss; - } - - return nullptr; - } - - const int ShaderResource::GetStageInputBinding(const AnsiString &name) const - { - const int count=stage_inputs.GetCount(); - ShaderStage **ss=stage_inputs.GetData(); - - for(int i=0;iname) - return i; - - ++ss; - } - - return -1; - } - - const int ShaderResource::GetBinding(VkDescriptorType desc_type,const AnsiString &name)const - { - if(desc_type>=VK_DESCRIPTOR_TYPE_RANGE_SIZE)return -1; - if(name.IsEmpty())return -1; - - const ShaderDescriptorList *sdl=descriptor_list+(size_t)desc_type; - - const int index=sdl->name_list.Find(name); - - uint binding; - - if(sdl->binding_list.Get(index,binding)) - return binding; - else - return -1; - } - - ShaderResource *LoadShaderResource(const uint8 *origin_filedata,const int64 filesize,bool include_file_header) - { - if(!origin_filedata)return(nullptr); - - const uint8 *filedata=origin_filedata; - const uint8 *file_end=filedata+filesize; - - if(include_file_header) - { - if(filesizeGetStageInputs(),filedata); - filedata=LoadShaderStages(sr->GetStageOutputs(),filedata); - - while(filedataGetDescriptorList((VkDescriptorType)desc_type),filedata); - } - - return sr; - } - - ShaderResource *LoadShaderResoruce(const OSString &filename) - { - int64 filesize; - AutoDeleteArray origin_filedata=(uint8 *)filesystem::LoadFileToMemory(filename+OS_TEXT(".shader"),filesize); - - return LoadShaderResource(origin_filedata,filesize,true); - } -VK_NAMESPACE_END