add readme
This commit is contained in:
		
							parent
							
								
									2ea409e6d2
								
							
						
					
					
						commit
						cb1c7ad1e5
					
				
							
								
								
									
										107
									
								
								README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										107
									
								
								README.md
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,107 @@ | ||||
| # 个人游戏引擎 | ||||
| 
 | ||||
| 这是一个模块化的 C++ 游戏引擎,旨在帮助学习和实现基本的游戏引擎系统。它包括多个模块,如渲染、资源管理、UI 等,并使用 Vulkan 作为主要的渲染 API。该引擎的结构被拆分为多个静态库和动态链接库(DLL),通过 `xmake` 管理。 | ||||
| 
 | ||||
| ## 功能 | ||||
| - **模块化架构**:将引擎拆分成多个独立模块,提高了可维护性和可扩展性。 | ||||
| - **渲染**:使用 Vulkan 实现,且有抽象层支持未来扩展到 OpenGL、DirectX 和 Metal 等其他渲染 API。 | ||||
| - **资源管理**:包括基础的资源管理、加载和序列化功能。 | ||||
| - **UI**:集成了 NoesisGUI 进行 XAML UI 元素的渲染。 | ||||
| - **全局变量管理**:通过 `engine.dll` 集中管理全局状态,避免模块间不一致。 | ||||
| - **高效内存管理**:通过 `pmr` 内存资源和模板元编程优化内存分配。 | ||||
| - **编辑器支持**:为编辑器功能提供基本的集成,未来计划使用 ImGui 和 NoesisGUI 开发完整的编辑器工具。 | ||||
| 
 | ||||
| ## 安装 | ||||
| 
 | ||||
| [代码生成工具](http://175.24.226.114:3000/ouczbs/cppast.git) | ||||
| 
 | ||||
| [xmake 第三方库](http://175.24.226.114:3000/ouczbs/xmake.repo.git) | ||||
| 
 | ||||
| ## 项目结构 | ||||
| - **engine.dll**:核心 DLL,负责整合所有模块并管理全局状态和模块生命周期。 | ||||
| - **core.lib, render.lib, asset.lib, app.lib, ui.lib**:提供不同功能的静态库(渲染、资源加载、UI 处理等),链接到 `engine.dll`。 | ||||
| - **singleton.dll**:确保全局变量在跨模块时唯一,并集中管理。 | ||||
| - **zlib.lib**:提供压缩、反射和内存管理优化。 | ||||
| - **vulkan.dll**:包含 Vulkan 特定的渲染逻辑,和 `engine.dll`、`editor.dll` 进行交互。 | ||||
| - **editor.dll**:使用 ImGui 和 NoesisGUI 提供编辑器界面(仍在开发中)。 | ||||
| - **zworld.exe**:目标游戏执行文件,当前实现了 Vulkan 渲染三角形,并展示了 NoesisGUI 的 XAML UI。 | ||||
| 
 | ||||
| ### 模块工作方式 | ||||
| - **全局变量**:所有全局变量都包含在 `engine.dll` 中,其他模块(如 `core.lib`、`render.lib` 等)可以通过指针引用访问。这减少了重复性并确保模块间的一致性。 | ||||
| - **模块化逻辑**:不是通过 DLL 接口导出所有函数,而是只导出必要的函数,最大限度地减少了冗余,确保代码简洁可维护。 | ||||
| - **生命周期管理**:`core` 模块负责其他模块的初始化、生命周期和销毁,确保它们按正确顺序加载,资源安全清理。 | ||||
| 
 | ||||
| ## 详细模块描述 | ||||
| 
 | ||||
| ### 1. singleton.dll | ||||
| 确保跨模块的全局变量唯一性,使用指针引用进行管理。每个模块都获取这些变量的指针副本,但它们指向相同的内存位置。 | ||||
| 
 | ||||
| - **全局变量管理**:保证跨模块的共享资源保持一致,避免重复或误管理。 | ||||
| - **跨模块访问**:模块可以访问共享变量,而不必担心重复问题。 | ||||
| 
 | ||||
| ### 2. zlib.lib | ||||
| 提供多种实用工具,包括压缩支持和高级内存管理。 | ||||
| 
 | ||||
| - **PMR 内存管理**:使用多态内存资源 (`pmr`) 优化内存分配和释放策略。 | ||||
| - **反射**:实现基础的运行时反射,用于数据序列化和反序列化(JSON、YAML)。 | ||||
| - **模板元编程**:通过模板提供高效的编译时计算和类型操作。 | ||||
| 
 | ||||
| ### 3. core.lib | ||||
| 处理引擎的核心功能,包括模块管理、序列化和文件挂载。 | ||||
| 
 | ||||
| - **模块管理**:负责模块的初始化、生命周期和销毁,确保按正确顺序初始化。 | ||||
| - **序列化**:使用 `zlib.lib` 的反射功能实现 JSON 和 YAML 序列化/反序列化。 | ||||
| - **文件挂载**:提供将资源从各种源(如本地文件系统或打包文件)挂载和加载的功能。 | ||||
| 
 | ||||
| ### 4. asset.lib | ||||
| 管理游戏资源,包括加载、缓存和序列化。 | ||||
| 
 | ||||
| - **资源管理**:高效管理纹理、模型、声音等资源的生命周期。 | ||||
| - **资源加载**:支持从多种格式加载资源,如图像和 3D 模型。 | ||||
| - **序列化**:实现资源的保存和加载功能。 | ||||
| 
 | ||||
| ### 5. render.lib | ||||
| 该模块抽象了渲染硬件接口(RHI),并处理渲染管线管理,包括支持 Vulkan。 | ||||
| 
 | ||||
| - **RHI 抽象**:当前仅实现 Vulkan API,但系统设计支持未来扩展到 OpenGL、DirectX 和 Metal 等渲染 API。 | ||||
| - **FrameGraph**:引入 `FrameGraph` 概念来管理渲染通道和资源依赖,优化渲染管线。 | ||||
| - **材质系统**:简单的材质系统,处理渲染用的材质属性和着色器。 | ||||
| - **GPU 动态缓冲区**:实现了 GPU 端的动态缓冲区,供 NoesisGUI 渲染 UI 元素时使用。 | ||||
| - **Vulkan 集成**:完全集成 Vulkan,处理命令缓冲区、资源管理和同步。 | ||||
| 
 | ||||
| ### 6. ui.lib | ||||
| 处理 UI 集成,最初关注于 NoesisGUI。 | ||||
| 
 | ||||
| - **NoesisGUI 集成**:提供一个基础系统,通过 NoesisGUI 渲染 XAML 文件,支持游戏和编辑器中的 UI 渲染。 | ||||
| - **UI 渲染**:管理 UI 元素的渲染及与 Vulkan 的交互。 | ||||
| - **未来扩展**:计划扩展该模块,支持其他 UI 框架(如 ImGui)来处理更复杂的编辑器和游戏内 UI。 | ||||
| 
 | ||||
| ### 7. app.lib | ||||
| 包含整个项目的全局设置和事件系统。 | ||||
| 
 | ||||
| - **项目设置**:管理引擎和游戏的全局配置和设置。 | ||||
| - **事件系统**:实现事件驱动系统,处理各种引擎和游戏事件,使不同模块解耦。 | ||||
| 
 | ||||
| ### 8. editor.dll | ||||
| 一个进行中的编辑器模块,用于管理游戏开发过程。 | ||||
| 
 | ||||
| - **编辑器 UI**:最终将使用 ImGui 和 NoesisGUI 创建游戏和资产管理的编辑器界面。 | ||||
| - **编辑器工具**:包含早期功能,用于构建场景编辑器、资产查看器等开发工具。 | ||||
| 
 | ||||
| ### 9. vulkan.dll | ||||
| 管理 Vulkan 特定的渲染逻辑。 | ||||
| 
 | ||||
| - **Vulkan RHI 实现**:包含所有 Vulkan 特定的代码,管理命令缓冲区、着色器和同步。 | ||||
| - **NoesisGUI 渲染**:将 NoesisGUI 集成到 Vulkan 管道中,进行 UI 元素渲染。 | ||||
| 
 | ||||
| ### 10. zworld.exe (目标游戏) | ||||
| 目标游戏的执行文件,当前处于早期阶段,使用 Vulkan 实现了基本渲染。 | ||||
| 
 | ||||
| - **Vulkan 渲染三角形**:演示如何使用 Vulkan 渲染一个简单的三角形到 ImGui 的 image 控件中。 | ||||
| - **NoesisGUI 集成**:通过 Vulkan 和 NoesisGUI 渲染一个简单的 XAML UI 文件,展示游戏中的 UI 渲染。 | ||||
| 
 | ||||
| ## 未来计划 | ||||
| - **更多渲染 API**:扩展渲染系统,支持 OpenGL、DirectX 和 Metal,实现跨平台兼容性。 | ||||
| - **游戏逻辑与玩法**:将游戏逻辑、物理和 AI 系统整合进引擎,创建完整的游戏环境。 | ||||
| - **高级资源管理**:添加更多的资源格式,并优化资源加载管道以提高性能。 | ||||
| - **编辑器开发**:继续开发编辑器,为场景管理、资产创建和调试提供工具。 | ||||
							
								
								
									
										101
									
								
								doc/README_EN.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										101
									
								
								doc/README_EN.md
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,101 @@ | ||||
| # Personal Game Engine | ||||
| 
 | ||||
| This is a modular C++ game engine designed to help learn and implement essential game engine systems. It includes various modules for rendering, asset management, UI, and more, and uses Vulkan as the primary rendering API. The engine is structured into several libraries and dynamic link libraries (DLLs), all managed with `xmake`. | ||||
| 
 | ||||
| ## Features | ||||
| - **Modular Architecture**: The engine is broken into independent modules to improve maintainability and extensibility. | ||||
| - **Rendering**: Implemented using Vulkan, with an abstraction layer for possible future expansion to OpenGL, DirectX, and Metal. | ||||
| - **Asset Management**: Includes basic resource management, loading, and serialization. | ||||
| - **UI**: Basic UI system integration with NoesisGUI for rendering XAML UI elements. | ||||
| - **Global Variables**: Centralized management of global state in `engine.dll` to avoid inconsistencies across modules. | ||||
| - **Efficient Memory Management**: Includes optimizations for memory allocation using `pmr` memory resources and template metaprogramming. | ||||
| - **Editor Support**: Basic integration for editor functionality, with plans for full editor tools using ImGui and NoesisGUI. | ||||
| 
 | ||||
| ## Project Structure | ||||
| - **engine.dll**: The core DLL that integrates all the modules and manages global state and module lifecycle. | ||||
| - **core.lib, render.lib, asset.lib, app.lib, ui.lib**: Static libraries providing different functionalities (rendering, asset loading, UI handling, etc.) linked into `engine.dll`. | ||||
| - **singleton.dll**: Ensures that global variables across modules are unique and managed centrally. | ||||
| - **zlib.lib**: Provides compression, reflection, and memory management optimizations. | ||||
| - **vulkan.dll**: Contains the Vulkan-specific rendering logic, interfacing with `engine.dll` and `editor.dll`. | ||||
| - **editor.dll**: Provides the editor interface using ImGui and NoesisGUI (still in early development). | ||||
| - **zworld.exe**: The target game executable that currently renders a triangle with Vulkan and displays a NoesisGUI XAML UI. | ||||
| 
 | ||||
| ### How the Modules Work | ||||
| - **Global Variables**: All global variables are contained within `engine.dll`, which other modules (like `core.lib`, `render.lib`, etc.) can access via pointer references. This reduces duplication and ensures consistency across modules. | ||||
| - **Modular Logic**: Instead of exporting all functions through DLL interfaces, only the necessary functions are exported, minimizing bloat and ensuring a clean and maintainable codebase. | ||||
| - **Lifecycle Management**: The `core` module manages the initialization, lifecycle, and shutdown of other modules, ensuring they are loaded in the correct order and resources are cleaned up safely. | ||||
| 
 | ||||
| ## Detailed Module Descriptions | ||||
| 
 | ||||
| ### 1. singleton.dll | ||||
| This module ensures that global variables across different modules are unique by using pointer references. Each module gets a copy of the pointer to these variables, but they all point to the same memory location. | ||||
| 
 | ||||
| - **Global Variable Management**: Guarantees that shared resources across modules remain consistent and avoid duplication or mismanagement. | ||||
| - **Cross-Module Access**: Modules can access shared variables without the risk of duplication. | ||||
| 
 | ||||
| ### 2. zlib.lib | ||||
| Provides a variety of utilities, including compression support and advanced memory management. | ||||
| 
 | ||||
| - **PMR Memory Management**: Optimized memory allocation and deallocation strategies using polymorphic memory resources (`pmr`). | ||||
| - **Reflection**: Implements basic runtime reflection for data serialization and deserialization (JSON, YAML). | ||||
| - **Template Metaprogramming**: High-performance template-based utilities for compile-time calculations and type manipulation. | ||||
| 
 | ||||
| ### 3. core.lib | ||||
| Handles the core functionality of the engine, including module management, serialization, and file mounting. | ||||
| 
 | ||||
| - **Module Management**: Manages the initialization, lifecycle, and shutdown of modules, ensuring that they are initialized in the correct order. | ||||
| - **Serialization**: Implements JSON and YAML serialization/deserialization using the reflection features of `zlib.lib`. | ||||
| - **File Mounting**: Provides the functionality to mount and load resources from various sources, such as local file systems or packaged files. | ||||
| 
 | ||||
| ### 4. asset.lib | ||||
| Manages game assets, including their loading, caching, and serialization. | ||||
| 
 | ||||
| - **Resource Management**: Efficiently manages the lifecycle of assets like textures, models, and sounds. | ||||
| - **Asset Loading**: Supports loading assets from various formats, such as images and 3D models. | ||||
| - **Serialization**: Implements functionality to save and load assets to and from disk. | ||||
| 
 | ||||
| ### 5. render.lib | ||||
| This module abstracts the rendering hardware interface (RHI) and handles rendering pipeline management, including support for Vulkan. | ||||
| 
 | ||||
| - **RHI Abstraction**: While Vulkan is currently the only fully implemented API, the system is designed to support other rendering APIs (OpenGL, DirectX, Metal) in the future. | ||||
| - **FrameGraph**: Introduces the `FrameGraph` concept to manage render passes and resource dependencies, optimizing the render pipeline. | ||||
| - **Material System**: A simple material system that handles material properties and shaders for rendering. | ||||
| - **GPU Dynamic Buffers**: Implements dynamic buffers for GPU-side storage, which is used by NoesisGUI to render UI elements. | ||||
| - **Vulkan Integration**: Fully integrates Vulkan, handling command buffers, resource management, and synchronization. | ||||
| 
 | ||||
| ### 6. ui.lib | ||||
| Handles the integration of user interfaces, initially focused on NoesisGUI. | ||||
| 
 | ||||
| - **NoesisGUI Integration**: Provides a basic system to render XAML files using NoesisGUI, supporting UI rendering within the game and editor. | ||||
| - **UI Rendering**: Manages the rendering of UI elements and their interaction with Vulkan. | ||||
| - **Future Expansion**: Plans to extend the module to support other UI frameworks such as ImGui for more complex editor and in-game UIs. | ||||
| 
 | ||||
| ### 7. app.lib | ||||
| Contains global settings and event systems for the entire project. | ||||
| 
 | ||||
| - **Project Settings**: Manages global configurations and settings for the engine and game. | ||||
| - **Event System**: Implements an event-driven system for handling various engine and game events, decoupling different parts of the engine. | ||||
| 
 | ||||
| ### 8. editor.dll | ||||
| A work-in-progress editor module for managing the game development process. | ||||
| 
 | ||||
| - **Editor UI**: Will eventually use ImGui and NoesisGUI to create an editor interface for game and asset management. | ||||
| - **Editor Tools**: Contains early-stage functionality to build scene editors, asset viewers, and other development tools. | ||||
| 
 | ||||
| ### 9. vulkan.dll | ||||
| Manages Vulkan-specific rendering logic. | ||||
| 
 | ||||
| - **Vulkan RHI Implementation**: Contains all Vulkan-specific code for managing command buffers, shaders, and synchronization. | ||||
| - **NoesisGUI Rendering**: Integrates NoesisGUI into the Vulkan pipeline to render UI elements. | ||||
| 
 | ||||
| ### 10. zworld.exe (Target Game) | ||||
| The executable for the target game, currently in its early stages, implements basic rendering using Vulkan. | ||||
| 
 | ||||
| - **Vulkan Triangle Rendering**: Demonstrates the use of Vulkan to render a simple triangle on screen. | ||||
| - **NoesisGUI Integration**: Renders a simple XAML UI file using Vulkan and NoesisGUI, showcasing UI rendering in the game. | ||||
| 
 | ||||
| ## Future Plans | ||||
| - **More Rendering APIs**: Expand the rendering system to support OpenGL, DirectX, and Metal, allowing for cross-platform compatibility. | ||||
| - **Game Logic and Gameplay**: Integrate game logic, physics, and AI systems into the engine to create a full-fledged game environment. | ||||
| - **Advanced Asset Management**: Add more asset formats and optimize the resource loading pipeline for better performance. | ||||
| - **Editor Development**: Continue development on the editor to provide tools for scene management, asset creation, and debugging. | ||||
| @ -4,6 +4,7 @@ header_component("zlib","engine") | ||||
|     if is_mode("debug") then  | ||||
|         add_defines("API_DEBUG", {public = true}) | ||||
|     end | ||||
|     add_defines("NOMINMAX", {public = true}) | ||||
|     add_syslinks("kernel32") | ||||
|     set_pcheader("include/refl/pch.h") | ||||
|     add_deps("xmalloc", {public = true}) | ||||
| @ -39,8 +39,6 @@ namespace vkn { | ||||
| 		uint32_t			mMinUniformBufferOffsetAlignment; | ||||
| 		uint32_t			mCachedStencilRef; | ||||
| 		VkBuffer			mCachedIndexBuffer; | ||||
| 		VkFormat			mStencilFormat{ VK_FORMAT_S8_UINT }; | ||||
| 		VkFormat			mBackBufferFormat{ VK_FORMAT_R8G8B8A8_SRGB }; | ||||
| 		VkCommandBuffer		mCommandBuffer = VK_NULL_HANDLE; | ||||
| 		VkPipeline			mCachedPipeline = VK_NULL_HANDLE; | ||||
| 		VkPipelineCache		mPipelineCache = VK_NULL_HANDLE; | ||||
| @ -79,7 +77,7 @@ namespace vkn { | ||||
| 		void BindPipeline(const Noesis::Batch& batch); | ||||
| 		void SetStencilRef(uint32_t stencilRef); | ||||
| 	public: | ||||
| 		void CreateRenderPass(VkSampleCountFlagBits sampleCount); | ||||
| 		void CreateRenderPass(TinyImageFormat format, VkSampleCountFlagBits sampleCount); | ||||
| 		void CreateLayouts(); | ||||
| 		void CreateLayout(uint32_t signature, Layout& layout); | ||||
| 		void LoadShaders(bool stereoSupport); | ||||
|  | ||||
| @ -157,7 +157,7 @@ namespace vkn { | ||||
| 		{ | ||||
| 			auto& barrier = desc.pTextureBarriers[i]; | ||||
| 			auto desc = vkApiGetTextureTransition(srcStageMask, dstStageMask, barrier); | ||||
| 			zlog::info("textureBarrier::{:#x} {} {}::{}", (uintptr_t)barrier.mTexture.image,(uint8_t)renderPassState,(uint8_t)barrier.mSrcState, (uint8_t)barrier.mDstState); | ||||
| 			//zlog::info("textureBarrier::{:#x} {} {}::{}", (uintptr_t)barrier.mTexture.image,(uint8_t)renderPassState,(uint8_t)barrier.mSrcState, (uint8_t)barrier.mDstState);
 | ||||
| 			imageBarriers.push_back(desc); | ||||
| 		} | ||||
| 		if (dstStageMask == 0) { | ||||
|  | ||||
| @ -8,9 +8,11 @@ | ||||
| #include "event/event_system.h" | ||||
| #include "data/global.h" | ||||
| #include "noesis/vulkan_noesis_help.h" | ||||
| #include <tinyimageformat/tinyimageformat_apis.h> | ||||
| #define DESCRIPTOR_POOL_MAX_SETS 128 | ||||
| namespace vkn { | ||||
| 	using namespace api; | ||||
|     constexpr TinyImageFormat CStencilFormat = TinyImageFormat_S8_UINT; | ||||
|     void vkn::VulkanUISystem::OnBeginRenderFrame(FrameGraph& graph, uint32_t frame) | ||||
|     { | ||||
| #ifdef WITH_EDITOR | ||||
| @ -24,9 +26,11 @@ namespace vkn { | ||||
|     } | ||||
|     void VulkanUISystem::Setup(FrameGraph& graph, RenderPassBuilder& builder) | ||||
|     { | ||||
| #include "windows.h" | ||||
|         TextureDesc stencil = graph.GetRenderSurface(); | ||||
|         stencil.id = 0; | ||||
|         stencil.format = TinyImageFormat_S8_UINT; | ||||
|         stencil.state = ResourceState::UNDEFINED; | ||||
|         stencil.format = CStencilFormat; | ||||
|         stencil.image = nullptr; | ||||
|         stencil.usage = TextureUsage::STENCIL_ATTACHMENT | TextureUsage::DEPTH_ATTACHMENT; | ||||
|         graph.AcquireTexture(stencil); | ||||
| @ -52,13 +56,14 @@ namespace vkn { | ||||
|     { | ||||
|         VulkanAPI* API = VulkanAPI::Ptr(); | ||||
|         mDevice = &API->GetBackend().GetDevice(); | ||||
|         TinyImageFormat colorFormat = API->context.surface.format; | ||||
|         mHasExtendedDynamicState = false; | ||||
|         mIsLinearRendering = linearRendering; | ||||
|         VkPhysicalDeviceProperties mDeviceProperties; | ||||
|         vkGetPhysicalDeviceProperties(mDevice->GetPhysical(), &mDeviceProperties); | ||||
|         mMinUniformBufferOffsetAlignment = mDeviceProperties.limits.minUniformBufferOffsetAlignment; | ||||
|         VkSampleCountFlagBits sampleCount = vkApiGetSmpleCountFlag(sampleCount_); | ||||
|         CreateRenderPass(sampleCount); | ||||
|         CreateRenderPass(colorFormat, sampleCount); | ||||
|         CreateLayouts(); | ||||
|         LoadShaders(stereoSupport); | ||||
|         CreatePipelines(sampleCount); | ||||
| @ -276,105 +281,56 @@ namespace vkn { | ||||
|             mCachedPipeline = pipeline; | ||||
|         } | ||||
|     } | ||||
|     void VulkanUISystem::CreateRenderPass(VkSampleCountFlagBits sampleCount) | ||||
|     void VulkanUISystem::CreateRenderPass(TinyImageFormat format, VkSampleCountFlagBits sampleCount) | ||||
|     { | ||||
|         VkAttachmentReference stencilRef{ 0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL }; | ||||
|         VkAttachmentReference colorRef{ 1, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL }; | ||||
|         VkAttachmentReference resolveRef{ 2, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL }; | ||||
|         VkAttachmentDescription colorAttachment = {}; | ||||
|         colorAttachment.format = (VkFormat)TinyImageFormat_ToVkFormat(format); | ||||
|         colorAttachment.samples = VK_SAMPLE_COUNT_1_BIT; | ||||
|         colorAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; | ||||
|         colorAttachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE; | ||||
|         colorAttachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; | ||||
|         colorAttachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; | ||||
|         colorAttachment.initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; | ||||
|         colorAttachment.finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR; | ||||
| 
 | ||||
|         VkSubpassDescription subpass{}; | ||||
|         VkAttachmentDescription stencilAttachment = {}; | ||||
|         stencilAttachment.format = (VkFormat)TinyImageFormat_ToVkFormat(CStencilFormat);; | ||||
|         stencilAttachment.samples = VK_SAMPLE_COUNT_1_BIT; | ||||
|         stencilAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; | ||||
|         stencilAttachment.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; | ||||
|         stencilAttachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; | ||||
|         stencilAttachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; | ||||
|         stencilAttachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; | ||||
|         stencilAttachment.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; | ||||
| 
 | ||||
|         VkAttachmentReference colorAttachmentRef = {}; | ||||
|         colorAttachmentRef.attachment = 0; | ||||
|         colorAttachmentRef.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; | ||||
| 
 | ||||
|         VkSubpassDescription subpass = {}; | ||||
|         subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; | ||||
|         subpass.colorAttachmentCount = 1; | ||||
|         subpass.pColorAttachments = &colorRef; | ||||
|         subpass.pDepthStencilAttachment = &stencilRef; | ||||
|         subpass.pColorAttachments = &colorAttachmentRef; | ||||
| 
 | ||||
|         Vector<VkAttachmentDescription, 3> attachments; | ||||
| 
 | ||||
|         // Stencil: Clear -> Don't care
 | ||||
|         VkAttachmentDescription stencil{}; | ||||
|         stencil.samples = sampleCount; | ||||
|         stencil.format = mStencilFormat; | ||||
|         stencil.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; | ||||
|         stencil.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; | ||||
|         stencil.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; | ||||
|         stencil.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; | ||||
|         stencil.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; | ||||
|         stencil.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; | ||||
|         attachments.PushBack(stencil); | ||||
| 
 | ||||
|         if (sampleCount > 1) | ||||
|         { | ||||
|             // Multisampled Color: Clear -> Don't care
 | ||||
|             VkAttachmentDescription colorAA{}; | ||||
|             colorAA.format = mBackBufferFormat; | ||||
|             colorAA.samples = sampleCount; | ||||
|             colorAA.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; | ||||
|             colorAA.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; | ||||
|             colorAA.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; | ||||
|             colorAA.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; | ||||
|             colorAA.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; | ||||
|             colorAA.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; | ||||
|             attachments.PushBack(colorAA); | ||||
| 
 | ||||
|             // Resolved Color: Don't care -> Store
 | ||||
|             VkAttachmentDescription color{}; | ||||
|             color.format = mBackBufferFormat; | ||||
|             color.samples = VK_SAMPLE_COUNT_1_BIT; | ||||
|             color.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; | ||||
|             color.storeOp = VK_ATTACHMENT_STORE_OP_STORE; | ||||
|             color.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; | ||||
|             color.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; | ||||
|             color.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; | ||||
|             color.finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR; | ||||
|             attachments.PushBack(color); | ||||
| 
 | ||||
|             subpass.pResolveAttachments = &resolveRef; | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             // Color: Clear -> Store
 | ||||
|             VkAttachmentDescription color{}; | ||||
|             color.format = mBackBufferFormat; | ||||
|             color.samples = VK_SAMPLE_COUNT_1_BIT; | ||||
|             color.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; | ||||
|             color.storeOp = VK_ATTACHMENT_STORE_OP_STORE; | ||||
|             color.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; | ||||
|             color.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; | ||||
|             color.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; | ||||
|             color.finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR; | ||||
|             attachments.PushBack(color); | ||||
|         } | ||||
| 
 | ||||
|         // The acquisition semaphore's pWaitDstStageMask guarantees that the image acquisition happens
 | ||||
|         // before VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, but we do not know exactly when. Thus
 | ||||
|         // we need an external dependency which fixes the stage for the transition to
 | ||||
|         // VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT. Otherwise, the GPU might try to transition
 | ||||
|         // the image before it is acquired from the presentation engine.
 | ||||
| 
 | ||||
|         // For the stencil, we also need VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT to wait for
 | ||||
|         // the clear operation before starting to write and read it (Write-After-Write hazard)
 | ||||
| 
 | ||||
|         VkSubpassDependency dependency{}; | ||||
|         VkSubpassDependency dependency = {}; | ||||
|         dependency.srcSubpass = VK_SUBPASS_EXTERNAL; | ||||
|         dependency.dstSubpass = 0; | ||||
|         dependency.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; | ||||
|         dependency.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; | ||||
|         dependency.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | | ||||
|             VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT; | ||||
|         dependency.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | | ||||
|             VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT; | ||||
| 
 | ||||
|         VkRenderPassCreateInfo renderPassInfo{}; | ||||
|         renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; | ||||
|         renderPassInfo.attachmentCount = attachments.Size(); | ||||
|         renderPassInfo.pAttachments = attachments.Data(); | ||||
|         renderPassInfo.subpassCount = 1; | ||||
|         renderPassInfo.pSubpasses = &subpass; | ||||
|         renderPassInfo.dependencyCount = 1; | ||||
|         renderPassInfo.pDependencies = &dependency; | ||||
| 
 | ||||
|         V(vkCreateRenderPass(mDevice->Ptr(), &renderPassInfo, nullptr, &mRenderPass)); | ||||
| 
 | ||||
|         attachments[1].loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; | ||||
|         V(vkCreateRenderPass(mDevice->Ptr(), &renderPassInfo, nullptr, &mRenderPassNoClear)); | ||||
|         VkAttachmentDescription attachmentList[2] = { colorAttachment , stencilAttachment }; | ||||
|         VkRenderPassCreateInfo info = {}; | ||||
|         info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; | ||||
|         info.attachmentCount = 2; | ||||
|         info.pAttachments = attachmentList; | ||||
|         info.subpassCount = 1; | ||||
|         info.pSubpasses = &subpass; | ||||
|         info.dependencyCount = 1; | ||||
|         info.pDependencies = &dependency; | ||||
|         V(vkCreateRenderPass(mDevice->Ptr(), &info, VK_NULL_HANDLE, &mRenderPass)); | ||||
|     } | ||||
|     void VulkanUISystem::CreateLayouts() | ||||
|     { | ||||
|  | ||||
| @ -54,10 +54,7 @@ namespace vkn { | ||||
| 			VK_TRUE,                                    // VkBool32                         clipped
 | ||||
| 			VK_NULL_HANDLE                              // VkSwapchainKHR                   oldSwapchain
 | ||||
| 		}; | ||||
| 		VkResult result = vkCreateSwapchainKHR(device.Ptr(), &swapchain_create_info, nullptr, &mPtr); | ||||
| 		if (result != VK_SUCCESS) { | ||||
| 			zlog::error("Failed to create swap chain."); | ||||
| 		} | ||||
| 		V(vkCreateSwapchainKHR(device.Ptr(), &swapchain_create_info, nullptr, &mPtr)); | ||||
| 		mFrames = args.framesInFlight; | ||||
| 		uint32_t flightFrames = args.framesInFlight * 2; | ||||
| 		pmr::vector<VkImage> swapchain_images{ FramePool() }; | ||||
| @ -98,17 +95,17 @@ namespace vkn { | ||||
| 	void VulkanSwapchain::Aquire(VulkanContext& ctx) | ||||
| 	{ | ||||
| 		VkFence surfaceFence = mFences[ctx.frame]; | ||||
| 		VkFence transferFence = mFences[ctx.frame]; | ||||
| 		VkFence transferFence = mFences[ctx.frame + mFrames]; | ||||
| 		VkSemaphore surfaceSemaphore = mSemaphores[ctx.frame]; | ||||
| 		ctx.surfaceCommand = mCommands[ctx.frame]; | ||||
| 		ctx.surfaceFence = surfaceFence; | ||||
| 		ctx.transferFence = transferFence; | ||||
| 		ctx.surfaceSemaphore = surfaceSemaphore; | ||||
| 		ctx.presentSemaphore = mSemaphores[ctx.frame + mFrames]; | ||||
| 		ctx.transferSemaphore = mSemaphores[ctx.frame + mFrames + mFrames]; | ||||
| 		VkFence waitFence[2] = { surfaceFence, transferFence }; | ||||
| 		uint32_t fenceNum = ctx.waitFenceNums[ctx.frame]; | ||||
| 		if (vkWaitForFences(mDevice.Ptr(), fenceNum, waitFence, VK_TRUE, UINT64_MAX) != VK_SUCCESS) | ||||
| 			throw std::runtime_error("Failed to wait for fence!"); | ||||
| 		V(vkWaitForFences(mDevice.Ptr(), fenceNum, waitFence, VK_TRUE, UINT64_MAX)); | ||||
| 		vkAcquireNextImageKHR(mDevice.Ptr(), mPtr, UINT64_MAX, surfaceSemaphore, VK_NULL_HANDLE, &ctx.presentFrame); | ||||
| 		vkResetFences(mDevice.Ptr(), fenceNum, waitFence); | ||||
| 		ctx.surface = mSurfaces[ctx.presentFrame]; | ||||
|  | ||||
| @ -4,9 +4,7 @@ | ||||
| namespace vkn { | ||||
| 	Instance::Instance(InstanceCreator& Creator) | ||||
| 	{ | ||||
| 		VkResult res = volkInitialize(); | ||||
| 		if (res != VK_SUCCESS) | ||||
| 			zlog::error("Could not initialize volk!"); | ||||
| 		V(volkInitialize()); | ||||
| 		VkApplicationInfo application_info = { | ||||
| 		  VK_STRUCTURE_TYPE_APPLICATION_INFO,         // VkStructureType           sType
 | ||||
| 		  nullptr,                                    // const void              * pNext
 | ||||
| @ -37,10 +35,7 @@ namespace vkn { | ||||
| 		VkDebugUtilsMessengerCreateInfoEXT debugInfo = Creator.DebugUtilsLayerNext(); | ||||
| 		instance_create_info.pNext = &debugInfo; | ||||
| #endif | ||||
| 		VkResult result = vkCreateInstance(&instance_create_info, nullptr, &mPtr); | ||||
| 		if (result != VK_SUCCESS) { | ||||
| 			zlog::error("Failed to create instance."); | ||||
| 		} | ||||
| 		V(vkCreateInstance(&instance_create_info, nullptr, &mPtr)); | ||||
| 		volkLoadInstanceOnly(mPtr); | ||||
| 	} | ||||
| 	bool Instance::EnumerateAvailablePhysicalDevices(pmr::vector<VkPhysicalDevice>& available_devices) | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user